omx_base_sink.c

Go to the documentation of this file.
00001 
00031 #include <omxcore.h>
00032 
00033 #include <omx_base_sink.h>
00034 
00035 OMX_ERRORTYPE omx_base_sink_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00036   OMX_ERRORTYPE err = OMX_ErrorNone;  
00037   omx_base_sink_PrivateType* omx_base_sink_Private;
00038 
00039   if (openmaxStandComp->pComponentPrivate) {
00040     omx_base_sink_Private = (omx_base_sink_PrivateType*)openmaxStandComp->pComponentPrivate;
00041   } else {
00042     omx_base_sink_Private = malloc(sizeof(omx_base_sink_PrivateType));
00043     if (!omx_base_sink_Private) {
00044       return OMX_ErrorInsufficientResources;
00045     }
00046   }
00047 
00048   // we could create our own port structures here
00049   // fixme maybe the base class could use a "port factory" function pointer?  
00050   err = omx_base_component_Constructor(openmaxStandComp,cComponentName);
00051 
00052   /* here we can override whatever defaults the base_component constructor set
00053   * e.g. we can override the function pointers in the private struct  */
00054   omx_base_sink_Private = openmaxStandComp->pComponentPrivate;
00055 
00056   omx_base_sink_Private->BufferMgmtFunction = omx_base_sink_BufferMgmtFunction;
00057 
00058   return err;
00059 }
00060 
00061 OMX_ERRORTYPE omx_base_sink_Destructor(OMX_COMPONENTTYPE *openmaxStandComp)
00062 {
00063   return omx_base_component_Destructor(openmaxStandComp);
00064 }
00065 
00071 void* omx_base_sink_BufferMgmtFunction (void* param) {
00072   OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
00073   omx_base_component_PrivateType* omx_base_component_Private  = (omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00074   omx_base_sink_PrivateType*      omx_base_sink_Private       = (omx_base_sink_PrivateType*)omx_base_component_Private;
00075   omx_base_PortType               *pInPort                    = (omx_base_PortType *)omx_base_sink_Private->ports[OMX_BASE_SINK_INPUTPORT_INDEX];
00076   tsem_t*                         pInputSem                   = pInPort->pBufferSem;
00077   queue_t*                        pInputQueue                 = pInPort->pBufferQueue;
00078   OMX_BUFFERHEADERTYPE*           pInputBuffer                = NULL;
00079   OMX_COMPONENTTYPE*              target_component;
00080   OMX_BOOL                        isInputBufferNeeded         = OMX_TRUE;
00081   int                             inBufExchanged              = 0;
00082 
00083   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s \n", __func__);
00084   while(omx_base_component_Private->state == OMX_StateIdle || omx_base_component_Private->state == OMX_StateExecuting ||  omx_base_component_Private->state == OMX_StatePause || 
00085     omx_base_component_Private->transientState == OMX_TransStateLoadedToIdle){
00086 
00087     /*Wait till the ports are being flushed*/
00088     pthread_mutex_lock(&omx_base_sink_Private->flush_mutex);
00089     while( PORT_IS_BEING_FLUSHED(pInPort)) {
00090       pthread_mutex_unlock(&omx_base_sink_Private->flush_mutex);
00091 
00092       if(isInputBufferNeeded==OMX_FALSE) {
00093         pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
00094         inBufExchanged--;
00095         pInputBuffer=NULL;
00096         isInputBufferNeeded=OMX_TRUE;
00097         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning input buffer\n");
00098       }
00099       DEBUG(DEB_LEV_FULL_SEQ, "In %s signalling flush all condition \n", __func__);
00100       
00101       pthread_mutex_lock(&omx_base_sink_Private->flush_mutex);
00102       pthread_cond_signal(&omx_base_sink_Private->flush_all_condition);
00103       pthread_cond_wait(&omx_base_sink_Private->flush_condition,&omx_base_sink_Private->flush_mutex);
00104     }
00105     pthread_mutex_unlock(&omx_base_sink_Private->flush_mutex);
00106 
00107     /*No buffer to process. So wait here*/
00108     if((pInputSem->semval==0 && isInputBufferNeeded==OMX_TRUE ) && 
00109       (omx_base_sink_Private->state != OMX_StateLoaded && omx_base_sink_Private->state != OMX_StateInvalid)) {
00110       DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for input buffer \n");
00111       tsem_down(omx_base_sink_Private->bMgmtSem);
00112     }
00113 
00114     if(omx_base_sink_Private->state == OMX_StateLoaded || omx_base_sink_Private->state == OMX_StateInvalid) {
00115       DEBUG(DEB_LEV_FULL_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00116       break;
00117     }
00118 
00119     DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for input buffer semval=%d \n",pInputSem->semval);
00120     if(pInputSem->semval>0 && isInputBufferNeeded==OMX_TRUE ) {
00121       tsem_down(pInputSem);
00122       if(pInputQueue->nelem>0){
00123         inBufExchanged++;
00124         isInputBufferNeeded=OMX_FALSE;
00125         pInputBuffer = dequeue(pInputQueue);
00126         if(pInputBuffer == NULL){
00127           DEBUG(DEB_LEV_ERR, "Had NULL input buffer!!\n");
00128           break;
00129         }
00130       }
00131     }
00132     
00133     if(isInputBufferNeeded==OMX_FALSE) {
00134       if(pInputBuffer->nFlags==OMX_BUFFERFLAG_EOS) {
00135         DEBUG(DEB_LEV_SIMPLE_SEQ, "Detected EOS flags in input buffer\n");
00136         
00137         (*(omx_base_component_Private->callbacks->EventHandler))
00138           (openmaxStandComp,
00139           omx_base_component_Private->callbackData,
00140           OMX_EventBufferFlag, /* The command was completed */
00141           0, /* The commands was a OMX_CommandStateSet */
00142           pInputBuffer->nFlags, /* The state has been changed in message->messageParam2 */
00143           NULL);
00144         pInputBuffer->nFlags=0;
00145       }
00146       if(omx_base_sink_Private->pMark!=NULL){
00147          omx_base_sink_Private->pMark=NULL;
00148       }
00149       target_component=(OMX_COMPONENTTYPE*)pInputBuffer->hMarkTargetComponent;
00150       if(target_component==(OMX_COMPONENTTYPE *)openmaxStandComp) {
00151         /*Clear the mark and generate an event*/
00152         (*(omx_base_component_Private->callbacks->EventHandler))
00153           (openmaxStandComp,
00154           omx_base_component_Private->callbackData,
00155           OMX_EventMark, /* The command was completed */
00156           1, /* The commands was a OMX_CommandStateSet */
00157           0, /* The state has been changed in message->messageParam2 */
00158           pInputBuffer->pMarkData);
00159       } else if(pInputBuffer->hMarkTargetComponent!=NULL){
00160         /*If this is not the target component then pass the mark*/
00161         DEBUG(DEB_LEV_FULL_SEQ, "Can't Pass Mark. This is a Sink!!\n");
00162       }
00163       if (omx_base_sink_Private->BufferMgmtCallback && pInputBuffer->nFilledLen != 0) {
00164         (*(omx_base_sink_Private->BufferMgmtCallback))(openmaxStandComp, pInputBuffer);
00165       }
00166       else {
00167         /*If no buffer management call back the explicitly consume input buffer*/
00168         pInputBuffer->nFilledLen = 0;
00169       }
00170       /*Input Buffer has been completely consumed. So, get new input buffer*/
00171 
00172       if(omx_base_sink_Private->state==OMX_StatePause && !PORT_IS_BEING_FLUSHED(pInPort)) {
00173         /*Waiting at paused state*/
00174         tsem_wait(omx_base_sink_Private->bStateSem);
00175       }
00176 
00177       /*Input Buffer has been completely consumed. So, return input buffer*/
00178       if(pInputBuffer->nFilledLen==0) {
00179         pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
00180         inBufExchanged--;
00181         pInputBuffer=NULL;
00182         isInputBufferNeeded = OMX_TRUE;
00183       }
00184 
00185     }
00186   }
00187   DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
00188   return NULL;
00189 }

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