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
This commit is contained in:
Alexander Kojevnikov 2010-07-27 10:08:34 +00:00 committed by Carl Eugen Hoyos
parent 8a0f61c4fb
commit 49d7ef282d
2 changed files with 17 additions and 7 deletions

View File

@ -2054,7 +2054,8 @@ static int decode_frame(AVCodecContext * avctx,
} }
/* update codec info */ /* update codec info */
avctx->channels = s->nb_channels; 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; avctx->sub_id = s->layer;
if(*data_size < 1152*avctx->channels*sizeof(OUT_INT)) if(*data_size < 1152*avctx->channels*sizeof(OUT_INT))
@ -2122,7 +2123,8 @@ static int decode_frame_adu(AVCodecContext * avctx,
/* update codec info */ /* update codec info */
avctx->sample_rate = s->sample_rate; avctx->sample_rate = s->sample_rate;
avctx->channels = s->nb_channels; 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; avctx->sub_id = s->layer;
s->frame_size = len; s->frame_size = len;

View File

@ -84,6 +84,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
{ {
uint32_t v, spf; uint32_t v, spf;
int frames = -1; /* Total number of frames in file */ 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}}; const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
MPADecodeHeader c; MPADecodeHeader c;
int vbrtag_size = 0; 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); v = get_be32(s->pb);
if(v & 0x1) if(v & 0x1)
frames = get_be32(s->pb); 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) */ /* 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')) { if(v == MKBETAG('V', 'B', 'R', 'I')) {
/* Check tag version */ /* Check tag version */
if(get_be16(s->pb) == 1) { if(get_be16(s->pb) == 1) {
/* skip delay, quality and total bytes */ /* skip delay and quality */
url_fseek(s->pb, 8, SEEK_CUR); url_fseek(s->pb, 4, SEEK_CUR);
frames = get_be32(s->pb); frames = get_be32(s->pb);
size = get_be32(s->pb);
} }
} }
if(frames < 0) if(frames < 0 && !size)
return -1; return -1;
/* Skip the vbr tag frame */ /* Skip the vbr tag frame */
url_fseek(s->pb, base + vbrtag_size, SEEK_SET); url_fseek(s->pb, base + vbrtag_size, SEEK_SET);
spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */
st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, if(frames >= 0)
st->time_base); 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; return 0;
} }