PR #25728 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25728 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25728.patch
>From a12c6c1163872b8dd8f61002df67ab0a5d86acae Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 3 Nov 2026 19:28:53 +0100 Subject: [PATCH 1/3] avcodec/encode: derive the last packet's padding from the padded frame Fixes: wrong skip samples side data and duration on the last packet Testcase: ffmpeg -f lavfi -i "sine=r=48000,atrim=end_sample=85" -c:a dfpwm -f framecrc - (discard padding of the last packet 4011 before, 3 after) --- libavcodec/encode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 82ea3aedbb4..9a161111e77 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -257,9 +257,11 @@ static int encode_set_packet_props(AVCodecContext *avctx, AVPacket *avpkt, const int discard_padding = AV_RL32(frame_sd->data + 4); if (discard_padding > 0 && avctx->frame_size && ec->last_audio_frame) { + if (!frame->duration) + avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples - discard_padding); avpkt->duration = av_sat_add64(avpkt->duration, ff_samples_to_time_base(avctx, avctx->initial_padding)); - avpkt->duration = FFMIN(avpkt->duration, ff_samples_to_time_base(avctx, avctx->frame_size)); - discard_padding = avctx->frame_size - ff_samples_from_time_base(avctx, avpkt->duration); + avpkt->duration = FFMIN(avpkt->duration, ff_samples_to_time_base(avctx, frame->nb_samples)); + discard_padding = frame->nb_samples - ff_samples_from_time_base(avctx, avpkt->duration); } if (skip_samples > 0 || discard_padding > 0) { -- 2.54.0 >From f0d6874e4d65d091e9341aee211283227e2a3e22 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 3 Nov 2026 19:28:53 +0100 Subject: [PATCH 2/3] avcodec/encode: pad to the frame size when a fixed frame size is requested Fixes: AV_CODEC_FLAG2_FIXED_FRAME_SIZE ignored by encoders with pad_samples Testcase: ffmpeg -f lavfi -i "sine=r=48000,atrim=end_sample=85" -ac 2 -c:a aptx -flags2 +fixed_frame_size -f framecrc - --- libavcodec/encode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 9a161111e77..179a6eb37df 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -509,7 +509,8 @@ static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src) ec->last_audio_frame = 1; if (!(avctx->codec->capabilities & AV_CODEC_CAP_SMALL_LAST_FRAME) || (avctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE)) { - int pad_samples = avci->pad_samples ? avci->pad_samples : avctx->frame_size; + int pad_samples = avci->pad_samples && !(avctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE) ? + avci->pad_samples : avctx->frame_size; int out_samples = (src->nb_samples + pad_samples - 1) / pad_samples * pad_samples; if (out_samples != src->nb_samples) { -- 2.54.0 >From c163a50935e0ad637841beddb09f1bb64c897d3b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 3 Nov 2026 19:28:53 +0100 Subject: [PATCH 3/3] avcodec/pcm-dvdenc: pad the last frame to a whole block The FATE test encodes 85 samples with and without a fixed frame size. Fixes: up to 3 samples dropped at the end of a 24 bit stream Testcase: ffmpeg -f lavfi -i "sine=r=48000,atrim=end_sample=85" -c:a pcm_dvd -sample_fmt s32 -f framecrc - --- libavcodec/pcm-dvdenc.c | 5 +++-- tests/fate/pcm.mak | 4 ++++ tests/ref/fate/pcm-dvd-last-block | 12 ++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/pcm-dvd-last-block diff --git a/libavcodec/pcm-dvdenc.c b/libavcodec/pcm-dvdenc.c index 4904eea4ca5..c7400582829 100644 --- a/libavcodec/pcm-dvdenc.c +++ b/libavcodec/pcm-dvdenc.c @@ -25,6 +25,7 @@ #include "bytestream.h" #include "codec_internal.h" #include "encode.h" +#include "internal.h" typedef struct PCMDVDContext { uint8_t header[3]; // Header added to every frame @@ -107,6 +108,7 @@ static av_cold int pcm_dvd_encode_init(AVCodecContext *avctx) s->header[2] = 0x80; avctx->frame_size = frame_size; + avctx->internal->pad_samples = s->samples_per_block; return 0; } @@ -176,8 +178,7 @@ const FFCodec ff_pcm_dvd_encoder = { CODEC_LONG_NAME("PCM signed 16|20|24-bit big-endian for DVD-Video media"), .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_PCM_DVD, - .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME | - AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, + .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE, .priv_data_size = sizeof(PCMDVDContext), .init = pcm_dvd_encode_init, FF_CODEC_ENCODE_CB(pcm_dvd_encode_frame), diff --git a/tests/fate/pcm.mak b/tests/fate/pcm.mak index 60462444917..4989e2bd713 100644 --- a/tests/fate/pcm.mak +++ b/tests/fate/pcm.mak @@ -62,6 +62,10 @@ FATE_PCM-$(call TRANSCODE, PCM_DVD, MPEG2VOB MPEGPS, WAV_DEMUXER PCM_S16LE_DECOD fate-pcm_dvd-16-1-96000: tests/data/asynth-96000-1.wav fate-pcm_dvd-16-1-96000: CMD = transcode wav $(TARGET_PATH)/tests/data/asynth-96000-1.wav vob "-c:a pcm_dvd" "-t 0.2" +FATE_PCM-$(call ALLYES, PCM_DVD_ENCODER LAVFI_INDEV SINE_FILTER ATRIM_FILTER ARESAMPLE_FILTER \ + PCM_S16$(if $(filter yes,$(HAVE_BIGENDIAN)),BE,LE)_DECODER FRAMECRC_MUXER PIPE_PROTOCOL) += fate-pcm-dvd-last-block +fate-pcm-dvd-last-block: CMD = framecrc -auto_conversion_filters -f lavfi -i "sine=r=48000,atrim=end_sample=85" -c:a pcm_dvd -sample_fmt s32 -map 0:a -map 0:a -flags2:a:1 +fixed_frame_size + # PCM Blu-ray encoder/decoder roundtrip tests (s16, locally generated sources) FATE_PCM_BLURAY_S16 = fate-pcm-bluray-s16-mono \ fate-pcm-bluray-s16-stereo \ diff --git a/tests/ref/fate/pcm-dvd-last-block b/tests/ref/fate/pcm-dvd-last-block new file mode 100644 index 00000000000..92d75383a7e --- /dev/null +++ b/tests/ref/fate/pcm-dvd-last-block @@ -0,0 +1,12 @@ +#tb 0: 1/48000 +#media_type 0: audio +#codec_id 0: pcm_dvd +#sample_rate 0: 48000 +#channel_layout_name 0: mono +#tb 1: 1/48000 +#media_type 1: audio +#codec_id 1: pcm_dvd +#sample_rate 1: 48000 +#channel_layout_name 1: mono +0, 0, 0, 85, 267, 0x7f3a49be, S=1, Skip Samples, 10, 0x00120003 +1, 0, 0, 85, 507, 0xa56549be, S=1, Skip Samples, 10, 0x01f20053 -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
