[FFmpeg-devel] [PATCH 15/17] swscale/graph: add color mapping pass
Niklas Haas
ffmpeg at haasn.xyz
Thu Dec 5 13:30:24 EET 2024
From: Niklas Haas <git at haasn.dev>
This leverages the previously introduced color management subsystem in order
to adapt between transfer functions and color spaces, as well as for HDR tone
mapping.
---
libswscale/graph.c | 81 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 79 insertions(+), 2 deletions(-)
diff --git a/libswscale/graph.c b/libswscale/graph.c
index 34621c784b..5a2d7947fc 100644
--- a/libswscale/graph.c
+++ b/libswscale/graph.c
@@ -30,6 +30,8 @@
#include "libswscale/swscale.h"
#include "libswscale/utils.h"
+#include "cms.h"
+#include "lut3d.h"
#include "swscale_internal.h"
#include "graph.h"
@@ -463,6 +465,75 @@ static int add_legacy_sws_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
return 0;
}
+/**************************
+ * Gamut and tone mapping *
+ **************************/
+
+static void free_lut3d(void *priv)
+{
+ SwsLut3D *lut = priv;
+ sws_lut3d_free(&lut);
+}
+
+static void run_lut3d(const SwsImg *out_base, const SwsImg *in_base,
+ int y, int h, const SwsPass *pass)
+{
+ SwsLut3D *lut = pass->priv;
+ const SwsImg in = shift_img(in_base, y);
+ const SwsImg out = shift_img(out_base, y);
+
+ sws_lut3d_apply(lut, in.data[0], in.linesize[0], out.data[0],
+ out.linesize[0], pass->width, h);
+}
+
+static int adapt_colors(SwsGraph *graph, SwsFormat src, SwsFormat dst,
+ SwsPass *input, SwsPass **output)
+{
+ enum AVPixelFormat fmt_in, fmt_out;
+ SwsLut3D *lut;
+ SwsPass *pass;
+ int ret;
+
+ SwsColorMap map = {
+ .intent = graph->ctx->intent,
+ .src = src.color,
+ .dst = dst.color,
+ };
+
+ if (sws_color_map_noop(&map))
+ return 0;
+
+ lut = sws_lut3d_alloc();
+ if (!lut)
+ return AVERROR(ENOMEM);
+
+ fmt_in = sws_lut3d_pick_pixfmt(src, 0);
+ fmt_out = sws_lut3d_pick_pixfmt(dst, 1);
+ if (fmt_in != src.format) {
+ SwsFormat tmp = src;
+ tmp.format = fmt_in;
+ ret = add_legacy_sws_pass(graph, src, tmp, input, &input);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = sws_lut3d_generate(lut, fmt_in, fmt_out, &map);
+ if (ret < 0) {
+ sws_lut3d_free(&lut);
+ return ret;
+ }
+
+ pass = pass_add(graph, lut, fmt_out, src.width, src.height,
+ input, 1, run_lut3d);
+ if (!pass) {
+ sws_lut3d_free(&lut);
+ return AVERROR(ENOMEM);
+ }
+ pass->free = free_lut3d;
+
+ *output = pass;
+ return 0;
+}
/***************************************
* Main filter graph construction code *
@@ -470,11 +541,17 @@ static int add_legacy_sws_pass(SwsGraph *graph, SwsFormat src, SwsFormat dst,
static int init_passes(SwsGraph *graph)
{
- const SwsFormat src = graph->src;
- const SwsFormat dst = graph->dst;
+ SwsFormat src = graph->src;
+ SwsFormat dst = graph->dst;
SwsPass *pass = NULL; /* read from main input image */
int ret;
+ ret = adapt_colors(graph, src, dst, pass, &pass);
+ if (ret < 0)
+ return ret;
+ src.format = pass ? pass->format : src.format;
+ src.color = dst.color;
+
if (!ff_fmt_equal(&src, &dst)) {
ret = add_legacy_sws_pass(graph, src, dst, pass, &pass);
if (ret < 0)
--
2.47.0
More information about the ffmpeg-devel
mailing list