Merge commit '617a1a98a6be3e59db6fbfc21afab2fb9a049c03'
* commit '617a1a98a6be3e59db6fbfc21afab2fb9a049c03': mp3enc: Properly write bitrate value in XING header Conflicts: libavformat/mp3enc.c See: 40176fc3149bc72c1309f93989a57aec2322e626 See: d62bf5d4e73250295c0a652e151498c5b19cbd63 See: various others Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
571d2ffa47
@ -116,15 +116,16 @@ static int mp3_write_xing(AVFormatContext *s)
|
|||||||
{
|
{
|
||||||
MP3Context *mp3 = s->priv_data;
|
MP3Context *mp3 = s->priv_data;
|
||||||
AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
|
AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
|
||||||
int bitrate_idx;
|
int32_t header;
|
||||||
int best_bitrate_idx = -1;
|
MPADecodeHeader mpah;
|
||||||
int best_bitrate_error= INT_MAX;
|
int srate_idx, i, channels;
|
||||||
int xing_offset;
|
int bitrate_idx;
|
||||||
int32_t header, mask;
|
int best_bitrate_idx = -1;
|
||||||
MPADecodeHeader c;
|
int best_bitrate_error = INT_MAX;
|
||||||
int srate_idx, ver = 0, i, channels;
|
int xing_offset;
|
||||||
int needed;
|
int ver = 0;
|
||||||
const char *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT;
|
int bytes_needed, lsf;
|
||||||
|
const char *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT;
|
||||||
|
|
||||||
if (!s->pb->seekable || !mp3->write_xing)
|
if (!s->pb->seekable || !mp3->write_xing)
|
||||||
return 0;
|
return 0;
|
||||||
@ -156,28 +157,29 @@ static int mp3_write_xing(AVFormatContext *s)
|
|||||||
/* dummy MPEG audio header */
|
/* dummy MPEG audio header */
|
||||||
header = 0xffU << 24; // sync
|
header = 0xffU << 24; // sync
|
||||||
header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/
|
header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/
|
||||||
header |= (srate_idx << 2) << 8;
|
header |= (srate_idx << 2) << 8;
|
||||||
header |= channels << 6;
|
header |= channels << 6;
|
||||||
|
|
||||||
for (bitrate_idx=1; bitrate_idx<15; bitrate_idx++) {
|
for (bitrate_idx = 1; bitrate_idx < 15; bitrate_idx++) {
|
||||||
int error;
|
int bit_rate = 1000 * avpriv_mpa_bitrate_tab[lsf][3 - 1][bitrate_idx];
|
||||||
avpriv_mpegaudio_decode_header(&c, header | (bitrate_idx << (4+8)));
|
int error = FFABS(bit_rate - codec->bit_rate);
|
||||||
error= FFABS(c.bit_rate - codec->bit_rate);
|
|
||||||
if(error < best_bitrate_error){
|
if (error < best_bitrate_error) {
|
||||||
best_bitrate_error= error;
|
best_bitrate_error = error;
|
||||||
best_bitrate_idx = bitrate_idx;
|
best_bitrate_idx = bitrate_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
av_assert0(best_bitrate_idx >= 0);
|
av_assert0(best_bitrate_idx >= 0);
|
||||||
|
|
||||||
for (bitrate_idx= best_bitrate_idx;; bitrate_idx++) {
|
for (bitrate_idx = best_bitrate_idx; ; bitrate_idx++) {
|
||||||
|
int32_t mask = bitrate_idx << (4 + 8);
|
||||||
if (15 == bitrate_idx)
|
if (15 == bitrate_idx)
|
||||||
return -1;
|
return -1;
|
||||||
mask = bitrate_idx << (4+8);
|
|
||||||
header |= mask;
|
header |= mask;
|
||||||
avpriv_mpegaudio_decode_header(&c, header);
|
|
||||||
xing_offset=xing_offtbl[c.lsf == 1][c.nb_channels == 1];
|
avpriv_mpegaudio_decode_header(&mpah, header);
|
||||||
needed = 4 // header
|
xing_offset=xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1];
|
||||||
|
bytes_needed = 4 // header
|
||||||
+ xing_offset
|
+ xing_offset
|
||||||
+ 4 // xing tag
|
+ 4 // xing tag
|
||||||
+ 4 // frames/size/toc flags
|
+ 4 // frames/size/toc flags
|
||||||
@ -187,8 +189,9 @@ static int mp3_write_xing(AVFormatContext *s)
|
|||||||
+ 24
|
+ 24
|
||||||
;
|
;
|
||||||
|
|
||||||
if (needed <= c.frame_size)
|
if (bytes_needed <= mpah.frame_size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
header &= ~mask;
|
header &= ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +202,7 @@ static int mp3_write_xing(AVFormatContext *s)
|
|||||||
ffio_wfourcc(s->pb, "Xing");
|
ffio_wfourcc(s->pb, "Xing");
|
||||||
avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames / size / TOC
|
avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames / size / TOC
|
||||||
|
|
||||||
mp3->size = c.frame_size;
|
mp3->size = mpah.frame_size;
|
||||||
mp3->want=1;
|
mp3->want=1;
|
||||||
mp3->seen=0;
|
mp3->seen=0;
|
||||||
mp3->pos=0;
|
mp3->pos=0;
|
||||||
@ -217,7 +220,7 @@ static int mp3_write_xing(AVFormatContext *s)
|
|||||||
avio_w8(s->pb, 0);
|
avio_w8(s->pb, 0);
|
||||||
avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12);
|
avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12);
|
||||||
|
|
||||||
ffio_fill(s->pb, 0, c.frame_size - needed);
|
ffio_fill(s->pb, 0, mpah.frame_size - bytes_needed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -257,7 +260,7 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
MP3Context *mp3 = s->priv_data;
|
MP3Context *mp3 = s->priv_data;
|
||||||
|
|
||||||
if (pkt->data && pkt->size >= 4) {
|
if (pkt->data && pkt->size >= 4) {
|
||||||
MPADecodeHeader c;
|
MPADecodeHeader mpah;
|
||||||
int av_unused base;
|
int av_unused base;
|
||||||
uint32_t head = AV_RB32(pkt->data);
|
uint32_t head = AV_RB32(pkt->data);
|
||||||
|
|
||||||
@ -266,16 +269,16 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
"is invalid, writing it anyway.\n", pkt->size, head);
|
"is invalid, writing it anyway.\n", pkt->size, head);
|
||||||
return ff_raw_write_packet(s, pkt);
|
return ff_raw_write_packet(s, pkt);
|
||||||
}
|
}
|
||||||
avpriv_mpegaudio_decode_header(&c, head);
|
avpriv_mpegaudio_decode_header(&mpah, head);
|
||||||
|
|
||||||
if (!mp3->initial_bitrate)
|
if (!mp3->initial_bitrate)
|
||||||
mp3->initial_bitrate = c.bit_rate;
|
mp3->initial_bitrate = mpah.bit_rate;
|
||||||
if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))
|
if ((mpah.bit_rate == 0) || (mp3->initial_bitrate != mpah.bit_rate))
|
||||||
mp3->has_variable_bitrate = 1;
|
mp3->has_variable_bitrate = 1;
|
||||||
|
|
||||||
#ifdef FILTER_VBR_HEADERS
|
#ifdef FILTER_VBR_HEADERS
|
||||||
/* filter out XING and INFO headers. */
|
/* filter out XING and INFO headers. */
|
||||||
base = 4 + xing_offtbl[c.lsf == 1][c.nb_channels == 1];
|
base = 4 + xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1];
|
||||||
|
|
||||||
if (base + 4 <= pkt->size) {
|
if (base + 4 <= pkt->size) {
|
||||||
uint32_t v = AV_RB32(pkt->data + base);
|
uint32_t v = AV_RB32(pkt->data + base);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user