[FFmpeg-devel] [PATCH 16/17] swscale/graph: allow dynamically updating HDR metadata

Niklas Haas ffmpeg at haasn.xyz
Thu Dec 5 13:30:25 EET 2024


From: Niklas Haas <git at haasn.dev>

Without triggering a full graph reinit.
---
 libswscale/graph.c | 21 ++++++++++++++++++++-
 libswscale/graph.h | 12 +++++++++---
 libswscale/utils.h |  6 ++++++
 3 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/libswscale/graph.c b/libswscale/graph.c
index 5a2d7947fc..d60dcff326 100644
--- a/libswscale/graph.c
+++ b/libswscale/graph.c
@@ -475,6 +475,14 @@ static void free_lut3d(void *priv)
     sws_lut3d_free(&lut);
 }
 
+static void setup_lut3d(const SwsImg *out, const SwsImg *in, const SwsPass *pass)
+{
+    SwsLut3D *lut = pass->priv;
+
+    /* Update dynamic frame metadata from the original source frame */
+    sws_lut3d_update(lut, &pass->graph->src.color);
+}
+
 static void run_lut3d(const SwsImg *out_base, const SwsImg *in_base,
                       int y, int h, const SwsPass *pass)
 {
@@ -529,6 +537,7 @@ static int adapt_colors(SwsGraph *graph, SwsFormat src, SwsFormat dst,
         sws_lut3d_free(&lut);
         return AVERROR(ENOMEM);
     }
+    pass->setup = setup_lut3d;
     pass->free = free_lut3d;
 
     *output = pass;
@@ -678,16 +687,26 @@ static int opts_equal(const SwsContext *c1, const SwsContext *c2)
 int sws_graph_reinit(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src,
                      int field, SwsGraph **out_graph)
 {
-    const SwsGraph *graph = *out_graph;
+    SwsGraph *graph = *out_graph;
     if (graph && ff_fmt_equal(&graph->src, src) &&
                  ff_fmt_equal(&graph->dst, dst) &&
                  opts_equal(ctx, &graph->opts_copy))
+    {
+        sws_graph_update_metadata(graph, &src->color);
         return 0;
+    }
 
     sws_graph_free(out_graph);
     return sws_graph_create(ctx, dst, src, field, out_graph);
 }
 
+void sws_graph_update_metadata(SwsGraph *graph, const SwsColor *color)
+{
+    if (!color)
+        return;
+
+    ff_color_update_dynamic(&graph->src.color, color);
+}
 
 void sws_graph_run(SwsGraph *graph, uint8_t *const out_data[4],
                    const int out_linesize[4],
diff --git a/libswscale/graph.h b/libswscale/graph.h
index 989695043d..758060ca12 100644
--- a/libswscale/graph.h
+++ b/libswscale/graph.h
@@ -134,9 +134,15 @@ int sws_graph_create(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src
 void sws_graph_free(SwsGraph **graph);
 
 /**
- * Wrapper around sws_graph_create that does nothing if the format is
- * unchanged. Must be called after changing any of the fields in `ctx`, or else
- * they will have no effect.
+ * Update dynamic per-frame HDR metadata without requiring a full reinit.
+ */
+void sws_graph_update_metadata(SwsGraph *graph, const SwsColor *color);
+
+/**
+ * Wrapper around sws_graph_create() that reuses the existing graph if the
+ * format is compatible. This will also update dynamic per-frame metadata.
+ * Must be called after changing any of the fields in `ctx`, or else they will
+ * have no effect.
  */
 int sws_graph_reinit(SwsContext *ctx, const SwsFormat *dst, const SwsFormat *src,
                      int field, SwsGraph **graph);
diff --git a/libswscale/utils.h b/libswscale/utils.h
index a115c46cf6..37165d0650 100644
--- a/libswscale/utils.h
+++ b/libswscale/utils.h
@@ -54,6 +54,12 @@ typedef struct SwsColor {
     AVRational frame_avg;        /* per-frame/scene average luminance, or 0 */
 } SwsColor;
 
+static inline void ff_color_update_dynamic(SwsColor *dst, const SwsColor *src)
+{
+    dst->frame_peak = src->frame_peak;
+    dst->frame_avg  = src->frame_avg;
+}
+
 /* Subset of AVFrame parameters that uniquely determine pixel representation */
 typedef struct SwsFormat {
     int width, height;
-- 
2.47.0



More information about the ffmpeg-devel mailing list