|
OpenMAXBellagio 0.9.3
|
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