26 #include "config_components.h"
44 #define OFFSET(x) offsetof(VPPContext, x)
45 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
48 #define ENH_FILTERS_COUNT (8)
64 mfxExtVideoSignalInfo invsi_conf;
66 mfxExtVideoSignalInfo outvsi_conf;
68 mfxExtMasteringDisplayColourVolume mdcv_conf;
69 mfxExtContentLightLevelInfo clli_conf;
158 #define PASS_EXPR(e, s) {\
160 ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \
162 av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s); \
167 #define CALC_EXPR(e, v, i, d) {\
169 i = v = av_expr_eval(e, var_values, NULL); \
196 var_values[
VAR_SAR] =
ctx->inputs[0]->sample_aspect_ratio.num ?
197 (
double)
ctx->inputs[0]->sample_aspect_ratio.num /
ctx->inputs[0]->sample_aspect_ratio.den : 1;
275 #define STRING_OPTION(var_name, func_name, default_value) do { \
276 if (vpp->var_name ## _str) { \
277 int var = av_ ## func_name ## _from_name(vpp->var_name ## _str); \
279 av_log(ctx, AV_LOG_ERROR, "Invalid %s.\n", #var_name); \
280 return AVERROR(EINVAL); \
282 vpp->var_name = var; \
284 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)
372 if (
inlink->hw_frames_ctx) {
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;
507 fp->ext_buf[
fp->num_ext_buf++] = (mfxExtBuffer*)&vpp->invsi_conf;
509 vpp->outvsi_conf = outvsi_conf;
510 fp->ext_buf[
fp->num_ext_buf++] = (mfxExtBuffer*)&vpp->outvsi_conf;
512 vpp->mdcv_conf = mdcv_conf;
513 if (mdcv_conf.Header.BufferId)
514 fp->ext_buf[
fp->num_ext_buf++] = (mfxExtBuffer*)&vpp->mdcv_conf;
516 vpp->clli_conf = clli_conf;
517 if (clli_conf.Header.BufferId)
518 fp->ext_buf[
fp->num_ext_buf++] = (mfxExtBuffer*)&vpp->clli_conf;
532 mfxVersion mfx_version;
555 if (!
inlink->hw_frames_ctx || !
inlink->hw_frames_ctx->data)
560 in_format =
inlink->format;
577 #define INIT_MFX_EXTBUF(extbuf, id) do { \
578 memset(&vpp->extbuf, 0, sizeof(vpp->extbuf)); \
579 vpp->extbuf.Header.BufferId = id; \
580 vpp->extbuf.Header.BufferSz = sizeof(vpp->extbuf); \
581 param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->extbuf; \
584 #define SET_MFX_PARAM_FIELD(extbuf, field, value) do { \
585 vpp->extbuf.field = value; \
591 MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED));
621 vpp->
rotate = MFX_ANGLE_270;
622 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
625 vpp->
rotate = MFX_ANGLE_90;
626 vpp->
hflip = MFX_MIRRORING_DISABLED;
629 vpp->
rotate = MFX_ANGLE_270;
630 vpp->
hflip = MFX_MIRRORING_DISABLED;
633 vpp->
rotate = MFX_ANGLE_90;
634 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
637 vpp->
rotate = MFX_ANGLE_180;
638 vpp->
hflip = MFX_MIRRORING_DISABLED;
641 vpp->
rotate = MFX_ANGLE_0;
642 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
645 vpp->
rotate = MFX_ANGLE_180;
646 vpp->
hflip = MFX_MIRRORING_HORIZONTAL;
654 "not supported with this MSDK version.\n");
664 if (MFX_ANGLE_90 == vpp->
rotate || MFX_ANGLE_270 == vpp->
rotate) {
666 FFSWAP(
int, outlink->
w, outlink->
h);
671 "not supported with this MSDK version.\n");
682 "not supported with this MSDK version.\n");
693 mode = MFX_SCALING_MODE_VENDOR +
mode - 2;
700 "option is not supported with this MSDK version.\n");
703 #undef INIT_MFX_EXTBUF
704 #undef SET_MFX_PARAM_FIELD
719 if (
inlink->hw_frames_ctx)
750 if (in || qsv->
eof) {
824 #define DEFINE_QSV_FILTER(x, sn, ln, fmts) \
825 static const AVClass x##_class = { \
826 .class_name = #sn "_qsv", \
827 .item_name = av_default_item_name, \
828 .option = x##_options, \
829 .version = LIBAVUTIL_VERSION_INT, \
831 const AVFilter ff_vf_##sn##_qsv = { \
832 .name = #sn "_qsv", \
833 .description = NULL_IF_CONFIG_SMALL("Quick Sync Video " #ln), \
834 .preinit = x##_preinit, \
836 .uninit = vpp_uninit, \
837 .priv_size = sizeof(VPPContext), \
838 .priv_class = &x##_class, \
839 FILTER_INPUTS(vpp_inputs), \
840 FILTER_OUTPUTS(vpp_outputs), \
842 .activate = activate, \
843 .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, \
844 .flags = AVFILTER_FLAG_HWDEVICE, \
847 #if CONFIG_VPP_QSV_FILTER
849 static const AVOption vpp_options[] = {
850 {
"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" },
851 {
"bob",
"Bob deinterlace mode.", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_BOB }, .flags =
FLAGS, .unit =
"deinterlace" },
852 {
"advanced",
"Advanced deinterlace mode. ", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_ADVANCED }, .flags =
FLAGS, .unit =
"deinterlace" },
877 {
"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 },
878 {
"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 },
879 {
"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 },
880 {
"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 },
882 {
"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 },
884 {
"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" },
886 {
"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" },
888 {
"auto",
"auto mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_DEFAULT}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
889 {
"low_power",
"low power mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
890 {
"hq",
"high quality mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_QUALITY}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
892 {
"compute",
"compute", 0,
AV_OPT_TYPE_CONST, { .i64 = 3}, INT_MIN, INT_MAX,
FLAGS, .unit =
"scale mode"},
897 {
"rate",
"Generate output at frame rate or field rate, available only for deinterlace mode",
899 {
"frame",
"Output at frame rate (one frame of output for each field-pair)",
901 {
"field",
"Output at field rate (one frame of output for each field)",
904 {
"out_range",
"Output color range",
907 {
"full",
"Full range",
909 {
"limited",
"Limited range",
911 {
"jpeg",
"Full range",
913 {
"mpeg",
"Limited range",
915 {
"tv",
"Limited range",
917 {
"pc",
"Full range",
919 {
"out_color_matrix",
"Output color matrix coefficient set",
921 {
"out_color_primaries",
"Output color primaries",
923 {
"out_color_transfer",
"Output color transfer characteristics",
926 {
"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},
950 &
ctx->inputs[0]->outcfg.formats);
967 &
ctx->outputs[0]->incfg.formats);
974 #if CONFIG_SCALE_QSV_FILTER
976 static const AVOption qsvscale_options[] = {
977 {
"w",
"Output video width(0=input video width, -1=keep input video aspect)",
OFFSET(ow),
AV_OPT_TYPE_STRING, { .str =
"iw" }, .flags =
FLAGS },
978 {
"h",
"Output video height(0=input video height, -1=keep input video aspect)",
OFFSET(oh),
AV_OPT_TYPE_STRING, { .str =
"ih" }, .flags =
FLAGS },
982 {
"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"},
984 {
"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"},
986 {
"low_power",
"low power mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX,
FLAGS, .unit =
"mode"},
987 {
"hq",
"high quality mode", 0,
AV_OPT_TYPE_CONST, { .i64 = MFX_SCALING_MODE_QUALITY}, INT_MIN, INT_MAX,
FLAGS, .unit =
"mode"},
1011 #if CONFIG_DEINTERLACE_QSV_FILTER
1013 static const AVOption qsvdeint_options[] = {
1014 {
"mode",
"set deinterlace mode",
OFFSET(deinterlace),
AV_OPT_TYPE_INT, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED,
FLAGS, .unit =
"mode"},
1015 {
"bob",
"bob algorithm", 0,
AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED,
FLAGS, .unit =
"mode"},
1016 {
"advanced",
"Motion adaptive algorithm", 0,
AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED,
FLAGS, .unit =
"mode"},