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
00051 err = omx_base_component_Constructor(openmaxStandComp,cComponentName);
00052
00053
00054
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
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
00127 if((isInputBufferNeeded==OMX_TRUE && pInputSem->semval==0) &&
00128 (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid)) {
00129
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
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
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
00188 (*(omx_base_filter_Private->callbacks->EventHandler))
00189 (openmaxStandComp,
00190 omx_base_filter_Private->callbackData,
00191 OMX_EventMark,
00192 1,
00193 0,
00194 pInputBuffer->pMarkData);
00195 } else if(pInputBuffer->hMarkTargetComponent!=NULL){
00196
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
00213 pInputBuffer->nFilledLen = 0;
00214 }
00215
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,
00228 1,
00229 pOutputBuffer->nFlags,
00230 NULL);
00231 }
00232 if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
00233
00234 tsem_wait(omx_base_component_Private->bStateSem);
00235 }
00236
00237
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
00250 tsem_wait(omx_base_component_Private->bStateSem);
00251 }
00252
00253
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