avfilter/vf_libplacebo: add chroma_location option

Add chroma_location option so that, in the subsampled-to-subsampled case, the destination's chroma siting can be changed from the source's without having to use other filters. Useful, for example, when converting BT.2020 to BT.709, where the former customarily uses "top left" and the latter "left."

Update documentation.

Closes: #21185
This commit is contained in:
GeoffreyAA
2026-01-23 11:32:11 +00:00
committed by Niklas Haas
parent ec8e0b3592
commit ff63d4865b
2 changed files with 15 additions and 0 deletions
+1
View File
@@ -16689,6 +16689,7 @@ exist.
@item color_primaries
@item color_trc
@item range
@item chroma_location
Configure the colorspace that output frames will be delivered in. The default
value of @code{auto} outputs frames in the same format as the input frames,
leading to no change. For any other value, conversion will be performed.
+14
View File
@@ -219,6 +219,7 @@ typedef struct LibplaceboContext {
int color_range;
int color_primaries;
int color_trc;
int chroma_location;
int rotation;
int alpha_mode;
AVDictionary *extra_opts;
@@ -1039,6 +1040,8 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
out->color_trc = s->color_trc;
if (s->color_primaries >= 0)
out->color_primaries = s->color_primaries;
if (s->chroma_location >= 0)
out->chroma_location = s->chroma_location;
/* Strip side data if no longer relevant */
if (out->width != ref->width || out->height != ref->height)
@@ -1695,6 +1698,17 @@ static const AVOption libplacebo_options[] = {
{"arib-std-b67", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_ARIB_STD_B67}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
{"vlog", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCOL_TRC_V_LOG}, INT_MIN, INT_MAX, STATIC, .unit = "color_trc"},
{"chroma_location", "select chroma location", OFFSET(chroma_location), AV_OPT_TYPE_INT, {.i64=-1}, -1, AVCHROMA_LOC_NB-1, DYNAMIC, .unit = "chroma_location"},
{"auto", "keep the same chroma location", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, STATIC, .unit = "chroma_location"},
{"unspecified", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, STATIC, .unit = "chroma_location"},
{"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_UNSPECIFIED}, 0, 0, STATIC, .unit = "chroma_location"},
{"left", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_LEFT}, 0, 0, STATIC, .unit = "chroma_location"},
{"center", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_CENTER}, 0, 0, STATIC, .unit = "chroma_location"},
{"topleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOPLEFT}, 0, 0, STATIC, .unit = "chroma_location"},
{"top", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_TOP}, 0, 0, STATIC, .unit = "chroma_location"},
{"bottomleft", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOMLEFT}, 0, 0, STATIC, .unit = "chroma_location"},
{"bottom", NULL, 0, AV_OPT_TYPE_CONST, {.i64=AVCHROMA_LOC_BOTTOM}, 0, 0, STATIC, .unit = "chroma_location"},
{"rotate", "rotate the input clockwise", OFFSET(rotation), AV_OPT_TYPE_INT, {.i64=PL_ROTATION_0}, PL_ROTATION_0, PL_ROTATION_360, DYNAMIC, .unit = "rotation"},
{"0", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_0}, .flags = STATIC, .unit = "rotation"},
{"90", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PL_ROTATION_90}, .flags = STATIC, .unit = "rotation"},