Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PR] avfilter/vf_opencolorio: Updating query_formats to specify different input and output pix_fmts. (PR #21799)
@ 2026-02-19 16:30 richardssam via ffmpeg-devel
  0 siblings, 0 replies; only message in thread
From: richardssam via ffmpeg-devel @ 2026-02-19 16:30 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: richardssam

PR #21799 opened by richardssam
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21799
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21799.patch

The format parameter within the filter was specifying the output filter, but doing it too late, so some filters were getting a different value for the output pix_fmt (e.g. zscale).

Separately there are enough issues with outputting half-floats (since negative numbers get truncated) that we are better off saying that we don't support outputs of half floats.
However, I do still want to support half floats as inputs without forcing them to use a format string (so in that case, the output is forced to be AV_PIX_FMT_GBRAPF32 if nothing is defined.
So switched to using FILTER_QUERY_FUNC2 so that I could specify separate input and output pixel_formats.

Signed-off-by: Sam.Richards@taurich.org <Sam.Richards@taurich.org>


>From f4ffc851b0cd0fb6f9ffc3cbcf0ac2a7c3679076 Mon Sep 17 00:00:00 2001
From: "Sam.Richards@taurich.org" <Sam.Richards@taurich.org>
Date: Thu, 19 Feb 2026 16:24:36 +0000
Subject: [PATCH] avfilter/vf_opencolorio: Updating query_formats to
 FILTER_QUERY_FUNC2 The format parameter within the filter was specifying the
 output filter, but doing it too late, so some filters were getting a
 different value for the output pix_fmt (e.g. zscale).

Separately there are enough issues with outputting half-floats (since negative numbers get truncated) that we are better off saying that we dont support outputs of half floats.
However, I do still want to support half floats as inputs without forcing them to use a format string (so in that case, the output is forced to be AV_PIX_FMT_GBRAPF32 if nothing is defined.

Signed-off-by: Sam.Richards@taurich.org <Sam.Richards@taurich.org>
---
 libavfilter/vf_opencolorio.c | 100 ++++++++++++++++++++++++++++-------
 1 file changed, 80 insertions(+), 20 deletions(-)

diff --git a/libavfilter/vf_opencolorio.c b/libavfilter/vf_opencolorio.c
index d34922deca..3e89355d35 100644
--- a/libavfilter/vf_opencolorio.c
+++ b/libavfilter/vf_opencolorio.c
@@ -62,21 +62,62 @@ static int ocio_filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_
     return ocio_apply(ctx, s->ocio, in, out, slice_start, slice_h);
 }
 
-static int query_formats(AVFilterContext *ctx) {
-    static const enum AVPixelFormat pix_fmts[] = {
-      // 8-bit
-      AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB24,
-      // 16-bit
-      AV_PIX_FMT_RGBA64, AV_PIX_FMT_RGB48,
-      // 10-bit
-      AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
-      // 12-bit
-      AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
-      // Half-float and float
-      AV_PIX_FMT_GBRPF16, AV_PIX_FMT_GBRAPF16,
-      // Float
-      AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32, AV_PIX_FMT_NONE};
-    return ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+// All pixel formats supported by this filter for inputs.
+static const enum AVPixelFormat supported_pix_fmts[] = {
+    // 8-bit
+    AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB24,
+    // 16-bit
+    AV_PIX_FMT_RGBA64, AV_PIX_FMT_RGB48,
+    // 10-bit
+    AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
+    // 12-bit
+    AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
+    // Half-float (input only by default; swscale clips negatives on output)
+    AV_PIX_FMT_GBRPF16, AV_PIX_FMT_GBRAPF16,
+    // Float
+    AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32,
+    AV_PIX_FMT_NONE
+};
+
+// Default output formats (excludes half-float to avoid swscale negative clipping)
+static const enum AVPixelFormat output_pix_fmts[] = {
+    // 8-bit
+    AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB24,
+    // 16-bit
+    AV_PIX_FMT_RGBA64, AV_PIX_FMT_RGB48,
+    // 10-bit
+    AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRAP10,
+    // 12-bit
+    AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRAP12,
+    // Float
+    AV_PIX_FMT_GBRPF32, AV_PIX_FMT_GBRAPF32,
+    AV_PIX_FMT_NONE
+};
+
+static int query_formats(const AVFilterContext *ctx,
+                         AVFilterFormatsConfig **cfg_in,
+                         AVFilterFormatsConfig **cfg_out)
+{
+    const OCIOContext *s = ctx->priv;
+    int ret;
+
+    // Input accepts all supported formats including half-float
+    ret = ff_formats_ref(ff_make_pixel_format_list(supported_pix_fmts),
+                         &cfg_in[0]->formats);
+    if (ret < 0)
+        return ret;
+
+    // Output: if user specified a format, constrain to just that format
+    if (s->output_format != AV_PIX_FMT_NONE) {
+        const enum AVPixelFormat user_fmts[] = { s->output_format, AV_PIX_FMT_NONE };
+        ret = ff_formats_ref(ff_make_pixel_format_list(user_fmts),
+                             &cfg_out[0]->formats);
+    } else {
+        // Default output excludes half-float formats
+        ret = ff_formats_ref(ff_make_pixel_format_list(output_pix_fmts),
+                             &cfg_out[0]->formats);
+    }
+    return ret;
 }
 
 static int config_props(AVFilterLink *inlink)
@@ -95,8 +136,8 @@ static int config_props(AVFilterLink *inlink)
     if (s->output_format == AV_PIX_FMT_NONE) {
         // Need to set the output format now, if not known.
         if (is_half) {
-            // If its half-float, we output float, due to a bug in ffmpeg with
-            // half-float frames
+            // If the user hasn't specified an output format, and the input is half-float, we output float to be safe.
+            // swscale clips negative values to 0, which can be problematic since it can occur with OCIO transforms.
             s->output_format = AV_PIX_FMT_GBRAPF32;
         } else {
             // If output format not set, use same as input
@@ -126,10 +167,29 @@ static int config_props(AVFilterLink *inlink)
 static av_cold int init(AVFilterContext *ctx)
 {
     OCIOContext *s = ctx->priv;
-    if (s->out_format_string != NULL)
+    if (s->out_format_string != NULL) {
         s->output_format = av_get_pix_fmt(s->out_format_string);
-    else
+        if (s->output_format == AV_PIX_FMT_NONE) {
+            av_log(ctx, AV_LOG_ERROR, "Unknown pixel format: '%s'\n",
+                   s->out_format_string);
+            return AVERROR(EINVAL);
+        }
+        // Verify the format is a supported output format
+        int valid = 0;
+        for (int i = 0; output_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+            if (s->output_format == output_pix_fmts[i]) {
+                valid = 1;
+                break;
+            }
+        }
+        if (!valid) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Unsupported output format: '%s'\n", s->out_format_string);
+            return AVERROR(EINVAL);
+        }
+    } else {
         s->output_format = AV_PIX_FMT_NONE; // Default to same as input format (see later).
+    }
 
     if (s->filetransform && strlen(s->filetransform) > 0) {
         s->ocio = ocio_create_file_transform_processor(
@@ -286,4 +346,4 @@ const FFFilter ff_vf_ocio = {
     .uninit = uninit,
     FILTER_INPUTS(inputs),
     FILTER_OUTPUTS(outputs),
-    FILTER_QUERY_FUNC(query_formats)};
+    FILTER_QUERY_FUNC2(query_formats)};
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-02-19 16:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-19 16:30 [FFmpeg-devel] [PR] avfilter/vf_opencolorio: Updating query_formats to specify different input and output pix_fmts. (PR #21799) richardssam via ffmpeg-devel

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git