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

Generated for OpenMAX Bellagio rel. 0.3.5-svn by  doxygen 1.5.1
SourceForge.net Logo