[FFmpeg-devel] [RFC] [PATCH] mp3: keep gapless information on stream-copy
Andreas Cadhalpun
andreas.cadhalpun at googlemail.com
Tue Dec 22 23:40:15 CET 2015
Fixes Debian bug #797965, https://bugs.debian.org/797965
---
This can't be used as is, because it requires copying private stream fields
in ffmpeg.c.
Also the duplication between codec->initial_padding and st->start_skip_samples
is less than ideal.
Does someone have a better idea how to fix this?
---
ffmpeg.c | 3 +++
libavformat/mp3enc.c | 23 +++++++++++++++++++----
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/ffmpeg.c b/ffmpeg.c
index 10d0f25..a2a0bd7 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -3012,6 +3012,9 @@ static int transcode_init(void)
enc_ctx->block_align= 0;
if(enc_ctx->codec_id == AV_CODEC_ID_AC3)
enc_ctx->block_align= 0;
+ ost->st->start_skip_samples = ist->st->start_skip_samples;
+ ost->st->first_discard_sample = ist->st->first_discard_sample;
+ ost->st->last_discard_sample = ist->st->last_discard_sample;
break;
case AVMEDIA_TYPE_VIDEO:
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index 40f0672..364442e 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -129,8 +129,9 @@ static const uint8_t xing_offtbl[2][2] = {{32, 17}, {17, 9}};
static int mp3_write_xing(AVFormatContext *s)
{
MP3Context *mp3 = s->priv_data;
- AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
- AVDictionaryEntry *enc = av_dict_get(s->streams[mp3->audio_stream_idx]->metadata, "encoder", NULL, 0);
+ AVStream *st = s->streams[mp3->audio_stream_idx];
+ AVCodecContext *codec = st->codec;
+ AVDictionaryEntry *enc = av_dict_get(st->metadata, "encoder", NULL, 0);
AVIOContext *dyn_ctx;
int32_t header;
MPADecodeHeader mpah;
@@ -141,6 +142,7 @@ static int mp3_write_xing(AVFormatContext *s)
int ret;
int ver = 0;
int bytes_needed;
+ int start_pad, end_pad;
if (!s->pb->seekable || !mp3->write_xing)
return 0;
@@ -248,10 +250,23 @@ static int mp3_write_xing(AVFormatContext *s)
avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate
// encoder delay
- if (codec->initial_padding - 528 - 1 >= 1 << 12) {
+ if (codec->initial_padding)
+ start_pad = FFMAX(codec->initial_padding - 528 - 1, 0); // from the encoder
+ else
+ start_pad = FFMAX(st->start_skip_samples - 528 - 1, 0); // from the demuxer
+
+ if (start_pad >= 1 << 12) {
av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n");
+ start_pad = (1 << 12) - 1;
+ }
+
+ end_pad = FFMAX(st->last_discard_sample - st->first_discard_sample + 528 + 1, 0);
+ if (end_pad >= 1 << 12) {
+ av_log(s, AV_LOG_WARNING, "Too many samples of final padding.\n");
+ end_pad = (1 << 12) - 1;
}
- avio_wb24(dyn_ctx, FFMAX(codec->initial_padding - 528 - 1, 0)<<12);
+
+ avio_wb24(dyn_ctx, start_pad<<12 | end_pad);
avio_w8(dyn_ctx, 0); // misc
avio_w8(dyn_ctx, 0); // mp3gain
--
2.6.2
More information about the ffmpeg-devel
mailing list