User may set color range / matrix coefficient set / primaries / transfer characteristics for output.
Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -61,6 +61,8 @@ typedef struct VPPContext{ · 60 unmodified lines | ||
| 61 | 61 | #if QSV_ONEVPL |
| 62 | 62 | /** Video signal info attached on the input frame */ |
| 63 | 63 | mfxExtVideoSignalInfo invsi_conf; |
| 64 | + /** Video signal info attached on the output frame */ | |
| 65 | + mfxExtVideoSignalInfo outvsi_conf; | |
| 64 | 66 | #endif |
| 65 | 67 | |
| 66 | 68 | /** |
| @@ -104,6 +106,16 @@ typedef struct VPPContext{ · 37 unmodified lines | ||
| 104 | 106 | char *ow, *oh; |
| 105 | 107 | char *output_format_str; |
| 106 | 108 | |
| 109 | + /** The color properties for output */ | |
| 110 | + char *color_primaries_str; | |
| 111 | + char *color_transfer_str; | |
| 112 | + char *color_matrix_str; | |
| 113 | + | |
| 114 | + int color_range; | |
| 115 | + enum AVColorPrimaries color_primaries; | |
| 116 | + enum AVColorTransferCharacteristic color_transfer; | |
| 117 | + enum AVColorSpace color_matrix; | |
| 118 | + | |
| 107 | 119 | int has_passthrough; /* apply pass through mode if possible */ |
| 108 | 120 | int field_rate; /* Generate output at frame rate or field rate for deinterlace mode, 0: frame, 1: field */ |
| 109 | 121 | } VPPContext; |
| @@ -231,6 +243,11 @@ static av_cold int vpp_preinit(AVFilterContext *ctx) · 121 unmodified lines | ||
| 231 | 243 | vpp->contrast = 1.0; |
| 232 | 244 | vpp->transpose = -1; |
| 233 | 245 | |
| 246 | + vpp->color_range = AVCOL_RANGE_UNSPECIFIED; | |
| 247 | + vpp->color_primaries = AVCOL_PRI_UNSPECIFIED; | |
| 248 | + vpp->color_transfer = AVCOL_TRC_UNSPECIFIED; | |
| 249 | + vpp->color_matrix = AVCOL_SPC_UNSPECIFIED; | |
| 250 | + | |
| 234 | 251 | vpp->has_passthrough = 1; |
| 235 | 252 | |
| 236 | 253 | return 0; |
| @@ -250,6 +267,24 @@ static av_cold int vpp_init(AVFilterContext *ctx) · 13 unmodified lines | ||
| 250 | 267 | } |
| 251 | 268 | } |
| 252 | 269 | |
| 270 | +#define STRING_OPTION(var_name, func_name, default_value) do { \ | |
| 271 | + if (vpp->var_name ## _str) { \ | |
| 272 | + int var = av_ ## func_name ## _from_name(vpp->var_name ## _str); \ | |
| 273 | + if (var < 0) { \ | |
| 274 | + av_log(ctx, AV_LOG_ERROR, "Invalid %s.\n", #var_name); \ | |
| 275 | + return AVERROR(EINVAL); \ | |
| 276 | + } \ | |
| 277 | + vpp->var_name = var; \ | |
| 278 | + } else { \ | |
| 279 | + vpp->var_name = default_value; \ | |
| 280 | + } \ | |
| 281 | + } while (0) | |
| 282 | + | |
| 283 | + STRING_OPTION(color_primaries, color_primaries, AVCOL_PRI_UNSPECIFIED); | |
| 284 | + STRING_OPTION(color_transfer, color_transfer, AVCOL_TRC_UNSPECIFIED); | |
| 285 | + STRING_OPTION(color_matrix, color_space, AVCOL_SPC_UNSPECIFIED); | |
| 286 | + | |
| 287 | +#undef STRING_OPTION | |
| 253 | 288 | return 0; |
| 254 | 289 | } |
| 255 | 290 | |
| @@ -353,11 +388,11 @@ static int vpp_set_frame_ext_params(AVFilterContext *ctx, const AVFrame *in, AVF · 97 unmodified lines | ||
| 353 | 388 | #if QSV_ONEVPL |
| 354 | 389 | VPPContext *vpp = ctx->priv; |
| 355 | 390 | QSVVPPContext *qsvvpp = &vpp->qsv; |
| 356 | − mfxExtVideoSignalInfo invsi_conf; | |
| 391 | + mfxExtVideoSignalInfo invsi_conf, outvsi_conf; | |
| 357 | 392 | |
| 358 | 393 | fp->num_ext_buf = 0; |
| 359 | 394 | |
| 360 | − if (!in || | |
| 395 | + if (!in || !out || | |
| 361 | 396 | !QSV_RUNTIME_VERSION_ATLEAST(qsvvpp->ver, 2, 0)) |
| 362 | 397 | return 0; |
| 363 | 398 | |
| @@ -370,9 +405,32 @@ static int vpp_set_frame_ext_params(AVFilterContext *ctx, const AVFrame *in, AVF · 6 unmodified lines | ||
| 370 | 405 | invsi_conf.MatrixCoefficients = (in->colorspace == AVCOL_SPC_UNSPECIFIED) ? AVCOL_SPC_BT709 : in->colorspace; |
| 371 | 406 | invsi_conf.ColourDescriptionPresent = 1; |
| 372 | 407 | |
| 373 | − if (memcmp(&vpp->invsi_conf, &invsi_conf, sizeof(mfxExtVideoSignalInfo))) { | |
| 408 | + if (vpp->color_range != AVCOL_RANGE_UNSPECIFIED) | |
| 409 | + out->color_range = vpp->color_range; | |
| 410 | + if (vpp->color_primaries != AVCOL_PRI_UNSPECIFIED) | |
| 411 | + out->color_primaries = vpp->color_primaries; | |
| 412 | + if (vpp->color_transfer != AVCOL_TRC_UNSPECIFIED) | |
| 413 | + out->color_trc = vpp->color_transfer; | |
| 414 | + if (vpp->color_matrix != AVCOL_SPC_UNSPECIFIED) | |
| 415 | + out->colorspace = vpp->color_matrix; | |
| 416 | + | |
| 417 | + memset(&outvsi_conf, 0, sizeof(mfxExtVideoSignalInfo)); | |
| 418 | + outvsi_conf.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO_OUT; | |
| 419 | + outvsi_conf.Header.BufferSz = sizeof(mfxExtVideoSignalInfo); | |
| 420 | + outvsi_conf.VideoFullRange = (out->color_range == AVCOL_RANGE_JPEG); | |
| 421 | + outvsi_conf.ColourPrimaries = (out->color_primaries == AVCOL_PRI_UNSPECIFIED) ? AVCOL_PRI_BT709 : out->color_primaries; | |
| 422 | + outvsi_conf.TransferCharacteristics = (out->color_trc == AVCOL_TRC_UNSPECIFIED) ? AVCOL_TRC_BT709 : out->color_trc; | |
| 423 | + outvsi_conf.MatrixCoefficients = (out->colorspace == AVCOL_SPC_UNSPECIFIED) ? AVCOL_SPC_BT709 : out->colorspace; | |
| 424 | + outvsi_conf.ColourDescriptionPresent = 1; | |
| 425 | + | |
| 426 | + if (memcmp(&vpp->invsi_conf, &invsi_conf, sizeof(mfxExtVideoSignalInfo)) || | |
| 427 | + memcmp(&vpp->outvsi_conf, &outvsi_conf, sizeof(mfxExtVideoSignalInfo))) { | |
| 374 | 428 | vpp->invsi_conf = invsi_conf; |
| 375 | 429 | fp->ext_buf[fp->num_ext_buf++] = (mfxExtBuffer*)&vpp->invsi_conf; |
| 430 | + | |
| 431 | + vpp->outvsi_conf = outvsi_conf; | |
| 432 | + fp->ext_buf[fp->num_ext_buf++] = (mfxExtBuffer*)&vpp->outvsi_conf; | |
| 433 | + | |
| 376 | 434 | } |
| 377 | 435 | #endif |
| 378 | 436 | |
| @@ -560,6 +618,10 @@ static int config_output(AVFilterLink *outlink) · 181 unmodified lines | ||
| 560 | 618 | if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise || |
| 561 | 619 | vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip || |
| 562 | 620 | inlink->w != outlink->w || inlink->h != outlink->h || in_format != vpp->out_format || |
| 621 | + vpp->color_range != AVCOL_RANGE_UNSPECIFIED || | |
| 622 | + vpp->color_primaries != AVCOL_PRI_UNSPECIFIED || | |
| 623 | + vpp->color_transfer != AVCOL_TRC_UNSPECIFIED || | |
| 624 | + vpp->color_matrix != AVCOL_SPC_UNSPECIFIED || | |
| 563 | 625 | !vpp->has_passthrough) |
| 564 | 626 | return ff_qsvvpp_init(ctx, ¶m); |
| 565 | 627 | else { |
| @@ -750,6 +812,28 @@ static const AVOption vpp_options[] = { · 184 unmodified lines | ||
| 750 | 812 | { "field", "Output at field rate (one frame of output for each field)", |
| 751 | 813 | 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "rate" }, |
| 752 | 814 | |
| 815 | + { "out_range", "Output color range", | |
| 816 | + OFFSET(color_range), AV_OPT_TYPE_INT, { .i64 = AVCOL_RANGE_UNSPECIFIED }, | |
| 817 | + AVCOL_RANGE_UNSPECIFIED, AVCOL_RANGE_JPEG, FLAGS, "range" }, | |
| 818 | + { "full", "Full range", | |
| 819 | + 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, | |
| 820 | + { "limited", "Limited range", | |
| 821 | + 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, | |
| 822 | + { "jpeg", "Full range", | |
| 823 | + 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, | |
| 824 | + { "mpeg", "Limited range", | |
| 825 | + 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, | |
| 826 | + { "tv", "Limited range", | |
| 827 | + 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, | |
| 828 | + { "pc", "Full range", | |
| 829 | + 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, | |
| 830 | + { "out_color_matrix", "Output color matrix coefficient set", | |
| 831 | + OFFSET(color_matrix_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, | |
| 832 | + { "out_color_primaries", "Output color primaries", | |
| 833 | + OFFSET(color_primaries_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, | |
| 834 | + { "out_color_transfer", "Output color transfer characteristics", | |
| 835 | + OFFSET(color_transfer_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, | |
| 836 | + | |
| 753 | 837 | { NULL } |
| 754 | 838 | }; |
| 755 | 839 | |