class MP3DecodeModule : public SimpleModule {
public:
MP3DecodeModule() : audioCodecContext( 0 )
{
}
void init()
{
av_register_all();
if ( avcodec_open( audioCodecContext = avcodec_alloc_context(), &mp3_decoder ) < 0 ) {
printf("error opening context\n");
audioCodecContext = 0;
}
}
void process( const Frame &frame )
{
AVPacket *pkt = ((FFMpegStreamPacket*)frame.data())->packet;
Frame *f = getAvailableFrame();
PCMData *pcm = (PCMData *)f->data();
int count = 0, ret = 0, bytesRead;
AVPacket *mp3 = pkt;
unsigned char *ptr = (unsigned char*)mp3->data;
for ( int len = mp3->size; len && ret >= 0; len -= ret, ptr += ret ) {
ret = avcodec_decode_audio(audioCodecContext, (short*)(pcm->data + count), &bytesRead, ptr, len);
if ( bytesRead > 0 )
count += bytesRead;
}
frame.deref();
pcm->size = count;
SimpleModule::process( *f );
}
Frame* createNewFrame()
{
return new Frame( "FRAME_ID_PCM_AUDIO_DATA", new PCMData );
}
const char *name() { return "MP3 Decoder"; }
Format inputFormat() { return "FRAME_ID_MPEG_AUDIO_PACKET"; }
Format outputFormat() { return "FRAME_ID_PCM_AUDIO_DATA"; }
bool isBlocking() { return true; }
private:
AVCodecContext *audioCodecContext;
};