OpenMAXBellagio 0.9.3
omx_volume_component.c
Go to the documentation of this file.
00001 
00027 #include <omxcore.h>
00028 #include <omx_base_audio_port.h>
00029 #include <omx_volume_component.h>
00030 #include<OMX_Audio.h>
00031 
00032 /* gain value */
00033 #define GAIN_VALUE 100.0f
00034 
00035 OMX_ERRORTYPE omx_volume_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName) {
00036     OMX_ERRORTYPE err;
00037     omx_volume_component_PrivateType* omx_volume_component_Private;
00038     OMX_U32 i;
00039 
00040     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n",__func__);
00041 
00042     RM_RegisterComponent(VOLUME_COMP_NAME, MAX_VOLUME_COMPONENTS);
00043     if (!openmaxStandComp->pComponentPrivate) {
00044         openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_volume_component_PrivateType));
00045         DEBUG(DEB_LEV_FUNCTION_NAME, "In %s allocated private structure %p for std component %p\n",
00046                 __func__, openmaxStandComp->pComponentPrivate, openmaxStandComp);
00047         if(openmaxStandComp->pComponentPrivate == NULL) {
00048             return OMX_ErrorInsufficientResources;
00049         }
00050     } else {
00051         DEBUG(DEB_LEV_ERR, "In %s, Error Component %p Already Allocated\n", __func__, openmaxStandComp->pComponentPrivate);
00052         return OMX_ErrorUndefined;
00053     }
00054 
00055     omx_volume_component_Private = openmaxStandComp->pComponentPrivate;
00056     omx_volume_component_Private->ports = NULL;
00057 
00059     err = omx_base_filter_Constructor(openmaxStandComp, cComponentName);
00060     if (err != OMX_ErrorNone) {
00061             DEBUG(DEB_LEV_ERR, "In %s failed base class constructor\n", __func__);
00062             return err;
00063     }
00064 
00065     omx_volume_component_Private->sPortTypesParam[OMX_PortDomainAudio].nStartPortNumber = 0;
00066     omx_volume_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts = 2;
00067 
00069     if (omx_volume_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts && !omx_volume_component_Private->ports) {
00070         omx_volume_component_Private->ports = calloc(omx_volume_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts, sizeof(omx_base_PortType *));
00071         if (!omx_volume_component_Private->ports) {
00072             return OMX_ErrorInsufficientResources;
00073         }
00074         for (i=0; i < omx_volume_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++) {
00075             omx_volume_component_Private->ports[i] = calloc(1, sizeof(omx_base_audio_PortType));
00076             if (!omx_volume_component_Private->ports[i]) {
00077                 return OMX_ErrorInsufficientResources;
00078             }
00079         }
00080     }
00081 
00082     err = base_audio_port_Constructor(openmaxStandComp, &omx_volume_component_Private->ports[0], 0, OMX_TRUE);
00083     if (err != OMX_ErrorNone) {
00084         return OMX_ErrorInsufficientResources;
00085     }
00086     err = base_audio_port_Constructor(openmaxStandComp, &omx_volume_component_Private->ports[1], 1, OMX_FALSE);
00087     if (err != OMX_ErrorNone) {
00088         return OMX_ErrorInsufficientResources;
00089     }
00090 
00092     omx_volume_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;
00093     omx_volume_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX]->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;
00094 
00095     omx_volume_component_Private->gain = GAIN_VALUE; //100.0f; // default gain
00096     omx_volume_component_Private->destructor = omx_volume_component_Destructor;
00097     openmaxStandComp->SetParameter = omx_volume_component_SetParameter;
00098     openmaxStandComp->GetParameter = omx_volume_component_GetParameter;
00099     openmaxStandComp->GetConfig = omx_volume_component_GetConfig;
00100     openmaxStandComp->SetConfig = omx_volume_component_SetConfig;
00101     omx_volume_component_Private->BufferMgmtCallback = omx_volume_component_BufferMgmtCallback;
00102 
00103   /* resource management special section */
00104   omx_volume_component_Private->nqualitylevels = VOLUME_QUALITY_LEVELS;
00105   omx_volume_component_Private->currentQualityLevel = 1;
00106   omx_volume_component_Private->multiResourceLevel = malloc(sizeof(multiResourceDescriptor *) * VOLUME_QUALITY_LEVELS);
00107   for (i = 0; i<VOLUME_QUALITY_LEVELS; i++) {
00108       omx_volume_component_Private->multiResourceLevel[i] = malloc(sizeof(multiResourceDescriptor));
00109       omx_volume_component_Private->multiResourceLevel[i]->CPUResourceRequested = volumeQualityLevels[i * 2];
00110       omx_volume_component_Private->multiResourceLevel[i]->MemoryResourceRequested = volumeQualityLevels[i * 2 + 1];
00111   }
00112 
00113     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for component %p\n", __func__, openmaxStandComp);
00114     return OMX_ErrorNone;
00115 }
00116 
00117 
00120 OMX_ERRORTYPE omx_volume_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00121 
00122     omx_volume_component_PrivateType* omx_volume_component_Private = openmaxStandComp->pComponentPrivate;
00123     OMX_U32 i;
00124 
00125     /* frees port/s */
00126     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for component %p\n", __func__, openmaxStandComp);
00127     if (omx_volume_component_Private->ports) {
00128         for (i=0; i < omx_volume_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++) {
00129             if(omx_volume_component_Private->ports[i]) {
00130                 omx_volume_component_Private->ports[i]->PortDestructor(omx_volume_component_Private->ports[i]);
00131             }
00132         }
00133         free(omx_volume_component_Private->ports);
00134         omx_volume_component_Private->ports=NULL;
00135     }
00136 
00137     omx_base_filter_Destructor(openmaxStandComp);
00138 
00139     DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for component %p\n", __func__, openmaxStandComp);
00140     return OMX_ErrorNone;
00141 }
00142 
00145 void omx_volume_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pInputBuffer, OMX_BUFFERHEADERTYPE* pOutputBuffer) {
00146   int i;
00147   int sampleCount = pInputBuffer->nFilledLen / 2; // signed 16 bit samples assumed
00148   omx_volume_component_PrivateType* omx_volume_component_Private = openmaxStandComp->pComponentPrivate;
00149 
00150   if(omx_volume_component_Private->gain != GAIN_VALUE) {
00151     for (i = 0; i < sampleCount; i++) {
00152       ((OMX_S16*) pOutputBuffer->pBuffer)[i] = (OMX_S16)
00153               (((OMX_S16*) pInputBuffer->pBuffer)[i] * (omx_volume_component_Private->gain / 100.0f));
00154     }
00155   } else {
00156     memcpy(pOutputBuffer->pBuffer,pInputBuffer->pBuffer,pInputBuffer->nFilledLen);
00157   }
00158   pOutputBuffer->nFilledLen = pInputBuffer->nFilledLen;
00159   pInputBuffer->nFilledLen=0;
00160 }
00161 
00163 OMX_ERRORTYPE omx_volume_component_SetConfig(
00164   OMX_HANDLETYPE hComponent,
00165   OMX_INDEXTYPE nIndex,
00166   OMX_PTR pComponentConfigStructure) {
00167 
00168   OMX_AUDIO_CONFIG_VOLUMETYPE* pVolume;
00169   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00170   omx_volume_component_PrivateType* omx_volume_component_Private = openmaxStandComp->pComponentPrivate;
00171   OMX_ERRORTYPE err = OMX_ErrorNone;
00172 
00173   switch (nIndex) {
00174     case OMX_IndexConfigAudioVolume :
00175       pVolume = (OMX_AUDIO_CONFIG_VOLUMETYPE*) pComponentConfigStructure;
00176       if(pVolume->sVolume.nValue > 100) {
00177         err = OMX_ErrorBadParameter;
00178         break;
00179       }
00180       omx_volume_component_Private->gain = pVolume->sVolume.nValue;
00181       err = OMX_ErrorNone;
00182       break;
00183     default: // delegate to superclass
00184       err = omx_base_component_SetConfig(hComponent, nIndex, pComponentConfigStructure);
00185   }
00186 
00187   return err;
00188 }
00189 
00190 OMX_ERRORTYPE omx_volume_component_GetConfig(
00191   OMX_HANDLETYPE hComponent,
00192   OMX_INDEXTYPE nIndex,
00193   OMX_PTR pComponentConfigStructure) {
00194   OMX_AUDIO_CONFIG_VOLUMETYPE* pVolume;
00195   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00196   omx_volume_component_PrivateType* omx_volume_component_Private = openmaxStandComp->pComponentPrivate;
00197   OMX_ERRORTYPE err = OMX_ErrorNone;
00198 
00199   switch (nIndex) {
00200     case OMX_IndexConfigAudioVolume :
00201       pVolume = (OMX_AUDIO_CONFIG_VOLUMETYPE*) pComponentConfigStructure;
00202       setHeader(pVolume,sizeof(OMX_AUDIO_CONFIG_VOLUMETYPE));
00203       pVolume->sVolume.nValue = omx_volume_component_Private->gain;
00204       pVolume->sVolume.nMin = 0;
00205       pVolume->sVolume.nMax = 100;
00206       pVolume->bLinear = OMX_TRUE;
00207       err = OMX_ErrorNone;
00208       break;
00209     default :
00210       err = omx_base_component_GetConfig(hComponent, nIndex, pComponentConfigStructure);
00211   }
00212   return err;
00213 }
00214 
00215 OMX_ERRORTYPE omx_volume_component_SetParameter(
00216   OMX_HANDLETYPE hComponent,
00217   OMX_INDEXTYPE nParamIndex,
00218   OMX_PTR ComponentParameterStructure) {
00219 
00220   OMX_ERRORTYPE err = OMX_ErrorNone;
00221   OMX_AUDIO_PARAM_PORTFORMATTYPE *pAudioPortFormat;
00222   OMX_PARAM_COMPONENTROLETYPE *pComponentRole;
00223   OMX_U32 portIndex;
00224   omx_base_audio_PortType *port;
00225 
00226   /* Check which structure we are being fed and make control its header */
00227   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00228   omx_volume_component_PrivateType* omx_volume_component_Private = openmaxStandComp->pComponentPrivate;
00229   if (ComponentParameterStructure == NULL) {
00230     return OMX_ErrorBadParameter;
00231   }
00232 
00233   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting parameter %i\n", nParamIndex);
00234   switch(nParamIndex) {
00235     case OMX_IndexParamAudioPortFormat:
00236       pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00237       portIndex = pAudioPortFormat->nPortIndex;
00238       err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00239       if(err!=OMX_ErrorNone) {
00240         DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err);
00241         break;
00242       }
00243       if (portIndex <= 1) {
00244         port= (omx_base_audio_PortType *)omx_volume_component_Private->ports[portIndex];
00245         memcpy(&port->sAudioParam, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00246       } else {
00247         err = OMX_ErrorBadPortIndex;
00248       }
00249       break;
00250     case OMX_IndexParamStandardComponentRole:
00251       pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00252 
00253       if (omx_volume_component_Private->state != OMX_StateLoaded && omx_volume_component_Private->state != OMX_StateWaitForResources) {
00254         DEBUG(DEB_LEV_ERR, "In %s Incorrect State=%x lineno=%d\n",__func__,omx_volume_component_Private->state,__LINE__);
00255         return OMX_ErrorIncorrectStateOperation;
00256       }
00257 
00258       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
00259         break;
00260       }
00261 
00262       if (strcmp( (char*) pComponentRole->cRole, VOLUME_COMP_ROLE)) {
00263         return OMX_ErrorBadParameter;
00264       }
00265       break;
00266     default:
00267       err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00268   }
00269   return err;
00270 }
00271 
00272 OMX_ERRORTYPE omx_volume_component_GetParameter(
00273   OMX_HANDLETYPE hComponent,
00274   OMX_INDEXTYPE nParamIndex,
00275   OMX_PTR ComponentParameterStructure) {
00276 
00277   OMX_AUDIO_PARAM_PORTFORMATTYPE *pAudioPortFormat;
00278   OMX_AUDIO_PARAM_PCMMODETYPE *pAudioPcmMode;
00279   OMX_PARAM_COMPONENTROLETYPE *pComponentRole;
00280   OMX_ERRORTYPE err = OMX_ErrorNone;
00281   omx_base_audio_PortType *port;
00282   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00283   omx_volume_component_PrivateType* omx_volume_component_Private = openmaxStandComp->pComponentPrivate;
00284   if (ComponentParameterStructure == NULL) {
00285     return OMX_ErrorBadParameter;
00286   }
00287   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Getting parameter %i\n", nParamIndex);
00288   /* Check which structure we are being fed and fill its header */
00289   switch(nParamIndex) {
00290     case OMX_IndexParamAudioInit:
00291       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
00292         break;
00293       }
00294       memcpy(ComponentParameterStructure, &omx_volume_component_Private->sPortTypesParam[OMX_PortDomainAudio], sizeof(OMX_PORT_PARAM_TYPE));
00295       break;
00296     case OMX_IndexParamAudioPortFormat:
00297       pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00298       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
00299         break;
00300       }
00301       if (pAudioPortFormat->nPortIndex <= 1) {
00302         port= (omx_base_audio_PortType *)omx_volume_component_Private->ports[pAudioPortFormat->nPortIndex];
00303         memcpy(pAudioPortFormat, &port->sAudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00304       } else {
00305         err = OMX_ErrorBadPortIndex;
00306       }
00307     break;
00308     case OMX_IndexParamAudioPcm:
00309       pAudioPcmMode = (OMX_AUDIO_PARAM_PCMMODETYPE*)ComponentParameterStructure;
00310       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE))) != OMX_ErrorNone) {
00311         break;
00312       }
00313 
00314       if (pAudioPcmMode->nPortIndex > 1) {
00315         return OMX_ErrorBadPortIndex;
00316       }
00317       pAudioPcmMode->nChannels = 2;
00318       pAudioPcmMode->eNumData = OMX_NumericalDataSigned;
00319       pAudioPcmMode->eEndian = OMX_EndianBig;
00320       pAudioPcmMode->bInterleaved = OMX_TRUE;
00321       pAudioPcmMode->nBitPerSample = 16;
00322       pAudioPcmMode->nSamplingRate = 0;
00323       pAudioPcmMode->ePCMMode = OMX_AUDIO_PCMModeLinear;
00324       break;
00325     case OMX_IndexParamStandardComponentRole:
00326       pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00327       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
00328         break;
00329       }
00330       strcpy( (char*) pComponentRole->cRole, VOLUME_COMP_ROLE);
00331       break;
00332     default:
00333       err = omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00334   }
00335   return err;
00336 }