Commit 29d8cd26 authored by Alexander Kojevnikov's avatar Alexander Kojevnikov Committed by Michael Niedermayer

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.
Signed-off-by: 's avatarAlexander Kojevnikov <alexander@kojevnikov.com>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent d2b0b839
...@@ -30,6 +30,7 @@ typedef struct MpegAudioParseContext { ...@@ -30,6 +30,7 @@ typedef struct MpegAudioParseContext {
int frame_size; int frame_size;
uint32_t header; uint32_t header;
int header_count; int header_count;
int no_bitrate;
} MpegAudioParseContext; } MpegAudioParseContext;
#define MPA_HEADER_SIZE 4 #define MPA_HEADER_SIZE 4
...@@ -74,15 +75,18 @@ static int mpegaudio_parse(AVCodecParserContext *s1, ...@@ -74,15 +75,18 @@ static int mpegaudio_parse(AVCodecParserContext *s1,
if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
s->header_count= -3; s->header_count= -3;
s->header= state; s->header= state;
s->header_count++;
s->frame_size = ret-4; s->frame_size = ret-4;
if (s->header_count > 1) { if (s->header_count > 0) {
avctx->sample_rate= sr; avctx->sample_rate= sr;
avctx->channels = channels; avctx->channels = channels;
s1->duration = frame_size; 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; break;
} }
} }
......
...@@ -120,6 +120,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) ...@@ -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}}; const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
MPADecodeHeader c; MPADecodeHeader c;
int vbrtag_size = 0; int vbrtag_size = 0;
int is_cbr;
v = avio_rb32(s->pb); v = avio_rb32(s->pb);
if(ff_mpa_check_header(v) < 0) if(ff_mpa_check_header(v) < 0)
...@@ -135,7 +136,8 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) ...@@ -135,7 +136,8 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
/* Check for Xing / Info tag */ /* Check for Xing / Info tag */
avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]);
v = avio_rb32(s->pb); 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); v = avio_rb32(s->pb);
if(v & XING_FLAG_FRAMES) if(v & XING_FLAG_FRAMES)
frames = avio_rb32(s->pb); frames = avio_rb32(s->pb);
...@@ -180,7 +182,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) ...@@ -180,7 +182,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
if(frames) if(frames)
st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
st->time_base); 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); st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf);
return 0; return 0;
......
40a4e41ae74ec8dacdf02402831a6a58 *./tests/data/lavf-fate/lavf.mp3 7fcf80c2059b5c058a6cdd2e2f798b6c *./tests/data/lavf-fate/lavf.mp3
97230 ./tests/data/lavf-fate/lavf.mp3 96366 ./tests/data/lavf-fate/lavf.mp3
./tests/data/lavf-fate/lavf.mp3 CRC=0x6c9850fe ./tests/data/lavf-fate/lavf.mp3 CRC=0x6c9850fe
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment