... | ... |
@@ -14483,6 +14483,34 @@ Possible value are: |
14483 | 14483 |
@item 2020_ncl |
14484 | 14484 |
@item 2020_cl |
14485 | 14485 |
@end table |
14486 |
+ |
|
14487 |
+@item chromal, c |
|
14488 |
+Set the output chroma location. |
|
14489 |
+ |
|
14490 |
+Possible values are: |
|
14491 |
+@table @var |
|
14492 |
+@item input |
|
14493 |
+@item left |
|
14494 |
+@item center |
|
14495 |
+@item topleft |
|
14496 |
+@item top |
|
14497 |
+@item bottomleft |
|
14498 |
+@item bottom |
|
14499 |
+@end table |
|
14500 |
+ |
|
14501 |
+@item chromalin, cin |
|
14502 |
+Set the input chroma location. |
|
14503 |
+ |
|
14504 |
+Possible values are: |
|
14505 |
+@table @var |
|
14506 |
+@item input |
|
14507 |
+@item left |
|
14508 |
+@item center |
|
14509 |
+@item topleft |
|
14510 |
+@item top |
|
14511 |
+@item bottomleft |
|
14512 |
+@item bottom |
|
14513 |
+@end table |
|
14486 | 14514 |
@end table |
14487 | 14515 |
|
14488 | 14516 |
The values of the @option{w} and @option{h} options are expressions |
... | ... |
@@ -88,10 +88,12 @@ typedef struct ZScaleContext { |
88 | 88 |
int trc; |
89 | 89 |
int primaries; |
90 | 90 |
int range; |
91 |
+ int chromal; |
|
91 | 92 |
int colorspace_in; |
92 | 93 |
int trc_in; |
93 | 94 |
int primaries_in; |
94 | 95 |
int range_in; |
96 |
+ int chromal_in; |
|
95 | 97 |
char *size_str; |
96 | 98 |
|
97 | 99 |
char *w_expr; ///< width expression string |
... | ... |
@@ -116,6 +118,7 @@ typedef struct ZScaleContext { |
116 | 116 |
enum AVColorTransferCharacteristic in_trc, out_trc; |
117 | 117 |
enum AVColorPrimaries in_primaries, out_primaries; |
118 | 118 |
enum AVColorRange in_range, out_range; |
119 |
+ enum AVChromaLocation in_chromal, out_chromal; |
|
119 | 120 |
} ZScaleContext; |
120 | 121 |
|
121 | 122 |
static av_cold int init_dict(AVFilterContext *ctx, AVDictionary **opts) |
... | ... |
@@ -316,6 +319,26 @@ static int print_zimg_error(AVFilterContext *ctx) |
316 | 316 |
return err_code; |
317 | 317 |
} |
318 | 318 |
|
319 |
+static int convert_chroma_location(enum AVChromaLocation chroma_location) |
|
320 |
+{ |
|
321 |
+ switch (chroma_location) { |
|
322 |
+ case AVCHROMA_LOC_UNSPECIFIED: |
|
323 |
+ case AVCHROMA_LOC_LEFT: |
|
324 |
+ return ZIMG_CHROMA_LEFT; |
|
325 |
+ case AVCHROMA_LOC_CENTER: |
|
326 |
+ return ZIMG_CHROMA_CENTER; |
|
327 |
+ case AVCHROMA_LOC_TOPLEFT: |
|
328 |
+ return ZIMG_CHROMA_TOP_LEFT; |
|
329 |
+ case AVCHROMA_LOC_TOP: |
|
330 |
+ return ZIMG_CHROMA_TOP; |
|
331 |
+ case AVCHROMA_LOC_BOTTOMLEFT: |
|
332 |
+ return ZIMG_CHROMA_BOTTOM_LEFT; |
|
333 |
+ case AVCHROMA_LOC_BOTTOM: |
|
334 |
+ return ZIMG_CHROMA_BOTTOM; |
|
335 |
+ } |
|
336 |
+ return ZIMG_CHROMA_LEFT; |
|
337 |
+} |
|
338 |
+ |
|
319 | 339 |
static int convert_matrix(enum AVColorSpace colorspace) |
320 | 340 |
{ |
321 | 341 |
switch (colorspace) { |
... | ... |
@@ -420,7 +443,9 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) |
420 | 420 |
|| s->out_colorspace != out->colorspace |
421 | 421 |
|| s->out_trc != out->color_trc |
422 | 422 |
|| s->out_primaries != out->color_primaries |
423 |
- || s->out_range != out->color_range) { |
|
423 |
+ || s->out_range != out->color_range |
|
424 |
+ || s->in_chromal != in->chroma_location |
|
425 |
+ || s->out_chromal != out->chroma_location) { |
|
424 | 426 |
snprintf(buf, sizeof(buf)-1, "%d", outlink->w); |
425 | 427 |
av_opt_set(s, "w", buf, 0); |
426 | 428 |
snprintf(buf, sizeof(buf)-1, "%d", outlink->h); |
... | ... |
@@ -456,6 +481,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) |
456 | 456 |
s->src_format.transfer_characteristics = s->trc_in == - 1 ? convert_trc(in->color_trc) : s->trc_in; |
457 | 457 |
s->src_format.color_primaries = s->primaries_in == -1 ? convert_primaries(in->color_primaries) : s->primaries_in; |
458 | 458 |
s->src_format.pixel_range = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_RANGE_FULL : s->range_in == -1 ? convert_range(in->color_range) : s->range_in; |
459 |
+ s->src_format.chroma_location = s->chromal_in == -1 ? convert_chroma_location(in->chroma_location) : s->chromal_in; |
|
459 | 460 |
|
460 | 461 |
s->dst_format.width = out->width; |
461 | 462 |
s->dst_format.height = out->height; |
... | ... |
@@ -468,6 +494,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) |
468 | 468 |
s->dst_format.transfer_characteristics = s->trc == -1 ? convert_trc(out->color_trc) : s->trc; |
469 | 469 |
s->dst_format.color_primaries = s->primaries == -1 ? convert_primaries(out->color_primaries) : s->primaries; |
470 | 470 |
s->dst_format.pixel_range = (odesc->flags & AV_PIX_FMT_FLAG_RGB) ? ZIMG_RANGE_FULL : s->range == -1 ? convert_range(out->color_range) : s->range; |
471 |
+ s->dst_format.chroma_location = s->chromal == -1 ? convert_chroma_location(out->chroma_location) : s->chromal; |
|
471 | 472 |
|
472 | 473 |
if (s->colorspace != -1) |
473 | 474 |
out->colorspace = (int)s->dst_format.matrix_coefficients; |
... | ... |
@@ -481,6 +508,9 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) |
481 | 481 |
if (s->trc != -1) |
482 | 482 |
out->color_trc = (int)s->dst_format.transfer_characteristics; |
483 | 483 |
|
484 |
+ if (s->chromal != -1) |
|
485 |
+ out->chroma_location = (int)s->dst_format.chroma_location - 1; |
|
486 |
+ |
|
484 | 487 |
zimg_filter_graph_free(s->graph); |
485 | 488 |
s->graph = zimg_filter_graph_build(&s->src_format, &s->dst_format, &s->params); |
486 | 489 |
if (!s->graph) { |
... | ... |
@@ -705,6 +735,17 @@ static const AVOption zscale_options[] = { |
705 | 705 |
{ "tin", "set input transfer characteristic", OFFSET(trc_in), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_TRANSFER_2020_12, FLAGS, "transfer" }, |
706 | 706 |
{ "matrixin", "set input colorspace matrix", OFFSET(colorspace_in), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_MATRIX_2020_CL, FLAGS, "matrix" }, |
707 | 707 |
{ "min", "set input colorspace matrix", OFFSET(colorspace_in), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_MATRIX_2020_CL, FLAGS, "matrix" }, |
708 |
+ { "chromal", "set output chroma location", OFFSET(chromal), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM, FLAGS, "chroma" }, |
|
709 |
+ { "c", "set output chroma location", OFFSET(chromal), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM, FLAGS, "chroma" }, |
|
710 |
+ { "input", 0, 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, FLAGS, "chroma" }, |
|
711 |
+ { "left", 0, 0, AV_OPT_TYPE_CONST, {.i64 = ZIMG_CHROMA_LEFT}, 0, 0, FLAGS, "chroma" }, |
|
712 |
+ { "center", 0, 0, AV_OPT_TYPE_CONST, {.i64 = ZIMG_CHROMA_CENTER}, 0, 0, FLAGS, "chroma" }, |
|
713 |
+ { "topleft", 0, 0, AV_OPT_TYPE_CONST, {.i64 = ZIMG_CHROMA_TOP_LEFT}, 0, 0, FLAGS, "chroma" }, |
|
714 |
+ { "top", 0, 0, AV_OPT_TYPE_CONST, {.i64 = ZIMG_CHROMA_TOP}, 0, 0, FLAGS, "chroma" }, |
|
715 |
+ { "bottomleft",0, 0, AV_OPT_TYPE_CONST, {.i64 = ZIMG_CHROMA_BOTTOM_LEFT}, 0, 0, FLAGS, "chroma" }, |
|
716 |
+ { "bottom", 0, 0, AV_OPT_TYPE_CONST, {.i64 = ZIMG_CHROMA_BOTTOM}, 0, 0, FLAGS, "chroma" }, |
|
717 |
+ { "chromalin", "set input chroma location", OFFSET(chromal_in), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM, FLAGS, "chroma" }, |
|
718 |
+ { "cin", "set input chroma location", OFFSET(chromal_in), AV_OPT_TYPE_INT, {.i64 = -1}, -1, ZIMG_CHROMA_BOTTOM, FLAGS, "chroma" }, |
|
708 | 719 |
{ NULL } |
709 | 720 |
}; |
710 | 721 |
|