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
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
00174 tsem_up(omx_base_component_Private->messageSem);
00175
00176
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00595 strcpy(pComponentName, omx_base_component_Private->name);
00596
00597
00598 pComponentVersion->s.nVersionMajor = SPECVERSIONMAJOR;
00599 pComponentVersion->s.nVersionMinor = SPECVERSIONMINOR;
00600 pComponentVersion->s.nRevision = SPECREVISION;
00601 pComponentVersion->s.nStep = SPECSTEP;
00602
00603
00604 memcpy(pSpecVersion, &omx_component->nVersion, sizeof(OMX_VERSIONTYPE));
00605
00606
00607
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
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
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
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
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
01128 if(omx_base_component_Private->state == OMX_StateInvalid) {
01129 break;
01130 }
01131
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
01138 omx_base_component_Private->messageHandler(openmaxStandComp,message);
01139
01140
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
01169
01170
01171
01172
01173 switch(message->messageType){
01174 case OMX_CommandStateSet: {
01175
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,
01182 err,
01183 0,
01184 NULL);
01185 } else {
01186
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,
01192 OMX_CommandStateSet,
01193 message->messageParam,
01194 NULL);
01195 }
01196 }
01197 break;
01198 case OMX_CommandFlush: {
01199
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,
01218 err,
01219 0,
01220 NULL);
01221 } else {
01222 if(message->messageParam == OMX_ALL){
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,
01228 OMX_CommandFlush,
01229 i,
01230 NULL);
01231 }
01232 for (i = 0; i < omx_base_component_Private->sPortTypesParam.nPorts; i++) {
01233
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
01238 tsem_up(omx_base_component_Private->bMgmtSem);
01239 }
01240 }
01241 }
01242 } else {
01243 (*(omx_base_component_Private->callbacks->EventHandler))
01244 (openmaxStandComp,
01245 omx_base_component_Private->callbackData,
01246 OMX_EventCmdComplete,
01247 OMX_CommandFlush,
01248 message->messageParam,
01249 NULL);
01250
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
01256 tsem_up(omx_base_component_Private->bMgmtSem);
01257 }
01258 }
01259 }
01260 }
01261 }
01262 break;
01263 case OMX_CommandPortDisable: {
01264
01265 if(message->messageParam == OMX_ALL) {
01266
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,
01292 err,
01293 0,
01294 NULL);
01295 } else {
01296 if(message->messageParam == OMX_ALL){
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,
01302 OMX_CommandPortDisable,
01303 i,
01304 NULL);
01305 }
01306 } else {
01307 (*(omx_base_component_Private->callbacks->EventHandler))
01308 (openmaxStandComp,
01309 omx_base_component_Private->callbackData,
01310 OMX_EventCmdComplete,
01311 OMX_CommandPortDisable,
01312 message->messageParam,
01313 NULL);
01314 }
01315 }
01316 }
01317 break;
01318 case OMX_CommandPortEnable:{
01319
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,
01334 err,
01335 0,
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,
01343 OMX_CommandPortEnable,
01344 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,
01363 OMX_CommandPortEnable,
01364 i,
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