OpenMAXBellagio 0.9.3
omx_audiomixer_component.c
Go to the documentation of this file.
00001 
00027 #include <omxcore.h>
00028 #include <omx_base_audio_port.h>
00029 #include <omx_audiomixer_component.h>
00030 #include<OMX_Audio.h>
00031 
00032 /* Gain value */
00033 #define GAIN_VALUE 100.0f
00034 
00035 OMX_ERRORTYPE omx_audio_mixer_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName) {
00036   OMX_ERRORTYPE err = OMX_ErrorNone;
00037   omx_audio_mixer_component_PrivateType* omx_audio_mixer_component_Private;
00038   omx_audio_mixer_component_PortType *pPort;//,*inPort1, *outPort;
00039   OMX_U32 i;
00040 
00041   RM_RegisterComponent(MIXER_COMP_NAME, MAX_MIXER_COMPONENTS);
00042   if (!openmaxStandComp->pComponentPrivate) {
00043     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, allocating component\n",__func__);
00044     openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_audio_mixer_component_PrivateType));
00045     if(openmaxStandComp->pComponentPrivate == NULL) {
00046       return OMX_ErrorInsufficientResources;
00047     }
00048   } else {
00049     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, Error Component %p Already Allocated\n", __func__, openmaxStandComp->pComponentPrivate);
00050   }
00051 
00052   omx_audio_mixer_component_Private = openmaxStandComp->pComponentPrivate;
00053   omx_audio_mixer_component_Private->ports = NULL;
00054 
00056   err = omx_base_filter_Constructor(openmaxStandComp, cComponentName);
00057 
00058   /*Assuming 4 input and 1 output ports*/
00059   omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nStartPortNumber = 0;
00060   omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts = MAX_PORTS;
00061 
00063   if (omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts && !omx_audio_mixer_component_Private->ports) {
00064     omx_audio_mixer_component_Private->ports = calloc(omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts, sizeof(omx_base_PortType *));
00065     if (!omx_audio_mixer_component_Private->ports) {
00066       return OMX_ErrorInsufficientResources;
00067     }
00068     for (i=0; i < omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++) {
00069       omx_audio_mixer_component_Private->ports[i] = calloc(1, sizeof(omx_audio_mixer_component_PortType));
00070       if (!omx_audio_mixer_component_Private->ports[i]) {
00071         return OMX_ErrorInsufficientResources;
00072       }
00073     }
00074   }
00075 
00076   /* construct all input ports */
00077   for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts-1;i++) {
00078     base_audio_port_Constructor(openmaxStandComp, &omx_audio_mixer_component_Private->ports[i], i, OMX_TRUE);
00079   }
00080 
00081   /* construct one output port */
00082   base_audio_port_Constructor(openmaxStandComp, &omx_audio_mixer_component_Private->ports[omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts-1], omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts-1, OMX_FALSE);
00083 
00085   for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts;i++) {
00086     pPort = (omx_audio_mixer_component_PortType *) omx_audio_mixer_component_Private->ports[i];
00087 
00088     pPort->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;
00089     pPort->gain = GAIN_VALUE; //100.0f; // default gain
00090 
00091     setHeader(&pPort->pAudioPcmMode,sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
00092     pPort->pAudioPcmMode.nPortIndex = i;
00093     pPort->pAudioPcmMode.nChannels = 2;
00094     pPort->pAudioPcmMode.eNumData = OMX_NumericalDataSigned;
00095     pPort->pAudioPcmMode.eEndian = OMX_EndianBig;
00096     pPort->pAudioPcmMode.bInterleaved = OMX_TRUE;
00097     pPort->pAudioPcmMode.nBitPerSample = 16;
00098     pPort->pAudioPcmMode.nSamplingRate = 44100;
00099     pPort->pAudioPcmMode.ePCMMode = OMX_AUDIO_PCMModeLinear;
00100 
00101     setHeader(&pPort->sVolume,sizeof(OMX_AUDIO_CONFIG_VOLUMETYPE));
00102     pPort->sVolume.nPortIndex = i;
00103     pPort->sVolume.bLinear = OMX_TRUE;           
00105     pPort->sVolume.sVolume.nValue = (OMX_S32)GAIN_VALUE;
00106     pPort->sVolume.sVolume.nMin = 0;   
00107     pPort->sVolume.sVolume.nMax = (OMX_S32)GAIN_VALUE;
00108   }
00109 
00110   omx_audio_mixer_component_Private->destructor = omx_audio_mixer_component_Destructor;
00111   openmaxStandComp->SetParameter = omx_audio_mixer_component_SetParameter;
00112   openmaxStandComp->GetParameter = omx_audio_mixer_component_GetParameter;
00113   openmaxStandComp->GetConfig = omx_audio_mixer_component_GetConfig;
00114   openmaxStandComp->SetConfig = omx_audio_mixer_component_SetConfig;
00115   omx_audio_mixer_component_Private->BufferMgmtCallback = omx_audio_mixer_component_BufferMgmtCallback;
00116   omx_audio_mixer_component_Private->BufferMgmtFunction = omx_audio_mixer_BufferMgmtFunction;
00117 
00118   /* resource management special section */
00119   omx_audio_mixer_component_Private->nqualitylevels = MIXER_QUALITY_LEVELS;
00120   omx_audio_mixer_component_Private->currentQualityLevel = 1;
00121   omx_audio_mixer_component_Private->multiResourceLevel = malloc(sizeof(multiResourceDescriptor *) * MIXER_QUALITY_LEVELS);
00122   for (i = 0; i<MIXER_QUALITY_LEVELS; i++) {
00123       omx_audio_mixer_component_Private->multiResourceLevel[i] = malloc(sizeof(multiResourceDescriptor));
00124       omx_audio_mixer_component_Private->multiResourceLevel[i]->CPUResourceRequested = mixerQualityLevels[i * 2];
00125       omx_audio_mixer_component_Private->multiResourceLevel[i]->MemoryResourceRequested = mixerQualityLevels[i * 2 + 1];
00126   }
00127 
00128   return err;
00129 }
00130 
00131 
00134 OMX_ERRORTYPE omx_audio_mixer_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00135 
00136   omx_audio_mixer_component_PrivateType* omx_audio_mixer_component_Private = openmaxStandComp->pComponentPrivate;
00137   OMX_U32 i;
00138 
00139   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00140   /* frees port/s */
00141   if (omx_audio_mixer_component_Private->ports) {
00142     for (i=0; i < omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++) {
00143       if(omx_audio_mixer_component_Private->ports[i])
00144         omx_audio_mixer_component_Private->ports[i]->PortDestructor(omx_audio_mixer_component_Private->ports[i]);
00145     }
00146     free(omx_audio_mixer_component_Private->ports);
00147     omx_audio_mixer_component_Private->ports=NULL;
00148   }
00149 
00150   omx_base_filter_Destructor(openmaxStandComp);
00151 
00152   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s\n", __func__);
00153 
00154   return OMX_ErrorNone;
00155 }
00156 
00159 void omx_audio_mixer_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pInBuffer, OMX_BUFFERHEADERTYPE* pOutBuffer) {
00160   OMX_S32 denominator=0;
00161   OMX_U32 i,sampleCount = pInBuffer->nFilledLen / 2; // signed 16 bit samples assumed
00162   omx_audio_mixer_component_PrivateType* omx_audio_mixer_component_Private = openmaxStandComp->pComponentPrivate;
00163   omx_audio_mixer_component_PortType* pPort;
00164 
00165   for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts-1;i++) {
00166     pPort = (omx_audio_mixer_component_PortType*)omx_audio_mixer_component_Private->ports[i];
00167     if(PORT_IS_ENABLED(pPort)){
00168       denominator+=pPort->sVolume.sVolume.nValue;
00169     }
00170   }
00171 
00172   pPort = (omx_audio_mixer_component_PortType*)omx_audio_mixer_component_Private->ports[pInBuffer->nInputPortIndex];
00173 
00174   /*Copy the first buffer with appropriate gain*/
00175   if(pOutBuffer->nFilledLen == 0) {
00176     memset(pOutBuffer->pBuffer,0,pInBuffer->nFilledLen);
00177 
00178     for (i = 0; i < sampleCount; i++) {
00179       ((OMX_S16*) pOutBuffer->pBuffer)[i] = (OMX_S16)
00180               ((((OMX_S16*) pInBuffer->pBuffer)[i] * pPort->sVolume.sVolume.nValue ) / denominator);
00181     }
00182   } else { // For the second buffer add with the first buffer with gain
00183     for (i = 0; i < sampleCount; i++) {
00184       ((OMX_S16*) pOutBuffer->pBuffer)[i] += (OMX_S16)
00185                 ((((OMX_S16*) pInBuffer->pBuffer)[i] * pPort->sVolume.sVolume.nValue ) / denominator);
00186     }
00187   }
00188 
00189   pOutBuffer->nFilledLen = pInBuffer->nFilledLen;
00190   pInBuffer->nFilledLen=0;
00191 }
00192 
00194 OMX_ERRORTYPE omx_audio_mixer_component_SetConfig(
00195   OMX_HANDLETYPE hComponent,
00196   OMX_INDEXTYPE nIndex,
00197   OMX_PTR pComponentConfigStructure) {
00198 
00199   OMX_AUDIO_CONFIG_VOLUMETYPE* pVolume;
00200   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00201   omx_audio_mixer_component_PrivateType* omx_audio_mixer_component_Private = openmaxStandComp->pComponentPrivate;
00202   omx_audio_mixer_component_PortType * pPort;
00203   OMX_ERRORTYPE err = OMX_ErrorNone;
00204 
00205   switch (nIndex) {
00206     case OMX_IndexConfigAudioVolume :
00207       pVolume = (OMX_AUDIO_CONFIG_VOLUMETYPE*) pComponentConfigStructure;
00208       if(pVolume->sVolume.nValue > 100) {
00209         err =  OMX_ErrorBadParameter;
00210         break;
00211       }
00212 
00213       if (pVolume->nPortIndex <= omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts) {
00214         pPort= (omx_audio_mixer_component_PortType *)omx_audio_mixer_component_Private->ports[pVolume->nPortIndex];
00215         DEBUG(DEB_LEV_SIMPLE_SEQ, "Port %i Gain=%d\n",(int)pVolume->nPortIndex,(int)pVolume->sVolume.nValue);
00216         memcpy(&pPort->sVolume, pVolume, sizeof(OMX_AUDIO_CONFIG_VOLUMETYPE));
00217       } else {
00218         err = OMX_ErrorBadPortIndex;
00219       }
00220       break;
00221     default: // delegate to superclass
00222       err = omx_base_component_SetConfig(hComponent, nIndex, pComponentConfigStructure);
00223   }
00224   return err;
00225 }
00226 
00227 OMX_ERRORTYPE omx_audio_mixer_component_GetConfig(
00228   OMX_HANDLETYPE hComponent,
00229   OMX_INDEXTYPE nIndex,
00230   OMX_PTR pComponentConfigStructure) {
00231   OMX_AUDIO_CONFIG_VOLUMETYPE           *pVolume;
00232   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00233   omx_audio_mixer_component_PrivateType *omx_audio_mixer_component_Private = openmaxStandComp->pComponentPrivate;
00234   omx_audio_mixer_component_PortType    *pPort;
00235   OMX_ERRORTYPE err = OMX_ErrorNone;
00236 
00237   switch (nIndex) {
00238     case OMX_IndexConfigAudioVolume :
00239       pVolume = (OMX_AUDIO_CONFIG_VOLUMETYPE*) pComponentConfigStructure;
00240       if (pVolume->nPortIndex <= omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts) {
00241         pPort= (omx_audio_mixer_component_PortType *)omx_audio_mixer_component_Private->ports[pVolume->nPortIndex];
00242         memcpy(pVolume,&pPort->sVolume,sizeof(OMX_AUDIO_CONFIG_VOLUMETYPE));
00243       } else {
00244         err = OMX_ErrorBadPortIndex;
00245       }
00246       break;
00247     default :
00248       err = omx_base_component_GetConfig(hComponent, nIndex, pComponentConfigStructure);
00249   }
00250   return err;
00251 }
00252 
00253 OMX_ERRORTYPE omx_audio_mixer_component_SetParameter(
00254   OMX_HANDLETYPE hComponent,
00255   OMX_INDEXTYPE nParamIndex,
00256   OMX_PTR ComponentParameterStructure) {
00257 
00258   OMX_ERRORTYPE                   err = OMX_ErrorNone;
00259   OMX_AUDIO_PARAM_PORTFORMATTYPE  *pAudioPortFormat;
00260   OMX_PARAM_COMPONENTROLETYPE     *pComponentRole;
00261   OMX_U32                         portIndex;
00262   omx_audio_mixer_component_PortType *port;
00263 
00264   /* Check which structure we are being fed and make control its header */
00265   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00266   omx_audio_mixer_component_PrivateType* omx_audio_mixer_component_Private = openmaxStandComp->pComponentPrivate;
00267   if (ComponentParameterStructure == NULL) {
00268     return OMX_ErrorBadParameter;
00269   }
00270 
00271   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting parameter %i\n", nParamIndex);
00272   switch(nParamIndex) {
00273     case OMX_IndexParamAudioPortFormat:
00274       pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00275       portIndex = pAudioPortFormat->nPortIndex;
00276       err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00277       if(err!=OMX_ErrorNone) {
00278         DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err);
00279         break;
00280       }
00281       if (portIndex <= omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts) {
00282         port= (omx_audio_mixer_component_PortType *)omx_audio_mixer_component_Private->ports[portIndex];
00283         memcpy(&port->sAudioParam, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00284       } else {
00285         err = OMX_ErrorBadPortIndex;
00286       }
00287       break;
00288     case OMX_IndexParamStandardComponentRole:
00289       pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00290 
00291       if (omx_audio_mixer_component_Private->state != OMX_StateLoaded && omx_audio_mixer_component_Private->state != OMX_StateWaitForResources) {
00292         DEBUG(DEB_LEV_ERR, "In %s Incorrect State=%x lineno=%d\n",__func__,omx_audio_mixer_component_Private->state,__LINE__);
00293         return OMX_ErrorIncorrectStateOperation;
00294       }
00295 
00296       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
00297         break;
00298       }
00299 
00300       if (strcmp( (char*) pComponentRole->cRole, MIXER_COMP_ROLE)) {
00301         return OMX_ErrorBadParameter;
00302       }
00303       break;
00304     default:
00305       err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00306   }
00307   return err;
00308 }
00309 
00310 OMX_ERRORTYPE omx_audio_mixer_component_GetParameter(
00311   OMX_HANDLETYPE hComponent,
00312   OMX_INDEXTYPE nParamIndex,
00313   OMX_PTR ComponentParameterStructure) {
00314 
00315   OMX_AUDIO_PARAM_PORTFORMATTYPE  *pAudioPortFormat;
00316   OMX_AUDIO_PARAM_PCMMODETYPE     *pAudioPcmMode;
00317   OMX_PARAM_COMPONENTROLETYPE     *pComponentRole;
00318   OMX_ERRORTYPE                   err = OMX_ErrorNone;
00319   omx_audio_mixer_component_PortType    *port;
00320   OMX_COMPONENTTYPE                     *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00321   omx_audio_mixer_component_PrivateType *omx_audio_mixer_component_Private = openmaxStandComp->pComponentPrivate;
00322   if (ComponentParameterStructure == NULL) {
00323     return OMX_ErrorBadParameter;
00324   }
00325   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Getting parameter %i\n", nParamIndex);
00326   /* Check which structure we are being fed and fill its header */
00327   switch(nParamIndex) {
00328     case OMX_IndexParamAudioInit:
00329       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
00330         break;
00331       }
00332       memcpy(ComponentParameterStructure, &omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio], sizeof(OMX_PORT_PARAM_TYPE));
00333       break;
00334     case OMX_IndexParamAudioPortFormat:
00335       pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00336       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
00337         break;
00338       }
00339       if (pAudioPortFormat->nPortIndex <= omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts) {
00340         port= (omx_audio_mixer_component_PortType *)omx_audio_mixer_component_Private->ports[pAudioPortFormat->nPortIndex];
00341         memcpy(pAudioPortFormat, &port->sAudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00342       } else {
00343         err = OMX_ErrorBadPortIndex;
00344       }
00345       break;
00346     case OMX_IndexParamAudioPcm:
00347       pAudioPcmMode = (OMX_AUDIO_PARAM_PCMMODETYPE*)ComponentParameterStructure;
00348       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE))) != OMX_ErrorNone) {
00349         break;
00350       }
00351 
00352       if (pAudioPcmMode->nPortIndex <= omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts) {
00353         port= (omx_audio_mixer_component_PortType *)omx_audio_mixer_component_Private->ports[pAudioPcmMode->nPortIndex];
00354         memcpy(pAudioPcmMode, &port->pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
00355       } else {
00356         err = OMX_ErrorBadPortIndex;
00357       }
00358       break;
00359     case OMX_IndexParamStandardComponentRole:
00360       pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00361       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
00362         break;
00363       }
00364       strcpy( (char*) pComponentRole->cRole, MIXER_COMP_ROLE);
00365       break;
00366     default:
00367       err = omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00368   }
00369   return err;
00370 }
00371 
00372 int checkAnyPortBeingFlushed(omx_audio_mixer_component_PrivateType* omx_audio_mixer_component_Private) {
00373   omx_base_PortType *pPort;
00374   int ret = OMX_FALSE,i;
00375 
00376   if(omx_audio_mixer_component_Private->state == OMX_StateLoaded ||
00377      omx_audio_mixer_component_Private->state == OMX_StateInvalid) {
00378     return 0;
00379   }
00380 
00381   pthread_mutex_lock(&omx_audio_mixer_component_Private->flush_mutex);
00382   for (i=0; i < omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++) {
00383     pPort = omx_audio_mixer_component_Private->ports[i];
00384     if(PORT_IS_BEING_FLUSHED(pPort)) {
00385       ret = OMX_TRUE;
00386       break;
00387     }
00388   }
00389   pthread_mutex_unlock(&omx_audio_mixer_component_Private->flush_mutex);
00390 
00391   return ret;
00392 }
00393 
00399 void* omx_audio_mixer_BufferMgmtFunction (void* param) {
00400   OMX_COMPONENTTYPE* openmaxStandComp = (OMX_COMPONENTTYPE*)param;
00401   omx_audio_mixer_component_PrivateType* omx_audio_mixer_component_Private = (omx_audio_mixer_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00402 
00403   omx_base_PortType *pPort[MAX_PORTS];
00404   tsem_t* pSem[MAX_PORTS];
00405   queue_t* pQueue[MAX_PORTS];
00406   OMX_BUFFERHEADERTYPE* pBuffer[MAX_PORTS];
00407   OMX_BOOL isBufferNeeded[MAX_PORTS];
00408   OMX_COMPONENTTYPE* target_component;
00409   OMX_U32 nOutputPortIndex,i;
00410 
00411   for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts;i++){
00412     pPort[i] = omx_audio_mixer_component_Private->ports[i];
00413     pSem[i] = pPort[i]->pBufferSem;
00414     pQueue[i] = pPort[i]->pBufferQueue;
00415     pBuffer[i] = NULL;
00416     isBufferNeeded[i] = OMX_TRUE;
00417   }
00418 
00419   nOutputPortIndex = omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts - 1;
00420 
00421 
00422   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00423   while(omx_audio_mixer_component_Private->state == OMX_StateIdle || omx_audio_mixer_component_Private->state == OMX_StateExecuting ||  omx_audio_mixer_component_Private->state == OMX_StatePause ||
00424     omx_audio_mixer_component_Private->transientState == OMX_TransStateLoadedToIdle) {
00425 
00426     /*Wait till the ports are being flushed*/
00427     while( checkAnyPortBeingFlushed(omx_audio_mixer_component_Private) ) {
00428 
00429       DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signalling flush all cond iF=%d,oF=%d iSemVal=%d,oSemval=%d\n",
00430         __func__,isBufferNeeded[0],isBufferNeeded[nOutputPortIndex],pSem[0]->semval,pSem[nOutputPortIndex]->semval);
00431 
00432       for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts;i++){
00433         if(isBufferNeeded[i]==OMX_FALSE && PORT_IS_BEING_FLUSHED(pPort[i])) {
00434           pPort[i]->ReturnBufferFunction(pPort[i],pBuffer[i]);
00435           pBuffer[i]=NULL;
00436           isBufferNeeded[i]=OMX_TRUE;
00437           DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning buffer %i\n",(int)i);
00438         }
00439       }
00440 
00441       DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signalling flush all cond iF=%d,oF=%d iSemVal=%d,oSemval=%d\n",
00442         __func__,isBufferNeeded[0],isBufferNeeded[nOutputPortIndex],pSem[0]->semval,pSem[nOutputPortIndex]->semval);
00443 
00444       tsem_up(omx_audio_mixer_component_Private->flush_all_condition);
00445       tsem_down(omx_audio_mixer_component_Private->flush_condition);
00446     }
00447 
00448     if(omx_audio_mixer_component_Private->state == OMX_StateLoaded || omx_audio_mixer_component_Private->state == OMX_StateInvalid) {
00449       DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00450       break;
00451     }
00452 
00453     /*No buffer to process. So wait here*/
00454     for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts;i++){
00455       if((isBufferNeeded[i]==OMX_TRUE && pSem[i]->semval==0) &&
00456         (omx_audio_mixer_component_Private->state != OMX_StateLoaded && omx_audio_mixer_component_Private->state != OMX_StateInvalid) &&
00457         PORT_IS_ENABLED(pPort[i]) && !PORT_IS_BEING_FLUSHED(pPort[i])) {
00458         //Signalled from EmptyThisBuffer or FillThisBuffer or some thing else
00459         DEBUG(DEB_LEV_FULL_SEQ, "Waiting for next input/output buffer\n");
00460         tsem_down(omx_audio_mixer_component_Private->bMgmtSem);
00461 
00462       }
00463       /*Don't wait for buffers, if any port is flushing*/
00464       if(checkAnyPortBeingFlushed(omx_audio_mixer_component_Private)) {
00465         break;
00466       }
00467       if(omx_audio_mixer_component_Private->state == OMX_StateLoaded || omx_audio_mixer_component_Private->state == OMX_StateInvalid) {
00468         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
00469         break;
00470       }
00471     }
00472 
00473     for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts;i++){
00474       DEBUG(DEB_LEV_SIMPLE_SEQ, "Waiting for buffer %i semval=%d \n",(int)i,pSem[i]->semval);
00475       if(pSem[i]->semval>0 && isBufferNeeded[i]==OMX_TRUE && PORT_IS_ENABLED(pPort[i])) {
00476         tsem_down(pSem[i]);
00477         if(pQueue[i]->nelem>0){
00478           isBufferNeeded[i]=OMX_FALSE;
00479           pBuffer[i] = dequeue(pQueue[i]);
00480           if(pBuffer[i] == NULL){
00481             DEBUG(DEB_LEV_ERR, "Had NULL input buffer!!\n");
00482             break;
00483           }
00484         }
00485       }
00486     }
00487 
00488     if(isBufferNeeded[nOutputPortIndex]==OMX_FALSE) {
00489 
00490       if(omx_audio_mixer_component_Private->pMark.hMarkTargetComponent != NULL){
00491         pBuffer[nOutputPortIndex]->hMarkTargetComponent = omx_audio_mixer_component_Private->pMark.hMarkTargetComponent;
00492         pBuffer[nOutputPortIndex]->pMarkData            = omx_audio_mixer_component_Private->pMark.pMarkData;
00493         omx_audio_mixer_component_Private->pMark.hMarkTargetComponent = NULL;
00494         omx_audio_mixer_component_Private->pMark.pMarkData            = NULL;
00495       }
00496       for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts-1;i++){
00497         if(isBufferNeeded[i]==OMX_FALSE && PORT_IS_ENABLED(pPort[i])) {
00498 
00499           if(isBufferNeeded[i]==OMX_FALSE) {
00500             target_component=(OMX_COMPONENTTYPE*)pBuffer[i]->hMarkTargetComponent;
00501             if(target_component==(OMX_COMPONENTTYPE *)openmaxStandComp) {
00502               /*Clear the mark and generate an event*/
00503               (*(omx_audio_mixer_component_Private->callbacks->EventHandler))
00504                 (openmaxStandComp,
00505                 omx_audio_mixer_component_Private->callbackData,
00506                 OMX_EventMark, /* The command was completed */
00507                 1, /* The commands was a OMX_CommandStateSet */
00508                 0, /* The state has been changed in message->messageParam2 */
00509                 pBuffer[i]->pMarkData);
00510             } else if(pBuffer[i]->hMarkTargetComponent!=NULL){
00511               /*If this is not the target component then pass the mark*/
00512               pBuffer[nOutputPortIndex]->hMarkTargetComponent  = pBuffer[i]->hMarkTargetComponent;
00513               pBuffer[nOutputPortIndex]->pMarkData = pBuffer[i]->pMarkData;
00514               pBuffer[i]->pMarkData=NULL;
00515             }
00516             pBuffer[nOutputPortIndex]->nTimeStamp = pBuffer[i]->nTimeStamp;
00517           }
00518 
00519           if((pBuffer[i]->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS && pBuffer[i]->nFilledLen==0) {
00520             DEBUG(DEB_LEV_FULL_SEQ, "Detected EOS flags in input buffer %p of %i filled len=%d\n", pBuffer[i], (int)i, (int)pBuffer[i]->nFilledLen);
00521             pBuffer[nOutputPortIndex]->nFlags = pBuffer[i]->nFlags;
00522             pBuffer[i]->nFlags=0;
00523             (*(omx_audio_mixer_component_Private->callbacks->EventHandler))
00524               (openmaxStandComp,
00525               omx_audio_mixer_component_Private->callbackData,
00526               OMX_EventBufferFlag, /* The command was completed */
00527               nOutputPortIndex, /* The commands was a OMX_CommandStateSet */
00528               pBuffer[nOutputPortIndex]->nFlags, /* The state has been changed in message->messageParam2 */
00529               NULL);
00530           }
00531 
00532           //TBD: To be verified
00533           if(omx_audio_mixer_component_Private->state == OMX_StateExecuting)  {
00534             if (omx_audio_mixer_component_Private->BufferMgmtCallback && pBuffer[i]->nFilledLen != 0) {
00535               (*(omx_audio_mixer_component_Private->BufferMgmtCallback))(openmaxStandComp, pBuffer[i], pBuffer[nOutputPortIndex]);
00536             } else {
00537               /*It no buffer management call back the explicitly consume input buffer*/
00538               pBuffer[i]->nFilledLen = 0;
00539             }
00540           } else {
00541             DEBUG(DEB_LEV_ERR, "In %s Received Buffer in non-Executing State(%x)\n", __func__, (int)omx_audio_mixer_component_Private->state);
00542             if(OMX_TransStateExecutingToIdle == omx_audio_mixer_component_Private->transientState ||
00543                OMX_TransStatePauseToIdle == omx_audio_mixer_component_Private->transientState) {
00544               pBuffer[i]->nFilledLen = 0;
00545             }
00546           }
00547 
00548           /*Input Buffer has been completely consumed. So, get new input buffer*/
00549           if(pBuffer[i]->nFilledLen==0) {
00550             isBufferNeeded[i] = OMX_TRUE;
00551           }
00552         }
00553       }
00554 
00555       if(omx_audio_mixer_component_Private->state==OMX_StatePause &&
00556         !(checkAnyPortBeingFlushed(omx_audio_mixer_component_Private))) {
00557         /*Waiting at paused state*/
00558         tsem_wait(omx_audio_mixer_component_Private->bStateSem);
00559       }
00560 
00561       /*If EOS and Input buffer Filled Len Zero then Return output buffer immediately*/
00562       if(pBuffer[nOutputPortIndex]->nFilledLen!=0 || (pBuffer[nOutputPortIndex]->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS){
00563         DEBUG(DEB_LEV_SIMPLE_SEQ, "Returning output buffer \n");
00564         pPort[nOutputPortIndex]->ReturnBufferFunction(pPort[nOutputPortIndex],pBuffer[nOutputPortIndex]);
00565         pBuffer[nOutputPortIndex]=NULL;
00566         isBufferNeeded[nOutputPortIndex]=OMX_TRUE;
00567       }
00568     }
00569 
00570     DEBUG(DEB_LEV_FULL_SEQ, "Input buffer arrived\n");
00571 
00572     if(omx_audio_mixer_component_Private->state==OMX_StatePause &&
00573       !(checkAnyPortBeingFlushed(omx_audio_mixer_component_Private))) {
00574       /*Waiting at paused state*/
00575       tsem_wait(omx_audio_mixer_component_Private->bStateSem);
00576     }
00577 
00578     /*Input Buffer has been completely consumed. So, return input buffer*/
00579     for(i=0;i<omx_audio_mixer_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts-1;i++){
00580       if(isBufferNeeded[i] == OMX_TRUE && pBuffer[i]!=NULL && PORT_IS_ENABLED(pPort[i])) {
00581         pPort[i]->ReturnBufferFunction(pPort[i],pBuffer[i]);
00582         pBuffer[i]=NULL;
00583       }
00584     }
00585   }
00586   DEBUG(DEB_LEV_SIMPLE_SEQ,"Exiting Buffer Management Thread\n");
00587   return NULL;
00588 }
00589