* [FFmpeg-devel] [PATCH 1/3] avcodec/decode: Move is_open check to, avcodec_receive_frame()
@ 2025-03-10 16:25 Andreas Rheinhardt
0 siblings, 0 replies; only message in thread
From: Andreas Rheinhardt @ 2025-03-10 16:25 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 29 bytes --]
Patches attached.
- Andreas
[-- Attachment #2: 0001-avcodec-decode-Move-is_open-check-to-avcodec_receive.patch --]
[-- Type: text/x-patch, Size: 1573 bytes --]
From 9636bd44f005059938e9f8526eba4a3a9af38914 Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 10 Mar 2025 16:14:26 +0100
Subject: [PATCH 1/3] avcodec/decode: Move is_open check to
avcodec_receive_frame()
It also applies to scenarios where ff_encode_receive_frame()
is used. Also remove the redundant av_codec_is_decoder().
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/avcodec.c | 3 +++
libavcodec/decode.c | 3 ---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index e7e2c09222..64c1788c57 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -718,6 +718,9 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
{
av_frame_unref(frame);
+ if (!avcodec_is_open(avctx))
+ return AVERROR(EINVAL);
+
if (av_codec_is_decoder(avctx->codec))
return ff_decode_receive_frame(avctx, frame);
return ff_encode_receive_frame(avctx, frame);
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index c5a577f4f1..3a1c35a55f 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -817,9 +817,6 @@ int ff_decode_receive_frame(AVCodecContext *avctx, AVFrame *frame)
AVCodecInternal *avci = avctx->internal;
int ret;
- if (!avcodec_is_open(avctx) || !av_codec_is_decoder(avctx->codec))
- return AVERROR(EINVAL);
-
if (avci->buffer_frame->buf[0]) {
av_frame_move_ref(frame, avci->buffer_frame);
} else {
--
2.45.2
[-- Attachment #3: 0002-avcodec-codec_internal-Add-dedicated-is_decoder-flag.patch --]
[-- Type: text/x-patch, Size: 3501 bytes --]
From bc8357f6ab0bcbc53e21b619dde4e3471fa7885d Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 10 Mar 2025 16:40:39 +0100
Subject: [PATCH 2/3] avcodec/codec_internal: Add dedicated is_decoder flag to
FFCodec
Allows to simplify av_codec_is_decoder() and av_codec_is_encoder().
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/codec_internal.h | 13 ++++++++++++-
libavcodec/utils.c | 8 ++------
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
index b2df8e729a..2b9c7354a0 100644
--- a/libavcodec/codec_internal.h
+++ b/libavcodec/codec_internal.h
@@ -133,7 +133,12 @@ typedef struct FFCodec {
/**
* Internal codec capabilities FF_CODEC_CAP_*.
*/
- unsigned caps_internal:27;
+ unsigned caps_internal:26;
+
+ /**
+ * Is this a decoder?
+ */
+ unsigned is_decoder:1;
/**
* This field determines the video color ranges supported by an encoder.
@@ -309,21 +314,27 @@ int ff_default_get_supported_config(const struct AVCodecContext *avctx,
#endif
#define FF_CODEC_DECODE_CB(func) \
+ .is_decoder = 1, \
.cb_type = FF_CODEC_CB_TYPE_DECODE, \
.cb.decode = (func)
#define FF_CODEC_DECODE_SUB_CB(func) \
+ .is_decoder = 1, \
.cb_type = FF_CODEC_CB_TYPE_DECODE_SUB, \
.cb.decode_sub = (func)
#define FF_CODEC_RECEIVE_FRAME_CB(func) \
+ .is_decoder = 1, \
.cb_type = FF_CODEC_CB_TYPE_RECEIVE_FRAME, \
.cb.receive_frame = (func)
#define FF_CODEC_ENCODE_CB(func) \
+ .is_decoder = 0, \
.cb_type = FF_CODEC_CB_TYPE_ENCODE, \
.cb.encode = (func)
#define FF_CODEC_ENCODE_SUB_CB(func) \
+ .is_decoder = 0, \
.cb_type = FF_CODEC_CB_TYPE_ENCODE_SUB, \
.cb.encode_sub = (func)
#define FF_CODEC_RECEIVE_PACKET_CB(func) \
+ .is_decoder = 0, \
.cb_type = FF_CODEC_CB_TYPE_RECEIVE_PACKET, \
.cb.receive_packet = (func)
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 0aa5a6f55e..90867ed6b1 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -79,17 +79,13 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size)
int av_codec_is_encoder(const AVCodec *avcodec)
{
const FFCodec *const codec = ffcodec(avcodec);
- return codec && (codec->cb_type == FF_CODEC_CB_TYPE_ENCODE ||
- codec->cb_type == FF_CODEC_CB_TYPE_ENCODE_SUB ||
- codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_PACKET);
+ return codec && !codec->is_decoder;
}
int av_codec_is_decoder(const AVCodec *avcodec)
{
const FFCodec *const codec = ffcodec(avcodec);
- return codec && (codec->cb_type == FF_CODEC_CB_TYPE_DECODE ||
- codec->cb_type == FF_CODEC_CB_TYPE_DECODE_SUB ||
- codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_FRAME);
+ return codec && codec->is_decoder;
}
int ff_set_dimensions(AVCodecContext *s, int width, int height)
--
2.45.2
[-- Attachment #4: 0003-avcodec-codec_internal-Add-inlined-version-of-av_cod.patch --]
[-- Type: text/x-patch, Size: 7683 bytes --]
From 4da22ec6fc5e752b3e6871090920f29599fde53f Mon Sep 17 00:00:00 2001
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Date: Mon, 10 Mar 2025 17:00:36 +0100
Subject: [PATCH 3/3] avcodec/codec_internal: Add inlined version of
av_codec_is_(de|en)coder
These functions check whether the AVCodec* is NULL, but this
has already been checked at a lot of places in our codebase,
so that it boils down to checking the is_decoder flag.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
libavcodec/allcodecs.c | 8 ++++----
libavcodec/avcodec.c | 16 ++++++++--------
libavcodec/codec_internal.h | 30 +++++++++++++++++++++++++-----
libavcodec/options.c | 2 +-
libavcodec/pthread_slice.c | 2 +-
5 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 3be33f5cc4..34a94ae93d 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -1013,12 +1013,12 @@ static const AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{
- return find_codec(id, av_codec_is_encoder);
+ return find_codec(id, ff_codec_is_encoder);
}
const AVCodec *avcodec_find_decoder(enum AVCodecID id)
{
- return find_codec(id, av_codec_is_decoder);
+ return find_codec(id, ff_codec_is_decoder);
}
static const AVCodec *find_codec_by_name(const char *name, int (*x)(const AVCodec *))
@@ -1041,10 +1041,10 @@ static const AVCodec *find_codec_by_name(const char *name, int (*x)(const AVCode
const AVCodec *avcodec_find_encoder_by_name(const char *name)
{
- return find_codec_by_name(name, av_codec_is_encoder);
+ return find_codec_by_name(name, ff_codec_is_encoder);
}
const AVCodec *avcodec_find_decoder_by_name(const char *name)
{
- return find_codec_by_name(name, av_codec_is_decoder);
+ return find_codec_by_name(name, ff_codec_is_decoder);
}
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 64c1788c57..8263f7904e 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -190,7 +190,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
return AVERROR(EINVAL);
}
- avci = av_codec_is_decoder(codec) ?
+ avci = ff_codec_is_decoder(codec) ?
ff_decode_internal_alloc() :
ff_encode_internal_alloc();
if (!avci) {
@@ -270,7 +270,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && !avctx->ch_layout.nb_channels
&& !(codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)) {
av_log(avctx, AV_LOG_ERROR, "%s requires channel layout to be set\n",
- av_codec_is_decoder(codec) ? "Decoder" : "Encoder");
+ ff_codec_is_decoder(codec) ? "Decoder" : "Encoder");
ret = AVERROR(EINVAL);
goto free_and_end;
}
@@ -290,13 +290,13 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
if ((avctx->codec->capabilities & AV_CODEC_CAP_EXPERIMENTAL) &&
avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
- const char *codec_string = av_codec_is_encoder(codec) ? "encoder" : "decoder";
+ const char *codec_string = ff_codec_is_encoder(codec) ? "encoder" : "decoder";
const AVCodec *codec2;
av_log(avctx, AV_LOG_ERROR,
"The %s '%s' is experimental but experimental codecs are not enabled, "
"add '-strict %d' if you want to use it.\n",
codec_string, codec->name, FF_COMPLIANCE_EXPERIMENTAL);
- codec2 = av_codec_is_encoder(codec) ? avcodec_find_encoder(codec->id) : avcodec_find_decoder(codec->id);
+ codec2 = ff_codec_is_encoder(codec) ? avcodec_find_encoder(codec->id) : avcodec_find_decoder(codec->id);
if (!(codec2->capabilities & AV_CODEC_CAP_EXPERIMENTAL))
av_log(avctx, AV_LOG_ERROR, "Alternatively use the non experimental %s '%s'.\n",
codec_string, codec2->name);
@@ -310,7 +310,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
avctx->time_base.den = avctx->sample_rate;
}
- if (av_codec_is_encoder(avctx->codec))
+ if (ff_codec_is_encoder(avctx->codec))
ret = ff_encode_preinit(avctx);
else
ret = ff_decode_preinit(avctx);
@@ -345,7 +345,7 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
ret=0;
- if (av_codec_is_decoder(avctx->codec)) {
+ if (ff_codec_is_decoder(avctx->codec)) {
if (!avctx->bit_rate)
avctx->bit_rate = get_bit_rate(avctx);
@@ -718,10 +718,10 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
{
av_frame_unref(frame);
- if (!avcodec_is_open(avctx))
+ if (!avcodec_is_open(avctx) || !avctx->codec)
return AVERROR(EINVAL);
- if (av_codec_is_decoder(avctx->codec))
+ if (ff_codec_is_decoder(avctx->codec))
return ff_decode_receive_frame(avctx, frame);
return ff_encode_receive_frame(avctx, frame);
}
diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
index 2b9c7354a0..7fa3097aa9 100644
--- a/libavcodec/codec_internal.h
+++ b/libavcodec/codec_internal.h
@@ -281,6 +281,31 @@ typedef struct FFCodec {
int *out_num_configs);
} FFCodec;
+static av_always_inline const FFCodec *ffcodec(const AVCodec *codec)
+{
+ return (const FFCodec*)codec;
+}
+
+/**
+ * Internal version of av_codec_is_encoder(). Must not be called with
+ * a NULL AVCodec*.
+ */
+static inline int ff_codec_is_encoder(const AVCodec *avcodec)
+{
+ const FFCodec *const codec = ffcodec(avcodec);
+ return !codec->is_decoder;
+}
+
+/**
+ * Internal version of av_codec_is_decoder(). Must not be called with
+ * a NULL AVCodec*.
+ */
+static inline int ff_codec_is_decoder(const AVCodec *avcodec)
+{
+ const FFCodec *const codec = ffcodec(avcodec);
+ return codec->is_decoder;
+}
+
/**
* Default implementation for avcodec_get_supported_config(). Will return the
* relevant fields from AVCodec if present, or NULL otherwise.
@@ -366,9 +391,4 @@ int ff_default_get_supported_config(const struct AVCodecContext *avctx,
.p.field = (array) \
ENABLE_DEPRECATION_WARNINGS
-static av_always_inline const FFCodec *ffcodec(const AVCodec *codec)
-{
- return (const FFCodec*)codec;
-}
-
#endif /* AVCODEC_CODEC_INTERNAL_H */
diff --git a/libavcodec/options.c b/libavcodec/options.c
index f60c41bdc3..834beb5757 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -69,7 +69,7 @@ static const AVClass *codec_child_class_iterate(void **iter)
static AVClassCategory get_category(void *ptr)
{
AVCodecContext* avctx = ptr;
- if (avctx->codec && av_codec_is_decoder(avctx->codec))
+ if (avctx->codec && ff_codec_is_decoder(avctx->codec))
return AV_CLASS_CATEGORY_DECODER;
else
return AV_CLASS_CATEGORY_ENCODER;
diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
index ac455e48ed..f7b5679e0b 100644
--- a/libavcodec/pthread_slice.c
+++ b/libavcodec/pthread_slice.c
@@ -119,7 +119,7 @@ int ff_slice_thread_init(AVCodecContext *avctx)
void (*mainfunc)(void *);
// We cannot do this in the encoder init as the threads are created before
- if (av_codec_is_encoder(avctx->codec) &&
+ if (ff_codec_is_encoder(avctx->codec) &&
avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO &&
avctx->height > 2800)
thread_count = avctx->thread_count = 1;
--
2.45.2
[-- Attachment #5: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-03-10 16:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-10 16:25 [FFmpeg-devel] [PATCH 1/3] avcodec/decode: Move is_open check to, avcodec_receive_frame() Andreas Rheinhardt
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git