Browse code

avfilter/vf_scale: Add in/out yuv color matrix option

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2013/07/21 05:11:50
Showing 2 changed files
... ...
@@ -6252,6 +6252,33 @@ applies a bilinear scaling algorithm.
6252 6252
 @item size, s
6253 6253
 Set the video size, the value must be a valid abbreviation or in the
6254 6254
 form @var{width}x@var{height}.
6255
+
6256
+@item in_color_matrix
6257
+@item out_color_matrix
6258
+Set in/output YCbCr colorspace type.
6259
+This allows the autodetected value to be overridden as well as allows forcing
6260
+a specific value used for the output and encoder.
6261
+If not specified, the colorspace type depends on the pixel format.
6262
+@table @samp
6263
+@item auto
6264
+Choose automatically
6265
+
6266
+@item bt709
6267
+ITU Rec BT709
6268
+
6269
+@item fcc
6270
+United States Federal Communications Commission Title 47 Code of
6271
+Federal Regulations (2003) 73.682 (a)
6272
+
6273
+@item bt601
6274
+ITU Rec BT601
6275
+ITU-R Rec. BT.470-6 System B, G
6276
+Society of Motion Picture and Television Engineers 170M (2004)
6277
+
6278
+@item smpte240m
6279
+Society of Motion Picture and Television Engineers 240M
6280
+@end table
6281
+
6255 6282
 @end table
6256 6283
 
6257 6284
 The values of the @var{w} and @var{h} options are expressions
... ...
@@ -90,6 +90,9 @@ typedef struct {
90 90
     char *w_expr;               ///< width  expression string
91 91
     char *h_expr;               ///< height expression string
92 92
     char *flags_str;
93
+
94
+    char *in_color_matrix;
95
+    char *out_color_matrix;
93 96
 } ScaleContext;
94 97
 
95 98
 static av_cold int init(AVFilterContext *ctx)
... ...
@@ -181,6 +184,38 @@ static int query_formats(AVFilterContext *ctx)
181 181
     return 0;
182 182
 }
183 183
 
184
+static const int *parse_yuv_type(const char *s, enum AVColorSpace colorspace)
185
+{
186
+    const static int32_t yuv2rgb_coeffs[8][4] = {
187
+        {},
188
+        { 117504, 138453, 13954, 34903 }, /* ITU-R Rec. 709 (1990) */
189
+        { 104597, 132201, 25675, 53279 }, /* unspecified */
190
+        { 104597, 132201, 25675, 53279 }, /* reserved */
191
+        { 104448, 132798, 24759, 53109 }, /* FCC */
192
+        { 104597, 132201, 25675, 53279 }, /* ITU-R Rec. 624-4 System B, G */
193
+        { 104597, 132201, 25675, 53279 }, /* SMPTE 170M */
194
+        { 117579, 136230, 16907, 35559 }  /* SMPTE 240M (1987) */
195
+    };
196
+    if (!s)
197
+        s = "bt601";
198
+
199
+    if (s && strstr(s, "bt709")) {
200
+        colorspace = AVCOL_SPC_BT709;
201
+    } else if (s && strstr(s, "fcc")) {
202
+        colorspace = AVCOL_SPC_FCC;
203
+    } else if (s && strstr(s, "smpte240m")) {
204
+        colorspace = AVCOL_SPC_SMPTE240M;
205
+    } else if (s && (strstr(s, "bt601") || strstr(s, "bt470") || strstr(s, "smpte170m"))) {
206
+        colorspace = AVCOL_SPC_BT470BG;
207
+    }
208
+
209
+    if (colorspace < 1 || colorspace > 7) {
210
+        colorspace = AVCOL_SPC_BT470BG;
211
+    }
212
+
213
+    return yuv2rgb_coeffs[colorspace];
214
+}
215
+
184 216
 static int config_props(AVFilterLink *outlink)
185 217
 {
186 218
     AVFilterContext *ctx = outlink->src;
... ...
@@ -381,6 +416,35 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
381 381
     if(scale->output_is_pal)
382 382
         avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format);
383 383
 
384
+    if (   scale->in_color_matrix
385
+        || scale->out_color_matrix
386
+        || scale-> in_range != AVCOL_RANGE_UNSPECIFIED
387
+        || scale->out_range != AVCOL_RANGE_UNSPECIFIED) {
388
+        int in_full, out_full, brightness, contrast, saturation;
389
+        const int *inv_table, *table;
390
+
391
+        sws_getColorspaceDetails(scale->sws, (int **)&inv_table, &in_full,
392
+                                 (int **)&table, &out_full,
393
+                                 &brightness, &contrast, &saturation);
394
+
395
+        if (scale->in_color_matrix)
396
+            inv_table = parse_yuv_type(scale->in_color_matrix, av_frame_get_colorspace(in));
397
+        if (scale->out_color_matrix)
398
+            table     = parse_yuv_type(scale->out_color_matrix, AVCOL_SPC_UNSPECIFIED);
399
+
400
+        sws_setColorspaceDetails(scale->sws, inv_table, in_full,
401
+                                 table, out_full,
402
+                                 brightness, contrast, saturation);
403
+        if (scale->isws[0])
404
+        sws_setColorspaceDetails(scale->isws[0], inv_table, in_full,
405
+                                 table, out_full,
406
+                                 brightness, contrast, saturation);
407
+        if (scale->isws[1])
408
+        sws_setColorspaceDetails(scale->isws[1], inv_table, in_full,
409
+                                 table, out_full,
410
+                                 brightness, contrast, saturation);
411
+    }
412
+
384 413
     av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den,
385 414
               (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
386 415
               (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
... ...
@@ -409,6 +473,8 @@ static const AVOption scale_options[] = {
409 409
     { "interl", "set interlacing", OFFSET(interlaced), AV_OPT_TYPE_INT, {.i64 = 0 }, -1, 1, FLAGS },
410 410
     { "size",   "set video size",          OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
411 411
     { "s",      "set video size",          OFFSET(size_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, FLAGS },
412
+    {  "in_color_matrix", "set input YCbCr type",   OFFSET(in_color_matrix),  AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
413
+    { "out_color_matrix", "set output YCbCr type",  OFFSET(out_color_matrix), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS },
412 414
     { NULL },
413 415
 };
414 416