diff mbox series

[FFmpeg-devel,v2,2/2] avfilter/vf_colorspace: Use colorspace negotiation API

Message ID 20240329154746.439232-3-nicolas.gaullier@cji.paris
State New
Headers show
Series avfilter/vf_colorspace: Use colorspace negotiation API | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Nicolas Gaullier March 29, 2024, 3:47 p.m. UTC
Fixes a regression due to the fact that the colorspace filter does
not use the new API introduced by 8c7934f73ab6c568acaa.
The scale filter uses it since 45e09a30419cc2a7251e, and the setparams
filter since 3bf80df3ccd32aed23f0.

Example 1 - color_range specified and chained with scale filter:
ffmpeg -f lavfi -i testsrc -vf setparams=color_primaries=bt470bg:
color_trc=smpte170m:colorspace=bt470bg,colorspace=bt709:range=tv,scale
,showinfo -f null -frames 1 -

Before:
  color_range:unknown color_space:bt470bg ...
After:
  color_range:tv color_space:bt709 ...

Example 2 - color_range pass-through:
ffmpeg -f lavfi -i testsrc -vf "setparams=color_primaries=bt470bg:
color_trc=smpte170m:colorspace=bt470bg:range=unknown,
setparams=range=pc:enable='between(n,1,2)',
setparams=range=tv:enable='between(n,2,3)',
colorspace=bt709,showinfo"
-f null -frames 3 - 2>&1|awk "/color_/ {print \$4}"

Before:
color_range:tv
color_range:tv
color_range:tv
After:
color_range:unknown
color_range:pc
color_range:tv

Signed-off-by: Nicolas Gaullier <nicolas.gaullier@cji.paris>
---
 libavfilter/vf_colorspace.c | 64 +++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 27 deletions(-)
diff mbox series

Patch

diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c
index f367ce17c6..a006fd5aac 100644
--- a/libavfilter/vf_colorspace.c
+++ b/libavfilter/vf_colorspace.c
@@ -432,8 +432,7 @@  static int create_filtergraph(AVFilterContext *ctx,
     if (out->color_trc       != s->out_trc) s->out_txchr     = NULL;
     if (in->colorspace       != s->in_csp ||
         in->color_range      != s->in_rng)  s->in_lumacoef   = NULL;
-    if (out->colorspace      != s->out_csp ||
-        out->color_range     != s->out_rng) s->out_lumacoef  = NULL;
+    if (out->color_range     != s->out_rng) s->rgb2yuv       = NULL;
 
     if (!s->out_primaries || !s->in_primaries) {
         s->in_prm = in->color_primaries;
@@ -562,26 +561,8 @@  static int create_filtergraph(AVFilterContext *ctx,
         redo_yuv2rgb = 1;
     }
 
-    if (!s->out_lumacoef) {
-        s->out_csp = out->colorspace;
+    if (!s->rgb2yuv) {
         s->out_rng = out->color_range;
-        s->out_lumacoef = av_csp_luma_coeffs_from_avcsp(s->out_csp);
-        if (!s->out_lumacoef) {
-            if (s->out_csp == AVCOL_SPC_UNSPECIFIED) {
-                if (s->user_all == CS_UNSPECIFIED) {
-                    av_log(ctx, AV_LOG_ERROR,
-                           "Please specify output colorspace\n");
-                } else {
-                    av_log(ctx, AV_LOG_ERROR,
-                           "Unsupported output color property %d\n", s->user_all);
-                }
-            } else {
-                av_log(ctx, AV_LOG_ERROR,
-                       "Unsupported output colorspace %d (%s)\n", s->out_csp,
-                       av_color_space_name(s->out_csp));
-            }
-            return AVERROR(EINVAL);
-        }
         redo_rgb2yuv = 1;
     }
 
@@ -686,6 +667,26 @@  static av_cold int init(AVFilterContext *ctx)
 {
     ColorSpaceContext *s = ctx->priv;
 
+    s->out_csp  = s->user_csp == AVCOL_SPC_UNSPECIFIED ?
+                  default_csp[FFMIN(s->user_all, CS_NB)] : s->user_csp;
+    s->out_lumacoef = av_csp_luma_coeffs_from_avcsp(s->out_csp);
+    if (!s->out_lumacoef) {
+        if (s->out_csp == AVCOL_SPC_UNSPECIFIED) {
+            if (s->user_all == CS_UNSPECIFIED) {
+                av_log(ctx, AV_LOG_ERROR,
+                       "Please specify output colorspace\n");
+            } else {
+                av_log(ctx, AV_LOG_ERROR,
+                       "Unsupported output color property %d\n", s->user_all);
+            }
+        } else {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Unsupported output colorspace %d (%s)\n", s->out_csp,
+                   av_color_space_name(s->out_csp));
+        }
+        return AVERROR(EINVAL);
+    }
+
     ff_colorspacedsp_init(&s->dsp);
 
     return 0;
@@ -734,6 +735,10 @@  static int filter_frame(AVFilterLink *link, AVFrame *in)
         return res;
     }
 
+    out->colorspace = outlink->colorspace;
+    if (s->user_rng == AVCOL_RANGE_UNSPECIFIED)
+        outlink->color_range = link->src->inputs[0]->color_range;
+    out->color_range = outlink->color_range;
     out->color_primaries = s->user_prm == AVCOL_PRI_UNSPECIFIED ?
                            default_prm[FFMIN(s->user_all, CS_NB)] : s->user_prm;
     if (s->user_trc == AVCOL_TRC_UNSPECIFIED) {
@@ -745,10 +750,6 @@  static int filter_frame(AVFilterLink *link, AVFrame *in)
     } else {
         out->color_trc   = s->user_trc;
     }
-    out->colorspace      = s->user_csp == AVCOL_SPC_UNSPECIFIED ?
-                           default_csp[FFMIN(s->user_all, CS_NB)] : s->user_csp;
-    out->color_range     = s->user_rng == AVCOL_RANGE_UNSPECIFIED ?
-                           in->color_range : s->user_rng;
     if (rgb_sz != s->rgb_sz) {
         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(out->format);
         int uvw = in->width >> desc->log2_chroma_w;
@@ -838,10 +839,19 @@  static int query_formats(AVFilterContext *ctx)
         AV_PIX_FMT_YUVJ420P,  AV_PIX_FMT_YUVJ422P,  AV_PIX_FMT_YUVJ444P,
         AV_PIX_FMT_NONE
     };
-    int res;
+    int res, ret;
     ColorSpaceContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
     AVFilterFormats *formats = ff_make_format_list(pix_fmts);
 
+    if (ret = ff_formats_ref(ff_make_formats_list_singleton(s->out_csp),
+                             &outlink->incfg.color_spaces) < 0)
+        return ret;
+    if (s->user_rng != AVCOL_RANGE_UNSPECIFIED
+        && (ret = ff_formats_ref(ff_make_formats_list_singleton(s->user_rng),
+                             &outlink->incfg.color_ranges) < 0))
+        return ret;
+
     if (!formats)
         return AVERROR(ENOMEM);
     if (s->user_format == AV_PIX_FMT_NONE)
@@ -854,7 +864,7 @@  static int query_formats(AVFilterContext *ctx)
     if (res < 0)
         return res;
 
-    return ff_formats_ref(formats, &ctx->outputs[0]->incfg.formats);
+    return ff_formats_ref(formats, &outlink->incfg.formats);
 }
 
 static int config_props(AVFilterLink *outlink)