Browse code

avfilter/vf_zscale: make possible to change chroma location

Paul B Mahol authored on 2016/09/02 23:03:58
Showing 2 changed files
... ...
@@ -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