PR #23041 opened by James Almer (jamrial) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23041 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23041.patch
This is required for encoding and muxing PCM audio on IAMF, where variable frame size is not allowed. >From cfdf6ed4b94410316ba077fd904d4583bfcdcac4 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 7 May 2026 14:53:55 -0300 Subject: [PATCH 1/6] avcodec: add a flag to force encoders to expect fixed size frames Signed-off-by: James Almer <[email protected]> --- libavcodec/avcodec.h | 10 ++++++++-- libavcodec/mfenc.c | 2 ++ libavcodec/null.c | 8 ++++++++ libavcodec/options_table.h | 1 + libavcodec/pcm.c | 3 ++- libavcodec/s302menc.c | 3 ++- 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 780557710b..ac250a2777 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -353,6 +353,11 @@ typedef struct RcOverride{ * Discard cropping information from SPS. */ #define AV_CODEC_FLAG2_IGNORE_CROP (1 << 16) +/** + * Force audio encoders to use a fixed frame size, including the last + * frame on codecs that allow it to be smaller. + */ +#define AV_CODEC_FLAG2_FIXED_FRAME_SIZE (1 << 17) /** * Show all frames before the first keyframe @@ -1050,11 +1055,11 @@ typedef struct AVCodecContext { */ AVChannelLayout ch_layout; - /* The following data should not be initialized. */ /** * Number of samples per channel in an audio frame. * - * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame + * - encoding: may be set by the user before calling avcodec_open2(), and + * libavcodec may then overwrite it if needed. Each submitted frame * except the last must contain exactly frame_size samples per channel. * May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the * frame size is not restricted. @@ -1062,6 +1067,7 @@ typedef struct AVCodecContext { */ int frame_size; + /* The following data should not be initialized. */ /** * number of bytes per packet if constant and known or 0 * Used by some WAV based audio codecs. diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c index b51735268b..34607c65d4 100644 --- a/libavcodec/mfenc.c +++ b/libavcodec/mfenc.c @@ -1405,6 +1405,8 @@ static int mf_close(AVCodecContext *avctx) static av_cold int mf_init(AVCodecContext *avctx) { int ret; + if (!(avctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE)) + avctx->frame_size = 0; if ((ret = mf_load_library(avctx)) == 0) { if ((ret = mf_init_encoder(avctx)) == 0) { return 0; diff --git a/libavcodec/null.c b/libavcodec/null.c index e443ddf4f9..ba07166831 100644 --- a/libavcodec/null.c +++ b/libavcodec/null.c @@ -44,6 +44,13 @@ const FFCodec ff_vnull_decoder = { #endif #if CONFIG_ANULL_DECODER +static av_cold int null_init(AVCodecContext *avctx) +{ + if (!(avctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE)) + avctx->frame_size = 0; + return 0; +} + const FFCodec ff_anull_decoder = { .p.name = "anull", CODEC_LONG_NAME("null audio"), @@ -81,6 +88,7 @@ const FFCodec ff_anull_encoder = { .p.type = AVMEDIA_TYPE_AUDIO, .p.id = AV_CODEC_ID_ANULL, .p.capabilities = AV_CODEC_CAP_VARIABLE_FRAME_SIZE, + .init = null_init, CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8P, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32P, diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 99e7002076..7f01909ae6 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -85,6 +85,7 @@ static const AVOption avcodec_options[] = { {"skip_manual", "do not skip samples and export skip information as frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_SKIP_MANUAL}, INT_MIN, INT_MAX, A|D, .unit = "flags2"}, {"ass_ro_flush_noop", "do not reset ASS ReadOrder field on flush", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_RO_FLUSH_NOOP}, INT_MIN, INT_MAX, S|D, .unit = "flags2"}, {"icc_profiles", "generate/parse embedded ICC profiles from/to colorimetry tags", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_ICC_PROFILES}, INT_MIN, INT_MAX, S|D, .unit = "flags2"}, +{"fixed_frame_size", "Force a fixed frame size", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_FLAG2_FIXED_FRAME_SIZE}, INT_MIN, INT_MAX, A|E, .unit = "flags2"}, {"export_side_data", "Export metadata as side data", OFFSET(export_side_data), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT}, 0, UINT_MAX, A|V|S|D|E, .unit = "export_side_data"}, {"mvs", "export motion vectors through frame side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_MVS}, INT_MIN, INT_MAX, V|D, .unit = "export_side_data"}, {"prft", "export Producer Reference Time through packet side data", 0, AV_OPT_TYPE_CONST, {.i64 = AV_CODEC_EXPORT_DATA_PRFT}, INT_MIN, INT_MAX, A|V|S|E, .unit = "export_side_data"}, diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 157adc92d7..d4efb39fdd 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -40,7 +40,8 @@ av_unused av_cold static int pcm_encode_init(AVCodecContext *avctx) { - avctx->frame_size = 0; + if (!(avctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE)) + avctx->frame_size = 0; #if !CONFIG_HARDCODED_TABLES switch (avctx->codec->id) { #if CONFIG_PCM_ALAW_ENCODER diff --git a/libavcodec/s302menc.c b/libavcodec/s302menc.c index ba84ab73b6..86ac24ad70 100644 --- a/libavcodec/s302menc.c +++ b/libavcodec/s302menc.c @@ -61,7 +61,8 @@ static av_cold int s302m_encode_init(AVCodecContext *avctx) } } - avctx->frame_size = 0; + if (!(avctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE)) + avctx->frame_size = 0; avctx->bit_rate = 48000 * avctx->ch_layout.nb_channels * (avctx->bits_per_raw_sample + 4); s->framing_index = 0; -- 2.52.0 >From b754ef538bae8f50dfec43e563294104c3c9d409 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 7 May 2026 15:01:15 -0300 Subject: [PATCH 2/6] avformat/matroskaenc: use frame_size to write audio DefaultDuration Signed-off-by: James Almer <[email protected]> --- libavformat/matroskaenc.c | 2 ++ tests/ref/fate/aac-autobsf-adtstoasc | 4 ++-- tests/ref/fate/matroska-dovi-write-config8 | 4 ++-- tests/ref/fate/matroska-flac-extradata-update | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index f4d4a9cc88..4412b44f33 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2097,6 +2097,8 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO); audio_frame_samples = av_get_audio_frame_duration2(par, 0); + if (!audio_frame_samples) + audio_frame_samples = par->frame_size; if (audio_frame_samples) mkv_write_default_duration(track, pb, (AVRational){ audio_frame_samples, par->sample_rate }); diff --git a/tests/ref/fate/aac-autobsf-adtstoasc b/tests/ref/fate/aac-autobsf-adtstoasc index 616f875ab3..1d7fe46536 100644 --- a/tests/ref/fate/aac-autobsf-adtstoasc +++ b/tests/ref/fate/aac-autobsf-adtstoasc @@ -1,5 +1,5 @@ -b8594ae7884fcad4acfc5b997d012857 *tests/data/fate/aac-autobsf-adtstoasc.matroska -6645 tests/data/fate/aac-autobsf-adtstoasc.matroska +e76eb6a17a975e0f12b6868082bfaf0d *tests/data/fate/aac-autobsf-adtstoasc.matroska +6653 tests/data/fate/aac-autobsf-adtstoasc.matroska #extradata 0: 2, 0x0030001c #tb 0: 1/1000 #media_type 0: audio diff --git a/tests/ref/fate/matroska-dovi-write-config8 b/tests/ref/fate/matroska-dovi-write-config8 index ca21892686..43a703bb25 100644 --- a/tests/ref/fate/matroska-dovi-write-config8 +++ b/tests/ref/fate/matroska-dovi-write-config8 @@ -1,5 +1,5 @@ -2f28699111ea95a7d2937a23e92dfd77 *tests/data/fate/matroska-dovi-write-config8.matroska -3600617 tests/data/fate/matroska-dovi-write-config8.matroska +6562aa21af7d0e8ef44c9bca106731cb *tests/data/fate/matroska-dovi-write-config8.matroska +3600625 tests/data/fate/matroska-dovi-write-config8.matroska #extradata 0: 551, 0xb1ddcd66 #extradata 1: 2, 0x00340022 #tb 0: 1/1000 diff --git a/tests/ref/fate/matroska-flac-extradata-update b/tests/ref/fate/matroska-flac-extradata-update index a4f8bf2dac..7bd2080f08 100644 --- a/tests/ref/fate/matroska-flac-extradata-update +++ b/tests/ref/fate/matroska-flac-extradata-update @@ -1,5 +1,5 @@ -f0b0a6a8a0fc975aef9048023faf7c92 *tests/data/fate/matroska-flac-extradata-update.matroska -1804 tests/data/fate/matroska-flac-extradata-update.matroska +099e0feb5990575e2b46ed9abafc998a *tests/data/fate/matroska-flac-extradata-update.matroska +1828 tests/data/fate/matroska-flac-extradata-update.matroska #extradata 0: 34, 0x93650c81 #extradata 1: 34, 0x93650c81 #extradata 2: 34, 0x93650c81 -- 2.52.0 >From fccea6f36cba287c1854dc99bb240a16fb7a1126 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 7 May 2026 15:06:35 -0300 Subject: [PATCH 3/6] avcodec/encode: report that the padded samples must be discarded For encoders where we pad the last frame, actually tag the silent samples as discardable. Signed-off-by: James Almer <[email protected]> --- libavcodec/encode.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index f1a65a9b23..aad68586e0 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -155,6 +155,8 @@ static int encode_make_refcounted(AVCodecContext *avctx, AVPacket *avpkt) */ static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src, int out_samples) { + AVFrameSideData *sd; + int discard_padding; int ret; frame->format = src->format; @@ -179,6 +181,17 @@ static int pad_last_frame(AVCodecContext *s, AVFrame *frame, const AVFrame *src, s->ch_layout.nb_channels, s->sample_fmt)) < 0) goto fail; + discard_padding = frame->nb_samples - src->nb_samples; + av_assert1(discard_padding > 0); + sd = av_frame_new_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES, 10); + if (!sd) { + ret = AVERROR(ENOMEM); + goto fail; + } + AV_WL32A(sd->data, 0); + AV_WL32A(sd->data + 4, discard_padding); + AV_WL16A(sd->data + 8, 0); + return 0; fail: -- 2.52.0 >From b84d827f819c23aff9efa6bd6936c3c76d9fa582 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 7 May 2026 15:15:47 -0300 Subject: [PATCH 4/6] avcodec/encode: propagate skip samples side data if present Only for non-delay codecs. Signed-off-by: James Almer <[email protected]> --- libavcodec/encode.c | 14 ++++++++++++++ tests/ref/fate/dca-xll_51_16_192_768_0 | 2 +- tests/ref/fate/dca-xll_51_16_192_768_0-dmix_2 | 2 +- tests/ref/fate/dca-xll_51_16_192_768_0-dmix_6 | 2 +- tests/ref/fate/dca-xll_51_16_192_768_1 | 2 +- tests/ref/fate/dca-xll_51_16_192_768_1-dmix_2 | 2 +- tests/ref/fate/dca-xll_51_16_192_768_1-dmix_6 | 2 +- tests/ref/fate/dca-xll_51_24_48_768 | 2 +- tests/ref/fate/dca-xll_51_24_48_768-dmix_2 | 2 +- tests/ref/fate/dca-xll_51_24_48_768-dmix_6 | 2 +- tests/ref/fate/dca-xll_51_24_48_none | 2 +- tests/ref/fate/dca-xll_51_24_48_none-dmix_2 | 2 +- tests/ref/fate/dca-xll_51_24_48_none-dmix_6 | 2 +- tests/ref/fate/dca-xll_71_24_48_768_0 | 2 +- tests/ref/fate/dca-xll_71_24_48_768_0-dmix_2 | 2 +- tests/ref/fate/dca-xll_71_24_48_768_0-dmix_6 | 2 +- tests/ref/fate/dca-xll_71_24_48_768_1 | 2 +- tests/ref/fate/dca-xll_71_24_48_768_1-dmix_2 | 2 +- tests/ref/fate/dca-xll_71_24_48_768_1-dmix_6 | 2 +- tests/ref/fate/dca-xll_71_24_96_768 | 2 +- tests/ref/fate/dca-xll_71_24_96_768-dmix_2 | 2 +- tests/ref/fate/dca-xll_71_24_96_768-dmix_6 | 2 +- tests/ref/fate/dca-xll_x96_51_24_96_1509 | 2 +- tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_2 | 2 +- tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_6 | 2 +- tests/ref/fate/dca-xll_xch_61_24_48_768 | 2 +- tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_2 | 2 +- tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_6 | 2 +- tests/ref/fate/ffmpeg-filter_complex_audio | 2 +- tests/ref/fate/matroska-encoding-delay | 6 +++--- tests/ref/lavf/mkv | 6 +++--- tests/ref/lavf/mkv_attachment | 6 +++--- 32 files changed, 51 insertions(+), 37 deletions(-) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index aad68586e0..652ce59f6d 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -275,6 +275,20 @@ int ff_encode_encode_cb(AVCodecContext *avctx, AVPacket *avpkt, avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); } + if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) { + AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_SKIP_SAMPLES); + if (sd && sd->size >= 10) { + uint8_t *skip_samples = av_packet_new_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, 10); + if (!skip_samples) { + ret = AVERROR(ENOMEM); + goto unref; + } + AV_WL32(skip_samples + 0, AV_RL32(sd->data + 0)); + AV_WL32(skip_samples + 4, AV_RL32(sd->data + 4)); + AV_WB8 (skip_samples + 8, AV_RB8 (sd->data + 8)); + AV_WB8 (skip_samples + 9, AV_RB8 (sd->data + 9)); + } + } } ret = ff_encode_reordered_opaque(avctx, avpkt, frame); diff --git a/tests/ref/fate/dca-xll_51_16_192_768_0 b/tests/ref/fate/dca-xll_51_16_192_768_0 index 30bb49ca1a..fa6978f6f6 100644 --- a/tests/ref/fate/dca-xll_51_16_192_768_0 +++ b/tests/ref/fate/dca-xll_51_16_192_768_0 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s16le #sample_rate 0: 192000 #channel_layout_name 0: 5.1(side) -0, -4096, -4096, 2048, 24576, 0x00000000 +0, -4096, -4096, 2048, 24576, 0x00000000, S=1, Skip Samples, 10, 0x00900010 0, -2048, -2048, 2048, 24576, 0x00000000 0, 0, 0, 2048, 24576, 0x004b62f1 0, 2048, 2048, 2048, 24576, 0x66edba5f diff --git a/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_2 b/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_2 index 30bb49ca1a..fa6978f6f6 100644 --- a/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_2 +++ b/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s16le #sample_rate 0: 192000 #channel_layout_name 0: 5.1(side) -0, -4096, -4096, 2048, 24576, 0x00000000 +0, -4096, -4096, 2048, 24576, 0x00000000, S=1, Skip Samples, 10, 0x00900010 0, -2048, -2048, 2048, 24576, 0x00000000 0, 0, 0, 2048, 24576, 0x004b62f1 0, 2048, 2048, 2048, 24576, 0x66edba5f diff --git a/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_6 b/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_6 index 30bb49ca1a..fa6978f6f6 100644 --- a/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_6 +++ b/tests/ref/fate/dca-xll_51_16_192_768_0-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s16le #sample_rate 0: 192000 #channel_layout_name 0: 5.1(side) -0, -4096, -4096, 2048, 24576, 0x00000000 +0, -4096, -4096, 2048, 24576, 0x00000000, S=1, Skip Samples, 10, 0x00900010 0, -2048, -2048, 2048, 24576, 0x00000000 0, 0, 0, 2048, 24576, 0x004b62f1 0, 2048, 2048, 2048, 24576, 0x66edba5f diff --git a/tests/ref/fate/dca-xll_51_16_192_768_1 b/tests/ref/fate/dca-xll_51_16_192_768_1 index 30bb49ca1a..fa6978f6f6 100644 --- a/tests/ref/fate/dca-xll_51_16_192_768_1 +++ b/tests/ref/fate/dca-xll_51_16_192_768_1 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s16le #sample_rate 0: 192000 #channel_layout_name 0: 5.1(side) -0, -4096, -4096, 2048, 24576, 0x00000000 +0, -4096, -4096, 2048, 24576, 0x00000000, S=1, Skip Samples, 10, 0x00900010 0, -2048, -2048, 2048, 24576, 0x00000000 0, 0, 0, 2048, 24576, 0x004b62f1 0, 2048, 2048, 2048, 24576, 0x66edba5f diff --git a/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_2 b/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_2 index 2ebc65ab6c..b34dba9ce7 100644 --- a/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_2 +++ b/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s16le #sample_rate 0: 192000 #channel_layout_name 0: stereo -0, -4096, -4096, 2048, 8192, 0x00000000 +0, -4096, -4096, 2048, 8192, 0x00000000, S=1, Skip Samples, 10, 0x00900010 0, -2048, -2048, 2048, 8192, 0x5a180402 0, 0, 0, 2048, 8192, 0x53413568 0, 2048, 2048, 2048, 8192, 0x2a34e9e1 diff --git a/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_6 b/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_6 index 30bb49ca1a..fa6978f6f6 100644 --- a/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_6 +++ b/tests/ref/fate/dca-xll_51_16_192_768_1-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s16le #sample_rate 0: 192000 #channel_layout_name 0: 5.1(side) -0, -4096, -4096, 2048, 24576, 0x00000000 +0, -4096, -4096, 2048, 24576, 0x00000000, S=1, Skip Samples, 10, 0x00900010 0, -2048, -2048, 2048, 24576, 0x00000000 0, 0, 0, 2048, 24576, 0x004b62f1 0, 2048, 2048, 2048, 24576, 0x66edba5f diff --git a/tests/ref/fate/dca-xll_51_24_48_768 b/tests/ref/fate/dca-xll_51_24_48_768 index e2c2e9c035..8a573993a1 100644 --- a/tests/ref/fate/dca-xll_51_24_48_768 +++ b/tests/ref/fate/dca-xll_51_24_48_768 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 512, 9216, 0x00000000 +0, -1024, -1024, 512, 9216, 0x00000000, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 9216, 0x00000000 0, 0, 0, 512, 9216, 0x03de31ea 0, 512, 512, 512, 9216, 0xfdbede52 diff --git a/tests/ref/fate/dca-xll_51_24_48_768-dmix_2 b/tests/ref/fate/dca-xll_51_24_48_768-dmix_2 index 43396ba00f..16be11e744 100644 --- a/tests/ref/fate/dca-xll_51_24_48_768-dmix_2 +++ b/tests/ref/fate/dca-xll_51_24_48_768-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: stereo -0, -1024, -1024, 512, 3072, 0x00000000 +0, -1024, -1024, 512, 3072, 0x00000000, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 3072, 0x00000000 0, 0, 0, 512, 3072, 0xa27d155c 0, 512, 512, 512, 3072, 0x56efed53 diff --git a/tests/ref/fate/dca-xll_51_24_48_768-dmix_6 b/tests/ref/fate/dca-xll_51_24_48_768-dmix_6 index e2c2e9c035..8a573993a1 100644 --- a/tests/ref/fate/dca-xll_51_24_48_768-dmix_6 +++ b/tests/ref/fate/dca-xll_51_24_48_768-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 512, 9216, 0x00000000 +0, -1024, -1024, 512, 9216, 0x00000000, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 9216, 0x00000000 0, 0, 0, 512, 9216, 0x03de31ea 0, 512, 512, 512, 9216, 0xfdbede52 diff --git a/tests/ref/fate/dca-xll_51_24_48_none b/tests/ref/fate/dca-xll_51_24_48_none index 26a7326039..7942888eaa 100644 --- a/tests/ref/fate/dca-xll_51_24_48_none +++ b/tests/ref/fate/dca-xll_51_24_48_none @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 1024, 18432, 0x00000000 +0, -1024, -1024, 1024, 18432, 0x00000000, S=1, Skip Samples, 10, 0x00240004 0, 0, 0, 1024, 18432, 0x5ca6ebf7 0, 1024, 1024, 1024, 18432, 0xb5520ea3 [PACKET] diff --git a/tests/ref/fate/dca-xll_51_24_48_none-dmix_2 b/tests/ref/fate/dca-xll_51_24_48_none-dmix_2 index 26a7326039..7942888eaa 100644 --- a/tests/ref/fate/dca-xll_51_24_48_none-dmix_2 +++ b/tests/ref/fate/dca-xll_51_24_48_none-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 1024, 18432, 0x00000000 +0, -1024, -1024, 1024, 18432, 0x00000000, S=1, Skip Samples, 10, 0x00240004 0, 0, 0, 1024, 18432, 0x5ca6ebf7 0, 1024, 1024, 1024, 18432, 0xb5520ea3 [PACKET] diff --git a/tests/ref/fate/dca-xll_51_24_48_none-dmix_6 b/tests/ref/fate/dca-xll_51_24_48_none-dmix_6 index 26a7326039..7942888eaa 100644 --- a/tests/ref/fate/dca-xll_51_24_48_none-dmix_6 +++ b/tests/ref/fate/dca-xll_51_24_48_none-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 1024, 18432, 0x00000000 +0, -1024, -1024, 1024, 18432, 0x00000000, S=1, Skip Samples, 10, 0x00240004 0, 0, 0, 1024, 18432, 0x5ca6ebf7 0, 1024, 1024, 1024, 18432, 0xb5520ea3 [PACKET] diff --git a/tests/ref/fate/dca-xll_71_24_48_768_0 b/tests/ref/fate/dca-xll_71_24_48_768_0 index fc5e4cd09f..fdd9d59d15 100644 --- a/tests/ref/fate/dca-xll_71_24_48_768_0 +++ b/tests/ref/fate/dca-xll_71_24_48_768_0 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 7.1 -0, -1024, -1024, 512, 12288, 0xa5edf1df +0, -1024, -1024, 512, 12288, 0xa5edf1df, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 12288, 0x00000000 0, 0, 0, 512, 12288, 0x6613373c 0, 512, 512, 512, 12288, 0xa36ccec0 diff --git a/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_2 b/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_2 index e28ee93429..2d5737fb82 100644 --- a/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_2 +++ b/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 512, 9216, 0xa1d1f1df +0, -1024, -1024, 512, 9216, 0xa1d1f1df, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 9216, 0x00000000 0, 0, 0, 512, 9216, 0xeeb20c83 0, 512, 512, 512, 9216, 0xfda4b141 diff --git a/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_6 b/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_6 index e28ee93429..2d5737fb82 100644 --- a/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_6 +++ b/tests/ref/fate/dca-xll_71_24_48_768_0-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 512, 9216, 0xa1d1f1df +0, -1024, -1024, 512, 9216, 0xa1d1f1df, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 9216, 0x00000000 0, 0, 0, 512, 9216, 0xeeb20c83 0, 512, 512, 512, 9216, 0xfda4b141 diff --git a/tests/ref/fate/dca-xll_71_24_48_768_1 b/tests/ref/fate/dca-xll_71_24_48_768_1 index fc5e4cd09f..fdd9d59d15 100644 --- a/tests/ref/fate/dca-xll_71_24_48_768_1 +++ b/tests/ref/fate/dca-xll_71_24_48_768_1 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 7.1 -0, -1024, -1024, 512, 12288, 0xa5edf1df +0, -1024, -1024, 512, 12288, 0xa5edf1df, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 12288, 0x00000000 0, 0, 0, 512, 12288, 0x6613373c 0, 512, 512, 512, 12288, 0xa36ccec0 diff --git a/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_2 b/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_2 index da70f543b6..afe80260cc 100644 --- a/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_2 +++ b/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: stereo -0, -1024, -1024, 512, 3072, 0x00000000 +0, -1024, -1024, 512, 3072, 0x00000000, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 3072, 0x00000000 0, 0, 0, 512, 3072, 0x1bf4e1f9 0, 512, 512, 512, 3072, 0x89a1d6cd diff --git a/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_6 b/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_6 index f1f7ddddea..89fe2ab225 100644 --- a/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_6 +++ b/tests/ref/fate/dca-xll_71_24_48_768_1-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 512, 9216, 0xa1d1f1df +0, -1024, -1024, 512, 9216, 0xa1d1f1df, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 9216, 0x00000000 0, 0, 0, 512, 9216, 0xd12a04fd 0, 512, 512, 512, 9216, 0x7832be51 diff --git a/tests/ref/fate/dca-xll_71_24_96_768 b/tests/ref/fate/dca-xll_71_24_96_768 index 6bbabfc736..cf7b3d138a 100644 --- a/tests/ref/fate/dca-xll_71_24_96_768 +++ b/tests/ref/fate/dca-xll_71_24_96_768 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 96000 #channel_layout_name 0: 7.1 -0, -2048, -2048, 1024, 24576, 0xbdfff0e4 +0, -2048, -2048, 1024, 24576, 0xbdfff0e4, S=1, Skip Samples, 10, 0x00480008 0, -1024, -1024, 1024, 24576, 0x00000000 0, 0, 0, 1024, 24576, 0x47d8aee7 0, 1024, 1024, 1024, 24576, 0x2018104b diff --git a/tests/ref/fate/dca-xll_71_24_96_768-dmix_2 b/tests/ref/fate/dca-xll_71_24_96_768-dmix_2 index 1c8bd6c0e7..05fcb13147 100644 --- a/tests/ref/fate/dca-xll_71_24_96_768-dmix_2 +++ b/tests/ref/fate/dca-xll_71_24_96_768-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 96000 #channel_layout_name 0: 5.1(side) -0, -2048, -2048, 1024, 18432, 0xb8cdf0e4 +0, -2048, -2048, 1024, 18432, 0xb8cdf0e4, S=1, Skip Samples, 10, 0x00480008 0, -1024, -1024, 1024, 18432, 0x00000000 0, 0, 0, 1024, 18432, 0x89262806 0, 1024, 1024, 1024, 18432, 0xab935a48 diff --git a/tests/ref/fate/dca-xll_71_24_96_768-dmix_6 b/tests/ref/fate/dca-xll_71_24_96_768-dmix_6 index 1c8bd6c0e7..05fcb13147 100644 --- a/tests/ref/fate/dca-xll_71_24_96_768-dmix_6 +++ b/tests/ref/fate/dca-xll_71_24_96_768-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 96000 #channel_layout_name 0: 5.1(side) -0, -2048, -2048, 1024, 18432, 0xb8cdf0e4 +0, -2048, -2048, 1024, 18432, 0xb8cdf0e4, S=1, Skip Samples, 10, 0x00480008 0, -1024, -1024, 1024, 18432, 0x00000000 0, 0, 0, 1024, 18432, 0x89262806 0, 1024, 1024, 1024, 18432, 0xab935a48 diff --git a/tests/ref/fate/dca-xll_x96_51_24_96_1509 b/tests/ref/fate/dca-xll_x96_51_24_96_1509 index 05b36097d9..bc36fbe226 100644 --- a/tests/ref/fate/dca-xll_x96_51_24_96_1509 +++ b/tests/ref/fate/dca-xll_x96_51_24_96_1509 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 96000 #channel_layout_name 0: 5.1(side) -0, -2048, -2048, 1024, 18432, 0x00000000 +0, -2048, -2048, 1024, 18432, 0x00000000, S=1, Skip Samples, 10, 0x00480008 0, -1024, -1024, 1024, 18432, 0x00000000 0, 0, 0, 1024, 18432, 0xa6b18739 0, 1024, 1024, 1024, 18432, 0xd4df050d diff --git a/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_2 b/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_2 index 05b36097d9..bc36fbe226 100644 --- a/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_2 +++ b/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 96000 #channel_layout_name 0: 5.1(side) -0, -2048, -2048, 1024, 18432, 0x00000000 +0, -2048, -2048, 1024, 18432, 0x00000000, S=1, Skip Samples, 10, 0x00480008 0, -1024, -1024, 1024, 18432, 0x00000000 0, 0, 0, 1024, 18432, 0xa6b18739 0, 1024, 1024, 1024, 18432, 0xd4df050d diff --git a/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_6 b/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_6 index 05b36097d9..bc36fbe226 100644 --- a/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_6 +++ b/tests/ref/fate/dca-xll_x96_51_24_96_1509-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 96000 #channel_layout_name 0: 5.1(side) -0, -2048, -2048, 1024, 18432, 0x00000000 +0, -2048, -2048, 1024, 18432, 0x00000000, S=1, Skip Samples, 10, 0x00480008 0, -1024, -1024, 1024, 18432, 0x00000000 0, 0, 0, 1024, 18432, 0xa6b18739 0, 1024, 1024, 1024, 18432, 0xd4df050d diff --git a/tests/ref/fate/dca-xll_xch_61_24_48_768 b/tests/ref/fate/dca-xll_xch_61_24_48_768 index 8a17ddb5f9..da19abb69b 100644 --- a/tests/ref/fate/dca-xll_xch_61_24_48_768 +++ b/tests/ref/fate/dca-xll_xch_61_24_48_768 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 6.1 -0, -1024, -1024, 512, 10752, 0xd4320448 +0, -1024, -1024, 512, 10752, 0xd4320448, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 10752, 0x00000000 0, 0, 0, 512, 10752, 0xb0d63493 0, 512, 512, 512, 10752, 0xb25bd689 diff --git a/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_2 b/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_2 index 1b0e77adaf..2f1f14c320 100644 --- a/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_2 +++ b/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_2 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 512, 9216, 0xb1820448 +0, -1024, -1024, 512, 9216, 0xb1820448, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 9216, 0x00000000 0, 0, 0, 512, 9216, 0xeeef4c10 0, 512, 512, 512, 9216, 0x7bb4ed68 diff --git a/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_6 b/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_6 index 1b0e77adaf..2f1f14c320 100644 --- a/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_6 +++ b/tests/ref/fate/dca-xll_xch_61_24_48_768-dmix_6 @@ -3,7 +3,7 @@ #codec_id 0: pcm_s24le #sample_rate 0: 48000 #channel_layout_name 0: 5.1(side) -0, -1024, -1024, 512, 9216, 0xb1820448 +0, -1024, -1024, 512, 9216, 0xb1820448, S=1, Skip Samples, 10, 0x00240004 0, -512, -512, 512, 9216, 0x00000000 0, 0, 0, 512, 9216, 0xeeef4c10 0, 512, 512, 512, 9216, 0x7bb4ed68 diff --git a/tests/ref/fate/ffmpeg-filter_complex_audio b/tests/ref/fate/ffmpeg-filter_complex_audio index 3f2f670514..4b6c73545c 100644 --- a/tests/ref/fate/ffmpeg-filter_complex_audio +++ b/tests/ref/fate/ffmpeg-filter_complex_audio @@ -6,4 +6,4 @@ 0, -256, -256, 1536, 416, 0x3001fb2d 0, 1280, 1280, 1536, 418, 0xba72fc16 0, 2816, 2816, 1536, 418, 0xba72fc16 -0, 4352, 4352, 3, 418, 0xba72fc16 +0, 4352, 4352, 3, 418, 0xba72fc16, S=1, Skip Samples, 10, 0x06070102 diff --git a/tests/ref/fate/matroska-encoding-delay b/tests/ref/fate/matroska-encoding-delay index ad1edad1e8..2ba3edf84c 100644 --- a/tests/ref/fate/matroska-encoding-delay +++ b/tests/ref/fate/matroska-encoding-delay @@ -1,5 +1,5 @@ -ece637ed28526724c88f5c69b8bf7d6f *tests/data/fate/matroska-encoding-delay.matroska -961252 tests/data/fate/matroska-encoding-delay.matroska +5febd4af0b197d8d0756fcaa99c066a2 *tests/data/fate/matroska-encoding-delay.matroska +961258 tests/data/fate/matroska-encoding-delay.matroska #extradata 0: 22, 0x32ea0490 #tb 0: 1/1000 #media_type 0: video @@ -21,7 +21,7 @@ ece637ed28526724c88f5c69b8bf7d6f *tests/data/fate/matroska-encoding-delay.matros 1, 86, 86, 24, 1152, 0xc9e85398 1, 110, 110, 24, 1152, 0xda1287d3 0, 120, 120, 40, 238290, 0xbe18b18f -1, 134, 134, 16, 1152, 0x1c9a6102 +1, 134, 134, 16, 1152, 0x1c9a6102, S=1, Skip Samples, 10, 0x03050081 [PACKET] codec_type=audio stream_index=1 diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv index 94605b3f4c..6e2bdfefdd 100644 --- a/tests/ref/lavf/mkv +++ b/tests/ref/lavf/mkv @@ -1,3 +1,3 @@ -dd709c2b5e173eaca39cdd4a10aac3ec *tests/data/lavf/lavf.mkv -320447 tests/data/lavf/lavf.mkv -tests/data/lavf/lavf.mkv CRC=0x29d44368 +3d79de7fc1c67016e864b40cdb207ff7 *tests/data/lavf/lavf.mkv +320454 tests/data/lavf/lavf.mkv +tests/data/lavf/lavf.mkv CRC=0xb05f51a3 diff --git a/tests/ref/lavf/mkv_attachment b/tests/ref/lavf/mkv_attachment index 6effac49e1..55ce58bfe2 100644 --- a/tests/ref/lavf/mkv_attachment +++ b/tests/ref/lavf/mkv_attachment @@ -1,3 +1,3 @@ -7cd7b06892b74d66da217c8dda90bfac *tests/data/lavf/lavf.mkv_attachment -472597 tests/data/lavf/lavf.mkv_attachment -tests/data/lavf/lavf.mkv_attachment CRC=0x29d44368 +2d9ed072357227c31cb68534f7483a81 *tests/data/lavf/lavf.mkv_attachment +472604 tests/data/lavf/lavf.mkv_attachment +tests/data/lavf/lavf.mkv_attachment CRC=0xb05f51a3 -- 2.52.0 >From 91be6744f6109d6ed0d3ba5ee6e5dd9465cfaec0 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 7 May 2026 15:18:41 -0300 Subject: [PATCH 5/6] avcodec/encode: honor the user request for fixed size frames Signed-off-by: James Almer <[email protected]> --- libavcodec/encode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/encode.c b/libavcodec/encode.c index 652ce59f6d..fc7ece9c8a 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -466,7 +466,7 @@ static int encode_send_frame_internal(AVCodecContext *avctx, const AVFrame *src) avctx->audio_service_type = *(enum AVAudioServiceType*)sd->data; /* check for valid frame size */ - if (!(avctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { + if (avctx->frame_size) { /* if we already got an undersized frame, that must have been the last */ if (ec->last_audio_frame) { av_log(avctx, AV_LOG_ERROR, "frame_size (%d) was not respected for a non-last frame\n", avctx->frame_size); -- 2.52.0 >From edeb514f50600d05de312c580509a51f17ba3894 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 7 May 2026 15:20:20 -0300 Subject: [PATCH 6/6] fftools:/ffmpeg_enc: honor the user request for fixed size frames Signed-off-by: James Almer <[email protected]> --- fftools/ffmpeg_enc.c | 2 ++ fftools/ffmpeg_mux_init.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c index a595912933..5738f2ae15 100644 --- a/fftools/ffmpeg_enc.c +++ b/fftools/ffmpeg_enc.c @@ -227,6 +227,8 @@ int enc_open(void *opaque, const AVFrame *frame) frame->ch_layout.nb_channels > 0); enc_ctx->sample_fmt = frame->format; enc_ctx->sample_rate = frame->sample_rate; + if (enc_ctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE) + enc_ctx->frame_size = frame->nb_samples; ret = av_channel_layout_copy(&enc_ctx->ch_layout, &frame->ch_layout); if (ret < 0) return ret; diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c index e0eecf78f2..638c53cfb3 100644 --- a/fftools/ffmpeg_mux_init.c +++ b/fftools/ffmpeg_mux_init.c @@ -2127,7 +2127,8 @@ static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, nb_interleaved += IS_INTERLEAVED(type); nb_av_enc += IS_AV_ENC(ost, type); nb_audio_fs += (ost->enc && type == AVMEDIA_TYPE_AUDIO && - !(ost->enc->enc_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)); + (!(ost->enc->enc_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) || + (ost->enc->enc_ctx->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE))); limit_frames |= ms->max_frames < INT64_MAX; limit_frames_av_enc |= (ms->max_frames < INT64_MAX) && IS_AV_ENC(ost, type); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
