From: Michael Niedermayer <[email protected]> Instead of using a fixed bitrate_idx, try to calculate a matching bitrate for the XING header.
Using a fixed bitrate_idx causes tools such as file(1) and mediainfo(1) to report wrong bitrate and bitrate mode when using CBR. Bug: https://bugs.debian.org/736088 --- This was adapted from ffmpeg's commit 40176fc3 and pre-existing code. libavformat/mp3enc.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 46889fc..4d9ba2b 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -119,6 +119,8 @@ static void mp3_write_xing(AVFormatContext *s) MPADecodeHeader mpah; int srate_idx, i, channels; int bitrate_idx; + int best_bitrate_idx; + int best_bitrate_error = INT_MAX; int xing_offset; int ver = 0; @@ -150,14 +152,49 @@ static void mp3_write_xing(AVFormatContext *s) return; } - /* 64 kbps frame, should be large enough */ - bitrate_idx = (ver == 3) ? 5 : 8; - /* dummy MPEG audio header */ header = 0xff << 24; // sync header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/ - header |= (bitrate_idx << 4 | srate_idx << 2) << 8; + header |= (srate_idx << 2) << 8; header |= channels << 6; + + for (bitrate_idx = 1; bitrate_idx < 15; bitrate_idx++) { + int error; + + avpriv_mpegaudio_decode_header(&mpah, header | (bitrate_idx << (4+8))); + error = FFABS(mpah.bit_rate - codec->bit_rate); + + if (error < best_bitrate_error){ + best_bitrate_error = error; + best_bitrate_idx = bitrate_idx; + } + } + av_assert0(best_bitrate_idx >= 0); + + for (bitrate_idx = best_bitrate_idx; bitrate_idx < 15; bitrate_idx++) { + int needed; + int32_t mask; + + mask = bitrate_idx << (4 + 8); + header |= mask; + avpriv_mpegaudio_decode_header(&mpah, header); + xing_offset = xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1]; + needed = 4 // header + + xing_offset + + 4 // xing tag + + 4 // frames/size/toc flags + + 4 // frames + + 4 // size + + XING_TOC_SIZE // toc + + 24 + ; + + if (needed <= mpah.frame_size) + break; + + header &= ~mask; + } + avio_wb32(s->pb, header); avpriv_mpegaudio_decode_header(&mpah, header); -- 1.9.1 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
