|
OpenMAXBellagio 0.9.3
|
00001 00026 #include <string.h> 00027 #include <unistd.h> 00028 #include <omxcore.h> 00029 #include <OMX_Core.h> 00030 #include <OMX_Component.h> 00031 00032 #include "omx_base_component.h" 00033 #include "omx_base_port.h" 00034 00036 #define DEFAULT_NUMBER_BUFFERS_PER_PORT 2 00037 00038 #define DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT 2 00039 00055 OMX_ERRORTYPE base_port_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,omx_base_PortType **openmaxStandPort,OMX_U32 nPortIndex, OMX_BOOL isInput) { 00056 00057 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for component %p\n", __func__, openmaxStandComp); 00058 00059 // create ports, but only if the subclass hasn't done it 00060 if (!(*openmaxStandPort)) { 00061 *openmaxStandPort = calloc(1,sizeof (omx_base_PortType)); 00062 } 00063 00064 if (!(*openmaxStandPort)) { 00065 DEBUG(DEB_LEV_ERR, "Out of %s for component %p for a lack of resources\n", __func__, openmaxStandComp); 00066 return OMX_ErrorInsufficientResources; 00067 } 00068 00069 (*openmaxStandPort)->hTunneledComponent = NULL; 00070 (*openmaxStandPort)->nTunnelFlags=0; 00071 (*openmaxStandPort)->nTunneledPort=0; 00072 (*openmaxStandPort)->eBufferSupplier=OMX_BufferSupplyUnspecified; 00073 (*openmaxStandPort)->nNumTunnelBuffer=0; 00074 00075 if((*openmaxStandPort)->pAllocSem==NULL) { 00076 (*openmaxStandPort)->pAllocSem = calloc(1,sizeof(tsem_t)); 00077 if((*openmaxStandPort)->pAllocSem==NULL) { 00078 return OMX_ErrorInsufficientResources; 00079 } 00080 tsem_init((*openmaxStandPort)->pAllocSem, 0); 00081 } 00082 (*openmaxStandPort)->nNumBufferFlushed=0; 00083 (*openmaxStandPort)->bIsPortFlushed=OMX_FALSE; 00085 if(!(*openmaxStandPort)->pBufferQueue) { 00086 (*openmaxStandPort)->pBufferQueue = calloc(1,sizeof(queue_t)); 00087 if((*openmaxStandPort)->pBufferQueue==NULL) return OMX_ErrorInsufficientResources; 00088 queue_init((*openmaxStandPort)->pBufferQueue); 00089 } 00090 /*Allocate and initialise port semaphores*/ 00091 if(!(*openmaxStandPort)->pBufferSem) { 00092 (*openmaxStandPort)->pBufferSem = calloc(1,sizeof(tsem_t)); 00093 if((*openmaxStandPort)->pBufferSem==NULL) return OMX_ErrorInsufficientResources; 00094 tsem_init((*openmaxStandPort)->pBufferSem, 0); 00095 } 00096 00097 (*openmaxStandPort)->nNumAssignedBuffers=0; 00098 setHeader(&(*openmaxStandPort)->sPortParam, sizeof (OMX_PARAM_PORTDEFINITIONTYPE)); 00099 (*openmaxStandPort)->sPortParam.nPortIndex = nPortIndex; 00100 (*openmaxStandPort)->sPortParam.nBufferCountActual = DEFAULT_NUMBER_BUFFERS_PER_PORT; 00101 (*openmaxStandPort)->sPortParam.nBufferCountMin = DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT; 00102 (*openmaxStandPort)->sPortParam.bEnabled = OMX_TRUE; 00103 (*openmaxStandPort)->sPortParam.bPopulated = OMX_FALSE; 00104 (*openmaxStandPort)->sPortParam.eDir = (isInput == OMX_TRUE)?OMX_DirInput:OMX_DirOutput; 00105 00106 (*openmaxStandPort)->standCompContainer=openmaxStandComp; 00107 (*openmaxStandPort)->bIsTransientToEnabled=OMX_FALSE; 00108 (*openmaxStandPort)->bIsTransientToDisabled=OMX_FALSE; 00109 (*openmaxStandPort)->bIsFullOfBuffers=OMX_FALSE; 00110 (*openmaxStandPort)->bIsEmptyOfBuffers=OMX_FALSE; 00111 (*openmaxStandPort)->bBufferStateAllocated = NULL; 00112 (*openmaxStandPort)->pInternalBufferStorage = NULL; 00113 00114 (*openmaxStandPort)->PortDestructor = &base_port_Destructor; 00115 (*openmaxStandPort)->Port_AllocateBuffer = &base_port_AllocateBuffer; 00116 (*openmaxStandPort)->Port_UseBuffer = &base_port_UseBuffer; 00117 (*openmaxStandPort)->Port_FreeBuffer = &base_port_FreeBuffer; 00118 (*openmaxStandPort)->Port_DisablePort = &base_port_DisablePort; 00119 (*openmaxStandPort)->Port_EnablePort = &base_port_EnablePort; 00120 (*openmaxStandPort)->Port_SendBufferFunction = &base_port_SendBufferFunction; 00121 (*openmaxStandPort)->FlushProcessingBuffers = &base_port_FlushProcessingBuffers; 00122 (*openmaxStandPort)->ReturnBufferFunction = &base_port_ReturnBufferFunction; 00123 (*openmaxStandPort)->ComponentTunnelRequest = &base_port_ComponentTunnelRequest; 00124 (*openmaxStandPort)->Port_AllocateTunnelBuffer = &base_port_AllocateTunnelBuffer; 00125 (*openmaxStandPort)->Port_FreeTunnelBuffer = &base_port_FreeTunnelBuffer; 00126 (*openmaxStandPort)->bIsDestroying = OMX_FALSE; 00127 pthread_mutex_init(&((*openmaxStandPort)->exitMutex), NULL); 00128 00129 00130 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for component %p\n", __func__, openmaxStandComp); 00131 return OMX_ErrorNone; 00132 } 00133 00134 OMX_ERRORTYPE base_port_Destructor(omx_base_PortType *openmaxStandPort){ 00135 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00136 00137 if(openmaxStandPort->pAllocSem) { 00138 pthread_mutex_lock(&openmaxStandPort->exitMutex); 00139 openmaxStandPort->bIsDestroying = OMX_TRUE; 00140 pthread_mutex_unlock(&openmaxStandPort->exitMutex); 00147 tsem_deinit(openmaxStandPort->pAllocSem); 00148 free(openmaxStandPort->pAllocSem); 00149 openmaxStandPort->pAllocSem=NULL; 00150 } 00152 if(openmaxStandPort->pBufferQueue) { 00153 queue_deinit(openmaxStandPort->pBufferQueue); 00154 free(openmaxStandPort->pBufferQueue); 00155 openmaxStandPort->pBufferQueue=NULL; 00156 } 00157 /*Allocate and initialize port semaphores*/ 00158 if(openmaxStandPort->pBufferSem) { 00159 tsem_deinit(openmaxStandPort->pBufferSem); 00160 free(openmaxStandPort->pBufferSem); 00161 openmaxStandPort->pBufferSem=NULL; 00162 } 00163 00164 pthread_mutex_destroy(&openmaxStandPort->exitMutex); 00165 00166 free(openmaxStandPort); 00167 openmaxStandPort = NULL; 00168 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00169 return OMX_ErrorNone; 00170 } 00171 00176 OMX_ERRORTYPE base_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort) { 00177 omx_base_component_PrivateType* omx_base_component_Private; 00178 OMX_BUFFERHEADERTYPE* pBuffer; 00179 int errQue; 00180 00181 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00182 omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate; 00183 00184 if(openmaxStandPort->sPortParam.eDomain!=OMX_PortDomainOther) { /* clock buffers not used in the clients buffer managment function */ 00185 pthread_mutex_lock(&omx_base_component_Private->flush_mutex); 00186 openmaxStandPort->bIsPortFlushed=OMX_TRUE; 00187 /*Signal the buffer management thread of port flush,if it is waiting for buffers*/ 00188 if(omx_base_component_Private->bMgmtSem->semval==0) { 00189 tsem_up(omx_base_component_Private->bMgmtSem); 00190 } 00191 00192 if(omx_base_component_Private->state != OMX_StateExecuting ) { 00193 /*Waiting at paused state*/ 00194 tsem_signal(omx_base_component_Private->bStateSem); 00195 } 00196 DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex); 00197 /* Wait until flush is completed */ 00198 pthread_mutex_unlock(&omx_base_component_Private->flush_mutex); 00199 tsem_down(omx_base_component_Private->flush_all_condition); 00200 } 00201 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s flushed all the buffers under processing\n", __func__); 00202 00203 tsem_reset(omx_base_component_Private->bMgmtSem); 00204 00205 /* Flush all the buffers not under processing */ 00206 while (openmaxStandPort->pBufferSem->semval > 0) { 00207 DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n", 00208 __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex, 00209 (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem); 00210 00211 tsem_down(openmaxStandPort->pBufferSem); 00212 pBuffer = dequeue(openmaxStandPort->pBufferQueue); 00213 if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) { 00214 DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n", 00215 __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex); 00216 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { 00217 ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); 00218 } else { 00219 ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); 00220 } 00221 } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { 00222 errQue = queue(openmaxStandPort->pBufferQueue,pBuffer); 00223 if (errQue) { 00224 /* /TODO the queue is full. This can be handled in a fine way with 00225 * some retrials, or other checking. For the moment this is a critical error 00226 * and simply causes the failure of this call 00227 */ 00228 return OMX_ErrorInsufficientResources; 00229 } 00230 } else { 00231 (*(openmaxStandPort->BufferProcessedCallback))( 00232 openmaxStandPort->standCompContainer, 00233 omx_base_component_Private->callbackData, 00234 pBuffer); 00235 } 00236 } 00237 /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/ 00238 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { 00239 while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){ 00240 tsem_down(openmaxStandPort->pBufferSem); 00241 DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem); 00242 } 00243 tsem_reset(openmaxStandPort->pBufferSem); 00244 } 00245 00246 pthread_mutex_lock(&omx_base_component_Private->flush_mutex); 00247 openmaxStandPort->bIsPortFlushed=OMX_FALSE; 00248 pthread_mutex_unlock(&omx_base_component_Private->flush_mutex); 00249 00250 tsem_up(omx_base_component_Private->flush_condition); 00251 00252 DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__, 00253 (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_base_component_Private->name); 00254 00255 DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__, 00256 (int)openmaxStandPort->nTunnelFlags, 00257 (int)openmaxStandPort->pBufferQueue->nelem, 00258 (int)openmaxStandPort->pBufferSem->semval, 00259 (int)omx_base_component_Private->bMgmtSem->semval, 00260 omx_base_component_Private->name); 00261 00262 DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port %p Index=%d\n", __func__, openmaxStandPort, (int)openmaxStandPort->sPortParam.nPortIndex); 00263 return OMX_ErrorNone; 00264 } 00265 00273 OMX_ERRORTYPE base_port_DisablePort(omx_base_PortType *openmaxStandPort) { 00274 omx_base_component_PrivateType* omx_base_component_Private; 00275 OMX_ERRORTYPE err=OMX_ErrorNone; 00276 00277 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Port %p Index=%d\n", __func__, openmaxStandPort, (int)openmaxStandPort->sPortParam.nPortIndex); 00278 omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate; 00279 if (! PORT_IS_ENABLED(openmaxStandPort)) { 00280 return OMX_ErrorNone; 00281 } 00282 00283 if(omx_base_component_Private->state!=OMX_StateLoaded) { 00284 if(!PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) { 00285 /*Signal Buffer Mgmt Thread if it's holding any buffer*/ 00286 if(omx_base_component_Private->bMgmtSem->semval==0) { 00287 tsem_up(omx_base_component_Private->bMgmtSem); 00288 } 00289 /*Wait till all buffers are freed*/ 00290 tsem_down(openmaxStandPort->pAllocSem); 00291 tsem_reset(omx_base_component_Private->bMgmtSem); 00292 } else { 00293 /*Since port is being disabled then remove buffers from the queue*/ 00294 while(openmaxStandPort->pBufferQueue->nelem > 0) { 00295 dequeue(openmaxStandPort->pBufferQueue); 00296 } 00297 00298 err = openmaxStandPort->Port_FreeTunnelBuffer(openmaxStandPort,openmaxStandPort->sPortParam.nPortIndex); 00299 if(err!=OMX_ErrorNone) { 00300 DEBUG(DEB_LEV_ERR, "In %s Freeing Tunnel Buffer Error=%x\n",__func__,err); 00301 } 00302 DEBUG(DEB_LEV_PARAMS, "In %s Qelem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem); 00303 } 00304 } 00305 00306 DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__, 00307 (int)openmaxStandPort->nTunnelFlags, 00308 (int)openmaxStandPort->pBufferQueue->nelem, 00309 (int)openmaxStandPort->pBufferSem->semval, 00310 (int)omx_base_component_Private->bMgmtSem->semval, 00311 omx_base_component_Private->name); 00312 openmaxStandPort->bIsTransientToDisabled = OMX_FALSE; 00313 openmaxStandPort->sPortParam.bEnabled = OMX_FALSE; 00314 DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d isEnabled=%d\n", __func__, 00315 (int)openmaxStandPort->sPortParam.nPortIndex, 00316 (int)openmaxStandPort->sPortParam.bEnabled); 00317 return err; 00318 } 00319 00327 OMX_ERRORTYPE base_port_EnablePort(omx_base_PortType *openmaxStandPort) { 00328 omx_base_component_PrivateType* omx_base_component_Private; 00329 OMX_ERRORTYPE err=OMX_ErrorNone; 00330 OMX_U32 i; 00331 00332 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00333 if (PORT_IS_ENABLED(openmaxStandPort)) { 00334 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00335 return OMX_ErrorNone; 00336 } 00337 omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate; 00338 00339 openmaxStandPort->sPortParam.bEnabled = OMX_TRUE; 00340 00341 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s port T flag=%x popu=%d state=%x\n", __func__, 00342 (int)openmaxStandPort->nTunnelFlags, 00343 (int)openmaxStandPort->sPortParam.bPopulated, 00344 (int)omx_base_component_Private->state); 00345 00346 00347 if (!PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) { 00348 /*Wait Till All buffers are allocated if the component state is not Loaded*/ 00349 if (omx_base_component_Private->state!=OMX_StateLoaded && omx_base_component_Private->state!=OMX_StateWaitForResources) { 00350 tsem_down(openmaxStandPort->pAllocSem); 00351 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; 00352 } 00353 } else { //Port Tunneled and supplier. Then allocate tunnel buffers 00354 err= openmaxStandPort->Port_AllocateTunnelBuffer(openmaxStandPort, openmaxStandPort->sPortParam.nPortIndex); 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 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; 00360 if (omx_base_component_Private->state==OMX_StateExecuting) { 00361 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual;i++) { 00362 tsem_up(openmaxStandPort->pBufferSem); 00363 tsem_up(omx_base_component_Private->bMgmtSem); 00364 } 00365 } 00366 DEBUG(DEB_LEV_PARAMS, "In %s Qelem=%d BSem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem,openmaxStandPort->pBufferSem->semval); 00367 } 00368 00369 openmaxStandPort->bIsTransientToEnabled = OMX_FALSE; 00370 00371 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00372 return OMX_ErrorNone; 00373 } 00374 00383 OMX_ERRORTYPE base_port_AllocateBuffer( 00384 omx_base_PortType *openmaxStandPort, 00385 OMX_BUFFERHEADERTYPE** pBuffer, 00386 OMX_U32 nPortIndex, 00387 OMX_PTR pAppPrivate, 00388 OMX_U32 nSizeBytes) { 00389 00390 unsigned int i; 00391 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; 00392 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; 00393 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00394 00395 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { 00396 return OMX_ErrorBadPortIndex; 00397 } 00398 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { 00399 return OMX_ErrorBadPortIndex; 00400 } 00401 00402 if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { 00403 if (!openmaxStandPort->bIsTransientToEnabled) { 00404 DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__); 00405 return OMX_ErrorIncorrectStateTransition; 00406 } 00407 } 00408 00409 if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) { 00410 DEBUG(DEB_LEV_ERR, "In %s: Requested Buffer Size %lu is less than Minimum Buffer Size %lu\n", __func__, nSizeBytes, openmaxStandPort->sPortParam.nBufferSize); 00411 return OMX_ErrorIncorrectStateTransition; 00412 } 00413 00414 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ 00415 if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) { 00416 openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE)); 00417 if (!openmaxStandPort->pInternalBufferStorage[i]) { 00418 return OMX_ErrorInsufficientResources; 00419 } 00420 setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE)); 00421 /* allocate the buffer */ 00422 openmaxStandPort->pInternalBufferStorage[i]->pBuffer = calloc(1,nSizeBytes); 00423 if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer==NULL) { 00424 return OMX_ErrorInsufficientResources; 00425 } 00426 openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes; 00427 openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort; 00428 openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate; 00429 *pBuffer = openmaxStandPort->pInternalBufferStorage[i]; 00430 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED; 00431 openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED; 00432 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { 00433 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00434 } else { 00435 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00436 } 00437 openmaxStandPort->nNumAssignedBuffers++; 00438 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); 00439 00440 if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) { 00441 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; 00442 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; 00443 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__,(int)nPortIndex); 00444 tsem_up(openmaxStandPort->pAllocSem); 00445 } 00446 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00447 return OMX_ErrorNone; 00448 } 00449 } 00450 DEBUG(DEB_LEV_ERR, "Out of %s for port %p. Error: no available buffers\n",__func__, openmaxStandPort); 00451 return OMX_ErrorInsufficientResources; 00452 } 00453 00462 OMX_ERRORTYPE base_port_UseBuffer( 00463 omx_base_PortType *openmaxStandPort, 00464 OMX_BUFFERHEADERTYPE** ppBufferHdr, 00465 OMX_U32 nPortIndex, 00466 OMX_PTR pAppPrivate, 00467 OMX_U32 nSizeBytes, 00468 OMX_U8* pBuffer) { 00469 00470 unsigned int i; 00471 OMX_BUFFERHEADERTYPE* returnBufferHeader; 00472 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; 00473 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; 00474 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00475 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { 00476 return OMX_ErrorBadPortIndex; 00477 } 00478 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { 00479 return OMX_ErrorBadPortIndex; 00480 } 00481 00482 if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { 00483 if (!openmaxStandPort->bIsTransientToEnabled) { 00484 DEBUG(DEB_LEV_ERR, "In %s: The port of Comp %s is not allowed to receive buffers\n", __func__,omx_base_component_Private->name); 00485 return OMX_ErrorIncorrectStateTransition; 00486 } 00487 } 00488 00489 if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) { 00490 DEBUG(DEB_LEV_ERR, "In %s: Port %d Given Buffer Size %u is less than Minimum Buffer Size %u\n", __func__, (int)nPortIndex, (int)nSizeBytes, (int)openmaxStandPort->sPortParam.nBufferSize); 00491 return OMX_ErrorIncorrectStateTransition; 00492 } 00493 00494 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ 00495 if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) { 00496 openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE)); 00497 if (!openmaxStandPort->pInternalBufferStorage[i]) { 00498 return OMX_ErrorInsufficientResources; 00499 } 00500 openmaxStandPort->bIsEmptyOfBuffers = OMX_FALSE; 00501 setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE)); 00502 00503 openmaxStandPort->pInternalBufferStorage[i]->pBuffer = pBuffer; 00504 openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes; 00505 openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort; 00506 openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate; 00507 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ASSIGNED; 00508 openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED; 00509 returnBufferHeader = calloc(1,sizeof(OMX_BUFFERHEADERTYPE)); 00510 if (!returnBufferHeader) { 00511 return OMX_ErrorInsufficientResources; 00512 } 00513 setHeader(returnBufferHeader, sizeof(OMX_BUFFERHEADERTYPE)); 00514 returnBufferHeader->pBuffer = pBuffer; 00515 returnBufferHeader->nAllocLen = nSizeBytes; 00516 returnBufferHeader->pPlatformPrivate = openmaxStandPort; 00517 returnBufferHeader->pAppPrivate = pAppPrivate; 00518 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { 00519 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00520 returnBufferHeader->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00521 } else { 00522 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00523 returnBufferHeader->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00524 } 00525 *ppBufferHdr = returnBufferHeader; 00526 openmaxStandPort->nNumAssignedBuffers++; 00527 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); 00528 00529 if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) { 00530 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; 00531 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; 00532 tsem_up(openmaxStandPort->pAllocSem); 00533 } 00534 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00535 return OMX_ErrorNone; 00536 } 00537 } 00538 DEBUG(DEB_LEV_ERR, "In %s Error: no available buffers CompName=%s\n",__func__,omx_base_component_Private->name); 00539 return OMX_ErrorInsufficientResources; 00540 } 00541 00547 OMX_ERRORTYPE base_port_FreeBuffer( 00548 omx_base_PortType *openmaxStandPort, 00549 OMX_U32 nPortIndex, 00550 OMX_BUFFERHEADERTYPE* pBuffer) { 00551 00552 unsigned int i; 00553 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; 00554 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; 00555 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00556 00557 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { 00558 return OMX_ErrorBadPortIndex; 00559 } 00560 if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { 00561 return OMX_ErrorBadPortIndex; 00562 } 00563 00564 if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) { 00565 if (!openmaxStandPort->bIsTransientToDisabled) { 00566 DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__); 00567 (*(omx_base_component_Private->callbacks->EventHandler)) 00568 (omxComponent, 00569 omx_base_component_Private->callbackData, 00570 OMX_EventError, /* The command was completed */ 00571 OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */ 00572 nPortIndex, /* The state has been changed in message->messageParam2 */ 00573 NULL); 00574 } 00575 } 00576 00577 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ 00578 if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) { 00579 00580 openmaxStandPort->bIsFullOfBuffers = OMX_FALSE; 00581 if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) { 00582 if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer){ 00583 DEBUG(DEB_LEV_PARAMS, "In %s freeing %i pBuffer=%p\n",__func__, (int)i, openmaxStandPort->pInternalBufferStorage[i]->pBuffer); 00584 free(openmaxStandPort->pInternalBufferStorage[i]->pBuffer); 00585 openmaxStandPort->pInternalBufferStorage[i]->pBuffer=NULL; 00586 } 00587 } else if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ASSIGNED) { 00588 free(pBuffer); 00589 } 00590 if(openmaxStandPort->bBufferStateAllocated[i] & HEADER_ALLOCATED) { 00591 free(openmaxStandPort->pInternalBufferStorage[i]); 00592 openmaxStandPort->pInternalBufferStorage[i]=NULL; 00593 } 00594 00595 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE; 00596 00597 openmaxStandPort->nNumAssignedBuffers--; 00598 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); 00599 00600 if (openmaxStandPort->nNumAssignedBuffers == 0) { 00601 openmaxStandPort->sPortParam.bPopulated = OMX_FALSE; 00602 openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE; 00603 tsem_up(openmaxStandPort->pAllocSem); 00604 } 00605 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00606 return OMX_ErrorNone; 00607 } 00608 } 00609 DEBUG(DEB_LEV_ERR, "Out of %s for port %p with OMX_ErrorInsufficientResources\n", __func__, openmaxStandPort); 00610 return OMX_ErrorInsufficientResources; 00611 } 00612 00613 OMX_ERRORTYPE base_port_AllocateTunnelBuffer( 00614 omx_base_PortType *openmaxStandPort, 00615 OMX_U32 nPortIndex) 00616 { 00617 unsigned int i; 00618 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; 00619 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; 00620 OMX_U8* pBuffer=NULL; 00621 OMX_ERRORTYPE eError=OMX_ErrorNone,err; 00622 int errQue; 00623 OMX_U32 numRetry=0,nBufferSize; 00624 OMX_PARAM_PORTDEFINITIONTYPE sPortDef; 00625 OMX_U32 nLocalBufferCountActual; 00626 00627 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00628 00629 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { 00630 DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__); 00631 return OMX_ErrorBadPortIndex; 00632 } 00633 if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { 00634 DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled Flag=%x\n", __func__, (int)openmaxStandPort->nTunnelFlags); 00635 return OMX_ErrorBadPortIndex; 00636 } 00637 00638 if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) { 00639 if (!openmaxStandPort->bIsTransientToEnabled) { 00640 DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__); 00641 return OMX_ErrorIncorrectStateTransition; 00642 } 00643 } 00644 /*Get nBufferSize of the peer port and allocate which one is bigger*/ 00645 nBufferSize = openmaxStandPort->sPortParam.nBufferSize; 00646 setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); 00647 sPortDef.nPortIndex = openmaxStandPort->nTunneledPort; 00648 err = OMX_GetParameter(openmaxStandPort->hTunneledComponent, OMX_IndexParamPortDefinition, &sPortDef); 00649 if(err == OMX_ErrorNone) { 00650 nBufferSize = (sPortDef.nBufferSize > openmaxStandPort->sPortParam.nBufferSize) ? sPortDef.nBufferSize: openmaxStandPort->sPortParam.nBufferSize; 00651 } else { 00652 return OMX_ErrorPortsNotCompatible; 00653 } 00654 /* set the number of buffer needed getting the max nBufferCountActual of the two components 00655 * On the one with the minor nBufferCountActual a setParam should be called to normalize the value, 00656 * if possible. 00657 */ 00658 nLocalBufferCountActual = openmaxStandPort->sPortParam.nBufferCountActual; 00659 if (nLocalBufferCountActual < sPortDef.nBufferCountActual) { 00660 nLocalBufferCountActual = sPortDef.nBufferCountActual; 00661 openmaxStandPort->sPortParam.nBufferCountActual = nLocalBufferCountActual; 00662 } else if (sPortDef.nBufferCountActual < nLocalBufferCountActual){ 00663 sPortDef.nBufferCountActual = nLocalBufferCountActual; 00664 err = OMX_SetParameter(openmaxStandPort->hTunneledComponent, OMX_IndexParamPortDefinition, &sPortDef); 00665 if(err != OMX_ErrorNone) { 00666 /* for some reasons undetected during negotiation the tunnel cannot be established. 00667 */ 00668 return OMX_ErrorPortsNotCompatible; 00669 } 00670 } 00671 if (openmaxStandPort->sPortParam.nBufferCountActual == 0) { 00672 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; 00673 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; 00674 DEBUG(DEB_LEV_ERR, "In %s Allocated nothing\n",__func__); 00675 return OMX_ErrorNone; 00676 } 00677 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ 00678 if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) { 00679 pBuffer = calloc(1,nBufferSize); 00680 if(pBuffer==NULL) { 00681 return OMX_ErrorInsufficientResources; 00682 } 00683 /*Retry more than once, if the tunneled component is not in Loaded->Idle State*/ 00684 while(numRetry <TUNNEL_USE_BUFFER_RETRY) { 00685 eError=OMX_UseBuffer(openmaxStandPort->hTunneledComponent,&openmaxStandPort->pInternalBufferStorage[i], 00686 openmaxStandPort->nTunneledPort,NULL,nBufferSize,pBuffer); 00687 if(eError!=OMX_ErrorNone) { 00688 DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Component Couldn't Use buffer %i From Comp=%s Retry=%d\n", 00689 i,omx_base_component_Private->name,(int)numRetry); 00690 00691 if((eError == OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) { 00692 DEBUG(DEB_LEV_FULL_SEQ,"Waiting for next try %i \n",(int)numRetry); 00693 usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME); 00694 numRetry++; 00695 continue; 00696 } 00697 free(pBuffer); 00698 pBuffer = NULL; 00699 return eError; 00700 } 00701 else { 00702 if(openmaxStandPort->sPortParam.eDir == OMX_DirInput) { 00703 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00704 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->nTunneledPort; 00705 } else { 00706 openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->nTunneledPort; 00707 openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00708 } 00709 break; 00710 } 00711 } 00712 if(eError!=OMX_ErrorNone) { 00713 free(pBuffer); 00714 pBuffer = NULL; 00715 DEBUG(DEB_LEV_ERR,"In %s Tunneled Component Couldn't Use Buffer err = %x \n",__func__,(int)eError); 00716 return eError; 00717 } 00718 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED; 00719 openmaxStandPort->nNumAssignedBuffers++; 00720 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); 00721 00722 if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) { 00723 openmaxStandPort->sPortParam.bPopulated = OMX_TRUE; 00724 openmaxStandPort->bIsFullOfBuffers = OMX_TRUE; 00725 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__, (int)nPortIndex); 00726 } 00727 errQue = queue(openmaxStandPort->pBufferQueue, openmaxStandPort->pInternalBufferStorage[i]); 00728 if (errQue) { 00729 /* /TODO the queue is full. This can be handled in a fine way with 00730 * some retrials, or other checking. For the moment this is a critical error 00731 * and simply causes the failure of this call 00732 */ 00733 return OMX_ErrorInsufficientResources; 00734 } 00735 } 00736 } 00737 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p. Allocated all the buffers\n", __func__, openmaxStandPort); 00738 return OMX_ErrorNone; 00739 } 00740 00741 OMX_ERRORTYPE base_port_FreeTunnelBuffer(omx_base_PortType *openmaxStandPort,OMX_U32 nPortIndex) 00742 { 00743 unsigned int i; 00744 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; 00745 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; 00746 OMX_ERRORTYPE eError=OMX_ErrorNone; 00747 OMX_U32 numRetry=0; 00748 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00749 00750 if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) { 00751 DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__); 00752 return OMX_ErrorBadPortIndex; 00753 } 00754 if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) { 00755 DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled\n", __func__); 00756 return OMX_ErrorBadPortIndex; 00757 } 00758 00759 if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) { 00760 if (!openmaxStandPort->bIsTransientToDisabled) { 00761 DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__); 00762 (*(omx_base_component_Private->callbacks->EventHandler)) 00763 (omxComponent, 00764 omx_base_component_Private->callbackData, 00765 OMX_EventError, /* The command was completed */ 00766 OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */ 00767 nPortIndex, /* The state has been changed in message->messageParam2 */ 00768 NULL); 00769 } 00770 } 00771 00772 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ 00773 if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) { 00774 00775 openmaxStandPort->bIsFullOfBuffers = OMX_FALSE; 00776 if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) { 00777 free(openmaxStandPort->pInternalBufferStorage[i]->pBuffer); 00778 openmaxStandPort->pInternalBufferStorage[i]->pBuffer = NULL; 00779 } 00780 /*Retry more than once, if the tunneled component is not in Idle->Loaded State*/ 00781 while(numRetry <TUNNEL_USE_BUFFER_RETRY) { 00782 eError=OMX_FreeBuffer(openmaxStandPort->hTunneledComponent,openmaxStandPort->nTunneledPort,openmaxStandPort->pInternalBufferStorage[i]); 00783 if(eError!=OMX_ErrorNone) { 00784 DEBUG(DEB_LEV_ERR,"Tunneled Component Couldn't free buffer %i \n",i); 00785 if((eError == OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) { 00786 DEBUG(DEB_LEV_ERR,"Waiting for next try %i \n",(int)numRetry); 00787 usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME); 00788 numRetry++; 00789 continue; 00790 } 00791 return eError; 00792 } else { 00793 break; 00794 } 00795 } 00796 openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE; 00797 00798 openmaxStandPort->nNumAssignedBuffers--; 00799 DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers); 00800 00801 if (openmaxStandPort->nNumAssignedBuffers == 0) { 00802 openmaxStandPort->sPortParam.bPopulated = OMX_FALSE; 00803 openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE; 00804 //tsem_up(openmaxStandPort->pAllocSem); 00805 } 00806 } 00807 } 00808 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p Qelem=%d BSem=%d\n", __func__, openmaxStandPort, 00809 openmaxStandPort->pBufferQueue->nelem, openmaxStandPort->pBufferSem->semval); 00810 return OMX_ErrorNone; 00811 } 00812 00818 OMX_ERRORTYPE base_port_SendBufferFunction( 00819 omx_base_PortType *openmaxStandPort, 00820 OMX_BUFFERHEADERTYPE* pBuffer) { 00821 00822 OMX_ERRORTYPE err; 00823 int errQue; 00824 OMX_U32 portIndex; 00825 OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer; 00826 omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate; 00827 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00828 #if NO_GST_OMX_PATCH 00829 unsigned int i; 00830 #endif 00831 portIndex = (openmaxStandPort->sPortParam.eDir == OMX_DirInput)?pBuffer->nInputPortIndex:pBuffer->nOutputPortIndex; 00832 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %lu\n", __func__, portIndex); 00833 00834 if (portIndex != openmaxStandPort->sPortParam.nPortIndex) { 00835 DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n", __func__, (int)portIndex, (int)openmaxStandPort->sPortParam.nPortIndex); 00836 return OMX_ErrorBadPortIndex; 00837 } 00838 00839 if(omx_base_component_Private->state == OMX_StateInvalid) { 00840 DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__); 00841 return OMX_ErrorInvalidState; 00842 } 00843 00844 if(omx_base_component_Private->state != OMX_StateExecuting && 00845 omx_base_component_Private->state != OMX_StatePause && 00846 omx_base_component_Private->state != OMX_StateIdle) { 00847 DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state); 00848 return OMX_ErrorIncorrectStateOperation; 00849 } 00850 if (!PORT_IS_ENABLED(openmaxStandPort) || (PORT_IS_BEING_DISABLED(openmaxStandPort) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) || 00851 ((omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle || 00852 omx_base_component_Private->transientState == OMX_TransStatePauseToIdle) && 00853 (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)))) { 00854 DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex,omx_base_component_Private->name); 00855 return OMX_ErrorIncorrectStateOperation; 00856 } 00857 00858 /* Temporarily disable this check for gst-openmax */ 00859 #if NO_GST_OMX_PATCH 00860 { 00861 OMX_BOOL foundBuffer = OMX_FALSE; 00862 if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) { 00863 for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){ 00864 if (pBuffer->pBuffer == openmaxStandPort->pInternalBufferStorage[i]->pBuffer) { 00865 foundBuffer = OMX_TRUE; 00866 break; 00867 } 00868 } 00869 } 00870 if (!foundBuffer) { 00871 return OMX_ErrorBadParameter; 00872 } 00873 } 00874 #endif 00875 00876 if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) { 00877 DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__); 00878 return err; 00879 } 00880 00881 /* And notify the buffer management thread we have a fresh new buffer to manage */ 00882 if(!PORT_IS_BEING_FLUSHED(openmaxStandPort) && !(PORT_IS_BEING_DISABLED(openmaxStandPort) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))){ 00883 errQue = queue(openmaxStandPort->pBufferQueue, pBuffer); 00884 if (errQue) { 00885 /* /TODO the queue is full. This can be handled in a fine way with 00886 * some retrials, or other checking. For the moment this is a critical error 00887 * and simply causes the failure of this call 00888 */ 00889 return OMX_ErrorInsufficientResources; 00890 } 00891 tsem_up(openmaxStandPort->pBufferSem); 00892 DEBUG(DEB_LEV_PARAMS, "In %s Signalling bMgmtSem Port Index=%d\n",__func__, (int)portIndex); 00893 tsem_up(omx_base_component_Private->bMgmtSem); 00894 }else if(PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)){ 00895 DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n", 00896 __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex); 00897 errQue = queue(openmaxStandPort->pBufferQueue, pBuffer); 00898 if (errQue) { 00899 /* /TODO the queue is full. This can be handled in a fine way with 00900 * some retrials, or other checking. For the moment this is a critical error 00901 * and simply causes the failure of this call 00902 */ 00903 return OMX_ErrorInsufficientResources; 00904 } 00905 tsem_up(openmaxStandPort->pBufferSem); 00906 } 00907 else { // If port being flushed and not tunneled then return error 00908 DEBUG(DEB_LEV_FULL_SEQ, "In %s \n", __func__); 00909 return OMX_ErrorIncorrectStateOperation; 00910 } 00911 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00912 return OMX_ErrorNone; 00913 } 00914 00918 OMX_ERRORTYPE base_port_ReturnBufferFunction(omx_base_PortType* openmaxStandPort,OMX_BUFFERHEADERTYPE* pBuffer){ 00919 omx_base_component_PrivateType* omx_base_component_Private=openmaxStandPort->standCompContainer->pComponentPrivate; 00920 queue_t* pQueue = openmaxStandPort->pBufferQueue; 00921 tsem_t* pSem = openmaxStandPort->pBufferSem; 00922 OMX_ERRORTYPE eError = OMX_ErrorNone; 00923 int errQue; 00924 00925 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 00926 if (PORT_IS_TUNNELED(openmaxStandPort) && 00927 ! PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) { 00928 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { 00929 pBuffer->nOutputPortIndex = openmaxStandPort->nTunneledPort; 00930 pBuffer->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00931 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); 00932 if(eError != OMX_ErrorNone) { 00933 DEBUG(DEB_LEV_ERR, "In %s eError %08x in FillThis Buffer from Component %s Non-Supplier\n", 00934 __func__, eError,omx_base_component_Private->name); 00935 } 00936 } else { 00937 pBuffer->nInputPortIndex = openmaxStandPort->nTunneledPort; 00938 pBuffer->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex; 00939 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); 00940 if(eError != OMX_ErrorNone) { 00941 DEBUG(DEB_LEV_ERR, "In %s eError %08x in EmptyThis Buffer from Component %s Non-Supplier\n", 00942 __func__, eError,omx_base_component_Private->name); 00943 } 00944 } 00945 } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort) && 00946 !PORT_IS_BEING_FLUSHED(openmaxStandPort)) { 00947 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { 00948 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); 00949 if(eError != OMX_ErrorNone) { 00950 DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in FillThis Buffer from Component %s Supplier\n", 00951 __func__, eError,omx_base_component_Private->name); 00952 /*If Error Occured then queue the buffer*/ 00953 errQue = queue(pQueue, pBuffer); 00954 if (errQue) { 00955 /* /TODO the queue is full. This can be handled in a fine way with 00956 * some retrials, or other checking. For the moment this is a critical error 00957 * and simply causes the failure of this call 00958 */ 00959 return OMX_ErrorInsufficientResources; 00960 } 00961 tsem_up(pSem); 00962 } 00963 } else { 00964 eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer); 00965 if(eError != OMX_ErrorNone) { 00966 DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in EmptyThis Buffer from Component %s Supplier\n", 00967 __func__, eError,omx_base_component_Private->name); 00968 /*If Error Occured then queue the buffer*/ 00969 errQue = queue(pQueue, pBuffer); 00970 if (errQue) { 00971 /* /TODO the queue is full. This can be handled in a fine way with 00972 * some retrials, or other checking. For the moment this is a critical error 00973 * and simply causes the failure of this call 00974 */ 00975 return OMX_ErrorInsufficientResources; 00976 } 00977 tsem_up(pSem); 00978 } 00979 } 00980 } else if (!PORT_IS_TUNNELED(openmaxStandPort)){ 00981 (*(openmaxStandPort->BufferProcessedCallback))( 00982 openmaxStandPort->standCompContainer, 00983 omx_base_component_Private->callbackData, 00984 pBuffer); 00985 } else { 00986 errQue = queue(pQueue, pBuffer); 00987 if (errQue) { 00988 /* /TODO the queue is full. This can be handled in a fine way with 00989 * some retrials, or other checking. For the moment this is a critical error 00990 * and simply causes the failure of this call 00991 */ 00992 return OMX_ErrorInsufficientResources; 00993 } 00994 openmaxStandPort->nNumBufferFlushed++; 00995 } 00996 00997 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 00998 return OMX_ErrorNone; 00999 } 01000 01001 01002 OMX_ERRORTYPE base_port_ComponentTunnelRequest(omx_base_PortType* openmaxStandPort, OMX_HANDLETYPE hTunneledComp, OMX_U32 nTunneledPort, OMX_TUNNELSETUPTYPE* pTunnelSetup) { 01003 OMX_ERRORTYPE err = OMX_ErrorNone; 01004 OMX_PARAM_PORTDEFINITIONTYPE param; 01005 OMX_PARAM_BUFFERSUPPLIERTYPE pSupplier; 01006 01007 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for port %p\n", __func__, openmaxStandPort); 01008 if (pTunnelSetup == NULL || hTunneledComp == 0) { 01009 /* cancel previous tunnel */ 01010 openmaxStandPort->hTunneledComponent = 0; 01011 openmaxStandPort->nTunneledPort = 0; 01012 openmaxStandPort->nTunnelFlags = 0; 01013 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyUnspecified; 01014 return OMX_ErrorNone; 01015 } 01016 01017 if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) { 01018 /* Get Port Definition of the Tunnelled Component*/ 01019 param.nPortIndex=nTunneledPort; 01020 setHeader(¶m, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); 01021 err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, ¶m); 01023 if (err != OMX_ErrorNone) { 01024 DEBUG(DEB_LEV_ERR,"In %s Tunneled Port Definition error=0x%08x Line=%d\n",__func__,err,__LINE__); 01025 // compatibility not reached 01026 return OMX_ErrorPortsNotCompatible; 01027 } 01028 openmaxStandPort->nNumTunnelBuffer = param.nBufferCountActual; 01029 if(param.eDomain!=openmaxStandPort->sPortParam.eDomain) { 01030 return OMX_ErrorPortsNotCompatible; 01031 } 01032 if(param.eDomain==OMX_PortDomainAudio) { 01033 if(param.format.audio.eEncoding == OMX_AUDIO_CodingMax) { 01034 return OMX_ErrorPortsNotCompatible; 01035 } 01036 } else if(param.eDomain==OMX_PortDomainVideo) { 01037 if(param.format.video.eCompressionFormat == OMX_VIDEO_CodingMax) { 01038 return OMX_ErrorPortsNotCompatible; 01039 } 01040 } else if(param.eDomain==OMX_PortDomainOther) { 01041 if(param.format.other.eFormat == OMX_OTHER_FormatMax) { 01042 return OMX_ErrorPortsNotCompatible; 01043 } 01044 } 01045 01046 /* Get Buffer Supplier type of the Tunneled Component*/ 01047 pSupplier.nPortIndex=nTunneledPort; 01048 setHeader(&pSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE)); 01049 err = OMX_GetParameter(hTunneledComp, OMX_IndexParamCompBufferSupplier, &pSupplier); 01050 if (err != OMX_ErrorNone) { 01051 // compatibility not reached 01052 DEBUG(DEB_LEV_ERR,"In %s Tunneled Buffer Supplier error=0x%08x Line=%d\n",__func__,err,__LINE__); 01053 return OMX_ErrorPortsNotCompatible; 01054 } else { 01055 DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Port eBufferSupplier=%x\n", pSupplier.eBufferSupplier); 01056 } 01057 01058 // store the current callbacks, if defined 01059 openmaxStandPort->hTunneledComponent = hTunneledComp; 01060 openmaxStandPort->nTunneledPort = nTunneledPort; 01061 01062 /*Check for and set proprietary communication flag. 01063 In case a component support Deep Tunneling should set it's tunnel flag to PROPRIETARY_COMMUNICATION_ESTABLISHED */ 01064 if(PORT_IS_DEEP_TUNNELED(openmaxStandPort)) { 01065 OMX_VENDOR_PROP_TUNNELSETUPTYPE pPropTunnelSetup; 01066 pPropTunnelSetup.nPortIndex = nTunneledPort; 01067 01068 err = OMX_GetParameter(hTunneledComp, OMX_IndexVendorCompPropTunnelFlags, &pPropTunnelSetup); 01069 if (err != OMX_ErrorNone) { 01070 // compatibility not reached 01071 DEBUG(DEB_LEV_ERR,"In %s Proprietary Tunneled Buffer Supplier nTunneledPort=%d error=0x%08x Line=%d \n", 01072 __func__,(int)pPropTunnelSetup.nPortIndex,err,__LINE__); 01073 openmaxStandPort->nTunnelFlags = 0; 01074 } else { 01075 openmaxStandPort->nTunnelFlags = PROPRIETARY_COMMUNICATION_ESTABLISHED; 01076 } 01077 } else { 01078 openmaxStandPort->nTunnelFlags = 0; 01079 } 01080 01081 // Negotiation 01082 if (pTunnelSetup->nTunnelFlags & OMX_PORTTUNNELFLAG_READONLY) { 01083 // the buffer provider MUST be the output port provider 01084 pTunnelSetup->eSupplier = OMX_BufferSupplyInput; 01085 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER; 01086 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput; 01087 } else { 01088 if (pTunnelSetup->eSupplier == OMX_BufferSupplyInput) { 01089 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER; 01090 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput; 01091 } else if (pTunnelSetup->eSupplier == OMX_BufferSupplyUnspecified) { 01092 pTunnelSetup->eSupplier = OMX_BufferSupplyInput; 01093 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER; 01094 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput; 01095 } 01096 } 01097 openmaxStandPort->nTunnelFlags |= TUNNEL_ESTABLISHED; 01098 01099 /* Set Buffer Supplier type of the Tunnelled Component after final negotiation*/ 01100 pSupplier.nPortIndex=nTunneledPort; 01101 pSupplier.eBufferSupplier=openmaxStandPort->eBufferSupplier; 01102 err = OMX_SetParameter(hTunneledComp, OMX_IndexParamCompBufferSupplier, &pSupplier); 01103 if (err != OMX_ErrorNone) { 01104 // compatibility not reached 01105 DEBUG(DEB_LEV_ERR,"In %s Tunneled Buffer Supplier error=0x%08x Line=%d\n",__func__,err,__LINE__); 01106 openmaxStandPort->nTunnelFlags=0; 01107 return OMX_ErrorPortsNotCompatible; 01108 } 01109 } else { 01110 // output port 01111 // all the consistency checks are under other component responsibility 01112 01113 /* Get Port Definition of the Tunnelled Component*/ 01114 param.nPortIndex=nTunneledPort; 01115 setHeader(¶m, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); 01116 err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, ¶m); 01117 if (err != OMX_ErrorNone) { 01118 DEBUG(DEB_LEV_ERR,"In %s Tunneled Port Definition error=0x%08x Line=%d\n",__func__,err,__LINE__); 01119 // compatibility not reached 01120 return OMX_ErrorPortsNotCompatible; 01121 } 01122 if(param.eDomain!=openmaxStandPort->sPortParam.eDomain) { 01123 return OMX_ErrorPortsNotCompatible; 01124 } 01125 01126 if(param.eDomain==OMX_PortDomainAudio) { 01127 if(param.format.audio.eEncoding == OMX_AUDIO_CodingMax) { 01128 return OMX_ErrorPortsNotCompatible; 01129 } 01130 } else if(param.eDomain==OMX_PortDomainVideo) { 01131 if(param.format.video.eCompressionFormat == OMX_VIDEO_CodingMax) { 01132 return OMX_ErrorPortsNotCompatible; 01133 } 01134 } else if(param.eDomain==OMX_PortDomainOther) { 01135 if(param.format.other.eFormat == OMX_OTHER_FormatMax) { 01136 return OMX_ErrorPortsNotCompatible; 01137 } 01138 } 01139 01140 /*Check for and set proprietary communication flag*/ 01141 if(PORT_IS_DEEP_TUNNELED(openmaxStandPort)) { 01142 OMX_VENDOR_PROP_TUNNELSETUPTYPE pPropTunnelSetup; 01143 pPropTunnelSetup.nPortIndex = nTunneledPort; 01144 01145 err = OMX_GetParameter(hTunneledComp, OMX_IndexVendorCompPropTunnelFlags, &pPropTunnelSetup); 01146 if (err != OMX_ErrorNone) { 01147 // compatibility not reached 01148 DEBUG(DEB_LEV_ERR,"In %s Proprietary Tunneled Buffer Supplier nTunneledPort=%d error=0x%08x Line=%d \n", 01149 __func__,(int)pPropTunnelSetup.nPortIndex,err,__LINE__); 01150 openmaxStandPort->nTunnelFlags = 0; 01151 } else { 01152 openmaxStandPort->nTunnelFlags = PROPRIETARY_COMMUNICATION_ESTABLISHED; 01153 } 01154 } else { 01155 openmaxStandPort->nTunnelFlags = 0; 01156 } 01157 01158 openmaxStandPort->nNumTunnelBuffer=param.nBufferCountActual; 01159 01160 openmaxStandPort->hTunneledComponent = hTunneledComp; 01161 openmaxStandPort->nTunneledPort = nTunneledPort; 01162 pTunnelSetup->eSupplier = OMX_BufferSupplyOutput; 01163 openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER; 01164 openmaxStandPort->nTunnelFlags |= TUNNEL_ESTABLISHED; 01165 01166 openmaxStandPort->eBufferSupplier=OMX_BufferSupplyOutput; 01167 } 01168 01169 DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for port %p\n", __func__, openmaxStandPort); 01170 return OMX_ErrorNone; 01171 }