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->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
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
00130 if((isInputBufferNeeded==OMX_TRUE && pInputSem->semval==0) &&
00131 (omx_base_filter_Private->state != OMX_StateLoaded && omx_base_filter_Private->state != OMX_StateInvalid)) {
00132
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
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
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
00191 (*(omx_base_filter_Private->callbacks->EventHandler))
00192 (openmaxStandComp,
00193 omx_base_filter_Private->callbackData,
00194 OMX_EventMark,
00195 1,
00196 0,
00197 pInputBuffer->pMarkData);
00198 } else if(pInputBuffer->hMarkTargetComponent!=NULL){
00199
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
00210 pInputBuffer->nFilledLen = 0;
00211 }
00212
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,
00225 1,
00226 pOutputBuffer->nFlags,
00227 NULL);
00228 }
00229 if(omx_base_filter_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pInPort) || PORT_IS_BEING_FLUSHED(pOutPort))) {
00230
00231 tsem_wait(omx_base_component_Private->bStateSem);
00232 }
00233
00234
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
00247 tsem_wait(omx_base_component_Private->bStateSem);
00248 }
00249
00250
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