[FFmpeg-devel] [PATCH 0/2] Fix gapless encoding/remuxing for MP3
Round trip wav->mp3->wav now preserves the correct number of samples. Remuxing mp3->mp3 with -c:a copy also preserves any existing gapless metadata in the Info tag. The code in libmp3lame.c to set AV_PKT_DATA_SKIP_SAMPLES was mostly copied from libopusenc.c. Jon Toohill (2): lavc/libmp3lame: send encoder delay/padding in packet side data lavf/mp3enc: write encoder delay/padding upon closing libavcodec/libmp3lame.c | 27 ++- libavformat/mp3enc.c| 34 -- 2 files changed, 54 insertions(+), 7 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] lavc/libmp3lame: send encoder delay/padding in packet side data
--- libavcodec/libmp3lame.c | 27 ++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 5642264..e55aa85 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -50,6 +50,7 @@ typedef struct LAMEContext { int reservoir; int joint_stereo; int abr; +int delay_sent; float *samples_flt[2]; AudioFrameQueue afq; AVFloatDSPContext *fdsp; @@ -185,7 +186,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, { LAMEContext *s = avctx->priv_data; MPADecodeHeader hdr; -int len, ret, ch; +int len, ret, ch, discard_padding; int lame_result; uint32_t h; @@ -269,6 +270,30 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ff_af_queue_remove(>afq, avctx->frame_size, >pts, >duration); +discard_padding = avctx->frame_size - avpkt->duration; +// Check if subtraction resulted in an overflow +if ((discard_padding < avctx->frame_size) != (avpkt->duration > 0)) { +av_log(avctx, AV_LOG_ERROR, "discard padding overflow\n"); +av_packet_unref(avpkt); +av_free(avpkt); +return AVERROR(EINVAL); +} +if ((!s->delay_sent && avctx->initial_padding > 0) || discard_padding > 0) { +uint8_t* side_data = av_packet_new_side_data(avpkt, + AV_PKT_DATA_SKIP_SAMPLES, + 10); +if(!side_data) { +av_packet_unref(avpkt); +av_free(avpkt); +return AVERROR(ENOMEM); +} +if (!s->delay_sent) { +AV_WL32(side_data, avctx->initial_padding); +s->delay_sent = 1; +} +AV_WL32(side_data + 4, discard_padding); +} + avpkt->size = len; *got_packet_ptr = 1; } -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] lavf/mp3enc: write encoder delay/padding upon closing
--- libavformat/mp3enc.c | 34 -- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index de63401..4c97fa1 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -111,6 +111,8 @@ typedef struct MP3Context { uint64_t bag[XING_NUM_BAGS]; int initial_bitrate; int has_variable_bitrate; +int delay; +int padding; /* index of the audio stream */ int audio_stream_idx; @@ -247,12 +249,7 @@ static int mp3_write_xing(AVFormatContext *s) ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate - -// encoder delay -if (par->initial_padding - 528 - 1 >= 1 << 12) { -av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); -} -avio_wb24(dyn_ctx, FFMAX(par->initial_padding - 528 - 1, 0)<<12); +avio_wb24(dyn_ctx, 0);// empty encoder delay/padding avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain @@ -345,10 +342,24 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) #endif if (mp3->xing_offset) { +uint8_t *side_data = NULL; +int side_data_size = 0; + mp3_xing_add_frame(mp3, pkt); mp3->audio_size += pkt->size; mp3->audio_crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), mp3->audio_crc, pkt->data, pkt->size); + +side_data = av_packet_get_side_data(pkt, +AV_PKT_DATA_SKIP_SAMPLES, +_data_size); +if (side_data && side_data_size >= 10) { +mp3->padding = FFMAX(AV_RL32(side_data + 4) + 528 + 1, 0); +if (!mp3->delay) +mp3->delay = FFMAX(AV_RL32(side_data) - 528 - 1, 0); +} else { +mp3->padding = 0; +} } } @@ -422,6 +433,17 @@ static void mp3_update_xing(AVFormatContext *s) } } +/* write encoder delay/padding */ +if (mp3->delay >= 1 << 12) { +mp3->delay = (1 << 12) - 1; +av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); +} +if (mp3->padding >= 1 << 12) { +mp3->padding = (1 << 12) - 1; +av_log(s, AV_LOG_WARNING, "Too many samples of trailing padding.\n"); +} +AV_WB24(mp3->xing_frame + mp3->xing_offset + 141, (mp3->delay << 12) + mp3->padding); + AV_WB32(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 8, mp3->audio_size); AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 4, mp3->audio_crc); -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] lavf/mp3enc: write encoder delay/padding upon closing
--- libavformat/mp3enc.c | 34 +++--- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index de63401..ddf4b93 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -111,6 +111,8 @@ typedef struct MP3Context { uint64_t bag[XING_NUM_BAGS]; int initial_bitrate; int has_variable_bitrate; +int delay; +int padding; /* index of the audio stream */ int audio_stream_idx; @@ -247,12 +249,7 @@ static int mp3_write_xing(AVFormatContext *s) ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate - -// encoder delay -if (par->initial_padding - 528 - 1 >= 1 << 12) { -av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); -} -avio_wb24(dyn_ctx, FFMAX(par->initial_padding - 528 - 1, 0)<<12); +avio_wb24(dyn_ctx, 0);// empty encoder delay/padding avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain @@ -345,10 +342,24 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) #endif if (mp3->xing_offset) { +uint8_t *side_data = NULL; +int side_data_size = 0; + mp3_xing_add_frame(mp3, pkt); mp3->audio_size += pkt->size; mp3->audio_crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), mp3->audio_crc, pkt->data, pkt->size); + +side_data = av_packet_get_side_data(pkt, +AV_PKT_DATA_SKIP_SAMPLES, +_data_size); +if (side_data && side_data_size >= 10) { +mp3->padding = AV_RL32(side_data + 4) + 528 + 1; +if (!mp3->delay) +mp3->delay = FFMAX(AV_RL32(side_data) - 528 - 1, 0); +} else { +mp3->padding = 0; +} } } @@ -381,7 +392,7 @@ static void mp3_update_xing(AVFormatContext *s) AVReplayGain *rg; uint16_t tag_crc; uint8_t *toc; -int i, rg_size; +int i, rg_size, delay; /* replace "Xing" identification string with "Info" for CBR files. */ if (!mp3->has_variable_bitrate) @@ -422,6 +433,15 @@ static void mp3_update_xing(AVFormatContext *s) } } +/* write encoder delay/padding */ +if (mp3->delay >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); +} +if (mp3->padding >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of trailing padding.\n"); +} +AV_WB24(mp3->xing_frame + mp3->xing_offset + 141, (mp3->delay << 12) + mp3->padding); + AV_WB32(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 8, mp3->audio_size); AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 4, mp3->audio_crc); -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/2] Fix gapless encoding/remuxing for MP3
Round trip wav->mp3->wav now preserves the correct number of samples. Remuxing mp3->mp3 with -c:a copy also preserves any existing gapless metadata in the Info tag. The code in libmp3lame.c to set AV_PKT_DATA_SKIP_SAMPLES was mostly copied from libopusenc.c. Jon Toohill (2): lavc/libmp3lame: send encoder delay/padding in packet side data lavf/mp3enc: write encoder delay/padding upon closing libavcodec/libmp3lame.c | 26 +- libavformat/mp3enc.c| 34 +++--- 2 files changed, 52 insertions(+), 8 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] lavc/libmp3lame: send encoder delay/padding in packet side data
--- libavcodec/libmp3lame.c | 26 +- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 5642264..b3ba0d8 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -50,6 +50,7 @@ typedef struct LAMEContext { int reservoir; int joint_stereo; int abr; +int delay_sent; float *samples_flt[2]; AudioFrameQueue afq; AVFloatDSPContext *fdsp; @@ -185,7 +186,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, { LAMEContext *s = avctx->priv_data; MPADecodeHeader hdr; -int len, ret, ch; +int len, ret, ch, discard_padding; int lame_result; uint32_t h; @@ -269,6 +270,29 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ff_af_queue_remove(>afq, avctx->frame_size, >pts, >duration); +discard_padding = avctx->frame_size - avpkt->duration; +// Check if subtraction resulted in an overflow +if ((discard_padding < avctx->frame_size) != (avpkt->duration > 0)) { +av_packet_unref(avpkt); +av_free(avpkt); +return AVERROR(EINVAL); +} +if ((!s->delay_sent && avctx->initial_padding > 0) || discard_padding > 0) { +uint8_t* side_data = av_packet_new_side_data(avpkt, + AV_PKT_DATA_SKIP_SAMPLES, + 10); +if(!side_data) { +av_packet_unref(avpkt); +av_free(avpkt); +return AVERROR(ENOMEM); +} +if (!s->delay_sent) { +AV_WL32(side_data, avctx->initial_padding); +s->delay_sent = 1; +} +AV_WL32(side_data + 4, discard_padding); +} + avpkt->size = len; *got_packet_ptr = 1; } -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/3] lavf/mp3dec: read encoder delay/padding from Info tag
On Wed, Oct 5, 2016 at 11:03 AM, wm4 <nfx...@googlemail.com> wrote: > On Wed, 5 Oct 2016 10:42:13 -0700 > Jon Toohill <jtoohill-at-google@ffmpeg.org> wrote: > > > On Wed, Oct 5, 2016 at 10:40 AM, Jon Toohill <jtooh...@google.com> > wrote: > > > > > On Tue, Oct 4, 2016 at 7:19 AM, wm4 <nfx...@googlemail.com> wrote: > > > > > >> On Mon, 3 Oct 2016 17:45:08 -0700 > > >> Jon Toohill <jtoohill-at-google@ffmpeg.org> wrote: > > >> > > >> > Muxers can check AVCodecParameters.initial_padding for the > > >> > encoder+decoder delay, and read the AV_PKT_DATA_SKIP_SAMPLES > > >> > side data from the last packet for the encoder padding. > > >> > > > >> > This change also fixes the first_discard_sample calculation > > >> > which erroneously included the decoder delay. Decoder delay > > >> > is already accounted for in st->skip_samples. The affected > > >> > FATE tests have been updated accordingly. > > >> > --- > > >> > libavformat/mp3dec.c | 3 ++- > > >> > tests/ref/fate/audiomatch-square-mp3 | 2 +- > > >> > tests/ref/fate/gapless-mp3 | 10 +- > > >> > 3 files changed, 8 insertions(+), 7 deletions(-) > > >> > > > >> > diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c > > >> > index 56c7f8c..e8b2428 100644 > > >> > --- a/libavformat/mp3dec.c > > >> > +++ b/libavformat/mp3dec.c > > >> > @@ -239,9 +239,10 @@ static void mp3_parse_info_tag(AVFormatContext > > >> *s, AVStream *st, > > >> > > > >> > mp3->start_pad = v>>12; > > >> > mp3-> end_pad = v&4095; > > >> > +st->codecpar->initial_padding = mp3->start_pad + 528 + 1; > > >> > st->start_skip_samples = mp3->start_pad + 528 + 1; > > >> > if (mp3->frames) { > > >> > -st->first_discard_sample = -mp3->end_pad + 528 + 1 + > > >> mp3->frames * (int64_t)spf; > > >> > +st->first_discard_sample = -mp3->end_pad + mp3->frames > * > > >> (int64_t)spf; > > >> > > >> How does mixing these even make sense? > > >> > > > > > > mp3enc.c already uses initial_padding for the encoder delay, and as you > > > previously pointed out, mp3dec.c already uses > AV_PKT_START_SKIP_SAMPLES for > > > the encoder delay. I'm not attempting to solve the inconsistency in > this > > > patch set. > > > > > > > err, *mp3dec.c already uses AV_PKT_DATA_SKIP_SAMPLES for the encoder > > padding. Sorry for the confusion. > > > > Not solving the inconsistency is problematic - but the worse issue is > that you seem to introduce inconsistencies. In my current opinion, the > packet side data and the initial_padding fields do the same (i.e. > duplicated API), so only one of them can or should be used. Your patch > seems to require the decoder to use them both, though. > That's a fair point; I'll send a revised patch set that doesn't change mp3dec.c. Note that I don't think I can get away from having libmp3lame.c set AVCodecContext.initial_padding, since that field is used by the AudioFrameQueue (and other encoders rely on it as well). ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/3] lavf/mp3dec: read encoder delay/padding from Info tag
On Tue, Oct 4, 2016 at 9:10 AM, Michael Niedermayer <mich...@niedermayer.cc> wrote: > On Mon, Oct 03, 2016 at 05:45:08PM -0700, Jon Toohill wrote: > > Muxers can check AVCodecParameters.initial_padding for the > > encoder+decoder delay, and read the AV_PKT_DATA_SKIP_SAMPLES > > side data from the last packet for the encoder padding. > > > > This change also fixes the first_discard_sample calculation > > which erroneously included the decoder delay. Decoder delay > > is already accounted for in st->skip_samples. The affected > > FATE tests have been updated accordingly. > > --- > > libavformat/mp3dec.c | 3 ++- > > tests/ref/fate/audiomatch-square-mp3 | 2 +- > > tests/ref/fate/gapless-mp3 | 10 +- > > 3 files changed, 8 insertions(+), 7 deletions(-) > > > > diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c > > index 56c7f8c..e8b2428 100644 > > --- a/libavformat/mp3dec.c > > +++ b/libavformat/mp3dec.c > > @@ -239,9 +239,10 @@ static void mp3_parse_info_tag(AVFormatContext *s, > AVStream *st, > > > > mp3->start_pad = v>>12; > > mp3-> end_pad = v&4095; > > +st->codecpar->initial_padding = mp3->start_pad + 528 + 1; > > st->start_skip_samples = mp3->start_pad + 528 + 1; > > if (mp3->frames) { > > -st->first_discard_sample = -mp3->end_pad + 528 + 1 + > mp3->frames * (int64_t)spf; > > +st->first_discard_sample = -mp3->end_pad + mp3->frames * > (int64_t)spf; > > st->last_discard_sample = mp3->frames * (int64_t)spf; > > } > > if (!st->start_time) > > diff --git a/tests/ref/fate/audiomatch-square-mp3 > b/tests/ref/fate/audiomatch-square-mp3 > > index 8de55c2..05176a0 100644 > > --- a/tests/ref/fate/audiomatch-square-mp3 > > +++ b/tests/ref/fate/audiomatch-square-mp3 > > @@ -1 +1 @@ > > -presig: 0 postsig:0 c: 0.9447 lenerr:0 > > +presig: 0 postsig:-529 c: 0.9334 lenerr:-529 > > isnt this exactly correct before and wrong after this change ? > > zero signal before and zero signal after the original is what one would > expect and equal length and high correlation > > every number that changes gets worse > Michael - you're right, this patch is incorrect currently. I had mistakenly convinced myself that mp3dec.c was overcompensating for the decoder delay. I also found that LAME itself writes the encoder padding + decoder delay into the trailing padding field (e.g. for an input where 468 samples of padding are added by the encoder, the Info tag contains the value 997). I'll send a revised patch set. > [...] > > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Never trust a computer, one day, it may think you are the virus. -- Compn > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/3] lavf/mp3dec: read encoder delay/padding from Info tag
On Tue, Oct 4, 2016 at 7:19 AM, wm4 <nfx...@googlemail.com> wrote: > On Mon, 3 Oct 2016 17:45:08 -0700 > Jon Toohill <jtoohill-at-google@ffmpeg.org> wrote: > > > Muxers can check AVCodecParameters.initial_padding for the > > encoder+decoder delay, and read the AV_PKT_DATA_SKIP_SAMPLES > > side data from the last packet for the encoder padding. > > > > This change also fixes the first_discard_sample calculation > > which erroneously included the decoder delay. Decoder delay > > is already accounted for in st->skip_samples. The affected > > FATE tests have been updated accordingly. > > --- > > libavformat/mp3dec.c | 3 ++- > > tests/ref/fate/audiomatch-square-mp3 | 2 +- > > tests/ref/fate/gapless-mp3 | 10 +- > > 3 files changed, 8 insertions(+), 7 deletions(-) > > > > diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c > > index 56c7f8c..e8b2428 100644 > > --- a/libavformat/mp3dec.c > > +++ b/libavformat/mp3dec.c > > @@ -239,9 +239,10 @@ static void mp3_parse_info_tag(AVFormatContext *s, > AVStream *st, > > > > mp3->start_pad = v>>12; > > mp3-> end_pad = v&4095; > > +st->codecpar->initial_padding = mp3->start_pad + 528 + 1; > > st->start_skip_samples = mp3->start_pad + 528 + 1; > > if (mp3->frames) { > > -st->first_discard_sample = -mp3->end_pad + 528 + 1 + > mp3->frames * (int64_t)spf; > > +st->first_discard_sample = -mp3->end_pad + mp3->frames * > (int64_t)spf; > > How does mixing these even make sense? > mp3enc.c already uses initial_padding for the encoder delay, and as you previously pointed out, mp3dec.c already uses AV_PKT_START_SKIP_SAMPLES for the encoder delay. I'm not attempting to solve the inconsistency in this patch set. > > st->last_discard_sample = mp3->frames * (int64_t)spf; > > } > > if (!st->start_time) > > diff --git a/tests/ref/fate/audiomatch-square-mp3 > b/tests/ref/fate/audiomatch-square-mp3 > > index 8de55c2..05176a0 100644 > > --- a/tests/ref/fate/audiomatch-square-mp3 > > +++ b/tests/ref/fate/audiomatch-square-mp3 > > @@ -1 +1 @@ > > -presig: 0 postsig:0 c: 0.9447 lenerr:0 > > +presig: 0 postsig:-529 c: 0.9334 lenerr:-529 > > diff --git a/tests/ref/fate/gapless-mp3 b/tests/ref/fate/gapless-mp3 > > index ebe7bfa..8b80bfc 100644 > > --- a/tests/ref/fate/gapless-mp3 > > +++ b/tests/ref/fate/gapless-mp3 > > @@ -1,5 +1,5 @@ > > -37534a3bcc3ef306e8c5ebfcfedfc41c *tests/data/fate/gapless-mp3.out-1 > > -c96c3ae7bd3300fd2f4debac222de5b7 > > -0cd1cdbcfd5cdbf6270cd98219bf31cd *tests/data/fate/gapless-mp3.out-2 > > -c96c3ae7bd3300fd2f4debac222de5b7 > > -9d3d8ba8a61b534f2d02ee648d6a8229 *tests/data/fate/gapless-mp3.out-3 > > +81695be427d45e8be4d527a6b2af2a85 *tests/data/fate/gapless-mp3.out-1 > > +c7879a827ab017364774069268d9a267 > > +62d074296f8c84a5f86a6afdd7bab459 *tests/data/fate/gapless-mp3.out-2 > > +c7879a827ab017364774069268d9a267 > > +e931f3fe1ba25e0d5eece4977c4061a9 *tests/data/fate/gapless-mp3.out-3 > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/3] lavf/mp3dec: read encoder delay/padding from Info tag
Muxers can check AVCodecParameters.initial_padding for the encoder+decoder delay, and read the AV_PKT_DATA_SKIP_SAMPLES side data from the last packet for the encoder padding. This change also fixes the first_discard_sample calculation which erroneously included the decoder delay. Decoder delay is already accounted for in st->skip_samples. The affected FATE tests have been updated accordingly. --- libavformat/mp3dec.c | 3 ++- tests/ref/fate/audiomatch-square-mp3 | 2 +- tests/ref/fate/gapless-mp3 | 10 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 56c7f8c..e8b2428 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -239,9 +239,10 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; +st->codecpar->initial_padding = mp3->start_pad + 528 + 1; st->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { -st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; +st->first_discard_sample = -mp3->end_pad + mp3->frames * (int64_t)spf; st->last_discard_sample = mp3->frames * (int64_t)spf; } if (!st->start_time) diff --git a/tests/ref/fate/audiomatch-square-mp3 b/tests/ref/fate/audiomatch-square-mp3 index 8de55c2..05176a0 100644 --- a/tests/ref/fate/audiomatch-square-mp3 +++ b/tests/ref/fate/audiomatch-square-mp3 @@ -1 +1 @@ -presig: 0 postsig:0 c: 0.9447 lenerr:0 +presig: 0 postsig:-529 c: 0.9334 lenerr:-529 diff --git a/tests/ref/fate/gapless-mp3 b/tests/ref/fate/gapless-mp3 index ebe7bfa..8b80bfc 100644 --- a/tests/ref/fate/gapless-mp3 +++ b/tests/ref/fate/gapless-mp3 @@ -1,5 +1,5 @@ -37534a3bcc3ef306e8c5ebfcfedfc41c *tests/data/fate/gapless-mp3.out-1 -c96c3ae7bd3300fd2f4debac222de5b7 -0cd1cdbcfd5cdbf6270cd98219bf31cd *tests/data/fate/gapless-mp3.out-2 -c96c3ae7bd3300fd2f4debac222de5b7 -9d3d8ba8a61b534f2d02ee648d6a8229 *tests/data/fate/gapless-mp3.out-3 +81695be427d45e8be4d527a6b2af2a85 *tests/data/fate/gapless-mp3.out-1 +c7879a827ab017364774069268d9a267 +62d074296f8c84a5f86a6afdd7bab459 *tests/data/fate/gapless-mp3.out-2 +c7879a827ab017364774069268d9a267 +e931f3fe1ba25e0d5eece4977c4061a9 *tests/data/fate/gapless-mp3.out-3 -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] lavc/libmp3lame: send encoder padding in side data of final packet
--- libavcodec/libmp3lame.c | 21 - 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 5642264..a1bf122 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -185,7 +185,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, { LAMEContext *s = avctx->priv_data; MPADecodeHeader hdr; -int len, ret, ch; +int len, ret, ch, discard_padding; int lame_result; uint32_t h; @@ -269,6 +269,25 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ff_af_queue_remove(>afq, avctx->frame_size, >pts, >duration); +discard_padding = avctx->frame_size - avpkt->duration; +// Check if subtraction resulted in an overflow +if ((discard_padding < avctx->frame_size) != (avpkt->duration > 0)) { +av_packet_unref(avpkt); +av_free(avpkt); +return AVERROR(EINVAL); +} +if (discard_padding > 0) { +uint8_t* side_data = av_packet_new_side_data(avpkt, + AV_PKT_DATA_SKIP_SAMPLES, + 10); +if(!side_data) { +av_packet_unref(avpkt); +av_free(avpkt); +return AVERROR(ENOMEM); +} +AV_WL32(side_data + 4, discard_padding); +} + avpkt->size = len; *got_packet_ptr = 1; } -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3] lavf/mp3enc: write encoder delay/padding upon closing
--- libavformat/mp3enc.c | 32 +--- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index de63401..48cb0b4 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -111,6 +111,7 @@ typedef struct MP3Context { uint64_t bag[XING_NUM_BAGS]; int initial_bitrate; int has_variable_bitrate; +int trailing_padding; /* index of the audio stream */ int audio_stream_idx; @@ -247,12 +248,7 @@ static int mp3_write_xing(AVFormatContext *s) ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate - -// encoder delay -if (par->initial_padding - 528 - 1 >= 1 << 12) { -av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); -} -avio_wb24(dyn_ctx, FFMAX(par->initial_padding - 528 - 1, 0)<<12); +avio_wb24(dyn_ctx, 0);// empty encoder delay/padding avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain @@ -345,10 +341,22 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) #endif if (mp3->xing_offset) { +uint8_t *side_data = NULL; +int side_data_size = 0; + mp3_xing_add_frame(mp3, pkt); mp3->audio_size += pkt->size; mp3->audio_crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), mp3->audio_crc, pkt->data, pkt->size); + +side_data = av_packet_get_side_data(pkt, +AV_PKT_DATA_SKIP_SAMPLES, +_data_size); +if (side_data && side_data_size >= 10) { +mp3->trailing_padding = AV_RL32(side_data + 4); +} else { +mp3->trailing_padding = 0; +} } } @@ -381,7 +389,7 @@ static void mp3_update_xing(AVFormatContext *s) AVReplayGain *rg; uint16_t tag_crc; uint8_t *toc; -int i, rg_size; +int i, rg_size, delay; /* replace "Xing" identification string with "Info" for CBR files. */ if (!mp3->has_variable_bitrate) @@ -422,6 +430,16 @@ static void mp3_update_xing(AVFormatContext *s) } } +/* write encoder delay/padding */ +delay = FFMAX(s->streams[0]->codecpar->initial_padding - 528 - 1, 0); +if (delay >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); +} +if (mp3->trailing_padding >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of trailing padding.\n"); +} +AV_WB24(mp3->xing_frame + mp3->xing_offset + 141, (delay << 12) + mp3->trailing_padding); + AV_WB32(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 8, mp3->audio_size); AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 4, mp3->audio_crc); -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/3] Fix gapless encoding/decoding for MP3
Round trip wav->mp3->wav now preserves the correct number of samples. Remuxing mp3->mp3 with -c:a copy also preserves any existing gapless metadata in the Info tag. The code in libmp3lame.c to set AV_PKT_DATA_SKIP_SAMPLES was mostly copied from libopusenc.c. Jon Toohill (3): lavc/libmp3lame: send encoder padding in side data of final packet lavf/mp3enc: write encoder delay/padding upon closing lavf/mp3dec: read encoder delay/padding from Info tag libavcodec/libmp3lame.c | 21 - libavformat/mp3dec.c | 3 ++- libavformat/mp3enc.c | 32 +--- tests/ref/fate/audiomatch-square-mp3 | 2 +- tests/ref/fate/gapless-mp3 | 10 +- 5 files changed, 53 insertions(+), 15 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/4] ffmpeg: re-copy codec contexts after encoding
This was sent in error, please disregard. Jon Toohill | Google Play Music | jtooh...@google.com | (650) 215-0770 On Wed, Sep 28, 2016 at 11:28 AM, Jon Toohill <jtooh...@google.com> wrote: > This preserves changes to fields of AVCodecContext that get > updated during encoding, such as trailing_padding (which > may not be known until encoding is complete). > --- > ffmpeg.c | 15 +++ > 1 file changed, 15 insertions(+) > > diff --git a/ffmpeg.c b/ffmpeg.c > index df55a49..1e973f5 100644 > --- a/ffmpeg.c > +++ b/ffmpeg.c > @@ -4243,6 +4243,21 @@ static int transcode(void) > > term_exit(); > > +/* update output codec contexts after encoding */ > +for (i = 0; i < nb_output_streams; i++) { > +ost = output_streams[i]; > +if (ost->encoding_needed) { > +ret = avcodec_copy_context( > +output_files[ost->file_index]->ctx->streams[ost->index]-> > codec, > +ost->enc_ctx); > +if (ret < 0) { > +av_log(ost, AV_LOG_ERROR, "Error copying final codec > context: %s\n", av_err2str(ret)); > +if (exit_on_error) > +exit_program(1); > +} > +} > +} > + > /* write the trailer if needed and close file */ > for (i = 0; i < nb_output_files; i++) { > os = output_files[i]->ctx; > -- > 2.8.0.rc3.226.g39d4020 > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 0/4] Handle trailing_padding in MP3 Info tag
Oops, forgot to send this in reply to the previous thread. Should I re-send? http://ffmpeg.org/pipermail/ffmpeg-devel/2016-September/200092.html On Wed, Sep 28, 2016 at 11:28 AM, Jon Toohill <jtooh...@google.com> wrote: > Trimming trailing_padding samples from the end of the track is not yet > implemented. > > Jon Toohill (4): > ffmpeg: re-copy codec parameters after encoding > lavc/libmp3lame: set trailing_padding after flushing encoder > lavf/mp3enc: write encoder delay/padding upon closing > lavf/mp3dec: read encoder delay/padding from Info tag > > ffmpeg.c| 15 +++ > libavcodec/libmp3lame.c | 1 + > libavformat/mp3dec.c| 2 ++ > libavformat/mp3enc.c| 20 +--- > 4 files changed, 31 insertions(+), 7 deletions(-) > > -- > 2.8.0.rc3.226.g39d4020 > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] lavf/mp3dec: read encoder delay/padding from Info tag
--- libavformat/mp3dec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 56c7f8c..9cc85a3 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -239,6 +239,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; +st->codecpar->initial_padding = mp3->start_pad + 528 + 1; +st->codecpar->trailing_padding = mp3->end_pad; st->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] lavf/mp3enc: write encoder delay/padding upon closing
trailing_padding is not known before encoding. --- libavformat/mp3enc.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index de63401..37608f1 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -247,12 +247,7 @@ static int mp3_write_xing(AVFormatContext *s) ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate - -// encoder delay -if (par->initial_padding - 528 - 1 >= 1 << 12) { -av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); -} -avio_wb24(dyn_ctx, FFMAX(par->initial_padding - 528 - 1, 0)<<12); +avio_wb24(dyn_ctx, 0);// empty encoder delay/padding avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain @@ -381,7 +376,7 @@ static void mp3_update_xing(AVFormatContext *s) AVReplayGain *rg; uint16_t tag_crc; uint8_t *toc; -int i, rg_size; +int i, rg_size, delay, padding; /* replace "Xing" identification string with "Info" for CBR files. */ if (!mp3->has_variable_bitrate) @@ -422,6 +417,17 @@ static void mp3_update_xing(AVFormatContext *s) } } +/* write encoder delay/padding */ +delay = FFMAX(s->streams[0]->codecpar->initial_padding - 528 - 1, 0); +padding = s->streams[0]->codecpar->trailing_padding; +if (delay >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); +} +if (padding >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); +} +AV_WB24(mp3->xing_frame + mp3->xing_offset + 141, (delay << 12) + padding); + AV_WB32(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 8, mp3->audio_size); AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 4, mp3->audio_crc); -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/4] lavc/libmp3lame: set trailing_padding after flushing encoder
On Tue, Sep 27, 2016 at 1:04 AM, Carl Eugen Hoyos <ceffm...@gmail.com> wrote: > 2016-09-26 19:13 GMT+02:00 Jon Toohill <jtoohill-at-google@ffmpeg.org > >: > > > +avctx->trailing_padding = FFMAX(lame_get_encoder_padding(s->gfp) > - 528 - 1, 0); > > Can you confirm that this function exists in lame 3.98.3? > I downloaded the source tarball for lame 3.98 and found it exists there. Is that sufficient? > > Thank you, Carl Eugen > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] ffmpeg: re-copy codec parameters after encoding
This preserves changes to fields of AVCodecParameters that get updated during encoding, such as trailing_padding (which may not be known until encoding is complete). --- ffmpeg.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/ffmpeg.c b/ffmpeg.c index d0f247e..0cdc762 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -4255,6 +4255,21 @@ static int transcode(void) term_exit(); +/* update output codec parameters after encoding */ +for (i = 0; i < nb_output_streams; i++) { +ost = output_streams[i]; +if (ost->encoding_needed) { +ret = avcodec_parameters_from_context( + output_files[ost->file_index]->ctx->streams[ost->index]->codecpar, +ost->enc_ctx); +if (ret < 0) { +av_log(ost, AV_LOG_ERROR, "Error copying final codec context: %s\n", av_err2str(ret)); +if (exit_on_error) +exit_program(1); +} +} +} + /* write the trailer if needed and close file */ for (i = 0; i < nb_output_files; i++) { os = output_files[i]->ctx; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] ffmpeg: re-copy codec contexts after encoding
This preserves changes to fields of AVCodecContext that get updated during encoding, such as trailing_padding (which may not be known until encoding is complete). --- ffmpeg.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/ffmpeg.c b/ffmpeg.c index df55a49..1e973f5 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -4243,6 +4243,21 @@ static int transcode(void) term_exit(); +/* update output codec contexts after encoding */ +for (i = 0; i < nb_output_streams; i++) { +ost = output_streams[i]; +if (ost->encoding_needed) { +ret = avcodec_copy_context( +output_files[ost->file_index]->ctx->streams[ost->index]->codec, +ost->enc_ctx); +if (ret < 0) { +av_log(ost, AV_LOG_ERROR, "Error copying final codec context: %s\n", av_err2str(ret)); +if (exit_on_error) +exit_program(1); +} +} +} + /* write the trailer if needed and close file */ for (i = 0; i < nb_output_files; i++) { os = output_files[i]->ctx; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] lavc/libmp3lame: set trailing_padding after flushing encoder
--- libavcodec/libmp3lame.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 5642264..1566921 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -218,6 +218,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } else { lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index, s->buffer_size - s->buffer_index); +avctx->trailing_padding = FFMAX(lame_get_encoder_padding(s->gfp) - 528 - 1, 0); } if (lame_result < 0) { if (lame_result == -1) { -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] Handle trailing_padding in MP3 Info tag
Trimming trailing_padding samples from the end of the track is not yet implemented. Jon Toohill (4): ffmpeg: re-copy codec parameters after encoding lavc/libmp3lame: set trailing_padding after flushing encoder lavf/mp3enc: write encoder delay/padding upon closing lavf/mp3dec: read encoder delay/padding from Info tag ffmpeg.c| 15 +++ libavcodec/libmp3lame.c | 1 + libavformat/mp3dec.c| 2 ++ libavformat/mp3enc.c| 20 +--- 4 files changed, 31 insertions(+), 7 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 4/4] lavf/mp3dec: read encoder delay/padding from Info tag
A similar concern was raised in a previous related patch: http://ffmpeg.org/pipermail/ffmpeg-devel/2016-May/194690.html I think the resolution at the time was to go ahead with using both, since both are used widely and serve slightly different purposes, although I do agree that it's confusing. I think I could use AV_PKT_DATA_SKIP_SAMPLES here, and change mp3enc to use that to fill out the Info tag. But that only seems worthwhile to me if there is a general consensus to move to just AV_PKT_DATA_SKIP_SAMPLES (and deprecate/remove initial_padding and trailing_padding). If there's a concrete case where knowing trailing_padding at the start of a stream is necessary, then that's not possible, but I'm pretty new to this and don't know of one. Thoughts? Jon Toohill | Google Play Music | jtooh...@google.com | (650) 215-0770 On Mon, Sep 26, 2016 at 11:30 AM, wm4 <nfx...@googlemail.com> wrote: > On Mon, 26 Sep 2016 10:13:39 -0700 > Jon Toohill <jtoohill-at-google@ffmpeg.org> wrote: > > > --- > > libavformat/mp3dec.c | 2 ++ > > 1 file changed, 2 insertions(+) > > > > diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c > > index 56c7f8c..9cc85a3 100644 > > --- a/libavformat/mp3dec.c > > +++ b/libavformat/mp3dec.c > > @@ -239,6 +239,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, > AVStream *st, > > > > mp3->start_pad = v>>12; > > mp3-> end_pad = v&4095; > > +st->codecpar->initial_padding = mp3->start_pad + 528 + 1; > > +st->codecpar->trailing_padding = mp3->end_pad; > > st->start_skip_samples = mp3->start_pad + 528 + 1; > > if (mp3->frames) { > > st->first_discard_sample = -mp3->end_pad + 528 + 1 + > mp3->frames * (int64_t)spf; > > I'm somewhat suspicious about this, because mp3dec.c uses > AV_PKT_DATA_SKIP_SAMPLES to communicate delay/padding > (libavformat/utils.c turns the start_skip_samples field into side > data). So I'm not quite convinced is this mess of FFmpeg and Libav API > mixture is healthy. Opinions welcome. > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/4] lavf/mp3enc: write encoder delay/padding upon closing
trailing_padding is not known before encoding. --- libavformat/mp3enc.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index de63401..433b070 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -247,12 +247,7 @@ static int mp3_write_xing(AVFormatContext *s) ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate - -// encoder delay -if (par->initial_padding - 528 - 1 >= 1 << 12) { -av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); -} -avio_wb24(dyn_ctx, FFMAX(par->initial_padding - 528 - 1, 0)<<12); +avio_wb24(dyn_ctx, 0);// empty encoder delay/padding avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain @@ -381,7 +376,7 @@ static void mp3_update_xing(AVFormatContext *s) AVReplayGain *rg; uint16_t tag_crc; uint8_t *toc; -int i, rg_size; +int i, rg_size, delay, padding; /* replace "Xing" identification string with "Info" for CBR files. */ if (!mp3->has_variable_bitrate) @@ -422,6 +417,17 @@ static void mp3_update_xing(AVFormatContext *s) } } +/* write encoder delay/padding */ +delay = FFMAX(s->streams[0]->codec->initial_padding - 528 - 1, 0); +padding = s->streams[0]->codec->trailing_padding; +if (delay >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); +} +if (padding >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); +} +AV_WB24(mp3->xing_frame + mp3->xing_offset + 141, (delay << 12) + padding); + AV_WB32(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 8, mp3->audio_size); AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 4, mp3->audio_crc); -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/4] lavf/mp3dec: read encoder delay/padding from Info tag
--- libavformat/mp3dec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 56c7f8c..9cc85a3 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -239,6 +239,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; +st->codecpar->initial_padding = mp3->start_pad + 528 + 1; +st->codecpar->trailing_padding = mp3->end_pad; st->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/4] ffmpeg: re-copy codec contexts after encoding
This preserves changes to fields of AVCodecContext that get updated during encoding, such as trailing_padding (which may not be known until encoding is complete). --- ffmpeg.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/ffmpeg.c b/ffmpeg.c index df55a49..1e973f5 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -4243,6 +4243,21 @@ static int transcode(void) term_exit(); +/* update output codec contexts after encoding */ +for (i = 0; i < nb_output_streams; i++) { +ost = output_streams[i]; +if (ost->encoding_needed) { +ret = avcodec_copy_context( +output_files[ost->file_index]->ctx->streams[ost->index]->codec, +ost->enc_ctx); +if (ret < 0) { +av_log(ost, AV_LOG_ERROR, "Error copying final codec context: %s\n", av_err2str(ret)); +if (exit_on_error) +exit_program(1); +} +} +} + /* write the trailer if needed and close file */ for (i = 0; i < nb_output_files; i++) { os = output_files[i]->ctx; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/4] lavc/libmp3lame: set trailing_padding after flushing encoder
--- libavcodec/libmp3lame.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 5642264..1566921 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -218,6 +218,7 @@ static int mp3lame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } else { lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index, s->buffer_size - s->buffer_index); +avctx->trailing_padding = FFMAX(lame_get_encoder_padding(s->gfp) - 528 - 1, 0); } if (lame_result < 0) { if (lame_result == -1) { -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/4] Handle trailing_padding in MP3 Info tag
Trimming trailing_padding samples from the end of the track is not yet implemented. Jon Toohill (4): ffmpeg: re-copy codec contexts after encoding lavc/libmp3lame: set trailing_padding after flushing encoder lavf/mp3enc: write encoder delay/padding upon closing lavf/mp3dec: read encoder delay/padding from Info tag ffmpeg.c| 15 +++ libavcodec/libmp3lame.c | 1 + libavformat/mp3dec.c| 2 ++ libavformat/mp3enc.c| 20 +--- 4 files changed, 31 insertions(+), 7 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] ffmpeg: copy trailing_padding when using -acodec copy
--- ffmpeg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ffmpeg.c b/ffmpeg.c index bae515d..49a1b03 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3001,6 +3001,7 @@ static int transcode_init(void) enc_ctx->audio_service_type = dec_ctx->audio_service_type; enc_ctx->block_align= dec_ctx->block_align; enc_ctx->initial_padding= dec_ctx->delay; +enc_ctx->trailing_padding = dec_ctx->trailing_padding; enc_ctx->profile= dec_ctx->profile; #if FF_API_AUDIOENC_DELAY enc_ctx->delay = dec_ctx->delay; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] lavc: add trailing_padding to AVCodecContext to match AVCodecParameters.
Shows encoder delay/padding in the stream summary if they are set. --- doc/APIchanges | 4 libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 40 +++- libavcodec/version.h | 2 +- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 209ab41..74145b2 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-08-15 - xxx - lavc 57.53.100 - avcodec.h + Add trailing_padding to AVCodecContext to match the corresponding + field in AVCodecParameters. + 2016-08-04 - xxx - lavf 57.46.100 - avformat.h Add av_get_frame_filename2() diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 06c2b89..b43ee5a 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3524,6 +3524,17 @@ typedef struct AVCodecContext { #define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1 #endif +/** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + * + * - decoding: unused + * - encoding: unused + */ +int trailing_padding; + } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 783f62c..6f4d553 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3258,6 +3258,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%d bit)", enc->bits_per_raw_sample); +if (enc->initial_padding || enc->trailing_padding) { +snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", delay %d, padding %d", enc->initial_padding, enc->trailing_padding); +} break; case AVMEDIA_TYPE_DATA: if (av_log_get_level() >= AV_LOG_DEBUG) { @@ -4103,14 +4107,15 @@ int avcodec_parameters_from_context(AVCodecParameters *par, par->video_delay = codec->has_b_frames; break; case AVMEDIA_TYPE_AUDIO: -par->format = codec->sample_fmt; -par->channel_layout = codec->channel_layout; -par->channels= codec->channels; -par->sample_rate = codec->sample_rate; -par->block_align = codec->block_align; -par->frame_size = codec->frame_size; -par->initial_padding = codec->initial_padding; -par->seek_preroll= codec->seek_preroll; +par->format = codec->sample_fmt; +par->channel_layout = codec->channel_layout; +par->channels = codec->channels; +par->sample_rate = codec->sample_rate; +par->block_align = codec->block_align; +par->frame_size = codec->frame_size; +par->initial_padding = codec->initial_padding; +par->trailing_padding = codec->trailing_padding; +par->seek_preroll = codec->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: par->width = codec->width; @@ -4157,15 +4162,16 @@ int avcodec_parameters_to_context(AVCodecContext *codec, codec->has_b_frames = par->video_delay; break; case AVMEDIA_TYPE_AUDIO: -codec->sample_fmt = par->format; -codec->channel_layout = par->channel_layout; -codec->channels= par->channels; -codec->sample_rate = par->sample_rate; -codec->block_align = par->block_align; -codec->frame_size = par->frame_size; -codec->delay = -codec->initial_padding = par->initial_padding; -codec->seek_preroll= par->seek_preroll; +codec->sample_fmt = par->format; +codec->channel_layout = par->channel_layout; +codec->channels = par->channels; +codec->sample_rate = par->sample_rate; +codec->block_align = par->block_align; +codec->frame_size = par->frame_size; +codec->delay= +codec->initial_padding = par->initial_padding; +codec->trailing_padding = par->trailing_padding; +codec->seek_preroll = par->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: codec->width = par->width; diff --git a/libavcodec/version.h b/libavcodec/version.h index a697261..cdfc4f9 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 52 +#define LIBAVCODEC_VERSION_MINOR 53 #define
[FFmpeg-devel] [PATCH 0/2] Minor fixes for encoder padding
These patches backport the trailing_padding field to AVCodecContext, add gapless information to the stream summary string, and fix some cases where trailing_padding was being lost. I'll continue working on supporting initial_padding and trailing_padding for MP3 encoding/decoding in a separate patch set. Jon Toohill (2): lavc: add trailing_padding to AVCodecContext to match AVCodecParameters. ffmpeg: copy trailing_padding when using -acodec copy doc/APIchanges | 4 ffmpeg.c | 1 + libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 40 +++- libavcodec/version.h | 2 +- 5 files changed, 40 insertions(+), 18 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/5] libmp3lame + mp3enc: removes decoder delay compensation
initial_padding specifies only encoder delay, decoder delay is handled by start_skip_samples. --- doc/APIchanges | 4 libavcodec/libmp3lame.c | 2 +- libavcodec/version.h| 2 +- libavformat/mp3enc.c| 4 ++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index d777dc0..ae450e1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-07-12 - xxx - lavc 57.47.100 - libmp3lame.c + Removed MP3 decoder delay from initial_padding in AVCodecContext. + initial_padding only includes the encoder delay. + 2016-04-27 - xxx - lavu 55.23.100 - log.h Add a new function av_log_format_line2() which returns number of bytes written to the target buffer. diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 5642264..198ac94 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -137,7 +137,7 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) } /* get encoder delay */ -avctx->initial_padding = lame_get_encoder_delay(s->gfp) + 528 + 1; +avctx->initial_padding = lame_get_encoder_delay(s->gfp); ff_af_queue_init(avctx, >afq); avctx->frame_size = lame_get_framesize(s->gfp); diff --git a/libavcodec/version.h b/libavcodec/version.h index 0852b43..37a6e17 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 46 +#define LIBAVCODEC_VERSION_MINOR 47 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index de63401..3b77d29 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -249,10 +249,10 @@ static int mp3_write_xing(AVFormatContext *s) avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate // encoder delay -if (par->initial_padding - 528 - 1 >= 1 << 12) { +if (par->initial_padding >= 1 << 12) { av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); } -avio_wb24(dyn_ctx, FFMAX(par->initial_padding - 528 - 1, 0)<<12); +avio_wb24(dyn_ctx, par->initial_padding << 12); avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 4/5] ffmpeg: copy trailing_padding when using -acodec copy
--- ffmpeg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ffmpeg.c b/ffmpeg.c index 652774f..442f818 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3001,6 +3001,7 @@ static int transcode_init(void) enc_ctx->audio_service_type = dec_ctx->audio_service_type; enc_ctx->block_align= dec_ctx->block_align; enc_ctx->initial_padding= dec_ctx->delay; +enc_ctx->trailing_padding = dec_ctx->trailing_padding; enc_ctx->profile= dec_ctx->profile; #if FF_API_AUDIOENC_DELAY enc_ctx->delay = dec_ctx->delay; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 5/5] lavf/mp3enc: write trailing_padding in Xing header
--- libavformat/mp3enc.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index 3b77d29..da70d13 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -248,11 +248,14 @@ static int mp3_write_xing(AVFormatContext *s) avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate -// encoder delay +// encoder delay/padding if (par->initial_padding >= 1 << 12) { av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); } -avio_wb24(dyn_ctx, par->initial_padding << 12); +if (par->trailing_padding >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of trailing padding.\n"); +} +avio_wb24(dyn_ctx, (par->initial_padding << 12) | (par->trailing_padding & 0xFFF)); avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/5] lavc: show gapless info in stream summary
Also adds trailing_padding to AVCodecContext to match AVCodecParameters so that it doesn't get lost when mapping between them. --- doc/APIchanges | 4 libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 40 +++- libavcodec/version.h | 2 +- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index ae450e1..6e92cd4 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-07-12 - xxx - lavc 57.48.100 - avcodec.h + Add trailing_padding to AVCodecContext to match the corresponding + field in AVCodecParameters. + 2016-07-12 - xxx - lavc 57.47.100 - libmp3lame.c Removed MP3 decoder delay from initial_padding in AVCodecContext. initial_padding only includes the encoder delay. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0181eb1..700c9b8 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3504,6 +3504,17 @@ typedef struct AVCodecContext { #define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1 #endif +/** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + * + * - decoding: unused + * - encoding: unused + */ +int trailing_padding; + } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 402a9d8..481e09c 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3252,6 +3252,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%d bit)", enc->bits_per_raw_sample); +if (enc->initial_padding || enc->trailing_padding) { +snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", delay %d, padding %d", enc->initial_padding, enc->trailing_padding); +} break; case AVMEDIA_TYPE_DATA: if (av_log_get_level() >= AV_LOG_DEBUG) { @@ -4097,14 +4101,15 @@ int avcodec_parameters_from_context(AVCodecParameters *par, par->video_delay = codec->has_b_frames; break; case AVMEDIA_TYPE_AUDIO: -par->format = codec->sample_fmt; -par->channel_layout = codec->channel_layout; -par->channels= codec->channels; -par->sample_rate = codec->sample_rate; -par->block_align = codec->block_align; -par->frame_size = codec->frame_size; -par->initial_padding = codec->initial_padding; -par->seek_preroll= codec->seek_preroll; +par->format = codec->sample_fmt; +par->channel_layout = codec->channel_layout; +par->channels = codec->channels; +par->sample_rate = codec->sample_rate; +par->block_align = codec->block_align; +par->frame_size = codec->frame_size; +par->initial_padding = codec->initial_padding; +par->trailing_padding = codec->trailing_padding; +par->seek_preroll = codec->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: par->width = codec->width; @@ -4151,15 +4156,16 @@ int avcodec_parameters_to_context(AVCodecContext *codec, codec->has_b_frames = par->video_delay; break; case AVMEDIA_TYPE_AUDIO: -codec->sample_fmt = par->format; -codec->channel_layout = par->channel_layout; -codec->channels= par->channels; -codec->sample_rate = par->sample_rate; -codec->block_align = par->block_align; -codec->frame_size = par->frame_size; -codec->delay = -codec->initial_padding = par->initial_padding; -codec->seek_preroll= par->seek_preroll; +codec->sample_fmt = par->format; +codec->channel_layout = par->channel_layout; +codec->channels = par->channels; +codec->sample_rate = par->sample_rate; +codec->block_align = par->block_align; +codec->frame_size = par->frame_size; +codec->delay= +codec->initial_padding = par->initial_padding; +codec->trailing_padding = par->trailing_padding; +codec->seek_preroll = par->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: codec->width = par->width; diff --git a/libavcodec/version.h b/libavcodec/version.h index 37a6e17..412fd01 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include
[FFmpeg-devel] [PATCH 1/5] lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters
--- libavformat/mp3dec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 56c7f8c..345fa88 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -239,6 +239,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; +st->codecpar->initial_padding = mp3->start_pad; +st->codecpar->trailing_padding = mp3->end_pad; st->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/5] Pass Xing gapless metadata to users during mp3 parsing
These patches expose the encoder delay/padding parsed from an mp3's Xing header to users of lavc/lavf, and show gapless info in the stream summary string. They also change ffmpeg to pass Xing gapless metadata from input to output when using -acodec copy. trailing_padding is still not set properly when encoding with libmp3lame, causing an encode/decode round trip to add trailing silence. This is not a regression from current behavior, and will be addressed in a separate patch set. Jon Toohill (5): lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters libmp3lame + mp3enc: removes decoder delay compensation lavc: show gapless info in stream summary ffmpeg: copy trailing_padding when using -acodec copy lavf/mp3enc: write trailing_padding in Xing header doc/APIchanges | 8 ffmpeg.c| 1 + libavcodec/avcodec.h| 11 +++ libavcodec/libmp3lame.c | 2 +- libavcodec/utils.c | 40 +++- libavcodec/version.h| 2 +- libavformat/mp3dec.c| 2 ++ libavformat/mp3enc.c| 9 ++--- 8 files changed, 53 insertions(+), 22 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/3] lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters
I'm having a hard time finding software that uses this via simple GitHub searches. I think this should be considered a bugfix, since the struct field states that it only represents encoder delay, not decoder delay. I'll send out an updated patchset that splits this into more patches, including documentation and another minor version bump. Jon Toohill | Google Play Music | jtooh...@google.com | (650) 215-0770 On Fri, Jun 17, 2016 at 5:32 PM, Michael Niedermayer <mich...@niedermayer.cc > wrote: > On Thu, Jun 16, 2016 at 11:16:05AM -0700, Jon Toohill wrote: > > Also removes decoder delay compensation from libmp3lame and mp3enc. > > initial_padding specifies only encoder delay, decoder delay is > > handled by start_skip_samples. > > --- > > libavcodec/libmp3lame.c | 2 +- > > libavformat/mp3dec.c| 2 ++ > > libavformat/mp3enc.c| 9 ++--- > > 3 files changed, 9 insertions(+), 4 deletions(-) > > > > diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c > > index 5642264..198ac94 100644 > > --- a/libavcodec/libmp3lame.c > > +++ b/libavcodec/libmp3lame.c > > @@ -137,7 +137,7 @@ static av_cold int > mp3lame_encode_init(AVCodecContext *avctx) > > } > > > > /* get encoder delay */ > > -avctx->initial_padding = lame_get_encoder_delay(s->gfp) + 528 + 1; > > +avctx->initial_padding = lame_get_encoder_delay(s->gfp); > > ff_af_queue_init(avctx, >afq); > > > > avctx->frame_size = lame_get_framesize(s->gfp); > > you are changing a field of the public API > changing public API without major version bumps is tricky, we dont want > to break applications linkng to a newer lib > > is there software that uses this? > software that would break if this is applied ? (or maybe it wuld fix > some software usig it) > > If this is a bugfix it should be documented in APIChanges with > minor version bumps, any available references to specifications > should be added too > > Such bugfix should also be seperate of other unrelated changes > > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > I have often repented speaking, but never of holding my tongue. > -- Xenocrates > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/3] ffmpeg: copy trailing_padding when using -acodec copy
--- ffmpeg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ffmpeg.c b/ffmpeg.c index 652774f..442f818 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3001,6 +3001,7 @@ static int transcode_init(void) enc_ctx->audio_service_type = dec_ctx->audio_service_type; enc_ctx->block_align= dec_ctx->block_align; enc_ctx->initial_padding= dec_ctx->delay; +enc_ctx->trailing_padding = dec_ctx->trailing_padding; enc_ctx->profile= dec_ctx->profile; #if FF_API_AUDIOENC_DELAY enc_ctx->delay = dec_ctx->delay; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters
Also removes decoder delay compensation from libmp3lame and mp3enc. initial_padding specifies only encoder delay, decoder delay is handled by start_skip_samples. --- libavcodec/libmp3lame.c | 2 +- libavformat/mp3dec.c| 2 ++ libavformat/mp3enc.c| 9 ++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c index 5642264..198ac94 100644 --- a/libavcodec/libmp3lame.c +++ b/libavcodec/libmp3lame.c @@ -137,7 +137,7 @@ static av_cold int mp3lame_encode_init(AVCodecContext *avctx) } /* get encoder delay */ -avctx->initial_padding = lame_get_encoder_delay(s->gfp) + 528 + 1; +avctx->initial_padding = lame_get_encoder_delay(s->gfp); ff_af_queue_init(avctx, >afq); avctx->frame_size = lame_get_framesize(s->gfp); diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 56c7f8c..345fa88 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -239,6 +239,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; +st->codecpar->initial_padding = mp3->start_pad; +st->codecpar->trailing_padding = mp3->end_pad; st->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index de63401..da70d13 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -248,11 +248,14 @@ static int mp3_write_xing(AVFormatContext *s) avio_w8(dyn_ctx, 0); // unknown encoding flags avio_w8(dyn_ctx, 0); // unknown abr/minimal bitrate -// encoder delay -if (par->initial_padding - 528 - 1 >= 1 << 12) { +// encoder delay/padding +if (par->initial_padding >= 1 << 12) { av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n"); } -avio_wb24(dyn_ctx, FFMAX(par->initial_padding - 528 - 1, 0)<<12); +if (par->trailing_padding >= 1 << 12) { +av_log(s, AV_LOG_WARNING, "Too many samples of trailing padding.\n"); +} +avio_wb24(dyn_ctx, (par->initial_padding << 12) | (par->trailing_padding & 0xFFF)); avio_w8(dyn_ctx, 0); // misc avio_w8(dyn_ctx, 0); // mp3gain -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/3] lavc: show gapless info in stream summary
Also adds trailing_padding to AVCodecContext to match AVCodecParameters so that it doesn't get lost when mapping between them. --- doc/APIchanges | 4 libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 40 +++- libavcodec/version.h | 2 +- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index d777dc0..6092419 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-05-25 - xxx - lavc 57.47.100 - avcodec.h + Add trailing_padding to AVCodecContext to match the corresponding + field in AVCodecParameters. + 2016-04-27 - xxx - lavu 55.23.100 - log.h Add a new function av_log_format_line2() which returns number of bytes written to the target buffer. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0181eb1..700c9b8 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3504,6 +3504,17 @@ typedef struct AVCodecContext { #define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1 #endif +/** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + * + * - decoding: unused + * - encoding: unused + */ +int trailing_padding; + } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 402a9d8..481e09c 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3252,6 +3252,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%d bit)", enc->bits_per_raw_sample); +if (enc->initial_padding || enc->trailing_padding) { +snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", delay %d, padding %d", enc->initial_padding, enc->trailing_padding); +} break; case AVMEDIA_TYPE_DATA: if (av_log_get_level() >= AV_LOG_DEBUG) { @@ -4097,14 +4101,15 @@ int avcodec_parameters_from_context(AVCodecParameters *par, par->video_delay = codec->has_b_frames; break; case AVMEDIA_TYPE_AUDIO: -par->format = codec->sample_fmt; -par->channel_layout = codec->channel_layout; -par->channels= codec->channels; -par->sample_rate = codec->sample_rate; -par->block_align = codec->block_align; -par->frame_size = codec->frame_size; -par->initial_padding = codec->initial_padding; -par->seek_preroll= codec->seek_preroll; +par->format = codec->sample_fmt; +par->channel_layout = codec->channel_layout; +par->channels = codec->channels; +par->sample_rate = codec->sample_rate; +par->block_align = codec->block_align; +par->frame_size = codec->frame_size; +par->initial_padding = codec->initial_padding; +par->trailing_padding = codec->trailing_padding; +par->seek_preroll = codec->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: par->width = codec->width; @@ -4151,15 +4156,16 @@ int avcodec_parameters_to_context(AVCodecContext *codec, codec->has_b_frames = par->video_delay; break; case AVMEDIA_TYPE_AUDIO: -codec->sample_fmt = par->format; -codec->channel_layout = par->channel_layout; -codec->channels= par->channels; -codec->sample_rate = par->sample_rate; -codec->block_align = par->block_align; -codec->frame_size = par->frame_size; -codec->delay = -codec->initial_padding = par->initial_padding; -codec->seek_preroll= par->seek_preroll; +codec->sample_fmt = par->format; +codec->channel_layout = par->channel_layout; +codec->channels = par->channels; +codec->sample_rate = par->sample_rate; +codec->block_align = par->block_align; +codec->frame_size = par->frame_size; +codec->delay= +codec->initial_padding = par->initial_padding; +codec->trailing_padding = par->trailing_padding; +codec->seek_preroll = par->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: codec->width = par->width; diff --git a/libavcodec/version.h b/libavcodec/version.h index 0852b43..37a6e17 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define
[FFmpeg-devel] [PATCH 0/3] Pass Xing gapless metadata to users during mp3 parsing
These patches expose the encoder delay/padding parsed from an mp3's Xing header to users of lavc/lavf, and show gapless info in the stream summary string. They also change ffmpeg to pass Xing gapless metadata from input to output when using -acodec copy. trailing_padding is still not set properly when encoding with libmp3lame, causing an encode/decode round trip to add trailing silence. This is not a regression from current behavior, and will be addressed in a separate patch set. Jon Toohill (3): lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters lavc: show gapless info in stream summary ffmpeg: copy trailing_padding when using -acodec copy doc/APIchanges | 4 ffmpeg.c| 1 + libavcodec/avcodec.h| 11 +++ libavcodec/libmp3lame.c | 2 +- libavcodec/utils.c | 40 +++- libavcodec/version.h| 2 +- libavformat/mp3dec.c| 2 ++ libavformat/mp3enc.c| 9 ++--- 8 files changed, 49 insertions(+), 22 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/2] lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters
Michael et al., is this good to merge as-is? I just tested and a round trip with ffmpeg from wav -> mp3 -> wav retains the correct number of samples. Jon Toohill | Google Play Music | jtooh...@google.com | (650) 215-0770 On Wed, Jun 1, 2016 at 5:58 PM, Jon Toohill <jtooh...@google.com> wrote: > Based on my understanding of [1], these values in the Info tag specify > only the encoder delay/padding, which matches the documentation for these > fields. It looks like other formats are using the fields that way as well. > > I think the extra 528 + 1 samples are the decoder delay [2]. It looks like > libmp3lame adds the 528 + 1 only to have mp3dec subtract it, so I'm not > sure why that's done. IIUC start_skip_samples is the mechanism that > actually accounts for the extra delay when decoding. > > [1]: http://gabriel.mp3-tech.org/mp3infotag.html#delays > [2]: http://lame.sourceforge.net/tech-FAQ.txt > > > > Jon Toohill | Google Play Music | jtooh...@google.com | (650) 215-0770 > > On Thu, May 26, 2016 at 7:51 PM, Michael Niedermayer < > mich...@niedermayer.cc> wrote: > >> On Wed, May 25, 2016 at 09:56:59AM -0700, Jon Toohill wrote: >> > --- >> > libavformat/mp3dec.c | 2 ++ >> > 1 file changed, 2 insertions(+) >> > >> > diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c >> > index 3725d67..192f5ef 100644 >> > --- a/libavformat/mp3dec.c >> > +++ b/libavformat/mp3dec.c >> > @@ -234,6 +234,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, >> AVStream *st, >> > >> > mp3->start_pad = v>>12; >> > mp3-> end_pad = v&4095; >> > +st->codecpar->initial_padding = mp3->start_pad; >> > +st->codecpar->trailing_padding = mp3->end_pad; >> > st->start_skip_samples = mp3->start_pad + 528 + 1; >> > if (mp3->frames) { >> > st->first_discard_sample = -mp3->end_pad + 528 + 1 + >> mp3->frames * (int64_t)spf; >> >> is the 528 + 1 difference intended to >> start_skip_samples/first_discard_sample >> ? >> mp3enc stores par->initial_padding - 528 - 1 >> >> [...] >> >> -- >> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB >> >> If you drop bombs on a foreign country and kill a hundred thousand >> innocent people, expect your government to call the consequence >> "unprovoked inhuman terrorist attacks" and use it to justify dropping >> more bombs and killing more people. The technology changed, the idea is >> old. >> >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> >> > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/2] lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters
Based on my understanding of [1], these values in the Info tag specify only the encoder delay/padding, which matches the documentation for these fields. It looks like other formats are using the fields that way as well. I think the extra 528 + 1 samples are the decoder delay [2]. It looks like libmp3lame adds the 528 + 1 only to have mp3dec subtract it, so I'm not sure why that's done. IIUC start_skip_samples is the mechanism that actually accounts for the extra delay when decoding. [1]: http://gabriel.mp3-tech.org/mp3infotag.html#delays [2]: http://lame.sourceforge.net/tech-FAQ.txt Jon Toohill | Google Play Music | jtooh...@google.com | (650) 215-0770 On Thu, May 26, 2016 at 7:51 PM, Michael Niedermayer <mich...@niedermayer.cc > wrote: > On Wed, May 25, 2016 at 09:56:59AM -0700, Jon Toohill wrote: > > --- > > libavformat/mp3dec.c | 2 ++ > > 1 file changed, 2 insertions(+) > > > > diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c > > index 3725d67..192f5ef 100644 > > --- a/libavformat/mp3dec.c > > +++ b/libavformat/mp3dec.c > > @@ -234,6 +234,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, > AVStream *st, > > > > mp3->start_pad = v>>12; > > mp3-> end_pad = v&4095; > > +st->codecpar->initial_padding = mp3->start_pad; > > +st->codecpar->trailing_padding = mp3->end_pad; > > st->start_skip_samples = mp3->start_pad + 528 + 1; > > if (mp3->frames) { > > st->first_discard_sample = -mp3->end_pad + 528 + 1 + > mp3->frames * (int64_t)spf; > > is the 528 + 1 difference intended to > start_skip_samples/first_discard_sample > ? > mp3enc stores par->initial_padding - 528 - 1 > > [...] > > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > If you drop bombs on a foreign country and kill a hundred thousand > innocent people, expect your government to call the consequence > "unprovoked inhuman terrorist attacks" and use it to justify dropping > more bombs and killing more people. The technology changed, the idea is > old. > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters
--- libavformat/mp3dec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 3725d67..192f5ef 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -234,6 +234,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; +st->codecpar->initial_padding = mp3->start_pad; +st->codecpar->trailing_padding = mp3->end_pad; st->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/2] Pass Xing gapless metadata to users during mp3 parsing
These patches expose the encoder delay/padding parsed from an mp3's Xing header to users of lavc/lavf, and show gapless info in the stream summary string. Jon Toohill (2): lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters lavc: show gapless info in stream summary doc/APIchanges | 4 libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 38 ++ libavcodec/version.h | 2 +- libavformat/mp3dec.c | 2 ++ 5 files changed, 40 insertions(+), 17 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] lavc: show gapless info in stream summary
Also adds trailing_padding to AVCodecContext to match AVCodecParameters so that it doesn't get lost when mapping between them. --- doc/APIchanges | 4 libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 38 ++ libavcodec/version.h | 2 +- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index d777dc0..4720b70 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-05-25 - xxx - lavc 57.43.100 - avcodec.h + Add trailing_padding to AVCodecContext to match the corresponding + field in AVCodecParameters. + 2016-04-27 - xxx - lavu 55.23.100 - log.h Add a new function av_log_format_line2() which returns number of bytes written to the target buffer. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 9ec9adf..554e1ee 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3497,6 +3497,17 @@ typedef struct AVCodecContext { #define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1 #endif +/** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + * + * - decoding: unused + * - encoding: unused + */ +int trailing_padding; + } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index e5a832b..51f50b0 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3251,6 +3251,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%d bit)", enc->bits_per_raw_sample); +if (enc->initial_padding || enc->trailing_padding) { +snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", delay %d, padding %d", enc->initial_padding, enc->trailing_padding); +} break; case AVMEDIA_TYPE_DATA: if (av_log_get_level() >= AV_LOG_DEBUG) { @@ -4094,14 +4098,15 @@ int avcodec_parameters_from_context(AVCodecParameters *par, par->video_delay = codec->has_b_frames; break; case AVMEDIA_TYPE_AUDIO: -par->format = codec->sample_fmt; -par->channel_layout = codec->channel_layout; -par->channels= codec->channels; -par->sample_rate = codec->sample_rate; -par->block_align = codec->block_align; -par->frame_size = codec->frame_size; -par->initial_padding = codec->initial_padding; -par->seek_preroll= codec->seek_preroll; +par->format = codec->sample_fmt; +par->channel_layout = codec->channel_layout; +par->channels = codec->channels; +par->sample_rate = codec->sample_rate; +par->block_align = codec->block_align; +par->frame_size = codec->frame_size; +par->initial_padding = codec->initial_padding; +par->trailing_padding = codec->trailing_padding; +par->seek_preroll = codec->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: par->width = codec->width; @@ -4148,14 +4153,15 @@ int avcodec_parameters_to_context(AVCodecContext *codec, codec->has_b_frames = par->video_delay; break; case AVMEDIA_TYPE_AUDIO: -codec->sample_fmt = par->format; -codec->channel_layout = par->channel_layout; -codec->channels= par->channels; -codec->sample_rate = par->sample_rate; -codec->block_align = par->block_align; -codec->frame_size = par->frame_size; -codec->initial_padding = par->initial_padding; -codec->seek_preroll= par->seek_preroll; +codec->sample_fmt = par->format; +codec->channel_layout = par->channel_layout; +codec->channels = par->channels; +codec->sample_rate = par->sample_rate; +codec->block_align = par->block_align; +codec->frame_size = par->frame_size; +codec->initial_padding = par->initial_padding; +codec->trailing_padding = par->trailing_padding; +codec->seek_preroll = par->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: codec->width = par->width; diff --git a/libavcodec/version.h b/libavcodec/version.h index 0916f81..ee3006c 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 42
Re: [FFmpeg-devel] [PATCH 0/2] Pass Xing gapless metadata to users during mp3 parsing
Forgot to fix the author line in those patches, it should read "Jon Toohill <jtooh...@google.com>" instead. I can fix it when sending updated patches if there are revisions to make, otherwise can you change it before merging (or should I send updated patches)? Jon Toohill | Google Play Music | jtooh...@google.com | (650) 215-0770 On Tue, May 24, 2016 at 3:52 PM, Jon Toohill <jtooh...@google.com> wrote: > These patches expose the encoder delay/padding parsed from an mp3's Xing > header to users of lavc/lavf, and show gapless info in the stream summary > string. > > Jon Toohill (2): > lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters > lavc: show gapless info in stream summary > > libavcodec/avcodec.h | 11 +++ > libavcodec/utils.c | 38 ++ > libavformat/mp3dec.c | 2 ++ > 3 files changed, 35 insertions(+), 16 deletions(-) > > -- > 2.8.0.rc3.226.g39d4020 > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 2/2] lavc: show gapless info in stream summary
From: Jon Toohill <jon.tooh...@gmail.com> Also adds trailing_padding to AVCodecContext to match AVCodecParameters so that it doesn't get lost when mapping between them. --- libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 38 ++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 9ec9adf..408efe1 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3321,6 +3321,17 @@ typedef struct AVCodecContext { int initial_padding; /** + * Audio only. The amount of padding (in samples) appended by the encoder to + * the end of the audio. I.e. this number of decoded samples must be + * discarded by the caller from the end of the stream to get the original + * audio without any trailing padding. + * + * - decoding: unused + * - encoding: unused + */ +int trailing_padding; + +/** * - decoding: For codecs that store a framerate value in the compressed * bitstream, the decoder may export it here. { 0, 1} when * unknown. diff --git a/libavcodec/utils.c b/libavcodec/utils.c index e5a832b..51f50b0 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3251,6 +3251,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%d bit)", enc->bits_per_raw_sample); +if (enc->initial_padding || enc->trailing_padding) { +snprintf(buf + strlen(buf), buf_size - strlen(buf), + ", delay %d, padding %d", enc->initial_padding, enc->trailing_padding); +} break; case AVMEDIA_TYPE_DATA: if (av_log_get_level() >= AV_LOG_DEBUG) { @@ -4094,14 +4098,15 @@ int avcodec_parameters_from_context(AVCodecParameters *par, par->video_delay = codec->has_b_frames; break; case AVMEDIA_TYPE_AUDIO: -par->format = codec->sample_fmt; -par->channel_layout = codec->channel_layout; -par->channels= codec->channels; -par->sample_rate = codec->sample_rate; -par->block_align = codec->block_align; -par->frame_size = codec->frame_size; -par->initial_padding = codec->initial_padding; -par->seek_preroll= codec->seek_preroll; +par->format = codec->sample_fmt; +par->channel_layout = codec->channel_layout; +par->channels = codec->channels; +par->sample_rate = codec->sample_rate; +par->block_align = codec->block_align; +par->frame_size = codec->frame_size; +par->initial_padding = codec->initial_padding; +par->trailing_padding = codec->trailing_padding; +par->seek_preroll = codec->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: par->width = codec->width; @@ -4148,14 +4153,15 @@ int avcodec_parameters_to_context(AVCodecContext *codec, codec->has_b_frames = par->video_delay; break; case AVMEDIA_TYPE_AUDIO: -codec->sample_fmt = par->format; -codec->channel_layout = par->channel_layout; -codec->channels= par->channels; -codec->sample_rate = par->sample_rate; -codec->block_align = par->block_align; -codec->frame_size = par->frame_size; -codec->initial_padding = par->initial_padding; -codec->seek_preroll= par->seek_preroll; +codec->sample_fmt = par->format; +codec->channel_layout = par->channel_layout; +codec->channels = par->channels; +codec->sample_rate = par->sample_rate; +codec->block_align = par->block_align; +codec->frame_size = par->frame_size; +codec->initial_padding = par->initial_padding; +codec->trailing_padding = par->trailing_padding; +codec->seek_preroll = par->seek_preroll; break; case AVMEDIA_TYPE_SUBTITLE: codec->width = par->width; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/2] lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters
From: Jon Toohill <jon.tooh...@gmail.com> --- libavformat/mp3dec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 3725d67..192f5ef 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -234,6 +234,8 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st, mp3->start_pad = v>>12; mp3-> end_pad = v&4095; +st->codecpar->initial_padding = mp3->start_pad; +st->codecpar->trailing_padding = mp3->end_pad; st->start_skip_samples = mp3->start_pad + 528 + 1; if (mp3->frames) { st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf; -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 0/2] Pass Xing gapless metadata to users during mp3 parsing
These patches expose the encoder delay/padding parsed from an mp3's Xing header to users of lavc/lavf, and show gapless info in the stream summary string. Jon Toohill (2): lavf/mp3dec: pass Xing gapless metadata to AVCodecParameters lavc: show gapless info in stream summary libavcodec/avcodec.h | 11 +++ libavcodec/utils.c | 38 ++ libavformat/mp3dec.c | 2 ++ 3 files changed, 35 insertions(+), 16 deletions(-) -- 2.8.0.rc3.226.g39d4020 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel