00001
00032 #include <omxcore.h>
00033 #include <omx_base_source.h>
00034
00035 OMX_ERRORTYPE omx_base_source_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName) {
00036
00037 OMX_ERRORTYPE err = OMX_ErrorNone;
00038 omx_base_source_PrivateType* omx_base_source_Private;
00039
00040 if (openmaxStandComp->pComponentPrivate) {
00041 omx_base_source_Private = (omx_base_source_PrivateType*)openmaxStandComp->pComponentPrivate;
00042 } else {
00043 omx_base_source_Private = malloc(sizeof(omx_base_source_PrivateType));
00044 if (!omx_base_source_Private) {
00045 return OMX_ErrorInsufficientResources;
00046 }
00047 }
00048
00049
00050
00051 err = omx_base_component_Constructor(openmaxStandComp, cComponentName);
00052
00053
00054
00055 omx_base_source_Private = openmaxStandComp->pComponentPrivate;
00056 omx_base_source_Private->BufferMgmtFunction = omx_base_source_BufferMgmtFunction;
00057
00058 return err;
00059 }
00060
00061 OMX_ERRORTYPE omx_base_source_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00062
00063 return omx_base_component_Destructor(openmaxStandComp);
00064 }
00065
00071 void* omx_base_source_BufferMgmtFunction (void* param) {
00072
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_source_PrivateType* omx_base_source_Private = (omx_base_source_PrivateType*)omx_base_component_Private;
00076 omx_base_PortType *pOutPort = (omx_base_PortType *)omx_base_source_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
00077 tsem_t* pOutputSem = pOutPort->pBufferSem;
00078 queue_t* pOutputQueue = pOutPort->pBufferQueue;
00079 OMX_BUFFERHEADERTYPE* pOutputBuffer = NULL;
00080 OMX_COMPONENTTYPE* target_component;
00081 OMX_BOOL isOutputBufferNeeded = OMX_TRUE;
00082 int outBufExchanged = 0;
00083
00084 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s \n", __func__);
00085 while(omx_base_component_Private->state == OMX_StateIdle || omx_base_component_Private->state == OMX_StateExecuting ||
00086 omx_base_component_Private->state == OMX_StatePause || omx_base_component_Private->transientState == OMX_TransStateLoadedToIdle){
00087
00088
00089 pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
00090 while( PORT_IS_BEING_FLUSHED(pOutPort)) {
00091 pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);
00092
00093 if(isOutputBufferNeeded == OMX_FALSE) {
00094 pOutPort->ReturnBufferFunction(pOutPort, pOutputBuffer);
00095 outBufExchanged--;
00096 pOutputBuffer = NULL;
00097 isOutputBufferNeeded = OMX_TRUE;
00098 DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output buffer\n");
00099 }
00100 DEBUG(DEB_LEV_FULL_SEQ, "In %s signalling flush all condition \n", __func__);
00101
00102 pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
00103 pthread_cond_signal(&omx_base_source_Private->flush_all_condition);
00104 pthread_cond_wait(&omx_base_source_Private->flush_condition, &omx_base_source_Private->flush_mutex);
00105 }
00106 pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);
00107
00108
00109 if((isOutputBufferNeeded==OMX_TRUE && pOutputSem->semval==0) &&
00110 (omx_base_source_Private->state != OMX_StateLoaded && omx_base_source_Private->state != OMX_StateInvalid)) {
00111 DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for output buffer \n");
00112 tsem_down(omx_base_source_Private->bMgmtSem);
00113 }
00114
00115 if(omx_base_source_Private->state == OMX_StateLoaded || omx_base_source_Private->state == OMX_StateInvalid) {
00116 DEBUG(DEB_LEV_FULL_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00117 break;
00118 }
00119
00120 DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for output buffer semval=%d \n",pOutputSem->semval);
00121 if(pOutputSem->semval > 0 && isOutputBufferNeeded == OMX_TRUE ) {
00122 tsem_down(pOutputSem);
00123 if(pOutputQueue->nelem>0){
00124 outBufExchanged++;
00125 isOutputBufferNeeded = OMX_FALSE;
00126 pOutputBuffer = dequeue(pOutputQueue);
00127 if(pOutputBuffer == NULL){
00128 DEBUG(DEB_LEV_ERR, "In %s Had NULL output buffer!!\n",__func__);
00129 break;
00130 }
00131 }
00132 }
00133
00134 if(isOutputBufferNeeded == OMX_FALSE) {
00135 if(pOutputBuffer->nFlags == OMX_BUFFERFLAG_EOS) {
00136 DEBUG(DEB_LEV_SIMPLE_SEQ, "Detected EOS flags in output buffer\n");
00137
00138 (*(omx_base_component_Private->callbacks->EventHandler))
00139 (openmaxStandComp,
00140 omx_base_component_Private->callbackData,
00141 OMX_EventBufferFlag,
00142 0,
00143 pOutputBuffer->nFlags,
00144 NULL);
00145 pOutputBuffer->nFlags = 0;
00146 }
00147 if(omx_base_source_Private->pMark!=NULL){
00148 omx_base_source_Private->pMark=NULL;
00149 }
00150 target_component = (OMX_COMPONENTTYPE*)pOutputBuffer->hMarkTargetComponent;
00151 if(target_component == (OMX_COMPONENTTYPE *)openmaxStandComp) {
00152
00153 (*(omx_base_component_Private->callbacks->EventHandler))
00154 (openmaxStandComp,
00155 omx_base_component_Private->callbackData,
00156 OMX_EventMark,
00157 1,
00158 0,
00159 pOutputBuffer->pMarkData);
00160 } else if(pOutputBuffer->hMarkTargetComponent != NULL) {
00161
00162 DEBUG(DEB_LEV_FULL_SEQ, "Can't Pass Mark. This is a Source!!\n");
00163 }
00164
00165 if (omx_base_source_Private->BufferMgmtCallback && pOutputBuffer->nFilledLen == 0) {
00166 (*(omx_base_source_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer);
00167 } else {
00168
00169 pOutputBuffer->nFilledLen = 0;
00170 }
00171 if(omx_base_source_Private->state == OMX_StatePause && !PORT_IS_BEING_FLUSHED(pOutPort)) {
00172
00173 tsem_wait(omx_base_source_Private->bStateSem);
00174 }
00175
00176
00177 if(pOutputBuffer->nFilledLen != 0 || pOutputBuffer->nFlags == OMX_BUFFERFLAG_EOS) {
00178 pOutPort->ReturnBufferFunction(pOutPort, pOutputBuffer);
00179 outBufExchanged--;
00180 pOutputBuffer = NULL;
00181 isOutputBufferNeeded = OMX_TRUE;
00182 }
00183
00184 }
00185 }
00186 DEBUG(DEB_LEV_SIMPLE_SEQ, "Exiting Buffer Management Thread\n");
00187 return NULL;
00188 }
00189
00196 void* omx_base_source_twoport_BufferMgmtFunction (void* param) {
00197 OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
00198 omx_base_component_PrivateType* omx_base_component_Private=(omx_base_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00199 omx_base_source_PrivateType* omx_base_source_Private = (omx_base_source_PrivateType*)omx_base_component_Private;
00200 omx_base_PortType *pOutPort[2];
00201 tsem_t* pOutputSem[2];
00202 queue_t* pOutputQueue[2];
00203 OMX_BUFFERHEADERTYPE* pOutputBuffer[2];
00204 OMX_COMPONENTTYPE* target_component;
00205 OMX_BOOL isOutputBufferNeeded[2];
00206 int i,outBufExchanged[2];
00207
00208 pOutPort[0]=(omx_base_PortType *)omx_base_source_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
00209 pOutPort[1]=(omx_base_PortType *)omx_base_source_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX_1];
00210 pOutputSem[0] = pOutPort[0]->pBufferSem;
00211 pOutputSem[1] = pOutPort[1]->pBufferSem;
00212 pOutputQueue[0] = pOutPort[0]->pBufferQueue;
00213 pOutputQueue[1] = pOutPort[1]->pBufferQueue;
00214 pOutputBuffer[1]= pOutputBuffer[0]=NULL;
00215 isOutputBufferNeeded[0]=isOutputBufferNeeded[1]=OMX_TRUE;
00216 outBufExchanged[0]=outBufExchanged[1]=0;
00217
00218 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00219 while(omx_base_source_Private->state == OMX_StateIdle || omx_base_source_Private->state == OMX_StateExecuting || omx_base_source_Private->state == OMX_StatePause ||
00220 omx_base_source_Private->transientState == OMX_TransStateLoadedToIdle){
00221
00222
00223 pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
00224 while( PORT_IS_BEING_FLUSHED(pOutPort[0]) ||
00225 PORT_IS_BEING_FLUSHED(pOutPort[1])) {
00226 pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);
00227
00228 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",
00229 __func__,outBufExchanged[0],isOutputBufferNeeded[0],outBufExchanged[1],isOutputBufferNeeded[1],pOutputSem[0]->semval,pOutputSem[1]->semval);
00230
00231 if(isOutputBufferNeeded[1]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[1])) {
00232 pOutPort[1]->ReturnBufferFunction(pOutPort[1],pOutputBuffer[1]);
00233 outBufExchanged[1]--;
00234 pOutputBuffer[1]=NULL;
00235 isOutputBufferNeeded[1]=OMX_TRUE;
00236 DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output 1 buffer\n");
00237 }
00238
00239 if(isOutputBufferNeeded[0]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pOutPort[0])) {
00240 pOutPort[0]->ReturnBufferFunction(pOutPort[0],pOutputBuffer[0]);
00241 outBufExchanged[0]--;
00242 pOutputBuffer[0]=NULL;
00243 isOutputBufferNeeded[0]=OMX_TRUE;
00244 DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning output 0 buffer\n");
00245 }
00246
00247 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",
00248 __func__,outBufExchanged[0],isOutputBufferNeeded[0],outBufExchanged[1],isOutputBufferNeeded[1],pOutputSem[0]->semval,pOutputSem[1]->semval);
00249
00250 pthread_mutex_lock(&omx_base_source_Private->flush_mutex);
00251 pthread_cond_signal(&omx_base_source_Private->flush_all_condition);
00252 pthread_cond_wait(&omx_base_source_Private->flush_condition,&omx_base_source_Private->flush_mutex);
00253 }
00254 pthread_mutex_unlock(&omx_base_source_Private->flush_mutex);
00255
00256
00257 if((isOutputBufferNeeded[0]==OMX_TRUE && pOutputSem[0]->semval==0) &&
00258 (omx_base_source_Private->state != OMX_StateLoaded && omx_base_source_Private->state != OMX_StateInvalid)) {
00259
00260 DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next output buffer 0\n");
00261 tsem_down(omx_base_source_Private->bMgmtSem);
00262
00263 }
00264 if(omx_base_source_Private->state == OMX_StateLoaded || omx_base_source_Private->state == OMX_StateInvalid) {
00265 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00266 break;
00267 }
00268 if((isOutputBufferNeeded[1]==OMX_TRUE && pOutputSem[1]->semval==0) &&
00269 (omx_base_source_Private->state != OMX_StateLoaded && omx_base_source_Private->state != OMX_StateInvalid) &&
00270 !(PORT_IS_BEING_FLUSHED(pOutPort[0]) || PORT_IS_BEING_FLUSHED(pOutPort[1]))) {
00271
00272 DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next output buffer 1\n");
00273 tsem_down(omx_base_source_Private->bMgmtSem);
00274
00275 }
00276 if(omx_base_source_Private->state == OMX_StateLoaded || omx_base_source_Private->state == OMX_StateInvalid) {
00277 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00278 break;
00279 }
00280
00281 DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for output buffer 0 semval=%d \n",pOutputSem[0]->semval);
00282 if(pOutputSem[0]->semval>0 && isOutputBufferNeeded[0]==OMX_TRUE ) {
00283 tsem_down(pOutputSem[0]);
00284 if(pOutputQueue[0]->nelem>0){
00285 outBufExchanged[0]++;
00286 isOutputBufferNeeded[0]=OMX_FALSE;
00287 pOutputBuffer[0] = dequeue(pOutputQueue[0]);
00288 if(pOutputBuffer[0] == NULL){
00289 DEBUG(DEB_LEV_ERR, "Had NULL output buffer!!\n");
00290 break;
00291 }
00292 }
00293 }
00294
00295 if(pOutputSem[1]->semval>0 && isOutputBufferNeeded[1]==OMX_TRUE) {
00296 tsem_down(pOutputSem[1]);
00297 if(pOutputQueue[1]->nelem>0){
00298 outBufExchanged[1]++;
00299 isOutputBufferNeeded[1]=OMX_FALSE;
00300 pOutputBuffer[1] = dequeue(pOutputQueue[1]);
00301 if(pOutputBuffer[1] == NULL){
00302 DEBUG(DEB_LEV_ERR, "Had NULL output buffer!! op is=%d,iq=%d\n",pOutputSem[1]->semval,pOutputQueue[1]->nelem);
00303 break;
00304 }
00305 }
00306 }
00307
00308 for(i=0;i < (omx_base_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts +
00309 omx_base_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts +
00310 omx_base_component_Private->sPortTypesParam[OMX_PortDomainImage].nPorts +
00311 omx_base_component_Private->sPortTypesParam[OMX_PortDomainOther].nPorts -1);i++) {
00312
00313 if(omx_base_source_Private->ports[i]->sPortParam.eDomain!=OMX_PortDomainOther){
00314
00315 if(isOutputBufferNeeded[i]==OMX_FALSE) {
00316 if(omx_base_source_Private->pMark!=NULL){
00317 pOutputBuffer[i]->hMarkTargetComponent=omx_base_source_Private->pMark->hMarkTargetComponent;
00318 pOutputBuffer[i]->pMarkData=omx_base_source_Private->pMark->pMarkData;
00319 omx_base_source_Private->pMark=NULL;
00320 }
00321 target_component=(OMX_COMPONENTTYPE*)pOutputBuffer[i]->hMarkTargetComponent;
00322 if(target_component==(OMX_COMPONENTTYPE *)openmaxStandComp) {
00323
00324 (*(omx_base_source_Private->callbacks->EventHandler))
00325 (openmaxStandComp,
00326 omx_base_source_Private->callbackData,
00327 OMX_EventMark,
00328 1,
00329 i,
00330 pOutputBuffer[i]->pMarkData);
00331 } else if(pOutputBuffer[i]->hMarkTargetComponent!=NULL){
00332
00333 pOutputBuffer[i]->pMarkData=NULL;
00334 }
00335
00336 if (omx_base_source_Private->BufferMgmtCallback && pOutputBuffer[i]->nFilledLen == 0) {
00337
00338 (*(omx_base_source_Private->BufferMgmtCallback))(openmaxStandComp, pOutputBuffer[i]);
00339 } else {
00340
00341 pOutputBuffer[i]->nFilledLen = 0;
00342 }
00343
00344 if(pOutputBuffer[i]->nFlags==OMX_BUFFERFLAG_EOS && pOutputBuffer[i]->nFilledLen==0) {
00345 DEBUG(DEB_LEV_FULL_SEQ, "Detected EOS flags in input buffer filled len=%d\n", (int)pOutputBuffer[i]->nFilledLen);
00346 (*(omx_base_source_Private->callbacks->EventHandler))
00347 (openmaxStandComp,
00348 omx_base_source_Private->callbackData,
00349 OMX_EventBufferFlag,
00350 i,
00351 pOutputBuffer[i]->nFlags,
00352 NULL);
00353 }
00354 if(omx_base_source_Private->state==OMX_StatePause && !(PORT_IS_BEING_FLUSHED(pOutPort[0]) || PORT_IS_BEING_FLUSHED(pOutPort[1]))) {
00355
00356 tsem_wait(omx_base_component_Private->bStateSem);
00357 }
00358
00359
00360 if(pOutputBuffer[i]->nFilledLen!=0 || pOutputBuffer[i]->nFlags==OMX_BUFFERFLAG_EOS){
00361 pOutPort[i]->ReturnBufferFunction(pOutPort[i],pOutputBuffer[i]);
00362 outBufExchanged[i]--;
00363 pOutputBuffer[i]=NULL;
00364 isOutputBufferNeeded[i]=OMX_TRUE;
00365 }
00366 }
00367 }
00368 }
00369 }
00370 DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
00371 return NULL;
00372 }