omx_base_component.c

Go to the documentation of this file.
00001 
00031 #ifdef __cplusplus
00032 extern "C" {
00033 #endif
00034 
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <unistd.h>
00039 #include <errno.h>
00040 
00041 #include <OMX_Core.h>
00042 #include <OMX_Component.h>
00043 
00044 #include "omxcore.h"
00045 #include "omx_base_component.h"
00046 
00047 #include "tsemaphore.h"
00048 #include "queue.h"
00049 
00065 OMX_ERRORTYPE omx_base_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00066   omx_base_component_PrivateType* omx_base_component_Private;
00067 
00068   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00069 
00070   if (openmaxStandComp->pComponentPrivate) {
00071     omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00072   } else {
00073     omx_base_component_Private = calloc(1,sizeof(omx_base_component_PrivateType));
00074     if (!omx_base_component_Private) {
00075       return OMX_ErrorInsufficientResources;
00076     }
00077   }
00078 
00079   if(!omx_base_component_Private->messageQueue) {
00080     omx_base_component_Private->messageQueue = calloc(1,sizeof(queue_t));
00081     queue_init(omx_base_component_Private->messageQueue);
00082   }
00083 
00084   if(!omx_base_component_Private->messageSem) {
00085     omx_base_component_Private->messageSem = calloc(1,sizeof(tsem_t));
00086     tsem_init(omx_base_component_Private->messageSem, 0);
00087   }
00088   if(!omx_base_component_Private->bMgmtSem) {
00089     omx_base_component_Private->bMgmtSem = calloc(1,sizeof(tsem_t));
00090     tsem_init(omx_base_component_Private->bMgmtSem, 0);
00091   }
00092 
00093   if(!omx_base_component_Private->bStateSem) {
00094     omx_base_component_Private->bStateSem = calloc(1,sizeof(tsem_t));
00095     tsem_init(omx_base_component_Private->bStateSem, 0);
00096   }
00097 
00098   openmaxStandComp->nSize = sizeof(OMX_COMPONENTTYPE);
00099   openmaxStandComp->pApplicationPrivate = NULL;
00100   openmaxStandComp->GetComponentVersion = omx_base_component_GetComponentVersion;
00101   openmaxStandComp->SendCommand = omx_base_component_SendCommand;
00102   openmaxStandComp->GetParameter = omx_base_component_GetParameter;
00103   openmaxStandComp->SetParameter = omx_base_component_SetParameter;
00104   openmaxStandComp->GetConfig = omx_base_component_GetConfig;
00105   openmaxStandComp->SetConfig = omx_base_component_SetConfig;
00106   openmaxStandComp->GetExtensionIndex = omx_base_component_GetExtensionIndex;
00107   openmaxStandComp->GetState = omx_base_component_GetState;
00108   openmaxStandComp->SetCallbacks = omx_base_component_SetCallbacks;
00109   openmaxStandComp->ComponentDeInit = omx_base_component_ComponentDeInit;
00110   openmaxStandComp->ComponentRoleEnum = omx_base_component_ComponentRoleEnum;
00111   openmaxStandComp->ComponentTunnelRequest =omx_base_component_ComponentTunnelRequest;
00112 
00113   /*Will make Specific port Allocate buffer call*/
00114   openmaxStandComp->AllocateBuffer = omx_base_component_AllocateBuffer;
00115   openmaxStandComp->UseBuffer = omx_base_component_UseBuffer;
00116   openmaxStandComp->UseEGLImage = omx_base_component_UseEGLImage;
00117   openmaxStandComp->FreeBuffer = omx_base_component_FreeBuffer;
00118   openmaxStandComp->EmptyThisBuffer = omx_base_component_EmptyThisBuffer;
00119   openmaxStandComp->FillThisBuffer = omx_base_component_FillThisBuffer;
00120   
00121   openmaxStandComp->nVersion.s.nVersionMajor = SPECVERSIONMAJOR;
00122   openmaxStandComp->nVersion.s.nVersionMinor = SPECVERSIONMINOR;
00123   openmaxStandComp->nVersion.s.nRevision = SPECREVISION;
00124   openmaxStandComp->nVersion.s.nStep = SPECSTEP;
00125 
00126   omx_base_component_Private->name = calloc(1,OMX_MAX_STRINGNAME_SIZE);
00127   if (!omx_base_component_Private->name) {
00128     return OMX_ErrorInsufficientResources;
00129   }
00130   strcpy(omx_base_component_Private->name,cComponentName);
00131   omx_base_component_Private->state = OMX_StateLoaded;
00132   omx_base_component_Private->transientState = OMX_TransStateInvalid;
00133   omx_base_component_Private->callbacks = NULL;
00134   omx_base_component_Private->callbackData = NULL;
00135   omx_base_component_Private->nGroupPriority = 0;
00136   omx_base_component_Private->nGroupID = 0;
00137   omx_base_component_Private->pMark=NULL;
00138   omx_base_component_Private->openmaxStandComp=openmaxStandComp;
00139   omx_base_component_Private->DoStateSet = &omx_base_component_DoStateSet;
00140   omx_base_component_Private->messageHandler = omx_base_component_MessageHandler;
00141   omx_base_component_Private->destructor = omx_base_component_Destructor;
00142 
00143   pthread_mutex_init(&omx_base_component_Private->flush_mutex, NULL);
00144   pthread_cond_init(&omx_base_component_Private->flush_all_condition, NULL);
00145   pthread_cond_init(&omx_base_component_Private->flush_condition, NULL);
00146 
00147   setHeader(&omx_base_component_Private->sPortTypesParam, sizeof(OMX_PORT_PARAM_TYPE));
00148 
00149   omx_base_component_Private->messageHandlerThreadID = pthread_create(&omx_base_component_Private->messageHandlerThread,
00150   NULL,
00151   compMessageHandlerFunction,
00152   openmaxStandComp);
00153 
00154   DEBUG(DEB_LEV_FUNCTION_NAME,"Out of %s\n",__func__);
00155   return OMX_ErrorNone;
00156 }
00157 
00165 OMX_ERRORTYPE omx_base_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00166   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00167   int err;
00168   
00169   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00170   omx_base_component_Private->state = OMX_StateInvalid;
00171   omx_base_component_Private->callbacks=NULL;
00172 
00173   /*Send Dummy signal to Component Message handler to exit*/
00174   tsem_up(omx_base_component_Private->messageSem);
00175 
00176   /*Deinitialize and free message queue*/
00177   if(omx_base_component_Private->messageQueue) {
00178     queue_deinit(omx_base_component_Private->messageQueue);
00179     free(omx_base_component_Private->messageQueue);
00180     omx_base_component_Private->messageQueue=NULL;
00181   }
00182   
00183   err = pthread_join(omx_base_component_Private->messageHandlerThread,NULL);
00184   if(err!=0) {
00185     DEBUG(DEB_LEV_FUNCTION_NAME,"In %s pthread_join returned err=%d\n", __func__, err);
00186   }
00187 
00188   /*Deinitialize and free buffer management semaphore*/
00189   if(omx_base_component_Private->bMgmtSem){
00190     tsem_deinit(omx_base_component_Private->bMgmtSem);
00191     free(omx_base_component_Private->bMgmtSem);
00192     omx_base_component_Private->bMgmtSem=NULL;
00193   }
00194 
00195   /*Deinitialize and free message semaphore*/
00196   if(omx_base_component_Private->messageSem) {
00197     tsem_deinit(omx_base_component_Private->messageSem);
00198     free(omx_base_component_Private->messageSem);
00199     omx_base_component_Private->messageSem=NULL;
00200   }
00201 
00202   if(omx_base_component_Private->bStateSem){
00203     tsem_deinit(omx_base_component_Private->bStateSem);
00204     free(omx_base_component_Private->bStateSem);
00205     omx_base_component_Private->bStateSem=NULL;
00206   }
00207 
00208   if(omx_base_component_Private->name){
00209     free(omx_base_component_Private->name);
00210     omx_base_component_Private->name=NULL;
00211   }
00212 
00213   pthread_mutex_destroy(&omx_base_component_Private->flush_mutex);
00214   pthread_cond_destroy(&omx_base_component_Private->flush_all_condition);
00215   pthread_cond_destroy(&omx_base_component_Private->flush_condition);
00216 
00217   DEBUG(DEB_LEV_FUNCTION_NAME,"Out of %s\n",__func__);
00218   return OMX_ErrorNone;
00219 }
00220 
00229 OMX_ERRORTYPE omx_base_component_ComponentDeInit(
00230   OMX_IN  OMX_HANDLETYPE hComponent) {
00231   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00232   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00233 
00234   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s pComponentPrivate =%x \n", __func__,(int)openmaxStandComp->pComponentPrivate);
00235   omx_base_component_Private->destructor(openmaxStandComp);    
00236 
00237   free(openmaxStandComp->pComponentPrivate);
00238   openmaxStandComp->pComponentPrivate=NULL;
00239   return OMX_ErrorNone;
00240 }
00241 
00252 OMX_ERRORTYPE omx_base_component_DoStateSet(OMX_COMPONENTTYPE *openmaxStandComp, OMX_U32 destinationState) {
00253   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00254   omx_base_PortType *pPort;
00255   OMX_U32 i,j;
00256   OMX_ERRORTYPE err=OMX_ErrorNone;
00257 
00258   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00259   DEBUG(DEB_LEV_PARAMS, "Changing state from %i to %i\n", omx_base_component_Private->state, (int)destinationState);
00260 
00261   if(destinationState == OMX_StateLoaded){
00262     switch(omx_base_component_Private->state){
00263     case OMX_StateInvalid:
00264         err = OMX_ErrorInvalidState;
00265         break;
00266     case OMX_StateWaitForResources:
00267       /* return back from wait for resources */
00268       omx_base_component_Private->state = OMX_StateLoaded;
00269       break;
00270     case OMX_StateLoaded:
00271       err = OMX_ErrorSameState;
00272       break;
00273     case OMX_StateIdle:
00274       for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
00275         pPort = omx_base_component_Private->ports[i];
00276         if (PORT_IS_TUNNELED(pPort) && PORT_IS_BUFFER_SUPPLIER(pPort)) {
00277           while(pPort->pBufferQueue->nelem > 0) {
00278             DEBUG(DEB_LEV_PARAMS, "In %s Buffer %d remained in the port %d queue of comp%s\n",
00279                  __func__,(int)pPort->pBufferQueue->nelem,(int)i,omx_base_component_Private->name);
00280             dequeue(pPort->pBufferQueue);
00281           }
00282           /* Freeing here the buffers allocated for the tunneling:*/
00283           err = pPort->Port_FreeTunnelBuffer(pPort,i);
00284           if(err!=OMX_ErrorNone) { 
00285             DEBUG(DEB_LEV_ERR, "In %s Freeing Tunnel Buffer Error=%x\n",__func__,err); 
00286             return err; 
00287           } 
00288         } else {
00289           DEBUG(DEB_LEV_FULL_SEQ, "In %s nPortIndex=%d pAllocSem Semval=%x\n", __func__,(int)i,(int)pPort->pAllocSem->semval);
00290 
00291           /*If ports are enabled then wait till all buffers are freed*/
00292           if(PORT_IS_ENABLED(pPort)) {
00293             tsem_down(pPort->pAllocSem);
00294           }
00295         }
00296         pPort->sPortParam.bPopulated = OMX_FALSE;
00297       }
00298       omx_base_component_Private->state = OMX_StateLoaded;
00299       /*Signal Buffer Management thread to exit*/
00300       tsem_up(omx_base_component_Private->bMgmtSem);
00301       pthread_join(omx_base_component_Private->bufferMgmtThread,NULL);
00302       if(err != 0) {
00303         DEBUG(DEB_LEV_FUNCTION_NAME,"In %s pthread_join returned err=%d\n",__func__,err);
00304       }
00305       /*Free Internal Buffer Storage and Buffer Allocation State flags*/
00306       for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
00307         pPort = omx_base_component_Private->ports[i];
00308         free(pPort->bBufferStateAllocated);
00309         pPort->bBufferStateAllocated=NULL;
00310         free(pPort->pInternalBufferStorage);
00311         pPort->pInternalBufferStorage=NULL;
00312       }
00313       break;
00314     default:
00315       DEBUG(DEB_LEV_ERR, "In %s: state transition not allowed\n", __func__);
00316       err = OMX_ErrorIncorrectStateTransition;
00317       break;
00318     }
00319     return err;
00320   }
00321 
00322   if(destinationState == OMX_StateWaitForResources){
00323     switch(omx_base_component_Private->state){
00324     case OMX_StateInvalid:
00325       err = OMX_ErrorInvalidState;
00326       break;
00327     case OMX_StateLoaded:
00328       omx_base_component_Private->state = OMX_StateWaitForResources;
00329       break;
00330     case OMX_StateWaitForResources:
00331       err = OMX_ErrorSameState;
00332       break;
00333     default:
00334       DEBUG(DEB_LEV_ERR, "In %s: state transition not allowed\n", __func__);
00335       return OMX_ErrorIncorrectStateTransition;
00336     }
00337     return err;
00338   }
00339 
00340   if(destinationState == OMX_StateIdle){
00341     switch(omx_base_component_Private->state){
00342     case OMX_StateInvalid:
00343       err = OMX_ErrorInvalidState;
00344       break;
00345     case OMX_StateWaitForResources:
00346       omx_base_component_Private->state = OMX_StateIdle;
00347       break;
00348     case OMX_StateLoaded:
00349       for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
00350         pPort = omx_base_component_Private->ports[i];
00351         if (PORT_IS_TUNNELED(pPort) && PORT_IS_BUFFER_SUPPLIER(pPort)) {
00352           if(PORT_IS_ENABLED(pPort)) {
00354             err= pPort->Port_AllocateTunnelBuffer(pPort, i, omx_base_component_Private->ports[i]->sPortParam.nBufferSize);
00355             if(err!=OMX_ErrorNone) { 
00356               DEBUG(DEB_LEV_ERR, "In %s Allocating Tunnel Buffer Error=%x\n",__func__,err); 
00357               return err; 
00358             } 
00359           }
00360         } else {
00361           if(PORT_IS_ENABLED(pPort)) {
00362             DEBUG(DEB_LEV_FULL_SEQ, "In %s: wait for buffers. port enabled %i,  port populated %i\n", 
00363               __func__, pPort->sPortParam.bEnabled,pPort->sPortParam.bPopulated);
00364             tsem_down(pPort->pAllocSem);
00365             pPort->sPortParam.bPopulated = OMX_TRUE;
00366           }
00367           else 
00368             DEBUG(DEB_LEV_ERR, "In %s: Port %i Disabled So no wait\n",__func__,(int)i);
00369         }
00370         DEBUG(DEB_LEV_SIMPLE_SEQ, "---> Tunnel status : port %d flags  0x%x\n",(int)i, (int)pPort->nTunnelFlags);
00371       }
00372       omx_base_component_Private->state = OMX_StateIdle;
00374       omx_base_component_Private->bufferMgmtThreadID = pthread_create(&omx_base_component_Private->bufferMgmtThread,
00375       NULL,
00376       omx_base_component_Private->BufferMgmtFunction,
00377       openmaxStandComp);  
00378       if(omx_base_component_Private->bufferMgmtThreadID < 0){
00379         DEBUG(DEB_LEV_ERR, "Starting buffer management thread failed\n");
00380         return OMX_ErrorUndefined;
00381       }  
00382       break;
00383     case OMX_StateIdle:
00384       err = OMX_ErrorSameState;
00385       break;
00386     case OMX_StateExecuting:
00387       /*Flush Ports*/
00388       for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
00389         DEBUG(DEB_LEV_FULL_SEQ, "Flushing Port %i\n",(int)i);
00390         pPort = omx_base_component_Private->ports[i];
00391         if(PORT_IS_ENABLED(pPort)) {
00392           pPort->FlushProcessingBuffers(pPort);
00393         }
00394       }
00395       omx_base_component_Private->state = OMX_StateIdle;
00396       break;
00397       case OMX_StatePause:
00398       omx_base_component_Private->state = OMX_StateIdle;
00399       /*Signal buffer management thread if waiting at paused state*/
00400       tsem_signal(omx_base_component_Private->bStateSem);
00401       break;
00402     default:
00403       DEBUG(DEB_LEV_ERR, "In %s: state transition not allowed\n", __func__);
00404       err = OMX_ErrorIncorrectStateTransition;
00405       break;
00406     }
00407     return err;
00408   }
00409 
00410   if(destinationState == OMX_StatePause) {
00411   switch(omx_base_component_Private->state) {
00412     case OMX_StateInvalid:
00413       err = OMX_ErrorInvalidState;
00414       break;
00415     case OMX_StatePause:
00416       err = OMX_ErrorSameState;
00417       break;
00418     case OMX_StateExecuting:
00419     case OMX_StateIdle:
00420       omx_base_component_Private->state = OMX_StatePause;
00421       break;
00422     default:
00423       DEBUG(DEB_LEV_ERR, "In %s: state transition not allowed\n", __func__);
00424       err = OMX_ErrorIncorrectStateTransition;
00425       break;
00426     }
00427     return err;
00428   }
00429 
00430   if(destinationState == OMX_StateExecuting) {
00431     switch(omx_base_component_Private->state) {
00432     case OMX_StateInvalid:
00433       err = OMX_ErrorInvalidState;
00434       break;
00435     case OMX_StateIdle:
00436       omx_base_component_Private->state=OMX_StateExecuting;
00437       /*Send Tunneled Buffer to the Neighbouring Components*/
00438       for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
00439         if (PORT_IS_TUNNELED(omx_base_component_Private->ports[i]) &&
00440           PORT_IS_BUFFER_SUPPLIER(omx_base_component_Private->ports[i])) {
00441           for(j=0;j<omx_base_component_Private->ports[i]->nNumTunnelBuffer;j++) {
00442             tsem_up(omx_base_component_Private->ports[i]->pBufferSem);
00443             /*signal buffer management thread availability of buffers*/
00444             tsem_up(omx_base_component_Private->bMgmtSem);
00445           }
00446         }
00447       }
00448       omx_base_component_Private->transientState = OMX_TransStateInvalid;
00449       err = OMX_ErrorNone;
00450       break;
00451     case OMX_StatePause:
00452       omx_base_component_Private->state=OMX_StateExecuting;
00453 
00454       /* Tunneled Supplier Ports were enabled in paused state. So signal buffer managment thread*/
00455       for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
00456         pPort=omx_base_component_Private->ports[i];
00457         DEBUG(DEB_LEV_PARAMS, "In %s: state transition Paused 2 Executing, nelem=%d,semval=%d,Buf Count Actual=%d\n", __func__,
00458           pPort->pBufferQueue->nelem,pPort->pBufferSem->semval,(int)pPort->sPortParam.nBufferCountActual);
00459         if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(pPort) && 
00460           (pPort->pBufferQueue->nelem == (pPort->pBufferSem->semval + pPort->sPortParam.nBufferCountActual))) {
00461           for(j=0; j < pPort->sPortParam.nBufferCountActual;j++) {
00462             tsem_up(pPort->pBufferSem);
00463             tsem_up(omx_base_component_Private->bMgmtSem);
00464           }
00465         }
00466       }
00467       /*Signal buffer management thread if waiting at paused state*/
00468       tsem_signal(omx_base_component_Private->bStateSem);
00469       break;
00470     case OMX_StateExecuting:
00471       err = OMX_ErrorSameState;
00472       break;
00473     default:
00474       DEBUG(DEB_LEV_ERR, "In %s: state transition not allowed\n", __func__);
00475       err = OMX_ErrorIncorrectStateTransition;
00476       break;
00477     }
00478     return err;
00479   }
00480 
00481   if(destinationState == OMX_StateInvalid) {
00482     switch(omx_base_component_Private->state) {
00483     case OMX_StateInvalid:
00484       err = OMX_ErrorInvalidState;
00485       break;
00486     default:
00487       omx_base_component_Private->state = OMX_StateInvalid;
00488       /*Signal Buffer Management Thread to Exit*/
00489       tsem_up(omx_base_component_Private->bMgmtSem);
00490       if(omx_base_component_Private->bufferMgmtThread){
00491         pthread_detach(omx_base_component_Private->bufferMgmtThread);
00492         pthread_join(omx_base_component_Private->bufferMgmtThread,NULL);
00493         if(err!=0) {
00494           DEBUG(DEB_LEV_FUNCTION_NAME,"In %s pthread_join returned err=%d\n",__func__,err);
00495         }
00496       }
00497       break;
00498     }
00499     return err;
00500   }
00501   return OMX_ErrorNone;
00502 }
00503 
00515 OMX_ERRORTYPE checkHeader(OMX_PTR header, OMX_U32 size) {
00516   OMX_VERSIONTYPE* ver;
00517   if (header == NULL) {
00518     DEBUG(DEB_LEV_ERR, "In %s the header is null\n",__func__);
00519     return OMX_ErrorBadParameter;
00520   }
00521   ver = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32));
00522   if(*((OMX_U32*)header) != size) {
00523     DEBUG(DEB_LEV_ERR, "In %s the header has a wrong size %i should be %i\n",__func__,(int)*((OMX_U32*)header),(int)size);
00524     return OMX_ErrorBadParameter;
00525   }
00526   if(ver->s.nVersionMajor != SPECVERSIONMAJOR ||
00527     ver->s.nVersionMinor != SPECVERSIONMINOR) {
00528     DEBUG(DEB_LEV_ERR, "The version does not match\n");
00529     return OMX_ErrorVersionMismatch;
00530   }
00531   return OMX_ErrorNone;
00532 }
00533 
00541 void setHeader(OMX_PTR header, OMX_U32 size) {
00542   OMX_VERSIONTYPE* ver = (OMX_VERSIONTYPE*)((char*)header + sizeof(OMX_U32));
00543   *((OMX_U32*)header) = size;
00544 
00545   ver->s.nVersionMajor = SPECVERSIONMAJOR;
00546   ver->s.nVersionMinor = SPECVERSIONMINOR;
00547   ver->s.nRevision = SPECREVISION;
00548   ver->s.nStep = SPECSTEP;
00549 }
00550 
00554 OMX_ERRORTYPE omx_base_component_ParameterSanityCheck(OMX_IN  OMX_HANDLETYPE hComponent,
00555   OMX_IN  OMX_U32 nPortIndex,
00556   OMX_IN  OMX_PTR pStructure,
00557   OMX_IN  size_t size) {
00558   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)(((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate);
00559   omx_base_PortType *pPort;
00560 
00561   if (nPortIndex >= (omx_base_component_Private->sPortTypesParam.nStartPortNumber + omx_base_component_Private->sPortTypesParam.nPorts)) {
00562     DEBUG(DEB_LEV_ERR, "Bad Port index %i when the component has %i ports\n", (int)nPortIndex, (int)omx_base_component_Private->sPortTypesParam.nPorts);
00563     return OMX_ErrorBadPortIndex;
00564   }
00565 
00566   pPort = omx_base_component_Private->ports[nPortIndex];
00567 
00568   if (omx_base_component_Private->state != OMX_StateLoaded && omx_base_component_Private->state != OMX_StateWaitForResources) {
00569     if(PORT_IS_ENABLED(pPort)) {
00570       DEBUG(DEB_LEV_ERR, "In %s Incorrect State=%x lineno=%d\n",__func__,omx_base_component_Private->state,__LINE__);
00571       return OMX_ErrorIncorrectStateOperation;
00572     }
00573   }
00574   
00575   return checkHeader(pStructure , size);
00576 } 
00577 
00582 OMX_ERRORTYPE omx_base_component_GetComponentVersion(OMX_IN  OMX_HANDLETYPE hComponent,
00583   OMX_OUT OMX_STRING pComponentName,
00584   OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
00585   OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
00586   OMX_OUT OMX_UUIDTYPE* pComponentUUID) {
00587 
00588   OMX_COMPONENTTYPE* omx_component = (OMX_COMPONENTTYPE*)hComponent;
00589   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omx_component->pComponentPrivate;
00590 
00591   OMX_U32 uuid[3];
00592 
00593   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00594   /* Fill component name */
00595   strcpy(pComponentName, omx_base_component_Private->name);
00596 
00597   /* Fill component version */
00598   pComponentVersion->s.nVersionMajor = SPECVERSIONMAJOR;
00599   pComponentVersion->s.nVersionMinor = SPECVERSIONMINOR;
00600   pComponentVersion->s.nRevision = SPECREVISION;
00601   pComponentVersion->s.nStep = SPECSTEP;
00602 
00603   /* Fill spec version (copy from component field) */
00604   memcpy(pSpecVersion, &omx_component->nVersion, sizeof(OMX_VERSIONTYPE));
00605 
00606   /* Fill UUID with handle address, PID and UID.
00607    * This should guarantee uiniqness */
00608   uuid[0] = (OMX_U32)omx_component;
00609   uuid[1] = getpid();
00610   uuid[2] = getuid();
00611   memcpy(*pComponentUUID, uuid, 3*sizeof(uuid));
00612 
00613   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00614   return OMX_ErrorNone;
00615 }
00616 
00625 OMX_ERRORTYPE omx_base_component_ComponentRoleEnum(
00626   OMX_IN OMX_HANDLETYPE hComponent,
00627   OMX_OUT OMX_U8 *cRole,
00628   OMX_IN OMX_U32 nIndex) {
00629   strcat((char*)cRole, "\0");
00630   return OMX_ErrorNoMore;
00631 }
00632 
00638 OMX_ERRORTYPE omx_base_component_SetCallbacks(
00639   OMX_IN  OMX_HANDLETYPE hComponent,
00640   OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
00641   OMX_IN  OMX_PTR pAppData) {
00642   
00643   OMX_COMPONENTTYPE *omxcomponent = (OMX_COMPONENTTYPE*)hComponent;
00644   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxcomponent->pComponentPrivate;
00645   omx_base_PortType *pPort;
00646   OMX_U32 i;
00647 
00648   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00649   omx_base_component_Private->callbacks = pCallbacks;
00650   omx_base_component_Private->callbackData = pAppData;  
00651 
00652   for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
00653     pPort = omx_base_component_Private->ports[i];
00654     if (pPort->sPortParam.eDir == OMX_DirInput) {
00655       pPort->BufferProcessedCallback = omx_base_component_Private->callbacks->EmptyBufferDone;
00656     } else {
00657       pPort->BufferProcessedCallback = omx_base_component_Private->callbacks->FillBufferDone;
00658     }  
00659   }
00660   return OMX_ErrorNone;
00661 }
00662 
00671 OMX_ERRORTYPE omx_base_component_GetParameter(
00672   OMX_IN  OMX_HANDLETYPE hComponent,
00673   OMX_IN  OMX_INDEXTYPE nParamIndex,
00674   OMX_INOUT OMX_PTR ComponentParameterStructure) {
00675   
00676   OMX_COMPONENTTYPE *omxcomponent = (OMX_COMPONENTTYPE*)hComponent;
00677   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxcomponent->pComponentPrivate;
00678   OMX_PRIORITYMGMTTYPE* pPrioMgmt;
00679   OMX_PARAM_PORTDEFINITIONTYPE *pPortDef;
00680   OMX_PARAM_BUFFERSUPPLIERTYPE *pBufferSupplier;
00681   omx_base_PortType *pPort;
00682   OMX_PORT_PARAM_TYPE* pPortDomains;
00683   OMX_ERRORTYPE err = OMX_ErrorNone;
00684 
00685   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00686   DEBUG(DEB_LEV_PARAMS, "Getting parameter %i\n", nParamIndex);
00687   if (ComponentParameterStructure == NULL) {
00688     return OMX_ErrorBadParameter;
00689   }
00690   switch(nParamIndex) {
00691   case OMX_IndexParamAudioInit:
00692   case OMX_IndexParamVideoInit:
00693   case OMX_IndexParamImageInit:
00694   case OMX_IndexParamOtherInit:
00695     pPortDomains = (OMX_PORT_PARAM_TYPE*)ComponentParameterStructure;
00696     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) { 
00697       break;
00698     }
00699     pPortDomains->nPorts = 0;
00700     pPortDomains->nStartPortNumber = 0;
00701     break;    
00702   case OMX_IndexParamPortDefinition:
00703     pPortDef  = (OMX_PARAM_PORTDEFINITIONTYPE*) ComponentParameterStructure;
00704     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_PORTDEFINITIONTYPE))) != OMX_ErrorNone) { 
00705       break;
00706     }
00707     if (pPortDef->nPortIndex >= (omx_base_component_Private->sPortTypesParam.nStartPortNumber + omx_base_component_Private->sPortTypesParam.nPorts)) {
00708       return OMX_ErrorBadPortIndex;
00709     }
00710     memcpy(pPortDef, &omx_base_component_Private->ports[pPortDef->nPortIndex]->sPortParam, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00711     break;
00712   case OMX_IndexParamPriorityMgmt:
00713     pPrioMgmt = (OMX_PRIORITYMGMTTYPE*)ComponentParameterStructure;
00714     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PRIORITYMGMTTYPE))) != OMX_ErrorNone) { 
00715       break;
00716     }
00717     pPrioMgmt->nGroupPriority = omx_base_component_Private->nGroupPriority;
00718     pPrioMgmt->nGroupID = omx_base_component_Private->nGroupID;
00719     break;
00720   case OMX_IndexParamCompBufferSupplier:
00721     pBufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE*)ComponentParameterStructure;
00722     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE))) != OMX_ErrorNone) { 
00723       break;
00724     }
00725     if (pBufferSupplier->nPortIndex >= omx_base_component_Private->sPortTypesParam.nPorts) {
00726       return OMX_ErrorBadPortIndex;
00727     }
00728 
00729     pPort = omx_base_component_Private->ports[pBufferSupplier->nPortIndex];
00730 
00731     if (pPort->sPortParam.eDir == OMX_DirInput) {
00732       if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
00733         pBufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;  
00734       } else if (PORT_IS_TUNNELED(pPort)) {
00735         pBufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;  
00736       } else {
00737         pBufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;  
00738       }
00739     } else {
00740       if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
00741         pBufferSupplier->eBufferSupplier = OMX_BufferSupplyOutput;  
00742       } else if (PORT_IS_TUNNELED(pPort)) {
00743         pBufferSupplier->eBufferSupplier = OMX_BufferSupplyInput;  
00744       } else {
00745         pBufferSupplier->eBufferSupplier = OMX_BufferSupplyUnspecified;  
00746       }
00747     }
00748     break;
00749   default:
00750     err = OMX_ErrorUnsupportedIndex;
00751     break;
00752   }
00753   return err;
00754 }
00755 
00764 OMX_ERRORTYPE omx_base_component_SetParameter(
00765   OMX_IN  OMX_HANDLETYPE hComponent,
00766   OMX_IN  OMX_INDEXTYPE nParamIndex,
00767   OMX_IN  OMX_PTR ComponentParameterStructure) {
00768     
00769   OMX_PRIORITYMGMTTYPE* pPrioMgmt;
00770   OMX_PARAM_PORTDEFINITIONTYPE *pPortDef;
00771   OMX_ERRORTYPE err = OMX_ErrorNone;
00772   OMX_COMPONENTTYPE *omxcomponent = (OMX_COMPONENTTYPE*)hComponent;
00773   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxcomponent->pComponentPrivate;
00774   OMX_PARAM_BUFFERSUPPLIERTYPE *pBufferSupplier;
00775   omx_base_PortType *pPort;
00776 
00777   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00778   DEBUG(DEB_LEV_PARAMS, "Setting parameter %i\n", nParamIndex);
00779   if (ComponentParameterStructure == NULL) {
00780     return OMX_ErrorBadParameter;
00781   }
00782  
00783   switch(nParamIndex) {
00784   case OMX_IndexParamAudioInit:
00785   case OMX_IndexParamVideoInit:
00786   case OMX_IndexParamImageInit:
00787   case OMX_IndexParamOtherInit:
00788     /* pPortParam  = (OMX_PORT_PARAM_TYPE* ) ComponentParameterStructure;*/
00789     if (omx_base_component_Private->state != OMX_StateLoaded && 
00790       omx_base_component_Private->state != OMX_StateWaitForResources) {
00791       return OMX_ErrorIncorrectStateOperation;
00792     }
00793     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) { 
00794       break;
00795     }
00796     err = OMX_ErrorUndefined;
00797     break;  
00798   case OMX_IndexParamPortDefinition: 
00799     pPortDef  = (OMX_PARAM_PORTDEFINITIONTYPE*) ComponentParameterStructure;
00800     err = omx_base_component_ParameterSanityCheck(hComponent, pPortDef->nPortIndex, pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00801     if(err!=OMX_ErrorNone) { 
00802       DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err); 
00803       break;
00804     } 
00805     {
00806       OMX_PARAM_PORTDEFINITIONTYPE *pPortParam;
00807       OMX_U32 j,old_nBufferCountActual=0;
00808       pPortParam = &omx_base_component_Private->ports[pPortDef->nPortIndex]->sPortParam;
00809       if( pPortDef->nBufferCountActual < pPortParam->nBufferCountMin) {
00810         return OMX_ErrorBadParameter;
00811       }
00812       old_nBufferCountActual         = pPortParam->nBufferCountActual;
00813       pPortParam->nBufferCountActual = pPortDef->nBufferCountActual;
00814 
00815       switch(pPortDef->eDomain) {
00816       case OMX_PortDomainAudio:
00817         memcpy(&pPortParam->format.audio, &pPortDef->format.audio, sizeof(OMX_AUDIO_PORTDEFINITIONTYPE));
00818         break;
00819       case OMX_PortDomainVideo:
00820         pPortParam->format.video.pNativeRender          = pPortDef->format.video.pNativeRender;
00821         pPortParam->format.video.nFrameWidth            = pPortDef->format.video.nFrameWidth;
00822         pPortParam->format.video.nFrameHeight           = pPortDef->format.video.nFrameHeight;
00823         pPortParam->format.video.nStride                = pPortDef->format.video.nStride;
00824         pPortParam->format.video.xFramerate             = pPortDef->format.video.xFramerate;
00825         pPortParam->format.video.bFlagErrorConcealment  = pPortDef->format.video.bFlagErrorConcealment;
00826         pPortParam->format.video.eCompressionFormat     = pPortDef->format.video.eCompressionFormat;
00827         pPortParam->format.video.eColorFormat           = pPortDef->format.video.eColorFormat;
00828         pPortParam->format.video.pNativeWindow          = pPortDef->format.video.pNativeWindow;
00829         break;
00830       case OMX_PortDomainImage:
00831         pPortParam->format.image.nFrameWidth            = pPortDef->format.image.nFrameWidth;
00832         pPortParam->format.image.nFrameHeight           = pPortDef->format.image.nFrameHeight;
00833         pPortParam->format.image.nStride                = pPortDef->format.image.nStride;
00834         pPortParam->format.image.bFlagErrorConcealment  = pPortDef->format.image.bFlagErrorConcealment;
00835         pPortParam->format.image.eCompressionFormat     = pPortDef->format.image.eCompressionFormat;
00836         pPortParam->format.image.eColorFormat           = pPortDef->format.image.eColorFormat;
00837         pPortParam->format.image.pNativeWindow          = pPortDef->format.image.pNativeWindow;
00838         break;
00839       case OMX_PortDomainOther:
00840         memcpy(&pPortParam->format.other, &pPortDef->format.other, sizeof(OMX_OTHER_PORTDEFINITIONTYPE));
00841         break;
00842       default:
00843         err = OMX_ErrorBadParameter;
00844         break;
00845       }
00846       
00847       /*If component state Idle/Pause/Executing and re-alloc the following private variables */
00848       if ((omx_base_component_Private->state == OMX_StateIdle || 
00849         omx_base_component_Private->state == OMX_StatePause  || 
00850         omx_base_component_Private->state == OMX_StateExecuting) && 
00851         (pPortParam->nBufferCountActual > old_nBufferCountActual)) {
00852 
00853         pPort = omx_base_component_Private->ports[pPortDef->nPortIndex];
00854         if(pPort->bBufferStateAllocated) {
00855           pPort->bBufferStateAllocated = realloc(pPort->bBufferStateAllocated,pPort->sPortParam.nBufferCountActual*sizeof(BUFFER_STATUS_FLAG *));
00856           for(j=0; j < pPort->sPortParam.nBufferCountActual; j++) {
00857             pPort->bBufferStateAllocated[j] = BUFFER_FREE;
00858           }
00859         }
00860         if(pPort->pInternalBufferStorage) {
00861           pPort->pInternalBufferStorage = realloc(pPort->pInternalBufferStorage,pPort->sPortParam.nBufferCountActual*sizeof(OMX_BUFFERHEADERTYPE *));
00862         }
00863       }
00864     }
00865     break;
00866   case OMX_IndexParamPriorityMgmt:
00867     if (omx_base_component_Private->state != OMX_StateLoaded && 
00868       omx_base_component_Private->state != OMX_StateWaitForResources) {
00869       return OMX_ErrorIncorrectStateOperation;
00870     }
00871     pPrioMgmt = (OMX_PRIORITYMGMTTYPE*)ComponentParameterStructure;
00872     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PRIORITYMGMTTYPE))) != OMX_ErrorNone) { 
00873       break;
00874     }
00875     omx_base_component_Private->nGroupPriority = pPrioMgmt->nGroupPriority;
00876     omx_base_component_Private->nGroupID = pPrioMgmt->nGroupID;
00877     break;
00878   case OMX_IndexParamCompBufferSupplier:
00879     pBufferSupplier = (OMX_PARAM_BUFFERSUPPLIERTYPE*)ComponentParameterStructure;
00880     DEBUG(DEB_LEV_PARAMS, "In %s Buf Sup Port index=%d, nport=%d\n", __func__,
00881       (int)pBufferSupplier->nPortIndex,(int)omx_base_component_Private->sPortTypesParam.nPorts);
00882     if(pBufferSupplier == NULL) {
00883       return OMX_ErrorBadParameter;
00884     }
00885     if(pBufferSupplier->nPortIndex > omx_base_component_Private->sPortTypesParam.nPorts) {
00886       return OMX_ErrorBadPortIndex;
00887     }
00888     err = omx_base_component_ParameterSanityCheck(hComponent, pBufferSupplier->nPortIndex, pBufferSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
00889     if(err==OMX_ErrorIncorrectStateOperation) {
00890       if (PORT_IS_ENABLED(omx_base_component_Private->ports[pBufferSupplier->nPortIndex])) {
00891         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Incorrect State=%x\n",__func__,omx_base_component_Private->state);
00892         return OMX_ErrorIncorrectStateOperation;
00893       }
00894     } else if (err != OMX_ErrorNone) {
00895       break;
00896     }
00897 
00898     if (pBufferSupplier->eBufferSupplier == OMX_BufferSupplyUnspecified) {
00899       DEBUG(DEB_LEV_PARAMS, "In %s: port is already buffer supplier unspecified\n", __func__);
00900       return OMX_ErrorNone;
00901     }
00902     if ((PORT_IS_TUNNELED(omx_base_component_Private->ports[pBufferSupplier->nPortIndex])) == 0) {
00903       return OMX_ErrorNone;
00904     }
00905 
00906     pPort = omx_base_component_Private->ports[pBufferSupplier->nPortIndex];
00907 
00908     if ((pBufferSupplier->eBufferSupplier == OMX_BufferSupplyInput) && 
00909         (pPort->sPortParam.eDir == OMX_DirInput)) {
00911       if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
00912         err = OMX_ErrorNone;
00913       }
00914       pPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
00915       pBufferSupplier->nPortIndex = pPort->nTunneledPort;
00916       err = OMX_SetParameter(pPort->hTunneledComponent, OMX_IndexParamCompBufferSupplier, pBufferSupplier);
00917     } else if ((pBufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) && 
00918                (pPort->sPortParam.eDir == OMX_DirInput)) {
00919       if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
00920         pPort->nTunnelFlags &= ~TUNNEL_IS_SUPPLIER;
00921         pBufferSupplier->nPortIndex = pPort->nTunneledPort;
00922         err = OMX_SetParameter(pPort->hTunneledComponent, OMX_IndexParamCompBufferSupplier, pBufferSupplier);
00923       }
00924       err = OMX_ErrorNone;
00925     } else if ((pBufferSupplier->eBufferSupplier == OMX_BufferSupplyOutput) && 
00926                (pPort->sPortParam.eDir == OMX_DirOutput)) {
00928       if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
00929         err = OMX_ErrorNone;
00930       }
00931       pPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
00932     } else {
00933       if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
00934         pPort->nTunnelFlags &= ~TUNNEL_IS_SUPPLIER;
00935         err = OMX_ErrorNone;
00936       }
00937       err = OMX_ErrorNone;
00938     }
00939     DEBUG(DEB_LEV_PARAMS, "In %s port %d Tunnel flag=%x \n", __func__,(int)pBufferSupplier->nPortIndex, (int)pPort->nTunnelFlags);
00940     break;
00941   default:
00942     err = OMX_ErrorUnsupportedIndex;
00943     break;
00944   }
00945   return err;
00946 }
00947 
00955 OMX_ERRORTYPE omx_base_component_GetConfig(
00956   OMX_IN  OMX_HANDLETYPE hComponent,
00957   OMX_IN  OMX_INDEXTYPE nIndex,
00958   OMX_INOUT OMX_PTR pComponentConfigStructure) {
00959   return OMX_ErrorNone;
00960 }
00961 
00969 OMX_ERRORTYPE omx_base_component_SetConfig(
00970   OMX_IN  OMX_HANDLETYPE hComponent,
00971   OMX_IN  OMX_INDEXTYPE nIndex,
00972   OMX_IN  OMX_PTR pComponentConfigStructure) {
00973   return OMX_ErrorNone;
00974 }
00975 
00981 OMX_ERRORTYPE omx_base_component_GetExtensionIndex(
00982   OMX_IN  OMX_HANDLETYPE hComponent,
00983   OMX_IN  OMX_STRING cParameterName,
00984   OMX_OUT OMX_INDEXTYPE* pIndexType) {    
00985 
00986   DEBUG(DEB_LEV_FUNCTION_NAME,"In  %s \n",__func__);
00987 
00988   return OMX_ErrorBadParameter;  
00989 }
00990 
00995 OMX_ERRORTYPE omx_base_component_GetState(
00996   OMX_IN  OMX_HANDLETYPE hComponent,
00997   OMX_OUT OMX_STATETYPE* pState) {
00998   OMX_COMPONENTTYPE *omxcomponent = (OMX_COMPONENTTYPE*)hComponent;
00999   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxcomponent->pComponentPrivate;
01000   *pState = omx_base_component_Private->state;
01001   return OMX_ErrorNone;
01002 }
01003 
01009 OMX_ERRORTYPE omx_base_component_SendCommand(
01010   OMX_IN  OMX_HANDLETYPE hComponent,
01011   OMX_IN  OMX_COMMANDTYPE Cmd,
01012   OMX_IN  OMX_U32 nParam,
01013   OMX_IN  OMX_PTR pCmdData) {
01014   OMX_COMPONENTTYPE* omxComponent = (OMX_COMPONENTTYPE*)hComponent;
01015   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
01016   internalRequestMessageType *message;
01017   queue_t* messageQueue;
01018   tsem_t* messageSem;
01019   OMX_U32 i,j;
01020   omx_base_PortType *pPort;
01021   OMX_ERRORTYPE err = OMX_ErrorNone;
01022   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
01023 
01024   messageQueue = omx_base_component_Private->messageQueue;
01025   messageSem = omx_base_component_Private->messageSem;
01026 
01027   if (omx_base_component_Private->state == OMX_StateInvalid) {
01028     return OMX_ErrorInvalidState;
01029   }
01030   
01031   message = calloc(1,sizeof(internalRequestMessageType));
01032   message->messageParam = nParam;
01033   message->pCmdData=pCmdData;
01035   switch (Cmd) {
01036   case OMX_CommandStateSet:
01037     message->messageType = OMX_CommandStateSet;
01038     if ((nParam == OMX_StateIdle) && (omx_base_component_Private->state == OMX_StateLoaded)) {
01039       /*Allocate Internal Buffer Storage and Buffer Allocation State flags*/
01040       for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
01041         pPort = omx_base_component_Private->ports[i];
01042         pPort->bBufferStateAllocated=calloc(1,pPort->sPortParam.nBufferCountActual*sizeof(BUFFER_STATUS_FLAG *));
01043         pPort->pInternalBufferStorage=calloc(1,pPort->sPortParam.nBufferCountActual*sizeof(OMX_BUFFERHEADERTYPE *));
01044         for(j=0; j < pPort->sPortParam.nBufferCountActual; j++)
01045           pPort->bBufferStateAllocated[j] = BUFFER_FREE;
01046       }
01047 
01048       omx_base_component_Private->transientState = OMX_TransStateLoadedToIdle;
01049     } else if ((nParam == OMX_StateLoaded) && (omx_base_component_Private->state == OMX_StateIdle)) {
01050       omx_base_component_Private->transientState = OMX_TransStateIdleToLoaded;
01051     } else if ((nParam == OMX_StateIdle) && (omx_base_component_Private->state == OMX_StateExecuting)) {
01052       omx_base_component_Private->transientState = OMX_TransStateExecutingToIdle;
01053     }    
01054     break;
01055   case OMX_CommandFlush:
01056     if (nParam >= omx_base_component_Private->sPortTypesParam.nPorts && nParam != OMX_ALL) {
01057       return OMX_ErrorBadPortIndex;
01058     }
01059     message->messageType = OMX_CommandFlush;
01060     break;
01061   case OMX_CommandPortDisable:
01062     if (nParam >= omx_base_component_Private->sPortTypesParam.nPorts && nParam != OMX_ALL) {
01063       return OMX_ErrorBadPortIndex;
01064     }
01065     message->messageType = OMX_CommandPortDisable;
01066     if(message->messageParam == OMX_ALL) {
01067       for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01068         omx_base_component_Private->ports[i]->bIsTransientToDisabled = OMX_TRUE;
01069       }
01070     } else {
01071       omx_base_component_Private->ports[message->messageParam]->bIsTransientToDisabled = OMX_TRUE;
01072     }
01073     break;
01074   case OMX_CommandPortEnable:
01075     if (nParam >= omx_base_component_Private->sPortTypesParam.nPorts && nParam != OMX_ALL) {
01076       return OMX_ErrorBadPortIndex;
01077     }
01078     message->messageType = OMX_CommandPortEnable;
01079     if(message->messageParam == OMX_ALL) {
01080       for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01081         omx_base_component_Private->ports[i]->bIsTransientToEnabled = OMX_TRUE;
01082       }
01083     } else {
01084       omx_base_component_Private->ports[message->messageParam]->bIsTransientToEnabled = OMX_TRUE;
01085     }
01086     break;
01087   case OMX_CommandMarkBuffer:
01088     if (nParam >= omx_base_component_Private->sPortTypesParam.nPorts && nParam != OMX_ALL) {
01089       return OMX_ErrorBadPortIndex;
01090     }
01091     message->messageType = OMX_CommandMarkBuffer;
01092     break;
01093   default:
01094     err = OMX_ErrorUnsupportedIndex;
01095     break;
01096   }
01097 
01098   if (err == OMX_ErrorNone)
01099   {
01100     queue(messageQueue, message);
01101     tsem_up(messageSem);
01102   }
01103 
01104   DEBUG(DEB_LEV_FULL_SEQ, "In %s messageSem up param=%d\n", __func__,message->messageParam);
01105 
01106   return err;
01107 }
01108 
01115 void* compMessageHandlerFunction(void* param) {
01116   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)param;
01117   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
01118   internalRequestMessageType *message;
01119 
01120   while(1){
01121     /* Wait for an incoming message */
01122     if (omx_base_component_Private == NULL) {
01123       break;
01124     }
01125     tsem_down(omx_base_component_Private->messageSem);
01126     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
01127     /*Destructor has been called. So exit from the loop*/
01128     if(omx_base_component_Private->state == OMX_StateInvalid) {
01129       break;
01130     }
01131     /* Dequeue it */
01132     message = dequeue(omx_base_component_Private->messageQueue);
01133     if(message == NULL){
01134       DEBUG(DEB_LEV_ERR, "In %s: ouch!! had null message!\n", __func__);
01135       break;
01136     }
01137     /* Process it by calling component's message handler method */
01138     omx_base_component_Private->messageHandler(openmaxStandComp,message);
01139     /* Message ownership has been transferred to us
01140     * so we gonna free it when finished.
01141     */
01142     free(message);
01143     message = NULL;
01144   }
01145   DEBUG(DEB_LEV_FUNCTION_NAME,"Exiting Message Handler thread\n");
01146   return NULL;
01147 }
01148 
01160 OMX_ERRORTYPE omx_base_component_MessageHandler(OMX_COMPONENTTYPE *openmaxStandComp,internalRequestMessageType* message) {
01161   omx_base_component_PrivateType* omx_base_component_Private=openmaxStandComp->pComponentPrivate;
01162   OMX_U32 i,j;
01163   OMX_ERRORTYPE err = OMX_ErrorNone;
01164   omx_base_PortType* pPort;
01165 
01166   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
01167 
01168   /* Dealing with a SendCommand call.
01169   * -messageType contains the command to execute
01170   * -messageParam contains the parameter of the command
01171   *  (destination state in case of a state change command).
01172   */
01173   switch(message->messageType){
01174   case OMX_CommandStateSet: {
01175     /* Do the actual state change */
01176     err = (*(omx_base_component_Private->DoStateSet))(openmaxStandComp, message->messageParam);        
01177     if (err != OMX_ErrorNone) {
01178       (*(omx_base_component_Private->callbacks->EventHandler))
01179       (openmaxStandComp,
01180       omx_base_component_Private->callbackData,
01181       OMX_EventError, /* The command was completed */
01182       err, /* The commands was a OMX_CommandStateSet */
01183       0, /* The state has been changed in message->messageParam */
01184       NULL);
01185     } else {
01186       /* And run the callback */
01187       DEBUG(DEB_LEV_FULL_SEQ,"running callback in %s\n",__func__);
01188       (*(omx_base_component_Private->callbacks->EventHandler))
01189       (openmaxStandComp,
01190       omx_base_component_Private->callbackData,
01191       OMX_EventCmdComplete, /* The command was completed */
01192       OMX_CommandStateSet, /* The commands was a OMX_CommandStateSet */
01193       message->messageParam, /* The state has been changed in message->messageParam */
01194       NULL);
01195     }
01196   }
01197   break;
01198   case OMX_CommandFlush: {
01199     /*Flush port/s*/
01200     if(message->messageParam == OMX_ALL) {
01201       for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01202         omx_base_component_Private->ports[i]->bIsPortFlushed = OMX_TRUE;
01203       }
01204       for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01205         pPort=omx_base_component_Private->ports[i];
01206         err = pPort->FlushProcessingBuffers(pPort);
01207       }
01208     }
01209     else {
01210       pPort=omx_base_component_Private->ports[message->messageParam];
01211       err = pPort->FlushProcessingBuffers(pPort);
01212     }
01213     if (err != OMX_ErrorNone) {
01214       (*(omx_base_component_Private->callbacks->EventHandler))
01215       (openmaxStandComp,
01216       omx_base_component_Private->callbackData,
01217       OMX_EventError, /* The command was completed */
01218       err, /* The commands was a OMX_CommandStateSet */
01219       0, /* The state has been changed in message->messageParam */
01220       NULL);
01221     } else {
01222       if(message->messageParam == OMX_ALL){ /*Flush all port*/
01223         for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
01224           (*(omx_base_component_Private->callbacks->EventHandler))
01225           (openmaxStandComp,
01226           omx_base_component_Private->callbackData,
01227           OMX_EventCmdComplete, /* The command was completed */
01228           OMX_CommandFlush, /* The commands was a OMX_CommandStateSet */
01229           i, /* The state has been changed in message->messageParam */
01230           NULL);
01231         }    
01232         for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
01233           /* Signal the buffer Semaphore and the buffer managment semaphore, to restart the exchange of buffers after flush */
01234           if (PORT_IS_TUNNELED(omx_base_component_Private->ports[i]) && PORT_IS_BUFFER_SUPPLIER(omx_base_component_Private->ports[i])) {
01235             for(j=0;j<omx_base_component_Private->ports[i]->nNumTunnelBuffer;j++) {
01236               tsem_up(omx_base_component_Private->ports[i]->pBufferSem);
01237               /*signal buffer management thread availability of buffers*/
01238               tsem_up(omx_base_component_Private->bMgmtSem);
01239             }
01240           }
01241         }    
01242       } else {/*Flush input/output port*/
01243         (*(omx_base_component_Private->callbacks->EventHandler))
01244         (openmaxStandComp,
01245         omx_base_component_Private->callbackData,
01246         OMX_EventCmdComplete, /* The command was completed */
01247         OMX_CommandFlush, /* The commands was a OMX_CommandStateSet */
01248         message->messageParam, /* The state has been changed in message->messageParam */
01249         NULL);
01250         /* Signal the buffer Semaphore and the buffer managment semaphore, to restart the exchange of buffers after flush */
01251         if (PORT_IS_TUNNELED(omx_base_component_Private->ports[message->messageParam])
01252              && PORT_IS_BUFFER_SUPPLIER(omx_base_component_Private->ports[message->messageParam])) {
01253             for(j=0;j<omx_base_component_Private->ports[message->messageParam]->nNumTunnelBuffer;j++) {
01254               tsem_up(omx_base_component_Private->ports[message->messageParam]->pBufferSem);
01255               /*signal buffer management thread availability of buffers*/
01256               tsem_up(omx_base_component_Private->bMgmtSem);
01257             }
01258         }
01259       }
01260     }
01261   }
01262   break;
01263   case OMX_CommandPortDisable: {
01264     /*Flush port/s*/
01265     if(message->messageParam == OMX_ALL) {
01266       /*If Component is not in loaded state,then First Flush all buffers then disable the port*/
01267       if(omx_base_component_Private->state!=OMX_StateLoaded) {
01268         for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01269           pPort=omx_base_component_Private->ports[i];
01270           err = pPort->FlushProcessingBuffers(pPort);
01271         }
01272       }
01273       for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01274         pPort=omx_base_component_Private->ports[i];
01275         err = pPort->Port_DisablePort(pPort);
01276       }
01277     }
01278     else {
01279       pPort=omx_base_component_Private->ports[message->messageParam];
01280       if(omx_base_component_Private->state!=OMX_StateLoaded) {
01281         err = pPort->FlushProcessingBuffers(pPort);
01282         DEBUG(DEB_LEV_FULL_SEQ, "In %s: Port Flush completed for Comp %s\n",__func__,omx_base_component_Private->name);
01283       }
01284       err = pPort->Port_DisablePort(pPort);
01285     }
01287     if (err != OMX_ErrorNone) {
01288       (*(omx_base_component_Private->callbacks->EventHandler))
01289       (openmaxStandComp,
01290       omx_base_component_Private->callbackData,
01291       OMX_EventError, /* The command was completed */
01292       err, /* The commands was a OMX_CommandStateSet */
01293       0, /* The state has been changed in message->messageParam */
01294       NULL);
01295     } else {
01296       if(message->messageParam == OMX_ALL){ /*Disable all ports*/
01297         for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
01298           (*(omx_base_component_Private->callbacks->EventHandler))
01299           (openmaxStandComp,
01300           omx_base_component_Private->callbackData,
01301           OMX_EventCmdComplete, /* The command was completed */
01302           OMX_CommandPortDisable, /* The commands was a OMX_CommandStateSet */
01303           i, /* The state has been changed in message->messageParam */
01304           NULL);
01305         }
01306       } else {
01307         (*(omx_base_component_Private->callbacks->EventHandler))
01308         (openmaxStandComp,
01309         omx_base_component_Private->callbackData,
01310         OMX_EventCmdComplete, /* The command was completed */
01311         OMX_CommandPortDisable, /* The commands was a OMX_CommandStateSet */
01312         message->messageParam, /* The state has been changed in message->messageParam */
01313         NULL);
01314       }           
01315     }
01316   }
01317   break;
01318   case OMX_CommandPortEnable:{
01319     /*Flush port/s*/
01320     if(message->messageParam == OMX_ALL) {
01321       for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01322         pPort=omx_base_component_Private->ports[i];
01323         err = pPort->Port_EnablePort(pPort);
01324         }
01325     } else {
01326       pPort=omx_base_component_Private->ports[message->messageParam];
01327       err = pPort->Port_EnablePort(pPort);
01328     }
01329     if (err != OMX_ErrorNone) {
01330       (*(omx_base_component_Private->callbacks->EventHandler))
01331       (openmaxStandComp,
01332       omx_base_component_Private->callbackData,
01333       OMX_EventError, /* The command was completed */
01334       err, /* The commands was a OMX_CommandStateSet */
01335       0, /* The state has been changed in message->messageParam */
01336       NULL);
01337     } else {
01338       if(message->messageParam != OMX_ALL) {
01339         (*(omx_base_component_Private->callbacks->EventHandler))
01340         (openmaxStandComp,
01341         omx_base_component_Private->callbackData,
01342         OMX_EventCmdComplete, /* The command was completed */
01343         OMX_CommandPortEnable, /* The commands was a OMX_CommandStateSet */
01344         message->messageParam, /* The state has been changed in message->messageParam */
01345         NULL);
01346 
01347         if (omx_base_component_Private->state==OMX_StateExecuting) {
01348           pPort=omx_base_component_Private->ports[message->messageParam];
01349           if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
01350             for(i=0; i < pPort->sPortParam.nBufferCountActual;i++) {
01351               tsem_up(pPort->pBufferSem);
01352               tsem_up(omx_base_component_Private->bMgmtSem);
01353             }
01354           }
01355         }
01356 
01357       } else {
01358         for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
01359           (*(omx_base_component_Private->callbacks->EventHandler))
01360           (openmaxStandComp,
01361           omx_base_component_Private->callbackData,
01362           OMX_EventCmdComplete, /* The command was completed */
01363           OMX_CommandPortEnable, /* The commands was a OMX_CommandStateSet */
01364           i, /* The state has been changed in message->messageParam */
01365           NULL);
01366         }
01367 
01368         if (omx_base_component_Private->state==OMX_StateExecuting) {
01369           for(i=0;i<omx_base_component_Private->sPortTypesParam.nPorts;i++) {
01370             pPort=omx_base_component_Private->ports[i];
01371             if (PORT_IS_BUFFER_SUPPLIER(pPort)) {
01372               for(i=0; i < pPort->sPortParam.nBufferCountActual;i++) {
01373                 tsem_up(pPort->pBufferSem);
01374                 tsem_up(omx_base_component_Private->bMgmtSem);
01375               }
01376             }
01377           }
01378         }
01379       }
01380     }
01381   }
01382   break;
01383   case OMX_CommandMarkBuffer: {
01384     omx_base_component_Private->pMark=(OMX_MARKTYPE *)message->pCmdData;
01385   }
01386   break;
01387   default:
01388     DEBUG(DEB_LEV_ERR, "In %s: Unrecognized command %i\n", __func__, message->messageType);
01389   break;
01390   }
01391   DEBUG(DEB_LEV_SIMPLE_SEQ, "Returning from %s: \n", __func__);
01392   return OMX_ErrorNone;
01393 }
01394 
01395 OMX_ERRORTYPE omx_base_component_AllocateBuffer(
01396             OMX_IN OMX_HANDLETYPE hComponent,
01397             OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
01398             OMX_IN OMX_U32 nPortIndex,
01399             OMX_IN OMX_PTR pAppPrivate,
01400             OMX_IN OMX_U32 nSizeBytes) {
01401   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
01402   omx_base_PortType *pPort;
01403 
01404   if (nPortIndex >= omx_base_component_Private->sPortTypesParam.nPorts) {
01405     DEBUG(DEB_LEV_ERR, "In %s: wrong port index\n", __func__);
01406     return OMX_ErrorBadPortIndex;
01407   }
01408   pPort = omx_base_component_Private->ports[nPortIndex];
01409 
01410   return pPort->Port_AllocateBuffer(pPort,
01411                                     ppBuffer,
01412                                     nPortIndex,
01413                                     pAppPrivate,
01414                                     nSizeBytes);
01415 }
01416 
01417 OMX_ERRORTYPE omx_base_component_UseBuffer(
01418             OMX_IN OMX_HANDLETYPE hComponent,
01419             OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
01420             OMX_IN OMX_U32 nPortIndex,
01421             OMX_IN OMX_PTR pAppPrivate,
01422             OMX_IN OMX_U32 nSizeBytes,
01423             OMX_IN OMX_U8* pBuffer) {
01424   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
01425   omx_base_PortType *pPort;
01426 
01427   if (nPortIndex >= omx_base_component_Private->sPortTypesParam.nPorts) {
01428     DEBUG(DEB_LEV_ERR, "In %s: wrong port index\n", __func__);
01429     return OMX_ErrorBadPortIndex;
01430   }
01431   pPort = omx_base_component_Private->ports[nPortIndex];
01432 
01433   return  pPort->Port_UseBuffer(pPort,
01434                                 ppBufferHdr,
01435                                 nPortIndex,
01436                                 pAppPrivate,
01437                                 nSizeBytes,
01438                                 pBuffer);
01439 }
01440 
01441 OMX_ERRORTYPE omx_base_component_UseEGLImage (
01442         OMX_HANDLETYPE hComponent,
01443         OMX_BUFFERHEADERTYPE** ppBufferHdr,
01444         OMX_U32 nPortIndex,
01445         OMX_PTR pAppPrivate,
01446         void* eglImage) {
01447   return OMX_ErrorNotImplemented;
01448 }
01449 
01450 OMX_ERRORTYPE omx_base_component_FreeBuffer(   
01451             OMX_IN  OMX_HANDLETYPE hComponent,
01452             OMX_IN  OMX_U32 nPortIndex,
01453             OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer) {
01454   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
01455   omx_base_PortType *pPort;
01456 
01457   if (nPortIndex >= omx_base_component_Private->sPortTypesParam.nPorts) {
01458     DEBUG(DEB_LEV_ERR, "In %s: wrong port index\n", __func__);
01459     return OMX_ErrorBadPortIndex;
01460   }
01461   pPort = omx_base_component_Private->ports[nPortIndex];
01462 
01463   return pPort->Port_FreeBuffer(pPort,
01464                                 nPortIndex,
01465                                 pBuffer);
01466 }
01467   
01468 OMX_ERRORTYPE omx_base_component_EmptyThisBuffer(
01469             OMX_IN  OMX_HANDLETYPE hComponent,
01470             OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer) {
01471   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
01472   omx_base_PortType *pPort;
01473   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
01474 
01475   if (pBuffer->nInputPortIndex >= omx_base_component_Private->sPortTypesParam.nPorts) {
01476     DEBUG(DEB_LEV_ERR, "In %s: wrong port index\n", __func__);
01477     return OMX_ErrorBadPortIndex;
01478   }
01479   pPort = omx_base_component_Private->ports[pBuffer->nInputPortIndex];
01480   if (pPort->sPortParam.eDir != OMX_DirInput) {
01481     DEBUG(DEB_LEV_ERR, "In %s: wrong port direction in Component %s\n", __func__,omx_base_component_Private->name);
01482     return OMX_ErrorBadPortIndex;
01483   }
01484   return pPort->Port_SendBufferFunction(pPort, pBuffer);
01485 }
01486 
01487 OMX_ERRORTYPE omx_base_component_FillThisBuffer(
01488   OMX_IN  OMX_HANDLETYPE hComponent,
01489   OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer) {
01490 
01491   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
01492   omx_base_PortType *pPort;
01493   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
01494   if (pBuffer->nOutputPortIndex >= omx_base_component_Private->sPortTypesParam.nPorts) {
01495     DEBUG(DEB_LEV_ERR, "In %s: wrong port index\n", __func__);
01496     return OMX_ErrorBadPortIndex;
01497   }
01498   pPort = omx_base_component_Private->ports[pBuffer->nOutputPortIndex];
01499   if (pPort->sPortParam.eDir != OMX_DirOutput) {
01500     DEBUG(DEB_LEV_ERR, "In %s: wrong port direction in Component %s\n", __func__,omx_base_component_Private->name);
01501     return OMX_ErrorBadPortIndex;
01502   }
01503   return pPort->Port_SendBufferFunction(pPort,  pBuffer);
01504 }
01505 
01506 OMX_ERRORTYPE omx_base_component_ComponentTunnelRequest(
01507   OMX_IN  OMX_HANDLETYPE hComponent,
01508   OMX_IN  OMX_U32 nPort,
01509   OMX_IN  OMX_HANDLETYPE hTunneledComp,
01510   OMX_IN  OMX_U32 nTunneledPort,
01511   OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup) {
01512 
01513   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
01514   omx_base_PortType *pPort; 
01515   
01516   if (nPort >= omx_base_component_Private->sPortTypesParam.nPorts) {
01517     return OMX_ErrorBadPortIndex;
01518   }
01519   
01520   pPort = omx_base_component_Private->ports[nPort];
01521 
01522   return pPort->ComponentTunnelRequest(pPort, hTunneledComp, nTunneledPort, pTunnelSetup);
01523 }
01524 #ifdef __cplusplus
01525 }
01526 #endif
01527 

Generated for OpenMAX Bellagio rel. 0.3.5-svn by  doxygen 1.5.1
SourceForge.net Logo