[FFmpeg-devel] [PATCH 06/10] avfilter: Avoid allocation of AVFilterGraphInternal

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Wed Aug 11 04:17:49 EEST 2021


This can be achieved by allocating it together with AVFilterGraph,
with the public AVFilterGraph as first element in the new structure.
Given that said structure is now more than just the internal, it has
been renamed to FFFilterGraph.
Accessing it is not type-safe, so this unsafety has been confined to
a single function.

This breaks ABI due to the removal of the removal of the
AVFilterGraph.internal pointer.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
This one is fairly easy due to the internal not being used much;
I also followed Nicolas suggestion to factor the unsafe code out into
a dedicated function.

 libavfilter/avfilter.c      |  6 +++---
 libavfilter/avfilter.h      |  7 -------
 libavfilter/avfiltergraph.c | 21 +++++++--------------
 libavfilter/internal.h      | 10 ++++++++--
 libavfilter/pthread.c       | 20 +++++++++++---------
 5 files changed, 29 insertions(+), 35 deletions(-)

diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index c04aefcaa8..7e48ff14c5 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -167,7 +167,7 @@ int avfilter_link(AVFilterContext *src, unsigned srcpad,
     link->type    = src->output_pads[srcpad].type;
     av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
     link->format  = -1;
-    ff_framequeue_init(&link->fifo, &src->graph->internal->frame_queues);
+    ff_framequeue_init(&link->fifo, &filtergraph(src->graph)->frame_queues);
 
     return 0;
 }
@@ -868,9 +868,9 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options)
 
     if (ctx->filter->flags & AVFILTER_FLAG_SLICE_THREADS &&
         ctx->thread_type & ctx->graph->thread_type & AVFILTER_THREAD_SLICE &&
-        ctx->graph->internal->thread_execute) {
+        filtergraph(ctx->graph)->thread_execute) {
         ctx->thread_type       = AVFILTER_THREAD_SLICE;
-        ctx->internal->execute = ctx->graph->internal->thread_execute;
+        ctx->internal->execute = filtergraph(ctx->graph)->thread_execute;
     } else {
         ctx->thread_type = 0;
     }
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 360f63bc45..4436eb7d2d 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -758,8 +758,6 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
  */
 const AVClass *avfilter_get_class(void);
 
-typedef struct AVFilterGraphInternal AVFilterGraphInternal;
-
 /**
  * A function pointer passed to the @ref AVFilterGraph.execute callback to be
  * executed multiple times, possibly in parallel.
@@ -817,11 +815,6 @@ typedef struct AVFilterGraph {
      */
     int nb_threads;
 
-    /**
-     * Opaque object for libavfilter internal use.
-     */
-    AVFilterGraphInternal *internal;
-
     /**
      * Opaque user data. May be set by the caller to an arbitrary value, e.g. to
      * be used from callbacks like @ref AVFilterGraph.execute.
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index f6bbcd8578..f8a2426c46 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -82,21 +82,15 @@ int ff_graph_thread_init(AVFilterGraph *graph)
 
 AVFilterGraph *avfilter_graph_alloc(void)
 {
-    AVFilterGraph *ret = av_mallocz(sizeof(*ret));
+    FFFilterGraph *const ret = av_mallocz(sizeof(*ret));
     if (!ret)
         return NULL;
 
-    ret->internal = av_mallocz(sizeof(*ret->internal));
-    if (!ret->internal) {
-        av_freep(&ret);
-        return NULL;
-    }
+    ret->pub.av_class = &filtergraph_class;
+    av_opt_set_defaults(&ret->pub);
+    ff_framequeue_global_init(&ret->frame_queues);
 
-    ret->av_class = &filtergraph_class;
-    av_opt_set_defaults(ret);
-    ff_framequeue_global_init(&ret->internal->frame_queues);
-
-    return ret;
+    return &ret->pub;
 }
 
 void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
@@ -132,7 +126,6 @@ void avfilter_graph_free(AVFilterGraph **graph)
     av_freep(&(*graph)->scale_sws_opts);
     av_freep(&(*graph)->aresample_swr_opts);
     av_freep(&(*graph)->filters);
-    av_freep(&(*graph)->internal);
     av_freep(graph);
 }
 
@@ -170,9 +163,9 @@ AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
 {
     AVFilterContext **filters, *s;
 
-    if (graph->thread_type && !graph->internal->thread_execute) {
+    if (graph->thread_type && !filtergraph(graph)->thread_execute) {
         if (graph->execute) {
-            graph->internal->thread_execute = graph->execute;
+            filtergraph(graph)->thread_execute = graph->execute;
         } else {
             int ret = ff_graph_thread_init(graph);
             if (ret < 0) {
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 6c908690b4..2d1dab5788 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -122,11 +122,17 @@ struct AVFilterPad {
     int needs_writable;
 };
 
-struct AVFilterGraphInternal {
+typedef struct FFFilterGraph {
+    AVFilterGraph pub;
     void *thread;
     avfilter_execute_func *thread_execute;
     FFFrameQueueGlobal frame_queues;
-};
+} FFFilterGraph;
+
+static av_always_inline FFFilterGraph *filtergraph(AVFilterGraph *graph)
+{
+    return (FFFilterGraph*)graph;
+}
 
 struct AVFilterInternal {
     avfilter_execute_func *execute;
diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c
index 34fc699505..0b8e98f60e 100644
--- a/libavfilter/pthread.c
+++ b/libavfilter/pthread.c
@@ -59,7 +59,7 @@ static void slice_thread_uninit(ThreadContext *c)
 static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func,
                           void *arg, int *ret, int nb_jobs)
 {
-    ThreadContext *c = ctx->graph->internal->thread;
+    ThreadContext *const c = filtergraph(ctx->graph)->thread;
 
     if (nb_jobs <= 0)
         return 0;
@@ -82,6 +82,7 @@ static int thread_init_internal(ThreadContext *c, int nb_threads)
 
 int ff_graph_thread_init(AVFilterGraph *graph)
 {
+    FFFilterGraph *const internal = filtergraph(graph);
     int ret;
 
     if (graph->nb_threads == 1) {
@@ -89,27 +90,28 @@ int ff_graph_thread_init(AVFilterGraph *graph)
         return 0;
     }
 
-    graph->internal->thread = av_mallocz(sizeof(ThreadContext));
-    if (!graph->internal->thread)
+    internal->thread = av_mallocz(sizeof(ThreadContext));
+    if (!internal->thread)
         return AVERROR(ENOMEM);
 
-    ret = thread_init_internal(graph->internal->thread, graph->nb_threads);
+    ret = thread_init_internal(internal->thread, graph->nb_threads);
     if (ret <= 1) {
-        av_freep(&graph->internal->thread);
+        av_freep(&internal->thread);
         graph->thread_type = 0;
         graph->nb_threads  = 1;
         return (ret < 0) ? ret : 0;
     }
     graph->nb_threads = ret;
 
-    graph->internal->thread_execute = thread_execute;
+    internal->thread_execute = thread_execute;
 
     return 0;
 }
 
 void ff_graph_thread_free(AVFilterGraph *graph)
 {
-    if (graph->internal->thread)
-        slice_thread_uninit(graph->internal->thread);
-    av_freep(&graph->internal->thread);
+    FFFilterGraph *const internal = filtergraph(graph);
+    if (internal->thread)
+        slice_thread_uninit(internal->thread);
+    av_freep(&internal->thread);
 }
-- 
2.30.2



More information about the ffmpeg-devel mailing list