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