Commit 950fe27d23 for ffmpeg
commit 950fe27d23b3998d4e66288d95359c5a65deeab8
Author: Kacper Michajłow <kasper93@gmail.com>
Date: Wed Sep 9 07:13:15 2026 +0200
avfilter/vf_scale: convert to the negotiated chroma location
Take the output location from the link instead of only from the
out_chroma_loc option, so the filter performs the conversion the graph
negotiated rather than just relabelling the frame. The option still wins
when set, and it now also constrains the outgoing link. Input without a
chroma location is tagged but not converted, since libswscale takes it as
sited like the output.
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
diff --git a/doc/filters.texi b/doc/filters.texi
index 0d20892f1f..520e0afc0c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -21866,9 +21866,12 @@ Set "MPEG" range (16-235 in case of 8-bit luma).
@item in_chroma_loc
@item out_chroma_loc
-Set in/output chroma sample location. If not specified, the chroma location
-tagged on the input frame is used, and untagged input is treated as
-center-sited. Possible values:
+Set in/output chroma sample location. If @option{in_chroma_loc} is not
+specified, the chroma location tagged on the input frame is used, and untagged
+input is assumed to be sited like the output, so it is tagged but not converted.
+If @option{out_chroma_loc} is not specified, the output is converted to the
+chroma location negotiated with the rest of the filtergraph, or keeps the input
+location if none was negotiated. Possible values:
@table @samp
@item auto, unknown
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 876fa773de..f925d08690 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -520,6 +520,16 @@ static int query_formats(const AVFilterContext *ctx,
if ((ret = ff_formats_ref(formats, &cfg_out[0]->color_ranges)) < 0)
return ret;
+ if ((ret = ff_formats_ref(ff_all_chroma_locations(),
+ &cfg_in[0]->chroma_locations)) < 0)
+ return ret;
+
+ formats = scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED
+ ? ff_make_formats_list_singleton(scale->out_chroma_loc)
+ : ff_all_chroma_locations();
+ if ((ret = ff_formats_ref(formats, &cfg_out[0]->chroma_locations)) < 0)
+ return ret;
+
if (scale->sws->alpha_blend) {
if ((ret = ff_formats_ref(ff_make_formats_list_singleton(AVALPHA_MODE_STRAIGHT),
&cfg_in[0]->alpha_modes)) < 0)
@@ -844,6 +854,8 @@ scale:
out->color_range = outlink->color_range;
out->colorspace = outlink->colorspace;
out->alpha_mode = outlink->alpha_mode;
+ if (outlink->chroma_location != AVCHROMA_LOC_UNSPECIFIED)
+ out->chroma_location = outlink->chroma_location;
if (scale->out_chroma_loc != AVCHROMA_LOC_UNSPECIFIED)
out->chroma_location = scale->out_chroma_loc;
if (scale->out_primaries != -1)