diff mbox series

[FFmpeg-devel,5/5] lavfi/avfilter: export AVFilter initialization state

Message ID 20240928142830.961-5-anton@khirnov.net
State New
Headers show
Series [FFmpeg-devel,1/5] lavu/class: improve AVClass doxy | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov Sept. 28, 2024, 2:28 p.m. UTC
This will allow the AVOption code to detect setting non-runtime options
after the filter has been initialized.
---
 libavfilter/avfilter.c          | 8 +++++---
 libavfilter/avfilter_internal.h | 5 ++---
 libavfilter/graphparser.c       | 3 ++-
 3 files changed, 9 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 8a2a9e0593..dc06ebab4d 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -159,7 +159,8 @@  int avfilter_link(AVFilterContext *src, unsigned srcpad,
         src->outputs[srcpad]      || dst->inputs[dstpad])
         return AVERROR(EINVAL);
 
-    if (!fffilterctx(src)->initialized || !fffilterctx(dst)->initialized) {
+    if (!(fffilterctx(src)->state_flags & AV_CLASS_STATE_INITIALIZED) ||
+        !(fffilterctx(dst)->state_flags & AV_CLASS_STATE_INITIALIZED)) {
         av_log(src, AV_LOG_ERROR, "Filters must be initialized before linking.\n");
         return AVERROR(EINVAL);
     }
@@ -676,6 +677,7 @@  static const AVClass avfilter_class = {
     .child_next = filter_child_next,
     .child_class_iterate = filter_child_class_iterate,
     .option           = avfilter_options,
+    .state_flags_offset = offsetof(FFFilterContext, state_flags),
 };
 
 static int default_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg,
@@ -909,7 +911,7 @@  int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
     FFFilterContext *ctxi = fffilterctx(ctx);
     int ret = 0;
 
-    if (ctxi->initialized) {
+    if (ctxi->state_flags & AV_CLASS_STATE_INITIALIZED) {
         av_log(ctx, AV_LOG_ERROR, "Filter already initialized\n");
         return AVERROR(EINVAL);
     }
@@ -940,7 +942,7 @@  int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
             return ret;
     }
 
-    ctxi->initialized = 1;
+    ctxi->state_flags |= AV_CLASS_STATE_INITIALIZED;
 
     return 0;
 }
diff --git a/libavfilter/avfilter_internal.h b/libavfilter/avfilter_internal.h
index ec3933b1d1..9ba890a70c 100644
--- a/libavfilter/avfilter_internal.h
+++ b/libavfilter/avfilter_internal.h
@@ -100,9 +100,8 @@  typedef struct FFFilterContext {
 
     avfilter_execute_func *execute;
 
-    // 1 when avfilter_init_*() was successfully called on this filter
-    // 0 otherwise
-    int initialized;
+    // AV_CLASS_STATE_FLAG_*
+    unsigned state_flags;
 } FFFilterContext;
 
 static inline FFFilterContext *fffilterctx(AVFilterContext *ctx)
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index 912804ecd6..a23e26d2e3 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -627,7 +627,8 @@  int avfilter_graph_segment_init(AVFilterGraphSegment *seg, int flags)
 
             if (p->filter_name)
                 return fail_creation_pending(seg, p->filter_name, __func__);
-            if (!p->filter || fffilterctx(p->filter)->initialized)
+            if (!p->filter ||
+                (fffilterctx(p->filter)->state_flags & AV_CLASS_STATE_INITIALIZED))
                 continue;
 
             ret = avfilter_init_dict(p->filter, NULL);