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

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