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, 
"deinterlace" },
 
  851     { 
"bob",         
"Bob deinterlace mode.",                      0,                   
AV_OPT_TYPE_CONST,    { .i64 = MFX_DEINTERLACING_BOB },            .flags = 
FLAGS, 
"deinterlace" },
 
  852     { 
"advanced",    
"Advanced deinterlace mode. ",                0,                   
AV_OPT_TYPE_CONST,    { .i64 = MFX_DEINTERLACING_ADVANCED },       .flags = 
FLAGS, 
"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 = 0 }, 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, 
"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, 
"scale mode" },
 
  888     { 
"auto",      
"auto mode",             0,    
AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_DEFAULT},  INT_MIN, INT_MAX, 
FLAGS, 
"scale mode"},
 
  889     { 
"low_power", 
"low power mode",        0,    
AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX, 
FLAGS, 
"scale mode"},
 
  890     { 
"hq",        
"high quality mode",     0,    
AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_QUALITY},  INT_MIN, INT_MAX, 
FLAGS, 
"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, 
"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, 
"mode"},
 
  986     { 
"low_power", 
"low power mode",        0,             
AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX, 
FLAGS, 
"mode"},
 
  987     { 
"hq",        
"high quality mode",     0,             
AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_QUALITY},  INT_MIN, INT_MAX, 
FLAGS, 
"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, 
"mode"},
 
 1015     { 
"bob",   
"bob algorithm",                  0, 
AV_OPT_TYPE_CONST,      {.i64 = MFX_DEINTERLACING_BOB}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, 
FLAGS, 
"mode"},
 
 1016     { 
"advanced", 
"Motion adaptive algorithm",   0, 
AV_OPT_TYPE_CONST, {.i64 = MFX_DEINTERLACING_ADVANCED}, MFX_DEINTERLACING_BOB, MFX_DEINTERLACING_ADVANCED, 
FLAGS, 
"mode"},