diff options
author | Christian Gmeiner <christian.gmeiner@gmail.com> | 2009-12-07 16:53:59 +0100 |
---|---|---|
committer | Christian Gmeiner <christian.gmeiner@gmail.com> | 2009-12-07 16:53:59 +0100 |
commit | 961b570ff897b54beabdcb4c54e59049203ce10a (patch) | |
tree | 8f672bbe988293a85af5b2ea490d3b6721f50e5e /dxr3audiodecoder.c | |
parent | df49033f6ed44ad04c7c273e371484f42c81cd8e (diff) | |
download | vdr-plugin-dxr3-961b570ff897b54beabdcb4c54e59049203ce10a.tar.gz vdr-plugin-dxr3-961b570ff897b54beabdcb4c54e59049203ce10a.tar.bz2 |
fixed bug #169
ffmpep warns that the frame size is incorrect. To fix this warning, we calcuate
the frame size based on the mpeg audio header. This calculated value is used for
avcodec_decode_audio functions.
Diffstat (limited to 'dxr3audiodecoder.c')
-rw-r--r-- | dxr3audiodecoder.c | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/dxr3audiodecoder.c b/dxr3audiodecoder.c index d65689c..b909485 100644 --- a/dxr3audiodecoder.c +++ b/dxr3audiodecoder.c @@ -101,13 +101,16 @@ void cDxr3AudioDecoder::Decode(cDxr3PesFrame *frame, uint32_t pts, cDxr3SyncBuff if ((buf[2] & 0xf0) != (lastBitrate & 0xf0)) { dsyslog("[dxr3-audiodecoder] found new audio header"); + // recalculate used framesize + frameSize = calcFrameSize(buf); + dsyslog("[dxr3-audiodecoder] calculated frame size %d", frameSize); + // we need now to reinit the deocder and to store the new // part from the audio header Init(); lastBitrate = buf[2]; } } - #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 26, 0) uint8_t *ptr = const_cast<uint8_t *>(buf); @@ -115,9 +118,9 @@ void cDxr3AudioDecoder::Decode(cDxr3PesFrame *frame, uint32_t pts, cDxr3SyncBuff out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(51, 29, 0) - len = avcodec_decode_audio(contextAudio, (short *)(&pcmbuf), &out_size, ptr, length); + len = avcodec_decode_audio(contextAudio, (short *)(&pcmbuf), &out_size, ptr, frameSize); #else - len = avcodec_decode_audio2(contextAudio, (short *)(&pcmbuf), &out_size, ptr, length); + len = avcodec_decode_audio2(contextAudio, (short *)(&pcmbuf), &out_size, ptr, frameSize); #endif if (len < 0) { @@ -139,9 +142,9 @@ void cDxr3AudioDecoder::Decode(cDxr3PesFrame *frame, uint32_t pts, cDxr3SyncBuff } #else avpkt.data = const_cast<uint8_t *>(buf); - avpkt.size = length; + avpkt.size = frameSize; - while (avpkt.size > 0) { + while (length > 0) { out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; len = avcodec_decode_audio3(contextAudio, (short *)(&pcmbuf), &out_size, &avpkt); @@ -160,7 +163,7 @@ void cDxr3AudioDecoder::Decode(cDxr3PesFrame *frame, uint32_t pts, cDxr3SyncBuff } } - avpkt.size -= len; + length -= len; avpkt.data += len; } #endif @@ -288,6 +291,69 @@ bool cDxr3AudioDecoder::checkMpegAudioHdr(const uint8_t *head) return true; } +int cDxr3AudioDecoder::calcFrameSize(const uint8_t *header) +{ + static const int bitrates[2][3][15] = + { + { // MPEG 1 + {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, // Layer1 + {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, // Layer2 + {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} // Layer3 + }, + { // MPEG 2, 2.5 + {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, // Layer1 + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, // Layer2 + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} // Layer3 + } + }; + + static const int samplingRates[4][3] = + { + {11025, 12000, 8000, }, // MPEG 2.5 + {0, 0, 0, }, // reserved + {22050, 24000, 16000, }, // MPEG 2 + {44100, 48000, 32000 } // MPEG 1 + }; + + static const int MPEG1 = 0x3; + + // in B the version is stored + int ver = (header[1] >> 3) & 0x03; + int version = 1; // default to MPEG2 + + // determine index into arrays based on ver + if (ver == MPEG1) { + version = 0; + } + + // in C the layer version is stored + int layer = 3 - ((header[1] >> 1) & 0x03); + + // in E the bitrate index is stored + int bitrateIndex = (header[2] >> 4) & 0x0f; + + // in F the sampling rate frequency index is stored + int samplingIndex = (header[2] >> 2) & 0x03; + + // in G the padding bit is stored + int padding = (header[2] >> 1) & 0x01; + + int bitrate = bitrates[version][layer][bitrateIndex]; // kbit + bitrate *= 1000; // kbit -> bit + int samplesrate = samplingRates[ver][samplingIndex]; + + // formulars used to calculate frame size + // layer I + // FrameLengthInBytes = (12 * BitRate / SampleRate + Padding) * 4 + // layer II & III + // FrameLengthInBytes = 144 * BitRate / SampleRate + Padding + if (layer == 0) { + return (12 * bitrate / samplesrate + padding) * 4; + } else { + return 144 * bitrate / samplesrate + padding; + } +} + // Local variables: // mode: c++ // c-file-style: "stroustrup" |