omx_maddec_component.c

Go to the documentation of this file.
00001 
00031 #include <omxcore.h>
00032 #include <omx_base_audio_port.h>
00033 #include <omx_maddec_component.h>
00034 #include <id3tag.h>
00035 
00036 #define MIN(X,Y)    ((X) < (Y) ?  (X) : (Y))
00037 
00039 #define MAX_COMPONENT_MADDEC 4
00040 
00042 static OMX_U32 noMadDecInstance=0;
00043 
00044 
00047 #define TEMP_BUF_COPY_SPACE 1024
00048 
00050 #define TEMP_BUFFER_SIZE DEFAULT_IN_BUFFER_SIZE * 2
00051 
00053 OMX_ERRORTYPE omx_maddec_component_madLibInit(omx_maddec_component_PrivateType* omx_maddec_component_Private) {
00054   
00055   mad_stream_init (omx_maddec_component_Private->stream);
00056   mad_frame_init (omx_maddec_component_Private->frame);
00057   mad_synth_init (omx_maddec_component_Private->synth);
00058   tsem_up (omx_maddec_component_Private->madDecSyncSem);
00059   return OMX_ErrorNone;  
00060 }
00061 
00062 
00064 void omx_maddec_component_madLibDeInit(omx_maddec_component_PrivateType* omx_maddec_component_Private) {
00065   
00066   mad_synth_finish (omx_maddec_component_Private->synth);
00067   mad_frame_finish (omx_maddec_component_Private->frame);
00068   mad_stream_finish (omx_maddec_component_Private->stream);
00069 }
00070 
00076 OMX_ERRORTYPE omx_maddec_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName) {
00077   
00078   OMX_ERRORTYPE err = OMX_ErrorNone;  
00079   omx_maddec_component_PrivateType* omx_maddec_component_Private;
00080   omx_base_audio_PortType *inPort,*outPort;
00081   OMX_U32 i;
00082 
00083   if (!openmaxStandComp->pComponentPrivate) {
00084     openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_maddec_component_PrivateType));
00085     if(openmaxStandComp->pComponentPrivate==NULL)  {
00086       return OMX_ErrorInsufficientResources;
00087     }
00088   }  else {
00089     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, Error Component %x Already Allocated\n", 
00090               __func__, (int)openmaxStandComp->pComponentPrivate);
00091   }
00092   
00093   omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;
00094   omx_maddec_component_Private->ports = NULL;
00095 
00099   err = omx_base_filter_Constructor(openmaxStandComp, cComponentName);
00100 
00101   DEBUG(DEB_LEV_SIMPLE_SEQ, "constructor of mad decoder component is called\n");
00102 
00107   omx_maddec_component_Private->sPortTypesParam[OMX_PortDomainAudio].nStartPortNumber = 0;
00108   omx_maddec_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts = 2;
00109 
00111   if (omx_maddec_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts && !omx_maddec_component_Private->ports) {
00112     omx_maddec_component_Private->ports = calloc(omx_maddec_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts, sizeof(omx_base_PortType *));
00113     if (!omx_maddec_component_Private->ports) {
00114       return OMX_ErrorInsufficientResources;
00115     }
00116     for (i=0; i < omx_maddec_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++) {
00117       omx_maddec_component_Private->ports[i] = calloc(1, sizeof(omx_base_audio_PortType));
00118       if (!omx_maddec_component_Private->ports[i]) {
00119         return OMX_ErrorInsufficientResources;
00120       }
00121     }
00122   }
00123 
00124   base_audio_port_Constructor(openmaxStandComp, &omx_maddec_component_Private->ports[0], 0, OMX_TRUE);
00125   base_audio_port_Constructor(openmaxStandComp, &omx_maddec_component_Private->ports[1], 1, OMX_FALSE);
00126   
00127   
00129   inPort = (omx_base_audio_PortType *) omx_maddec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00130   
00131   inPort->sPortParam.nBufferSize = DEFAULT_IN_BUFFER_SIZE;
00132   strcpy(inPort->sPortParam.format.audio.cMIMEType, "audio/mpeg");
00133   inPort->sPortParam.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
00134 
00135   inPort->sAudioParam.eEncoding = OMX_AUDIO_CodingMP3;
00136 
00137   setHeader(&omx_maddec_component_Private->pAudioMp3, sizeof(OMX_AUDIO_PARAM_MP3TYPE));    
00138   omx_maddec_component_Private->pAudioMp3.nPortIndex = 0;                                                                    
00139   omx_maddec_component_Private->pAudioMp3.nChannels = 2;                                                                    
00140   omx_maddec_component_Private->pAudioMp3.nBitRate = 28000;                                                                  
00141   omx_maddec_component_Private->pAudioMp3.nSampleRate = 44100;                                                               
00142   omx_maddec_component_Private->pAudioMp3.nAudioBandWidth = 0;
00143   omx_maddec_component_Private->pAudioMp3.eChannelMode = OMX_AUDIO_ChannelModeStereo;
00144   omx_maddec_component_Private->pAudioMp3.eFormat=OMX_AUDIO_MP3StreamFormatMP1Layer3;
00145 
00147   outPort = (omx_base_audio_PortType *) omx_maddec_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
00148   outPort->sPortParam.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
00149   outPort->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;
00150 
00151   outPort->sAudioParam.eEncoding = OMX_AUDIO_CodingPCM;
00152 
00154   setHeader(&omx_maddec_component_Private->pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
00155   omx_maddec_component_Private->pAudioPcmMode.nPortIndex = 1;
00156   omx_maddec_component_Private->pAudioPcmMode.nChannels = 2;
00157   omx_maddec_component_Private->pAudioPcmMode.eNumData = OMX_NumericalDataSigned;
00158   omx_maddec_component_Private->pAudioPcmMode.eEndian = OMX_EndianLittle;
00159   omx_maddec_component_Private->pAudioPcmMode.bInterleaved = OMX_TRUE;
00160   omx_maddec_component_Private->pAudioPcmMode.nBitPerSample = 16;
00161   omx_maddec_component_Private->pAudioPcmMode.nSamplingRate = 44100;
00162   omx_maddec_component_Private->pAudioPcmMode.ePCMMode = OMX_AUDIO_PCMModeLinear;
00163   omx_maddec_component_Private->pAudioPcmMode.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
00164   omx_maddec_component_Private->pAudioPcmMode.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
00165 
00167   if(!strcmp(cComponentName, AUDIO_DEC_MP3_NAME))  {   
00168     omx_maddec_component_Private->audio_coding_type = OMX_AUDIO_CodingMP3;
00169   }  else if (!strcmp(cComponentName, AUDIO_DEC_BASE_NAME)) {
00170     omx_maddec_component_Private->audio_coding_type = OMX_AUDIO_CodingUnused;
00171   }  else  {
00172     // IL client specified an invalid component name
00173     return OMX_ErrorInvalidComponentName;
00174   }
00176   if(!omx_maddec_component_Private->madDecSyncSem) {
00177     omx_maddec_component_Private->madDecSyncSem = malloc(sizeof(tsem_t));
00178     if(omx_maddec_component_Private->madDecSyncSem == NULL) {
00179       return OMX_ErrorInsufficientResources;
00180     }
00181     tsem_init(omx_maddec_component_Private->madDecSyncSem, 0);
00182   }
00183 
00187   omx_maddec_component_Private->maddecReady = OMX_FALSE;
00188   omx_maddec_component_Private->BufferMgmtCallback = omx_maddec_component_BufferMgmtCallback;
00189   omx_maddec_component_Private->messageHandler = omx_mad_decoder_MessageHandler;
00190   omx_maddec_component_Private->destructor = omx_maddec_component_Destructor;
00191   openmaxStandComp->SetParameter = omx_maddec_component_SetParameter;
00192   openmaxStandComp->GetParameter = omx_maddec_component_GetParameter;
00193 
00194   noMadDecInstance++;
00195 
00196   if(noMadDecInstance>MAX_COMPONENT_MADDEC)
00197     return OMX_ErrorInsufficientResources;
00198 
00200   omx_maddec_component_Private->stream = malloc (sizeof(struct mad_stream));
00201   omx_maddec_component_Private->synth = malloc (sizeof(struct mad_synth));
00202   omx_maddec_component_Private->frame = malloc (sizeof(struct mad_frame));
00203 
00204   return err;
00205 }
00206 
00208 void omx_maddec_component_SetInternalParameters(OMX_COMPONENTTYPE *openmaxStandComp) {
00209 
00210   omx_maddec_component_PrivateType* omx_maddec_component_Private;
00211   omx_base_audio_PortType *pPort;;
00212 
00213   omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;
00214 
00216   strcpy(omx_maddec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.audio.cMIMEType, "audio/mpeg");
00217   omx_maddec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
00218 
00219   setHeader(&omx_maddec_component_Private->pAudioMp3, sizeof(OMX_AUDIO_PARAM_MP3TYPE));    
00220   omx_maddec_component_Private->pAudioMp3.nPortIndex = 0;                                                                    
00221   omx_maddec_component_Private->pAudioMp3.nChannels = 2;                                                                    
00222   omx_maddec_component_Private->pAudioMp3.nBitRate = 28000;                                                                  
00223   omx_maddec_component_Private->pAudioMp3.nSampleRate = 44100;                                                               
00224   omx_maddec_component_Private->pAudioMp3.nAudioBandWidth = 0;
00225   omx_maddec_component_Private->pAudioMp3.eChannelMode = OMX_AUDIO_ChannelModeStereo;
00226   omx_maddec_component_Private->pAudioMp3.eFormat=OMX_AUDIO_MP3StreamFormatMP1Layer3;
00227 
00228   pPort = (omx_base_audio_PortType *) omx_maddec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00229   setHeader(&pPort->sAudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00230   pPort->sAudioParam.nPortIndex = 0;
00231   pPort->sAudioParam.nIndex = 0;
00232   pPort->sAudioParam.eEncoding = OMX_AUDIO_CodingMP3;
00233 
00234 }
00235 
00236 
00238 OMX_ERRORTYPE omx_maddec_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00239 
00240   omx_maddec_component_PrivateType* omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;
00241   OMX_U32 i;
00242 
00243   if(omx_maddec_component_Private->madDecSyncSem) {
00244     tsem_deinit(omx_maddec_component_Private->madDecSyncSem);
00245     free(omx_maddec_component_Private->madDecSyncSem);
00246     omx_maddec_component_Private->madDecSyncSem = NULL;
00247   }
00248   
00250   if(omx_maddec_component_Private->stream != NULL) {
00251     free(omx_maddec_component_Private->stream);
00252     omx_maddec_component_Private->stream = NULL;
00253   }
00254   if(omx_maddec_component_Private->synth != NULL) {
00255     free(omx_maddec_component_Private->synth);
00256     omx_maddec_component_Private->synth = NULL;
00257   }
00258   if(omx_maddec_component_Private->frame != NULL) {
00259     free(omx_maddec_component_Private->frame);
00260     omx_maddec_component_Private->frame = NULL;
00261   }
00262 
00263   /* frees port/s */
00264   if (omx_maddec_component_Private->ports) {
00265     for (i=0; i < omx_maddec_component_Private->sPortTypesParam[OMX_PortDomainAudio].nPorts; i++) {
00266       if(omx_maddec_component_Private->ports[i])
00267         omx_maddec_component_Private->ports[i]->PortDestructor(omx_maddec_component_Private->ports[i]);
00268     }
00269     free(omx_maddec_component_Private->ports);
00270     omx_maddec_component_Private->ports=NULL;
00271   }
00272 
00273   DEBUG(DEB_LEV_FUNCTION_NAME, "Destructor of mad decoder component is called\n");
00274 
00275   omx_base_filter_Destructor(openmaxStandComp);
00276 
00277   noMadDecInstance--;
00278 
00279   return OMX_ErrorNone;
00280 
00281 }
00282 
00284 OMX_ERRORTYPE omx_maddec_component_Init(OMX_COMPONENTTYPE *openmaxStandComp)  {
00285 
00286   omx_maddec_component_PrivateType* omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;
00287   OMX_ERRORTYPE err = OMX_ErrorNone;
00288 
00290   omx_maddec_component_Private->temporary_buffer = malloc(sizeof(OMX_BUFFERHEADERTYPE));
00291   omx_maddec_component_Private->temporary_buffer->pBuffer = malloc(DEFAULT_IN_BUFFER_SIZE*2);
00292   memset(omx_maddec_component_Private->temporary_buffer->pBuffer, 0, DEFAULT_IN_BUFFER_SIZE*2);
00293 
00294   omx_maddec_component_Private->temp_input_buffer = omx_maddec_component_Private->temporary_buffer->pBuffer;
00295   omx_maddec_component_Private->temporary_buffer->nFilledLen=0;
00296   omx_maddec_component_Private->temporary_buffer->nOffset=0;
00297 
00298   omx_maddec_component_Private->isFirstBuffer = 1;
00299   omx_maddec_component_Private->isNewBuffer = 1;
00300 
00301   return err;
00302 }
00303 
00305 OMX_ERRORTYPE omx_maddec_component_Deinit(OMX_COMPONENTTYPE *openmaxStandComp) {
00306 
00307   omx_maddec_component_PrivateType* omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;
00308   OMX_ERRORTYPE err = OMX_ErrorNone;
00309 
00310   if (omx_maddec_component_Private->maddecReady) {
00311     omx_maddec_component_madLibDeInit(omx_maddec_component_Private);
00312     omx_maddec_component_Private->maddecReady = OMX_FALSE;
00313   }
00314 
00315   /*Restore temporary input buffer pointer*/
00316   omx_maddec_component_Private->temporary_buffer->pBuffer = omx_maddec_component_Private->temp_input_buffer;
00317   DEBUG(DEB_LEV_SIMPLE_SEQ, "Freeing Temporary Buffer\n");
00318   /* freeing temporary memory allocation */
00319   if(omx_maddec_component_Private->temporary_buffer->pBuffer) {
00320     free(omx_maddec_component_Private->temporary_buffer->pBuffer);
00321     omx_maddec_component_Private->temporary_buffer->pBuffer = NULL;
00322   }
00323   if(omx_maddec_component_Private->temporary_buffer) {
00324     free(omx_maddec_component_Private->temporary_buffer);
00325     omx_maddec_component_Private->temporary_buffer = NULL;
00326   }
00327   
00328   return err;
00329 }
00330 
00336 static inline int scale_int (mad_fixed_t sample) {
00337 
00338   #if MAD_F_FRACBITS < 28
00339     /* round */
00340     sample += (1L << (28 - MAD_F_FRACBITS - 1));
00341   #endif
00342 
00343   /* clip */
00344   if (sample >= MAD_F_ONE)
00345     sample = MAD_F_ONE - 1;
00346   else if (sample < -MAD_F_ONE)
00347     sample = -MAD_F_ONE;
00348 
00349   #if MAD_F_FRACBITS < 28
00350     /* quantize */
00351     sample >>= (28 - MAD_F_FRACBITS);
00352   #endif
00353 
00354   /* convert from 29 bits to 32 bits */
00355   return (int) (sample << 3);
00356 }
00357 
00365 void omx_maddec_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* inputbuffer, OMX_BUFFERHEADERTYPE* outputbuffer) {
00366   omx_maddec_component_PrivateType* omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;  
00367   OMX_U32 nchannels;
00368   int count;
00369   int consumed = 0;
00370   int nsamples;
00371   unsigned char const *before_sync, *after_sync;
00372   mad_fixed_t const *left_ch, *right_ch;
00373   unsigned short *outdata;
00374   int tocopy;
00375  
00376   outputbuffer->nFilledLen = 0;
00377   outputbuffer->nOffset=0;
00378 
00379   if(omx_maddec_component_Private->isNewBuffer==1 || omx_maddec_component_Private->need_mad_stream == 1) {
00380     DEBUG(DEB_LEV_SIMPLE_SEQ,"In %s New Buffer len=%d\n", __func__,(int)inputbuffer->nFilledLen);
00381 
00383     tocopy = MIN (MAD_BUFFER_MDLEN, MIN (inputbuffer->nFilledLen,
00384               MAD_BUFFER_MDLEN * 3 - omx_maddec_component_Private->temporary_buffer->nFilledLen));
00385 
00386     if (tocopy == 0) {
00387       DEBUG(DEB_LEV_ERR,"mad claims to need more data than %u bytes, we don't have that much", MAD_BUFFER_MDLEN * 3);
00388       inputbuffer->nFilledLen=0;
00389       omx_maddec_component_Private->isNewBuffer = 1;
00390       return;
00391     }
00392 
00393     if(omx_maddec_component_Private->need_mad_stream == 1) {
00394       DEBUG(DEB_LEV_SIMPLE_SEQ,"In %s memmove temp buf len=%d\n", __func__,(int)omx_maddec_component_Private->temporary_buffer->nFilledLen);
00395       memmove (omx_maddec_component_Private->temp_input_buffer, omx_maddec_component_Private->temporary_buffer->pBuffer, omx_maddec_component_Private->temporary_buffer->nFilledLen);
00396       omx_maddec_component_Private->temporary_buffer->pBuffer = omx_maddec_component_Private->temp_input_buffer;
00397       omx_maddec_component_Private->need_mad_stream = 0;
00398       memcpy(omx_maddec_component_Private->temporary_buffer->pBuffer+omx_maddec_component_Private->temporary_buffer->nFilledLen, inputbuffer->pBuffer + inputbuffer->nOffset, tocopy);
00399       omx_maddec_component_Private->temporary_buffer->nFilledLen += tocopy;
00400       inputbuffer->nFilledLen -= tocopy;
00401       inputbuffer->nOffset += tocopy;
00402 
00403       DEBUG(DEB_LEV_SIMPLE_SEQ, "Input buffer filled len : %d temp buf len = %d tocopy=%d\n", (int)inputbuffer->nFilledLen, (int)omx_maddec_component_Private->temporary_buffer->nFilledLen,tocopy);
00404       omx_maddec_component_Private->isNewBuffer = 0;
00405 
00406       mad_stream_buffer(omx_maddec_component_Private->stream, omx_maddec_component_Private->temporary_buffer->pBuffer, omx_maddec_component_Private->temporary_buffer->nFilledLen);
00407     }
00408     if(inputbuffer->nFilledLen == 0) {
00409       omx_maddec_component_Private->isNewBuffer = 1;
00410       inputbuffer->nOffset=0;
00411     }
00412   }
00413 
00414   /* added separate header decoding to catch errors earlier, also fixes
00415    * some weird decoding errors... */
00416   DEBUG(DEB_LEV_SIMPLE_SEQ,"decoding the header now\n");
00417   
00418   if (mad_header_decode (&(omx_maddec_component_Private->frame->header), omx_maddec_component_Private->stream) == -1) {
00419     DEBUG(DEB_LEV_SIMPLE_SEQ,"mad_header_decode had an error: %s\n",
00420         mad_stream_errorstr (omx_maddec_component_Private->stream));
00421   }
00422 
00423   DEBUG(DEB_LEV_SIMPLE_SEQ,"decoding one frame now\n");
00424 
00426   omx_maddec_component_Private->frame->header.flags &= ~MAD_FLAG_PROTECTION;
00427 
00428   if (mad_frame_decode (omx_maddec_component_Private->frame, omx_maddec_component_Private->stream) == -1) {
00429     DEBUG(DEB_LEV_SIMPLE_SEQ,"got error %d\n", omx_maddec_component_Private->stream->error);
00430 
00431     /* not enough data, need to wait for next buffer? */
00432     if (omx_maddec_component_Private->stream->error == MAD_ERROR_BUFLEN) {
00433       if (omx_maddec_component_Private->stream->next_frame == omx_maddec_component_Private->temporary_buffer->pBuffer) {
00434         DEBUG(DEB_LEV_SIMPLE_SEQ,"not enough data in tempbuffer  breaking to get more\n");
00435         omx_maddec_component_Private->need_mad_stream=1;
00436         return;
00437       } else {
00438         DEBUG(DEB_LEV_SIMPLE_SEQ,"sync error, flushing unneeded data\n");
00439         /* figure out how many bytes mad consumed */
00443         if (consumed == 0) {
00444           consumed = omx_maddec_component_Private->stream->next_frame - omx_maddec_component_Private->temporary_buffer->pBuffer;
00445         }
00446         DEBUG(DEB_LEV_SIMPLE_SEQ,"consumed %d bytes\n", consumed);
00447         /* move out pointer to where mad want the next data */
00448         omx_maddec_component_Private->temporary_buffer->pBuffer += consumed;
00449         omx_maddec_component_Private->temporary_buffer->nFilledLen -= consumed;
00450         return;
00451       }
00452     }
00453     DEBUG(DEB_LEV_SIMPLE_SEQ,"mad_frame_decode had an error: %s\n",
00454         mad_stream_errorstr (omx_maddec_component_Private->stream));
00455     if (!MAD_RECOVERABLE (omx_maddec_component_Private->stream->error)) {
00456      DEBUG(DEB_LEV_ERR,"non recoverable error");
00457     } else if (omx_maddec_component_Private->stream->error == MAD_ERROR_LOSTSYNC) {
00458       /* lost sync, force a resync */
00459       signed long tagsize;
00460       tagsize = id3_tag_query(omx_maddec_component_Private->stream->this_frame, omx_maddec_component_Private->stream->bufend - omx_maddec_component_Private->stream->this_frame);
00461       mad_stream_skip(omx_maddec_component_Private->stream, tagsize);
00462       DEBUG(DEB_LEV_SIMPLE_SEQ,"recoverable lost sync error\n");
00463     }
00464 
00465     mad_frame_mute (omx_maddec_component_Private->frame);
00466     mad_synth_mute (omx_maddec_component_Private->synth);
00467     before_sync = omx_maddec_component_Private->stream->ptr.byte;
00468     if (mad_stream_sync (omx_maddec_component_Private->stream) != 0)
00469       DEBUG(DEB_LEV_ERR,"mad_stream_sync failed\n");
00470     after_sync = omx_maddec_component_Private->stream->ptr.byte;
00471     /* a succesful resync should make us drop bytes as consumed, so
00472        calculate from the byte pointers before and after resync */
00473     consumed = after_sync - before_sync;
00474     DEBUG(DEB_LEV_SIMPLE_SEQ,"resynchronization consumes %d bytes\n", consumed);
00475     DEBUG(DEB_LEV_SIMPLE_SEQ,"synced to data: 0x%0x 0x%0x\n", *omx_maddec_component_Private->stream->ptr.byte,
00476         *(omx_maddec_component_Private->stream->ptr.byte + 1));
00477 
00478     mad_stream_sync (omx_maddec_component_Private->stream);
00479     /* recoverable errors pass */
00480     /* figure out how many bytes mad consumed */
00484     if (consumed == 0) {
00485       consumed = omx_maddec_component_Private->stream->next_frame - omx_maddec_component_Private->temporary_buffer->pBuffer;
00486     }
00487     DEBUG(DEB_LEV_SIMPLE_SEQ,"consumed %d bytes\n", consumed);
00488     /* move out pointer to where mad want the next data */
00489     omx_maddec_component_Private->temporary_buffer->pBuffer += consumed;
00490     omx_maddec_component_Private->temporary_buffer->nFilledLen -= consumed;
00491     return;
00492   } 
00493 
00494   /* if we're not resyncing/in error, check if caps need to be set again */
00495   nsamples = MAD_NSBSAMPLES (&omx_maddec_component_Private->frame->header) *
00496       (omx_maddec_component_Private->stream->options & MAD_OPTION_HALFSAMPLERATE ? 16 : 32);
00497   nchannels = MAD_NCHANNELS (&omx_maddec_component_Private->frame->header);
00498 
00499   if((omx_maddec_component_Private->pAudioPcmMode.nSamplingRate != omx_maddec_component_Private->frame->header.samplerate) ||
00500     ( omx_maddec_component_Private->pAudioPcmMode.nChannels!=nchannels)) {
00501     DEBUG(DEB_LEV_FULL_SEQ, "---->Sending Port Settings Change Event\n");
00502 
00503     switch(omx_maddec_component_Private->audio_coding_type)  {
00504     case OMX_AUDIO_CodingMP3 :
00505       /*Update Parameter which has changed from avCodecContext*/
00506       /*pAudioMp3 is for input port Mp3 data*/
00507       omx_maddec_component_Private->pAudioMp3.nChannels = nchannels;
00508       omx_maddec_component_Private->pAudioMp3.nBitRate = omx_maddec_component_Private->frame->header.bitrate;
00509       omx_maddec_component_Private->pAudioMp3.nSampleRate = omx_maddec_component_Private->frame->header.samplerate;
00510       /*pAudioPcmMode is for output port PCM data*/
00511       omx_maddec_component_Private->pAudioPcmMode.nChannels = nchannels;
00512       omx_maddec_component_Private->pAudioPcmMode.nSamplingRate = 32;
00513       omx_maddec_component_Private->pAudioPcmMode.nSamplingRate = omx_maddec_component_Private->frame->header.samplerate;
00514       break;
00515     default :
00516       DEBUG(DEB_LEV_ERR, "Audio formats other than MP3 not supported\nCodec not found\n");
00517       break;                       
00518     }
00519 
00520     /*Send Port Settings changed call back*/
00521     (*(omx_maddec_component_Private->callbacks->EventHandler))
00522     (openmaxStandComp,
00523     omx_maddec_component_Private->callbackData,
00524     OMX_EventPortSettingsChanged, /* The command was completed */
00525     0, 
00526     1, /* This is the output port index */
00527     NULL);
00528   }
00529 
00530 
00531   mad_synth_frame (omx_maddec_component_Private->synth, omx_maddec_component_Private->frame);
00532   left_ch = omx_maddec_component_Private->synth->pcm.samples[0];
00533   right_ch = omx_maddec_component_Private->synth->pcm.samples[1];
00534 
00535   outdata = (unsigned short *)outputbuffer->pBuffer;
00536   outputbuffer->nFilledLen=nsamples * nchannels * 2;
00537 
00538   // output sample(s) in 16-bit signed native-endian PCM //
00539   if (nchannels == 1) {
00540     count = nsamples;
00541 
00542     while (count--) {
00543       *outdata++ = (scale_int (*left_ch++) >>16) & 0xffff;
00544     }
00545   } else {
00546     count = nsamples;
00547     while (count--) {
00548       *outdata++ = (scale_int (*left_ch++) >>16) & 0xffff;
00549       *outdata++ = (scale_int (*right_ch++)>>16) & 0xffff;
00550     }
00551   }
00552 
00553   DEBUG(DEB_LEV_SIMPLE_SEQ,"Returning output buffer size=%d \n", (int)outputbuffer->nFilledLen);
00554 
00555   /* figure out how many bytes mad consumed */
00559   if (consumed == 0)
00560     consumed = omx_maddec_component_Private->stream->next_frame - omx_maddec_component_Private->temporary_buffer->pBuffer;
00561 
00562   DEBUG(DEB_LEV_SIMPLE_SEQ,"consumed %d bytes\n", consumed);
00563   /* move out pointer to where mad want the next data */
00564   omx_maddec_component_Private->temporary_buffer->pBuffer += consumed;
00565   omx_maddec_component_Private->temporary_buffer->nFilledLen -= consumed;
00566 }
00567 
00569 OMX_ERRORTYPE omx_maddec_component_SetParameter(
00570   OMX_IN  OMX_HANDLETYPE hComponent,
00571   OMX_IN  OMX_INDEXTYPE nParamIndex,
00572   OMX_IN  OMX_PTR ComponentParameterStructure)  {
00573 
00574   OMX_ERRORTYPE err = OMX_ErrorNone;
00575   OMX_AUDIO_PARAM_PORTFORMATTYPE *pAudioPortFormat;
00576   OMX_AUDIO_PARAM_PCMMODETYPE* pAudioPcmMode;
00577   OMX_AUDIO_PARAM_MP3TYPE * pAudioMp3;
00578   OMX_PARAM_COMPONENTROLETYPE * pComponentRole;
00579   OMX_U32 portIndex;
00580 
00581   /* Check which structure we are being fed and make control its header */
00582   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00583   omx_maddec_component_PrivateType* omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;
00584   omx_base_audio_PortType *port;
00585   if (ComponentParameterStructure == NULL) {
00586     return OMX_ErrorBadParameter;
00587   }
00588 
00589   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting parameter %i\n", nParamIndex);
00590   switch(nParamIndex) {
00591   case OMX_IndexParamAudioPortFormat:
00592     pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00593     portIndex = pAudioPortFormat->nPortIndex;
00594     /*Check Structure Header and verify component state*/
00595     err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00596     if(err!=OMX_ErrorNone) { 
00597       DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err); 
00598       break;
00599     }
00600     if (portIndex <= 1) {
00601       port = (omx_base_audio_PortType *) omx_maddec_component_Private->ports[portIndex];
00602       memcpy(&port->sAudioParam, pAudioPortFormat, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00603     } else {
00604       return OMX_ErrorBadPortIndex;
00605     }
00606     break;
00607 
00608   case OMX_IndexParamAudioPcm:
00609     pAudioPcmMode = (OMX_AUDIO_PARAM_PCMMODETYPE*)ComponentParameterStructure;
00610     portIndex = pAudioPcmMode->nPortIndex;
00611     /*Check Structure Header and verify component state*/
00612     err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
00613     if(err!=OMX_ErrorNone) { 
00614       DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err); 
00615       break;
00616     }
00617     memcpy(&omx_maddec_component_Private->pAudioPcmMode, pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));          
00618     break;
00619     
00620   case OMX_IndexParamStandardComponentRole:
00621     pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00622     if (!strcmp( (char*) pComponentRole->cRole, AUDIO_DEC_MP3_ROLE)) {
00623       omx_maddec_component_Private->audio_coding_type = OMX_AUDIO_CodingMP3;
00624     }  else {
00625       return OMX_ErrorBadParameter;
00626     }
00627     omx_maddec_component_SetInternalParameters(openmaxStandComp);
00628     break;
00629 
00630   case OMX_IndexParamAudioMp3:
00631     pAudioMp3 = (OMX_AUDIO_PARAM_MP3TYPE*) ComponentParameterStructure;
00632     portIndex = pAudioMp3->nPortIndex;
00633     err = omx_base_component_ParameterSanityCheck(hComponent,portIndex,pAudioMp3,sizeof(OMX_AUDIO_PARAM_MP3TYPE));
00634     if(err!=OMX_ErrorNone) { 
00635       DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err); 
00636       break;
00637     }
00638     if (pAudioMp3->nPortIndex == 0) {
00639       memcpy(&omx_maddec_component_Private->pAudioMp3, pAudioMp3, sizeof(OMX_AUDIO_PARAM_MP3TYPE)); 
00640     }  else {
00641       return OMX_ErrorBadPortIndex;
00642     }
00643     break;
00644 
00645   default: /*Call the base component function*/
00646     return omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00647   }
00648   return err;
00649   
00650 }
00651 
00653 OMX_ERRORTYPE omx_maddec_component_GetParameter(
00654   OMX_IN  OMX_HANDLETYPE hComponent,
00655   OMX_IN  OMX_INDEXTYPE nParamIndex,
00656   OMX_INOUT OMX_PTR ComponentParameterStructure)  {
00657 
00658   OMX_AUDIO_PARAM_PORTFORMATTYPE *pAudioPortFormat;  
00659   OMX_AUDIO_PARAM_PCMMODETYPE *pAudioPcmMode;
00660   OMX_PARAM_COMPONENTROLETYPE * pComponentRole;
00661   OMX_AUDIO_PARAM_MP3TYPE *pAudioMp3;
00662   omx_base_audio_PortType *port;
00663   OMX_ERRORTYPE err = OMX_ErrorNone;
00664 
00665   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00666   omx_maddec_component_PrivateType* omx_maddec_component_Private = openmaxStandComp->pComponentPrivate;
00667   if (ComponentParameterStructure == NULL) {
00668     return OMX_ErrorBadParameter;
00669   }
00670   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Getting parameter %i\n", nParamIndex);
00671   /* Check which structure we are being fed and fill its header */
00672   switch(nParamIndex) {
00673   case OMX_IndexParamAudioInit:
00674     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) { 
00675       break;
00676     }
00677     memcpy(ComponentParameterStructure, &omx_maddec_component_Private->sPortTypesParam[OMX_PortDomainAudio], sizeof(OMX_PORT_PARAM_TYPE));
00678     break;    
00679 
00680   case OMX_IndexParamAudioPortFormat:
00681     pAudioPortFormat = (OMX_AUDIO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00682     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) { 
00683       break;
00684     }
00685     if (pAudioPortFormat->nPortIndex <= 1) {
00686       port = (omx_base_audio_PortType *)omx_maddec_component_Private->ports[pAudioPortFormat->nPortIndex];
00687       memcpy(pAudioPortFormat, &port->sAudioParam, sizeof(OMX_AUDIO_PARAM_PORTFORMATTYPE));
00688     } else {
00689       return OMX_ErrorBadPortIndex;
00690     }
00691     break;    
00692 
00693   case OMX_IndexParamAudioPcm:
00694     pAudioPcmMode = (OMX_AUDIO_PARAM_PCMMODETYPE*)ComponentParameterStructure;
00695     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE))) != OMX_ErrorNone) { 
00696       break;
00697     }
00698     if (pAudioPcmMode->nPortIndex > 1) {
00699       return OMX_ErrorBadPortIndex;
00700     }
00701     memcpy(pAudioPcmMode, &omx_maddec_component_Private->pAudioPcmMode, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
00702     break;
00703 
00704   case OMX_IndexParamAudioMp3:
00705     pAudioMp3 = (OMX_AUDIO_PARAM_MP3TYPE*)ComponentParameterStructure;
00706     if (pAudioMp3->nPortIndex != 0) {
00707       return OMX_ErrorBadPortIndex;
00708     }
00709     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_AUDIO_PARAM_MP3TYPE))) != OMX_ErrorNone) { 
00710       break;
00711     }
00712     memcpy(pAudioMp3, &omx_maddec_component_Private->pAudioMp3, sizeof(OMX_AUDIO_PARAM_MP3TYPE));
00713     break;
00714 
00715   case OMX_IndexParamStandardComponentRole:
00716     pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)ComponentParameterStructure;
00717     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) { 
00718       break;
00719     }
00720     if (omx_maddec_component_Private->audio_coding_type == OMX_AUDIO_CodingMP3) {
00721       strcpy( (char*) pComponentRole->cRole, AUDIO_DEC_MP3_ROLE);
00722     }  else {
00723       strcpy( (char*) pComponentRole->cRole,"\0");;
00724     }
00725     break;
00726   default: /*Call the base component function*/
00727     return omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00728   }
00729   return OMX_ErrorNone;
00730   
00731 }
00732 
00734 OMX_ERRORTYPE omx_mad_decoder_MessageHandler(OMX_COMPONENTTYPE* openmaxStandComp, internalRequestMessageType *message)  {
00735 
00736   omx_maddec_component_PrivateType* omx_maddec_component_Private = (omx_maddec_component_PrivateType*)openmaxStandComp->pComponentPrivate;  
00737   OMX_ERRORTYPE err;
00738   OMX_STATETYPE eCurrentState = omx_maddec_component_Private->state;
00739   DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s\n", __func__);
00740 
00741   if (message->messageType == OMX_CommandStateSet){
00742     if ((message->messageParam == OMX_StateIdle) && (omx_maddec_component_Private->state == OMX_StateLoaded)) {
00743       err = omx_maddec_component_Init(openmaxStandComp);
00744       if(err!=OMX_ErrorNone) { 
00745         DEBUG(DEB_LEV_ERR, "In %s MAD Decoder Init Failed Error=%x\n",__func__,err); 
00746         return err;
00747       }
00748     } else if ((message->messageParam == OMX_StateExecuting) && (omx_maddec_component_Private->state == OMX_StateIdle)) {
00749       DEBUG(DEB_LEV_FULL_SEQ, "State Changing from Idle to Exec\n");
00750       omx_maddec_component_Private->temporary_buffer->nFilledLen=0;
00751       omx_maddec_component_Private->temporary_buffer->nOffset=0;
00752       omx_maddec_component_Private->need_mad_stream = 1;
00753       if (!omx_maddec_component_Private->maddecReady) {
00754         err = omx_maddec_component_madLibInit(omx_maddec_component_Private);
00755         if (err != OMX_ErrorNone) {
00756           return OMX_ErrorNotReady;
00757         }
00758         omx_maddec_component_Private->maddecReady = OMX_TRUE;
00759       }
00760     }
00761   }
00763   err = omx_base_component_MessageHandler(openmaxStandComp, message);
00764 
00765   if (message->messageType == OMX_CommandStateSet){
00766     if ((message->messageParam == OMX_StateLoaded) && (eCurrentState == OMX_StateIdle)) {
00767       err = omx_maddec_component_Deinit(openmaxStandComp);
00768       if(err!=OMX_ErrorNone) { 
00769         DEBUG(DEB_LEV_ERR, "In %s MAD Decoder Deinit Failed Error=%x\n",__func__,err); 
00770         return err;
00771       }
00772     }else if ((message->messageParam == OMX_StateIdle) && (eCurrentState == OMX_StateExecuting)) {
00773       omx_maddec_component_madLibDeInit(omx_maddec_component_Private);
00774       omx_maddec_component_Private->maddecReady = OMX_FALSE;
00775     }
00776   }
00777 
00778   return err;  
00779 }
00780  

Generated for OpenMAX Bellagio rel. 0.9.0 by  doxygen 1.5.1
SourceForge.net Logo