summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2009-12-07 16:53:59 +0100
committerChristian Gmeiner <christian.gmeiner@gmail.com>2009-12-07 16:53:59 +0100
commit961b570ff897b54beabdcb4c54e59049203ce10a (patch)
tree8f672bbe988293a85af5b2ea490d3b6721f50e5e
parentdf49033f6ed44ad04c7c273e371484f42c81cd8e (diff)
downloadvdr-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.
-rw-r--r--dxr3audiodecoder.c78
-rw-r--r--dxr3audiodecoder.h2
2 files changed, 74 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"
diff --git a/dxr3audiodecoder.h b/dxr3audiodecoder.h
index 48b526b..7b0262f 100644
--- a/dxr3audiodecoder.h
+++ b/dxr3audiodecoder.h
@@ -55,6 +55,7 @@ public:
private:
bool checkMpegAudioHdr(const uint8_t *head);
+ int calcFrameSize(const uint8_t *header);
AVCodec *audio;
AVCodecContext *contextAudio;
@@ -63,6 +64,7 @@ private:
cRingBufferFrame rbuf;
cMultichannelAudio ac3dtsDecoder;
+ int frameSize;
uint8_t lastBitrate;
uint8_t pcmbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
};