[libav-stable] mp3dec: Fix VBR bit rate parsing

Alexander Kojevnikov git at libav.org
Fri Mar 8 08:00:07 CET 2013


Module: libav
Branch: master
Commit: eae0879d961b78717dd2a0899809ad22819ae9e3

Author:    Alexander Kojevnikov <alexander at kojevnikov.com>
Committer: Anton Khirnov <anton at khirnov.net>
Date:      Wed Mar  6 21:38:55 2013 -0800

mp3dec: Fix VBR bit rate parsing

When parsing the Xing/Info tag, don't set the bit rate if it's an Info tag.

When parsing the stream, don't override the bit rate if it's already set,
otherwise calculate the mean bit rate from parsed frames. This way, the bit
rate will be set correctly both for CBR and VBR streams.

CC:libav-stable at libav.org

Signed-off-by: Anton Khirnov <anton at khirnov.net>

---

 libavcodec/mpegaudio_parser.c |    6 +++++-
 libavformat/mp3dec.c          |    6 ++++--
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c
index c904873..58ea452 100644
--- a/libavcodec/mpegaudio_parser.c
+++ b/libavcodec/mpegaudio_parser.c
@@ -30,6 +30,7 @@ typedef struct MpegAudioParseContext {
     int frame_size;
     uint32_t header;
     int header_count;
+    int no_bitrate;
 } MpegAudioParseContext;
 
 #define MPA_HEADER_SIZE 4
@@ -80,7 +81,10 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
                         avctx->sample_rate= sr;
                         avctx->channels   = channels;
                         s1->duration      = frame_size;
-                        avctx->bit_rate   = bit_rate;
+                        if (s->no_bitrate || !avctx->bit_rate) {
+                            s->no_bitrate = 1;
+                            avctx->bit_rate += (bit_rate - avctx->bit_rate) / s->header_count;
+                        }
                     }
                     break;
                 }
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 7d0c2fb..48deefd 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -128,6 +128,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
     const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
     MPADecodeHeader c;
     int vbrtag_size = 0;
+    int is_cbr;
 
     v = avio_rb32(s->pb);
     if(ff_mpa_check_header(v) < 0)
@@ -143,7 +144,8 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
     /* Check for Xing / Info tag */
     avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]);
     v = avio_rb32(s->pb);
-    if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) {
+    is_cbr = v == MKBETAG('I', 'n', 'f', 'o');
+    if (v == MKBETAG('X', 'i', 'n', 'g') || is_cbr) {
         v = avio_rb32(s->pb);
         if(v & XING_FLAG_FRAMES)
             frames = avio_rb32(s->pb);
@@ -176,7 +178,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
     if(frames)
         st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
                                     st->time_base);
-    if(size && frames)
+    if (size && frames && !is_cbr)
         st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf);
 
     return 0;



More information about the libav-stable mailing list