This is an automated email from the git hooks/post-receive script.
Git pushed a commit to branch master
in repository ffmpeg.
The following commit(s) were added to refs/heads/master by this push:
new 23fccd657c avformat/mp3enc: keep trailing padding spanning several
packets
23fccd657c is described below
commit 23fccd657c0ac89f7e60f5465cf3f33fb796d29f
Author: Romain Beauxis <[email protected]>
AuthorDate: Sun Aug 2 13:17:48 2026 -0500
Commit: Romain Beauxis <[email protected]>
CommitDate: Fri Aug 7 21:18:03 2026 +0000
avformat/mp3enc: keep trailing padding spanning several packets
The trailing padding is read from the AV_PKT_DATA_SKIP_SAMPLES side data of
every packet, overwriting the previous value, so only the last packet was
ever accounted for. A single packet holds at most one frame, which caps the
padding that can be written at 1152 + 528 + 1 samples.
LAME regularly reports more than that: gapless/gapless.mp3 carries 1984 and
comes out of a stream copy with 1681, decoding to 303 samples more than the
file it was copied from.
Accumulate instead, and add the decoder delay once the total is known.
Fixes: https://trac.ffmpeg.org/ticket/9755
---
libavformat/mp3enc.c | 8 ++++++--
tests/fate/gapless.mak | 5 +++++
tests/ref/fate/gapless-mp3-remux | 3 +++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index 131fb231fc..14eac3dab6 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -126,7 +126,7 @@ typedef struct MP3Context {
int initial_bitrate;
int has_variable_bitrate;
int delay;
- int padding;
+ int64_t padding;
/* index of the audio stream */
int audio_stream_idx;
@@ -367,7 +367,9 @@ static int mp3_write_audio_packet(AVFormatContext *s,
AVPacket *pkt)
AV_PKT_DATA_SKIP_SAMPLES,
&side_data_size);
if (side_data && side_data_size >= 10) {
- mp3->padding = FFMAX((int64_t)AV_RL32(side_data + 4) + 528 +
1, 0);
+ uint32_t discard_padding = AV_RL32(side_data + 4);
+ /* Padding longer than a frame is spread over several packets.
*/
+ mp3->padding = discard_padding ? mp3->padding +
discard_padding : 0;
if (!mp3->delay)
mp3->delay = FFMAX((int64_t)AV_RL32(side_data) - 528 - 1,
0);
} else {
@@ -449,6 +451,8 @@ static void mp3_update_xing(AVFormatContext *s)
}
/* write encoder delay/padding */
+ if (mp3->padding)
+ mp3->padding += 528 + 1;
if (mp3->delay >= 1 << 12) {
mp3->delay = (1 << 12) - 1;
av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n");
diff --git a/tests/fate/gapless.mak b/tests/fate/gapless.mak
index c5addeebba..d21864546e 100644
--- a/tests/fate/gapless.mak
+++ b/tests/fate/gapless.mak
@@ -4,6 +4,11 @@ fate-gapless-mp3: CMD = gapless
$(TARGET_SAMPLES)/gapless/gapless.mp3 "-c:a mp3"
FATE_GAPLESSINFO_PROBE-$(CONFIG_MP3_DEMUXER) += fate-gapless-mp3-side-data
fate-gapless-mp3-side-data: CMD = ffprobe_demux
$(TARGET_SAMPLES)/gapless/gapless.mp3
+# The trailing padding of this sample spans two packets. The duration of the
+# remuxed file has to stay the one fate-gapless-mp3-side-data reports.
+FATE_GAPLESSENC_PROBE-$(call ALLYES, MP3_DEMUXER MP3_MUXER NULL_MUXER) +=
fate-gapless-mp3-remux
+fate-gapless-mp3-remux: CMD = transcode mp3
$(TARGET_SAMPLES)/gapless/gapless.mp3 mp3 "-c copy" "-c copy" "-of compact
-show_entries stream=start_pts,duration_ts" "" "" "" null
+
FATE_GAPLESS-$(call DEMDEC, MP3, MP3, ARESAMPLE_FILTER WAV_MUXER) +=
fate-audiomatch-square-mp3
fate-audiomatch-square-mp3: CMD = audio_match
$(TARGET_SAMPLES)/audiomatch/square3.mp3 $(SAMPLES)/audiomatch/square3.wav
diff --git a/tests/ref/fate/gapless-mp3-remux b/tests/ref/fate/gapless-mp3-remux
new file mode 100644
index 0000000000..0d3d625e33
--- /dev/null
+++ b/tests/ref/fate/gapless-mp3-remux
@@ -0,0 +1,3 @@
+4458dffaa3fd294d708f05965e1a3186 *tests/data/fate/gapless-mp3-remux.mp3
+249138 tests/data/fate/gapless-mp3-remux.mp3
+stream|start_pts=353600|duration_ts=218521600
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]