26 #include "config_components.h"
43 #define OFFSET(x) offsetof(VPPContext, x)
44 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
47 #define ENH_FILTERS_COUNT (8)
63 mfxExtVideoSignalInfo invsi_conf;
65 mfxExtVideoSignalInfo outvsi_conf;
67 mfxExtMasteringDisplayColourVolume mdcv_conf;
68 mfxExtContentLightLevelInfo clli_conf;
157 #define PASS_EXPR(e, s) {\
159 ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \
161 av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s); \
166 #define CALC_EXPR(e, v, i, d) {\
168 i = v = av_expr_eval(e, var_values, NULL); \
195 var_values[
VAR_SAR] =
ctx->inputs[0]->sample_aspect_ratio.num ?
196 (
double)
ctx->inputs[0]->sample_aspect_ratio.num /
ctx->inputs[0]->sample_aspect_ratio.den : 1;
274 #define STRING_OPTION(var_name, func_name, default_value) do { \
275 if (vpp->var_name ## _str) { \
276 int var = av_ ## func_name ## _from_name(vpp->var_name ## _str); \
278 av_log(ctx, AV_LOG_ERROR, "Invalid %s.\n", #var_name); \
279 return AVERROR(EINVAL); \
281 vpp->var_name = var; \
283 vpp->var_name = default_value; \
324 if (ow < -1 || oh < -1) {
329 if (ow == -1 && oh == -1)
344 if (ow > INT_MAX || oh > INT_MAX ||
345 (oh *
inlink->w) > INT_MAX ||
346 (ow *
inlink->h) > INT_MAX)
375 }
else if (
ctx->hw_device_ctx) {
376 device_ref =
ctx->hw_device_ctx;
380 mfx_version->Major = 0;
381 mfx_version->Minor = 0;
386 device_hwctx = device_ctx->
hwctx;
388 return MFXQueryVersion(device_hwctx->
session, mfx_version);
396 mfxExtVideoSignalInfo invsi_conf, outvsi_conf;
397 mfxExtMasteringDisplayColourVolume mdcv_conf;
398 mfxExtContentLightLevelInfo clli_conf;
408 memset(&invsi_conf, 0,
sizeof(mfxExtVideoSignalInfo));
409 invsi_conf.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO_IN;
410 invsi_conf.Header.BufferSz =
sizeof(mfxExtVideoSignalInfo);
415 invsi_conf.ColourDescriptionPresent = 1;
417 memset(&mdcv_conf, 0,
sizeof(mfxExtMasteringDisplayColourVolume));
423 const int mapping[3] = {1, 2, 0};
424 const int chroma_den = 50000;
425 const int luma_den = 10000;
428 mdcv_conf.Header.BufferId = MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME_IN;
429 mdcv_conf.Header.BufferSz =
sizeof(mfxExtMasteringDisplayColourVolume);
431 for (
i = 0;
i < 3;
i++) {
432 const int j = mapping[
i];
434 mdcv_conf.DisplayPrimariesX[
i] =
438 mdcv_conf.DisplayPrimariesY[
i] =
444 mdcv_conf.WhitePointX =
447 mdcv_conf.WhitePointY =
454 mdcv_conf.MaxDisplayMasteringLuminance =
456 mdcv_conf.MinDisplayMasteringLuminance =
462 memset(&clli_conf, 0,
sizeof(mfxExtContentLightLevelInfo));
467 clli_conf.Header.BufferId = MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO;
468 clli_conf.Header.BufferSz =
sizeof(mfxExtContentLightLevelInfo);
469 clli_conf.MaxContentLightLevel =
FFMIN(clm->
MaxCLL, 65535);
470 clli_conf.MaxPicAverageLightLevel =
FFMIN(clm->
MaxFALL, 65535);
493 memset(&outvsi_conf, 0,
sizeof(mfxExtVideoSignalInfo));
494 outvsi_conf.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO_OUT;
495 outvsi_conf.Header.BufferSz =
sizeof(mfxExtVideoSignalInfo);
500 outvsi_conf.ColourDescriptionPresent = 1;
502 if (memcmp(&vpp->invsi_conf, &invsi_conf,
sizeof(mfxExtVideoSignalInfo)) ||
503 memcmp(&vpp->mdcv_conf, &mdcv_conf,
sizeof(mfxExtMasteringDisplayColourVolume)) ||
504 memcmp(&vpp->clli_conf, &clli_conf,
sizeof(mfxExtContentLightLevelInfo)) ||
505 memcmp(&vpp->outvsi_conf, &outvsi_conf,
sizeof(mfxExtVideoSignalInfo))) {
506 vpp->invsi_conf = invsi_conf;
509 vpp->outvsi_conf = outvsi_conf;
512 vpp->mdcv_conf = mdcv_conf;
513 if (mdcv_conf.Header.BufferId)
516 vpp->clli_conf = clli_conf;
517 if (clli_conf.Header.BufferId)
533 mfxVersion mfx_version;
563 in_format =
inlink->format;
580 #define INIT_MFX_EXTBUF(extbuf, id) do { \
581 memset(&vpp->extbuf, 0, sizeof(vpp->extbuf)); \
582 vpp->extbuf.Header.BufferId = id; \
583 vpp->extbuf.Header.BufferSz = sizeof(vpp->extbuf); \
584 param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->extbuf; \
587 #define SET_MFX_PARAM_FIELD(extbuf, field, value) do { \
588 vpp->extbuf.field = value; \
594 MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED));
624 vpp->
rotate = MFX_ANGLE_270;
625 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
628 vpp->
rotate = MFX_ANGLE_90;
629 vpp->
hflip = MFX_MIRRORING_DISABLED;
632 vpp->
rotate = MFX_ANGLE_270;
633 vpp->
hflip = MFX_MIRRORING_DISABLED;
636 vpp->
rotate = MFX_ANGLE_90;
637 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
640 vpp->
rotate = MFX_ANGLE_180;
641 vpp->
hflip = MFX_MIRRORING_DISABLED;
644 vpp->
rotate = MFX_ANGLE_0;
645 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
648 vpp->
rotate = MFX_ANGLE_180;
649 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
657 "not supported with this MSDK version.\n");
667 if (MFX_ANGLE_90 == vpp->
rotate || MFX_ANGLE_270 == vpp->
rotate) {
669 FFSWAP(
int, outlink->
w, outlink->
h);
674 "not supported with this MSDK version.\n");
685 "not supported with this MSDK version.\n");
696 mode = MFX_SCALING_MODE_VENDOR +
mode - 2;
703 "option is not supported with this MSDK version.\n");
706 #undef INIT_MFX_EXTBUF
707 #undef SET_MFX_PARAM_FIELD
753 if (in || qsv->
eof) {
828 #define DEFINE_QSV_FILTER(x, sn, ln, fmts) \
829 static const AVClass x##_class = { \
830 .class_name = #sn "_qsv", \
831 .item_name = av_default_item_name, \
832 .option = x##_options, \
833 .version = LIBAVUTIL_VERSION_INT, \
835 const AVFilter ff_vf_##sn##_qsv = { \
836 .name = #sn "_qsv", \
837 .description = NULL_IF_CONFIG_SMALL("Quick Sync Video " #ln), \
838 .preinit = x##_preinit, \
840 .uninit = vpp_uninit, \
841 .priv_size = sizeof(VPPContext), \
842 .priv_class = &x##_class, \
843 FILTER_INPUTS(vpp_inputs), \
844 FILTER_OUTPUTS(vpp_outputs), \
846 .activate = activate, \
847 .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, \
848 .flags = AVFILTER_FLAG_HWDEVICE, \
851 #if CONFIG_VPP_QSV_FILTER
853 static const AVOption vpp_options[] = {
854 {
"deinterlace",
"deinterlace mode: 0=off, 1=bob, 2=advanced",
OFFSET(deinterlace),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MFX_DEINTERLACING_ADVANCED, .flags =
FLAGS, .unit =
"deinterlace" },
855 {
"bob",
"Bob deinterlace mode.", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_BOB }, .flags =
FLAGS, .unit =
"deinterlace" },
856 {
"advanced",
"Advanced deinterlace mode. ", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_ADVANCED }, .flags =
FLAGS, .unit =
"deinterlace" },
881 {
"w",
"Output video width(0=input video width, -1=keep input video aspect)",
OFFSET(ow),
AV_OPT_TYPE_STRING, { .str=
"cw" }, 0, 255, .flags =
FLAGS },
882 {
"width",
"Output video width(0=input video width, -1=keep input video aspect)",
OFFSET(ow),
AV_OPT_TYPE_STRING, { .str=
"cw" }, 0, 255, .flags =
FLAGS },
883 {
"h",
"Output video height(0=input video height, -1=keep input video aspect)",
OFFSET(oh),
AV_OPT_TYPE_STRING, { .str=
"w*ch/cw" }, 0, 255, .flags =
FLAGS },
884 {
"height",
"Output video height(0=input video height, -1=keep input video aspect)",
OFFSET(oh),
AV_OPT_TYPE_STRING, { .str=
"w*ch/cw" }, 0, 255, .flags =
FLAGS },
886 {
"async_depth",
"Internal parallelization depth, the higher the value the higher the latency.",
OFFSET(qsv.async_depth),
AV_OPT_TYPE_INT, { .i64 = 4 }, 0, INT_MAX, .flags =
FLAGS },
888 {
"scale_mode",
"scaling & format conversion mode (mode compute(3), vd(4) and ve(5) are only available on some platforms)",
OFFSET(scale_mode),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 5, .flags =
FLAGS, .unit =
"scale mode" },
890 {
"scale_mode",
"scaling & format conversion mode",
OFFSET(scale_mode),
AV_OPT_TYPE_INT, { .i64 = MFX_SCALING_MODE_DEFAULT }, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, .flags =
FLAGS, .unit =
"scale mode" },
892 {
"auto",
"auto mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_DEFAULT}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
893 {
"low_power",
"low power mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
894 {
"hq",
"high quality mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_QUALITY}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
896 {
"compute",
"compute", 0,
AV_OPT_TYPE_CONST, { .i64 = 3}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
901 {
"rate",
"Generate output at frame rate or field rate, available only for deinterlace mode",
903 {
"frame",
"Output at frame rate (one frame of output for each field-pair)",
905 {
"field",
"Output at field rate (one frame of output for each field)",
908 {
"out_range",
"Output color range",
911 {
"full",
"Full range",
913 {
"limited",
"Limited range",
915 {
"jpeg",
"Full range",
917 {
"mpeg",
"Limited range",
919 {
"tv",
"Limited range",
921 {
"pc",
"Full range",
923 {
"out_color_matrix",
"Output color matrix coefficient set",
925 {
"out_color_primaries",
"Output color primaries",
927 {
"out_color_transfer",
"Output color transfer characteristics",
930 {
"tonemap",
"Perform tonemapping (0=disable tonemapping, 1=perform tonemapping if the input has HDR metadata)",
OFFSET(
tonemap),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, .flags =
FLAGS},
954 &
ctx->inputs[0]->outcfg.formats);
971 &
ctx->outputs[0]->incfg.formats);
978 #if CONFIG_SCALE_QSV_FILTER
980 static const AVOption qsvscale_options[] = {
981 {
"w",
"Output video width(0=input video width, -1=keep input video aspect)",
OFFSET(ow),
AV_OPT_TYPE_STRING, { .str =
"iw" }, .flags =
FLAGS },
982 {
"h",
"Output video height(0=input video height, -1=keep input video aspect)",
OFFSET(oh),
AV_OPT_TYPE_STRING, { .str =
"ih" }, .flags =
FLAGS },
986 {
"mode",
"scaling & format conversion mode (mode compute(3), vd(4) and ve(5) are only available on some platforms)",
OFFSET(scale_mode),
AV_OPT_TYPE_INT, { .i64 = 0}, 0, 5,
FLAGS, .unit =
"mode"},
988 {
"mode",
"scaling & format conversion mode",
OFFSET(scale_mode),
AV_OPT_TYPE_INT, { .i64 = MFX_SCALING_MODE_DEFAULT}, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY,
FLAGS, .unit =
"mode"},
990 {
"low_power",
"low power mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX,
FLAGS, .unit =
"mode"},
991 {
"hq",
"high quality mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_QUALITY}, INT_MIN, INT_MAX,
FLAGS, .unit =
"mode"},
1015 #if CONFIG_DEINTERLACE_QSV_FILTER
1017 static const AVOption qsvdeint_options[] = {
1018 {
"mode",
"set deinterlace mode",
OFFSET(deinterlace),
AV_OPT_TYPE_INT, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED,
FLAGS, .unit =
"mode"},
1019 {
"bob",
"bob algorithm", 0,
AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED,
FLAGS, .unit =
"mode"},
1020 {
"advanced",
"Motion adaptive algorithm", 0,
AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED,
FLAGS, .unit =
"mode"},