omx_base_filter.c

Go to the documentation of this file.
00001 
00032 #include <omxcore.h>
00033 
00034 #include "omx_base_filter.h"
00035 
00036 OMX_ERRORTYPE omx_base_filter_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00037   OMX_ERRORTYPE err = OMX_ErrorNone;    
00038   omx_base_filter_PrivateType* omx_base_filter_Private;
00039 
00040   if (openmaxStandComp->pComponentPrivate) {
00041     omx_base_filter_Private = (omx_base_filter_PrivateType*)openmaxStandComp->pComponentPrivate;
00042   } else {
00043     omx_base_filter_Private = malloc(sizeof(omx_base_filter_PrivateType));
00044     if (!omx_base_filter_Private) {
00045       return OMX_ErrorInsufficientResources;
00046     }
00047     openmaxStandComp->pComponentPrivate=omx_base_filter_Private;
00048   }
00049 
00050   /* Call the base class constructory */
00051   err = omx_base_component_Constructor(openmaxStandComp,cComponentName);
00052 
00053   /* here we can override whatever defaults the base_component constructor set
00054   * e.g. we can override the function pointers in the private struct */
00055   omx_base_filter_Private = openmaxStandComp->pComponentPrivate;
00056 
00057   omx_base_filter_Private->sPortTypesParam.nPorts = 2;
00058   omx_base_filter_Private->sPortTypesParam.nStartPortNumber = 0;    
00059 
00060   omx_base_filter_Private->BufferMgmtFunction = omx_base_filter_BufferMgmtFunction;
00061 
00062   return err;
00063 }
00064 
00065 OMX_ERRORTYPE omx_base_filter_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00066   
00067   return omx_base_component_Destructor(openmaxStandComp);
00068 }
00069 
00075 void* omx_base_filter_BufferMgmtFunction (void* param) {
00076   OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
00077   omx_base_component_PrivateType* omx_base_component_Private=(omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00078   omx_base_filter_PrivateType* omx_base_filter_Private = (omx_base_filter_PrivateType*)omx_base_component_Private;
00079   omx_base_PortType *pInPort=(omx_base_PortType *)omx_base_filter_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00080   omx_base_PortType *pOutPort=(omx_base_PortType *)omx_base_filter_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
00081   tsem_t* pInputSem = pInPort->pBufferSem;
00082   tsem_t* pOutputSem = pOutPort->pBufferSem;
00083   queue_t* pInputQueue = pInPort->pBufferQueue;
00084   queue_t* pOutputQueue = pOutPort->pBufferQueue;
00085   OMX_BUFFERHEADERTYPE* pOutputBuffer=NULL;
00086   OMX_BUFFERHEADERTYPE* pInputBuffer=NULL;
00087   OMX_COMPONENTTYPE* target_component;
00088   OMX_BOOL isInputBufferNeeded=OMX_TRUE,isOutputBufferNeeded=OMX_TRUE;
00089   int inBufExchanged=0,outBufExchanged=0;
00090 
00091   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00092   while(omx_base_filter_Private->state == OMX_StateIdle || omx_base_filter_Private->state == OMX_StateExecuting ||  omx_base_filter_Private->state == OMX_StatePause || 
00093     omx_base_filter_Private->transientState == OMX_TransStateLoadedToIdle){
00094 
00095     /*Wait till the ports are being flushed*/
00096     pthread_mutex_lock(&omx_base_filter_Private->flush_mutex);
00097     while( PORT_IS_BEING_FLUSHED(pInPort) || 
00098            PORT_IS_BEING_FLUSHED(pOutPort)) {
00099       pthread_mutex_unlock(&omx_base_filter_Private->flush_mutex);
00100       
00101       DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signalling flush all cond iE=%d,iF=%d,oE=%d,oF=%d iSemVal=%d,oSemval=%d\n", 
00102         __func__,inBufExchanged,isInputBufferNeeded,outBufExchanged,isOutputBufferNeeded,pInputSem->semval,pOutputSem->semval);
00103 
00104       if(isOutputBufferNeeded==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort)) {
00105         pOutPort->ReturnBufferFunction(pOutPort,pOutputBuffer);
00106         outBufExchanged--;
00107         pOutputBuffer=NULL;
00108         isOutputBufferNeeded=OMX_TRUE;
00109         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer\n");
00110       }
00111 
00112       if(isInputBufferNeeded==OMX_FALSE && PORT_IS_BEING_FLUSHED(pInPort)) {
00113         pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
00114         inBufExchanged--;
00115         pInputBuffer=NULL;
00116         isInputBufferNeeded=OMX_TRUE;
00117         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning input buffer\n");
00118       }
00119 
00120       DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signalling flush all cond iE=%d,iF=%d,oE=%d,oF=%d iSemVal=%d,oSemval=%d\n", 
00121         __func__,inBufExchanged,isInputBufferNeeded,outBufExchanged,isOutputBufferNeeded,pInputSem->semval,pOutputSem->semval);
00122   
00123       pthread_mutex_lock(&omx_base_filter_Private->flush_mutex);
00124       pthread_cond_signal(&omx_base_filter_Private->flush_all_condition);
00125       pthread_cond_wait(&omx_base_filter_Private->flush_condition,&omx_base_filter_Private->flush_mutex);
00126     }
00127     pthread_mutex_unlock(&omx_base_filter_Private->flush_mutex);
00128 
00129     /*No buffer to process. So wait here*/
00130     if((isInputBufferNeeded==OMX_TRUE && pInputSem->semval==0) && 
00131       (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid)) {
00132       //Signalled from EmptyThisBuffer or FillThisBuffer or some thing else
00133       DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next input/output buffer\n");
00134       tsem_down(omx_base_filter_Private->bMgmtSem);
00135       
00136     }
00137     if(omx_base_filter_Private->state == OMX_StateLoaded || omx_base_filter_Private->state == OMX_StateInvalid) {
00138       DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00139       break;
00140     }
00141     if((isOutputBufferNeeded==OMX_TRUE && pOutputSem->semval==0) && 
00142       (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid) &&
00143        !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
00144       //Signalled from EmptyThisBuffer or FillThisBuffer or some thing else
00145       DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next input/output buffer\n");
00146       tsem_down(omx_base_filter_Private->bMgmtSem);
00147       
00148     }
00149     if(omx_base_filter_Private->state == OMX_StateLoaded || omx_base_filter_Private->state == OMX_StateInvalid) {
00150       DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00151       break;
00152     }
00153  
00154     DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for input buffer semval=%d \n",pInputSem->semval);
00155     if(pInputSem->semval>0 && isInputBufferNeeded==OMX_TRUE ) {
00156       tsem_down(pInputSem);
00157       if(pInputQueue->nelem>0){
00158         inBufExchanged++;
00159         isInputBufferNeeded=OMX_FALSE;
00160         pInputBuffer = dequeue(pInputQueue);
00161         if(pInputBuffer == NULL){
00162           DEBUG(DEB_LEV_ERR, "Had NULL input buffer!!\n");
00163           break;
00164         }
00165       }
00166     }
00167     /*When we have input buffer to process then get one output buffer*/
00168     if(pOutputSem->semval>0 && isOutputBufferNeeded==OMX_TRUE) {
00169       tsem_down(pOutputSem);
00170       if(pOutputQueue->nelem>0){
00171         outBufExchanged++;
00172         isOutputBufferNeeded=OMX_FALSE;
00173         pOutputBuffer = dequeue(pOutputQueue);
00174         if(pOutputBuffer == NULL){
00175           DEBUG(DEB_LEV_ERR, "Had NULL output buffer!! op is=%d,iq=%d\n",pOutputSem->semval,pOutputQueue->nelem);
00176           break;
00177         }
00178       }
00179     }
00180 
00181     if(isInputBufferNeeded==OMX_FALSE && isOutputBufferNeeded==OMX_FALSE) {
00182        
00183       if(omx_base_filter_Private->pMark!=NULL){
00184         pOutputBuffer->hMarkTargetComponent=omx_base_filter_Private->pMark->hMarkTargetComponent;
00185         pOutputBuffer->pMarkData=omx_base_filter_Private->pMark->pMarkData;
00186         omx_base_filter_Private->pMark=NULL;
00187       }
00188       target_component=(OMX_COMPONENTTYPE*)pInputBuffer->hMarkTargetComponent;
00189       if(target_component==(OMX_COMPONENTTYPE *)openmaxStandComp) {
00190         /*Clear the mark and generate an event*/
00191         (*(omx_base_filter_Private->callbacks->EventHandler))
00192           (openmaxStandComp,
00193           omx_base_filter_Private->callbackData,
00194           OMX_EventMark, /* The command was completed */
00195           1, /* The commands was a OMX_CommandStateSet */
00196           0, /* The state has been changed in message->messageParam2 */
00197           pInputBuffer->pMarkData);
00198       } else if(pInputBuffer->hMarkTargetComponent!=NULL){
00199         /*If this is not the target component then pass the mark*/
00200         pOutputBuffer->hMarkTargetComponent = pInputBuffer->hMarkTargetComponent;
00201         pOutputBuffer->pMarkData = pInputBuffer->pMarkData;
00202         pInputBuffer->pMarkData=NULL;
00203       }
00204       pOutputBuffer->nTimeStamp = pInputBuffer->nTimeStamp;
00205 
00206       if (omx_base_filter_Private->BufferMgmtCallback && pInputBuffer->nFilledLen != 0) {
00207         (*(omx_base_filter_Private->BufferMgmtCallback))(openmaxStandComp, pInputBuffer, pOutputBuffer);
00208       } else {
00209         /*It no buffer management call back the explicitly consume input buffer*/
00210         pInputBuffer->nFilledLen = 0;
00211       }
00212       /*Input Buffer has been completely consumed. So, get new input buffer*/
00213       if(pInputBuffer->nFilledLen==0) {
00214         isInputBufferNeeded = OMX_TRUE;
00215       }
00216 
00217       if(pInputBuffer->nFlags==OMX_BUFFERFLAG_EOS && pInputBuffer->nFilledLen==0) {
00218         DEBUG(DEB_LEV_FULL_SEQ, "Detected EOS flags in input buffer filled len=%d\n", (int)pInputBuffer->nFilledLen);
00219         pOutputBuffer->nFlags=pInputBuffer->nFlags;
00220         pInputBuffer->nFlags=0;
00221         (*(omx_base_filter_Private->callbacks->EventHandler))
00222           (openmaxStandComp,
00223           omx_base_filter_Private->callbackData,
00224           OMX_EventBufferFlag, /* The command was completed */
00225           1, /* The commands was a OMX_CommandStateSet */
00226           pOutputBuffer->nFlags, /* The state has been changed in message->messageParam2 */
00227           NULL);
00228       }
00229       if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
00230         /*Waiting at paused state*/
00231         tsem_wait(omx_base_component_Private->bStateSem);
00232       }
00233 
00234       /*If EOS and Input buffer Filled Len Zero then Return output buffer immediately*/
00235       if(pOutputBuffer->nFilledLen!=0 || pOutputBuffer->nFlags==OMX_BUFFERFLAG_EOS){
00236         pOutPort->ReturnBufferFunction(pOutPort,pOutputBuffer);
00237         outBufExchanged--;
00238         pOutputBuffer=NULL;
00239         isOutputBufferNeeded=OMX_TRUE;
00240       }
00241     }
00242 
00243     DEBUG(DEB_LEV_FULL_SEQ, "Input buffer arrived\n");
00244 
00245     if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
00246       /*Waiting at paused state*/
00247       tsem_wait(omx_base_component_Private->bStateSem);
00248     }
00249 
00250     /*Input Buffer has been completely consumed. So, return input buffer*/
00251     if(isInputBufferNeeded == OMX_TRUE && pInputBuffer!=NULL) {
00252       pInPort->ReturnBufferFunction(pInPort,pInputBuffer);
00253       inBufExchanged--;
00254       pInputBuffer=NULL;
00255     }
00256   }
00257   DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
00258   return NULL;
00259 }
00260 
00261 

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