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

Generated for OpenMAX Bellagio rel. 0.9.0 by  doxygen 1.5.1
SourceForge.net Logo