omx_base_port.c

Go to the documentation of this file.
00001 
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <unistd.h>
00032 #include <omxcore.h>
00033 #include <OMX_Core.h>
00034 #include <OMX_Component.h>
00035 
00036 #include "omx_base_component.h"
00037 #include "omx_base_port.h"
00038 
00040 #define DEFAULT_NUMBER_BUFFERS_PER_PORT 2
00041 
00042 #define DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT 2
00043 
00057 OMX_ERRORTYPE base_port_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,omx_base_PortType **openmaxStandPort,OMX_U32 nPortIndex, OMX_BOOL isInput) {
00058     
00059   /* omx_base_component_PrivateType* omx_base_component_Private; */
00060 
00061   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00062   /* omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate; */
00063 
00064   // create ports, but only if the subclass hasn't done it
00065   if (!(*openmaxStandPort)) {
00066     *openmaxStandPort = calloc(1,sizeof (omx_base_PortType));
00067   }
00068 
00069   if (!(*openmaxStandPort)) {
00070     return OMX_ErrorInsufficientResources;
00071   }
00072 
00073   (*openmaxStandPort)->hTunneledComponent = NULL;
00074   (*openmaxStandPort)->nTunnelFlags=0;
00075   (*openmaxStandPort)->nTunneledPort=0;
00076   (*openmaxStandPort)->eBufferSupplier=OMX_BufferSupplyUnspecified; 
00077   (*openmaxStandPort)->nNumTunnelBuffer=0;
00078 
00079   if((*openmaxStandPort)->pAllocSem==NULL) {
00080     (*openmaxStandPort)->pAllocSem = calloc(1,sizeof(tsem_t));
00081     if((*openmaxStandPort)->pAllocSem==NULL) {
00082         return OMX_ErrorInsufficientResources;
00083     }
00084     tsem_init((*openmaxStandPort)->pAllocSem, 0);
00085   }
00086   (*openmaxStandPort)->nNumBufferFlushed=0; 
00087   (*openmaxStandPort)->bIsPortFlushed=OMX_FALSE;
00089   if(!(*openmaxStandPort)->pBufferQueue) {
00090     (*openmaxStandPort)->pBufferQueue = calloc(1,sizeof(queue_t));
00091     if((*openmaxStandPort)->pBufferQueue==NULL) return OMX_ErrorInsufficientResources;
00092     queue_init((*openmaxStandPort)->pBufferQueue);
00093   }
00094   /*Allocate and initialise port semaphores*/
00095   if(!(*openmaxStandPort)->pBufferSem) {
00096     (*openmaxStandPort)->pBufferSem = calloc(1,sizeof(tsem_t));
00097     if((*openmaxStandPort)->pBufferSem==NULL) return OMX_ErrorInsufficientResources;
00098     tsem_init((*openmaxStandPort)->pBufferSem, 0);
00099   }
00100 
00101   (*openmaxStandPort)->nNumAssignedBuffers=0;
00102   setHeader(&(*openmaxStandPort)->sPortParam, sizeof (OMX_PARAM_PORTDEFINITIONTYPE));
00103   (*openmaxStandPort)->sPortParam.nPortIndex = nPortIndex;
00104   (*openmaxStandPort)->sPortParam.nBufferCountActual = DEFAULT_NUMBER_BUFFERS_PER_PORT;
00105   (*openmaxStandPort)->sPortParam.nBufferCountMin = DEFAULT_MIN_NUMBER_BUFFERS_PER_PORT;
00106   (*openmaxStandPort)->sPortParam.bEnabled = OMX_TRUE;
00107   (*openmaxStandPort)->sPortParam.bPopulated = OMX_FALSE; 
00108   (*openmaxStandPort)->sPortParam.eDir  =  (isInput == OMX_TRUE)?OMX_DirInput:OMX_DirOutput;
00109 
00110   (*openmaxStandPort)->standCompContainer=openmaxStandComp; 
00111   (*openmaxStandPort)->bIsTransientToEnabled=OMX_FALSE;
00112   (*openmaxStandPort)->bIsTransientToDisabled=OMX_FALSE;
00113   (*openmaxStandPort)->bIsFullOfBuffers=OMX_FALSE;
00114   (*openmaxStandPort)->bIsEmptyOfBuffers=OMX_FALSE;
00115 
00116   (*openmaxStandPort)->PortDestructor = &base_port_Destructor;
00117   (*openmaxStandPort)->Port_AllocateBuffer = &base_port_AllocateBuffer;
00118   (*openmaxStandPort)->Port_UseBuffer = &base_port_UseBuffer;
00119   (*openmaxStandPort)->Port_FreeBuffer = &base_port_FreeBuffer;
00120   (*openmaxStandPort)->Port_DisablePort = &base_port_DisablePort;
00121   (*openmaxStandPort)->Port_EnablePort = &base_port_EnablePort;
00122   (*openmaxStandPort)->Port_SendBufferFunction = &base_port_SendBufferFunction;
00123   (*openmaxStandPort)->FlushProcessingBuffers = &base_port_FlushProcessingBuffers;
00124   (*openmaxStandPort)->ReturnBufferFunction = &base_port_ReturnBufferFunction;
00125   (*openmaxStandPort)->ComponentTunnelRequest = &base_port_ComponentTunnelRequest;
00126   (*openmaxStandPort)->Port_AllocateTunnelBuffer = &base_port_AllocateTunnelBuffer;
00127   (*openmaxStandPort)->Port_FreeTunnelBuffer = &base_port_FreeTunnelBuffer;
00128   
00129   return OMX_ErrorNone;
00130 }
00131 
00132 OMX_ERRORTYPE base_port_Destructor(omx_base_PortType *openmaxStandPort){
00133 
00134   if(openmaxStandPort->pAllocSem) {
00135     tsem_deinit(openmaxStandPort->pAllocSem);
00136     free(openmaxStandPort->pAllocSem);
00137     openmaxStandPort->pAllocSem=NULL;
00138   }
00140   if(openmaxStandPort->pBufferQueue) {
00141     queue_deinit(openmaxStandPort->pBufferQueue);
00142     free(openmaxStandPort->pBufferQueue);
00143     openmaxStandPort->pBufferQueue=NULL;
00144   }
00145   /*Allocate and initialise port semaphores*/
00146   if(openmaxStandPort->pBufferSem) {
00147     tsem_deinit(openmaxStandPort->pBufferSem);
00148     free(openmaxStandPort->pBufferSem);
00149     openmaxStandPort->pBufferSem=NULL;
00150   }
00151 
00152   free(openmaxStandPort);
00153   openmaxStandPort = NULL;
00154   return OMX_ErrorNone;
00155 }
00156 
00161 OMX_ERRORTYPE base_port_FlushProcessingBuffers(omx_base_PortType *openmaxStandPort) {
00162   omx_base_component_PrivateType* omx_base_component_Private;
00163   OMX_BUFFERHEADERTYPE* pBuffer;
00164 
00165   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00166   omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
00167 
00168   pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
00169   openmaxStandPort->bIsPortFlushed=OMX_TRUE;
00170   /*Signal the buffer management thread of port flush,if it is waiting for buffers*/
00171   if(omx_base_component_Private->bMgmtSem->semval==0) {
00172     tsem_up(omx_base_component_Private->bMgmtSem);
00173   }
00174 
00175   if(omx_base_component_Private->state==OMX_StatePause ) {
00176     /*Waiting at paused state*/
00177     tsem_signal(omx_base_component_Private->bStateSem);
00178   }
00179   DEBUG(DEB_LEV_FULL_SEQ, "In %s waiting for flush all condition port index =%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
00180   /* Wait until flush is completed */
00181   pthread_cond_wait(&omx_base_component_Private->flush_all_condition,&omx_base_component_Private->flush_mutex);
00182   pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);
00183 
00184   tsem_reset(omx_base_component_Private->bMgmtSem);
00185 
00186   /* Flush all the buffers not under processing */
00187   while (openmaxStandPort->pBufferSem->semval > 0) {
00188     DEBUG(DEB_LEV_FULL_SEQ, "In %s TFlag=%x Flusing Port=%d,Semval=%d Qelem=%d\n", 
00189     __func__,(int)openmaxStandPort->nTunnelFlags,(int)openmaxStandPort->sPortParam.nPortIndex,
00190     (int)openmaxStandPort->pBufferSem->semval,(int)openmaxStandPort->pBufferQueue->nelem);
00191 
00192     tsem_down(openmaxStandPort->pBufferSem);
00193     pBuffer = dequeue(openmaxStandPort->pBufferQueue);
00194     if (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
00195       DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s is returning io:%d buffer\n", 
00196         __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
00197       if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00198         ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00199       } else {
00200         ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00201       }
00202     } else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00203       queue(openmaxStandPort->pBufferQueue,pBuffer);
00204     } else {
00205       (*(openmaxStandPort->BufferProcessedCallback))(
00206         openmaxStandPort->standCompContainer,
00207         omx_base_component_Private->callbackData,
00208         pBuffer);
00209     }
00210   }
00211   /*Port is tunneled and supplier and didn't received all it's buffer then wait for the buffers*/
00212   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00213     while(openmaxStandPort->pBufferQueue->nelem!= openmaxStandPort->nNumAssignedBuffers){
00214       tsem_down(openmaxStandPort->pBufferSem);
00215       DEBUG(DEB_LEV_PARAMS, "In %s Got a buffer qelem=%d\n",__func__,openmaxStandPort->pBufferQueue->nelem);
00216     }
00217     tsem_reset(openmaxStandPort->pBufferSem);
00218   }
00219 
00220   openmaxStandPort->bIsPortFlushed=OMX_FALSE;
00221 
00222   pthread_mutex_lock(&omx_base_component_Private->flush_mutex);
00223   pthread_cond_signal(&omx_base_component_Private->flush_condition);
00224   pthread_mutex_unlock(&omx_base_component_Private->flush_mutex);
00225 
00226   DEBUG(DEB_LEV_FULL_SEQ, "Out %s Port Index=%d bIsPortFlushed=%d Component %s\n", __func__,
00227     (int)openmaxStandPort->sPortParam.nPortIndex,(int)openmaxStandPort->bIsPortFlushed,omx_base_component_Private->name);
00228 
00229   DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
00230     (int)openmaxStandPort->nTunnelFlags,
00231     (int)openmaxStandPort->pBufferQueue->nelem,
00232     (int)openmaxStandPort->pBufferSem->semval,
00233     (int)omx_base_component_Private->bMgmtSem->semval,
00234     omx_base_component_Private->name);
00235 
00236   DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
00237 
00238   return OMX_ErrorNone;
00239 }
00240 
00248 OMX_ERRORTYPE base_port_DisablePort(omx_base_PortType *openmaxStandPort) {
00249   omx_base_component_PrivateType* omx_base_component_Private;
00250   OMX_ERRORTYPE err=OMX_ErrorNone;
00251 
00252   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Port Index=%d\n", __func__,(int)openmaxStandPort->sPortParam.nPortIndex);
00253   omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
00254   if (! PORT_IS_ENABLED(openmaxStandPort)) {
00255     return OMX_ErrorNone;
00256   }
00257 
00258   if(omx_base_component_Private->state!=OMX_StateLoaded) {
00259     if(!PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
00260       /*Signal Buffer Mgmt Thread if it's holding any buffer*/
00261       if(omx_base_component_Private->bMgmtSem->semval==0) {
00262         tsem_up(omx_base_component_Private->bMgmtSem);
00263       }
00264       /*Wait till all buffers are freed*/
00265       tsem_down(openmaxStandPort->pAllocSem);
00266       tsem_reset(omx_base_component_Private->bMgmtSem);
00267     } else {
00268       /*Since port is being disabled then remove buffers from the queue*/
00269       while(openmaxStandPort->pBufferQueue->nelem > 0) {
00270         dequeue(openmaxStandPort->pBufferQueue);
00271       }
00272 
00273       err = openmaxStandPort->Port_FreeTunnelBuffer(openmaxStandPort,openmaxStandPort->sPortParam.nPortIndex);
00274       if(err!=OMX_ErrorNone) { 
00275         DEBUG(DEB_LEV_ERR, "In %s Freeing Tunnel Buffer Error=%x\n",__func__,err); 
00276       }
00277       DEBUG(DEB_LEV_PARAMS, "In %s Qelem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem);
00278     }
00279   }
00280 
00281   DEBUG(DEB_LEV_PARAMS, "In %s TFlag=%x Qelem=%d BSem=%d bMgmtsem=%d component=%s\n", __func__,
00282     (int)openmaxStandPort->nTunnelFlags,
00283     (int)openmaxStandPort->pBufferQueue->nelem,
00284     (int)openmaxStandPort->pBufferSem->semval,
00285     (int)omx_base_component_Private->bMgmtSem->semval,
00286     omx_base_component_Private->name);
00287   openmaxStandPort->bIsTransientToDisabled = OMX_FALSE;
00288   openmaxStandPort->sPortParam.bEnabled = OMX_FALSE;
00289   DEBUG(DEB_LEV_FUNCTION_NAME, "Out %s Port Index=%d isEnabled=%d\n", __func__,
00290         (int)openmaxStandPort->sPortParam.nPortIndex,
00291         (int)openmaxStandPort->sPortParam.bEnabled);
00292   return err;
00293 }
00294 
00302 OMX_ERRORTYPE base_port_EnablePort(omx_base_PortType *openmaxStandPort) {
00303   omx_base_component_PrivateType* omx_base_component_Private;
00304   OMX_ERRORTYPE err=OMX_ErrorNone;
00305   OMX_U32 i;
00306 
00307   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00308   if (PORT_IS_ENABLED(openmaxStandPort)) {
00309     return OMX_ErrorNone;
00310   }
00311   omx_base_component_Private = (omx_base_component_PrivateType*)openmaxStandPort->standCompContainer->pComponentPrivate;
00312 
00313   openmaxStandPort->sPortParam.bEnabled = OMX_TRUE;
00314 
00315   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s port T flag=%x popu=%d state=%x\n", __func__,
00316     (int)openmaxStandPort->nTunnelFlags,
00317       (int)openmaxStandPort->sPortParam.bPopulated,
00318     (int)omx_base_component_Private->state);
00319 
00320 
00321   if (!PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
00322     /*Wait Till All buffers are allocated if the component state is not Loaded*/
00323     if (omx_base_component_Private->state!=OMX_StateLoaded && omx_base_component_Private->state!=OMX_StateWaitForResources)  {
00324       tsem_down(openmaxStandPort->pAllocSem);
00325       openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
00326     }
00327   } else { //Port Tunneled and supplier. Then allocate tunnel buffers
00328     err= openmaxStandPort->Port_AllocateTunnelBuffer(openmaxStandPort, openmaxStandPort->sPortParam.nPortIndex, openmaxStandPort->sPortParam.nBufferSize);                      
00329     if(err!=OMX_ErrorNone) { 
00330       DEBUG(DEB_LEV_ERR, "In %s Allocating Tunnel Buffer Error=%x\n",__func__,err); 
00331       return err;
00332     }
00333     openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
00334     if (omx_base_component_Private->state==OMX_StateExecuting) {
00335       for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual;i++) {
00336         tsem_up(openmaxStandPort->pBufferSem);
00337         tsem_up(omx_base_component_Private->bMgmtSem);
00338       }
00339     }
00340     DEBUG(DEB_LEV_PARAMS, "In %s Qelem=%d BSem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem,openmaxStandPort->pBufferSem->semval);
00341   }
00342 
00343   openmaxStandPort->bIsTransientToEnabled = OMX_FALSE;
00344 
00345   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00346 
00347   return OMX_ErrorNone;
00348 }
00349 
00358 OMX_ERRORTYPE base_port_AllocateBuffer(
00359   omx_base_PortType *openmaxStandPort,
00360   OMX_BUFFERHEADERTYPE** pBuffer,
00361   OMX_U32 nPortIndex,
00362   OMX_PTR pAppPrivate,
00363   OMX_U32 nSizeBytes) {
00364     
00365   unsigned int i;
00366   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00367   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00368   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00369 
00370   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00371     return OMX_ErrorBadPortIndex;
00372   }
00373   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00374     return OMX_ErrorBadPortIndex;
00375   }
00376 
00377   if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
00378     if (!openmaxStandPort->bIsTransientToEnabled) {
00379       DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__);
00380       return OMX_ErrorIncorrectStateTransition;
00381     }
00382   }
00383 
00384   if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) {
00385     DEBUG(DEB_LEV_ERR, "In %s: Requested Buffer Size %lu is less than Minimum Buffer Size %lu\n", __func__, nSizeBytes, openmaxStandPort->sPortParam.nBufferSize);
00386     return OMX_ErrorIncorrectStateTransition;
00387   }
00388     
00389   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00390     if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
00391       openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
00392       if (!openmaxStandPort->pInternalBufferStorage[i]) {
00393         return OMX_ErrorInsufficientResources;
00394       }
00395       setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE));
00396       /* allocate the buffer */
00397       openmaxStandPort->pInternalBufferStorage[i]->pBuffer = calloc(1,nSizeBytes);
00398       if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer==NULL) {
00399         return OMX_ErrorInsufficientResources;
00400       }
00401       openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes;
00402       openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort;
00403       openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate;
00404       *pBuffer = openmaxStandPort->pInternalBufferStorage[i];
00405       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED;
00406       openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED;
00407       if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00408         openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00409       } else {
00410         openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00411       }
00412       openmaxStandPort->nNumAssignedBuffers++;
00413       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00414 
00415       if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
00416         openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
00417         openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
00418         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__,(int)nPortIndex);
00419         tsem_up(openmaxStandPort->pAllocSem);
00420       }
00421       return OMX_ErrorNone;
00422     }
00423   }
00424   DEBUG(DEB_LEV_ERR, "In %s Error: no available buffers\n",__func__);
00425   return OMX_ErrorInsufficientResources;
00426 }
00427     
00436 OMX_ERRORTYPE base_port_UseBuffer(
00437   omx_base_PortType *openmaxStandPort,
00438   OMX_BUFFERHEADERTYPE** ppBufferHdr,
00439   OMX_U32 nPortIndex,
00440   OMX_PTR pAppPrivate,
00441   OMX_U32 nSizeBytes,
00442   OMX_U8* pBuffer) {
00443 
00444   unsigned int i;
00445   OMX_BUFFERHEADERTYPE* returnBufferHeader;
00446   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00447   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00448   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00449   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00450     return OMX_ErrorBadPortIndex;
00451   }
00452   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00453     return OMX_ErrorBadPortIndex;
00454   }
00455 
00456   if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
00457     if (!openmaxStandPort->bIsTransientToEnabled) {
00458       DEBUG(DEB_LEV_ERR, "In %s: The port of Comp %s is not allowed to receive buffers\n", __func__,omx_base_component_Private->name);
00459       return OMX_ErrorIncorrectStateTransition;
00460     }
00461   }
00462 
00463   if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) {
00464     DEBUG(DEB_LEV_ERR, "In %s: Given Buffer Size %lu is less than Minimum Buffer Size %lu\n", __func__, nSizeBytes, openmaxStandPort->sPortParam.nBufferSize);
00465     return OMX_ErrorIncorrectStateTransition;
00466   }
00467     
00468   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00469     if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
00470       openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
00471       if (!openmaxStandPort->pInternalBufferStorage[i]) {
00472         return OMX_ErrorInsufficientResources;
00473       }
00474       openmaxStandPort->bIsEmptyOfBuffers = OMX_FALSE;
00475       setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE));
00476 
00477       openmaxStandPort->pInternalBufferStorage[i]->pBuffer = pBuffer;
00478       openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = nSizeBytes;
00479       openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort;
00480       openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate;
00481       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ASSIGNED;
00482       openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED;
00483       returnBufferHeader = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
00484       if (!returnBufferHeader) {
00485         return OMX_ErrorInsufficientResources;
00486       }
00487       setHeader(returnBufferHeader, sizeof(OMX_BUFFERHEADERTYPE));
00488       returnBufferHeader->pBuffer = pBuffer;
00489       returnBufferHeader->nAllocLen = nSizeBytes;
00490       returnBufferHeader->pPlatformPrivate = openmaxStandPort;
00491       returnBufferHeader->pAppPrivate = pAppPrivate;
00492       if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00493         openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00494         returnBufferHeader->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00495       } else {
00496         openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00497         returnBufferHeader->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00498       }
00499       *ppBufferHdr = returnBufferHeader;
00500       openmaxStandPort->nNumAssignedBuffers++;
00501       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00502 
00503       if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
00504         openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
00505         openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
00506         tsem_up(openmaxStandPort->pAllocSem);
00507       }
00508       return OMX_ErrorNone;
00509     }
00510   }
00511   DEBUG(DEB_LEV_ERR, "In %s Error: no available buffers CompName=%s\n",__func__,omx_base_component_Private->name);
00512   return OMX_ErrorInsufficientResources;
00513 }
00514 
00520 OMX_ERRORTYPE base_port_FreeBuffer(
00521   omx_base_PortType *openmaxStandPort,
00522   OMX_U32 nPortIndex,
00523   OMX_BUFFERHEADERTYPE* pBuffer) {
00524 
00525   unsigned int i;
00526   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00527   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00528   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00529 
00530   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00531     return OMX_ErrorBadPortIndex;
00532   }
00533   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00534     return OMX_ErrorBadPortIndex;
00535   }
00536 
00537   if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) {
00538     if (!openmaxStandPort->bIsTransientToDisabled) {
00539       DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__);
00540       (*(omx_base_component_Private->callbacks->EventHandler))
00541         (omxComponent,
00542         omx_base_component_Private->callbackData,
00543         OMX_EventError, /* The command was completed */
00544         OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */
00545         nPortIndex, /* The state has been changed in message->messageParam2 */
00546         NULL);
00547     }
00548   }
00549     
00550   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00551     if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) {
00552 
00553       openmaxStandPort->bIsFullOfBuffers = OMX_FALSE;
00554       if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) {
00555         if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer){
00556           DEBUG(DEB_LEV_PARAMS, "In %s freeing %i pBuffer=%x\n",__func__, (int)i, (int)openmaxStandPort->pInternalBufferStorage[i]->pBuffer);
00557           free(openmaxStandPort->pInternalBufferStorage[i]->pBuffer);
00558           openmaxStandPort->pInternalBufferStorage[i]->pBuffer=NULL;
00559         }
00560       } else if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ASSIGNED) {
00561         free(pBuffer);
00562       }
00563       if(openmaxStandPort->bBufferStateAllocated[i] & HEADER_ALLOCATED) {
00564         free(openmaxStandPort->pInternalBufferStorage[i]);
00565         openmaxStandPort->pInternalBufferStorage[i]=NULL;
00566       }
00567 
00568       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE;
00569 
00570       openmaxStandPort->nNumAssignedBuffers--;
00571       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00572 
00573       if (openmaxStandPort->nNumAssignedBuffers == 0) {
00574         openmaxStandPort->sPortParam.bPopulated = OMX_FALSE;
00575         openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE;
00576         tsem_up(openmaxStandPort->pAllocSem);
00577       }
00578       return OMX_ErrorNone;
00579     }
00580   }
00581   return OMX_ErrorInsufficientResources;
00582 }
00583 
00584 OMX_ERRORTYPE base_port_AllocateTunnelBuffer(omx_base_PortType *openmaxStandPort,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_U32 nSizeBytes)
00585 {
00586   unsigned int i;
00587   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00588   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00589   OMX_U8* pBuffer=NULL;
00590   OMX_ERRORTYPE eError=OMX_ErrorNone;
00591   OMX_U32 numRetry=0;
00592   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00593 
00594   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00595     DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__);
00596     return OMX_ErrorBadPortIndex;
00597   }
00598   if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00599     DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled Flag=%x\n", __func__, (int)openmaxStandPort->nTunnelFlags);
00600     return OMX_ErrorBadPortIndex;
00601   }
00602 
00603   if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
00604     if (!openmaxStandPort->bIsTransientToEnabled) {
00605       DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__);
00606       return OMX_ErrorIncorrectStateTransition;
00607     }
00608   }
00609     
00610   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00611     if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
00612       pBuffer = calloc(1,nSizeBytes);
00613       if(pBuffer==NULL) {
00614         return OMX_ErrorInsufficientResources;
00615       }
00616       /*Retry more than once, if the tunneled component is not in Loaded->Idle State*/
00617       while(numRetry <TUNNEL_USE_BUFFER_RETRY) {
00618         eError=OMX_UseBuffer(openmaxStandPort->hTunneledComponent,&openmaxStandPort->pInternalBufferStorage[i],
00619                              openmaxStandPort->nTunneledPort,NULL,nSizeBytes,pBuffer); 
00620         if(eError!=OMX_ErrorNone) {
00621           DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Component Couldn't Use buffer %i From Comp=%s Retry=%d\n",
00622           i,omx_base_component_Private->name,(int)numRetry);
00623 
00624           if((eError ==  OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) {
00625             DEBUG(DEB_LEV_FULL_SEQ,"Waiting for next try %i \n",(int)numRetry);
00626             usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME);
00627             numRetry++;
00628             continue;
00629           }
00630           free(pBuffer);
00631           pBuffer = NULL;
00632           return eError;
00633         }
00634         else {
00635           break;
00636         }
00637       }
00638       if(eError!=OMX_ErrorNone) {
00639         free(pBuffer);
00640         pBuffer = NULL;
00641         DEBUG(DEB_LEV_ERR,"In %s Tunneled Component Couldn't Use Buffer %x \n",__func__,(int)eError);
00642         return eError;
00643       }
00644       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED;
00645       openmaxStandPort->nNumAssignedBuffers++;
00646       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00647 
00648       if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
00649         openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
00650         openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
00651         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__, (int)nPortIndex);
00652       }
00653       queue(openmaxStandPort->pBufferQueue, openmaxStandPort->pInternalBufferStorage[i]);
00654     }
00655   }
00656   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Allocated all buffers\n",__func__);
00657   return OMX_ErrorNone;
00658 }
00659 
00660 OMX_ERRORTYPE base_port_FreeTunnelBuffer(omx_base_PortType *openmaxStandPort,OMX_U32 nPortIndex)
00661 {
00662   unsigned int i;
00663   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00664   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00665   OMX_ERRORTYPE eError=OMX_ErrorNone;
00666   OMX_U32 numRetry=0;
00667   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00668 
00669   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00670     DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__);
00671     return OMX_ErrorBadPortIndex;
00672   }
00673   if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00674     DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled\n", __func__);
00675     return OMX_ErrorBadPortIndex;
00676   }
00677 
00678   if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) {
00679     if (!openmaxStandPort->bIsTransientToDisabled) {
00680       DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__);
00681       (*(omx_base_component_Private->callbacks->EventHandler))
00682         (omxComponent,
00683         omx_base_component_Private->callbackData,
00684         OMX_EventError, /* The command was completed */
00685         OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */
00686         nPortIndex, /* The state has been changed in message->messageParam2 */
00687         NULL);
00688     }
00689   }
00690 
00691   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00692     if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) {
00693 
00694       openmaxStandPort->bIsFullOfBuffers = OMX_FALSE;
00695       if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) {
00696         free(openmaxStandPort->pInternalBufferStorage[i]->pBuffer);
00697         openmaxStandPort->pInternalBufferStorage[i]->pBuffer = NULL;
00698       }
00699       /*Retry more than once, if the tunneled component is not in Idle->Loaded State*/
00700       while(numRetry <TUNNEL_USE_BUFFER_RETRY) {
00701         eError=OMX_FreeBuffer(openmaxStandPort->hTunneledComponent,openmaxStandPort->nTunneledPort,openmaxStandPort->pInternalBufferStorage[i]);
00702         if(eError!=OMX_ErrorNone) {
00703           DEBUG(DEB_LEV_ERR,"Tunneled Component Couldn't free buffer %i \n",i);
00704           if((eError ==  OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) {
00705             DEBUG(DEB_LEV_ERR,"Waiting for next try %i \n",(int)numRetry);
00706             usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME);
00707             numRetry++;
00708             continue;
00709           }
00710           return eError;
00711         } else {
00712           break;
00713         }
00714       }
00715       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE;
00716 
00717       openmaxStandPort->nNumAssignedBuffers--;
00718       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00719 
00720       if (openmaxStandPort->nNumAssignedBuffers == 0) {
00721         openmaxStandPort->sPortParam.bPopulated = OMX_FALSE;
00722         openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE;
00723         //tsem_up(openmaxStandPort->pAllocSem);
00724       }
00725     }
00726   }
00727   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Qelem=%d BSem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem,openmaxStandPort->pBufferSem->semval);
00728   return OMX_ErrorNone;
00729 }
00730 
00736 OMX_ERRORTYPE base_port_SendBufferFunction(
00737   omx_base_PortType *openmaxStandPort,
00738   OMX_BUFFERHEADERTYPE* pBuffer) {
00739 
00740   OMX_ERRORTYPE err;
00741   OMX_U32 portIndex;
00742   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00743   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00744 #if NO_GST_OMX_PATCH
00745   unsigned int i;
00746 #endif
00747   portIndex = (openmaxStandPort->sPortParam.eDir == OMX_DirInput)?pBuffer->nInputPortIndex:pBuffer->nOutputPortIndex;
00748   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s portIndex %lu\n", __func__, portIndex);
00749 
00750   if (portIndex != openmaxStandPort->sPortParam.nPortIndex) {
00751     DEBUG(DEB_LEV_ERR, "In %s: wrong port for this operation portIndex=%d port->portIndex=%d\n", __func__, (int)portIndex, (int)openmaxStandPort->sPortParam.nPortIndex);
00752     return OMX_ErrorBadPortIndex;
00753   }
00754 
00755   if(omx_base_component_Private->state == OMX_StateInvalid) {
00756     DEBUG(DEB_LEV_ERR, "In %s: we are in OMX_StateInvalid\n", __func__);
00757     return OMX_ErrorInvalidState;
00758   }
00759 
00760   if(omx_base_component_Private->state != OMX_StateExecuting &&
00761     omx_base_component_Private->state != OMX_StatePause &&
00762     omx_base_component_Private->state != OMX_StateIdle) {
00763     DEBUG(DEB_LEV_ERR, "In %s: we are not in executing/paused/idle state, but in %d\n", __func__, omx_base_component_Private->state);
00764     return OMX_ErrorIncorrectStateOperation;
00765   }
00766   if (!PORT_IS_ENABLED(openmaxStandPort) || (PORT_IS_BEING_DISABLED(openmaxStandPort) && !PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) ||
00767       (omx_base_component_Private->transientState == OMX_TransStateExecutingToIdle && 
00768       (PORT_IS_TUNNELED(openmaxStandPort) && !PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)))) {
00769     DEBUG(DEB_LEV_ERR, "In %s: Port %d is disabled comp = %s \n", __func__, (int)portIndex,omx_base_component_Private->name);
00770     return OMX_ErrorIncorrectStateOperation;
00771   }
00772 
00773   /* Temporarily disable this check for gst-openmax */
00774 #if NO_GST_OMX_PATCH
00775   {
00776     OMX_BOOL foundBuffer = OMX_FALSE;
00777     if(pBuffer!=NULL && pBuffer->pBuffer!=NULL) {
00778       for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00779         if (pBuffer->pBuffer == openmaxStandPort->pInternalBufferStorage[i]->pBuffer) {
00780             foundBuffer = OMX_TRUE;
00781             break;
00782         }
00783       }
00784     }
00785     if (!foundBuffer) {
00786       return OMX_ErrorBadParameter;
00787     }
00788   }
00789 #endif
00790 
00791   if ((err = checkHeader(pBuffer, sizeof(OMX_BUFFERHEADERTYPE))) != OMX_ErrorNone) {
00792     DEBUG(DEB_LEV_ERR, "In %s: received wrong buffer header on input port\n", __func__);
00793     return err;
00794   }
00795     
00796   /* And notify the buffer management thread we have a fresh new buffer to manage */
00797   if(!PORT_IS_BEING_FLUSHED(openmaxStandPort) && !(PORT_IS_BEING_DISABLED(openmaxStandPort) && PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort))){
00798     queue(openmaxStandPort->pBufferQueue, pBuffer);
00799     tsem_up(openmaxStandPort->pBufferSem);
00800     DEBUG(DEB_LEV_PARAMS, "In %s Signalling bMgmtSem Port Index=%d\n",__func__, (int)portIndex);
00801     tsem_up(omx_base_component_Private->bMgmtSem);
00802   }else if(PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)){
00803     DEBUG(DEB_LEV_FULL_SEQ, "In %s: Comp %s received io:%d buffer\n", 
00804         __func__,omx_base_component_Private->name,(int)openmaxStandPort->sPortParam.nPortIndex);
00805     queue(openmaxStandPort->pBufferQueue, pBuffer);
00806     tsem_up(openmaxStandPort->pBufferSem);
00807   }
00808   else { // If port being flushed and not tunneled then return error
00809     DEBUG(DEB_LEV_FULL_SEQ, "In %s \n", __func__);
00810     return OMX_ErrorIncorrectStateOperation;
00811   }
00812   return OMX_ErrorNone;
00813 }
00814 
00818 OMX_ERRORTYPE base_port_ReturnBufferFunction(omx_base_PortType* openmaxStandPort,OMX_BUFFERHEADERTYPE* pBuffer){ 
00819   omx_base_component_PrivateType* omx_base_component_Private=openmaxStandPort->standCompContainer->pComponentPrivate;
00820   queue_t* pQueue = openmaxStandPort->pBufferQueue;
00821   tsem_t* pSem = openmaxStandPort->pBufferSem;
00822   OMX_ERRORTYPE eError = OMX_ErrorNone;
00823 
00824   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00825   if (PORT_IS_TUNNELED(openmaxStandPort) && 
00826     ! PORT_IS_BUFFER_SUPPLIER(openmaxStandPort)) {
00827     if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00828       pBuffer->nOutputPortIndex = openmaxStandPort->nTunneledPort;
00829       pBuffer->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00830       eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00831       if(eError != OMX_ErrorNone) {
00832         DEBUG(DEB_LEV_ERR, "In %s eError %08x in FillThis Buffer from Component %s Non-Supplier\n", 
00833         __func__, eError,omx_base_component_Private->name);
00834       }
00835     } else {
00836       pBuffer->nInputPortIndex = openmaxStandPort->nTunneledPort;
00837       pBuffer->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00838       eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00839       if(eError != OMX_ErrorNone) {
00840         DEBUG(DEB_LEV_ERR, "In %s eError %08x in EmptyThis Buffer from Component %s Non-Supplier\n", 
00841         __func__, eError,omx_base_component_Private->name);
00842       }
00843     }
00844   } 
00845   else if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort) && 
00846             !PORT_IS_BEING_FLUSHED(openmaxStandPort)) {
00847     if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00848       eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->FillThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00849       if(eError != OMX_ErrorNone) {
00850         DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in FillThis Buffer from Component %s Supplier\n", 
00851         __func__, eError,omx_base_component_Private->name);
00852         /*If Error Occured then queue the buffer*/
00853         queue(pQueue, pBuffer);
00854         tsem_up(pSem);
00855       }
00856     } else {
00857       eError = ((OMX_COMPONENTTYPE*)(openmaxStandPort->hTunneledComponent))->EmptyThisBuffer(openmaxStandPort->hTunneledComponent, pBuffer);
00858       if(eError != OMX_ErrorNone) {
00859         DEBUG(DEB_LEV_FULL_SEQ, "In %s eError %08x in EmptyThis Buffer from Component %s Supplier\n", 
00860         __func__, eError,omx_base_component_Private->name);
00861         /*If Error Occured then queue the buffer*/
00862         queue(pQueue, pBuffer);
00863         tsem_up(pSem);
00864       }
00865     }
00866   }else if (! PORT_IS_TUNNELED(openmaxStandPort)){
00867     (*(openmaxStandPort->BufferProcessedCallback))(
00868       openmaxStandPort->standCompContainer,
00869       omx_base_component_Private->callbackData,
00870       pBuffer);
00871   }
00872   else {
00873     queue(pQueue,pBuffer);
00874     openmaxStandPort->nNumBufferFlushed++;
00875   }
00876 
00877   return OMX_ErrorNone;
00878 }
00879 
00880 
00881 OMX_ERRORTYPE base_port_ComponentTunnelRequest(omx_base_PortType* openmaxStandPort,OMX_IN  OMX_HANDLETYPE hTunneledComp,OMX_IN  OMX_U32 nTunneledPort,OMX_INOUT  OMX_TUNNELSETUPTYPE* pTunnelSetup) {
00882   OMX_ERRORTYPE err = OMX_ErrorNone;
00883   OMX_PARAM_PORTDEFINITIONTYPE param;
00884   OMX_PARAM_BUFFERSUPPLIERTYPE pSupplier;
00885 
00886   if (pTunnelSetup == NULL || hTunneledComp == 0) {
00887     /* cancel previous tunnel */
00888     openmaxStandPort->hTunneledComponent = 0;
00889     openmaxStandPort->nTunneledPort = 0;
00890     openmaxStandPort->nTunnelFlags = 0;
00891     openmaxStandPort->eBufferSupplier=OMX_BufferSupplyUnspecified;
00892     return OMX_ErrorNone;
00893   }
00894 
00895   if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00896     /* Get Port Definition of the Tunnelled Component*/
00897     param.nPortIndex=nTunneledPort;
00898     setHeader(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00899     err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, &param);
00901     if (err != OMX_ErrorNone) {
00902       DEBUG(DEB_LEV_ERR,"In %s Tunneled Port Definition error=0x%08x Line=%d\n",__func__,err,__LINE__);
00903       // compatibility not reached
00904       return OMX_ErrorPortsNotCompatible;
00905     }
00906     openmaxStandPort->nNumTunnelBuffer=param.nBufferCountMin;
00907     if(param.eDomain!=openmaxStandPort->sPortParam.eDomain) {
00908       return OMX_ErrorPortsNotCompatible;
00909     }
00910     if(param.eDomain==OMX_PortDomainAudio) {
00911       if(param.format.audio.eEncoding == OMX_AUDIO_CodingMax) {
00912         return OMX_ErrorPortsNotCompatible;
00913       }
00914     } else if(param.eDomain==OMX_PortDomainVideo) {
00915       if(param.format.video.eCompressionFormat == OMX_VIDEO_CodingMax) {
00916         return OMX_ErrorPortsNotCompatible;
00917       }
00918     }
00919 
00920     /* Get Buffer Supplier type of the Tunnelled Component*/
00921     pSupplier.nPortIndex=nTunneledPort;
00922     setHeader(&pSupplier, sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE));
00923     err = OMX_GetParameter(hTunneledComp, OMX_IndexParamCompBufferSupplier, &pSupplier);
00924     if (err != OMX_ErrorNone) {
00925       // compatibility not reached
00926       DEBUG(DEB_LEV_ERR,"In %s Tunneled Buffer Supplier error=0x%08x Line=%d\n",__func__,err,__LINE__);
00927       return OMX_ErrorPortsNotCompatible;
00928     } else {
00929       DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Port eBufferSupplier=%x\n",pSupplier.eBufferSupplier);
00930     }
00931 
00932     // store the current callbacks, if defined
00933     openmaxStandPort->hTunneledComponent = hTunneledComp;
00934     openmaxStandPort->nTunneledPort = nTunneledPort;
00935     openmaxStandPort->nTunnelFlags = 0;
00936     // Negotiation
00937     if (pTunnelSetup->nTunnelFlags & OMX_PORTTUNNELFLAG_READONLY) {
00938       // the buffer provider MUST be the output port provider
00939       pTunnelSetup->eSupplier = OMX_BufferSupplyInput;
00940       openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER; 
00941       openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput;
00942     } else {
00943       if (pTunnelSetup->eSupplier == OMX_BufferSupplyInput) {
00944         openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
00945         openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput;
00946       } else if (pTunnelSetup->eSupplier == OMX_BufferSupplyUnspecified) {
00947         pTunnelSetup->eSupplier = OMX_BufferSupplyInput;
00948         openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
00949         openmaxStandPort->eBufferSupplier=OMX_BufferSupplyInput;
00950       }
00951     }
00952     openmaxStandPort->nTunnelFlags |= TUNNEL_ESTABLISHED;
00953 
00954     /* Set Buffer Supplier type of the Tunnelled Component after final negotiation*/
00955     pSupplier.nPortIndex=nTunneledPort;
00956     pSupplier.eBufferSupplier=openmaxStandPort->eBufferSupplier;
00957     err = OMX_SetParameter(hTunneledComp, OMX_IndexParamCompBufferSupplier, &pSupplier);
00958     if (err != OMX_ErrorNone) {
00959       // compatibility not reached
00960       DEBUG(DEB_LEV_ERR,"In %s Tunneled Buffer Supplier error=0x%08x Line=%d\n",__func__,err,__LINE__);
00961       openmaxStandPort->nTunnelFlags=0;
00962       return OMX_ErrorPortsNotCompatible;
00963     }
00964   } else {
00965     // output port
00966     // all the consistency checks are under other component responsibility
00967 
00968     /* Get Port Definition of the Tunnelled Component*/
00969     param.nPortIndex=nTunneledPort;
00970     setHeader(&param, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00971     err = OMX_GetParameter(hTunneledComp, OMX_IndexParamPortDefinition, &param);
00972     if (err != OMX_ErrorNone) {
00973       DEBUG(DEB_LEV_ERR,"In %s Tunneled Port Definition error=0x%08x Line=%d\n",__func__,err,__LINE__);
00974       // compatibility not reached
00975       return OMX_ErrorPortsNotCompatible;
00976     }
00977     if(param.eDomain!=openmaxStandPort->sPortParam.eDomain) {
00978       return OMX_ErrorPortsNotCompatible;
00979     }
00980 
00981     if(param.eDomain==OMX_PortDomainAudio) {
00982       if(param.format.audio.eEncoding == OMX_AUDIO_CodingMax) {
00983         return OMX_ErrorPortsNotCompatible;
00984       }
00985     } else if(param.eDomain==OMX_PortDomainVideo) {
00986       if(param.format.video.eCompressionFormat == OMX_VIDEO_CodingMax) {
00987         return OMX_ErrorPortsNotCompatible;
00988       }
00989     }
00990 
00991     openmaxStandPort->nNumTunnelBuffer=param.nBufferCountMin;
00992 
00993     openmaxStandPort->hTunneledComponent = hTunneledComp;
00994     openmaxStandPort->nTunneledPort = nTunneledPort;
00995     pTunnelSetup->eSupplier = OMX_BufferSupplyOutput;
00996     openmaxStandPort->nTunnelFlags |= TUNNEL_IS_SUPPLIER;
00997     openmaxStandPort->nTunnelFlags |= TUNNEL_ESTABLISHED;
00998 
00999     openmaxStandPort->eBufferSupplier=OMX_BufferSupplyOutput;
01000   }
01001   return OMX_ErrorNone;
01002 }

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