From 49d7ef282d9a78e4a6813ddabb78f99dac7f55a5 Mon Sep 17 00:00:00 2001 From: Alexander Kojevnikov Date: Tue, 27 Jul 2010 10:08:34 +0000 Subject: [PATCH] Show correct bitrate for VBR MP3 files. Patch by Alexander Kojevnikov, alexander kojevnikov com Originally committed as revision 24539 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/mpegaudiodec.c | 6 ++++-- libavformat/mp3.c | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 4f48c15e09..769be89913 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -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; diff --git a/libavformat/mp3.c b/libavformat/mp3.c index 11ce59cec4..a90654eff2 100644 --- a/libavformat/mp3.c +++ b/libavformat/mp3.c @@ -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; }