mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2026-06-11 08:13:06 +00:00
avcodec: add a flag to force encoders to use fixed size frames
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+11
-4
@@ -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
|
||||
|
||||
+3
-2
@@ -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;
|
||||
|
||||
|
||||
@@ -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"},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, \
|
||||
|
||||
Reference in New Issue
Block a user