diff mbox series

[FFmpeg-devel] qsv: add requirement for the mininal version of libmfx

Message ID 20220522121911.10993-1-haihao.xiang@intel.com
State New
Headers show
Series [FFmpeg-devel] qsv: add requirement for the mininal version of libmfx | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_armv7_RPi4 success Make finished
andriy/make_fate_armv7_RPi4 success Make fate finished

Commit Message

Xiang, Haihao May 22, 2022, 12:19 p.m. UTC
libmfx 1.28 was released 3 years ago, it is easy to get a greater
version than 1.28. We may remove lots of compile-time checks if adding
the requirement for the minimal version in the configure script.
---
 configure                  |   7 +-
 libavcodec/qsv.c           |  24 --
 libavcodec/qsvenc.c        | 471 +++++++++++++------------------------
 libavcodec/qsvenc.h        |  51 +---
 libavcodec/qsvenc_h264.c   |   6 -
 libavcodec/qsvenc_hevc.c   |  10 -
 libavfilter/vf_scale_qsv.c |  13 +-
 libavfilter/vf_vpp_qsv.c   | 143 ++++++-----
 libavutil/hwcontext_qsv.c  |   2 -
 9 files changed, 249 insertions(+), 478 deletions(-)

Comments

Jean-Baptiste Kempf May 22, 2022, 2:04 p.m. UTC | #1
On Sun, 22 May 2022, at 14:19, Haihao Xiang wrote:
> libmfx 1.28 was released 3 years ago, it is easy to get a greater
> version than 1.28. We may remove lots of compile-time checks if adding
> the requirement for the minimal version in the configure script.

I think this is reasonable.

jb
Soft Works May 22, 2022, 6:09 p.m. UTC | #2
> -----Original Message-----
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Haihao
> Xiang
> Sent: Sunday, May 22, 2022 2:19 PM
> To: ffmpeg-devel@ffmpeg.org
> Cc: Haihao Xiang <haihao.xiang@intel.com>
> Subject: [FFmpeg-devel] [PATCH] qsv: add requirement for the mininal
> version of libmfx
> 
> libmfx 1.28 was released 3 years ago, it is easy to get a greater
> version than 1.28. We may remove lots of compile-time checks if adding
> the requirement for the minimal version in the configure script.
> ---
>  configure                  |   7 +-
>  libavcodec/qsv.c           |  24 --
>  libavcodec/qsvenc.c        | 471 +++++++++++++------------------------
>  libavcodec/qsvenc.h        |  51 +---
>  libavcodec/qsvenc_h264.c   |   6 -
>  libavcodec/qsvenc_hevc.c   |  10 -
>  libavfilter/vf_scale_qsv.c |  13 +-
>  libavfilter/vf_vpp_qsv.c   | 143 ++++++-----
>  libavutil/hwcontext_qsv.c  |   2 -
>  9 files changed, 249 insertions(+), 478 deletions(-)
> 
> diff --git a/configure b/configure
> index f115b21064..2337f0a8f2 100755
> --- a/configure
> +++ b/configure
> @@ -6566,8 +6566,11 @@ enabled liblensfun        && require_pkg_config
> liblensfun lensfun lensfun.h lf_
>  # Media SDK or Intel Media Server Studio, these don't come with
>  # pkg-config support.  Instead, users should make sure that the build
>  # can find the libraries and headers through other means.
> -enabled libmfx            && { check_pkg_config libmfx libmfx
> "mfx/mfxvideo.h" MFXInit ||
> -                               { require libmfx "mfx/mfxvideo.h" MFXInit
> "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config";
> } }
> +enabled libmfx            && { check_pkg_config libmfx "mfx >= 1.28"
> "mfx/mfxvideo.h" MFXInit ||
> +                               { require libmfx "mfx/mfxvideo.h
> mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
> +                                 { test_cpp_condition mfx/mfxdefs.h
> "MFX_VERSION >= 1028" || die "ERROR: libmfx version must be >= 1.28"; }
> &&
> +                                 warn "using libmfx without pkg-config";
> } }
> +
>  if enabled libmfx; then
>     check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h"
> "MFX_CODEC_VP9"
>  fi
> diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
> index b86c20b153..385b43bb6c 100644
> --- a/libavcodec/qsv.c
> +++ b/libavcodec/qsv.c
> @@ -38,34 +38,26 @@
> 
>  #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
> 
> -#if QSV_VERSION_ATLEAST(1, 12)
>  #include "mfx/mfxvp8.h"
> -#endif
> 
>  int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
>  {
>      switch (codec_id) {
>      case AV_CODEC_ID_H264:
>          return MFX_CODEC_AVC;
> -#if QSV_VERSION_ATLEAST(1, 8)
>      case AV_CODEC_ID_HEVC:
>          return MFX_CODEC_HEVC;
> -#endif
>      case AV_CODEC_ID_MPEG1VIDEO:
>      case AV_CODEC_ID_MPEG2VIDEO:
>          return MFX_CODEC_MPEG2;
>      case AV_CODEC_ID_VC1:
>          return MFX_CODEC_VC1;
> -#if QSV_VERSION_ATLEAST(1, 12)
>      case AV_CODEC_ID_VP8:
>          return MFX_CODEC_VP8;
> -#endif
>      case AV_CODEC_ID_MJPEG:
>          return MFX_CODEC_JPEG;
> -#if QSV_VERSION_ATLEAST(1, 19)
>      case AV_CODEC_ID_VP9:
>          return MFX_CODEC_VP9;
> -#endif
>  #if QSV_VERSION_ATLEAST(1, 34)
>      case AV_CODEC_ID_AV1:
>          return MFX_CODEC_AV1;
> @@ -189,17 +181,11 @@ enum AVPixelFormat ff_qsv_map_fourcc(uint32_t
> fourcc)
>      case MFX_FOURCC_NV12: return AV_PIX_FMT_NV12;
>      case MFX_FOURCC_P010: return AV_PIX_FMT_P010;
>      case MFX_FOURCC_P8:   return AV_PIX_FMT_PAL8;
> -#if QSV_VERSION_ATLEAST(1, 9)
>      case MFX_FOURCC_A2RGB10: return AV_PIX_FMT_X2RGB10;
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 17)
>      case MFX_FOURCC_RGB4: return AV_PIX_FMT_BGRA;
> -#endif
>  #if CONFIG_VAAPI
>      case MFX_FOURCC_YUY2: return AV_PIX_FMT_YUYV422;
> -#if QSV_VERSION_ATLEAST(1, 27)
>      case MFX_FOURCC_Y210: return AV_PIX_FMT_Y210;
> -#endif
>  #endif
>      }
>      return AV_PIX_FMT_NONE;
> @@ -217,27 +203,21 @@ int ff_qsv_map_pixfmt(enum AVPixelFormat format,
> uint32_t *fourcc)
>      case AV_PIX_FMT_P010:
>          *fourcc = MFX_FOURCC_P010;
>          return AV_PIX_FMT_P010;
> -#if QSV_VERSION_ATLEAST(1, 9)
>      case AV_PIX_FMT_X2RGB10:
>          *fourcc = MFX_FOURCC_A2RGB10;
>          return AV_PIX_FMT_X2RGB10;
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 17)
>      case AV_PIX_FMT_BGRA:
>          *fourcc = MFX_FOURCC_RGB4;
>          return AV_PIX_FMT_BGRA;
> -#endif
>  #if CONFIG_VAAPI
>      case AV_PIX_FMT_YUV422P:
>      case AV_PIX_FMT_YUYV422:
>          *fourcc = MFX_FOURCC_YUY2;
>          return AV_PIX_FMT_YUYV422;
> -#if QSV_VERSION_ATLEAST(1, 27)
>      case AV_PIX_FMT_YUV422P10:
>      case AV_PIX_FMT_Y210:
>          *fourcc = MFX_FOURCC_Y210;
>          return AV_PIX_FMT_Y210;
> -#endif
>  #endif
>      default:
>          return AVERROR(ENOSYS);
> @@ -438,9 +418,7 @@ int ff_qsv_init_internal_session(AVCodecContext
> *avctx, QSVSession *qs,
>      const char *desc;
>      int ret;
> 
> -#if QSV_VERSION_ATLEAST(1, 16)
>      init_par.GPUCopy        = gpu_copy;
> -#endif
>      init_par.Implementation = impl;
>      init_par.Version        = ver;
>      ret = MFXInitEx(init_par, &qs->session);
> @@ -791,9 +769,7 @@ int ff_qsv_init_session_device(AVCodecContext *avctx,
> mfxSession *psession,
>                 "from the session\n");
>      }
> 
> -#if QSV_VERSION_ATLEAST(1, 16)
>      init_par.GPUCopy        = gpu_copy;
> -#endif
>      init_par.Implementation = impl;
>      init_par.Version        = ver;
>      err = MFXInitEx(init_par, &session);
> diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
> index fbb22ca436..b6242bf4c8 100644
> --- a/libavcodec/qsvenc.c
> +++ b/libavcodec/qsvenc.c
> @@ -53,14 +53,10 @@ static const struct profile_names avc_profiles[] = {
>      { MFX_PROFILE_AVC_MAIN,                     "avc main"
> },
>      { MFX_PROFILE_AVC_EXTENDED,                 "avc extended"
> },
>      { MFX_PROFILE_AVC_HIGH,                     "avc high"
> },
> -#if QSV_VERSION_ATLEAST(1, 15)
>      { MFX_PROFILE_AVC_HIGH_422,                 "avc high 422"
> },
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 4)
>      { MFX_PROFILE_AVC_CONSTRAINED_BASELINE,     "avc constrained
> baseline"  },
>      { MFX_PROFILE_AVC_CONSTRAINED_HIGH,         "avc constrained high"
> },
>      { MFX_PROFILE_AVC_PROGRESSIVE_HIGH,         "avc progressive high"
> },
> -#endif
>  };
> 
>  static const struct profile_names mpeg2_profiles[] = {
> @@ -70,24 +66,20 @@ static const struct profile_names mpeg2_profiles[] = {
>  };
> 
>  static const struct profile_names hevc_profiles[] = {
> -#if QSV_VERSION_ATLEAST(1, 8)
>      { MFX_PROFILE_HEVC_MAIN,                    "hevc main"
> },
>      { MFX_PROFILE_HEVC_MAIN10,                  "hevc main10"
> },
>      { MFX_PROFILE_HEVC_MAINSP,                  "hevc mainsp"
> },
>      { MFX_PROFILE_HEVC_REXT,                    "hevc rext"
> },
> -#endif
>  #if QSV_VERSION_ATLEAST(1, 32)
>      { MFX_PROFILE_HEVC_SCC,                     "hevc scc"
> },
>  #endif
>  };
> 
>  static const struct profile_names vp9_profiles[] = {
> -#if QSV_VERSION_ATLEAST(1, 19)
>      { MFX_PROFILE_VP9_0,                        "vp9 0"
> },
>      { MFX_PROFILE_VP9_1,                        "vp9 1"
> },
>      { MFX_PROFILE_VP9_2,                        "vp9 2"
> },
>      { MFX_PROFILE_VP9_3,                        "vp9 3"
> },
> -#endif
>  };
> 
>  typedef struct QSVPacket {
> @@ -143,25 +135,15 @@ static const struct {
>  #if QSV_HAVE_AVBR
>      { MFX_RATECONTROL_AVBR,    "AVBR" },
>  #endif
> -#if QSV_HAVE_LA
>      { MFX_RATECONTROL_LA,      "LA" },
> -#endif
> -#if QSV_HAVE_ICQ
>      { MFX_RATECONTROL_ICQ,     "ICQ" },
>      { MFX_RATECONTROL_LA_ICQ,  "LA_ICQ" },
> -#endif
>  #if QSV_HAVE_VCM
>      { MFX_RATECONTROL_VCM,     "VCM" },
>  #endif
> -#if QSV_VERSION_ATLEAST(1, 10)
>      { MFX_RATECONTROL_LA_EXT,  "LA_EXT" },
> -#endif
> -#if QSV_HAVE_LA_HRD
>      { MFX_RATECONTROL_LA_HRD,  "LA_HRD" },
> -#endif
> -#if QSV_HAVE_QVBR
>      { MFX_RATECONTROL_QVBR,    "QVBR" },
> -#endif
>  };
> 
>  static const char *print_ratecontrol(mfxU16 rc_mode)
> @@ -187,16 +169,20 @@ static void dump_video_param(AVCodecContext *avctx,
> QSVEncContext *q,
>  {
>      mfxInfoMFX *info = &q->param.mfx;
> 
> -    mfxExtCodingOption   *co = (mfxExtCodingOption*)coding_opts[0];
> -#if QSV_HAVE_CO2
> -    mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
> -#endif
> -#if QSV_HAVE_CO3
> -    mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];
> -#endif
> -#if QSV_HAVE_EXT_HEVC_TILES
> -    mfxExtHEVCTiles *exthevctiles = (mfxExtHEVCTiles *)coding_opts[3 +
> QSV_HAVE_CO_VPS];
> -#endif
> +    // co is always at index 1
> +    mfxExtCodingOption   *co = (mfxExtCodingOption*)coding_opts[1];
> +    mfxExtCodingOption2 *co2 = NULL;
> +    mfxExtCodingOption3 *co3 = NULL;
> +    mfxExtHEVCTiles *exthevctiles = NULL;
> +
> +    if (q->co2_idx > 0)
> +        co2 = (mfxExtCodingOption2*)coding_opts[q->co2_idx];
> +
> +    if (q->co3_idx > 0)
> +        co3 = (mfxExtCodingOption3*)coding_opts[q->co3_idx];
> +
> +    if (q->exthevctiles_idx > 0)
> +        exthevctiles = (mfxExtHEVCTiles *)coding_opts[q-
> >exthevctiles_idx];
> 
>      av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",
>             print_profile(avctx->codec_id, info->CodecProfile), info-
> >CodecLevel);
> @@ -221,11 +207,6 @@ static void dump_video_param(AVCodecContext *avctx,
> QSVEncContext *q,
>          av_log(avctx, AV_LOG_VERBOSE,
>                 "BufferSizeInKB: %"PRIu16"; InitialDelayInKB: %"PRIu16";
> TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"; BRCParamMultiplier:
> %"PRIu16"\n",
>                 info->BufferSizeInKB, info->InitialDelayInKB, info-
> >TargetKbps, info->MaxKbps, info->BRCParamMultiplier);
> -#if QSV_HAVE_LA
> -        if (info->RateControlMethod == MFX_RATECONTROL_VBR && q->extbrc
> && q->look_ahead_depth > 0 ) {
> -            av_log(avctx, AV_LOG_VERBOSE, "LookAheadDepth:
> %"PRIu16"\n",co2->LookAheadDepth);
> -        }
> -#endif
>      } else if (info->RateControlMethod == MFX_RATECONTROL_CQP) {
>          av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16";
> QPB: %"PRIu16"\n",
>                 info->QPI, info->QPP, info->QPB);
> @@ -237,117 +218,25 @@ static void dump_video_param(AVCodecContext *avctx,
> QSVEncContext *q,
>                 info->TargetKbps, info->Accuracy, info->Convergence, info-
> >BRCParamMultiplier);
>      }
>  #endif
> -#if QSV_HAVE_LA
>      else if (info->RateControlMethod == MFX_RATECONTROL_LA
> -#if QSV_HAVE_LA_HRD
>               || info->RateControlMethod == MFX_RATECONTROL_LA_HRD
> -#endif
>               ) {
>          av_log(avctx, AV_LOG_VERBOSE,
> -               "TargetKbps: %"PRIu16"; LookAheadDepth: %"PRIu16";
> BRCParamMultiplier: %"PRIu16"\n",
> -               info->TargetKbps, co2->LookAheadDepth, info-
> >BRCParamMultiplier);
> +               "TargetKbps: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
> +               info->TargetKbps, info->BRCParamMultiplier);
>      }
> -#endif
> -#if QSV_HAVE_ICQ
>      else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {
>          av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info-
> >ICQQuality);
>      } else if (info->RateControlMethod == MFX_RATECONTROL_LA_ICQ) {
> -        av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16";
> LookAheadDepth: %"PRIu16"\n",
> -               info->ICQQuality, co2->LookAheadDepth);
> -    }
> -#endif
> -#if QSV_HAVE_QVBR
> -    else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {
> -        av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
> -               co3->QVBRQuality);
> +        av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info-
> >ICQQuality);

This branch is now identical with the previous one. But I wouldn't 
mind leaving it like this as it's better readable.

Probably somebody will mind the curly brace formatting around else if,
though.


>      }
> -#endif
>      av_log(avctx, AV_LOG_VERBOSE, "NumSlice: %"PRIu16"; NumRefFrame:
> %"PRIu16"\n",
>             info->NumSlice, info->NumRefFrame);
>      av_log(avctx, AV_LOG_VERBOSE, "RateDistortionOpt: %s\n",
>             print_threestate(co->RateDistortionOpt));
> 
> -#if QSV_HAVE_EXT_HEVC_TILES
> -    if (avctx->codec_id == AV_CODEC_ID_HEVC)
> -        av_log(avctx, AV_LOG_VERBOSE, "NumTileColumns: %"PRIu16";
> NumTileRows: %"PRIu16"\n",
> -               exthevctiles->NumTileColumns, exthevctiles->NumTileRows);
> -#endif
> -
> -#if QSV_HAVE_CO2
> -    av_log(avctx, AV_LOG_VERBOSE,
> -           "RecoveryPointSEI: %s IntRefType: %"PRIu16"; IntRefCycleSize:
> %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
> -           print_threestate(co->RecoveryPointSEI), co2->IntRefType, co2-
> >IntRefCycleSize, co2->IntRefQPDelta);
> -
> -    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2-
> >MaxFrameSize);
> -#if QSV_HAVE_MAX_SLICE_SIZE
> -    av_log(avctx, AV_LOG_VERBOSE, "MaxSliceSize: %d; ", co2-
> >MaxSliceSize);
> -#endif
> -    av_log(avctx, AV_LOG_VERBOSE, "\n");
> -
> -    av_log(avctx, AV_LOG_VERBOSE,
> -           "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
> -           print_threestate(co2->BitrateLimit), print_threestate(co2-
> >MBBRC),
> -           print_threestate(co2->ExtBRC));
> -
> -#if QSV_HAVE_TRELLIS
> -    av_log(avctx, AV_LOG_VERBOSE, "Trellis: ");
> -    if (co2->Trellis & MFX_TRELLIS_OFF) {
> -        av_log(avctx, AV_LOG_VERBOSE, "off");
> -    } else if (!co2->Trellis) {
> -        av_log(avctx, AV_LOG_VERBOSE, "auto");
> -    } else {
> -        if (co2->Trellis & MFX_TRELLIS_I) av_log(avctx, AV_LOG_VERBOSE,
> "I");
> -        if (co2->Trellis & MFX_TRELLIS_P) av_log(avctx, AV_LOG_VERBOSE,
> "P");
> -        if (co2->Trellis & MFX_TRELLIS_B) av_log(avctx, AV_LOG_VERBOSE,
> "B");
> -    }
> -    av_log(avctx, AV_LOG_VERBOSE, "\n");
> -#endif
> -
> -#if QSV_HAVE_VDENC
> +    av_log(avctx, AV_LOG_VERBOSE, "RecoveryPointSEI: %s\n",
> print_threestate(co->RecoveryPointSEI));
>      av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", print_threestate(info-
> >LowPower));
> -#endif
> -
> -#if QSV_VERSION_ATLEAST(1, 8)
> -    av_log(avctx, AV_LOG_VERBOSE,
> -           "RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
> -           print_threestate(co2->RepeatPPS), co2->NumMbPerSlice);
> -    switch (co2->LookAheadDS) {
> -    case MFX_LOOKAHEAD_DS_OFF: av_log(avctx, AV_LOG_VERBOSE, "off");
> break;
> -    case MFX_LOOKAHEAD_DS_2x:  av_log(avctx, AV_LOG_VERBOSE, "2x");
> break;
> -    case MFX_LOOKAHEAD_DS_4x:  av_log(avctx, AV_LOG_VERBOSE, "4x");
> break;
> -    default:                   av_log(avctx, AV_LOG_VERBOSE, "unknown");
> break;
> -    }
> -    av_log(avctx, AV_LOG_VERBOSE, "\n");
> -
> -    av_log(avctx, AV_LOG_VERBOSE, "AdaptiveI: %s; AdaptiveB: %s;
> BRefType: ",
> -           print_threestate(co2->AdaptiveI), print_threestate(co2-
> >AdaptiveB));
> -    switch (co2->BRefType) {
> -    case MFX_B_REF_OFF:     av_log(avctx, AV_LOG_VERBOSE, "off");
> break;
> -    case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");
> break;
> -    default:                av_log(avctx, AV_LOG_VERBOSE, "auto");
> break;
> -    }
> -
> -    av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
> -    switch (co3->PRefType) {
> -    case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");
> break;
> -    case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");
> break;
> -    case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");
> break;
> -    default:                av_log(avctx, AV_LOG_VERBOSE, "unknown");
> break;
> -    }
> -    av_log(avctx, AV_LOG_VERBOSE, "\n");
> -#endif
> -
> -#if QSV_VERSION_ATLEAST(1, 9)
> -    av_log(avctx, AV_LOG_VERBOSE,
> -           "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP:
> %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
> -           co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2-
> >MinQPB, co2->MaxQPB);
> -#endif
> -#endif
> -
> -#if QSV_HAVE_GPB
> -    if (avctx->codec_id == AV_CODEC_ID_HEVC)
> -        av_log(avctx, AV_LOG_VERBOSE,"GPB: %s\n", print_threestate(co3-
> >GPB));
> -#endif
> 
>      if (avctx->codec_id == AV_CODEC_ID_H264) {
>          av_log(avctx, AV_LOG_VERBOSE, "Entropy coding: %s;
> MaxDecFrameBuffering: %"PRIu16"\n",
> @@ -365,36 +254,103 @@ static void dump_video_param(AVCodecContext *avctx,
> QSVEncContext *q,
>      av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32";
> FrameRateExtN: %"PRIu32" \n",
>             info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
> 
> -#if QSV_HAVE_DISABLEDEBLOCKIDC
> -    av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n",
> co2->DisableDeblockingIdc);
> -#endif
> +    if (co2) {
> +        if ((info->RateControlMethod == MFX_RATECONTROL_VBR && q->extbrc
> && q->look_ahead_depth > 0) ||
> +            (info->RateControlMethod == MFX_RATECONTROL_LA) ||
> +            (info->RateControlMethod == MFX_RATECONTROL_LA_HRD) ||
> +            (info->RateControlMethod == MFX_RATECONTROL_LA_ICQ))
> +            av_log(avctx, AV_LOG_VERBOSE, "LookAheadDepth: %"PRIu16"\n",
> co2->LookAheadDepth);
> 
> -#if QSV_VERSION_ATLEAST(1, 26)
> -    av_log(avctx, AV_LOG_VERBOSE, "TransformSkip: %s \n",
> print_threestate(co3->TransformSkip));
> -#endif
> +        av_log(avctx, AV_LOG_VERBOSE, "IntRefType: %"PRIu16";
> IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
> +               co2->IntRefType, co2->IntRefCycleSize, co2-
> >IntRefQPDelta);
> 
> -#if QSV_VERSION_ATLEAST(1, 16)
> -    av_log(avctx, AV_LOG_VERBOSE, "IntRefCycleDist: %"PRId16"\n", co3-
> >IntRefCycleDist);
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 23)
> -    av_log(avctx, AV_LOG_VERBOSE, "LowDelayBRC: %s\n",
> print_threestate(co3->LowDelayBRC));
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 19)
> -    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeI: %d; ", co3-
> >MaxFrameSizeI);
> -    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeP: %d\n", co3-
> >MaxFrameSizeP);
> -#endif
> +        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2-
> >MaxFrameSize);
> +        av_log(avctx, AV_LOG_VERBOSE, "MaxSliceSize: %d; ", co2-
> >MaxSliceSize);
> +        av_log(avctx, AV_LOG_VERBOSE, "\n");
> +
> +        av_log(avctx, AV_LOG_VERBOSE,
> +               "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
> +               print_threestate(co2->BitrateLimit), print_threestate(co2-
> >MBBRC),
> +               print_threestate(co2->ExtBRC));
> +
> +        av_log(avctx, AV_LOG_VERBOSE, "Trellis: ");
> +        if (co2->Trellis & MFX_TRELLIS_OFF) {
> +            av_log(avctx, AV_LOG_VERBOSE, "off");
> +        } else if (!co2->Trellis) {
> +            av_log(avctx, AV_LOG_VERBOSE, "auto");
> +        } else {
> +            if (co2->Trellis & MFX_TRELLIS_I) av_log(avctx,
> AV_LOG_VERBOSE, "I");
> +            if (co2->Trellis & MFX_TRELLIS_P) av_log(avctx,
> AV_LOG_VERBOSE, "P");
> +            if (co2->Trellis & MFX_TRELLIS_B) av_log(avctx,
> AV_LOG_VERBOSE, "B");
> +        }
> +        av_log(avctx, AV_LOG_VERBOSE, "\n");
> +
> +        av_log(avctx, AV_LOG_VERBOSE,
> +               "RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
> +               print_threestate(co2->RepeatPPS), co2->NumMbPerSlice);
> +        switch (co2->LookAheadDS) {
> +        case MFX_LOOKAHEAD_DS_OFF: av_log(avctx, AV_LOG_VERBOSE, "off");
> break;
> +        case MFX_LOOKAHEAD_DS_2x:  av_log(avctx, AV_LOG_VERBOSE, "2x");
> break;
> +        case MFX_LOOKAHEAD_DS_4x:  av_log(avctx, AV_LOG_VERBOSE, "4x");
> break;
> +        default:                   av_log(avctx, AV_LOG_VERBOSE,
> "unknown"); break;
> +        }
> +        av_log(avctx, AV_LOG_VERBOSE, "\n");
> +
> +        av_log(avctx, AV_LOG_VERBOSE, "AdaptiveI: %s; AdaptiveB: %s;
> BRefType: ",
> +               print_threestate(co2->AdaptiveI), print_threestate(co2-
> >AdaptiveB));
> +        switch (co2->BRefType) {
> +        case MFX_B_REF_OFF:     av_log(avctx, AV_LOG_VERBOSE, "off");
> break;
> +        case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");
> break;
> +        default:                av_log(avctx, AV_LOG_VERBOSE, "auto");
> break;
> +        }
> +
> +        av_log(avctx, AV_LOG_VERBOSE,
> +               "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8";
> MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
> +               co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2-
> >MinQPB, co2->MaxQPB);
> +        av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32"
> \n", co2->DisableDeblockingIdc);
> +    }
> +
> +    if (co3) {
> +        if (info->RateControlMethod == MFX_RATECONTROL_QVBR)
> +            av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
> co3->QVBRQuality);
> +
> +        av_log(avctx, AV_LOG_VERBOSE, "PRefType: ");
> +        switch (co3->PRefType) {
> +        case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");
> break;
> +        case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");
> break;
> +        case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");
> break;
> +        default:                av_log(avctx, AV_LOG_VERBOSE, "unknown");
> break;
> +        }
> +        av_log(avctx, AV_LOG_VERBOSE, "\n");
> +
> +        if (avctx->codec_id == AV_CODEC_ID_HEVC)
> +            av_log(avctx, AV_LOG_VERBOSE,"GPB: %s\n",
> print_threestate(co3->GPB));
> +
> +        av_log(avctx, AV_LOG_VERBOSE, "TransformSkip: %s \n",
> print_threestate(co3->TransformSkip));
> +        av_log(avctx, AV_LOG_VERBOSE, "IntRefCycleDist: %"PRId16"\n",
> co3->IntRefCycleDist);
> +        av_log(avctx, AV_LOG_VERBOSE, "LowDelayBRC: %s\n",
> print_threestate(co3->LowDelayBRC));
> +        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeI: %d; ", co3-
> >MaxFrameSizeI);
> +        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeP: %d\n", co3-
> >MaxFrameSizeP);
> +    }
> +
> +    if (exthevctiles) {
> +        av_log(avctx, AV_LOG_VERBOSE, "NumTileColumns: %"PRIu16";
> NumTileRows: %"PRIu16"\n",
> +               exthevctiles->NumTileColumns, exthevctiles->NumTileRows);
> +    }
>  }
> 
>  static void dump_video_vp9_param(AVCodecContext *avctx, QSVEncContext *q,
>                                   mfxExtBuffer **coding_opts)
>  {
>      mfxInfoMFX *info = &q->param.mfx;
> -#if QSV_HAVE_EXT_VP9_PARAM
> -    mfxExtVP9Param *vp9_param = (mfxExtVP9Param *)coding_opts[0];
> -#endif
> -#if QSV_HAVE_CO2
> -    mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
> -#endif
> +    mfxExtVP9Param *vp9_param = NULL;
> +    mfxExtCodingOption2 *co2 = NULL;
> +
> +    if (q->vp9_idx >= 0)
> +        vp9_param = (mfxExtVP9Param *)coding_opts[q->vp9_idx];
> +
> +    if (q->co2_idx >= 0)
> +        co2 = (mfxExtCodingOption2*)coding_opts[q->co2_idx];
> 
>      av_log(avctx, AV_LOG_VERBOSE, "profile: %s \n",
>             print_profile(avctx->codec_id, info->CodecProfile));
> @@ -419,48 +375,41 @@ static void dump_video_vp9_param(AVCodecContext
> *avctx, QSVEncContext *q,
>          av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16";
> QPB: %"PRIu16"\n",
>                 info->QPI, info->QPP, info->QPB);
>      }
> -#if QSV_HAVE_ICQ
>      else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {
>          av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info-
> >ICQQuality);
>      }
> -#endif
>      else {
>          av_log(avctx, AV_LOG_VERBOSE, "Unsupported ratecontrol method: %d
> \n", info->RateControlMethod);
>      }
> 
>      av_log(avctx, AV_LOG_VERBOSE, "NumRefFrame: %"PRIu16"\n", info-
> >NumRefFrame);
> +    av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32";
> FrameRateExtN: %"PRIu32" \n",
> +           info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
> 
> -#if QSV_HAVE_CO2
> -    av_log(avctx, AV_LOG_VERBOSE,
> -           "IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16";
> IntRefQPDelta: %"PRId16"\n",
> -           co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
> +    if (co2) {
> +        av_log(avctx, AV_LOG_VERBOSE,
> +               "IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16";
> IntRefQPDelta: %"PRId16"\n",
> +               co2->IntRefType, co2->IntRefCycleSize, co2-
> >IntRefQPDelta);
> 
> -    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2-
> >MaxFrameSize);
> -    av_log(avctx, AV_LOG_VERBOSE, "\n");
> +        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2-
> >MaxFrameSize);
> +        av_log(avctx, AV_LOG_VERBOSE, "\n");
> 
> -    av_log(avctx, AV_LOG_VERBOSE,
> -           "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
> -           print_threestate(co2->BitrateLimit), print_threestate(co2-
> >MBBRC),
> -           print_threestate(co2->ExtBRC));
> +        av_log(avctx, AV_LOG_VERBOSE,
> +               "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
> +               print_threestate(co2->BitrateLimit), print_threestate(co2-
> >MBBRC),
> +               print_threestate(co2->ExtBRC));
> 
> -#if QSV_HAVE_VDENC
> -    av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", print_threestate(info-
> >LowPower));
> -#endif
> +        av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n",
> print_threestate(info->LowPower));
> 
> -#if QSV_VERSION_ATLEAST(1, 9)
> -    av_log(avctx, AV_LOG_VERBOSE,
> -           "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP:
> %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
> -           co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2-
> >MinQPB, co2->MaxQPB);
> -#endif
> -#endif
> -
> -    av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32";
> FrameRateExtN: %"PRIu32" \n",
> -           info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
> +        av_log(avctx, AV_LOG_VERBOSE,
> +               "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8";
> MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
> +               co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2-
> >MinQPB, co2->MaxQPB);
> +    }
> 
> -#if QSV_HAVE_EXT_VP9_PARAM
> -    av_log(avctx, AV_LOG_VERBOSE, "WriteIVFHeaders: %s \n",
> -           print_threestate(vp9_param->WriteIVFHeaders));
> -#endif
> +    if (vp9_param) {
> +        av_log(avctx, AV_LOG_VERBOSE, "WriteIVFHeaders: %s \n",
> +               print_threestate(vp9_param->WriteIVFHeaders));
> +    }
>  }
> 
>  static void dump_video_mjpeg_param(AVCodecContext *avctx, QSVEncContext
> *q)
> @@ -484,11 +433,6 @@ static int select_rc_mode(AVCodecContext *avctx,
> QSVEncContext *q)
>      int want_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
>      int want_vcm    = q->vcm;
> 
> -    if (want_la && !QSV_HAVE_LA) {
> -        av_log(avctx, AV_LOG_ERROR,
> -               "Lookahead ratecontrol mode requested, but is not
> supported by this SDK version\n");
> -        return AVERROR(ENOSYS);
> -    }
>      if (want_vcm && !QSV_HAVE_VCM) {
>          av_log(avctx, AV_LOG_ERROR,
>                 "VCM ratecontrol mode requested, but is not supported by
> this SDK version\n");
> @@ -502,12 +446,6 @@ static int select_rc_mode(AVCodecContext *avctx,
> QSVEncContext *q)
>          return AVERROR(EINVAL);
>      }
> 
> -    if (!want_qscale && avctx->global_quality > 0 && !QSV_HAVE_ICQ){
> -        av_log(avctx, AV_LOG_ERROR,
> -               "ICQ ratecontrol mode requested, but is not supported by
> this SDK version\n");
> -        return AVERROR(ENOSYS);
> -    }
> -
>      if (want_qscale) {
>          rc_mode = MFX_RATECONTROL_CQP;
>          rc_desc = "constant quantization parameter (CQP)";
> @@ -518,25 +456,19 @@ static int select_rc_mode(AVCodecContext *avctx,
> QSVEncContext *q)
>          rc_desc = "video conferencing mode (VCM)";
>      }
>  #endif
> -#if QSV_HAVE_LA
>      else if (want_la) {
>          rc_mode = MFX_RATECONTROL_LA;
>          rc_desc = "VBR with lookahead (LA)";
> 
> -#if QSV_HAVE_ICQ
>          if (avctx->global_quality > 0) {
>              rc_mode = MFX_RATECONTROL_LA_ICQ;
>              rc_desc = "intelligent constant quality with lookahead
> (LA_ICQ)";
>          }
> -#endif
>      }
> -#endif
> -#if QSV_HAVE_ICQ
>      else if (avctx->global_quality > 0 && !avctx->rc_max_rate) {
>          rc_mode = MFX_RATECONTROL_ICQ;
>          rc_desc = "intelligent constant quality (ICQ)";
>      }
> -#endif
>      else if (avctx->rc_max_rate == avctx->bit_rate) {
>          rc_mode = MFX_RATECONTROL_CBR;
>          rc_desc = "constant bitrate (CBR)";
> @@ -547,12 +479,10 @@ static int select_rc_mode(AVCodecContext *avctx,
> QSVEncContext *q)
>          rc_desc = "average variable bitrate (AVBR)";
>      }
>  #endif
> -#if QSV_HAVE_QVBR
>      else if (avctx->global_quality > 0) {
>          rc_mode = MFX_RATECONTROL_QVBR;
>          rc_desc = "constant quality with VBR algorithm (QVBR)";
>      }
> -#endif
>      else {
>          rc_mode = MFX_RATECONTROL_VBR;
>          rc_desc = "variable bitrate (VBR)";
> @@ -692,14 +622,7 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>      }
> 
>      if (q->low_power == 1) {
> -#if QSV_HAVE_VDENC
>          q->param.mfx.LowPower = MFX_CODINGOPTION_ON;
> -#else
> -        av_log(avctx, AV_LOG_WARNING, "The low_power option is "
> -                            "not supported with this MSDK version.\n");
> -        q->low_power = 0;
> -        q->param.mfx.LowPower = MFX_CODINGOPTION_OFF;
> -#endif
>      } else if (q->low_power == -1)
>          q->param.mfx.LowPower = MFX_CODINGOPTION_UNKNOWN;
>      else
> @@ -789,26 +712,20 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>      switch (q->param.mfx.RateControlMethod) {
>      case MFX_RATECONTROL_CBR:
>      case MFX_RATECONTROL_VBR:
> -#if QSV_HAVE_LA
>          if (q->extbrc) {
>              q->extco2.LookAheadDepth = q->look_ahead_depth;
>          }
> -#endif
>  #if QSV_HAVE_VCM
>      case MFX_RATECONTROL_VCM:
>  #endif
> -#if QSV_HAVE_QVBR
>      case MFX_RATECONTROL_QVBR:
> -#endif
>          q->param.mfx.BufferSizeInKB   = buffer_size_in_kilobytes /
> brc_param_multiplier;
>          q->param.mfx.InitialDelayInKB = initial_delay_in_kilobytes /
> brc_param_multiplier;
>          q->param.mfx.TargetKbps       = target_bitrate_kbps /
> brc_param_multiplier;
>          q->param.mfx.MaxKbps          = max_bitrate_kbps /
> brc_param_multiplier;
>          q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
> -#if QSV_HAVE_QVBR
>          if (q->param.mfx.RateControlMethod == MFX_RATECONTROL_QVBR)
>              q->extco3.QVBRQuality = av_clip(avctx->global_quality, 0,
> 51);
> -#endif
>          break;
>      case MFX_RATECONTROL_CQP:
>          quant = avctx->global_quality / FF_QP2LAMBDA;
> @@ -826,20 +743,16 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>          q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
>          break;
>  #endif
> -#if QSV_HAVE_LA
>      case MFX_RATECONTROL_LA:
>          q->param.mfx.TargetKbps  = target_bitrate_kbps /
> brc_param_multiplier;
>          q->extco2.LookAheadDepth = q->look_ahead_depth;
>          q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
>          break;
> -#if QSV_HAVE_ICQ
>      case MFX_RATECONTROL_LA_ICQ:
>          q->extco2.LookAheadDepth = q->look_ahead_depth;
>      case MFX_RATECONTROL_ICQ:
>          q->param.mfx.ICQQuality  = av_clip(avctx->global_quality, 1, 51);
>          break;
> -#endif
> -#endif
>      }
> 
>      // The HEVC encoder plugin currently fails with some old libmfx
> version if coding options
> @@ -883,19 +796,15 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
> 
>          q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer
> *)&q->extco;
> 
> -#if QSV_HAVE_CO2
>          if (avctx->codec_id == AV_CODEC_ID_H264) {
>              if (q->bitrate_limit >= 0)
>                  q->extco2.BitrateLimit = q->bitrate_limit ?
> MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
> 
> -#if QSV_HAVE_TRELLIS
>              if (avctx->trellis >= 0)
>                  q->extco2.Trellis = (avctx->trellis == 0) ?
> MFX_TRELLIS_OFF : (MFX_TRELLIS_I | MFX_TRELLIS_P | MFX_TRELLIS_B);
>              else
>                  q->extco2.Trellis = MFX_TRELLIS_UNKNOWN;
> -#endif
> 
> -#if QSV_VERSION_ATLEAST(1, 8)
>              q->extco2.LookAheadDS = q->look_ahead_downsampling;
>              q->extco2.RepeatPPS   = q->repeat_pps ? MFX_CODINGOPTION_ON :
> MFX_CODINGOPTION_OFF;
> 
> @@ -903,7 +812,6 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>                  q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON
> : MFX_CODINGOPTION_OFF;
>              if (q->adaptive_b >= 0)
>                  q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON
> : MFX_CODINGOPTION_OFF;
> -#endif
>          }
> 
>          if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id ==
> AV_CODEC_ID_HEVC) {
> @@ -917,19 +825,12 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>                  q->extco2.IntRefCycleSize = q->int_ref_cycle_size;
>              if (q->int_ref_qp_delta != INT16_MIN)
>                  q->extco2.IntRefQPDelta = q->int_ref_qp_delta;
> -#if QSV_HAVE_MAX_SLICE_SIZE
>              if (q->max_slice_size >= 0)
>                  q->extco2.MaxSliceSize = q->max_slice_size;
> -#endif
> -#if QSV_HAVE_DISABLEDEBLOCKIDC
>              q->extco2.DisableDeblockingIdc = q->dblk_idc;
> -#endif
> 
> -#if QSV_VERSION_ATLEAST(1, 8)
>              if (q->b_strategy >= 0)
>                  q->extco2.BRefType = q->b_strategy ? MFX_B_REF_PYRAMID :
> MFX_B_REF_OFF;
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 9)
>              if (avctx->qmin >= 0 && avctx->qmax >= 0 && avctx->qmin >
> avctx->qmax) {
>                  av_log(avctx, AV_LOG_ERROR, "qmin and or qmax are set but
> invalid, please make sure min <= max\n");
>                  return AVERROR(EINVAL);
> @@ -942,7 +843,6 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>                  q->extco2.MaxQPI = avctx->qmax > 51 ? 51 : avctx->qmax;
>                  q->extco2.MaxQPP = q->extco2.MaxQPB = q->extco2.MaxQPI;
>              }
> -#endif
>              if (q->mbbrc >= 0)
>                  q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON :
> MFX_CODINGOPTION_OFF;
> 
> @@ -951,7 +851,6 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
> 
>              q->extparam_internal[q->nb_extparam_internal++] =
> (mfxExtBuffer *)&q->extco2;
>          }
> -#endif
> 
>          if (avctx->codec_id == AV_CODEC_ID_H264) {
>  #if QSV_HAVE_MF
> @@ -965,13 +864,11 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>              }
>  #endif
>          }
> -#if QSV_HAVE_CO3
>          q->extco3.Header.BufferId      = MFX_EXTBUFF_CODING_OPTION3;
>          q->extco3.Header.BufferSz      = sizeof(q->extco3);
> 
>          if (avctx->codec_id == AV_CODEC_ID_HEVC ||
>              avctx->codec_id == AV_CODEC_ID_H264) {
> -#if QSV_HAVE_PREF
>              switch (q->p_strategy) {
>              case 0:
>                  q->extco3.PRefType = MFX_P_REF_DEFAULT;
> @@ -993,40 +890,27 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>                  av_log(avctx, AV_LOG_WARNING,
>                         "Please set max_b_frames(-bf) to 0 to enable P-
> pyramid\n");
>              }
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 16)
>              if (q->int_ref_cycle_dist >= 0)
>                  q->extco3.IntRefCycleDist = q->int_ref_cycle_dist;
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 23)
>              if (q->low_delay_brc >= 0)
>                  q->extco3.LowDelayBRC = q->low_delay_brc ?
> MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 19)
>              if (q->max_frame_size_i >= 0)
>                  q->extco3.MaxFrameSizeI = q->max_frame_size_i;
>              if (q->max_frame_size_p >= 0)
>                  q->extco3.MaxFrameSizeP = q->max_frame_size_p;
> -#endif
>          }
> 
>          if (avctx->codec_id == AV_CODEC_ID_HEVC) {
> -#if QSV_VERSION_ATLEAST(1, 26)
>              if (q->transform_skip >= 0)
>                  q->extco3.TransformSkip = q->transform_skip ?
> MFX_CODINGOPTION_ON :
> 
> MFX_CODINGOPTION_OFF;
>              else
>                  q->extco3.TransformSkip = MFX_CODINGOPTION_UNKNOWN;
> -#endif
> -#if QSV_HAVE_GPB
>              q->extco3.GPB              = q->gpb ? MFX_CODINGOPTION_ON :
> MFX_CODINGOPTION_OFF;
> -#endif
>          }
>          q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer
> *)&q->extco3;
> -#endif
>      }
> 
> -#if QSV_HAVE_EXT_VP9_PARAM
>      if (avctx->codec_id == AV_CODEC_ID_VP9) {
>          q->extvp9param.Header.BufferId = MFX_EXTBUFF_VP9_PARAM;
>          q->extvp9param.Header.BufferSz = sizeof(q->extvp9param);
> @@ -1037,9 +921,7 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>  #endif
>          q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer
> *)&q->extvp9param;
>      }
> -#endif
> 
> -#if QSV_HAVE_EXT_HEVC_TILES
>      if (avctx->codec_id == AV_CODEC_ID_HEVC) {
>          q->exthevctiles.Header.BufferId = MFX_EXTBUFF_HEVC_TILES;
>          q->exthevctiles.Header.BufferSz = sizeof(q->exthevctiles);
> @@ -1047,7 +929,6 @@ static int init_video_param(AVCodecContext *avctx,
> QSVEncContext *q)
>          q->exthevctiles.NumTileRows     = q->tile_rows;
>          q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer
> *)&q->exthevctiles;
>      }
> -#endif
> 
>      q->extvsi.VideoFullRange = (avctx->color_range == AVCOL_RANGE_JPEG);
>      q->extvsi.ColourDescriptionPresent = 0;
> @@ -1100,41 +981,44 @@ static int
> qsv_retrieve_enc_jpeg_params(AVCodecContext *avctx, QSVEncContext *q)
>  static int qsv_retrieve_enc_vp9_params(AVCodecContext *avctx,
> QSVEncContext *q)
>  {
>      int ret = 0;
> -#if QSV_HAVE_EXT_VP9_PARAM
>      mfxExtVP9Param vp9_extend_buf = {
>           .Header.BufferId = MFX_EXTBUFF_VP9_PARAM,
>           .Header.BufferSz = sizeof(vp9_extend_buf),
>      };
> -#endif
> 
> -#if QSV_HAVE_CO2
>      mfxExtCodingOption2 co2 = {
>          .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
>          .Header.BufferSz = sizeof(co2),
>      };
> -#endif
> 
> -#if QSV_HAVE_CO3
>      mfxExtCodingOption3 co3 = {
>          .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
>          .Header.BufferSz = sizeof(co3),
>      };
> -#endif
> 
> -    mfxExtBuffer *ext_buffers[] = {
> -#if QSV_HAVE_EXT_VP9_PARAM
> -        (mfxExtBuffer*)&vp9_extend_buf,
> -#endif
> -#if QSV_HAVE_CO2
> -        (mfxExtBuffer*)&co2,
> -#endif
> -#if QSV_HAVE_CO3
> -        (mfxExtBuffer*)&co3,
> -#endif
> -    };
> +    mfxExtBuffer *ext_buffers[3];
> +    int ext_buf_num = 0;
> +
> +    q->co2_idx = q->co3_idx = q->vp9_idx = -1;
> +
> +    // It is possible the runtime doesn't support the given ext buffer
> +    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 6)) {
> +        q->co2_idx = ext_buf_num;
> +        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co2;
> +    }
> +
> +    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 11)) {
> +        q->co3_idx = ext_buf_num;
> +        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co3;
> +    }
> +
> +    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 26)) {
> +        q->vp9_idx = ext_buf_num;
> +        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&vp9_extend_buf;
> +    }
> 
>      q->param.ExtParam    = ext_buffers;
> -    q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
> +    q->param.NumExtParam = ext_buf_num;
> 
>      ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
>      if (ret < 0)
> @@ -1166,20 +1050,15 @@ static int qsv_retrieve_enc_params(AVCodecContext
> *avctx, QSVEncContext *q)
>          .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
>          .Header.BufferSz = sizeof(co),
>      };
> -#if QSV_HAVE_CO2
>      mfxExtCodingOption2 co2 = {
>          .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
>          .Header.BufferSz = sizeof(co2),
>      };
> -#endif
> -#if QSV_HAVE_CO3
>      mfxExtCodingOption3 co3 = {
>          .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
>          .Header.BufferSz = sizeof(co3),
>      };
> -#endif
> 
> -#if QSV_HAVE_CO_VPS
>      uint8_t vps_buf[128];
>      mfxExtCodingOptionVPS extradata_vps = {
>          .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_VPS,
> @@ -1187,37 +1066,39 @@ static int qsv_retrieve_enc_params(AVCodecContext
> *avctx, QSVEncContext *q)
>          .VPSBuffer       = vps_buf,
>          .VPSBufSize      = sizeof(vps_buf),
>      };
> -#endif
> 
> -#if QSV_HAVE_EXT_HEVC_TILES
>      mfxExtHEVCTiles hevc_tile_buf = {
>           .Header.BufferId = MFX_EXTBUFF_HEVC_TILES,
>           .Header.BufferSz = sizeof(hevc_tile_buf),
>      };
> -#endif
> 
> -    mfxExtBuffer *ext_buffers[2 + QSV_HAVE_CO2 + QSV_HAVE_CO3 +
> QSV_HAVE_CO_VPS + QSV_HAVE_EXT_HEVC_TILES];
> +    mfxExtBuffer *ext_buffers[6];
> 
>      int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
>      int ret, ext_buf_num = 0, extradata_offset = 0;
> 
> +    q->co2_idx = q->co3_idx = q->exthevctiles_idx = -1;
>      ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&extradata;
>      ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co;
> -#if QSV_HAVE_CO2
> -    ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co2;
> -#endif
> -#if QSV_HAVE_CO3
> -    ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co3;
> -#endif
> -#if QSV_HAVE_CO_VPS
> +
> +    // It is possible the runtime doesn't support the given ext buffer
> +    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 6)) {
> +        q->co2_idx = ext_buf_num;
> +        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co2;
> +    }
> +
> +    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 11)) {
> +        q->co3_idx = ext_buf_num;
> +        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co3;
> +    }
> +
>      q->hevc_vps = ((avctx->codec_id == AV_CODEC_ID_HEVC) &&
> QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 17));
>      if (q->hevc_vps)
>          ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&extradata_vps;
> -#endif
> -#if QSV_HAVE_EXT_HEVC_TILES
> -    if (avctx->codec_id == AV_CODEC_ID_HEVC)
> +    if (avctx->codec_id == AV_CODEC_ID_HEVC &&
> QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 13)) {
> +        q->exthevctiles_idx = ext_buf_num;
>          ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&hevc_tile_buf;
> -#endif
> +    }
> 
>      q->param.ExtParam    = ext_buffers;
>      q->param.NumExtParam = ext_buf_num;
> @@ -1230,29 +1111,23 @@ static int qsv_retrieve_enc_params(AVCodecContext
> *avctx, QSVEncContext *q)
>      q->packet_size = q->param.mfx.BufferSizeInKB * q-
> >param.mfx.BRCParamMultiplier * 1000;
> 
>      if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)
> -#if QSV_HAVE_CO_VPS
>          || (q->hevc_vps && !extradata_vps.VPSBufSize)
> -#endif
>      ) {
>          av_log(avctx, AV_LOG_ERROR, "No extradata returned from
> libmfx.\n");
>          return AVERROR_UNKNOWN;
>      }
> 
>      avctx->extradata_size = extradata.SPSBufSize + need_pps *
> extradata.PPSBufSize;
> -#if QSV_HAVE_CO_VPS
>      avctx->extradata_size += q->hevc_vps * extradata_vps.VPSBufSize;
> -#endif
> 
>      avctx->extradata = av_malloc(avctx->extradata_size +
> AV_INPUT_BUFFER_PADDING_SIZE);
>      if (!avctx->extradata)
>          return AVERROR(ENOMEM);
> 
> -#if QSV_HAVE_CO_VPS
>      if (q->hevc_vps) {
>          memcpy(avctx->extradata, vps_buf, extradata_vps.VPSBufSize);
>          extradata_offset += extradata_vps.VPSBufSize;
>      }
> -#endif
> 
>      memcpy(avctx->extradata + extradata_offset, sps_buf,
> extradata.SPSBufSize);
>      extradata_offset += extradata.SPSBufSize;
> @@ -1270,7 +1145,7 @@ static int qsv_retrieve_enc_params(AVCodecContext
> *avctx, QSVEncContext *q)
>      cpb_props->avg_bitrate = avctx->bit_rate;
>      cpb_props->buffer_size = avctx->rc_buffer_size;
> 
> -    dump_video_param(avctx, q, ext_buffers + 1);
> +    dump_video_param(avctx, q, ext_buffers);
> 
>      return 0;
>  }
> @@ -1652,10 +1527,8 @@ static int encode_frame(AVCodecContext *avctx,
> QSVEncContext *q,
>                          const AVFrame *frame)
>  {
>      QSVPacket pkt = { { 0 } };
> -#if QSV_VERSION_ATLEAST(1, 26)
>      mfxExtAVCEncodedFrameInfo *enc_info = NULL;
>      mfxExtBuffer **enc_buf = NULL;
> -#endif
> 
>      mfxFrameSurface1 *surf = NULL;
>      QSVFrame *qsv_frame = NULL;
> @@ -1692,7 +1565,6 @@ static int encode_frame(AVCodecContext *avctx,
> QSVEncContext *q,
>      pkt.bs->Data      = pkt.pkt.data;
>      pkt.bs->MaxLength = pkt.pkt.size;
> 
> -#if QSV_VERSION_ATLEAST(1, 26)
>      if (avctx->codec_id == AV_CODEC_ID_H264) {
>          enc_info = av_mallocz(sizeof(*enc_info));
>          if (!enc_info)
> @@ -1708,7 +1580,6 @@ static int encode_frame(AVCodecContext *avctx,
> QSVEncContext *q,
> 
>          pkt.bs->ExtParam = enc_buf;
>      }
> -#endif
> 
>      if (q->set_encode_ctrl_cb) {
>          q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
> @@ -1745,12 +1616,10 @@ free:
>          av_freep(&pkt.sync);
>          av_packet_unref(&pkt.pkt);
>          av_freep(&pkt.bs);
> -#if QSV_VERSION_ATLEAST(1, 26)
>          if (avctx->codec_id == AV_CODEC_ID_H264) {
>              av_freep(&enc_info);
>              av_freep(&enc_buf);
>          }
> -#endif
>      }
> 
>      return ret;
> @@ -1771,10 +1640,8 @@ int ff_qsv_encode(AVCodecContext *avctx,
> QSVEncContext *q,
>      if ((av_fifo_can_read(q->async_fifo) >= q->async_depth) ||
>          (!frame && av_fifo_can_read(q->async_fifo))) {
>          QSVPacket qpkt;
> -#if QSV_VERSION_ATLEAST(1, 26)
>          mfxExtAVCEncodedFrameInfo *enc_info;
>          mfxExtBuffer **enc_buf;
> -#endif
>          enum AVPictureType pict_type;
> 
>          av_fifo_read(q->async_fifo, &qpkt, 1);
> @@ -1804,7 +1671,6 @@ int ff_qsv_encode(AVCodecContext *avctx,
> QSVEncContext *q,
>              return AVERROR_INVALIDDATA;
>          }
> 
> -#if QSV_VERSION_ATLEAST(1, 26)
>          if (avctx->codec_id == AV_CODEC_ID_H264) {
>              enc_buf = qpkt.bs->ExtParam;
>              enc_info = (mfxExtAVCEncodedFrameInfo *)(*enc_buf);
> @@ -1813,7 +1679,6 @@ int ff_qsv_encode(AVCodecContext *avctx,
> QSVEncContext *q,
>              av_freep(&enc_info);
>              av_freep(&enc_buf);
>          }
> -#endif
>          av_freep(&qpkt.bs);
>          av_freep(&qpkt.sync);
> 
> @@ -1850,14 +1715,12 @@ int ff_qsv_enc_close(AVCodecContext *avctx,
> QSVEncContext *q)
>      if (q->async_fifo) {
>          QSVPacket pkt;
>          while (av_fifo_read(q->async_fifo, &pkt, 1) >= 0) {
> -#if QSV_VERSION_ATLEAST(1, 26)
>              if (avctx->codec_id == AV_CODEC_ID_H264) {
>                  mfxExtBuffer **enc_buf = pkt.bs->ExtParam;
>                  mfxExtAVCEncodedFrameInfo *enc_info =
> (mfxExtAVCEncodedFrameInfo *)(*enc_buf);
>                  av_freep(&enc_info);
>                  av_freep(&enc_buf);
>              }
> -#endif
>              av_freep(&pkt.sync);
>              av_freep(&pkt.bs);
>              av_packet_unref(&pkt.pkt);
> diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
> index cb84723dfa..a0edd3ec17 100644
> --- a/libavcodec/qsvenc.h
> +++ b/libavcodec/qsvenc.h
> @@ -35,46 +35,16 @@
>  #include "hwconfig.h"
>  #include "qsv_internal.h"
> 
> -#define QSV_HAVE_CO2 QSV_VERSION_ATLEAST(1, 6)
> -#define QSV_HAVE_CO3 QSV_VERSION_ATLEAST(1, 11)
> -#define QSV_HAVE_CO_VPS  QSV_VERSION_ATLEAST(1, 17)
> -
> -#define QSV_HAVE_EXT_HEVC_TILES QSV_VERSION_ATLEAST(1, 13)
> -#define QSV_HAVE_EXT_VP9_PARAM QSV_VERSION_ATLEAST(1, 26)
>  #define QSV_HAVE_EXT_VP9_TILES QSV_VERSION_ATLEAST(1, 29)
> 
> -#define QSV_HAVE_TRELLIS QSV_VERSION_ATLEAST(1, 8)
> -#define QSV_HAVE_MAX_SLICE_SIZE QSV_VERSION_ATLEAST(1, 9)
> -#define QSV_HAVE_DISABLEDEBLOCKIDC QSV_VERSION_ATLEAST(1, 9)
> -#define QSV_HAVE_BREF_TYPE      QSV_VERSION_ATLEAST(1, 8)
> -
> -#define QSV_HAVE_LA     QSV_VERSION_ATLEAST(1, 7)
> -#define QSV_HAVE_LA_DS  QSV_VERSION_ATLEAST(1, 8)
> -#define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
> -#define QSV_HAVE_VDENC  QSV_VERSION_ATLEAST(1, 15)
> -#define QSV_HAVE_PREF   QSV_VERSION_ATLEAST(1, 16)
> -
> -#define QSV_HAVE_GPB    QSV_VERSION_ATLEAST(1, 18)
> -
>  #if defined(_WIN32) || defined(__CYGWIN__)
> -#define QSV_HAVE_AVBR   QSV_VERSION_ATLEAST(1, 3)
> -#define QSV_HAVE_ICQ    QSV_VERSION_ATLEAST(1, 8)
> -#define QSV_HAVE_VCM    QSV_VERSION_ATLEAST(1, 8)
> -#define QSV_HAVE_QVBR   QSV_VERSION_ATLEAST(1, 11)
> +#define QSV_HAVE_AVBR   1
> +#define QSV_HAVE_VCM    1
>  #define QSV_HAVE_MF     0
>  #else
>  #define QSV_HAVE_AVBR   0
> -#define QSV_HAVE_ICQ    QSV_VERSION_ATLEAST(1, 28)
>  #define QSV_HAVE_VCM    0
> -#define QSV_HAVE_QVBR   QSV_VERSION_ATLEAST(1, 28)
> -#define QSV_HAVE_MF     QSV_VERSION_ATLEAST(1, 25)
> -#endif
> -
> -#if !QSV_HAVE_LA_DS
> -#define MFX_LOOKAHEAD_DS_UNKNOWN 0
> -#define MFX_LOOKAHEAD_DS_OFF 0
> -#define MFX_LOOKAHEAD_DS_2x 0
> -#define MFX_LOOKAHEAD_DS_4x 0
> +#define QSV_HAVE_MF     1
>  #endif
> 
>  #define QSV_COMMON_OPTS \
> @@ -126,22 +96,14 @@ typedef struct QSVEncContext {
>      mfxFrameAllocRequest req;
> 
>      mfxExtCodingOption  extco;
> -#if QSV_HAVE_CO2
>      mfxExtCodingOption2 extco2;
> -#endif
> -#if QSV_HAVE_CO3
>      mfxExtCodingOption3 extco3;
> -#endif
>  #if QSV_HAVE_MF
>      mfxExtMultiFrameParam   extmfp;
>      mfxExtMultiFrameControl extmfc;
>  #endif
> -#if QSV_HAVE_EXT_HEVC_TILES
>      mfxExtHEVCTiles exthevctiles;
> -#endif
> -#if QSV_HAVE_EXT_VP9_PARAM
>      mfxExtVP9Param  extvp9param;
> -#endif
> 
>      mfxExtOpaqueSurfaceAlloc opaque_alloc;
>      mfxFrameSurface1       **opaque_surfaces;
> @@ -149,7 +111,7 @@ typedef struct QSVEncContext {
> 
>      mfxExtVideoSignalInfo extvsi;
> 
> -    mfxExtBuffer  *extparam_internal[3 + QSV_HAVE_CO2 + QSV_HAVE_CO3 +
> (QSV_HAVE_MF * 2)];
> +    mfxExtBuffer  *extparam_internal[5 + (QSV_HAVE_MF * 2)];
>      int         nb_extparam_internal;
> 
>      mfxExtBuffer **extparam;
> @@ -218,6 +180,11 @@ typedef struct QSVEncContext {
>      SetEncodeCtrlCB *set_encode_ctrl_cb;
>      int forced_idr;
>      int low_delay_brc;
> +
> +    int co2_idx;
> +    int co3_idx;
> +    int exthevctiles_idx;
> +    int vp9_idx;
>  } QSVEncContext;
> 
>  int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
> diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
> index b4cf9ea456..6470e9977d 100644
> --- a/libavcodec/qsvenc_h264.c
> +++ b/libavcodec/qsvenc_h264.c
> @@ -112,11 +112,8 @@ static const AVOption options[] = {
>      { "single_sei_nal_unit",    "Put all the SEI messages into one NALU",
> OFFSET(qsv.single_sei_nal_unit),     AV_OPT_TYPE_INT, { .i64 = -1 }, -1,
> 1, VE },
>      { "max_dec_frame_buffering", "Maximum number of frames buffered in
> the DPB", OFFSET(qsv.max_dec_frame_buffering), AV_OPT_TYPE_INT, { .i64 = 0
> },   0, UINT16_MAX, VE },
> 
> -#if QSV_HAVE_LA
>      { "look_ahead",       "Use VBR algorithm with look ahead",
> OFFSET(qsv.look_ahead),       AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
>      { "look_ahead_depth", "Depth of look ahead in number frames",
> OFFSET(qsv.look_ahead_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, VE },
> -#endif
> -#if QSV_HAVE_LA_DS
>      { "look_ahead_downsampling", "Downscaling factor for the frames saved
> for the lookahead analysis", OFFSET(qsv.look_ahead_downsampling),
>                                            AV_OPT_TYPE_INT,   { .i64 =
> MFX_LOOKAHEAD_DS_UNKNOWN }, MFX_LOOKAHEAD_DS_UNKNOWN, MFX_LOOKAHEAD_DS_4x,
> VE, "look_ahead_downsampling" },
>      { "unknown"                , NULL, 0, AV_OPT_TYPE_CONST, { .i64 =
> MFX_LOOKAHEAD_DS_UNKNOWN }, INT_MIN, INT_MAX,     VE,
> "look_ahead_downsampling" },
> @@ -124,7 +121,6 @@ static const AVOption options[] = {
>      { "off"                    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 =
> MFX_LOOKAHEAD_DS_OFF     }, INT_MIN, INT_MAX,     VE,
> "look_ahead_downsampling" },
>      { "2x"                     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 =
> MFX_LOOKAHEAD_DS_2x      }, INT_MIN, INT_MAX,     VE,
> "look_ahead_downsampling" },
>      { "4x"                     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 =
> MFX_LOOKAHEAD_DS_4x      }, INT_MIN, INT_MAX,     VE,
> "look_ahead_downsampling" },
> -#endif
> 
>      { "int_ref_type", "Intra refresh type. B frames should be set to 0.",
> OFFSET(qsv.int_ref_type),            AV_OPT_TYPE_INT, { .i64 = -1 }, -1,
> UINT16_MAX, VE, "int_ref_type" },
>          { "none",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags =
> VE, "int_ref_type" },
> @@ -133,9 +129,7 @@ static const AVOption options[] = {
>      { "int_ref_cycle_size", "Number of frames in the intra refresh
> cycle",       OFFSET(qsv.int_ref_cycle_size),      AV_OPT_TYPE_INT, { .i64
> = -1 },               -1, UINT16_MAX, VE },
>      { "int_ref_qp_delta",   "QP difference for the refresh MBs",
> OFFSET(qsv.int_ref_qp_delta),        AV_OPT_TYPE_INT, { .i64 = INT16_MIN
> }, INT16_MIN,  INT16_MAX, VE },
>      { "recovery_point_sei", "Insert recovery point SEI messages",
> OFFSET(qsv.recovery_point_sei),      AV_OPT_TYPE_INT, { .i64 = -1 },
> -1,          1, VE },
> -#if QSV_VERSION_ATLEAST(1, 16)
>      { "int_ref_cycle_dist",   "Distance between the beginnings of the
> intra-refresh cycles in frames",  OFFSET(qsv.int_ref_cycle_dist),
> AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
> -#endif
>      { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 =
> MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" },
>      { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 =
> MFX_PROFILE_UNKNOWN      }, INT_MIN, INT_MAX,     VE, "profile" },
>      { "baseline", NULL, 0, AV_OPT_TYPE_CONST, { .i64 =
> MFX_PROFILE_AVC_BASELINE }, INT_MIN, INT_MAX,     VE, "profile" },
> diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
> index 3a2d50e332..36d12ff06a 100644
> --- a/libavcodec/qsvenc_hevc.c
> +++ b/libavcodec/qsvenc_hevc.c
> @@ -235,9 +235,7 @@ static const AVOption options[] = {
>      { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to
> load in an internal session",
>          OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0,
> 0, VE },
> 
> -#if QSV_HAVE_LA
>      { "look_ahead_depth", "Depth of look ahead in number frames,
> available when extbrc option is enabled", OFFSET(qsv.look_ahead_depth),
> AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, VE },
> -#endif
>      { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 =
> MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" },
>      { "unknown", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN
> }, INT_MIN, INT_MAX,     VE, "profile" },
>      { "main",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 =
> MFX_PROFILE_HEVC_MAIN    }, INT_MIN, INT_MAX,     VE, "profile" },
> @@ -255,18 +253,14 @@ static const AVOption options[] = {
>      { "recovery_point_sei", "Insert recovery point SEI messages",
> OFFSET(qsv.recovery_point_sei),      AV_OPT_TYPE_INT, { .i64 = -1 },
> -1,          1, VE },
>      { "aud", "Insert the Access Unit Delimiter NAL", OFFSET(qsv.aud),
> AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
>      { "pic_timing_sei",    "Insert picture timing SEI with
> pic_struct_syntax element", OFFSET(qsv.pic_timing_sei), AV_OPT_TYPE_BOOL,
> { .i64 = 1 }, 0, 1, VE },
> -#if QSV_VERSION_ATLEAST(1, 26)
>      { "transform_skip", "Turn this option ON to enable transformskip",
> OFFSET(qsv.transform_skip),          AV_OPT_TYPE_INT,    { .i64 = -1},   -
> 1, 1,  VE},
> -#endif
>      { "int_ref_type", "Intra refresh type. B frames should be set to 0",
> OFFSET(qsv.int_ref_type),            AV_OPT_TYPE_INT, { .i64 = -1 }, -1,
> UINT16_MAX, VE, "int_ref_type" },
>          { "none",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags =
> VE, "int_ref_type" },
>          { "vertical", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .flags =
> VE, "int_ref_type" },
>          { "horizontal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, .flags
> = VE, "int_ref_type" },
>      { "int_ref_cycle_size", "Number of frames in the intra refresh
> cycle",       OFFSET(qsv.int_ref_cycle_size),      AV_OPT_TYPE_INT, { .i64
> = -1 },               -1, UINT16_MAX, VE },
>      { "int_ref_qp_delta",   "QP difference for the refresh MBs",
> OFFSET(qsv.int_ref_qp_delta),        AV_OPT_TYPE_INT, { .i64 = INT16_MIN
> }, INT16_MIN,  INT16_MAX, VE },
> -#if QSV_VERSION_ATLEAST(1, 16)
>      { "int_ref_cycle_dist",   "Distance between the beginnings of the
> intra-refresh cycles in frames",  OFFSET(qsv.int_ref_cycle_dist),
> AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
> -#endif
> 
>      { NULL },
>  };
> @@ -306,12 +300,8 @@ const FFCodec ff_hevc_qsv_encoder = {
>                                                      AV_PIX_FMT_YUYV422,
>                                                      AV_PIX_FMT_Y210,
>                                                      AV_PIX_FMT_QSV,
> -#if QSV_VERSION_ATLEAST(1, 17)
>                                                      AV_PIX_FMT_BGRA,
> -#endif
> -#if QSV_VERSION_ATLEAST(1, 9)
>                                                      AV_PIX_FMT_X2RGB10,
> -#endif
>                                                      AV_PIX_FMT_NONE },
>      .p.priv_class   = &class,
>      .defaults       = qsv_enc_defaults,
> diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c
> index 371f629457..da3c2eca86 100644
> --- a/libavfilter/vf_scale_qsv.c
> +++ b/libavfilter/vf_scale_qsv.c
> @@ -69,7 +69,6 @@ enum var_name {
>      VARS_NB
>  };
> 
> -#define QSV_HAVE_SCALING_CONFIG  QSV_VERSION_ATLEAST(1, 19)
>  #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
> 
>  typedef struct QSVScaleContext {
> @@ -92,12 +91,10 @@ typedef struct QSVScaleContext {
> 
>      mfxExtOpaqueSurfaceAlloc opaque_alloc;
> 
> -#if QSV_HAVE_SCALING_CONFIG
>      mfxExtVPPScaling         scale_conf;
> -#endif
>      int                      mode;
> 
> -    mfxExtBuffer             *ext_buffers[1 + QSV_HAVE_SCALING_CONFIG];
> +    mfxExtBuffer             *ext_buffers[2];
>      int                      num_ext_buf;
> 
>      int shift_width, shift_height;
> @@ -397,14 +394,12 @@ static int init_out_session(AVFilterContext *ctx)
>          par.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY |
> MFX_IOPATTERN_OUT_VIDEO_MEMORY;
>      }
> 
> -#if QSV_HAVE_SCALING_CONFIG
>      memset(&s->scale_conf, 0, sizeof(mfxExtVPPScaling));
>      s->scale_conf.Header.BufferId     = MFX_EXTBUFF_VPP_SCALING;
>      s->scale_conf.Header.BufferSz     = sizeof(mfxExtVPPScaling);
>      s->scale_conf.ScalingMode         = s->mode;
>      s->ext_buffers[s->num_ext_buf++]  = (mfxExtBuffer*)&s->scale_conf;
>      av_log(ctx, AV_LOG_VERBOSE, "Scaling mode: %d\n", s->mode);
> -#endif
> 
>      par.ExtParam    = s->ext_buffers;
>      par.NumExtParam = s->num_ext_buf;
> @@ -620,15 +615,9 @@ static const AVOption options[] = {
>      { "h",      "Output video height", OFFSET(h_expr),
> AV_OPT_TYPE_STRING, { .str = "ih"   }, .flags = FLAGS },
>      { "format", "Output pixel format", OFFSET(format_str),
> AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
> 
> -#if QSV_HAVE_SCALING_CONFIG
>      { "mode",      "set scaling mode",    OFFSET(mode),
> AV_OPT_TYPE_INT,    { .i64 = MFX_SCALING_MODE_DEFAULT},
> MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, FLAGS, "mode"},
>      { "low_power", "low power mode",        0,
> AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX,
> FLAGS, "mode"},
>      { "hq",        "high quality mode",     0,
> AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_QUALITY},  INT_MIN, INT_MAX,
> FLAGS, "mode"},
> -#else
> -    { "mode",      "(not supported)",     OFFSET(mode),
> AV_OPT_TYPE_INT,    { .i64 = 0}, 0, INT_MAX, FLAGS, "mode"},
> -    { "low_power", "",                      0,
> AV_OPT_TYPE_CONST,  { .i64 = 1}, 0,   0,     FLAGS, "mode"},
> -    { "hq",        "",                      0,
> AV_OPT_TYPE_CONST,  { .i64 = 2}, 0,   0,     FLAGS, "mode"},
> -#endif
> 
>      { NULL },
>  };
> diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
> index cfe343822b..6e5056d133 100644
> --- a/libavfilter/vf_vpp_qsv.c
> +++ b/libavfilter/vf_vpp_qsv.c
> @@ -43,9 +43,6 @@
> 
>  /* number of video enhancement filters */
>  #define ENH_FILTERS_COUNT (8)
> -#define QSV_HAVE_ROTATION       QSV_VERSION_ATLEAST(1, 17)
> -#define QSV_HAVE_MIRRORING      QSV_VERSION_ATLEAST(1, 19)
> -#define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19)
> 
>  typedef struct VPPContext{
>      const AVClass *class;
> @@ -60,9 +57,7 @@ typedef struct VPPContext{
>      mfxExtVPPProcAmp procamp_conf;
>      mfxExtVPPRotation rotation_conf;
>      mfxExtVPPMirroring mirroring_conf;
> -#ifdef QSV_HAVE_SCALING_CONFIG
>      mfxExtVPPScaling scale_conf;
> -#endif
> 
>      int out_width;
>      int out_height;
> @@ -138,9 +133,7 @@ static const AVOption options[] = {
>      { "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, {
> .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
>      { "format", "Output pixel format", OFFSET(output_format_str),
> AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
>      { "async_depth", "Internal parallelization depth, the higher the
> value the higher the latency.", OFFSET(async_depth), AV_OPT_TYPE_INT, {
> .i64 = 0 }, 0, INT_MAX, .flags = FLAGS },
> -#ifdef QSV_HAVE_SCALING_CONFIG
>      { "scale_mode", "scale mode: 0=auto, 1=low power, 2=high quality",
> OFFSET(scale_mode), AV_OPT_TYPE_INT, { .i64 = MFX_SCALING_MODE_DEFAULT },
> MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, .flags = FLAGS, "scale
> mode" },
> -#endif
>      { NULL }
>  };
> 
> @@ -422,84 +415,83 @@ static int config_output(AVFilterLink *outlink)
>      }
> 
>      if (vpp->transpose >= 0) {
> -#ifdef QSV_HAVE_ROTATION
> -        switch (vpp->transpose) {
> -        case TRANSPOSE_CCLOCK_FLIP:
> -            vpp->rotate = MFX_ANGLE_270;
> -            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> -            break;
> -        case TRANSPOSE_CLOCK:
> -            vpp->rotate = MFX_ANGLE_90;
> -            vpp->hflip  = MFX_MIRRORING_DISABLED;
> -            break;
> -        case TRANSPOSE_CCLOCK:
> -            vpp->rotate = MFX_ANGLE_270;
> -            vpp->hflip  = MFX_MIRRORING_DISABLED;
> -            break;
> -        case TRANSPOSE_CLOCK_FLIP:
> -            vpp->rotate = MFX_ANGLE_90;
> -            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> -            break;
> -        case TRANSPOSE_REVERSAL:
> -            vpp->rotate = MFX_ANGLE_180;
> -            vpp->hflip  = MFX_MIRRORING_DISABLED;
> -            break;
> -        case TRANSPOSE_HFLIP:
> -            vpp->rotate = MFX_ANGLE_0;
> -            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> -            break;
> -        case TRANSPOSE_VFLIP:
> -            vpp->rotate = MFX_ANGLE_180;
> -            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> -            break;
> -        default:
> -            av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode to
> %d.\n", vpp->transpose);
> -            return AVERROR(EINVAL);
> +        if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 17)) {
> +            switch (vpp->transpose) {
> +            case TRANSPOSE_CCLOCK_FLIP:
> +                vpp->rotate = MFX_ANGLE_270;
> +                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> +                break;
> +            case TRANSPOSE_CLOCK:
> +                vpp->rotate = MFX_ANGLE_90;
> +                vpp->hflip  = MFX_MIRRORING_DISABLED;
> +                break;
> +            case TRANSPOSE_CCLOCK:
> +                vpp->rotate = MFX_ANGLE_270;
> +                vpp->hflip  = MFX_MIRRORING_DISABLED;
> +                break;
> +            case TRANSPOSE_CLOCK_FLIP:
> +                vpp->rotate = MFX_ANGLE_90;
> +                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> +                break;
> +            case TRANSPOSE_REVERSAL:
> +                vpp->rotate = MFX_ANGLE_180;
> +                vpp->hflip  = MFX_MIRRORING_DISABLED;
> +                break;
> +            case TRANSPOSE_HFLIP:
> +                vpp->rotate = MFX_ANGLE_0;
> +                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> +                break;
> +            case TRANSPOSE_VFLIP:
> +                vpp->rotate = MFX_ANGLE_180;
> +                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
> +                break;
> +            default:
> +                av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode
> to %d.\n", vpp->transpose);
> +                return AVERROR(EINVAL);
> +            }
> +        } else {
> +            av_log(ctx, AV_LOG_WARNING, "The QSV VPP transpose option is
> "
> +                   "not supported with this MSDK version.\n");
> +            vpp->transpose = 0;
>          }
> -#else
> -        av_log(ctx, AV_LOG_WARNING, "The QSV VPP transpose option is "
> -            "not supported with this MSDK version.\n");
> -        vpp->transpose = 0;
> -#endif
>      }
> 
>      if (vpp->rotate) {
> -#ifdef QSV_HAVE_ROTATION
> -        memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
> -        vpp->rotation_conf.Header.BufferId  = MFX_EXTBUFF_VPP_ROTATION;
> -        vpp->rotation_conf.Header.BufferSz  = sizeof(mfxExtVPPRotation);
> -        vpp->rotation_conf.Angle = vpp->rotate;
> -
> -        if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate)
> {
> -            FFSWAP(int, vpp->out_width, vpp->out_height);
> -            FFSWAP(int, outlink->w, outlink->h);
> -            av_log(ctx, AV_LOG_DEBUG, "Swap width and height for
> clock/cclock rotation.\n");
> -        }
> +        if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 17)) {
> +            memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
> +            vpp->rotation_conf.Header.BufferId  =
> MFX_EXTBUFF_VPP_ROTATION;
> +            vpp->rotation_conf.Header.BufferSz  =
> sizeof(mfxExtVPPRotation);
> +            vpp->rotation_conf.Angle = vpp->rotate;
> +
> +            if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp-
> >rotate) {
> +                FFSWAP(int, vpp->out_width, vpp->out_height);
> +                FFSWAP(int, outlink->w, outlink->h);
> +                av_log(ctx, AV_LOG_DEBUG, "Swap width and height for
> clock/cclock rotation.\n");
> +            }
> 
> -        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp-
> >rotation_conf;
> -#else
> -        av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
> -            "not supported with this MSDK version.\n");
> -        vpp->rotate = 0;
> -#endif
> +            param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp-
> >rotation_conf;
> +        } else {
> +            av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
> +                   "not supported with this MSDK version.\n");
> +            vpp->rotate = 0;
> +        }
>      }
> 
>      if (vpp->hflip) {
> -#ifdef QSV_HAVE_MIRRORING
> -        memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
> -        vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
> -        vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
> -        vpp->mirroring_conf.Type = vpp->hflip;
> -
> -        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp-
> >mirroring_conf;
> -#else
> -        av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
> -            "not supported with this MSDK version.\n");
> -        vpp->hflip = 0;
> -#endif
> +        if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 19)) {
> +            memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
> +            vpp->mirroring_conf.Header.BufferId =
> MFX_EXTBUFF_VPP_MIRRORING;
> +            vpp->mirroring_conf.Header.BufferSz =
> sizeof(mfxExtVPPMirroring);
> +            vpp->mirroring_conf.Type = vpp->hflip;
> +
> +            param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp-
> >mirroring_conf;
> +        } else {
> +            av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
> +                   "not supported with this MSDK version.\n");
> +            vpp->hflip = 0;
> +        }
>      }
> 
> -#ifdef QSV_HAVE_SCALING_CONFIG
>      if (inlink->w != outlink->w || inlink->h != outlink->h) {
>          if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 19)) {
>              memset(&vpp->scale_conf, 0, sizeof(mfxExtVPPScaling));
> @@ -512,7 +504,6 @@ static int config_output(AVFilterLink *outlink)
>              av_log(ctx, AV_LOG_WARNING, "The QSV VPP Scale option is "
>                  "not supported with this MSDK version.\n");
>      }
> -#endif
> 
>      if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise
> ||
>          vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip ||
> diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
> index 66c0e38955..dde9db2d67 100644
> --- a/libavutil/hwcontext_qsv.c
> +++ b/libavutil/hwcontext_qsv.c
> @@ -106,11 +106,9 @@ static const struct {
>  #if CONFIG_VAAPI
>      { AV_PIX_FMT_YUYV422,
>                         MFX_FOURCC_YUY2 },
> -#if QSV_VERSION_ATLEAST(1, 27)
>      { AV_PIX_FMT_Y210,
>                         MFX_FOURCC_Y210 },
>  #endif
> -#endif
>  };
> 
>  extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf,
> --

LGTM. This patch is a great improvement to the qsv code as it is dropping
a lot of old and unnecessary clutter.

Thanks,
softworkz
Xiang, Haihao May 24, 2022, 8:46 a.m. UTC | #3
> > -----Original Message-----
> > From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Haihao
> > Xiang
> > Sent: Sunday, May 22, 2022 2:19 PM
> > To: ffmpeg-devel@ffmpeg.org
> > Cc: Haihao Xiang <haihao.xiang@intel.com>
> > Subject: [FFmpeg-devel] [PATCH] qsv: add requirement for the mininal
> > version of libmfx
> > 
> > libmfx 1.28 was released 3 years ago, it is easy to get a greater
> > version than 1.28. We may remove lots of compile-time checks if adding
> > the requirement for the minimal version in the configure script.
> > ---

[...]
> > LookAheadDepth: %"PRIu16"\n",
> > -               info->ICQQuality, co2->LookAheadDepth);
> > -    }
> > -#endif
> > -#if QSV_HAVE_QVBR
> > -    else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {
> > -        av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
> > -               co3->QVBRQuality);
> > +        av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info-
> > > ICQQuality);
> 
> This branch is now identical with the previous one. But I wouldn't 
> mind leaving it like this as it's better readable.
> 
> Probably somebody will mind the curly brace formatting around else if,
> though.
> 

Thanks for pointing it out. I'll change it when merging the patch.

[...]
> 
> LGTM. This patch is a great improvement to the qsv code as it is dropping
> a lot of old and unnecessary clutter.
> 

Thanks for reviewing this patch. I'll applying it if no more comment. 

BRs
Haihao
Timo Rothenpieler May 25, 2022, 4:05 p.m. UTC | #4
On 22/05/2022 14:19, Haihao Xiang wrote:
> libmfx 1.28 was released 3 years ago, it is easy to get a greater
> version than 1.28. We may remove lots of compile-time checks if adding
> the requirement for the minimal version in the configure script.
> ---
>   configure                  |   7 +-
>   libavcodec/qsv.c           |  24 --
>   libavcodec/qsvenc.c        | 471 +++++++++++++------------------------
>   libavcodec/qsvenc.h        |  51 +---
>   libavcodec/qsvenc_h264.c   |   6 -
>   libavcodec/qsvenc_hevc.c   |  10 -
>   libavfilter/vf_scale_qsv.c |  13 +-
>   libavfilter/vf_vpp_qsv.c   | 143 ++++++-----
>   libavutil/hwcontext_qsv.c  |   2 -
>   9 files changed, 249 insertions(+), 478 deletions(-)
> 
> diff --git a/configure b/configure
> index f115b21064..2337f0a8f2 100755
> --- a/configure
> +++ b/configure
> @@ -6566,8 +6566,11 @@ enabled liblensfun        && require_pkg_config liblensfun lensfun lensfun.h lf_
>   # Media SDK or Intel Media Server Studio, these don't come with
>   # pkg-config support.  Instead, users should make sure that the build
>   # can find the libraries and headers through other means.
> -enabled libmfx            && { check_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit ||
> -                               { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } }
> +enabled libmfx            && { check_pkg_config libmfx "mfx >= 1.28" "mfx/mfxvideo.h" MFXInit ||
> +                               { require libmfx "mfx/mfxvideo.h mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&

This broke build with mfx_dispatch. Before this, it checked for 
libmfx.pc. Now it checks for mfx.pc, which is not installed by it.

Which of those is correct? It should definitely not drop support for 
libmfx.pc, which was checked before this.
Leo Izen May 25, 2022, 4:22 p.m. UTC | #5
On 5/25/22 12:05, Timo Rothenpieler wrote:
> 
> 
> On 22/05/2022 14:19, Haihao Xiang wrote:
>> libmfx 1.28 was released 3 years ago, it is easy to get a greater
>> version than 1.28. We may remove lots of compile-time checks if adding
>> the requirement for the minimal version in the configure script.
>> ---
>>   configure                  |   7 +-
>>   libavcodec/qsv.c           |  24 --
>>   libavcodec/qsvenc.c        | 471 +++++++++++++------------------------
>>   libavcodec/qsvenc.h        |  51 +---
>>   libavcodec/qsvenc_h264.c   |   6 -
>>   libavcodec/qsvenc_hevc.c   |  10 -
>>   libavfilter/vf_scale_qsv.c |  13 +-
>>   libavfilter/vf_vpp_qsv.c   | 143 ++++++-----
>>   libavutil/hwcontext_qsv.c  |   2 -
>>   9 files changed, 249 insertions(+), 478 deletions(-)
>>
>> diff --git a/configure b/configure
>> index f115b21064..2337f0a8f2 100755
>> --- a/configure
>> +++ b/configure
>> @@ -6566,8 +6566,11 @@ enabled liblensfun        && require_pkg_config 
>> liblensfun lensfun lensfun.h lf_
>>   # Media SDK or Intel Media Server Studio, these don't come with
>>   # pkg-config support.  Instead, users should make sure that the build
>>   # can find the libraries and headers through other means.
>> -enabled libmfx            && { check_pkg_config libmfx libmfx 
>> "mfx/mfxvideo.h" MFXInit ||
>> -                               { require libmfx "mfx/mfxvideo.h" 
>> MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without 
>> pkg-config"; } }
>> +enabled libmfx            && { check_pkg_config libmfx "mfx >= 1.28" 
>> "mfx/mfxvideo.h" MFXInit ||
>> +                               { require libmfx "mfx/mfxvideo.h 
>> mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
> 
> This broke build with mfx_dispatch. Before this, it checked for 
> libmfx.pc. Now it checks for mfx.pc, which is not installed by it.
> 
> Which of those is correct? It should definitely not drop support for 
> libmfx.pc, which was checked before this.

It also attempts to link to -llibmfx, which means liblibmfx.so. I'm 
guessing it's supposed to link to -lmfx instead.

- Leo Izen (thebombzen)
Xiang, Haihao May 26, 2022, 12:39 a.m. UTC | #6
On Wed, 2022-05-25 at 18:05 +0200, Timo Rothenpieler wrote:
> 
> On 22/05/2022 14:19, Haihao Xiang wrote:
> > libmfx 1.28 was released 3 years ago, it is easy to get a greater
> > version than 1.28. We may remove lots of compile-time checks if adding
> > the requirement for the minimal version in the configure script.
> > ---
> >   configure                  |   7 +-
> >   libavcodec/qsv.c           |  24 --
> >   libavcodec/qsvenc.c        | 471 +++++++++++++------------------------
> >   libavcodec/qsvenc.h        |  51 +---
> >   libavcodec/qsvenc_h264.c   |   6 -
> >   libavcodec/qsvenc_hevc.c   |  10 -
> >   libavfilter/vf_scale_qsv.c |  13 +-
> >   libavfilter/vf_vpp_qsv.c   | 143 ++++++-----
> >   libavutil/hwcontext_qsv.c  |   2 -
> >   9 files changed, 249 insertions(+), 478 deletions(-)
> > 
> > diff --git a/configure b/configure
> > index f115b21064..2337f0a8f2 100755
> > --- a/configure
> > +++ b/configure
> > @@ -6566,8 +6566,11 @@ enabled liblensfun        && require_pkg_config
> > liblensfun lensfun lensfun.h lf_
> >   # Media SDK or Intel Media Server Studio, these don't come with
> >   # pkg-config support.  Instead, users should make sure that the build
> >   # can find the libraries and headers through other means.
> > -enabled libmfx            && { check_pkg_config libmfx libmfx
> > "mfx/mfxvideo.h" MFXInit ||
> > -                               { require libmfx "mfx/mfxvideo.h" MFXInit "-
> > llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } }
> > +enabled libmfx            && { check_pkg_config libmfx "mfx >= 1.28"
> > "mfx/mfxvideo.h" MFXInit ||
> > +                               { require libmfx "mfx/mfxvideo.h
> > mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
> 
> This broke build with mfx_dispatch. Before this, it checked for 
> libmfx.pc. Now it checks for mfx.pc, which is not installed by it.
> 
> Which of those is correct? It should definitely not drop support for 
> libmfx.pc, which was checked before this.

Sorry for this issue caused to you. The mfx dispatcher installed from 
https://github.com/Intel-Media-SDK/MediaSDK has both mfx.pc and libmfx.pc, but
definitely it should check for libmfx.pc here. I'll fix it ASAP.

BRs
Haihao
Xiang, Haihao May 26, 2022, 12:42 a.m. UTC | #7
On Wed, 2022-05-25 at 12:22 -0400, Leo Izen wrote:
> 
> On 5/25/22 12:05, Timo Rothenpieler wrote:
> > 
> > 
> > On 22/05/2022 14:19, Haihao Xiang wrote:
> > > libmfx 1.28 was released 3 years ago, it is easy to get a greater
> > > version than 1.28. We may remove lots of compile-time checks if adding
> > > the requirement for the minimal version in the configure script.
> > > ---
> > >   configure                  |   7 +-
> > >   libavcodec/qsv.c           |  24 --
> > >   libavcodec/qsvenc.c        | 471 +++++++++++++------------------------
> > >   libavcodec/qsvenc.h        |  51 +---
> > >   libavcodec/qsvenc_h264.c   |   6 -
> > >   libavcodec/qsvenc_hevc.c   |  10 -
> > >   libavfilter/vf_scale_qsv.c |  13 +-
> > >   libavfilter/vf_vpp_qsv.c   | 143 ++++++-----
> > >   libavutil/hwcontext_qsv.c  |   2 -
> > >   9 files changed, 249 insertions(+), 478 deletions(-)
> > > 
> > > diff --git a/configure b/configure
> > > index f115b21064..2337f0a8f2 100755
> > > --- a/configure
> > > +++ b/configure
> > > @@ -6566,8 +6566,11 @@ enabled liblensfun        && require_pkg_config 
> > > liblensfun lensfun lensfun.h lf_
> > >   # Media SDK or Intel Media Server Studio, these don't come with
> > >   # pkg-config support.  Instead, users should make sure that the build
> > >   # can find the libraries and headers through other means.
> > > -enabled libmfx            && { check_pkg_config libmfx libmfx 
> > > "mfx/mfxvideo.h" MFXInit ||
> > > -                               { require libmfx "mfx/mfxvideo.h" 
> > > MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without 
> > > pkg-config"; } }
> > > +enabled libmfx            && { check_pkg_config libmfx "mfx >= 1.28" 
> > > "mfx/mfxvideo.h" MFXInit ||
> > > +                               { require libmfx "mfx/mfxvideo.h 
> > > mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
> > 
> > This broke build with mfx_dispatch. Before this, it checked for 
> > libmfx.pc. Now it checks for mfx.pc, which is not installed by it.
> > 
> > Which of those is correct? It should definitely not drop support for 
> > libmfx.pc, which was checked before this.
> 
> It also attempts to link to -llibmfx, which means liblibmfx.so. I'm 
> guessing it's supposed to link to -lmfx instead.

It is -llibmfx in the original code. Please see commit
164e2773261451ef33c4616296ec5bebecff42af for why it is -llibmfx instead of -lmfx
here.

Thanks
Haihao
diff mbox series

Patch

diff --git a/configure b/configure
index f115b21064..2337f0a8f2 100755
--- a/configure
+++ b/configure
@@ -6566,8 +6566,11 @@  enabled liblensfun        && require_pkg_config liblensfun lensfun lensfun.h lf_
 # Media SDK or Intel Media Server Studio, these don't come with
 # pkg-config support.  Instead, users should make sure that the build
 # can find the libraries and headers through other means.
-enabled libmfx            && { check_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit ||
-                               { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } }
+enabled libmfx            && { check_pkg_config libmfx "mfx >= 1.28" "mfx/mfxvideo.h" MFXInit ||
+                               { require libmfx "mfx/mfxvideo.h mfx/mfxdefs.h" MFXInit "-llibmfx $advapi32_extralibs" &&
+                                 { test_cpp_condition mfx/mfxdefs.h "MFX_VERSION >= 1028" || die "ERROR: libmfx version must be >= 1.28"; }  &&
+                                 warn "using libmfx without pkg-config"; } }
+
 if enabled libmfx; then
    check_cc MFX_CODEC_VP9 "mfx/mfxvp9.h mfx/mfxstructures.h" "MFX_CODEC_VP9"
 fi
diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
index b86c20b153..385b43bb6c 100644
--- a/libavcodec/qsv.c
+++ b/libavcodec/qsv.c
@@ -38,34 +38,26 @@ 
 
 #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
 
-#if QSV_VERSION_ATLEAST(1, 12)
 #include "mfx/mfxvp8.h"
-#endif
 
 int ff_qsv_codec_id_to_mfx(enum AVCodecID codec_id)
 {
     switch (codec_id) {
     case AV_CODEC_ID_H264:
         return MFX_CODEC_AVC;
-#if QSV_VERSION_ATLEAST(1, 8)
     case AV_CODEC_ID_HEVC:
         return MFX_CODEC_HEVC;
-#endif
     case AV_CODEC_ID_MPEG1VIDEO:
     case AV_CODEC_ID_MPEG2VIDEO:
         return MFX_CODEC_MPEG2;
     case AV_CODEC_ID_VC1:
         return MFX_CODEC_VC1;
-#if QSV_VERSION_ATLEAST(1, 12)
     case AV_CODEC_ID_VP8:
         return MFX_CODEC_VP8;
-#endif
     case AV_CODEC_ID_MJPEG:
         return MFX_CODEC_JPEG;
-#if QSV_VERSION_ATLEAST(1, 19)
     case AV_CODEC_ID_VP9:
         return MFX_CODEC_VP9;
-#endif
 #if QSV_VERSION_ATLEAST(1, 34)
     case AV_CODEC_ID_AV1:
         return MFX_CODEC_AV1;
@@ -189,17 +181,11 @@  enum AVPixelFormat ff_qsv_map_fourcc(uint32_t fourcc)
     case MFX_FOURCC_NV12: return AV_PIX_FMT_NV12;
     case MFX_FOURCC_P010: return AV_PIX_FMT_P010;
     case MFX_FOURCC_P8:   return AV_PIX_FMT_PAL8;
-#if QSV_VERSION_ATLEAST(1, 9)
     case MFX_FOURCC_A2RGB10: return AV_PIX_FMT_X2RGB10;
-#endif
-#if QSV_VERSION_ATLEAST(1, 17)
     case MFX_FOURCC_RGB4: return AV_PIX_FMT_BGRA;
-#endif
 #if CONFIG_VAAPI
     case MFX_FOURCC_YUY2: return AV_PIX_FMT_YUYV422;
-#if QSV_VERSION_ATLEAST(1, 27)
     case MFX_FOURCC_Y210: return AV_PIX_FMT_Y210;
-#endif
 #endif
     }
     return AV_PIX_FMT_NONE;
@@ -217,27 +203,21 @@  int ff_qsv_map_pixfmt(enum AVPixelFormat format, uint32_t *fourcc)
     case AV_PIX_FMT_P010:
         *fourcc = MFX_FOURCC_P010;
         return AV_PIX_FMT_P010;
-#if QSV_VERSION_ATLEAST(1, 9)
     case AV_PIX_FMT_X2RGB10:
         *fourcc = MFX_FOURCC_A2RGB10;
         return AV_PIX_FMT_X2RGB10;
-#endif
-#if QSV_VERSION_ATLEAST(1, 17)
     case AV_PIX_FMT_BGRA:
         *fourcc = MFX_FOURCC_RGB4;
         return AV_PIX_FMT_BGRA;
-#endif
 #if CONFIG_VAAPI
     case AV_PIX_FMT_YUV422P:
     case AV_PIX_FMT_YUYV422:
         *fourcc = MFX_FOURCC_YUY2;
         return AV_PIX_FMT_YUYV422;
-#if QSV_VERSION_ATLEAST(1, 27)
     case AV_PIX_FMT_YUV422P10:
     case AV_PIX_FMT_Y210:
         *fourcc = MFX_FOURCC_Y210;
         return AV_PIX_FMT_Y210;
-#endif
 #endif
     default:
         return AVERROR(ENOSYS);
@@ -438,9 +418,7 @@  int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs,
     const char *desc;
     int ret;
 
-#if QSV_VERSION_ATLEAST(1, 16)
     init_par.GPUCopy        = gpu_copy;
-#endif
     init_par.Implementation = impl;
     init_par.Version        = ver;
     ret = MFXInitEx(init_par, &qs->session);
@@ -791,9 +769,7 @@  int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession,
                "from the session\n");
     }
 
-#if QSV_VERSION_ATLEAST(1, 16)
     init_par.GPUCopy        = gpu_copy;
-#endif
     init_par.Implementation = impl;
     init_par.Version        = ver;
     err = MFXInitEx(init_par, &session);
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index fbb22ca436..b6242bf4c8 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -53,14 +53,10 @@  static const struct profile_names avc_profiles[] = {
     { MFX_PROFILE_AVC_MAIN,                     "avc main"                  },
     { MFX_PROFILE_AVC_EXTENDED,                 "avc extended"              },
     { MFX_PROFILE_AVC_HIGH,                     "avc high"                  },
-#if QSV_VERSION_ATLEAST(1, 15)
     { MFX_PROFILE_AVC_HIGH_422,                 "avc high 422"              },
-#endif
-#if QSV_VERSION_ATLEAST(1, 4)
     { MFX_PROFILE_AVC_CONSTRAINED_BASELINE,     "avc constrained baseline"  },
     { MFX_PROFILE_AVC_CONSTRAINED_HIGH,         "avc constrained high"      },
     { MFX_PROFILE_AVC_PROGRESSIVE_HIGH,         "avc progressive high"      },
-#endif
 };
 
 static const struct profile_names mpeg2_profiles[] = {
@@ -70,24 +66,20 @@  static const struct profile_names mpeg2_profiles[] = {
 };
 
 static const struct profile_names hevc_profiles[] = {
-#if QSV_VERSION_ATLEAST(1, 8)
     { MFX_PROFILE_HEVC_MAIN,                    "hevc main"                  },
     { MFX_PROFILE_HEVC_MAIN10,                  "hevc main10"                },
     { MFX_PROFILE_HEVC_MAINSP,                  "hevc mainsp"                },
     { MFX_PROFILE_HEVC_REXT,                    "hevc rext"                  },
-#endif
 #if QSV_VERSION_ATLEAST(1, 32)
     { MFX_PROFILE_HEVC_SCC,                     "hevc scc"                   },
 #endif
 };
 
 static const struct profile_names vp9_profiles[] = {
-#if QSV_VERSION_ATLEAST(1, 19)
     { MFX_PROFILE_VP9_0,                        "vp9 0"                     },
     { MFX_PROFILE_VP9_1,                        "vp9 1"                     },
     { MFX_PROFILE_VP9_2,                        "vp9 2"                     },
     { MFX_PROFILE_VP9_3,                        "vp9 3"                     },
-#endif
 };
 
 typedef struct QSVPacket {
@@ -143,25 +135,15 @@  static const struct {
 #if QSV_HAVE_AVBR
     { MFX_RATECONTROL_AVBR,    "AVBR" },
 #endif
-#if QSV_HAVE_LA
     { MFX_RATECONTROL_LA,      "LA" },
-#endif
-#if QSV_HAVE_ICQ
     { MFX_RATECONTROL_ICQ,     "ICQ" },
     { MFX_RATECONTROL_LA_ICQ,  "LA_ICQ" },
-#endif
 #if QSV_HAVE_VCM
     { MFX_RATECONTROL_VCM,     "VCM" },
 #endif
-#if QSV_VERSION_ATLEAST(1, 10)
     { MFX_RATECONTROL_LA_EXT,  "LA_EXT" },
-#endif
-#if QSV_HAVE_LA_HRD
     { MFX_RATECONTROL_LA_HRD,  "LA_HRD" },
-#endif
-#if QSV_HAVE_QVBR
     { MFX_RATECONTROL_QVBR,    "QVBR" },
-#endif
 };
 
 static const char *print_ratecontrol(mfxU16 rc_mode)
@@ -187,16 +169,20 @@  static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
 {
     mfxInfoMFX *info = &q->param.mfx;
 
-    mfxExtCodingOption   *co = (mfxExtCodingOption*)coding_opts[0];
-#if QSV_HAVE_CO2
-    mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
-#endif
-#if QSV_HAVE_CO3
-    mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];
-#endif
-#if QSV_HAVE_EXT_HEVC_TILES
-    mfxExtHEVCTiles *exthevctiles = (mfxExtHEVCTiles *)coding_opts[3 + QSV_HAVE_CO_VPS];
-#endif
+    // co is always at index 1
+    mfxExtCodingOption   *co = (mfxExtCodingOption*)coding_opts[1];
+    mfxExtCodingOption2 *co2 = NULL;
+    mfxExtCodingOption3 *co3 = NULL;
+    mfxExtHEVCTiles *exthevctiles = NULL;
+
+    if (q->co2_idx > 0)
+        co2 = (mfxExtCodingOption2*)coding_opts[q->co2_idx];
+
+    if (q->co3_idx > 0)
+        co3 = (mfxExtCodingOption3*)coding_opts[q->co3_idx];
+
+    if (q->exthevctiles_idx > 0)
+        exthevctiles = (mfxExtHEVCTiles *)coding_opts[q->exthevctiles_idx];
 
     av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",
            print_profile(avctx->codec_id, info->CodecProfile), info->CodecLevel);
@@ -221,11 +207,6 @@  static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
         av_log(avctx, AV_LOG_VERBOSE,
                "BufferSizeInKB: %"PRIu16"; InitialDelayInKB: %"PRIu16"; TargetKbps: %"PRIu16"; MaxKbps: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
                info->BufferSizeInKB, info->InitialDelayInKB, info->TargetKbps, info->MaxKbps, info->BRCParamMultiplier);
-#if QSV_HAVE_LA
-        if (info->RateControlMethod == MFX_RATECONTROL_VBR && q->extbrc && q->look_ahead_depth > 0 ) {
-            av_log(avctx, AV_LOG_VERBOSE, "LookAheadDepth: %"PRIu16"\n",co2->LookAheadDepth);
-        }
-#endif
     } else if (info->RateControlMethod == MFX_RATECONTROL_CQP) {
         av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16"; QPB: %"PRIu16"\n",
                info->QPI, info->QPP, info->QPB);
@@ -237,117 +218,25 @@  static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
                info->TargetKbps, info->Accuracy, info->Convergence, info->BRCParamMultiplier);
     }
 #endif
-#if QSV_HAVE_LA
     else if (info->RateControlMethod == MFX_RATECONTROL_LA
-#if QSV_HAVE_LA_HRD
              || info->RateControlMethod == MFX_RATECONTROL_LA_HRD
-#endif
              ) {
         av_log(avctx, AV_LOG_VERBOSE,
-               "TargetKbps: %"PRIu16"; LookAheadDepth: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
-               info->TargetKbps, co2->LookAheadDepth, info->BRCParamMultiplier);
+               "TargetKbps: %"PRIu16"; BRCParamMultiplier: %"PRIu16"\n",
+               info->TargetKbps, info->BRCParamMultiplier);
     }
-#endif
-#if QSV_HAVE_ICQ
     else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {
         av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info->ICQQuality);
     } else if (info->RateControlMethod == MFX_RATECONTROL_LA_ICQ) {
-        av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"; LookAheadDepth: %"PRIu16"\n",
-               info->ICQQuality, co2->LookAheadDepth);
-    }
-#endif
-#if QSV_HAVE_QVBR
-    else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {
-        av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
-               co3->QVBRQuality);
+        av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info->ICQQuality);
     }
-#endif
     av_log(avctx, AV_LOG_VERBOSE, "NumSlice: %"PRIu16"; NumRefFrame: %"PRIu16"\n",
            info->NumSlice, info->NumRefFrame);
     av_log(avctx, AV_LOG_VERBOSE, "RateDistortionOpt: %s\n",
            print_threestate(co->RateDistortionOpt));
 
-#if QSV_HAVE_EXT_HEVC_TILES
-    if (avctx->codec_id == AV_CODEC_ID_HEVC)
-        av_log(avctx, AV_LOG_VERBOSE, "NumTileColumns: %"PRIu16"; NumTileRows: %"PRIu16"\n",
-               exthevctiles->NumTileColumns, exthevctiles->NumTileRows);
-#endif
-
-#if QSV_HAVE_CO2
-    av_log(avctx, AV_LOG_VERBOSE,
-           "RecoveryPointSEI: %s IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
-           print_threestate(co->RecoveryPointSEI), co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
-
-    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2->MaxFrameSize);
-#if QSV_HAVE_MAX_SLICE_SIZE
-    av_log(avctx, AV_LOG_VERBOSE, "MaxSliceSize: %d; ", co2->MaxSliceSize);
-#endif
-    av_log(avctx, AV_LOG_VERBOSE, "\n");
-
-    av_log(avctx, AV_LOG_VERBOSE,
-           "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
-           print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),
-           print_threestate(co2->ExtBRC));
-
-#if QSV_HAVE_TRELLIS
-    av_log(avctx, AV_LOG_VERBOSE, "Trellis: ");
-    if (co2->Trellis & MFX_TRELLIS_OFF) {
-        av_log(avctx, AV_LOG_VERBOSE, "off");
-    } else if (!co2->Trellis) {
-        av_log(avctx, AV_LOG_VERBOSE, "auto");
-    } else {
-        if (co2->Trellis & MFX_TRELLIS_I) av_log(avctx, AV_LOG_VERBOSE, "I");
-        if (co2->Trellis & MFX_TRELLIS_P) av_log(avctx, AV_LOG_VERBOSE, "P");
-        if (co2->Trellis & MFX_TRELLIS_B) av_log(avctx, AV_LOG_VERBOSE, "B");
-    }
-    av_log(avctx, AV_LOG_VERBOSE, "\n");
-#endif
-
-#if QSV_HAVE_VDENC
+    av_log(avctx, AV_LOG_VERBOSE, "RecoveryPointSEI: %s\n", print_threestate(co->RecoveryPointSEI));
     av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", print_threestate(info->LowPower));
-#endif
-
-#if QSV_VERSION_ATLEAST(1, 8)
-    av_log(avctx, AV_LOG_VERBOSE,
-           "RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
-           print_threestate(co2->RepeatPPS), co2->NumMbPerSlice);
-    switch (co2->LookAheadDS) {
-    case MFX_LOOKAHEAD_DS_OFF: av_log(avctx, AV_LOG_VERBOSE, "off");     break;
-    case MFX_LOOKAHEAD_DS_2x:  av_log(avctx, AV_LOG_VERBOSE, "2x");      break;
-    case MFX_LOOKAHEAD_DS_4x:  av_log(avctx, AV_LOG_VERBOSE, "4x");      break;
-    default:                   av_log(avctx, AV_LOG_VERBOSE, "unknown"); break;
-    }
-    av_log(avctx, AV_LOG_VERBOSE, "\n");
-
-    av_log(avctx, AV_LOG_VERBOSE, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",
-           print_threestate(co2->AdaptiveI), print_threestate(co2->AdaptiveB));
-    switch (co2->BRefType) {
-    case MFX_B_REF_OFF:     av_log(avctx, AV_LOG_VERBOSE, "off");       break;
-    case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
-    default:                av_log(avctx, AV_LOG_VERBOSE, "auto");      break;
-    }
-
-    av_log(avctx, AV_LOG_VERBOSE, "; PRefType: ");
-    switch (co3->PRefType) {
-    case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   break;
-    case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");    break;
-    case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
-    default:                av_log(avctx, AV_LOG_VERBOSE, "unknown");   break;
-    }
-    av_log(avctx, AV_LOG_VERBOSE, "\n");
-#endif
-
-#if QSV_VERSION_ATLEAST(1, 9)
-    av_log(avctx, AV_LOG_VERBOSE,
-           "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
-           co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);
-#endif
-#endif
-
-#if QSV_HAVE_GPB
-    if (avctx->codec_id == AV_CODEC_ID_HEVC)
-        av_log(avctx, AV_LOG_VERBOSE,"GPB: %s\n", print_threestate(co3->GPB));
-#endif
 
     if (avctx->codec_id == AV_CODEC_ID_H264) {
         av_log(avctx, AV_LOG_VERBOSE, "Entropy coding: %s; MaxDecFrameBuffering: %"PRIu16"\n",
@@ -365,36 +254,103 @@  static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
     av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32"; FrameRateExtN: %"PRIu32" \n",
            info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
 
-#if QSV_HAVE_DISABLEDEBLOCKIDC
-    av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n", co2->DisableDeblockingIdc);
-#endif
+    if (co2) {
+        if ((info->RateControlMethod == MFX_RATECONTROL_VBR && q->extbrc && q->look_ahead_depth > 0) ||
+            (info->RateControlMethod == MFX_RATECONTROL_LA) ||
+            (info->RateControlMethod == MFX_RATECONTROL_LA_HRD) ||
+            (info->RateControlMethod == MFX_RATECONTROL_LA_ICQ))
+            av_log(avctx, AV_LOG_VERBOSE, "LookAheadDepth: %"PRIu16"\n", co2->LookAheadDepth);
 
-#if QSV_VERSION_ATLEAST(1, 26)
-    av_log(avctx, AV_LOG_VERBOSE, "TransformSkip: %s \n", print_threestate(co3->TransformSkip));
-#endif
+        av_log(avctx, AV_LOG_VERBOSE, "IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
+               co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
 
-#if QSV_VERSION_ATLEAST(1, 16)
-    av_log(avctx, AV_LOG_VERBOSE, "IntRefCycleDist: %"PRId16"\n", co3->IntRefCycleDist);
-#endif
-#if QSV_VERSION_ATLEAST(1, 23)
-    av_log(avctx, AV_LOG_VERBOSE, "LowDelayBRC: %s\n", print_threestate(co3->LowDelayBRC));
-#endif
-#if QSV_VERSION_ATLEAST(1, 19)
-    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeI: %d; ", co3->MaxFrameSizeI);
-    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeP: %d\n", co3->MaxFrameSizeP);
-#endif
+        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2->MaxFrameSize);
+        av_log(avctx, AV_LOG_VERBOSE, "MaxSliceSize: %d; ", co2->MaxSliceSize);
+        av_log(avctx, AV_LOG_VERBOSE, "\n");
+
+        av_log(avctx, AV_LOG_VERBOSE,
+               "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
+               print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),
+               print_threestate(co2->ExtBRC));
+
+        av_log(avctx, AV_LOG_VERBOSE, "Trellis: ");
+        if (co2->Trellis & MFX_TRELLIS_OFF) {
+            av_log(avctx, AV_LOG_VERBOSE, "off");
+        } else if (!co2->Trellis) {
+            av_log(avctx, AV_LOG_VERBOSE, "auto");
+        } else {
+            if (co2->Trellis & MFX_TRELLIS_I) av_log(avctx, AV_LOG_VERBOSE, "I");
+            if (co2->Trellis & MFX_TRELLIS_P) av_log(avctx, AV_LOG_VERBOSE, "P");
+            if (co2->Trellis & MFX_TRELLIS_B) av_log(avctx, AV_LOG_VERBOSE, "B");
+        }
+        av_log(avctx, AV_LOG_VERBOSE, "\n");
+
+        av_log(avctx, AV_LOG_VERBOSE,
+               "RepeatPPS: %s; NumMbPerSlice: %"PRIu16"; LookAheadDS: ",
+               print_threestate(co2->RepeatPPS), co2->NumMbPerSlice);
+        switch (co2->LookAheadDS) {
+        case MFX_LOOKAHEAD_DS_OFF: av_log(avctx, AV_LOG_VERBOSE, "off");     break;
+        case MFX_LOOKAHEAD_DS_2x:  av_log(avctx, AV_LOG_VERBOSE, "2x");      break;
+        case MFX_LOOKAHEAD_DS_4x:  av_log(avctx, AV_LOG_VERBOSE, "4x");      break;
+        default:                   av_log(avctx, AV_LOG_VERBOSE, "unknown"); break;
+        }
+        av_log(avctx, AV_LOG_VERBOSE, "\n");
+
+        av_log(avctx, AV_LOG_VERBOSE, "AdaptiveI: %s; AdaptiveB: %s; BRefType: ",
+               print_threestate(co2->AdaptiveI), print_threestate(co2->AdaptiveB));
+        switch (co2->BRefType) {
+        case MFX_B_REF_OFF:     av_log(avctx, AV_LOG_VERBOSE, "off");       break;
+        case MFX_B_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
+        default:                av_log(avctx, AV_LOG_VERBOSE, "auto");      break;
+        }
+
+        av_log(avctx, AV_LOG_VERBOSE,
+               "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
+               co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);
+        av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n", co2->DisableDeblockingIdc);
+    }
+
+    if (co3) {
+        if (info->RateControlMethod == MFX_RATECONTROL_QVBR)
+            av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n", co3->QVBRQuality);
+
+        av_log(avctx, AV_LOG_VERBOSE, "PRefType: ");
+        switch (co3->PRefType) {
+        case MFX_P_REF_DEFAULT: av_log(avctx, AV_LOG_VERBOSE, "default");   break;
+        case MFX_P_REF_SIMPLE:  av_log(avctx, AV_LOG_VERBOSE, "simple");    break;
+        case MFX_P_REF_PYRAMID: av_log(avctx, AV_LOG_VERBOSE, "pyramid");   break;
+        default:                av_log(avctx, AV_LOG_VERBOSE, "unknown");   break;
+        }
+        av_log(avctx, AV_LOG_VERBOSE, "\n");
+
+        if (avctx->codec_id == AV_CODEC_ID_HEVC)
+            av_log(avctx, AV_LOG_VERBOSE,"GPB: %s\n", print_threestate(co3->GPB));
+
+        av_log(avctx, AV_LOG_VERBOSE, "TransformSkip: %s \n", print_threestate(co3->TransformSkip));
+        av_log(avctx, AV_LOG_VERBOSE, "IntRefCycleDist: %"PRId16"\n", co3->IntRefCycleDist);
+        av_log(avctx, AV_LOG_VERBOSE, "LowDelayBRC: %s\n", print_threestate(co3->LowDelayBRC));
+        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeI: %d; ", co3->MaxFrameSizeI);
+        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSizeP: %d\n", co3->MaxFrameSizeP);
+    }
+
+    if (exthevctiles) {
+        av_log(avctx, AV_LOG_VERBOSE, "NumTileColumns: %"PRIu16"; NumTileRows: %"PRIu16"\n",
+               exthevctiles->NumTileColumns, exthevctiles->NumTileRows);
+    }
 }
 
 static void dump_video_vp9_param(AVCodecContext *avctx, QSVEncContext *q,
                                  mfxExtBuffer **coding_opts)
 {
     mfxInfoMFX *info = &q->param.mfx;
-#if QSV_HAVE_EXT_VP9_PARAM
-    mfxExtVP9Param *vp9_param = (mfxExtVP9Param *)coding_opts[0];
-#endif
-#if QSV_HAVE_CO2
-    mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
-#endif
+    mfxExtVP9Param *vp9_param = NULL;
+    mfxExtCodingOption2 *co2 = NULL;
+
+    if (q->vp9_idx >= 0)
+        vp9_param = (mfxExtVP9Param *)coding_opts[q->vp9_idx];
+
+    if (q->co2_idx >= 0)
+        co2 = (mfxExtCodingOption2*)coding_opts[q->co2_idx];
 
     av_log(avctx, AV_LOG_VERBOSE, "profile: %s \n",
            print_profile(avctx->codec_id, info->CodecProfile));
@@ -419,48 +375,41 @@  static void dump_video_vp9_param(AVCodecContext *avctx, QSVEncContext *q,
         av_log(avctx, AV_LOG_VERBOSE, "QPI: %"PRIu16"; QPP: %"PRIu16"; QPB: %"PRIu16"\n",
                info->QPI, info->QPP, info->QPB);
     }
-#if QSV_HAVE_ICQ
     else if (info->RateControlMethod == MFX_RATECONTROL_ICQ) {
         av_log(avctx, AV_LOG_VERBOSE, "ICQQuality: %"PRIu16"\n", info->ICQQuality);
     }
-#endif
     else {
         av_log(avctx, AV_LOG_VERBOSE, "Unsupported ratecontrol method: %d \n", info->RateControlMethod);
     }
 
     av_log(avctx, AV_LOG_VERBOSE, "NumRefFrame: %"PRIu16"\n", info->NumRefFrame);
+    av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32"; FrameRateExtN: %"PRIu32" \n",
+           info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
 
-#if QSV_HAVE_CO2
-    av_log(avctx, AV_LOG_VERBOSE,
-           "IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
-           co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
+    if (co2) {
+        av_log(avctx, AV_LOG_VERBOSE,
+               "IntRefType: %"PRIu16"; IntRefCycleSize: %"PRIu16"; IntRefQPDelta: %"PRId16"\n",
+               co2->IntRefType, co2->IntRefCycleSize, co2->IntRefQPDelta);
 
-    av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2->MaxFrameSize);
-    av_log(avctx, AV_LOG_VERBOSE, "\n");
+        av_log(avctx, AV_LOG_VERBOSE, "MaxFrameSize: %d; ", co2->MaxFrameSize);
+        av_log(avctx, AV_LOG_VERBOSE, "\n");
 
-    av_log(avctx, AV_LOG_VERBOSE,
-           "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
-           print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),
-           print_threestate(co2->ExtBRC));
+        av_log(avctx, AV_LOG_VERBOSE,
+               "BitrateLimit: %s; MBBRC: %s; ExtBRC: %s\n",
+               print_threestate(co2->BitrateLimit), print_threestate(co2->MBBRC),
+               print_threestate(co2->ExtBRC));
 
-#if QSV_HAVE_VDENC
-    av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", print_threestate(info->LowPower));
-#endif
+        av_log(avctx, AV_LOG_VERBOSE, "VDENC: %s\n", print_threestate(info->LowPower));
 
-#if QSV_VERSION_ATLEAST(1, 9)
-    av_log(avctx, AV_LOG_VERBOSE,
-           "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
-           co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);
-#endif
-#endif
-
-    av_log(avctx, AV_LOG_VERBOSE, "FrameRateExtD: %"PRIu32"; FrameRateExtN: %"PRIu32" \n",
-           info->FrameInfo.FrameRateExtD, info->FrameInfo.FrameRateExtN);
+        av_log(avctx, AV_LOG_VERBOSE,
+               "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n",
+               co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2->MinQPB, co2->MaxQPB);
+    }
 
-#if QSV_HAVE_EXT_VP9_PARAM
-    av_log(avctx, AV_LOG_VERBOSE, "WriteIVFHeaders: %s \n",
-           print_threestate(vp9_param->WriteIVFHeaders));
-#endif
+    if (vp9_param) {
+        av_log(avctx, AV_LOG_VERBOSE, "WriteIVFHeaders: %s \n",
+               print_threestate(vp9_param->WriteIVFHeaders));
+    }
 }
 
 static void dump_video_mjpeg_param(AVCodecContext *avctx, QSVEncContext *q)
@@ -484,11 +433,6 @@  static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
     int want_qscale = !!(avctx->flags & AV_CODEC_FLAG_QSCALE);
     int want_vcm    = q->vcm;
 
-    if (want_la && !QSV_HAVE_LA) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Lookahead ratecontrol mode requested, but is not supported by this SDK version\n");
-        return AVERROR(ENOSYS);
-    }
     if (want_vcm && !QSV_HAVE_VCM) {
         av_log(avctx, AV_LOG_ERROR,
                "VCM ratecontrol mode requested, but is not supported by this SDK version\n");
@@ -502,12 +446,6 @@  static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
         return AVERROR(EINVAL);
     }
 
-    if (!want_qscale && avctx->global_quality > 0 && !QSV_HAVE_ICQ){
-        av_log(avctx, AV_LOG_ERROR,
-               "ICQ ratecontrol mode requested, but is not supported by this SDK version\n");
-        return AVERROR(ENOSYS);
-    }
-
     if (want_qscale) {
         rc_mode = MFX_RATECONTROL_CQP;
         rc_desc = "constant quantization parameter (CQP)";
@@ -518,25 +456,19 @@  static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
         rc_desc = "video conferencing mode (VCM)";
     }
 #endif
-#if QSV_HAVE_LA
     else if (want_la) {
         rc_mode = MFX_RATECONTROL_LA;
         rc_desc = "VBR with lookahead (LA)";
 
-#if QSV_HAVE_ICQ
         if (avctx->global_quality > 0) {
             rc_mode = MFX_RATECONTROL_LA_ICQ;
             rc_desc = "intelligent constant quality with lookahead (LA_ICQ)";
         }
-#endif
     }
-#endif
-#if QSV_HAVE_ICQ
     else if (avctx->global_quality > 0 && !avctx->rc_max_rate) {
         rc_mode = MFX_RATECONTROL_ICQ;
         rc_desc = "intelligent constant quality (ICQ)";
     }
-#endif
     else if (avctx->rc_max_rate == avctx->bit_rate) {
         rc_mode = MFX_RATECONTROL_CBR;
         rc_desc = "constant bitrate (CBR)";
@@ -547,12 +479,10 @@  static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
         rc_desc = "average variable bitrate (AVBR)";
     }
 #endif
-#if QSV_HAVE_QVBR
     else if (avctx->global_quality > 0) {
         rc_mode = MFX_RATECONTROL_QVBR;
         rc_desc = "constant quality with VBR algorithm (QVBR)";
     }
-#endif
     else {
         rc_mode = MFX_RATECONTROL_VBR;
         rc_desc = "variable bitrate (VBR)";
@@ -692,14 +622,7 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
     }
 
     if (q->low_power == 1) {
-#if QSV_HAVE_VDENC
         q->param.mfx.LowPower = MFX_CODINGOPTION_ON;
-#else
-        av_log(avctx, AV_LOG_WARNING, "The low_power option is "
-                            "not supported with this MSDK version.\n");
-        q->low_power = 0;
-        q->param.mfx.LowPower = MFX_CODINGOPTION_OFF;
-#endif
     } else if (q->low_power == -1)
         q->param.mfx.LowPower = MFX_CODINGOPTION_UNKNOWN;
     else
@@ -789,26 +712,20 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
     switch (q->param.mfx.RateControlMethod) {
     case MFX_RATECONTROL_CBR:
     case MFX_RATECONTROL_VBR:
-#if QSV_HAVE_LA
         if (q->extbrc) {
             q->extco2.LookAheadDepth = q->look_ahead_depth;
         }
-#endif
 #if QSV_HAVE_VCM
     case MFX_RATECONTROL_VCM:
 #endif
-#if QSV_HAVE_QVBR
     case MFX_RATECONTROL_QVBR:
-#endif
         q->param.mfx.BufferSizeInKB   = buffer_size_in_kilobytes / brc_param_multiplier;
         q->param.mfx.InitialDelayInKB = initial_delay_in_kilobytes / brc_param_multiplier;
         q->param.mfx.TargetKbps       = target_bitrate_kbps / brc_param_multiplier;
         q->param.mfx.MaxKbps          = max_bitrate_kbps / brc_param_multiplier;
         q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
-#if QSV_HAVE_QVBR
         if (q->param.mfx.RateControlMethod == MFX_RATECONTROL_QVBR)
             q->extco3.QVBRQuality = av_clip(avctx->global_quality, 0, 51);
-#endif
         break;
     case MFX_RATECONTROL_CQP:
         quant = avctx->global_quality / FF_QP2LAMBDA;
@@ -826,20 +743,16 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
         q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
         break;
 #endif
-#if QSV_HAVE_LA
     case MFX_RATECONTROL_LA:
         q->param.mfx.TargetKbps  = target_bitrate_kbps / brc_param_multiplier;
         q->extco2.LookAheadDepth = q->look_ahead_depth;
         q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
         break;
-#if QSV_HAVE_ICQ
     case MFX_RATECONTROL_LA_ICQ:
         q->extco2.LookAheadDepth = q->look_ahead_depth;
     case MFX_RATECONTROL_ICQ:
         q->param.mfx.ICQQuality  = av_clip(avctx->global_quality, 1, 51);
         break;
-#endif
-#endif
     }
 
     // The HEVC encoder plugin currently fails with some old libmfx version if coding options
@@ -883,19 +796,15 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
 
         q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco;
 
-#if QSV_HAVE_CO2
         if (avctx->codec_id == AV_CODEC_ID_H264) {
             if (q->bitrate_limit >= 0)
                 q->extco2.BitrateLimit = q->bitrate_limit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
 
-#if QSV_HAVE_TRELLIS
             if (avctx->trellis >= 0)
                 q->extco2.Trellis = (avctx->trellis == 0) ? MFX_TRELLIS_OFF : (MFX_TRELLIS_I | MFX_TRELLIS_P | MFX_TRELLIS_B);
             else
                 q->extco2.Trellis = MFX_TRELLIS_UNKNOWN;
-#endif
 
-#if QSV_VERSION_ATLEAST(1, 8)
             q->extco2.LookAheadDS = q->look_ahead_downsampling;
             q->extco2.RepeatPPS   = q->repeat_pps ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
 
@@ -903,7 +812,6 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
                 q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
             if (q->adaptive_b >= 0)
                 q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
-#endif
         }
 
         if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC) {
@@ -917,19 +825,12 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
                 q->extco2.IntRefCycleSize = q->int_ref_cycle_size;
             if (q->int_ref_qp_delta != INT16_MIN)
                 q->extco2.IntRefQPDelta = q->int_ref_qp_delta;
-#if QSV_HAVE_MAX_SLICE_SIZE
             if (q->max_slice_size >= 0)
                 q->extco2.MaxSliceSize = q->max_slice_size;
-#endif
-#if QSV_HAVE_DISABLEDEBLOCKIDC
             q->extco2.DisableDeblockingIdc = q->dblk_idc;
-#endif
 
-#if QSV_VERSION_ATLEAST(1, 8)
             if (q->b_strategy >= 0)
                 q->extco2.BRefType = q->b_strategy ? MFX_B_REF_PYRAMID : MFX_B_REF_OFF;
-#endif
-#if QSV_VERSION_ATLEAST(1, 9)
             if (avctx->qmin >= 0 && avctx->qmax >= 0 && avctx->qmin > avctx->qmax) {
                 av_log(avctx, AV_LOG_ERROR, "qmin and or qmax are set but invalid, please make sure min <= max\n");
                 return AVERROR(EINVAL);
@@ -942,7 +843,6 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
                 q->extco2.MaxQPI = avctx->qmax > 51 ? 51 : avctx->qmax;
                 q->extco2.MaxQPP = q->extco2.MaxQPB = q->extco2.MaxQPI;
             }
-#endif
             if (q->mbbrc >= 0)
                 q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
 
@@ -951,7 +851,6 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
 
             q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2;
         }
-#endif
 
         if (avctx->codec_id == AV_CODEC_ID_H264) {
 #if QSV_HAVE_MF
@@ -965,13 +864,11 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
             }
 #endif
         }
-#if QSV_HAVE_CO3
         q->extco3.Header.BufferId      = MFX_EXTBUFF_CODING_OPTION3;
         q->extco3.Header.BufferSz      = sizeof(q->extco3);
 
         if (avctx->codec_id == AV_CODEC_ID_HEVC ||
             avctx->codec_id == AV_CODEC_ID_H264) {
-#if QSV_HAVE_PREF
             switch (q->p_strategy) {
             case 0:
                 q->extco3.PRefType = MFX_P_REF_DEFAULT;
@@ -993,40 +890,27 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
                 av_log(avctx, AV_LOG_WARNING,
                        "Please set max_b_frames(-bf) to 0 to enable P-pyramid\n");
             }
-#endif
-#if QSV_VERSION_ATLEAST(1, 16)
             if (q->int_ref_cycle_dist >= 0)
                 q->extco3.IntRefCycleDist = q->int_ref_cycle_dist;
-#endif
-#if QSV_VERSION_ATLEAST(1, 23)
             if (q->low_delay_brc >= 0)
                 q->extco3.LowDelayBRC = q->low_delay_brc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
-#endif
-#if QSV_VERSION_ATLEAST(1, 19)
             if (q->max_frame_size_i >= 0)
                 q->extco3.MaxFrameSizeI = q->max_frame_size_i;
             if (q->max_frame_size_p >= 0)
                 q->extco3.MaxFrameSizeP = q->max_frame_size_p;
-#endif
         }
 
         if (avctx->codec_id == AV_CODEC_ID_HEVC) {
-#if QSV_VERSION_ATLEAST(1, 26)
             if (q->transform_skip >= 0)
                 q->extco3.TransformSkip = q->transform_skip ? MFX_CODINGOPTION_ON :
                                                               MFX_CODINGOPTION_OFF;
             else
                 q->extco3.TransformSkip = MFX_CODINGOPTION_UNKNOWN;
-#endif
-#if QSV_HAVE_GPB
             q->extco3.GPB              = q->gpb ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF;
-#endif
         }
         q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco3;
-#endif
     }
 
-#if QSV_HAVE_EXT_VP9_PARAM
     if (avctx->codec_id == AV_CODEC_ID_VP9) {
         q->extvp9param.Header.BufferId = MFX_EXTBUFF_VP9_PARAM;
         q->extvp9param.Header.BufferSz = sizeof(q->extvp9param);
@@ -1037,9 +921,7 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
 #endif
         q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extvp9param;
     }
-#endif
 
-#if QSV_HAVE_EXT_HEVC_TILES
     if (avctx->codec_id == AV_CODEC_ID_HEVC) {
         q->exthevctiles.Header.BufferId = MFX_EXTBUFF_HEVC_TILES;
         q->exthevctiles.Header.BufferSz = sizeof(q->exthevctiles);
@@ -1047,7 +929,6 @@  static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
         q->exthevctiles.NumTileRows     = q->tile_rows;
         q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->exthevctiles;
     }
-#endif
 
     q->extvsi.VideoFullRange = (avctx->color_range == AVCOL_RANGE_JPEG);
     q->extvsi.ColourDescriptionPresent = 0;
@@ -1100,41 +981,44 @@  static int qsv_retrieve_enc_jpeg_params(AVCodecContext *avctx, QSVEncContext *q)
 static int qsv_retrieve_enc_vp9_params(AVCodecContext *avctx, QSVEncContext *q)
 {
     int ret = 0;
-#if QSV_HAVE_EXT_VP9_PARAM
     mfxExtVP9Param vp9_extend_buf = {
          .Header.BufferId = MFX_EXTBUFF_VP9_PARAM,
          .Header.BufferSz = sizeof(vp9_extend_buf),
     };
-#endif
 
-#if QSV_HAVE_CO2
     mfxExtCodingOption2 co2 = {
         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
         .Header.BufferSz = sizeof(co2),
     };
-#endif
 
-#if QSV_HAVE_CO3
     mfxExtCodingOption3 co3 = {
         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
         .Header.BufferSz = sizeof(co3),
     };
-#endif
 
-    mfxExtBuffer *ext_buffers[] = {
-#if QSV_HAVE_EXT_VP9_PARAM
-        (mfxExtBuffer*)&vp9_extend_buf,
-#endif
-#if QSV_HAVE_CO2
-        (mfxExtBuffer*)&co2,
-#endif
-#if QSV_HAVE_CO3
-        (mfxExtBuffer*)&co3,
-#endif
-    };
+    mfxExtBuffer *ext_buffers[3];
+    int ext_buf_num = 0;
+
+    q->co2_idx = q->co3_idx = q->vp9_idx = -1;
+
+    // It is possible the runtime doesn't support the given ext buffer
+    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 6)) {
+        q->co2_idx = ext_buf_num;
+        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co2;
+    }
+
+    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 11)) {
+        q->co3_idx = ext_buf_num;
+        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co3;
+    }
+
+    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 26)) {
+        q->vp9_idx = ext_buf_num;
+        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&vp9_extend_buf;
+    }
 
     q->param.ExtParam    = ext_buffers;
-    q->param.NumExtParam = FF_ARRAY_ELEMS(ext_buffers);
+    q->param.NumExtParam = ext_buf_num;
 
     ret = MFXVideoENCODE_GetVideoParam(q->session, &q->param);
     if (ret < 0)
@@ -1166,20 +1050,15 @@  static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION,
         .Header.BufferSz = sizeof(co),
     };
-#if QSV_HAVE_CO2
     mfxExtCodingOption2 co2 = {
         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION2,
         .Header.BufferSz = sizeof(co2),
     };
-#endif
-#if QSV_HAVE_CO3
     mfxExtCodingOption3 co3 = {
         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
         .Header.BufferSz = sizeof(co3),
     };
-#endif
 
-#if QSV_HAVE_CO_VPS
     uint8_t vps_buf[128];
     mfxExtCodingOptionVPS extradata_vps = {
         .Header.BufferId = MFX_EXTBUFF_CODING_OPTION_VPS,
@@ -1187,37 +1066,39 @@  static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
         .VPSBuffer       = vps_buf,
         .VPSBufSize      = sizeof(vps_buf),
     };
-#endif
 
-#if QSV_HAVE_EXT_HEVC_TILES
     mfxExtHEVCTiles hevc_tile_buf = {
          .Header.BufferId = MFX_EXTBUFF_HEVC_TILES,
          .Header.BufferSz = sizeof(hevc_tile_buf),
     };
-#endif
 
-    mfxExtBuffer *ext_buffers[2 + QSV_HAVE_CO2 + QSV_HAVE_CO3 + QSV_HAVE_CO_VPS + QSV_HAVE_EXT_HEVC_TILES];
+    mfxExtBuffer *ext_buffers[6];
 
     int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;
     int ret, ext_buf_num = 0, extradata_offset = 0;
 
+    q->co2_idx = q->co3_idx = q->exthevctiles_idx = -1;
     ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&extradata;
     ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co;
-#if QSV_HAVE_CO2
-    ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co2;
-#endif
-#if QSV_HAVE_CO3
-    ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co3;
-#endif
-#if QSV_HAVE_CO_VPS
+
+    // It is possible the runtime doesn't support the given ext buffer
+    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 6)) {
+        q->co2_idx = ext_buf_num;
+        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co2;
+    }
+
+    if (QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 11)) {
+        q->co3_idx = ext_buf_num;
+        ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&co3;
+    }
+
     q->hevc_vps = ((avctx->codec_id == AV_CODEC_ID_HEVC) && QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 17));
     if (q->hevc_vps)
         ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&extradata_vps;
-#endif
-#if QSV_HAVE_EXT_HEVC_TILES
-    if (avctx->codec_id == AV_CODEC_ID_HEVC)
+    if (avctx->codec_id == AV_CODEC_ID_HEVC && QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 13)) {
+        q->exthevctiles_idx = ext_buf_num;
         ext_buffers[ext_buf_num++] = (mfxExtBuffer*)&hevc_tile_buf;
-#endif
+    }
 
     q->param.ExtParam    = ext_buffers;
     q->param.NumExtParam = ext_buf_num;
@@ -1230,29 +1111,23 @@  static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
     q->packet_size = q->param.mfx.BufferSizeInKB * q->param.mfx.BRCParamMultiplier * 1000;
 
     if (!extradata.SPSBufSize || (need_pps && !extradata.PPSBufSize)
-#if QSV_HAVE_CO_VPS
         || (q->hevc_vps && !extradata_vps.VPSBufSize)
-#endif
     ) {
         av_log(avctx, AV_LOG_ERROR, "No extradata returned from libmfx.\n");
         return AVERROR_UNKNOWN;
     }
 
     avctx->extradata_size = extradata.SPSBufSize + need_pps * extradata.PPSBufSize;
-#if QSV_HAVE_CO_VPS
     avctx->extradata_size += q->hevc_vps * extradata_vps.VPSBufSize;
-#endif
 
     avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
     if (!avctx->extradata)
         return AVERROR(ENOMEM);
 
-#if QSV_HAVE_CO_VPS
     if (q->hevc_vps) {
         memcpy(avctx->extradata, vps_buf, extradata_vps.VPSBufSize);
         extradata_offset += extradata_vps.VPSBufSize;
     }
-#endif
 
     memcpy(avctx->extradata + extradata_offset, sps_buf, extradata.SPSBufSize);
     extradata_offset += extradata.SPSBufSize;
@@ -1270,7 +1145,7 @@  static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
     cpb_props->avg_bitrate = avctx->bit_rate;
     cpb_props->buffer_size = avctx->rc_buffer_size;
 
-    dump_video_param(avctx, q, ext_buffers + 1);
+    dump_video_param(avctx, q, ext_buffers);
 
     return 0;
 }
@@ -1652,10 +1527,8 @@  static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
                         const AVFrame *frame)
 {
     QSVPacket pkt = { { 0 } };
-#if QSV_VERSION_ATLEAST(1, 26)
     mfxExtAVCEncodedFrameInfo *enc_info = NULL;
     mfxExtBuffer **enc_buf = NULL;
-#endif
 
     mfxFrameSurface1 *surf = NULL;
     QSVFrame *qsv_frame = NULL;
@@ -1692,7 +1565,6 @@  static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
     pkt.bs->Data      = pkt.pkt.data;
     pkt.bs->MaxLength = pkt.pkt.size;
 
-#if QSV_VERSION_ATLEAST(1, 26)
     if (avctx->codec_id == AV_CODEC_ID_H264) {
         enc_info = av_mallocz(sizeof(*enc_info));
         if (!enc_info)
@@ -1708,7 +1580,6 @@  static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
 
         pkt.bs->ExtParam = enc_buf;
     }
-#endif
 
     if (q->set_encode_ctrl_cb) {
         q->set_encode_ctrl_cb(avctx, frame, &qsv_frame->enc_ctrl);
@@ -1745,12 +1616,10 @@  free:
         av_freep(&pkt.sync);
         av_packet_unref(&pkt.pkt);
         av_freep(&pkt.bs);
-#if QSV_VERSION_ATLEAST(1, 26)
         if (avctx->codec_id == AV_CODEC_ID_H264) {
             av_freep(&enc_info);
             av_freep(&enc_buf);
         }
-#endif
     }
 
     return ret;
@@ -1771,10 +1640,8 @@  int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
     if ((av_fifo_can_read(q->async_fifo) >= q->async_depth) ||
         (!frame && av_fifo_can_read(q->async_fifo))) {
         QSVPacket qpkt;
-#if QSV_VERSION_ATLEAST(1, 26)
         mfxExtAVCEncodedFrameInfo *enc_info;
         mfxExtBuffer **enc_buf;
-#endif
         enum AVPictureType pict_type;
 
         av_fifo_read(q->async_fifo, &qpkt, 1);
@@ -1804,7 +1671,6 @@  int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
             return AVERROR_INVALIDDATA;
         }
 
-#if QSV_VERSION_ATLEAST(1, 26)
         if (avctx->codec_id == AV_CODEC_ID_H264) {
             enc_buf = qpkt.bs->ExtParam;
             enc_info = (mfxExtAVCEncodedFrameInfo *)(*enc_buf);
@@ -1813,7 +1679,6 @@  int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext *q,
             av_freep(&enc_info);
             av_freep(&enc_buf);
         }
-#endif
         av_freep(&qpkt.bs);
         av_freep(&qpkt.sync);
 
@@ -1850,14 +1715,12 @@  int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
     if (q->async_fifo) {
         QSVPacket pkt;
         while (av_fifo_read(q->async_fifo, &pkt, 1) >= 0) {
-#if QSV_VERSION_ATLEAST(1, 26)
             if (avctx->codec_id == AV_CODEC_ID_H264) {
                 mfxExtBuffer **enc_buf = pkt.bs->ExtParam;
                 mfxExtAVCEncodedFrameInfo *enc_info = (mfxExtAVCEncodedFrameInfo *)(*enc_buf);
                 av_freep(&enc_info);
                 av_freep(&enc_buf);
             }
-#endif
             av_freep(&pkt.sync);
             av_freep(&pkt.bs);
             av_packet_unref(&pkt.pkt);
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index cb84723dfa..a0edd3ec17 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -35,46 +35,16 @@ 
 #include "hwconfig.h"
 #include "qsv_internal.h"
 
-#define QSV_HAVE_CO2 QSV_VERSION_ATLEAST(1, 6)
-#define QSV_HAVE_CO3 QSV_VERSION_ATLEAST(1, 11)
-#define QSV_HAVE_CO_VPS  QSV_VERSION_ATLEAST(1, 17)
-
-#define QSV_HAVE_EXT_HEVC_TILES QSV_VERSION_ATLEAST(1, 13)
-#define QSV_HAVE_EXT_VP9_PARAM QSV_VERSION_ATLEAST(1, 26)
 #define QSV_HAVE_EXT_VP9_TILES QSV_VERSION_ATLEAST(1, 29)
 
-#define QSV_HAVE_TRELLIS QSV_VERSION_ATLEAST(1, 8)
-#define QSV_HAVE_MAX_SLICE_SIZE QSV_VERSION_ATLEAST(1, 9)
-#define QSV_HAVE_DISABLEDEBLOCKIDC QSV_VERSION_ATLEAST(1, 9)
-#define QSV_HAVE_BREF_TYPE      QSV_VERSION_ATLEAST(1, 8)
-
-#define QSV_HAVE_LA     QSV_VERSION_ATLEAST(1, 7)
-#define QSV_HAVE_LA_DS  QSV_VERSION_ATLEAST(1, 8)
-#define QSV_HAVE_LA_HRD QSV_VERSION_ATLEAST(1, 11)
-#define QSV_HAVE_VDENC  QSV_VERSION_ATLEAST(1, 15)
-#define QSV_HAVE_PREF   QSV_VERSION_ATLEAST(1, 16)
-
-#define QSV_HAVE_GPB    QSV_VERSION_ATLEAST(1, 18)
-
 #if defined(_WIN32) || defined(__CYGWIN__)
-#define QSV_HAVE_AVBR   QSV_VERSION_ATLEAST(1, 3)
-#define QSV_HAVE_ICQ    QSV_VERSION_ATLEAST(1, 8)
-#define QSV_HAVE_VCM    QSV_VERSION_ATLEAST(1, 8)
-#define QSV_HAVE_QVBR   QSV_VERSION_ATLEAST(1, 11)
+#define QSV_HAVE_AVBR   1
+#define QSV_HAVE_VCM    1
 #define QSV_HAVE_MF     0
 #else
 #define QSV_HAVE_AVBR   0
-#define QSV_HAVE_ICQ    QSV_VERSION_ATLEAST(1, 28)
 #define QSV_HAVE_VCM    0
-#define QSV_HAVE_QVBR   QSV_VERSION_ATLEAST(1, 28)
-#define QSV_HAVE_MF     QSV_VERSION_ATLEAST(1, 25)
-#endif
-
-#if !QSV_HAVE_LA_DS
-#define MFX_LOOKAHEAD_DS_UNKNOWN 0
-#define MFX_LOOKAHEAD_DS_OFF 0
-#define MFX_LOOKAHEAD_DS_2x 0
-#define MFX_LOOKAHEAD_DS_4x 0
+#define QSV_HAVE_MF     1
 #endif
 
 #define QSV_COMMON_OPTS \
@@ -126,22 +96,14 @@  typedef struct QSVEncContext {
     mfxFrameAllocRequest req;
 
     mfxExtCodingOption  extco;
-#if QSV_HAVE_CO2
     mfxExtCodingOption2 extco2;
-#endif
-#if QSV_HAVE_CO3
     mfxExtCodingOption3 extco3;
-#endif
 #if QSV_HAVE_MF
     mfxExtMultiFrameParam   extmfp;
     mfxExtMultiFrameControl extmfc;
 #endif
-#if QSV_HAVE_EXT_HEVC_TILES
     mfxExtHEVCTiles exthevctiles;
-#endif
-#if QSV_HAVE_EXT_VP9_PARAM
     mfxExtVP9Param  extvp9param;
-#endif
 
     mfxExtOpaqueSurfaceAlloc opaque_alloc;
     mfxFrameSurface1       **opaque_surfaces;
@@ -149,7 +111,7 @@  typedef struct QSVEncContext {
 
     mfxExtVideoSignalInfo extvsi;
 
-    mfxExtBuffer  *extparam_internal[3 + QSV_HAVE_CO2 + QSV_HAVE_CO3 + (QSV_HAVE_MF * 2)];
+    mfxExtBuffer  *extparam_internal[5 + (QSV_HAVE_MF * 2)];
     int         nb_extparam_internal;
 
     mfxExtBuffer **extparam;
@@ -218,6 +180,11 @@  typedef struct QSVEncContext {
     SetEncodeCtrlCB *set_encode_ctrl_cb;
     int forced_idr;
     int low_delay_brc;
+
+    int co2_idx;
+    int co3_idx;
+    int exthevctiles_idx;
+    int vp9_idx;
 } QSVEncContext;
 
 int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q);
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index b4cf9ea456..6470e9977d 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -112,11 +112,8 @@  static const AVOption options[] = {
     { "single_sei_nal_unit",    "Put all the SEI messages into one NALU",        OFFSET(qsv.single_sei_nal_unit),     AV_OPT_TYPE_INT, { .i64 = -1 }, -1,          1, VE },
     { "max_dec_frame_buffering", "Maximum number of frames buffered in the DPB", OFFSET(qsv.max_dec_frame_buffering), AV_OPT_TYPE_INT, { .i64 = 0 },   0, UINT16_MAX, VE },
 
-#if QSV_HAVE_LA
     { "look_ahead",       "Use VBR algorithm with look ahead",    OFFSET(qsv.look_ahead),       AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
     { "look_ahead_depth", "Depth of look ahead in number frames", OFFSET(qsv.look_ahead_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, VE },
-#endif
-#if QSV_HAVE_LA_DS
     { "look_ahead_downsampling", "Downscaling factor for the frames saved for the lookahead analysis", OFFSET(qsv.look_ahead_downsampling),
                                           AV_OPT_TYPE_INT,   { .i64 = MFX_LOOKAHEAD_DS_UNKNOWN }, MFX_LOOKAHEAD_DS_UNKNOWN, MFX_LOOKAHEAD_DS_4x, VE, "look_ahead_downsampling" },
     { "unknown"                , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_UNKNOWN }, INT_MIN, INT_MAX,     VE, "look_ahead_downsampling" },
@@ -124,7 +121,6 @@  static const AVOption options[] = {
     { "off"                    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_OFF     }, INT_MIN, INT_MAX,     VE, "look_ahead_downsampling" },
     { "2x"                     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_2x      }, INT_MIN, INT_MAX,     VE, "look_ahead_downsampling" },
     { "4x"                     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_LOOKAHEAD_DS_4x      }, INT_MIN, INT_MAX,     VE, "look_ahead_downsampling" },
-#endif
 
     { "int_ref_type", "Intra refresh type. B frames should be set to 0.",        OFFSET(qsv.int_ref_type),            AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE, "int_ref_type" },
         { "none",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags = VE, "int_ref_type" },
@@ -133,9 +129,7 @@  static const AVOption options[] = {
     { "int_ref_cycle_size", "Number of frames in the intra refresh cycle",       OFFSET(qsv.int_ref_cycle_size),      AV_OPT_TYPE_INT, { .i64 = -1 },               -1, UINT16_MAX, VE },
     { "int_ref_qp_delta",   "QP difference for the refresh MBs",                 OFFSET(qsv.int_ref_qp_delta),        AV_OPT_TYPE_INT, { .i64 = INT16_MIN }, INT16_MIN,  INT16_MAX, VE },
     { "recovery_point_sei", "Insert recovery point SEI messages",                OFFSET(qsv.recovery_point_sei),      AV_OPT_TYPE_INT, { .i64 = -1 },               -1,          1, VE },
-#if QSV_VERSION_ATLEAST(1, 16)
     { "int_ref_cycle_dist",   "Distance between the beginnings of the intra-refresh cycles in frames",  OFFSET(qsv.int_ref_cycle_dist),      AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
-#endif
     { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 = MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" },
     { "unknown" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN      }, INT_MIN, INT_MAX,     VE, "profile" },
     { "baseline", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_AVC_BASELINE }, INT_MIN, INT_MAX,     VE, "profile" },
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 3a2d50e332..36d12ff06a 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -235,9 +235,7 @@  static const AVOption options[] = {
     { "load_plugins", "A :-separate list of hexadecimal plugin UIDs to load in an internal session",
         OFFSET(qsv.load_plugins), AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VE },
 
-#if QSV_HAVE_LA
     { "look_ahead_depth", "Depth of look ahead in number frames, available when extbrc option is enabled", OFFSET(qsv.look_ahead_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, VE },
-#endif
     { "profile", NULL, OFFSET(qsv.profile), AV_OPT_TYPE_INT, { .i64 = MFX_PROFILE_UNKNOWN }, 0, INT_MAX, VE, "profile" },
     { "unknown", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_UNKNOWN      }, INT_MIN, INT_MAX,     VE, "profile" },
     { "main",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = MFX_PROFILE_HEVC_MAIN    }, INT_MIN, INT_MAX,     VE, "profile" },
@@ -255,18 +253,14 @@  static const AVOption options[] = {
     { "recovery_point_sei", "Insert recovery point SEI messages",       OFFSET(qsv.recovery_point_sei),      AV_OPT_TYPE_INT, { .i64 = -1 },               -1,          1, VE },
     { "aud", "Insert the Access Unit Delimiter NAL", OFFSET(qsv.aud), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE},
     { "pic_timing_sei",    "Insert picture timing SEI with pic_struct_syntax element", OFFSET(qsv.pic_timing_sei), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
-#if QSV_VERSION_ATLEAST(1, 26)
     { "transform_skip", "Turn this option ON to enable transformskip",   OFFSET(qsv.transform_skip),          AV_OPT_TYPE_INT,    { .i64 = -1},   -1, 1,  VE},
-#endif
     { "int_ref_type", "Intra refresh type. B frames should be set to 0",         OFFSET(qsv.int_ref_type),            AV_OPT_TYPE_INT, { .i64 = -1 }, -1, UINT16_MAX, VE, "int_ref_type" },
         { "none",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, .flags = VE, "int_ref_type" },
         { "vertical", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, .flags = VE, "int_ref_type" },
         { "horizontal", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, .flags = VE, "int_ref_type" },
     { "int_ref_cycle_size", "Number of frames in the intra refresh cycle",       OFFSET(qsv.int_ref_cycle_size),      AV_OPT_TYPE_INT, { .i64 = -1 },               -1, UINT16_MAX, VE },
     { "int_ref_qp_delta",   "QP difference for the refresh MBs",                 OFFSET(qsv.int_ref_qp_delta),        AV_OPT_TYPE_INT, { .i64 = INT16_MIN }, INT16_MIN,  INT16_MAX, VE },
-#if QSV_VERSION_ATLEAST(1, 16)
     { "int_ref_cycle_dist",   "Distance between the beginnings of the intra-refresh cycles in frames",  OFFSET(qsv.int_ref_cycle_dist),      AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
-#endif
 
     { NULL },
 };
@@ -306,12 +300,8 @@  const FFCodec ff_hevc_qsv_encoder = {
                                                     AV_PIX_FMT_YUYV422,
                                                     AV_PIX_FMT_Y210,
                                                     AV_PIX_FMT_QSV,
-#if QSV_VERSION_ATLEAST(1, 17)
                                                     AV_PIX_FMT_BGRA,
-#endif
-#if QSV_VERSION_ATLEAST(1, 9)
                                                     AV_PIX_FMT_X2RGB10,
-#endif
                                                     AV_PIX_FMT_NONE },
     .p.priv_class   = &class,
     .defaults       = qsv_enc_defaults,
diff --git a/libavfilter/vf_scale_qsv.c b/libavfilter/vf_scale_qsv.c
index 371f629457..da3c2eca86 100644
--- a/libavfilter/vf_scale_qsv.c
+++ b/libavfilter/vf_scale_qsv.c
@@ -69,7 +69,6 @@  enum var_name {
     VARS_NB
 };
 
-#define QSV_HAVE_SCALING_CONFIG  QSV_VERSION_ATLEAST(1, 19)
 #define MFX_IMPL_VIA_MASK(impl) (0x0f00 & (impl))
 
 typedef struct QSVScaleContext {
@@ -92,12 +91,10 @@  typedef struct QSVScaleContext {
 
     mfxExtOpaqueSurfaceAlloc opaque_alloc;
 
-#if QSV_HAVE_SCALING_CONFIG
     mfxExtVPPScaling         scale_conf;
-#endif
     int                      mode;
 
-    mfxExtBuffer             *ext_buffers[1 + QSV_HAVE_SCALING_CONFIG];
+    mfxExtBuffer             *ext_buffers[2];
     int                      num_ext_buf;
 
     int shift_width, shift_height;
@@ -397,14 +394,12 @@  static int init_out_session(AVFilterContext *ctx)
         par.IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY | MFX_IOPATTERN_OUT_VIDEO_MEMORY;
     }
 
-#if QSV_HAVE_SCALING_CONFIG
     memset(&s->scale_conf, 0, sizeof(mfxExtVPPScaling));
     s->scale_conf.Header.BufferId     = MFX_EXTBUFF_VPP_SCALING;
     s->scale_conf.Header.BufferSz     = sizeof(mfxExtVPPScaling);
     s->scale_conf.ScalingMode         = s->mode;
     s->ext_buffers[s->num_ext_buf++]  = (mfxExtBuffer*)&s->scale_conf;
     av_log(ctx, AV_LOG_VERBOSE, "Scaling mode: %d\n", s->mode);
-#endif
 
     par.ExtParam    = s->ext_buffers;
     par.NumExtParam = s->num_ext_buf;
@@ -620,15 +615,9 @@  static const AVOption options[] = {
     { "h",      "Output video height", OFFSET(h_expr),     AV_OPT_TYPE_STRING, { .str = "ih"   }, .flags = FLAGS },
     { "format", "Output pixel format", OFFSET(format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
 
-#if QSV_HAVE_SCALING_CONFIG
     { "mode",      "set scaling mode",    OFFSET(mode),    AV_OPT_TYPE_INT,    { .i64 = MFX_SCALING_MODE_DEFAULT}, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, FLAGS, "mode"},
     { "low_power", "low power mode",        0,             AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_LOWPOWER}, INT_MIN, INT_MAX, FLAGS, "mode"},
     { "hq",        "high quality mode",     0,             AV_OPT_TYPE_CONST,  { .i64 = MFX_SCALING_MODE_QUALITY},  INT_MIN, INT_MAX, FLAGS, "mode"},
-#else
-    { "mode",      "(not supported)",     OFFSET(mode),    AV_OPT_TYPE_INT,    { .i64 = 0}, 0, INT_MAX, FLAGS, "mode"},
-    { "low_power", "",                      0,             AV_OPT_TYPE_CONST,  { .i64 = 1}, 0,   0,     FLAGS, "mode"},
-    { "hq",        "",                      0,             AV_OPT_TYPE_CONST,  { .i64 = 2}, 0,   0,     FLAGS, "mode"},
-#endif
 
     { NULL },
 };
diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index cfe343822b..6e5056d133 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -43,9 +43,6 @@ 
 
 /* number of video enhancement filters */
 #define ENH_FILTERS_COUNT (8)
-#define QSV_HAVE_ROTATION       QSV_VERSION_ATLEAST(1, 17)
-#define QSV_HAVE_MIRRORING      QSV_VERSION_ATLEAST(1, 19)
-#define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19)
 
 typedef struct VPPContext{
     const AVClass *class;
@@ -60,9 +57,7 @@  typedef struct VPPContext{
     mfxExtVPPProcAmp procamp_conf;
     mfxExtVPPRotation rotation_conf;
     mfxExtVPPMirroring mirroring_conf;
-#ifdef QSV_HAVE_SCALING_CONFIG
     mfxExtVPPScaling scale_conf;
-#endif
 
     int out_width;
     int out_height;
@@ -138,9 +133,7 @@  static const AVOption options[] = {
     { "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
     { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
     { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS },
-#ifdef QSV_HAVE_SCALING_CONFIG
     { "scale_mode", "scale mode: 0=auto, 1=low power, 2=high quality", OFFSET(scale_mode), AV_OPT_TYPE_INT, { .i64 = MFX_SCALING_MODE_DEFAULT }, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, .flags = FLAGS, "scale mode" },
-#endif
     { NULL }
 };
 
@@ -422,84 +415,83 @@  static int config_output(AVFilterLink *outlink)
     }
 
     if (vpp->transpose >= 0) {
-#ifdef QSV_HAVE_ROTATION
-        switch (vpp->transpose) {
-        case TRANSPOSE_CCLOCK_FLIP:
-            vpp->rotate = MFX_ANGLE_270;
-            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
-            break;
-        case TRANSPOSE_CLOCK:
-            vpp->rotate = MFX_ANGLE_90;
-            vpp->hflip  = MFX_MIRRORING_DISABLED;
-            break;
-        case TRANSPOSE_CCLOCK:
-            vpp->rotate = MFX_ANGLE_270;
-            vpp->hflip  = MFX_MIRRORING_DISABLED;
-            break;
-        case TRANSPOSE_CLOCK_FLIP:
-            vpp->rotate = MFX_ANGLE_90;
-            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
-            break;
-        case TRANSPOSE_REVERSAL:
-            vpp->rotate = MFX_ANGLE_180;
-            vpp->hflip  = MFX_MIRRORING_DISABLED;
-            break;
-        case TRANSPOSE_HFLIP:
-            vpp->rotate = MFX_ANGLE_0;
-            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
-            break;
-        case TRANSPOSE_VFLIP:
-            vpp->rotate = MFX_ANGLE_180;
-            vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
-            break;
-        default:
-            av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode to %d.\n", vpp->transpose);
-            return AVERROR(EINVAL);
+        if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 17)) {
+            switch (vpp->transpose) {
+            case TRANSPOSE_CCLOCK_FLIP:
+                vpp->rotate = MFX_ANGLE_270;
+                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
+                break;
+            case TRANSPOSE_CLOCK:
+                vpp->rotate = MFX_ANGLE_90;
+                vpp->hflip  = MFX_MIRRORING_DISABLED;
+                break;
+            case TRANSPOSE_CCLOCK:
+                vpp->rotate = MFX_ANGLE_270;
+                vpp->hflip  = MFX_MIRRORING_DISABLED;
+                break;
+            case TRANSPOSE_CLOCK_FLIP:
+                vpp->rotate = MFX_ANGLE_90;
+                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
+                break;
+            case TRANSPOSE_REVERSAL:
+                vpp->rotate = MFX_ANGLE_180;
+                vpp->hflip  = MFX_MIRRORING_DISABLED;
+                break;
+            case TRANSPOSE_HFLIP:
+                vpp->rotate = MFX_ANGLE_0;
+                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
+                break;
+            case TRANSPOSE_VFLIP:
+                vpp->rotate = MFX_ANGLE_180;
+                vpp->hflip  = MFX_MIRRORING_HORIZONTAL;
+                break;
+            default:
+                av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode to %d.\n", vpp->transpose);
+                return AVERROR(EINVAL);
+            }
+        } else {
+            av_log(ctx, AV_LOG_WARNING, "The QSV VPP transpose option is "
+                   "not supported with this MSDK version.\n");
+            vpp->transpose = 0;
         }
-#else
-        av_log(ctx, AV_LOG_WARNING, "The QSV VPP transpose option is "
-            "not supported with this MSDK version.\n");
-        vpp->transpose = 0;
-#endif
     }
 
     if (vpp->rotate) {
-#ifdef QSV_HAVE_ROTATION
-        memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
-        vpp->rotation_conf.Header.BufferId  = MFX_EXTBUFF_VPP_ROTATION;
-        vpp->rotation_conf.Header.BufferSz  = sizeof(mfxExtVPPRotation);
-        vpp->rotation_conf.Angle = vpp->rotate;
-
-        if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) {
-            FFSWAP(int, vpp->out_width, vpp->out_height);
-            FFSWAP(int, outlink->w, outlink->h);
-            av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock rotation.\n");
-        }
+        if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 17)) {
+            memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
+            vpp->rotation_conf.Header.BufferId  = MFX_EXTBUFF_VPP_ROTATION;
+            vpp->rotation_conf.Header.BufferSz  = sizeof(mfxExtVPPRotation);
+            vpp->rotation_conf.Angle = vpp->rotate;
+
+            if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) {
+                FFSWAP(int, vpp->out_width, vpp->out_height);
+                FFSWAP(int, outlink->w, outlink->h);
+                av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock rotation.\n");
+            }
 
-        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->rotation_conf;
-#else
-        av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
-            "not supported with this MSDK version.\n");
-        vpp->rotate = 0;
-#endif
+            param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->rotation_conf;
+        } else {
+            av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
+                   "not supported with this MSDK version.\n");
+            vpp->rotate = 0;
+        }
     }
 
     if (vpp->hflip) {
-#ifdef QSV_HAVE_MIRRORING
-        memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
-        vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
-        vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
-        vpp->mirroring_conf.Type = vpp->hflip;
-
-        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->mirroring_conf;
-#else
-        av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
-            "not supported with this MSDK version.\n");
-        vpp->hflip = 0;
-#endif
+        if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 19)) {
+            memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
+            vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
+            vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
+            vpp->mirroring_conf.Type = vpp->hflip;
+
+            param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->mirroring_conf;
+        } else {
+            av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
+                   "not supported with this MSDK version.\n");
+            vpp->hflip = 0;
+        }
     }
 
-#ifdef QSV_HAVE_SCALING_CONFIG
     if (inlink->w != outlink->w || inlink->h != outlink->h) {
         if (QSV_RUNTIME_VERSION_ATLEAST(mfx_version, 1, 19)) {
             memset(&vpp->scale_conf, 0, sizeof(mfxExtVPPScaling));
@@ -512,7 +504,6 @@  static int config_output(AVFilterLink *outlink)
             av_log(ctx, AV_LOG_WARNING, "The QSV VPP Scale option is "
                 "not supported with this MSDK version.\n");
     }
-#endif
 
     if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise ||
         vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip ||
diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 66c0e38955..dde9db2d67 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -106,11 +106,9 @@  static const struct {
 #if CONFIG_VAAPI
     { AV_PIX_FMT_YUYV422,
                        MFX_FOURCC_YUY2 },
-#if QSV_VERSION_ATLEAST(1, 27)
     { AV_PIX_FMT_Y210,
                        MFX_FOURCC_Y210 },
 #endif
-#endif
 };
 
 extern int ff_qsv_get_surface_base_handle(mfxFrameSurface1 *surf,