This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit b1120b1ed80e255cc41d174335f0dd2536827c74
Author:     James Almer <[email protected]>
AuthorDate: Thu May 7 14:53:55 2026 -0300
Commit:     James Almer <[email protected]>
CommitDate: Sat May 16 13:55:22 2026 -0300

    avcodec: add a flag to force encoders to use fixed size frames
    
    Signed-off-by: James Almer <[email protected]>
---
 doc/APIchanges             |  3 +++
 doc/codecs.texi            |  2 ++
 libavcodec/avcodec.c       |  8 ++++++++
 libavcodec/avcodec.h       | 15 +++++++++++----
 libavcodec/encode.c        |  5 +++--
 libavcodec/options_table.h |  1 +
 libavcodec/pcm.c           |  1 -
 libavcodec/s302menc.c      |  1 -
 libavcodec/version.h       |  2 +-
 9 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 1b11f512c3..605672d5d3 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2025-03-28
 
 API changes, most recent first:
 
+2026-05-16 - xxxxxxxxxxx - lavc 62.33.100 - avcodec.h
+  Add AV_CODEC_FLAG2_FIXED_FRAME_SIZE.
+
 2026-05-12 - xxxxxxxxxx - lavu 60.31.100 - frame.h
 Add IAMF frame side data types to enum AVFrameSideDataType:
 - AV_FRAME_DATA_IAMF_MIX_GAIN_PARAM
diff --git a/doc/codecs.texi b/doc/codecs.texi
index eec5d8e8c7..63319551de 100644
--- a/doc/codecs.texi
+++ b/doc/codecs.texi
@@ -646,6 +646,8 @@ Do not skip samples and export skip information as frame 
side data.
 Do not reset ASS ReadOrder field on flush.
 @item icc_profiles
 Generate/parse embedded ICC profiles from/to colorimetry tags.
+@item fixed_frame_size
+Force audio encoders to use a fixed frame size.
 @end table
 
 @item export_side_data @var{flags} 
(@emph{decoding/encoding,audio,video,subtitles})
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 9ff4c7f319..e6a28d8bab 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -354,6 +354,14 @@ int attribute_align_arg avcodec_open2(AVCodecContext 
*avctx, const AVCodec *code
         if (!avctx->bit_rate)
             avctx->bit_rate = get_bit_rate(avctx);
 
+
+        if (avctx->codec_type == AVMEDIA_TYPE_AUDIO &&
+            !avctx->frame_size && (avctx->flags2 & 
AV_CODEC_FLAG2_FIXED_FRAME_SIZE)) {
+            av_log(avctx, AV_LOG_ERROR, "Fixed frame size requested but no 
frame_size value set\n");
+            ret = AVERROR(EINVAL);
+            goto free_and_end;
+        }
+
         avci->skip_samples = avctx->delay;
 
         /* validate channel layout from the decoder */
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 780557710b..11ee76efd9 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -353,6 +353,10 @@ 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.
+ */
+#define AV_CODEC_FLAG2_FIXED_FRAME_SIZE (1 << 17)
 
 /**
  * Show all frames before the first keyframe
@@ -1050,18 +1054,20 @@ 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
+     *   May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, 
except
+     *   when AV_CODEC_FLAG2_FIXED_FRAME_SIZE is requested, then the
      *   frame size is not restricted.
      * - decoding: may be set by some decoders to indicate constant frame size
      */
     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.
@@ -2414,7 +2420,8 @@ int avcodec_receive_frame(AVCodecContext *avctx, AVFrame 
*frame);
  *                  For audio:
  *                  If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
  *                  can have any number of samples.
- *                  If it is not set, frame->nb_samples must be equal to
+ *                  If it is not set, or AV_CODEC_FLAG2_FIXED_FRAME_SIZE was
+ *                  requested, then frame->nb_samples must be equal to
  *                  avctx->frame_size for all frames except the last.
  *                  The final frame may be smaller than avctx->frame_size.
  * @retval 0                 success
diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index f1a65a9b23..160aaa739e 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -439,7 +439,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);
@@ -451,7 +451,8 @@ static int encode_send_frame_internal(AVCodecContext 
*avctx, const AVFrame *src)
             }
             if (src->nb_samples < avctx->frame_size) {
                 ec->last_audio_frame = 1;
-                if (!(avctx->codec->capabilities & 
AV_CODEC_CAP_SMALL_LAST_FRAME)) {
+                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 out_samples = (src->nb_samples + pad_samples - 1) / 
pad_samples * pad_samples;
 
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..d699a9f4ae 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -40,7 +40,6 @@
 
 av_unused av_cold static int pcm_encode_init(AVCodecContext *avctx)
 {
-    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..6a743b69d7 100644
--- a/libavcodec/s302menc.c
+++ b/libavcodec/s302menc.c
@@ -61,7 +61,6 @@ static av_cold int s302m_encode_init(AVCodecContext *avctx)
         }
     }
 
-    avctx->frame_size = 0;
     avctx->bit_rate   = 48000 * avctx->ch_layout.nb_channels *
                        (avctx->bits_per_raw_sample + 4);
     s->framing_index  = 0;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 56dbb9238d..2a08e42d7e 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 
 #include "version_major.h"
 
-#define LIBAVCODEC_VERSION_MINOR  32
+#define LIBAVCODEC_VERSION_MINOR  33
 #define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to