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

Git pushed a commit to branch master
in repository ffmpeg.

commit d91855165000324592ac87e2050f868c2a3acabd
Author:     Niklas Haas <[email protected]>
AuthorDate: Sat Feb 21 14:32:44 2026 +0100
Commit:     Niklas Haas <[email protected]>
CommitDate: Mon Feb 23 19:39:17 2026 +0000

    swscale/graph: switch SwsPass.output to refstruct
    
    Allows multiple passes to share a single output buffer reference. We always
    allocate an output buffer so that subpasses can share the same output buffer
    reference while still allowing that reference to implicitly point to the
    final output image.
    
    Sponsored-by: Sovereign Tech Fund
    Signed-off-by: Niklas Haas <[email protected]>
---
 libswscale/graph.c | 40 +++++++++++++++++++++++++++-------------
 libswscale/graph.h |  2 +-
 2 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/libswscale/graph.c b/libswscale/graph.c
index 7a9985f56a..0829022bc4 100644
--- a/libswscale/graph.c
+++ b/libswscale/graph.c
@@ -26,6 +26,7 @@
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/refstruct.h"
 #include "libavutil/slicethread.h"
 
 #include "libswscale/swscale.h"
@@ -63,11 +64,11 @@ static int buffer_get_sizes(SwsPassBuffer *buffer, size_t 
sizes[4])
 
 static int pass_alloc_output(SwsPass *pass)
 {
-    if (!pass || pass->output.buf[0])
+    if (!pass || pass->output->buf[0])
         return 0;
 
     size_t sizes[4];
-    SwsPassBuffer *output = &pass->output;
+    SwsPassBuffer *output = pass->output;
     int ret = buffer_get_sizes(output, sizes);
     if (ret < 0)
         return ret;
@@ -88,6 +89,13 @@ static int pass_alloc_output(SwsPass *pass)
     return 0;
 }
 
+static void free_buffer(AVRefStructOpaque opaque, void *obj)
+{
+    SwsPassBuffer *buffer = obj;
+    for (int i = 0; i < FF_ARRAY_ELEMS(buffer->buf); i++)
+        av_buffer_unref(&buffer->buf[i]);
+}
+
 SwsPass *ff_sws_graph_add_pass(SwsGraph *graph, enum AVPixelFormat fmt,
                                int width, int height, SwsPass *input,
                                int align, void *priv, sws_filter_run_t run)
@@ -104,12 +112,13 @@ SwsPass *ff_sws_graph_add_pass(SwsGraph *graph, enum 
AVPixelFormat fmt,
     pass->width  = width;
     pass->height = height;
     pass->input  = input;
+    pass->output = av_refstruct_alloc_ext(sizeof(*pass->output), 0, NULL, 
free_buffer);
+    if (!pass->output)
+        goto fail;
 
     ret = pass_alloc_output(input);
-    if (ret < 0) {
-        av_free(pass);
-        return NULL;
-    }
+    if (ret < 0)
+        goto fail;
 
     if (!align) {
         pass->slice_h = pass->height;
@@ -121,14 +130,20 @@ SwsPass *ff_sws_graph_add_pass(SwsGraph *graph, enum 
AVPixelFormat fmt,
     }
 
     /* Align output buffer to include extra slice padding */
-    pass->output.img.fmt = fmt;
-    pass->output.width   = pass->width;
-    pass->output.height  = pass->slice_h * pass->num_slices;
+    pass->output->img.fmt = fmt;
+    pass->output->width   = pass->width;
+    pass->output->height  = pass->slice_h * pass->num_slices;
 
     ret = av_dynarray_add_nofree(&graph->passes, &graph->num_passes, pass);
     if (ret < 0)
-        av_freep(&pass);
+        goto fail;
+
     return pass;
+
+fail:
+    av_refstruct_unref(&pass->output);
+    av_free(pass);
+    return NULL;
 }
 
 /* Wrapper around ff_sws_graph_add_pass() that chains a pass "in-place" */
@@ -771,8 +786,7 @@ void ff_sws_graph_free(SwsGraph **pgraph)
         SwsPass *pass = graph->passes[i];
         if (pass->free)
             pass->free(pass->priv);
-        for (int n = 0; n < FF_ARRAY_ELEMS(pass->output.buf); n++)
-            av_buffer_unref(&pass->output.buf[n]);
+        av_refstruct_unref(&pass->output);
         av_free(pass);
     }
     av_free(graph->passes);
@@ -827,7 +841,7 @@ static SwsImg pass_output(const SwsPass *pass, const SwsImg 
*fallback)
     if (!pass)
         return *fallback;
 
-    SwsImg img = pass->output.img;
+    SwsImg img = pass->output->img;
     for (int i = 0; i < FF_ARRAY_ELEMS(img.data); i++) {
         if (!img.data[i]) {
             img.data[i]     = fallback->data[i];
diff --git a/libswscale/graph.h b/libswscale/graph.h
index f7a17aef59..b9ad2425bd 100644
--- a/libswscale/graph.h
+++ b/libswscale/graph.h
@@ -99,7 +99,7 @@ struct SwsPass {
     /**
      * Filter output buffer. Allocated on demand and freed automatically.
      */
-    SwsPassBuffer output;
+    SwsPassBuffer *output; /* refstruct */
 
     /**
      * Called once from the main thread before running the filter. Optional.

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

Reply via email to