OpenMAXBellagio 0.9.3
omx_base_port.c
Go to the documentation of this file.
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(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
01021     err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, &param);
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(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
01116     err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, &param);
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 }