Show correct bitrate for VBR MP3 files.
authorAlexander Kojevnikov <alexander@kojevnikov.com>
Tue, 27 Jul 2010 10:08:34 +0000 (10:08 +0000)
committerCarl Eugen Hoyos <cehoyos@rainbow.studorg.tuwien.ac.at>
Tue, 27 Jul 2010 10:08:34 +0000 (10:08 +0000)
Patch by Alexander Kojevnikov, alexander kojevnikov com

Originally committed as revision 24539 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/mpegaudiodec.c
libavformat/mp3.c

index 4f48c15..769be89 100644 (file)
@@ -2054,7 +2054,8 @@ static int decode_frame(AVCodecContext * avctx,
     }
     /* update codec info */
     avctx->channels = s->nb_channels;
-    avctx->bit_rate = s->bit_rate;
+    if (!avctx->bit_rate)
+        avctx->bit_rate = s->bit_rate;
     avctx->sub_id = s->layer;
 
     if(*data_size < 1152*avctx->channels*sizeof(OUT_INT))
@@ -2122,7 +2123,8 @@ static int decode_frame_adu(AVCodecContext * avctx,
     /* update codec info */
     avctx->sample_rate = s->sample_rate;
     avctx->channels = s->nb_channels;
-    avctx->bit_rate = s->bit_rate;
+    if (!avctx->bit_rate)
+        avctx->bit_rate = s->bit_rate;
     avctx->sub_id = s->layer;
 
     s->frame_size = len;
index 11ce59c..a90654e 100644 (file)
@@ -84,6 +84,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
 {
     uint32_t v, spf;
     int frames = -1; /* Total number of frames in file */
+    unsigned size = 0; /* Total number of bytes in the stream */
     const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
     MPADecodeHeader c;
     int vbrtag_size = 0;
@@ -104,6 +105,8 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
         v = get_be32(s->pb);
         if(v & 0x1)
             frames = get_be32(s->pb);
+        if(v & 0x2)
+            size = get_be32(s->pb);
     }
 
     /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */
@@ -112,21 +115,26 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
     if(v == MKBETAG('V', 'B', 'R', 'I')) {
         /* Check tag version */
         if(get_be16(s->pb) == 1) {
-            /* skip delay, quality and total bytes */
-            url_fseek(s->pb, 8, SEEK_CUR);
+            /* skip delay and quality */
+            url_fseek(s->pb, 4, SEEK_CUR);
             frames = get_be32(s->pb);
+            size = get_be32(s->pb);
         }
     }
 
-    if(frames < 0)
+    if(frames < 0 && !size)
         return -1;
 
     /* Skip the vbr tag frame */
     url_fseek(s->pb, base + vbrtag_size, SEEK_SET);
 
     spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */
-    st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
-                                st->time_base);
+    if(frames >= 0)
+        st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
+                                    st->time_base);
+    if(size)
+        st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf);
+
     return 0;
 }