]> git.sesse.net Git - ffmpeg/commitdiff
mp3dec: Fix VBR bit rate parsing
authorAlexander Kojevnikov <alexander@kojevnikov.com>
Wed, 27 Feb 2013 05:47:11 +0000 (21:47 -0800)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 5 Mar 2013 12:06:01 +0000 (13:06 +0100)
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.

Signed-off-by: Alexander Kojevnikov <alexander@kojevnikov.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavcodec/mpegaudio_parser.c
libavformat/mp3dec.c
tests/ref/lavf-fate/mp3

index 5f97d711c68c790be4933644398c924012ae822a..bb4d75c0668890d1e93443da3262959064c3f122 100644 (file)
@@ -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
@@ -74,15 +75,18 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
                     if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
                         s->header_count= -3;
                     s->header= state;
-                    s->header_count++;
                     s->frame_size = ret-4;
 
-                    if (s->header_count > 1) {
+                    if (s->header_count > 0) {
                         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;
+                        }
                     }
+                    s->header_count++;
                     break;
                 }
             }
index c6d6987eaaca41f185e57f6750ae10e2af80a7dd..57e4ba33b16144609dab687d62b939df7cc7276b 100644 (file)
@@ -120,6 +120,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)
@@ -135,7 +136,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);
@@ -180,7 +182,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;
index 91e2b48c03e08cee6b9b69798b74666c3287d3de..361314b2ca8d95e9b6815c2f00950347e22c2d63 100644 (file)
@@ -1,3 +1,3 @@
-40a4e41ae74ec8dacdf02402831a6a58 *./tests/data/lavf-fate/lavf.mp3
-97230 ./tests/data/lavf-fate/lavf.mp3
+7fcf80c2059b5c058a6cdd2e2f798b6c *./tests/data/lavf-fate/lavf.mp3
+96366 ./tests/data/lavf-fate/lavf.mp3
 ./tests/data/lavf-fate/lavf.mp3 CRC=0x6c9850fe