qsv: Import libmfx API and dispatch code from oneVPL project
authorSeungha Yang <seungha@centricular.com>
Wed, 1 Dec 2021 13:18:04 +0000 (22:18 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 8 Feb 2022 10:05:35 +0000 (10:05 +0000)
Copied from oneVPL project (https://github.com/oneapi-src/oneVPL)
v2022.0.3 tag at the commit of efc259f8b7ee5c334bca1a904a503186038bbbdd

This is corresponding to MFX API version 2.6

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1408>

55 files changed:
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfx.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxadapter.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxbrc.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxcommon.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdefs.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdispatcher.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdispatcherprefixedfunctions.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfximplcaps.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxjpeg.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxmvc.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxpcp.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxsession.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxstructures.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxsurfacepool.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvideo++.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvideo.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvp8.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/device_ids.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/libvpl.map [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxloader.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxloader.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxvideo_functions.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_config.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_loader.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_log.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_log.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_lowlatency.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_msdk.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_win.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/libmfx.def [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/main.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_critical_section.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_critical_section.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_defs.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_log.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_log.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_driver_store_loader.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_driver_store_loader.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dxva2_device.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dxva2_device.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_exposed_functions_list.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_function_table.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_library_iterator.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_library_iterator.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_load_dll.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_load_dll.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_vector.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_win_reg_key.cpp [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_win_reg_key.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfxvideo++.h [new file with mode: 0644]
subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/version.rc.in [new file with mode: 0644]

diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfx.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfx.h
new file mode 100644 (file)
index 0000000..43557a2
--- /dev/null
@@ -0,0 +1,27 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFX_H__
+#define __MFX_H__
+
+#include "mfxdefs.h"
+#include "mfxcommon.h"
+#include "mfxstructures.h"
+#include "mfxdispatcher.h"
+#include "mfximplcaps.h"
+#include "mfxsession.h"
+#include "mfxvideo.h"
+#include "mfxadapter.h"
+
+#include "mfxbrc.h"
+#include "mfxmvc.h"
+#include "mfxpcp.h"
+#include "mfxvp8.h"
+#include "mfxjpeg.h"
+
+#include "mfxsurfacepool.h" 
+
+#endif /* __MFXDEFS_H__ */
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxadapter.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxadapter.h
new file mode 100644 (file)
index 0000000..5d0679f
--- /dev/null
@@ -0,0 +1,73 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "mfxdefs.h"
+#ifndef __MFXADAPTER_H__
+#define __MFXADAPTER_H__
+
+#include "mfxstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+   @brief
+    Returns a list of adapters that are suitable to handle workload @p input_info. The list is sorted in priority order, with iGPU given the highest precedence.
+    This rule may change in the future. If the @p input_info pointer is NULL, the list of all available adapters will be returned.
+
+   @param[in] input_info Pointer to workload description. See mfxComponentInfo description for details.
+   @param[out] adapters  Pointer to output description of all suitable adapters for input workload. See mfxAdaptersInfo description for details.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_NULL_PTR  
+   @p input_info or adapters pointer is NULL. \n
+   MFX_ERR_NOT_FOUND  No suitable adapters found. \n
+   MFX_WRN_OUT_OF_RANGE  Not enough memory to report back entire list of adapters. In this case as many adapters as possible will be returned.
+
+   @since This function is available since API version 1.31.
+*/
+mfxStatus MFX_CDECL MFXQueryAdapters(mfxComponentInfo* input_info, mfxAdaptersInfo* adapters);
+
+/*!
+   @brief
+    Returns list of adapters that are suitable to decode the input bitstream. The list is sorted in priority order, with iGPU given the highest precedence. This rule may change in the future. This function is a simplification of MFXQueryAdapters, because bitstream is a description of the workload itself.
+
+   @param[in]  bitstream Pointer to bitstream with input data.
+   @param[in]  codec_id  Codec ID to determine the type of codec for the input bitstream.
+   @param[out] adapters  Pointer to the output list of adapters. Memory should be allocated by user. See mfxAdaptersInfo description for details.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_NULL_PTR  bitstream or @p adapters pointer is NULL. \n
+   MFX_ERR_NOT_FOUND No suitable adapters found. \n
+   MFX_WRN_OUT_OF_RANGE Not enough memory to report back entire list of adapters. In this case as many adapters as possible will be returned.
+
+   @since This function is available since API version 1.31.
+*/
+mfxStatus MFX_CDECL MFXQueryAdaptersDecode(mfxBitstream* bitstream, mfxU32 codec_id, mfxAdaptersInfo* adapters);
+
+/*!
+   @brief
+    Returns the number of detected graphics adapters. It can be used before calling MFXQueryAdapters  to determine the size of input data that the user will need to allocate.
+
+   @param[out] num_adapters Pointer for the output number of detected graphics adapters.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_NULL_PTR  num_adapters pointer is NULL.
+
+   @since This function is available since API version 1.31.
+*/
+mfxStatus MFX_CDECL MFXQueryAdaptersNumber(mfxU32* num_adapters);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // __MFXADAPTER_H__
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxbrc.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxbrc.h
new file mode 100644 (file)
index 0000000..bd876c3
--- /dev/null
@@ -0,0 +1,175 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXBRC_H__
+#define __MFXBRC_H__
+
+#include "mfxstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*! See the mfxExtBRC structure for details. */
+enum {
+    MFX_EXTBUFF_BRC = MFX_MAKEFOURCC('E','B','R','C')
+};
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Describes frame parameters required for external BRC functions.
+*/
+typedef struct {
+    mfxU32 reserved[23];
+    mfxU16 SceneChange;     /*!< Frame belongs to a new scene if non zero. */
+    mfxU16 LongTerm;        /*!< Frame is a Long Term Reference frame if non zero. */
+    mfxU32 FrameCmplx;      /*!< Frame Complexity Frame spatial complexity if non zero. Zero if complexity is not available. */
+    mfxU32 EncodedOrder;    /*!< The frame number in a sequence of reordered frames starting from encoder Init. */
+    mfxU32 DisplayOrder;    /*!< The frame number in a sequence of frames in display order starting from last IDR. */
+    mfxU32 CodedFrameSize;  /*!< Size of the frame in bytes after encoding. */
+    mfxU16 FrameType;       /*!< Frame type. See FrameType enumerator for possible values. */
+    mfxU16 PyramidLayer;    /*!< B-pyramid or P-pyramid layer that the frame belongs to. */
+    mfxU16 NumRecode;       /*!< Number of recodings performed for this frame. */
+    mfxU16 NumExtParam;     /*!< Reserved for future use. */
+    mfxExtBuffer** ExtParam;/*!< Reserved for future use. */
+} mfxBRCFrameParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Specifies controls for next frame encoding provided by external BRC functions.
+*/
+typedef struct {
+    mfxI32 QpY;                     /*!< Frame-level Luma QP. */
+    mfxU32 InitialCpbRemovalDelay;  /*!< See initial_cpb_removal_delay in codec standard. Ignored if no HRD control:
+                                         mfxExtCodingOption::VuiNalHrdParameters = MFX_CODINGOPTION_OFF. Calculated by encoder if
+                                         initial_cpb_removal_delay==0 && initial_cpb_removal_offset == 0 && HRD control is switched on. */
+    mfxU32 InitialCpbRemovalOffset; /*!< See initial_cpb_removal_offset in codec standard. Ignored if no HRD control:
+                                         mfxExtCodingOption::VuiNalHrdParameters = MFX_CODINGOPTION_OFF. Calculated by encoder if
+                                         initial_cpb_removal_delay==0 && initial_cpb_removal_offset == 0 && HRD control is switched on. */
+    mfxU32 reserved1[7];
+    mfxU32 MaxFrameSize;            /*!< Max frame size in bytes. Option for repack feature. Driver calls PAK until current frame size is
+                                         less than or equal to maxFrameSize, or number of repacking for this frame is equal to maxNumRePak. Repack is available
+                                         if there is driver support, MaxFrameSize !=0, and MaxNumRePak != 0. Ignored if maxNumRePak == 0. */
+    mfxU8  DeltaQP[8];              /*!< Option for repack feature. Ignored if maxNumRePak == 0 or maxNumRePak==0. If current
+                                         frame size > maxFrameSize and/or number of repacking (nRepack) for this frame <= maxNumRePak,
+                                         PAK is called with QP = mfxBRCFrameCtrl::QpY + Sum(DeltaQP[i]), where i = [0,nRepack].
+                                         Non zero DeltaQP[nRepack] are ignored if nRepack > maxNumRePak.
+                                         If repacking feature is on ( maxFrameSize & maxNumRePak are not zero), it is calculated by the encoder. */
+    mfxU16 MaxNumRepak;             /*!< Number of possible repacks in driver if current frame size > maxFrameSize. Ignored if maxFrameSize==0.
+                                         See maxFrameSize description. Possible values are in the range of 0 to 8. */
+    mfxU16 NumExtParam;             /*!< Reserved for future use. */
+    mfxExtBuffer** ExtParam;        /*!< Reserved for future use. */
+} mfxBRCFrameCtrl;
+MFX_PACK_END()
+
+/*! The BRCStatus enumerator itemizes instructions to the encoder by mfxExtBrc::Update. */
+enum {
+    MFX_BRC_OK                = 0, /*!< CodedFrameSize is acceptable, no further recoding/padding/skip required, proceed to next frame. */
+    MFX_BRC_BIG_FRAME         = 1, /*!< Coded frame is too big, recoding required. */
+    MFX_BRC_SMALL_FRAME       = 2, /*!< Coded frame is too small, recoding required. */
+    MFX_BRC_PANIC_BIG_FRAME   = 3, /*!< Coded frame is too big, no further recoding possible - skip frame. */
+    MFX_BRC_PANIC_SMALL_FRAME = 4  /*!< Coded frame is too small, no further recoding possible - required padding to mfxBRCFrameStatus::MinFrameSize. */
+};
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Specifies instructions for the encoder provided by external BRC after each frame encoding. See the BRCStatus enumerator for details.
+*/
+typedef struct {
+    mfxU32 MinFrameSize;    /*!< Size in bytes, coded frame must be padded to when Status = MFX_BRC_PANIC_SMALL_FRAME. */
+    mfxU16 BRCStatus;       /*!< BRC status. See the BRCStatus enumerator for possible values. */
+    mfxU16 reserved[25];
+    mfxHDL reserved1;
+} mfxBRCFrameStatus;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Contains a set of callbacks to perform external bitrate control. Can be attached to the mfxVideoParam structure during
+   encoder initialization. Set the mfxExtCodingOption2::ExtBRC option to ON to make the encoder use the external BRC instead of the native one.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_BRC. */
+
+    mfxU32 reserved[14];
+    mfxHDL pthis;        /*!< Pointer to the BRC object. */
+
+    /*!
+       @brief Initializes the BRC session according to parameters from input mfxVideoParam and attached structures. It does not modify the input mfxVideoParam and attached structures. Invoked during MFXVideoENCODE_Init.
+
+       @param[in]      pthis Pointer to the BRC object.
+       @param[in]      par   Pointer to the mfxVideoParam structure that was used for the encoder initialization.
+
+       @return
+          MFX_ERR_NONE               The function completed successfully. \n
+          MFX_ERR_UNSUPPORTED        The function detected unsupported video parameters.
+    */
+    mfxStatus (MFX_CDECL *Init)         (mfxHDL pthis, mfxVideoParam* par);
+
+    /*!
+       @brief Resets BRC session according to new parameters. It does not modify the input mfxVideoParam and attached structures. Invoked during MFXVideoENCODE_Reset.
+
+       @param[in]      pthis Pointer to the BRC object.
+       @param[in]      par   Pointer to the mfxVideoParam structure that was used for the encoder initialization.
+
+       @return
+          MFX_ERR_NONE                       The function completed successfully. \n
+          MFX_ERR_UNSUPPORTED                The function detected unsupported video parameters. \n
+          MFX_ERR_INCOMPATIBLE_VIDEO_PARAM   The function detected that the video parameters provided by the application are incompatible with
+                                             initialization parameters. Reset requires additional memory allocation and cannot be executed.
+    */
+    mfxStatus (MFX_CDECL *Reset)        (mfxHDL pthis, mfxVideoParam* par);
+
+    /*!
+       @brief Deallocates any internal resources acquired in Init for this BRC session. Invoked during MFXVideoENCODE_Close.
+
+       @param[in]      pthis Pointer to the BRC object.
+
+       @return
+          MFX_ERR_NONE               The function completed successfully.
+    */
+    mfxStatus (MFX_CDECL *Close)        (mfxHDL pthis);
+
+    /*! @brief Returns controls (@p ctrl) to encode next frame based on info from input mfxBRCFrameParam structure (@p par) and
+               internal BRC state. Invoked asynchronously before each frame encoding or recoding.
+
+       @param[in]      pthis Pointer to the BRC object.
+       @param[in]      par   Pointer to the mfxVideoParam structure that was used for the encoder initialization.
+       @param[out]     ctrl  Pointer to the output mfxBRCFrameCtrl structure.
+
+       @return
+          MFX_ERR_NONE               The function completed successfully.
+    */
+    mfxStatus (MFX_CDECL* GetFrameCtrl) (mfxHDL pthis, mfxBRCFrameParam* par, mfxBRCFrameCtrl* ctrl);
+
+    /*!
+       @brief Updates internal BRC state and returns status to instruct encoder whether it should recode the previous frame,
+               skip the previous frame, do padding, or proceed to next frame based on info from input mfxBRCFrameParam and mfxBRCFrameCtrl structures.
+               Invoked asynchronously after each frame encoding or recoding.
+
+       @param[in]      pthis Pointer to the BRC object.
+       @param[in]      par   Pointer to the mfxVideoParam structure that was used for the encoder initialization.
+       @param[in]      ctrl  Pointer to the output mfxBRCFrameCtrl structure.
+       @param[in]    status  Pointer to the output mfxBRCFrameStatus structure.
+
+
+       @return
+          MFX_ERR_NONE               The function completed successfully.
+    */
+    mfxStatus (MFX_CDECL* Update)       (mfxHDL pthis, mfxBRCFrameParam* par, mfxBRCFrameCtrl* ctrl, mfxBRCFrameStatus* status);
+
+    mfxHDL reserved1[10];
+} mfxExtBRC;
+MFX_PACK_END()
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxcommon.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxcommon.h
new file mode 100644 (file)
index 0000000..171a86b
--- /dev/null
@@ -0,0 +1,530 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXCOMMON_H__
+#define __MFXCOMMON_H__
+#include "mfxdefs.h"
+
+#if !defined (__GNUC__)
+#pragma warning(disable: 4201)
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define MFX_MAKEFOURCC(A,B,C,D)    ((((int)A))+(((int)B)<<8)+(((int)C)<<16)+(((int)D)<<24))
+
+/* Extended Configuration Header Structure */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The common header definition for external buffers and video
+    processing hints. */
+typedef struct {
+    mfxU32  BufferId; /*!< Identifier of the buffer content. See the ExtendedBufferID enumerator for a complete list of extended buffers. */
+    mfxU32  BufferSz; /*!< Size of the buffer. */
+} mfxExtBuffer;
+MFX_PACK_END()
+
+/* Library initialization and deinitialization */
+/*!
+    This enumerator itemizes implementation types.
+    The implementation type is a bit OR’ed value of the base type and any decorative flags.
+    @note This enumerator is for legacy dispatcher compatibility only. The new dispatcher does not use it.
+ */
+typedef mfxI32 mfxIMPL;
+/*!
+    The application can use the macro MFX_IMPL_BASETYPE(x) to obtain the base implementation type.
+*/
+#define MFX_IMPL_BASETYPE(x) (0x00ff & (x))
+
+enum  {
+    MFX_IMPL_AUTO         = 0x0000,  /*!< Auto Selection/In or Not Supported/Out. */
+    MFX_IMPL_SOFTWARE     = 0x0001,  /*!< Pure software implementation. */
+    MFX_IMPL_HARDWARE     = 0x0002,  /*!< Hardware accelerated implementation (default device). */
+    MFX_IMPL_AUTO_ANY     = 0x0003,  /*!< Auto selection of any hardware/software implementation. */
+    MFX_IMPL_HARDWARE_ANY = 0x0004,  /*!< Auto selection of any hardware implementation. */
+    MFX_IMPL_HARDWARE2    = 0x0005,  /*!< Hardware accelerated implementation (2nd device). */
+    MFX_IMPL_HARDWARE3    = 0x0006,  /*!< Hardware accelerated implementation (3rd device). */
+    MFX_IMPL_HARDWARE4    = 0x0007,  /*!< Hardware accelerated implementation (4th device). */
+    MFX_IMPL_RUNTIME      = 0x0008,  /*!< This value cannot be used for session initialization. It may be returned by the MFXQueryIMPL
+                                          function to show that the session has been initialized in run-time mode. */
+    MFX_IMPL_VIA_ANY      = 0x0100,  /*!< Hardware acceleration can go through any supported OS infrastructure. This is the default value. The default value
+                                          is used by the legacy Intel(r) Media SDK if none of the MFX_IMPL_VIA_xxx flags are specified by the application. */
+    MFX_IMPL_VIA_D3D9     = 0x0200,  /*!< Hardware acceleration goes through the Microsoft* Direct3D* 9 infrastructure. */
+    MFX_IMPL_VIA_D3D11    = 0x0300,  /*!< Hardware acceleration goes through the Microsoft* Direct3D* 11 infrastructure. */
+    MFX_IMPL_VIA_VAAPI    = 0x0400,  /*!< Hardware acceleration goes through the Linux* VA-API infrastructure. */
+    MFX_IMPL_VIA_HDDLUNITE     = 0x0500,  /*!< Hardware acceleration goes through the HDDL* Unite*. */
+
+    MFX_IMPL_UNSUPPORTED  = 0x0000  /*!< One of the MFXQueryIMPL returns. */
+};
+
+/* Version Info */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The mfxVersion union describes the version of the implementation.*/
+typedef union {
+    /*! @brief Structure with Major and Minor fields.  */
+    /*! @struct Anonymous */
+    struct {
+        /*! @{
+          @name Major and Minor fields
+          Anonymous structure with Major and Minor fields.
+           */
+        mfxU16  Minor; /*!< Minor number of the implementation. */
+        mfxU16  Major; /*!< Major number of the implementation. */
+        /*! @} */
+    };
+    mfxU32  Version;   /*!< Implementation version number. */
+} mfxVersion;
+MFX_PACK_END()
+
+/*! The mfxPriority enumerator describes the session priority. */
+typedef enum
+{
+    MFX_PRIORITY_LOW = 0,    /*!< Low priority: the session operation halts when high priority tasks are executing and more than 75% of the CPU is being used for normal priority tasks.*/
+    MFX_PRIORITY_NORMAL = 1, /*!< Normal priority: the session operation is halted if there are high priority tasks.*/
+    MFX_PRIORITY_HIGH = 2    /*!< High priority: the session operation blocks other lower priority session operations.*/
+
+} mfxPriority;
+
+typedef struct _mfxEncryptedData mfxEncryptedData;
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*! Defines the buffer that holds compressed video data. */
+typedef struct {
+     /*! @internal :unnamed(union) @endinternal */
+     union {
+        struct {
+            mfxEncryptedData* EncryptedData; /*!< Reserved and must be zero. */
+            mfxExtBuffer **ExtParam;         /*!< Array of extended buffers for additional bitstream configuration. See the ExtendedBufferID enumerator for a complete list of extended buffers. */
+            mfxU16  NumExtParam;             /*!< The number of extended buffers attached to this structure. */
+            mfxU32  CodecId;                 /*!< Specifies the codec format identifier in the FourCC code. See the CodecFormatFourCC enumerator for details. This optional parameter is required for the simplified decode initialization.  */
+
+        };
+         mfxU32  reserved[6];
+     };
+    /*! Decode time stamp of the compressed bitstream in units of 90KHz. A value of MFX_TIMESTAMP_UNKNOWN indicates that there is no time stamp.
+
+        This value is calculated by the encoder from the presentation time stamp provided by the application in the mfxFrameSurface1 structure and
+        from the frame rate provided by the application during the encoder initialization. */
+    mfxI64  DecodeTimeStamp;
+    mfxU64  TimeStamp;                       /*!< Time stamp of the compressed bitstream in units of 90KHz. A value of MFX_TIMESTAMP_UNKNOWN indicates that there is no time stamp. */
+    mfxU8*  Data;                            /*!< Bitstream buffer pointer, 32-bytes aligned. */
+    mfxU32  DataOffset;                      /*!< Next reading or writing position in the bitstream buffer. */
+    mfxU32  DataLength;                      /*!< Size of the actual bitstream data in bytes. */
+    mfxU32  MaxLength;                       /*!< Allocated bitstream buffer size in bytes. */
+
+    mfxU16  PicStruct;                       /*!< Type of the picture in the bitstream. Output parameter. */
+    mfxU16  FrameType;                       /*!< Frame type of the picture in the bitstream. Output parameter. */
+    mfxU16  DataFlag;                        /*!< Indicates additional bitstream properties. See the BitstreamDataFlag enumerator for details. */
+    mfxU16  reserved2;                       /*!< Reserved for future use. */
+} mfxBitstream;
+MFX_PACK_END()
+
+/*! Synchronization point object handle. */
+typedef struct _mfxSyncPoint *mfxSyncPoint;
+
+/*! The GPUCopy enumerator controls usage of GPU accelerated copying between video and system memory in the legacy Intel(r) Media SDK components. */
+enum {
+    MFX_GPUCOPY_DEFAULT = 0, /*!< Use default mode for the legacy Intel(r) Media SDK implementation. */
+    MFX_GPUCOPY_ON      = 1, /*!< Enable GPU accelerated copying. */
+    MFX_GPUCOPY_OFF     = 2  /*!< Disable GPU accelerated copying. */
+};
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! Specifies advanced initialization parameters.
+    A zero value in any of the fields indicates that the corresponding field
+    is not explicitly specified.
+*/
+typedef struct {
+    mfxIMPL     Implementation;  /*!< Enumerator that indicates the desired legacy Intel(r) Media SDK implementation. */
+    mfxVersion  Version;         /*!< Structure which specifies minimum library version or zero, if not specified. */
+    mfxU16      ExternalThreads; /*!< Desired threading mode. Value 0 means internal threading, 1 – external. */
+    /*! @internal :unnamed(union) @endinternal */
+    union {
+        struct {
+            mfxExtBuffer **ExtParam; /*!< Points to an array of pointers to the extra configuration structures; see the ExtendedBufferID enumerator for a list of extended configurations. */
+            mfxU16  NumExtParam;     /*!< The number of extra configuration structures attached to this structure. */
+        };
+        mfxU16  reserved2[5];
+    };
+    mfxU16      GPUCopy;         /*!< Enables or disables GPU accelerated copying between video and system memory in legacy Intel(r) Media SDK components. See the GPUCopy enumerator for a list of valid values. */
+    mfxU16      reserved[21];
+} mfxInitParam;
+MFX_PACK_END()
+
+enum {
+    MFX_EXTBUFF_THREADS_PARAM = MFX_MAKEFOURCC('T','H','D','P') /*!< mfxExtThreadsParam buffer ID */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies options for threads created by this session. Attached to the
+    mfxInitParam structure during legacy Intel(r) Media SDK session initialization
+    or to mfxInitializationParam by the dispatcher in MFXCreateSession function. */
+typedef struct {
+    mfxExtBuffer Header;         /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_THREADS_PARAM. */
+
+    mfxU16       NumThread;      /*!< The number of threads. */
+    mfxI32       SchedulingType; /*!< Scheduling policy for all threads.*/
+    mfxI32       Priority;       /*!< Priority for all threads. */
+    mfxU16       reserved[55];   /*!< Reserved for future use. */
+} mfxExtThreadsParam;
+MFX_PACK_END()
+
+/*! The PlatformCodeName enumerator itemizes product code names for platforms. 
+    For details about Intel code names, see ark.intel.com. */
+enum {
+    MFX_PLATFORM_UNKNOWN        = 0,  /*!< Unknown platform. */
+    MFX_PLATFORM_SANDYBRIDGE    = 1,  /*!< Intel(r) microarchitecture code name Sandy Bridge. */
+    MFX_PLATFORM_IVYBRIDGE      = 2,  /*!< Intel(r) microarchitecture code name Ivy Bridge. */
+    MFX_PLATFORM_HASWELL        = 3,  /*!< Code name Haswell. */
+    MFX_PLATFORM_BAYTRAIL       = 4,  /*!< Code name Bay Trail. */
+    MFX_PLATFORM_BROADWELL      = 5,  /*!< Intel(r) microarchitecture code name Broadwell. */
+    MFX_PLATFORM_CHERRYTRAIL    = 6,  /*!< Code name Cherry Trail. */
+    MFX_PLATFORM_SKYLAKE        = 7,  /*!< Intel(r) microarchitecture code name Skylake. */
+    MFX_PLATFORM_APOLLOLAKE     = 8,  /*!< Code name Apollo Lake. */
+    MFX_PLATFORM_KABYLAKE       = 9,  /*!< Code name Kaby Lake. */
+    MFX_PLATFORM_GEMINILAKE     = 10, /*!< Code name Gemini Lake. */
+    MFX_PLATFORM_COFFEELAKE     = 11, /*!< Code name Coffee Lake. */
+    MFX_PLATFORM_CANNONLAKE     = 20, /*!< Code name Cannon Lake. */
+    MFX_PLATFORM_ICELAKE        = 30, /*!< Code name Ice Lake. */
+    MFX_PLATFORM_JASPERLAKE     = 32, /*!< Code name Jasper Lake. */
+    MFX_PLATFORM_ELKHARTLAKE    = 33, /*!< Code name Elkhart Lake. */
+    MFX_PLATFORM_TIGERLAKE      = 40, /*!< Code name Tiger Lake. */
+    MFX_PLATFORM_ROCKETLAKE     = 42, /*!< Code name Rocket Lake. */
+    MFX_PLATFORM_ALDERLAKE_S    = 43, /*!< Code name Alder Lake S. */
+    MFX_PLATFORM_ALDERLAKE_P    = 44, /*!< Code name Alder Lake P. */
+    MFX_PLATFORM_ARCTICSOUND_P  = 45,
+    MFX_PLATFORM_XEHP_SDV       = 45, /*!< Code name XeHP SDV. */
+    MFX_PLATFORM_DG2            = 46, /*!< Code name DG2. */
+    MFX_PLATFORM_ATS_M          = 46, /*!< Code name ATS-M, same media functionality as DG2. */
+    MFX_PLATFORM_KEEMBAY        = 50, /*!< Code name Keem Bay. */
+};
+
+/*! The mfxMediaAdapterType enumerator itemizes types of graphics adapters. */
+typedef enum
+{
+    MFX_MEDIA_UNKNOWN           = 0xffff, /*!< Unknown type. */
+    MFX_MEDIA_INTEGRATED        = 0,      /*!< Integrated graphics adapter. */
+    MFX_MEDIA_DISCRETE          = 1       /*!< Discrete graphics adapter. */
+} mfxMediaAdapterType;
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Contains information about hardware platform for the Legacy mode. */
+typedef struct {
+    mfxU16 CodeName;         /*!< Microarchitecture code name. See the PlatformCodeName enumerator for a list of possible values. */
+    mfxU16 DeviceId;         /*!< Unique identifier of graphics device. */
+    mfxU16 MediaAdapterType; /*!< Description of graphics adapter type. See the mfxMediaAdapterType enumerator for a list of possible values. */
+    mfxU16 reserved[13];     /*!< Reserved for future use. */
+} mfxPlatform;
+MFX_PACK_END()
+
+
+/* The mfxResourceType enumerator specifies types of different native data frames and buffers. */
+typedef enum {
+    MFX_RESOURCE_SYSTEM_SURFACE                  = 1, /*!< System memory. */
+    MFX_RESOURCE_VA_SURFACE_PTR                  = 2, /*!< Pointer to VA surface index. */
+    MFX_RESOURCE_VA_SURFACE                      = MFX_RESOURCE_VA_SURFACE_PTR, /*!< Pointer to VA surface index. */
+    MFX_RESOURCE_VA_BUFFER_PTR                   = 3, /*!< Pointer to VA buffer index. */
+    MFX_RESOURCE_VA_BUFFER                       = MFX_RESOURCE_VA_BUFFER_PTR, /*!< Pointer to VA buffer index. */
+    MFX_RESOURCE_DX9_SURFACE                     = 4, /*!< IDirect3DSurface9. */
+    MFX_RESOURCE_DX11_TEXTURE                    = 5, /*!< ID3D11Texture2D. */
+    MFX_RESOURCE_DX12_RESOURCE                   = 6, /*!< ID3D12Resource. */
+    MFX_RESOURCE_DMA_RESOURCE                    = 7, /*!< DMA resource. */
+    MFX_RESOURCE_HDDLUNITE_REMOTE_MEMORY         = 8, /*!< HDDL Unite Remote memory handle. */
+} mfxResourceType;
+
+/*! Maximum allowed length of the implementation name. */
+#define MFX_IMPL_NAME_LEN         32
+/*! Maximum allowed length of the implementation name. */
+#define MFX_STRFIELD_LEN          128
+
+#define MFX_DECODERDESCRIPTION_VERSION MFX_STRUCT_VERSION(1, 0)
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! The mfxDecoderDescription structure represents the description of a decoder. */
+typedef struct {
+    mfxStructVersion Version;                            /*!< Version of the structure. */
+    mfxU16 reserved[7];                                  /*!< Reserved for future use. */
+    mfxU16 NumCodecs;                                    /*!< Number of supported decoders. */
+    /*! This structure represents the decoder description. */
+    struct decoder {
+        mfxU32 CodecID;                                  /*!< Decoder ID in FourCC format. */
+        mfxU16 reserved[8];                              /*!< Reserved for future use. */
+        mfxU16 MaxcodecLevel;                            /*!< Maximum supported codec level. See the CodecProfile enumerator for possible values. */
+        mfxU16 NumProfiles;                              /*!< Number of supported profiles. */
+        /*! This structure represents the codec profile description. */
+        struct decprofile {
+           mfxU32 Profile;                               /*!< Profile ID. See the CodecProfile enumerator for possible values.*/
+           mfxU16 reserved[7];                           /*!< Reserved for future use. */
+           mfxU16 NumMemTypes;                           /*!< Number of supported memory types. */
+           /*! This structure represents the underlying details of the memory type. */
+           struct decmemdesc {
+              mfxResourceType MemHandleType;             /*!< Memory handle type. */
+              mfxRange32U Width;                         /*!< Range of supported image widths. */
+              mfxRange32U Height;                        /*!< Range of supported image heights. */
+              mfxU16 reserved[7];                        /*!< Reserved for future use. */
+              mfxU16 NumColorFormats;                    /*!< Number of supported output color formats. */
+              mfxU32* ColorFormats;                      /*!< Pointer to the array of supported output color formats (in FOURCC). */
+           } * MemDesc;                                  /*!< Pointer to the array of memory types. */
+        } * Profiles;                                    /*!< Pointer to the array of profiles supported by the codec. */
+    } * Codecs;                                          /*!< Pointer to the array of decoders. */
+} mfxDecoderDescription;
+MFX_PACK_END()
+
+#define MFX_ENCODERDESCRIPTION_VERSION MFX_STRUCT_VERSION(1, 0)
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! This structure represents an encoder description. */
+typedef struct {
+    mfxStructVersion Version;                            /*!< Version of the structure. */
+    mfxU16 reserved[7];                                  /*!< Reserved for future use. */
+    mfxU16 NumCodecs;                                    /*!< Number of supported encoders. */
+    /*! This structure represents encoder description. */
+    struct encoder {
+        mfxU32 CodecID;                                  /*!< Encoder ID in FourCC format. */
+        mfxU16 MaxcodecLevel;                            /*!< Maximum supported codec level. See the CodecProfile enumerator for possible values. */
+        mfxU16 BiDirectionalPrediction;                  /*!< Indicates B-frames support. */
+        mfxU16 reserved[7];                              /*!< Reserved for future use. */
+        mfxU16 NumProfiles;                              /*!< Number of supported profiles. */
+        /*! This structure represents the codec profile description. */
+        struct encprofile {
+           mfxU32 Profile;                               /*!< Profile ID. See the CodecProfile enumerator for possible values.*/
+           mfxU16 reserved[7];                           /*!< Reserved for future use. */
+           mfxU16 NumMemTypes;                           /*!< Number of supported memory types. */
+           /*! This structure represents the underlying details of the memory type. */
+           struct encmemdesc {
+              mfxResourceType MemHandleType;             /*!< Memory handle type. */
+              mfxRange32U Width;                         /*!< Range of supported image widths. */
+              mfxRange32U Height;                        /*!< Range of supported image heights. */
+              mfxU16 reserved[7];                        /*!< Reserved for future use. */
+              mfxU16 NumColorFormats;                    /*!< Number of supported input color formats. */
+              mfxU32* ColorFormats;                      /*!< Pointer to the array of supported input color formats (in FOURCC). */
+           } * MemDesc;                                  /*!< Pointer to the array of memory types. */
+        } * Profiles;                                    /*!< Pointer to the array of profiles supported by the codec. */
+    } * Codecs;                                          /*!< Pointer to the array of encoders. */
+} mfxEncoderDescription;
+MFX_PACK_END()
+
+#define MFX_VPPDESCRIPTION_VERSION MFX_STRUCT_VERSION(1, 0)
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! This structure represents VPP description. */
+typedef struct {
+    mfxStructVersion Version;                            /*!< Version of the structure. */
+    mfxU16 reserved[7];                                  /*!< Reserved for future use. */
+    mfxU16 NumFilters;                                   /*!< Number of supported VPP filters. */
+    /*! This structure represents the VPP filters description. */
+    struct filter {
+       mfxU32 FilterFourCC;                              /*!< Filter ID in FourCC format. */
+       mfxU16 MaxDelayInFrames;                          /*!< Introduced output delay in frames. */
+       mfxU16 reserved[7];                               /*!< Reserved for future use. */
+       mfxU16 NumMemTypes;                               /*!< Number of supported memory types. */
+       /*! This structure represents the underlying details of the memory type. */
+       struct memdesc {
+          mfxResourceType MemHandleType;                 /*!< Memory handle type. */
+          mfxRange32U Width;                             /*!< Range of supported image widths. */
+          mfxRange32U Height;                            /*!< Range of supported image heights. */
+          mfxU16 reserved[7];                            /*!< Reserved for future use. */
+          mfxU16 NumInFormats;                           /*!< Number of supported input color formats. */
+          /*! This structure represents the input color format description. */
+          struct format {
+             mfxU32 InFormat;                            /*!< Input color in FourCC format. */
+             mfxU16 reserved[5];                         /*!< Reserved for future use. */
+             mfxU16 NumOutFormat;                        /*!< Number of supported output color formats. */
+             mfxU32* OutFormats;                         /*!< Pointer to the array of supported output color formats (in FOURCC). */
+          } * Formats;                                   /*!< Pointer to the array of supported formats. */
+       } * MemDesc;                                      /*!< Pointer to the array of memory types. */
+    } * Filters;                                         /*!< Pointer to the array of supported filters. */
+} mfxVPPDescription;
+MFX_PACK_END()
+
+/*! The current version of mfxDeviceDescription structure. */
+#define MFX_DEVICEDESCRIPTION_VERSION MFX_STRUCT_VERSION(1, 1)
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! This structure represents device description. */
+typedef struct {
+    mfxStructVersion Version;                            /*!< Version of the structure. */
+    mfxU16 reserved[6];                                  /*!< reserved for future use. */
+    mfxU16 MediaAdapterType; /*!< Graphics adapter type. See the mfxMediaAdapterType enumerator for a list of possible values. */
+    mfxChar DeviceID[MFX_STRFIELD_LEN];                  /*!< Null terminated string with device ID. */
+    mfxU16 NumSubDevices;                                /*!< Number of available uniform sub-devices. Pure software implementation can report 0. */
+    /*! This structure represents sub-device description. */
+    struct subdevices {
+       mfxU32 Index;                                     /*!< Index of the sub-device, started from 0 and increased by 1.*/
+       mfxChar SubDeviceID[MFX_STRFIELD_LEN];            /*!< Null terminated string with unique sub-device ID, mapped to the system ID. */
+       mfxU32 reserved[7];                               /*!< reserved for future use. */
+    } * SubDevices;                                      /*!< Pointer to the array of available sub-devices. */
+} mfxDeviceDescription;
+MFX_PACK_END()
+
+/*! This enum itemizes implementation type. */
+typedef enum {
+    MFX_IMPL_TYPE_SOFTWARE = 0x0001,  /*!< Pure Software Implementation. */
+    MFX_IMPL_TYPE_HARDWARE = 0x0002,  /*!< Hardware Accelerated Implementation. */
+} mfxImplType;
+
+/*! This enum itemizes hardware acceleration stack to use. */
+typedef enum {
+    MFX_ACCEL_MODE_NA           = 0,       /*!< Hardware acceleration is not applicable. */
+    MFX_ACCEL_MODE_VIA_D3D9     = 0x0200,  /*!< Hardware acceleration goes through the Microsoft* Direct3D9* infrastructure. */
+    MFX_ACCEL_MODE_VIA_D3D11    = 0x0300,  /*!< Hardware acceleration goes through the Microsoft* Direct3D11* infrastructure. */
+    MFX_ACCEL_MODE_VIA_VAAPI    = 0x0400,  /*!< Hardware acceleration goes through the Linux* VA-API infrastructure. */
+    MFX_ACCEL_MODE_VIA_VAAPI_DRM_RENDER_NODE    = MFX_ACCEL_MODE_VIA_VAAPI,  /*!< Hardware acceleration goes through the Linux* VA-API infrastructure with DRM RENDER MODE as default acceleration access point. */
+    MFX_ACCEL_MODE_VIA_VAAPI_DRM_MODESET = 0x0401, /*!< Hardware acceleration goes through the Linux* VA-API infrastructure with DRM MODESET as  default acceleration access point. */
+    MFX_ACCEL_MODE_VIA_VAAPI_GLX = 0x0402, /*! Hardware acceleration goes through the Linux* VA-API infrastructure with OpenGL Extension to the X Window System
+                                              as default acceleration access point. */
+    MFX_ACCEL_MODE_VIA_VAAPI_X11 = 0x0403, /*!< Hardware acceleration goes through the Linux* VA-API infrastructure with X11 as default acceleration access point. */
+    MFX_ACCEL_MODE_VIA_VAAPI_WAYLAND = 0x0404, /*!< Hardware acceleration goes through the Linux* VA-API infrastructure with Wayland as default acceleration access point. */
+    MFX_ACCEL_MODE_VIA_HDDLUNITE    = 0x0500,  /*!< Hardware acceleration goes through the HDDL* Unite*. */
+} mfxAccelerationMode;
+
+#define MFX_ACCELERATIONMODESCRIPTION_VERSION MFX_STRUCT_VERSION(1, 0)
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! This structure represents acceleration modes description. */
+typedef struct {
+    mfxStructVersion Version;                            /*!< Version of the structure. */
+    mfxU16 reserved[2];                                  /*!< reserved for future use. */
+    mfxU16 NumAccelerationModes;                         /*!< Number of supported acceleration modes. */
+    mfxAccelerationMode* Mode;                           /*!< Pointer to the array of supported acceleration modes. */
+} mfxAccelerationModeDescription;
+MFX_PACK_END()
+
+/*! Specifies the surface pool allocation policies. */
+ typedef enum {
+    /*! Recommends to limit max pool size by sum of requested surfaces asked by components. */
+    MFX_ALLOCATION_OPTIMAL = 0, 
+
+    /*! Dynamic allocation with no limit. */
+    MFX_ALLOCATION_UNLIMITED   = 1, 
+    
+    /*! Max pool size is limited by NumberToPreAllocate + DeltaToAllocateOnTheFly. */
+    MFX_ALLOCATION_LIMITED     = 2,  
+
+} mfxPoolAllocationPolicy;
+
+/*! The current version of mfxPoolPolicyDescription structure. */
+#define MFX_POOLPOLICYDESCRIPTION_VERSION MFX_STRUCT_VERSION(1, 0)
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! This structure represents pool policy description. */
+typedef struct {
+    mfxStructVersion Version;                       /*!< Version of the structure. */
+    mfxU16 reserved[2];                             /*!< reserved for future use. */
+    mfxU16 NumPoolPolicies;                         /*!< Number of supported pool policies. */
+    mfxPoolAllocationPolicy* Policy;                /*!< Pointer to the array of supported pool policies. */
+} mfxPoolPolicyDescription;
+MFX_PACK_END()
+
+/*! The current version of mfxImplDescription structure. */
+#define MFX_IMPLDESCRIPTION_VERSION MFX_STRUCT_VERSION(1, 2)
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! This structure represents the implementation description. */
+typedef struct {
+    mfxStructVersion       Version;                      /*!< Version of the structure. */
+    mfxImplType            Impl;                         /*!< Impl type: software/hardware. */
+    mfxAccelerationMode    AccelerationMode;             /*!< Default Hardware acceleration stack to use. OS dependent parameter. Use VA for Linux* and DX* for Windows*. */
+    mfxVersion             ApiVersion;                   /*!< Supported API version. */
+    mfxChar                ImplName[MFX_IMPL_NAME_LEN];  /*!< Null-terminated string with implementation name given by vendor. */
+    mfxChar                License[MFX_STRFIELD_LEN];    /*!< Null-terminated string with comma-separated list of license names of the implementation. */
+    mfxChar                Keywords[MFX_STRFIELD_LEN];   /*!< Null-terminated string with comma-separated list of keywords specific to this implementation that dispatcher can search for. */
+    mfxU32                 VendorID;                     /*!< Standard vendor ID 0x8086 - Intel. */
+    mfxU32                 VendorImplID;                 /*!< Vendor specific number with given implementation ID. */
+    mfxDeviceDescription   Dev;                          /*!< Supported device. */
+    mfxDecoderDescription  Dec;                          /*!< Decoder configuration. */
+    mfxEncoderDescription  Enc;                          /*!< Encoder configuration. */
+    mfxVPPDescription      VPP;                          /*!< VPP configuration. */
+    union
+    {
+        mfxAccelerationModeDescription   AccelerationModeDescription; /*!< Supported acceleration modes. */
+        mfxU32 reserved3[4];
+    };
+    mfxPoolPolicyDescription  PoolPolicies;                /*!< Supported surface pool polices. */
+    mfxU32                    reserved[8];                 /*!< Reserved for future use. */
+    mfxU32                    NumExtParam;                 /*!< Number of extension buffers. Reserved for future use. Must be 0. */
+    union {
+        mfxExtBuffer **ExtParam;                         /*!< Array of extension buffers. */
+        mfxU64       Reserved2;                          /*!< Reserved for future use. */
+    } ExtParams;                                         /*!< Extension buffers. Reserved for future. */
+} mfxImplDescription;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! This structure represents the list of names of implemented functions. */
+typedef struct {
+    mfxU16   NumFunctions;     /*!< Number of function names in the FunctionsName array. */
+    mfxChar** FunctionsName;   /*!< Array of the null-terminated strings. Each string contains name of the implemented function. */
+} mfxImplementedFunctions;
+MFX_PACK_END()
+
+#ifdef ONEVPL_EXPERIMENTAL
+
+#define MFX_EXTENDEDDEVICEID_VERSION MFX_STRUCT_VERSION(1, 0)
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies variouse physical device properties for device matching and identification outside of oneVPL. */
+typedef struct {
+    mfxStructVersion Version;                       /*!< Version of the structure. */
+    mfxU16           VendorID;                      /*!< PCI vendor ID. */
+    mfxU16           DeviceID;                      /*!< PCI device ID. */
+    mfxU32           PCIDomain;                     /*!< PCI bus domain. Equals to '0' if OS doesn't support it or
+                                                         has sequential numbering of buses accross domains. */
+    mfxU32           PCIBus;                        /*!< The number of the bus that the physical device is located on. */
+    mfxU32           PCIDevice;                     /*!< The index of the physical device on the bus. */
+    mfxU32           PCIFunction;                   /*!< The function number of the device on the physical device. */
+    mfxU8            DeviceLUID[8];                 /*!< LUID of DXGI adapter. */
+    mfxU32           LUIDDeviceNodeMask;            /*!< Bitfield identifying the node within a linked
+                                                         device adapter corresponding to the device. */
+    mfxU32           LUIDValid;                     /*!< Boolean value that will be 1 if DeviceLUID contains a valid LUID
+                                                         and LUIDDeviceNodeMask contains a valid node mask,
+                                                         and 0 if they do not. */
+    mfxU32           DRMRenderNodeNum;              /*!< Number of the DRM render node from the path /dev/dri/RenderD<num>.
+                                                         Value equals to 0 means that this field doesn't contain valid DRM Render
+                                                         Node number.*/
+    mfxU32           DRMPrimaryNodeNum;             /*!< Number of the DRM primary node from the path /dev/dri/card<num>.
+                                                         Value equals to 0x7FFFFFFF means that this field doesn't contain valid DRM Primary
+                                                         Node number.*/
+    mfxU8            reserved1[20];                 /*!< Reserved for future use. */
+    mfxChar          DeviceName[MFX_STRFIELD_LEN];  /*!< Null-terminated string in utf-8 with the name of the device. */
+} mfxExtendedDeviceId;
+MFX_PACK_END()
+
+#endif
+
+/* The mfxImplCapsDeliveryFormat enumerator specifies delivery format of the implementation capability. */
+typedef enum {
+    MFX_IMPLCAPS_IMPLDESCSTRUCTURE       = 1,  /*!< Deliver capabilities as mfxImplDescription structure. */
+    MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS    = 2,  /*!< Deliver capabilities as mfxImplementedFunctions structure. */
+    MFX_IMPLCAPS_IMPLPATH                = 3,  /*!< Deliver pointer to the null-terminated string with the path to the
+                                                    implementation. String is delivered in a form of buffer of
+                                                    mfxChar type. */
+#ifdef ONEVPL_EXPERIMENTAL
+    MFX_IMPLCAPS_DEVICE_ID_EXTENDED      = 4   /*!< Deliver extended device ID information as mfxExtendedDeviceId
+                                                    structure.*/
+#endif
+} mfxImplCapsDeliveryFormat;
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! Specifies initialization parameters for API version starting from 2.0.
+*/
+typedef struct {
+    mfxAccelerationMode    AccelerationMode; /*!< Hardware acceleration stack to use. OS dependent parameter. Use VA for Linux*, DX* for Windows* or HDDL. */
+    mfxU16  reserved[3];                     /*!< Reserved for future use. */
+    mfxU16  NumExtParam;                     /*!< The number of extra configuration structures attached to this structure. */
+    mfxExtBuffer **ExtParam;                 /*!< Points to an array of pointers to the extra configuration structures; see the ExtendedBufferID enumerator for a list of extended configurations. */
+    mfxU32      VendorImplID;                /*!< Vendor specific number with given implementation ID. Represents the same field from mfxImplDescription. */
+    mfxU32      reserved2[3];                /*!< Reserved for future use. */
+} mfxInitializationParam;
+MFX_PACK_END()
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdefs.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdefs.h
new file mode 100644 (file)
index 0000000..e31c6f4
--- /dev/null
@@ -0,0 +1,337 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXDEFS_H__
+#define __MFXDEFS_H__
+
+#define MFX_VERSION_MAJOR 2
+#define MFX_VERSION_MINOR 6
+
+// MFX_VERSION - version of API that 'assumed' by build may be provided externally
+// if it omitted then latest stable API derived from Major.Minor is assumed
+
+
+#if !defined(MFX_VERSION)
+    #define MFX_VERSION (MFX_VERSION_MAJOR * 1000 + MFX_VERSION_MINOR)
+#else
+  #undef MFX_VERSION_MAJOR
+  #define MFX_VERSION_MAJOR ((MFX_VERSION) / 1000)
+  
+  #undef MFX_VERSION_MINOR
+  #define MFX_VERSION_MINOR ((MFX_VERSION) % 1000)
+#endif
+
+/*! The corresponding version of the Intel(r) Media SDK legacy API that is used as a basis
+   for the current API. */
+
+#define MFX_LEGACY_VERSION 1035
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* In preprocessor syntax # symbol has stringize meaning,
+   so to expand some macro to preprocessor pragma we need to use
+   special compiler dependent construction */
+
+#if defined(_MSC_VER)
+    #define MFX_PRAGMA_IMPL(x) __pragma(x)
+#else
+    #define MFX_PRAGMA_IMPL(x) _Pragma(#x)
+#endif
+
+#define MFX_PACK_BEGIN_X(x) MFX_PRAGMA_IMPL(pack(push, x))
+#define MFX_PACK_END()      MFX_PRAGMA_IMPL(pack(pop))
+
+/* The general rule for alignment is following:
+   - structures with pointers have 4/8 bytes alignment on 32/64 bit systems
+   - structures with fields of type mfxU64/mfxF64 (unsigned long long / double)
+     have alignment 8 bytes on 64 bit and 32 bit Windows, on Linux alignment is 4 bytes
+   - all the rest structures are 4 bytes aligned
+   - there are several exceptions: some structs which had 4-byte alignment were extended
+     with pointer / long type fields; such structs have 4-byte alignment to keep binary
+     compatibility with previously release API */
+
+#define MFX_PACK_BEGIN_USUAL_STRUCT()        MFX_PACK_BEGIN_X(4)
+
+/* 64-bit LP64 data model */
+#if defined(_WIN64) || defined(__LP64__)
+    #define MFX_PACK_BEGIN_STRUCT_W_PTR()    MFX_PACK_BEGIN_X(8)
+    #define MFX_PACK_BEGIN_STRUCT_W_L_TYPE() MFX_PACK_BEGIN_X(8)
+/* 32-bit ILP32 data model Windows* (Intel(r) architecture) */
+#elif defined(_WIN32) || defined(_M_IX86) && !defined(__linux__)
+    #define MFX_PACK_BEGIN_STRUCT_W_PTR()    MFX_PACK_BEGIN_X(4)
+    #define MFX_PACK_BEGIN_STRUCT_W_L_TYPE() MFX_PACK_BEGIN_X(8)
+/* 32-bit ILP32 data model Linux* */
+#elif defined(__ILP32__)
+    #define MFX_PACK_BEGIN_STRUCT_W_PTR()    MFX_PACK_BEGIN_X(4)
+    #define MFX_PACK_BEGIN_STRUCT_W_L_TYPE() MFX_PACK_BEGIN_X(4)
+#else
+    #error Unknown packing
+#endif
+
+#ifdef _WIN32
+  #define MFX_CDECL __cdecl
+  #define MFX_STDCALL __stdcall
+#else
+  #define MFX_CDECL
+  #define MFX_STDCALL
+#endif /* _WIN32 */
+
+#define MFX_INFINITE 0xFFFFFFFF
+
+#ifndef MFX_DEPRECATED_OFF
+   #if defined(__cplusplus) && __cplusplus >= 201402L
+     #define MFX_DEPRECATED [[deprecated]]
+     #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg [[deprecated]]
+     #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg)
+   #elif defined(__clang__)
+     #define MFX_DEPRECATED __attribute__((deprecated))
+     #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg __attribute__((deprecated))
+     #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg)
+   #elif defined(__INTEL_COMPILER)
+     #if (defined(_WIN32) || defined(_WIN64))
+       #define MFX_DEPRECATED __declspec(deprecated)
+       #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg
+       #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg) __pragma(deprecated(arg))
+     #elif defined(__linux__)
+       #define MFX_DEPRECATED __attribute__((deprecated))
+       #if defined(__cplusplus)
+         #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg __attribute__((deprecated))
+       #else
+         #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg
+       #endif
+       #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg)
+     #endif
+   #elif defined(_MSC_VER) && _MSC_VER > 1200 // VS 6 doesn't support deprecation
+     #define MFX_DEPRECATED __declspec(deprecated)
+     #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg
+     #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg) __pragma(deprecated(arg))
+   #elif defined(__GNUC__)
+     #define MFX_DEPRECATED __attribute__((deprecated))
+     #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg __attribute__((deprecated))
+     #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg)
+   #else
+     #define MFX_DEPRECATED
+     #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg
+     #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg)
+   #endif
+ #else
+   #define MFX_DEPRECATED
+   #define MFX_DEPRECATED_ENUM_FIELD_INSIDE(arg) arg
+   #define MFX_DEPRECATED_ENUM_FIELD_OUTSIDE(arg)
+ #endif
+typedef unsigned char       mfxU8;         /*!< Unsigned integer, 8 bit type. */
+typedef char                mfxI8;         /*!< Signed integer, 8 bit type. */
+typedef short               mfxI16;        /*!< Signed integer, 16 bit type. */
+typedef unsigned short      mfxU16;        /*!< Unsigned integer, 16 bit type. */
+typedef unsigned int        mfxU32;        /*!< Unsigned integer, 32 bit type. */
+typedef int                 mfxI32;        /*!< Signed integer, 32 bit type. */
+#if defined( _WIN32 ) || defined ( _WIN64 )
+typedef unsigned long       mfxUL32;       /*!< Unsigned integer, 32 bit type. */
+typedef long                mfxL32;        /*!< Signed integer, 32 bit type. */
+#else
+typedef unsigned int        mfxUL32;       /*!< Unsigned integer, 32 bit type. */
+typedef int                 mfxL32;        /*!< Signed integer, 32 bit type. */
+#endif
+typedef float               mfxF32;        /*!< Single-precision floating point, 32 bit type. */
+typedef double              mfxF64;        /*!< Double-precision floating point, 64 bit type. */
+typedef unsigned long long  mfxU64;        /*!< Unsigned integer, 64 bit type. */
+typedef long long           mfxI64;        /*!< Signed integer, 64 bit type. */
+typedef void*               mfxHDL;        /*!< Handle type. */
+typedef mfxHDL              mfxMemId;      /*!< Memory ID type. */
+typedef void*               mfxThreadTask; /*!< Thread task type. */
+typedef char                mfxChar;       /*!< UTF-8 byte. */
+
+/* MFX structures version info */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Introduce the field Version for any structure.
+Assumed that any structure changes are backward binary compatible.
+ mfxStructVersion starts from {1,0} for any new API structures. If mfxStructVersion is
+ added to the existent legacy structure (replacing reserved fields) it starts from {1, 1}.
+*/
+typedef union {
+    /*! Structure with Major and Minor fields.  */
+    /*! @struct Anonymous */
+    struct {
+      /*! @{
+      @name Major and Minor fields
+      Anonymous structure with Major and Minor fields. Minor number is incremented when reserved fields are used. Major number is incremented when the size of structure is increased. */
+        mfxU8  Minor; /*!< Minor number of the correspondent structure. */
+        mfxU8  Major; /*!< Major number of the correspondent structure. */
+      /*! @} */
+    };
+    mfxU16  Version;   /*!< Structure version number. */
+} mfxStructVersion;
+MFX_PACK_END()
+
+#define MFX_STRUCT_VERSION(MAJOR, MINOR) (256*(MAJOR) + (MINOR))
+
+
+#define MFX_VARIANT_VERSION MFX_STRUCT_VERSION(1, 0)
+
+/*! The mfxDataType enumerates data type for mfxDataType. */
+typedef enum {
+    MFX_DATA_TYPE_UNSET   = 0,            /*!< Undefined type. */
+    MFX_DATA_TYPE_U8,                     /*!< 8-bit unsigned integer. */
+    MFX_DATA_TYPE_I8,                     /*!< 8-bit signed integer. */
+    MFX_DATA_TYPE_U16,                    /*!< 16-bit unsigned integer. */
+    MFX_DATA_TYPE_I16,                    /*!< 16-bit signed integer. */
+    MFX_DATA_TYPE_U32,                    /*!< 32-bit unsigned integer. */
+    MFX_DATA_TYPE_I32,                    /*!< 32-bit signed integer. */
+    MFX_DATA_TYPE_U64,                    /*!< 64-bit unsigned integer. */
+    MFX_DATA_TYPE_I64,                    /*!< 64-bit signed integer. */
+    MFX_DATA_TYPE_F32,                    /*!< 32-bit single precision floating point. */
+    MFX_DATA_TYPE_F64,                    /*!< 64-bit double precision floating point. */
+}mfxDataType;
+
+/*! The mfxVariantType enumerator data types for mfxVariantType. */
+typedef enum {
+    MFX_VARIANT_TYPE_UNSET = MFX_DATA_TYPE_UNSET,                        /*!< Undefined type. */
+    MFX_VARIANT_TYPE_U8    = MFX_DATA_TYPE_U8,                           /*!< 8-bit unsigned integer. */
+    MFX_VARIANT_TYPE_I8    = MFX_DATA_TYPE_I8,                           /*!< 8-bit signed integer. */
+    MFX_VARIANT_TYPE_U16   = MFX_DATA_TYPE_U16,                          /*!< 16-bit unsigned integer. */
+    MFX_VARIANT_TYPE_I16   = MFX_DATA_TYPE_I16,                          /*!< 16-bit signed integer. */
+    MFX_VARIANT_TYPE_U32   = MFX_DATA_TYPE_U32,                          /*!< 32-bit unsigned integer. */
+    MFX_VARIANT_TYPE_I32   = MFX_DATA_TYPE_I32,                          /*!< 32-bit signed integer. */
+    MFX_VARIANT_TYPE_U64   = MFX_DATA_TYPE_U64,                          /*!< 64-bit unsigned integer. */
+    MFX_VARIANT_TYPE_I64   = MFX_DATA_TYPE_I64,                          /*!< 64-bit signed integer. */
+    MFX_VARIANT_TYPE_F32   = MFX_DATA_TYPE_F32,                          /*!< 32-bit single precision floating point. */
+    MFX_VARIANT_TYPE_F64   = MFX_DATA_TYPE_F64,                          /*!< 64-bit double precision floating point. */
+    MFX_VARIANT_TYPE_PTR,                                                /*!< Generic type pointer. */
+} mfxVariantType;
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! The mfxVariantType enumerator data types for mfxVariant type. */
+typedef struct {
+    mfxStructVersion Version;    /*!< Version of the structure. */
+    mfxVariantType   Type;       /*!< Value type. */
+    /*! Value data holder. */
+    union data {
+        mfxU8   U8; /*!< mfxU8 data. */
+        mfxI8   I8; /*!< mfxI8 data. */
+        mfxU16 U16; /*!< mfxU16 data. */
+        mfxI16 I16; /*!< mfxI16 data. */
+        mfxU32 U32; /*!< mfxU32 data. */
+        mfxI32 I32; /*!< mfxI32 data. */
+        mfxU64 U64; /*!< mfxU64 data. */
+        mfxI64 I64; /*!< mfxI64 data. */
+        mfxF32 F32; /*!< mfxF32 data. */
+        mfxF64 F64; /*!< mfxF64 data. */
+        mfxHDL Ptr; /*!< Pointer. When this points to a string the string must be null terminated. */
+    } Data;         /*!< Value data member. */
+} mfxVariant;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Represents a range of unsigned values. */
+typedef struct {
+    mfxU32 Min;  /*!< Minimal value of the range. */
+    mfxU32 Max;  /*!< Maximal value of the range. */
+    mfxU32 Step; /*!< Value increment. */
+} mfxRange32U;
+MFX_PACK_END()
+
+
+/*! Represents a pair of numbers of type mfxI16. */
+typedef struct {
+    mfxI16  x; /*!< First number. */
+    mfxI16  y; /*!< Second number. */
+} mfxI16Pair;
+
+/*! Represents pair of handles of type mfxHDL. */
+typedef struct {
+    mfxHDL first;  /*!< First handle. */
+    mfxHDL second; /*!< Second handle. */
+} mfxHDLPair;
+
+
+/*********************************************************************************\
+Error message
+\*********************************************************************************/
+/*! @enum mfxStatus Itemizes status codes returned by API functions. */
+typedef enum
+{
+    /* no error */
+    MFX_ERR_NONE                        = 0,    /*!< No error. */
+    /* reserved for unexpected errors */
+    MFX_ERR_UNKNOWN                     = -1,   /*!< Unknown error. */
+
+    /* error codes <0 */
+    MFX_ERR_NULL_PTR                    = -2,   /*!< Null pointer. */
+    MFX_ERR_UNSUPPORTED                 = -3,   /*!< Unsupported feature. */
+    MFX_ERR_MEMORY_ALLOC                = -4,   /*!< Failed to allocate memory. */
+    MFX_ERR_NOT_ENOUGH_BUFFER           = -5,   /*!< Insufficient buffer at input/output. */
+    MFX_ERR_INVALID_HANDLE              = -6,   /*!< Invalid handle. */
+    MFX_ERR_LOCK_MEMORY                 = -7,   /*!< Failed to lock the memory block. */
+    MFX_ERR_NOT_INITIALIZED             = -8,   /*!< Member function called before initialization. */
+    MFX_ERR_NOT_FOUND                   = -9,   /*!< The specified object is not found. */
+    MFX_ERR_MORE_DATA                   = -10,  /*!< Expect more data at input. */
+    MFX_ERR_MORE_SURFACE                = -11,  /*!< Expect more surface at output. */
+    MFX_ERR_ABORTED                     = -12,  /*!< Operation aborted. */
+    MFX_ERR_DEVICE_LOST                 = -13,  /*!< Lose the hardware acceleration device. */
+    MFX_ERR_INCOMPATIBLE_VIDEO_PARAM    = -14,  /*!< Incompatible video parameters. */
+    MFX_ERR_INVALID_VIDEO_PARAM         = -15,  /*!< Invalid video parameters. */
+    MFX_ERR_UNDEFINED_BEHAVIOR          = -16,  /*!< Undefined behavior. */
+    MFX_ERR_DEVICE_FAILED               = -17,  /*!< Device operation failure. */
+    MFX_ERR_MORE_BITSTREAM              = -18,  /*!< Expect more bitstream buffers at output. */
+    MFX_ERR_GPU_HANG                    = -21,  /*!< Device operation failure caused by GPU hang. */
+    MFX_ERR_REALLOC_SURFACE             = -22,  /*!< Bigger output surface required. */
+    MFX_ERR_RESOURCE_MAPPED             = -23,  /*!< Write access is already acquired and user requested
+                                                   another write access, or read access with MFX_MEMORY_NO_WAIT flag. */
+    MFX_ERR_NOT_IMPLEMENTED             = -24,   /*!< Feature or function not implemented. */
+    /* warnings >0 */
+    MFX_WRN_IN_EXECUTION                = 1,    /*!< The previous asynchronous operation is in execution. */
+    MFX_WRN_DEVICE_BUSY                 = 2,    /*!< The hardware acceleration device is busy. */
+    MFX_WRN_VIDEO_PARAM_CHANGED         = 3,    /*!< The video parameters are changed during decoding. */
+    MFX_WRN_PARTIAL_ACCELERATION        = 4,    /*!< Software acceleration is used. */
+    MFX_WRN_INCOMPATIBLE_VIDEO_PARAM    = 5,    /*!< Incompatible video parameters. */
+    MFX_WRN_VALUE_NOT_CHANGED           = 6,    /*!< The value is saturated based on its valid range. */
+    MFX_WRN_OUT_OF_RANGE                = 7,    /*!< The value is out of valid range. */
+    MFX_WRN_FILTER_SKIPPED              = 10,   /*!< One of requested filters has been skipped. */
+    /* low-delay partial output */
+    MFX_ERR_NONE_PARTIAL_OUTPUT         = 12,   /*!< Frame is not ready, but bitstream contains partial output. */
+
+    MFX_WRN_ALLOC_TIMEOUT_EXPIRED       = 13,   /*!< Timeout expired for internal frame allocation. */
+
+    /* threading statuses */
+    MFX_TASK_DONE = MFX_ERR_NONE,               /*!< Task has been completed. */
+    MFX_TASK_WORKING                    = 8,    /*!< There is some more work to do. */
+    MFX_TASK_BUSY                       = 9,    /*!< Task is waiting for resources. */
+
+    /* plug-in statuses */
+    MFX_ERR_MORE_DATA_SUBMIT_TASK       = -10000, /*!< Return MFX_ERR_MORE_DATA but submit internal asynchronous task. */
+
+} mfxStatus;
+
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Represents Globally Unique Identifier (GUID) with memory layout 
+    compliant to RFC 4122. See https://www.rfc-editor.org/info/rfc4122 for details. */
+typedef struct
+{
+    mfxU8 Data[16]; /*!< Array to keep GUID. */
+} mfxGUID;
+MFX_PACK_END()
+
+
+
+// Application
+#if defined(MFX_DISPATCHER_EXPOSED_PREFIX)
+
+#include "mfxdispatcherprefixedfunctions.h"
+
+#endif // MFX_DISPATCHER_EXPOSED_PREFIX
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MFXDEFS_H__ */
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdispatcher.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdispatcher.h
new file mode 100644 (file)
index 0000000..73736d5
--- /dev/null
@@ -0,0 +1,247 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXDISPATCHER_H__
+#define __MFXDISPATCHER_H__
+
+#include "mfxdefs.h"
+#include "mfxcommon.h"
+#include "mfxsession.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! Loader handle. */
+typedef struct _mfxLoader *mfxLoader;
+
+/*! Config handle. */
+typedef struct _mfxConfig *mfxConfig;
+
+/*!
+   @brief Creates the loader.
+   @return Loader Loader handle or NULL if failed.
+
+   @since This function is available since API version 2.0.
+*/
+mfxLoader MFX_CDECL MFXLoad(void);
+
+/*!
+   @brief Destroys the dispatcher.
+   @param[in] loader Loader handle.
+
+   @since This function is available since API version 2.0.
+*/
+void MFX_CDECL MFXUnload(mfxLoader loader);
+
+/*!
+   @brief Creates dispatcher configuration.
+   @details Creates the dispatcher internal configuration, which is used to filter out available implementations.
+            This configuration is used to walk through selected implementations to gather more details and select the appropriate
+            implementation to load. The loader object remembers all created mfxConfig objects and destroys them during the mfxUnload
+            function call.
+
+            Multiple configurations per single mfxLoader object are possible.
+
+            Usage example:
+            @code
+               mfxLoader loader = MFXLoad();
+               mfxConfig cfg = MFXCreateConfig(loader);
+               MFXCreateSession(loader,0,&session);
+            @endcode
+   @param[in] loader Loader handle.
+   @return Config handle or NULL pointer is failed.
+
+   @since This function is available since API version 2.0.
+*/
+mfxConfig MFX_CDECL MFXCreateConfig(mfxLoader loader);
+
+/*!
+   @brief Adds additional filter properties (any fields of the mfxImplDescription structure) to the configuration of the loader object.
+          One mfxConfig properties can hold only single filter property.
+          @note Each new call with the same parameter name will overwrite the previously set value. This may invalidate other properties.
+          @note Each new call with another parameter name will delete the previous property and create a new property based on new name's value.
+
+   @param[in] config Config handle.
+   @param[in] name Name of the parameter (see mfxImplDescription structure and example).
+   @param[in] value Value of the parameter.
+   @return
+      MFX_ERR_NONE The function completed successfully.
+      MFX_ERR_NULL_PTR    If config is NULL. \n
+      MFX_ERR_NULL_PTR    If name is NULL. \n
+      MFX_ERR_NOT_FOUND   If name contains unknown parameter name.
+      MFX_ERR_UNSUPPORTED If value data type does not equal the parameter with provided name.
+
+   @since This function is available since API version 2.0.
+*/
+mfxStatus MFX_CDECL MFXSetConfigFilterProperty(mfxConfig config, const mfxU8* name, mfxVariant value);
+
+/*!
+   @brief Iterates over filtered out implementations to gather their details. This function allocates memory to store
+          mfxImplDescription structure instance. Use the MFXDispReleaseImplDescription function to free memory allocated to the mfxImplDescription structure.
+   @param[in] loader Loader handle.
+   @param[in] i Index of the implementation.
+   @param[in] format Format in which capabilities need to be delivered. See the mfxImplCapsDeliveryFormat enumerator for more details.
+   @param[out] idesc Pointer to the mfxImplDescription structure.
+   @return
+      MFX_ERR_NONE        The function completed successfully. The idesc contains valid information.\n
+      MFX_ERR_NULL_PTR    If loader is NULL. \n
+      MFX_ERR_NULL_PTR    If idesc is NULL. \n
+      MFX_ERR_NOT_FOUND   Provided index is out of possible range. \n
+      MFX_ERR_UNSUPPORTED If requested format is not supported.
+
+   @since This function is available since API version 2.0.
+*/
+mfxStatus MFX_CDECL MFXEnumImplementations(mfxLoader loader, mfxU32 i, mfxImplCapsDeliveryFormat format, mfxHDL* idesc);
+
+
+/*!
+   @brief Loads and initializes the implementation.
+   @code
+      mfxLoader loader = MFXLoad();
+      int i=0;
+      while(1) {
+         mfxImplDescription *idesc;
+         MFXEnumImplementations(loader, i, MFX_IMPLCAPS_IMPLDESCSTRUCTURE, (mfxHDL*)&idesc);
+         if(is_good(idesc)) {
+             MFXCreateSession(loader, i,&session);
+             // ...
+             MFXDispReleaseImplDescription(loader, idesc);
+         }
+         else
+         {
+             MFXDispReleaseImplDescription(loader, idesc);
+             break;
+         }
+      }
+   @endcode
+   @param[in] loader Loader handle.
+   @param[in] i Index of the implementation.
+   @param[out] session Pointer to the session handle.
+   @return
+      MFX_ERR_NONE        The function completed successfully. The session contains a pointer to the session handle.\n
+      MFX_ERR_NULL_PTR    If loader is NULL. \n
+      MFX_ERR_NULL_PTR    If session is NULL. \n
+      MFX_ERR_NOT_FOUND   Provided index is out of possible range.
+
+   @since This function is available since API version 2.0.
+*/
+mfxStatus MFX_CDECL MFXCreateSession(mfxLoader loader, mfxU32 i, mfxSession* session);
+
+/*!
+   @brief
+      Destroys handle allocated by the MFXEnumImplementations function.
+
+   @param[in] loader   Loader handle.
+   @param[in] hdl      Handle to destroy. Can be equal to NULL.
+
+   @return
+      MFX_ERR_NONE           The function completed successfully. \n
+      MFX_ERR_NULL_PTR       If loader is NULL. \n
+      MFX_ERR_INVALID_HANDLE Provided hdl handle is not associated with this loader.
+
+   @since This function is available since API version 2.0.
+*/
+mfxStatus MFX_CDECL MFXDispReleaseImplDescription(mfxLoader loader, mfxHDL hdl);
+
+/* Helper macro definitions to add config filter properties. */
+
+/*! Adds single property of mfxU32 type.
+   @param[in] loader Valid mfxLoader object
+   @param[in] name Property name string
+   @param[in] value Property value
+*/
+#define MFX_ADD_PROPERTY_U32(loader, name, value)               \
+{                                                               \
+    mfxVariant impl_value;                                      \
+    mfxConfig  cfg = MFXCreateConfig(loader);                   \
+    impl_value.Version.Version = MFX_VARIANT_VERSION;           \
+    impl_value.Type     = MFX_VARIANT_TYPE_U32;                 \
+    impl_value.Data.U32 = value;                                \
+    MFXSetConfigFilterProperty(cfg, (mfxU8 *)name, impl_value); \
+}
+
+/*! Adds single property of mfxU16 type.
+   @param[in] loader Valid mfxLoader object
+   @param[in] name Property name string
+   @param[in] value Property value
+*/
+#define MFX_ADD_PROPERTY_U16(loader, name, value)               \
+{                                                               \
+    mfxVariant impl_value               = { 0 };                \
+    mfxConfig  cfg = MFXCreateConfig(loader);                   \
+    impl_value.Version.Version = MFX_VARIANT_VERSION;           \
+    impl_value.Type     = MFX_VARIANT_TYPE_U16;                 \
+    impl_value.Data.U16 = value;                                \
+    MFXSetConfigFilterProperty(cfg, (mfxU8 *)name, impl_value); \
+}
+
+/*! Adds single property of pointer type.
+   @param[in] loader Valid mfxLoader object
+   @param[in] name Property name string
+   @param[in] value Property value
+*/
+#define MFX_ADD_PROPERTY_PTR(loader, name, value)               \
+{                                                               \
+    mfxVariant impl_value               = { 0 };                \
+    mfxConfig  cfg = MFXCreateConfig(loader);                   \
+    impl_value.Version.Version = MFX_VARIANT_VERSION;           \
+    impl_value.Type     = MFX_VARIANT_TYPE_PTR;                 \
+    impl_value.Data.Ptr = (mfxHDL)value;                        \
+    MFXSetConfigFilterProperty(cfg, (mfxU8 *)name, impl_value); \
+}
+
+/*! Update existing property of mfxU32 type.
+   @param[in] loader Valid mfxLoader object
+   @param[in] config Valid mfxConfig object
+   @param[in] name Property name string
+   @param[in] value Property value
+*/
+#define MFX_UPDATE_PROPERTY_U32(loader, config, name, value)       \
+{                                                                  \
+    mfxVariant impl_value;                                         \
+    impl_value.Version.Version = MFX_VARIANT_VERSION;              \
+    impl_value.Type     = MFX_VARIANT_TYPE_U32;                    \
+    impl_value.Data.U32 = value;                                   \
+    MFXSetConfigFilterProperty(config, (mfxU8 *)name, impl_value); \
+}
+
+/*! Update existing property of mfxU16 type.
+   @param[in] loader Valid mfxLoader object
+   @param[in] config Valid mfxConfig object
+   @param[in] name Property name string
+   @param[in] value Property value
+*/
+#define MFX_UPDATE_PROPERTY_U16(loader, config, name, value)       \
+{                                                                  \
+    mfxVariant impl_value;                                         \
+    impl_value.Version.Version = MFX_VARIANT_VERSION;              \
+    impl_value.Type     = MFX_VARIANT_TYPE_U16;                    \
+    impl_value.Data.U16 = value;                                   \
+    MFXSetConfigFilterProperty(config, (mfxU8 *)name, impl_value); \
+}
+
+/*! Update existing property of pointer type.
+   @param[in] loader Valid mfxLoader object
+   @param[in] config Valid mfxConfig object
+   @param[in] name Property name string
+   @param[in] value Property value
+*/
+#define MFX_UPDATE_PROPERTY_PTR(loader, config, name, value)       \
+{                                                                  \
+    mfxVariant impl_value;                                         \
+    impl_value.Version.Version = MFX_VARIANT_VERSION;              \
+    impl_value.Type     = MFX_VARIANT_TYPE_PTR;                    \
+    impl_value.Data.Ptr = (mfxHDL)value;                           \
+    MFXSetConfigFilterProperty(config, (mfxU8 *)name, impl_value); \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdispatcherprefixedfunctions.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxdispatcherprefixedfunctions.h
new file mode 100644 (file)
index 0000000..c998565
--- /dev/null
@@ -0,0 +1,150 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXDISPATCHERPREFIXEDFUNCTIONS_H__
+#define __MFXDISPATCHERPREFIXEDFUNCTIONS_H__
+
+// API 1.0 functions
+#define MFXInit                          disp_MFXInit
+#define MFXClose                         disp_MFXClose
+#define MFXQueryIMPL                     disp_MFXQueryIMPL
+#define MFXQueryVersion                  disp_MFXQueryVersion
+
+#define MFXJoinSession                   disp_MFXJoinSession
+#define MFXDisjoinSession                disp_MFXDisjoinSession
+#define MFXCloneSession                  disp_MFXCloneSession
+#define MFXSetPriority                   disp_MFXSetPriority
+#define MFXGetPriority                   disp_MFXGetPriority
+
+#define MFXVideoCORE_SetFrameAllocator   disp_MFXVideoCORE_SetFrameAllocator
+#define MFXVideoCORE_SetHandle           disp_MFXVideoCORE_SetHandle
+#define MFXVideoCORE_GetHandle           disp_MFXVideoCORE_GetHandle
+#define MFXVideoCORE_SyncOperation       disp_MFXVideoCORE_SyncOperation
+
+#define MFXVideoENCODE_Query             disp_MFXVideoENCODE_Query
+#define MFXVideoENCODE_QueryIOSurf       disp_MFXVideoENCODE_QueryIOSurf
+#define MFXVideoENCODE_Init              disp_MFXVideoENCODE_Init
+#define MFXVideoENCODE_Reset             disp_MFXVideoENCODE_Reset
+#define MFXVideoENCODE_Close             disp_MFXVideoENCODE_Close
+#define MFXVideoENCODE_GetVideoParam     disp_MFXVideoENCODE_GetVideoParam
+#define MFXVideoENCODE_GetEncodeStat     disp_MFXVideoENCODE_GetEncodeStat
+#define MFXVideoENCODE_EncodeFrameAsync  disp_MFXVideoENCODE_EncodeFrameAsync
+
+#define MFXVideoDECODE_Query             disp_MFXVideoDECODE_Query
+#define MFXVideoDECODE_DecodeHeader      disp_MFXVideoDECODE_DecodeHeader
+#define MFXVideoDECODE_QueryIOSurf       disp_MFXVideoDECODE_QueryIOSurf
+#define MFXVideoDECODE_Init              disp_MFXVideoDECODE_Init
+#define MFXVideoDECODE_Reset             disp_MFXVideoDECODE_Reset
+#define MFXVideoDECODE_Close             disp_MFXVideoDECODE_Close
+#define MFXVideoDECODE_GetVideoParam     disp_MFXVideoDECODE_GetVideoParam
+#define MFXVideoDECODE_GetDecodeStat     disp_MFXVideoDECODE_GetDecodeStat
+#define MFXVideoDECODE_SetSkipMode       disp_MFXVideoDECODE_SetSkipMode
+#define MFXVideoDECODE_GetPayload        disp_MFXVideoDECODE_GetPayload
+#define MFXVideoDECODE_DecodeFrameAsync  disp_MFXVideoDECODE_DecodeFrameAsync
+
+#define MFXVideoVPP_Query                disp_MFXVideoVPP_Query
+#define MFXVideoVPP_QueryIOSurf          disp_MFXVideoVPP_QueryIOSurf
+#define MFXVideoVPP_Init                 disp_MFXVideoVPP_Init
+#define MFXVideoVPP_Reset                disp_MFXVideoVPP_Reset
+#define MFXVideoVPP_Close                disp_MFXVideoVPP_Close
+
+#define MFXVideoVPP_GetVideoParam        disp_MFXVideoVPP_GetVideoParam
+#define MFXVideoVPP_GetVPPStat           disp_MFXVideoVPP_GetVPPStat
+#define MFXVideoVPP_RunFrameVPPAsync     disp_MFXVideoVPP_RunFrameVPPAsync
+
+// API 1.1 functions
+#define MFXVideoUSER_Register            disp_MFXVideoUSER_Register
+#define MFXVideoUSER_Unregister          disp_MFXVideoUSER_Unregister
+#define MFXVideoUSER_ProcessFrameAsync   disp_MFXVideoUSER_ProcessFrameAsync
+
+// API 1.10 functions
+
+#define MFXVideoENC_Query                disp_MFXVideoENC_Query
+#define MFXVideoENC_QueryIOSurf          disp_MFXVideoENC_QueryIOSurf
+#define MFXVideoENC_Init                 disp_MFXVideoENC_Init
+#define MFXVideoENC_Reset                disp_MFXVideoENC_Reset
+#define MFXVideoENC_Close                disp_MFXVideoENC_Close
+#define MFXVideoENC_ProcessFrameAsync    disp_MFXVideoENC_ProcessFrameAsync
+#define MFXVideoVPP_RunFrameVPPAsyncEx   disp_MFXVideoVPP_RunFrameVPPAsyncEx
+#define MFXVideoUSER_Load                disp_MFXVideoUSER_Load
+#define MFXVideoUSER_UnLoad              disp_MFXVideoUSER_UnLoad
+
+// API 1.11 functions
+
+#define MFXVideoPAK_Query                disp_MFXVideoPAK_Query
+#define MFXVideoPAK_QueryIOSurf          disp_MFXVideoPAK_QueryIOSurf
+#define MFXVideoPAK_Init                 disp_MFXVideoPAK_Init
+#define MFXVideoPAK_Reset                disp_MFXVideoPAK_Reset
+#define MFXVideoPAK_Close                disp_MFXVideoPAK_Close
+#define MFXVideoPAK_ProcessFrameAsync    disp_MFXVideoPAK_ProcessFrameAsync
+
+// API 1.13 functions
+
+#define MFXVideoUSER_LoadByPath          disp_MFXVideoUSER_LoadByPath
+
+// API 1.14 functions
+#define MFXInitEx                        disp_MFXInitEx
+
+// Audio library functions
+
+// API 1.8 functions
+
+#define MFXAudioCORE_SyncOperation       disp_MFXAudioCORE_SyncOperation
+#define MFXAudioENCODE_Query             disp_MFXAudioENCODE_Query
+#define MFXAudioENCODE_QueryIOSize       disp_MFXAudioENCODE_QueryIOSize
+#define MFXAudioENCODE_Init              disp_MFXAudioENCODE_Init
+#define MFXAudioENCODE_Reset             disp_MFXAudioENCODE_Reset
+#define MFXAudioENCODE_Close             disp_MFXAudioENCODE_Close
+#define MFXAudioENCODE_GetAudioParam     disp_MFXAudioENCODE_GetAudioParam
+#define MFXAudioENCODE_EncodeFrameAsync  disp_MFXAudioENCODE_EncodeFrameAsync
+
+#define MFXAudioDECODE_Query             disp_MFXAudioDECODE_Query
+#define MFXAudioDECODE_DecodeHeader      disp_MFXAudioDECODE_DecodeHeader
+#define MFXAudioDECODE_Init              disp_MFXAudioDECODE_Init
+#define MFXAudioDECODE_Reset             disp_MFXAudioDECODE_Reset
+#define MFXAudioDECODE_Close             disp_MFXAudioDECODE_Close
+#define MFXAudioDECODE_QueryIOSize       disp_MFXAudioDECODE_QueryIOSize
+#define MFXAudioDECODE_GetAudioParam     disp_MFXAudioDECODE_GetAudioParam
+#define MFXAudioDECODE_DecodeFrameAsync  disp_MFXAudioDECODE_DecodeFrameAsync
+
+// API 1.9 functions
+
+#define MFXAudioUSER_Register            disp_MFXAudioUSER_Register
+#define MFXAudioUSER_Unregister          disp_MFXAudioUSER_Unregister
+#define MFXAudioUSER_ProcessFrameAsync   disp_MFXAudioUSER_ProcessFrameAsync
+#define MFXAudioUSER_Load                disp_MFXAudioUSER_Load
+#define MFXAudioUSER_UnLoad              disp_MFXAudioUSER_UnLoad
+
+// API 1.19 functions
+
+#define MFXVideoENC_GetVideoParam        disp_MFXVideoENC_GetVideoParam
+#define MFXVideoPAK_GetVideoParam        disp_MFXVideoPAK_GetVideoParam
+#define MFXVideoCORE_QueryPlatform       disp_MFXVideoCORE_QueryPlatform
+#define MFXVideoUSER_GetPlugin           disp_MFXVideoUSER_GetPlugin
+
+// API 2.0 functions
+#define MFXMemory_GetSurfaceForVPP       disp_MFXMemory_GetSurfaceForVPP
+#define MFXMemory_GetSurfaceForEncode    disp_MFXMemory_GetSurfaceForEncode
+#define MFXMemory_GetSurfaceForDecode    disp_MFXMemory_GetSurfaceForDecode
+
+#define MFXQueryImplsDescription         disp_MFXQueryImplsDescription
+#define MFXReleaseImplDescription        disp_MFXReleaseImplDescription
+
+#define MFXInitialize                    disp_MFXInitialize
+
+// API 2.1 functions
+#define MFXMemory_GetSurfaceForVPPOut    disp_MFXMemory_GetSurfaceForVPPOut
+
+#define MFXVideoDECODE_VPP_Init                      disp_MFXVideoDECODE_VPP_Init
+#define MFXVideoDECODE_VPP_DecodeFrameAsync          disp_MFXVideoDECODE_VPP_DecodeFrameAsync
+#define MFXVideoDECODE_VPP_Reset                     disp_MFXVideoDECODE_VPP_Reset
+#define MFXVideoDECODE_VPP_GetChannelParam           disp_MFXVideoDECODE_VPP_GetChannelParam
+#define MFXVideoDECODE_VPP_Close                     disp_MFXVideoDECODE_VPP_Close
+
+#define MFXVideoVPP_ProcessFrameAsync                disp_MFXVideoVPP_ProcessFrameAsync
+
+
+#endif 
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfximplcaps.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfximplcaps.h
new file mode 100644 (file)
index 0000000..5c7f763
--- /dev/null
@@ -0,0 +1,54 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "mfxdefs.h"
+
+#ifndef __MFXIMPLCAPS_H__
+#define __MFXIMPLCAPS_H__
+
+#include "mfxstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+   @brief
+      Delivers implementation capabilities in the requested format according to the format value.
+
+   @param[in]  format      Format in which capabilities must be delivered. See mfxImplCapsDeliveryFormat for more details.
+   @param[out] num_impls   Number of the implementations.
+
+   @return
+      Array of handles to the capability report or NULL in case of unsupported format or NULL num_impls pointer.
+      Length of array is equal to num_impls.
+
+   @since This function is available since API version 2.0.
+*/
+mfxHDL* MFX_CDECL MFXQueryImplsDescription(mfxImplCapsDeliveryFormat format, mfxU32* num_impls);
+
+/*!
+   @brief
+      Destroys the handle allocated by the MFXQueryImplsDescription function.
+      Implementation must remember which handles are released. Once the last handle is released, this function must release memory
+      allocated for the array of handles.
+
+   @param[in] hdl   Handle to destroy. Can be equal to NULL.
+
+   @return
+      MFX_ERR_NONE The function completed successfully.
+
+   @since This function is available since API version 2.0.
+*/
+mfxStatus MFX_CDECL MFXReleaseImplDescription(mfxHDL hdl);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // __MFXIMPLCAPS_H__
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxjpeg.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxjpeg.h
new file mode 100644 (file)
index 0000000..9faba26
--- /dev/null
@@ -0,0 +1,136 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFX_JPEG_H__
+#define __MFX_JPEG_H__
+
+#include "mfxdefs.h"
+#include "mfxstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* CodecId */
+enum {
+    MFX_CODEC_JPEG    = MFX_MAKEFOURCC('J','P','E','G') /*!< JPEG codec */
+};
+
+/* CodecProfile, CodecLevel */
+enum
+{
+    MFX_PROFILE_JPEG_BASELINE      = 1 /*!< Baseline JPEG profile. */
+};
+
+/*! The Rotation enumerator itemizes the JPEG rotation options. */
+enum
+{
+    MFX_ROTATION_0      = 0, /*!< No rotation. */
+    MFX_ROTATION_90     = 1, /*!< 90 degree rotation. */
+    MFX_ROTATION_180    = 2, /*!< 180 degree rotation. */
+    MFX_ROTATION_270    = 3  /*!< 270 degree rotation. */
+};
+
+enum {
+    MFX_EXTBUFF_JPEG_QT      = MFX_MAKEFOURCC('J','P','G','Q'), /*!< This extended buffer defines quantization tables for JPEG encoder. */
+    MFX_EXTBUFF_JPEG_HUFFMAN = MFX_MAKEFOURCC('J','P','G','H')  /*!< This extended buffer defines Huffman tables for JPEG encoder. */
+};
+
+/*! The JPEGColorFormat enumerator itemizes the JPEG color format options. */
+enum {
+    MFX_JPEG_COLORFORMAT_UNKNOWN = 0, /*! Unknown color format. The decoder tries to determine color format from available in bitstream information.
+                                          If such information is not present, then MFX_JPEG_COLORFORMAT_YCbCr color format is assumed. */
+    MFX_JPEG_COLORFORMAT_YCbCr   = 1, /*! Bitstream contains Y, Cb and Cr components. */
+    MFX_JPEG_COLORFORMAT_RGB     = 2  /*! Bitstream contains R, G and B components. */
+};
+
+/*! The JPEGScanType enumerator itemizes the JPEG scan types. */
+enum {
+    MFX_SCANTYPE_UNKNOWN        = 0, /*!< Unknown scan type. */
+    MFX_SCANTYPE_INTERLEAVED    = 1, /*!< Interleaved scan. */
+    MFX_SCANTYPE_NONINTERLEAVED = 2  /*!< Non-interleaved scan. */
+};
+
+enum {
+    MFX_CHROMAFORMAT_JPEG_SAMPLING = 6 /*!< Color sampling specified via mfxInfoMFX::SamplingFactorH and SamplingFactorV. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Specifies quantization tables. The application may specify up to 4 quantization tables. The encoder assigns an ID to each table.
+   That ID is equal to the table index in the Qm array. Table “0” is used for encoding of the Y component, table “1” for the U component, and table “2”
+   for the V component. The application may specify fewer tables than the number of components in the image. If two tables are specified,
+   then table “1” is used for both U and V components. If only one table is specified then it is used for all components in the image.
+   The following table illustrates this behavior.
+
+   @internal
+   +------------------+---------+------+---+
+   | Table ID         | 0       | 1    | 2 |
+   +------------------+---------+------+---+
+   | Number of tables |         |      |   |
+   +==================+=========+======+===+
+   | 0                | Y, U, V |      |   |
+   +------------------+---------+------+---+
+   | 1                | Y       | U, V |   |
+   +------------------+---------+------+---+
+   | 2                | Y       | U    | V |
+   +------------------+---------+------+---+
+   @endinternal
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_JPEG_QT. */
+
+    mfxU16  reserved[7];
+    mfxU16  NumTable;       /*!< Number of quantization tables defined in Qmarray. */
+
+    mfxU16    Qm[4][64];    /*!< Quantization table values. */
+} mfxExtJPEGQuantTables;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Specifies Huffman tables. The application may specify up to 2 quantization table pairs for baseline process. The encoder
+   assigns an ID to each table. That ID is equal to the table index in the DCTables and ACTables arrays. Table “0” is used for encoding of the Y component and 
+   table “1” is used for encoding of the U and V component. The application may specify only one table, in which case the table will be used for all components in the image.
+   The following table illustrates this behavior.
+
+   @internal
+   +------------------+---------+------+
+   | Table ID         | 0       | 1    |
+   +------------------+---------+------+
+   | Number of tables |         |      |
+   +==================+=========+======+
+   | 0                | Y, U, V |      |
+   +------------------+---------+------+
+   | 1                | Y       | U, V |
+   +------------------+---------+------+
+   @endinternal
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_JPEG_HUFFMAN. */
+
+    mfxU16  reserved[2];
+    mfxU16  NumDCTable;      /*!< Number of DC quantization table in DCTables array. */
+    mfxU16  NumACTable;      /*!< Number of AC quantization table in ACTables array. */
+
+    struct {
+        mfxU8   Bits[16];    /*!< Number of codes for each code length. */
+        mfxU8   Values[12];  /*!< List of the 8-bit symbol values. */
+    } DCTables[4];           /*!< Array of DC tables. */
+
+    struct {
+        mfxU8   Bits[16];    /*!< Number of codes for each code length. */
+        mfxU8   Values[162]; /*!< Array of AC tables. */
+    } ACTables[4];           /*!< List of the 8-bit symbol values. */
+} mfxExtJPEGHuffmanTables;
+MFX_PACK_END()
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+#endif // __MFX_JPEG_H__
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxmvc.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxmvc.h
new file mode 100644 (file)
index 0000000..e183acf
--- /dev/null
@@ -0,0 +1,105 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXMVC_H__
+#define __MFXMVC_H__
+
+#include "mfxdefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CodecProfile, CodecLevel */
+enum {
+    /* MVC profiles */
+    MFX_PROFILE_AVC_MULTIVIEW_HIGH =118, /*!< Multi-view high profile. */
+    MFX_PROFILE_AVC_STEREO_HIGH    =128  /*!< Stereo high profile. */
+};
+
+/* Extended Buffer Ids */
+enum {
+    MFX_EXTBUFF_MVC_SEQ_DESC =   MFX_MAKEFOURCC('M','V','C','D'), /*!< This extended buffer describes the MVC stream information of view dependencies, view identifiers, and operation points. See the ITU*-T H.264 specification chapter H.7.3.2.1.4 for details. */
+    MFX_EXTBUFF_MVC_TARGET_VIEWS    =   MFX_MAKEFOURCC('M','V','C','T') /*!< This extended buffer defines target views at the decoder output.*/
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! 
+  Describes MVC view dependencies.
+*/
+typedef struct  {
+    mfxU16 ViewId; /*!< View identifier of this dependency structure. */
+
+    mfxU16 NumAnchorRefsL0; /*!< Number of view components for inter-view prediction in the initial reference picture list RefPicList0 for anchor view components. */
+    mfxU16 NumAnchorRefsL1; /*!< Number of view components for inter-view prediction in the initial reference picture list RefPicList1 for anchor view components. */
+    mfxU16 AnchorRefL0[16]; /*!<View identifiers of the view components for inter-view prediction in the initial reference picture list RefPicList0 for anchor view components. */
+    mfxU16 AnchorRefL1[16]; /*!<View identifiers of the view components for inter-view prediction in the initial reference picture list RefPicList1 for anchor view components. */
+
+    mfxU16 NumNonAnchorRefsL0; /*!<Number of view components for inter-view prediction in the initial reference picture list RefPicList0 for non-anchor view components. */
+    mfxU16 NumNonAnchorRefsL1; /*!<Number of view components for inter-view prediction in the initial reference picture list RefPicList1 for non-anchor view components. */
+    mfxU16 NonAnchorRefL0[16]; /*!<View identifiers of the view components for inter-view prediction in the initial reference picture list RefPicList0 for non-anchor view components. */
+    mfxU16 NonAnchorRefL1[16]; /*!View identifiers of the view components for inter-view prediction in the initial reference picture list RefPicList0 for non-anchor view components. */
+} mfxMVCViewDependency;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! 
+  Describes the MVC operation point.
+*/
+typedef struct {
+    mfxU16 TemporalId; /*!< Temporal identifier of the operation point. */
+    mfxU16 LevelIdc; /*!< Level value signaled for the operation point. */
+
+    mfxU16 NumViews; /*!< Number of views required for decoding the target output views that correspond to the operation point. */
+    mfxU16 NumTargetViews; /*!< Number of target output views for the operation point. */
+    mfxU16 *TargetViewId; /*!< Target output view identifiers for operation point. */
+} mfxMVCOperationPoint;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+  Describes the MVC stream information of view dependencies, view identifiers, and operation points. See the ITU*-T H.264 specification chapter H.7.3.2.1.4 for details.
+*/
+typedef struct  {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MVC_SEQUENCE_DESCRIPTION. */
+
+    mfxU32 NumView; /*!< Number of views. */
+    mfxU32 NumViewAlloc; /*!< The allocated view dependency array size. */
+    mfxMVCViewDependency *View; /*!< Pointer to a list of the mfxMVCViewDependency. */
+
+    mfxU32 NumViewId; /*!< Number of view identifiers. */
+    mfxU32 NumViewIdAlloc; /*!< The allocated view identifier array size. */
+    mfxU16 *ViewId; /*!< Pointer to the list of view identifier. */
+
+    mfxU32 NumOP; /*!< Number of operation points. */
+    mfxU32 NumOPAlloc; /*!< The allocated operation point array size. */
+    mfxMVCOperationPoint *OP; /*!< Pointer to a list of the mfxMVCOperationPoint structure. */
+
+    mfxU16 NumRefsTotal; /*!< Total number of reference frames in all views required to decode the stream. This value is returned from the MFXVideoDECODE_Decodeheader function. Do not modify this value. */
+    mfxU32 Reserved[16];
+
+} mfxExtMVCSeqDesc;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+ Configures views for the decoding output.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MVC_TARGET_VIEWS. */
+
+    mfxU16 TemporalId; /*!< The temporal identifier to be decoded. */
+    mfxU32 NumView; /*!< The number of views to be decoded. */
+    mfxU16 ViewId[1024]; /*!< List of view identifiers to be decoded. */
+} mfxExtMVCTargetViews ;
+MFX_PACK_END()
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxpcp.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxpcp.h
new file mode 100644 (file)
index 0000000..efbfc59
--- /dev/null
@@ -0,0 +1,45 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXPCP_H__
+#define __MFXPCP_H__
+#include "mfxstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*! The Protected enumerator describes the protection schemes. */
+enum {
+    MFX_PROTECTION_CENC_WV_CLASSIC      = 0x0004, /*!< The protection scheme is based on the Widevine* DRM from Google*. */
+    MFX_PROTECTION_CENC_WV_GOOGLE_DASH  = 0x0005, /*!< The protection scheme is based on the Widevine* Modular DRM* from Google*. */
+};
+
+/* Extended Buffer Ids */
+enum {
+    MFX_EXTBUFF_CENC_PARAM          = MFX_MAKEFOURCC('C','E','N','P') /*!< This structure is used to pass decryption status report index for Common
+                                                                           Encryption usage model. See the mfxExtCencParam structure for more details. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used to pass the decryption status report index for the Common Encryption usage model. The application can
+   attach this extended buffer to the mfxBitstream structure at runtime.
+*/
+typedef struct _mfxExtCencParam{
+    mfxExtBuffer Header;      /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_CENC_PARAM. */
+
+    mfxU32 StatusReportIndex; /*!< Decryption status report index. */
+    mfxU32 reserved[15];
+} mfxExtCencParam;
+MFX_PACK_END()
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+#endif
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxsession.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxsession.h
new file mode 100644 (file)
index 0000000..4dc4220
--- /dev/null
@@ -0,0 +1,234 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXSESSION_H__
+#define __MFXSESSION_H__
+#include "mfxcommon.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* Global Functions */
+
+/*! Session handle. */
+typedef struct _mfxSession *mfxSession;
+
+/*!
+   @brief
+      Creates and initializes a session in the legacy mode for compatibility with Intel(r) Media SDK applications. 
+      This function is deprecated starting from API version 2.0, applications must use MFXLoad with mfxCreateSession 
+      to select the implementation and initialize the session. 
+
+      Call this function before calling
+      any other API function. If the desired implementation specified by ``impl`` is MFX_IMPL_AUTO,
+      the function will search for the platform-specific implementation.
+      If the function cannot find the platform-specific implementation, it will use the software implementation instead.
+
+      The ``ver`` argument indicates the desired version of the library implementation.
+      The loaded implementation will have an API version compatible to the specified version (equal in
+      the major version number, and no less in the minor version number.) If the desired version
+      is not specified, the default is to use the API version from the library release with
+      which an application is built.
+
+      Production applications should always specify the minimum API version that meets the
+      functional requirements. For example, if an application uses only H.264 decoding as described
+      in API v1.0, the application should initialize the library with API v1.0. This ensures
+      backward compatibility.
+
+   @param[in] impl     mfxIMPL enumerator that indicates the desired legacy Intel(r) Media SDK implementation.
+   @param[in] ver      Pointer to the minimum library version or zero, if not specified.
+   @param[out] session Pointer to the legacy Intel(r) Media SDK session handle.
+
+   @return
+      MFX_ERR_NONE        The function completed successfully. The output parameter contains the handle of the session.\n
+      MFX_ERR_UNSUPPORTED The function cannot find the desired legacy Intel(r) Media SDK implementation or version.
+   
+   @since This function is available since API version 1.0.
+
+   @deprecated Deprecated in API version 2.3. Use MFXLoad and MFXCreateSession to initialize the session.
+               Use MFX_DEPRECATED_OFF macro to turn off the deprecation message visualization.
+*/
+MFX_DEPRECATED mfxStatus MFX_CDECL MFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session);
+
+/*!
+   @brief
+      Creates and initializes a session in the legacy mode for compatibility with Intel(r) Media SDK applications. 
+      This function is deprecated starting from API version 2.0, applications must use MFXLoad with mfxCreateSession 
+      to select the implementation and initialize the session.
+
+      Call this function before calling any other API functions.
+      If the desired implementation specified by ``par`` is MFX_IMPL_AUTO, the function will search for
+      the platform-specific implementation. If the function cannot find the platform-specific implementation, it will use the software implementation instead.
+
+      The argument ``par.Version`` indicates the desired version of the implementation. The loaded implementation will have an API
+      version compatible to the specified version (equal in the major version number, and no less in the minor version number.)
+      If the desired version is not specified, the default is to use the API version from the library release with
+      which an application is built.
+
+      Production applications should always specify the minimum API version that meets the functional requirements.
+      For example, if an application uses only H.264 decoding as described in API v1.0, the application should initialize the library with API v1.0. This ensures backward compatibility.
+
+      The argument ``par.ExternalThreads`` specifies threading mode. Value 0 means that the implementation should create and
+      handle work threads internally (this is essentially the equivalent of the regular MFXInit).
+
+   @param[in]  par     mfxInitParam structure that indicates the desired implementation, minimum library version and desired threading mode.
+   @param[out] session Pointer to the session handle.
+
+   @return
+      MFX_ERR_NONE        The function completed successfully. The output parameter contains the handle of the session.\n
+      MFX_ERR_UNSUPPORTED The function cannot find the desired implementation or version.
+
+   @since This function is available since API version 1.14.
+
+   @deprecated Deprecated in API version 2.3. Use MFXLoad and MFXCreateSession to initialize the session.
+               Use MFX_DEPRECATED_OFF macro to turn off the deprecation message visualization.
+*/
+MFX_DEPRECATED mfxStatus MFX_CDECL MFXInitEx(mfxInitParam par, mfxSession *session);
+
+/*!
+   @brief
+   Creates and initializes a session starting from API version 2.0. This function is used by the dispatcher.
+   The dispatcher creates and fills the mfxInitializationParam structure according to mfxConfig values set by an application.
+   Calling this function directly is not recommended. Instead, applications must call the mfxCreateSession function.
+
+
+   @param[in]  par     mfxInitializationParam structure that indicates the minimum library version and acceleration type.
+   @param[out] session Pointer to the session handle.
+
+   @return
+      MFX_ERR_NONE        The function completed successfully. The output parameter contains the handle of the session.\n
+      MFX_ERR_UNSUPPORTED The function cannot find the desired implementation or version.
+
+   @since This function is available since API version 2.0.
+*/
+mfxStatus MFX_CDECL MFXInitialize(mfxInitializationParam par, mfxSession *session);
+
+/*!
+   @brief Completes and deinitializes a session. Any active tasks in execution or
+    in queue are aborted. The application cannot call any API function after calling this function.
+
+   All child sessions must be disjoined before closing a parent session.
+   @param[in] session session handle.
+
+   @return MFX_ERR_NONE The function completed successfully.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXClose(mfxSession session);
+
+/*!
+   @brief Returns the implementation type of a given session.
+
+   @param[in]  session Session handle.
+   @param[out] impl    Pointer to the implementation type
+
+   @return MFX_ERR_NONE The function completed successfully.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXQueryIMPL(mfxSession session, mfxIMPL *impl);
+
+/*!
+   @brief Returns the implementation version.
+
+   @param[in]  session Session handle.
+   @param[out] version Pointer to the returned implementation version.
+
+   @return MFX_ERR_NONE The function completed successfully.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXQueryVersion(mfxSession session, mfxVersion *version);
+
+/*!
+   @brief Joins the child session to the current session.
+
+   After joining, the two sessions share thread and resource scheduling for asynchronous
+   operations. However, each session still maintains its own device manager and buffer/frame
+   allocator. Therefore, the application must use a compatible device manager and buffer/frame
+   allocator to share data between two joined sessions.
+
+   The application can join multiple sessions by calling this function multiple times. When joining
+   the first two sessions, the current session becomes the parent responsible for thread and
+   resource scheduling of any later joined sessions.
+
+   Joining of two parent sessions is not supported.
+
+   @param[in,out] session    The current session handle.
+   @param[in]     child      The child session handle to be joined
+
+   @return MFX_ERR_NONE         The function completed successfully. \n
+           MFX_WRN_IN_EXECUTION Active tasks are executing or in queue in one of the
+                                sessions. Call this function again after all tasks are completed. \n
+           MFX_ERR_UNSUPPORTED  The child session cannot be joined with the current session.
+
+   @since This function is available since API version 1.1.
+*/
+mfxStatus MFX_CDECL MFXJoinSession(mfxSession session, mfxSession child);
+
+/*!
+   @brief Removes the joined state of the current session.
+
+          After disjoining, the current session becomes independent. The application must ensure there is no active task running in the session before calling this API function.
+
+   @param[in,out] session    The current session handle.
+
+   @return MFX_ERR_NONE                The function completed successfully. \n
+           MFX_WRN_IN_EXECUTION        Active tasks are executing or in queue in one of the
+                                       sessions. Call this function again after all tasks are completed. \n
+           MFX_ERR_UNDEFINED_BEHAVIOR  The session is independent, or this session is the parent of all joined sessions.
+
+   @since This function is available since API version 1.1.
+*/
+mfxStatus MFX_CDECL MFXDisjoinSession(mfxSession session);
+
+/*!
+   @brief Creates a clean copy of the current session.
+
+          The cloned session is an independent session and does not inherit any user-defined buffer, frame allocator, or device manager handles from the current session.
+          This function is a light-weight equivalent of MFXJoinSession after MFXInit.
+
+   @param[in] session    The current session handle.
+   @param[out] clone     Pointer to the cloned session handle.
+
+   @return MFX_ERR_NONE                The function completed successfully.
+
+   @since This function is available since API version 1.1.
+*/
+mfxStatus MFX_CDECL MFXCloneSession(mfxSession session, mfxSession *clone);
+
+/*!
+   @brief Sets the current session priority.
+
+   @param[in] session    The current session handle.
+   @param[in] priority   Priority value.
+
+   @return MFX_ERR_NONE                The function completed successfully.
+
+   @since This function is available since API version 1.1.
+*/
+mfxStatus MFX_CDECL MFXSetPriority(mfxSession session, mfxPriority priority);
+
+/*!
+   @brief Returns the current session priority.
+
+   @param[in] session    The current session handle.
+   @param[out] priority   Pointer to the priority value.
+
+   @return MFX_ERR_NONE                The function completed successfully.
+
+   @since This function is available since API version 1.1.
+*/
+mfxStatus MFX_CDECL MFXGetPriority(mfxSession session, mfxPriority *priority);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxstructures.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxstructures.h
new file mode 100644 (file)
index 0000000..4f45fc3
--- /dev/null
@@ -0,0 +1,4765 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXSTRUCTURES_H__
+#define __MFXSTRUCTURES_H__
+#include "mfxcommon.h"
+
+#if !defined (__GNUC__)
+#pragma warning(disable: 4201)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Frame ID for MVC */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Describes the view and layer of a frame picture. */
+typedef struct {
+    mfxU16      TemporalId;  /*!< The temporal identifier as defined in the annex H of the ITU*-T H.264 specification. */
+    mfxU16      PriorityId;  /*!< Reserved and must be zero. */
+    union {
+        struct {
+            mfxU16  DependencyId; /*!< Reserved for future use. */
+            mfxU16  QualityId;    /*!< Reserved for future use. */
+        };
+        struct {
+            mfxU16  ViewId; /*!< The view identifier as defined in the annex H of the ITU-T H.264 specification. */
+        };
+    };
+} mfxFrameId;
+MFX_PACK_END()
+
+/* This struct has 4-byte alignment for binary compatibility with previously released versions of API. */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies properties of video frames. See also "Configuration Parameter Constraints" chapter. */
+typedef struct {
+    mfxU32  reserved[4]; /*!< Reserved for future use. */
+    /*! The unique ID of each VPP channel set by application. It's required that during Init/Reset application fills ChannelId for
+        each mfxVideoChannelParam provided by the application and the SDK sets it back to the correspondent
+        mfxSurfaceArray::mfxFrameSurface1 to distinguish different channels. It's expected that surfaces for some channels might be
+        returned with some delay so application has to use mfxFrameInfo::ChannelId to distinguish what returned surface belongs to
+        what VPP channel. Decoder's initialization parameters are always sent through channel with mfxFrameInfo::ChannelId equals to
+        zero. It's allowed to skip setting of decoder's parameters for simplified decoding procedure */
+    mfxU16  ChannelId;
+    /*! Number of bits used to represent luma samples.
+        @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    mfxU16  BitDepthLuma;
+    /*! Number of bits used to represent chroma samples.
+        @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    mfxU16  BitDepthChroma;
+    /*! When the value is not zero, indicates that values of luma and chroma samples are shifted. Use BitDepthLuma and BitDepthChroma to calculate
+        shift size. Use zero value to indicate absence of shift. See example data alignment below.
+
+        @note Not all codecs and implementations support this value. Use the Query API  function to check if this feature is supported.
+    */
+    mfxU16  Shift;
+    mfxFrameId FrameId; /*!< Describes the view and layer of a frame picture. */
+    mfxU32  FourCC;     /*!< FourCC code of the color format. See the ColorFourCC enumerator for details. */
+    union {
+        struct { /* Frame parameters */
+            mfxU16  Width;  /*!< Width of the video frame in pixels. Must be a multiple of 16. */
+            mfxU16  Height; /*!< Height of the video frame in pixels. Must be a multiple of 16 for progressive frame sequence and a multiple of 32 otherwise. */
+
+            /*! @{
+             @name ROI
+             The region of interest of the frame. Specify the display width and height in mfxVideoParam. */
+            mfxU16  CropX; /*!< X coordinate. */
+            mfxU16  CropY; /*!< Y coordinate. */
+            mfxU16  CropW; /*!< Width in pixels. */
+            mfxU16  CropH; /*!< Height in pixels. */
+            /*! @} */
+        };
+        struct { /* Buffer parameters (for plain formats like P8) */
+            mfxU64 BufferSize; /*!< Size of frame buffer in bytes. Valid only for plain formats (when FourCC is P8). In this case, Width, Height, and crop values are invalid. */
+            mfxU32 reserved5;
+        };
+    };
+
+    /*! @{
+        @name FrameRate
+        Specify the frame rate with the following formula: FrameRateExtN / FrameRateExtD.
+
+        For encoding, frame rate must be specified. For decoding, frame rate may be unspecified (FrameRateExtN and FrameRateExtD
+        are all zeros.) In this case, the frame rate is defaulted to 30 frames per second.
+    */
+    mfxU32  FrameRateExtN; /*!< Frame rate numerator. */
+    mfxU32  FrameRateExtD; /*!< Frame rate denominator. */
+    /*! @} */
+    mfxU16  reserved3;
+
+    /*! @{
+        @name AspectRatio
+        AspectRatioW and AspectRatioH are used to specify the sample aspect ratio. If sample aspect ratio is explicitly defined by the standards (see
+        Table 6-3 in the MPEG-2 specification or Table E-1 in the H.264 specification), AspectRatioW and AspectRatioH should be the defined values.
+        Otherwise, the sample aspect ratio can be derived as follows:
+
+        @li @c AspectRatioW=display_aspect_ratio_width*display_height
+
+        @li @c AspectRatioH=display_aspect_ratio_height*display_width
+
+        For MPEG-2, the above display aspect ratio must be one of the defined values in Table 6-3 in the MPEG-2 specification. For H.264, there is no restriction
+        on display aspect ratio values.
+
+        If both parameters are zero, the encoder uses the default value of sample aspect ratio.
+    */
+    mfxU16  AspectRatioW; /*!< Aspect Ratio for width. */
+    mfxU16  AspectRatioH; /*!< Aspect Ratio for height. */
+    /*! @} */
+
+    mfxU16  PicStruct;    /*!< Picture type as specified in the PicStruct enumerator. */
+    mfxU16  ChromaFormat; /*!< Color sampling method. Value is the same as that of ChromaFormatIdc.
+                               ChromaFormat is not defined if FourCC is zero.*/
+    mfxU16  reserved2;
+} mfxFrameInfo;
+MFX_PACK_END()
+
+/*! The ColorFourCC enumerator itemizes color formats. */
+enum {
+    MFX_FOURCC_NV12         = MFX_MAKEFOURCC('N','V','1','2'),   /*!< NV12 color planes. Native format for 4:2:0/8b Gen hardware implementation. */
+    MFX_FOURCC_YV12         = MFX_MAKEFOURCC('Y','V','1','2'),   /*!< YV12 color planes. */
+    MFX_FOURCC_NV16         = MFX_MAKEFOURCC('N','V','1','6'),   /*!< 4:2:2 color format with similar to NV12 layout. */
+    MFX_FOURCC_YUY2         = MFX_MAKEFOURCC('Y','U','Y','2'),   /*!< YUY2 color planes. */
+    MFX_FOURCC_RGB565       = MFX_MAKEFOURCC('R','G','B','2'),   /*!< 2 bytes per pixel, uint16 in little-endian format, where 0-4 bits are blue, bits 5-10 are green and bits 11-15 are red. */
+    /*! RGB 24 bit planar layout (3 separate channels, 8-bits per sample each). This format should be mapped to D3DFMT_R8G8B8 or VA_FOURCC_RGBP. */
+    MFX_FOURCC_RGBP         = MFX_MAKEFOURCC('R','G','B','P'),
+    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_FOURCC_RGB3)         = MFX_MAKEFOURCC('R','G','B','3'),   /* Deprecated. */
+    MFX_FOURCC_RGB4         = MFX_MAKEFOURCC('R','G','B','4'),   /*!< RGB4 (RGB32) color planes. BGRA is the order, ‘B’ is 8 MSBs, then 8 bits for ‘G’ channel, then ‘R’ and ‘A’ channels. */
+    /*!
+       Internal color format. The application should use the following functions to create a surface that corresponds to the Direct3D* version in use.
+
+       For Direct3D* 9: IDirectXVideoDecoderService::CreateSurface()
+
+       For Direct3D* 11: ID3D11Device::CreateBuffer()
+    */
+    MFX_FOURCC_P8           = 41,
+    /*!
+       Internal color format. The application should use the following functions to create a surface that corresponds to the Direct3D* version in use.
+
+       For Direct3D 9: IDirectXVideoDecoderService::CreateSurface()
+
+       For Direct3D 11: ID3D11Device::CreateTexture2D()
+    */
+    MFX_FOURCC_P8_TEXTURE   = MFX_MAKEFOURCC('P','8','M','B'),
+    MFX_FOURCC_P010         = MFX_MAKEFOURCC('P','0','1','0'), /*!< P010 color format. This is 10 bit per sample format with similar to NV12 layout. This format should be mapped to DXGI_FORMAT_P010. */
+    MFX_FOURCC_P016         = MFX_MAKEFOURCC('P','0','1','6'), /*!< P016 color format. This is 16 bit per sample format with similar to NV12 layout. This format should be mapped to DXGI_FORMAT_P016. */
+    MFX_FOURCC_P210         = MFX_MAKEFOURCC('P','2','1','0'), /*!< 10 bit per sample 4:2:2 color format with similar to NV12 layout. */
+    MFX_FOURCC_BGR4         = MFX_MAKEFOURCC('B','G','R','4'), /*!< RGBA color format. It is similar to MFX_FOURCC_RGB4 but with different order of channels. ‘R’ is 8 MSBs, then 8 bits for ‘G’ channel, then ‘B’ and ‘A’ channels. */
+    MFX_FOURCC_A2RGB10      = MFX_MAKEFOURCC('R','G','1','0'), /*!< 10 bits ARGB color format packed in 32 bits. ‘A’ channel is two MSBs, then ‘R’, then ‘G’ and then ‘B’ channels. This format should be mapped to DXGI_FORMAT_R10G10B10A2_UNORM or D3DFMT_A2R10G10B10. */
+    MFX_FOURCC_ARGB16       = MFX_MAKEFOURCC('R','G','1','6'), /*!< 10 bits ARGB color format packed in 64 bits. ‘A’ channel is 16 MSBs, then ‘R’, then ‘G’ and then ‘B’ channels. This format should be mapped to DXGI_FORMAT_R16G16B16A16_UINT or D3DFMT_A16B16G16R16 formats. */
+    MFX_FOURCC_ABGR16       = MFX_MAKEFOURCC('B','G','1','6'), /*!< 10 bits ABGR color format packed in 64 bits. ‘A’ channel is 16 MSBs, then ‘B’, then ‘G’ and then ‘R’ channels. This format should be mapped to DXGI_FORMAT_R16G16B16A16_UINT or D3DFMT_A16B16G16R16 formats. */
+    MFX_FOURCC_R16          = MFX_MAKEFOURCC('R','1','6','U'), /*!< 16 bits single channel color format. This format should be mapped to DXGI_FORMAT_R16_TYPELESS or D3DFMT_R16F. */
+    MFX_FOURCC_AYUV         = MFX_MAKEFOURCC('A','Y','U','V'), /*!< YUV 4:4:4, AYUV color format. This format should be mapped to DXGI_FORMAT_AYUV. */
+    MFX_FOURCC_AYUV_RGB4    = MFX_MAKEFOURCC('A','V','U','Y'), /*!< RGB4 stored in AYUV surface. This format should be mapped to DXGI_FORMAT_AYUV. */
+    MFX_FOURCC_UYVY         = MFX_MAKEFOURCC('U','Y','V','Y'), /*!< UYVY color planes. Same as YUY2 except the byte order is reversed. */
+    MFX_FOURCC_Y210         = MFX_MAKEFOURCC('Y','2','1','0'), /*!< 10 bit per sample 4:2:2 packed color format with similar to YUY2 layout. This format should be mapped to DXGI_FORMAT_Y210. */
+    MFX_FOURCC_Y410         = MFX_MAKEFOURCC('Y','4','1','0'), /*!< 10 bit per sample 4:4:4 packed color format. This format should be mapped to DXGI_FORMAT_Y410. */
+    MFX_FOURCC_Y216         = MFX_MAKEFOURCC('Y','2','1','6'), /*!< 16 bit per sample 4:2:2 packed color format with similar to YUY2 layout. This format should be mapped to DXGI_FORMAT_Y216. */
+    MFX_FOURCC_Y416         = MFX_MAKEFOURCC('Y','4','1','6'), /*!< 16 bit per sample 4:4:4 packed color format. This format should be mapped to DXGI_FORMAT_Y416. */
+    MFX_FOURCC_NV21         = MFX_MAKEFOURCC('N', 'V', '2', '1'), /*!< Same as NV12 but with weaved V and U values. */
+    MFX_FOURCC_IYUV         = MFX_MAKEFOURCC('I', 'Y', 'U', 'V'), /*!< Same as  YV12 except that the U and V plane order is reversed. */
+    MFX_FOURCC_I010         = MFX_MAKEFOURCC('I', '0', '1', '0'), /*!< 10-bit YUV 4:2:0, each component has its own plane. */
+    MFX_FOURCC_I210         = MFX_MAKEFOURCC('I', '2', '1', '0'), /*!< 10-bit YUV 4:2:2, each component has its own plane. */
+    MFX_FOURCC_I420         = MFX_FOURCC_IYUV,                 /*!< Alias for the IYUV color format. */
+    MFX_FOURCC_I422         = MFX_MAKEFOURCC('I', '4', '2', '2'), /*!< Same as YV16 except that the U and V plane order is reversed */
+    MFX_FOURCC_BGRA         = MFX_FOURCC_RGB4,                 /*!< Alias for the RGB4 color format. */
+    /*! BGR 24 bit planar layout (3 separate channels, 8-bits per sample each). This format should be mapped to VA_FOURCC_BGRP. */
+    MFX_FOURCC_BGRP         = MFX_MAKEFOURCC('B','G','R','P'),
+};
+
+/* PicStruct */
+enum {
+    MFX_PICSTRUCT_UNKNOWN       =0x00,  /*!< Unspecified or mixed progressive/interlaced/field pictures. */
+    MFX_PICSTRUCT_PROGRESSIVE   =0x01,  /*!< Progressive picture. */
+    MFX_PICSTRUCT_FIELD_TFF     =0x02,  /*!< Top field in first interlaced picture.  */
+    MFX_PICSTRUCT_FIELD_BFF     =0x04,  /*!< Bottom field in first interlaced picture.  */
+
+    MFX_PICSTRUCT_FIELD_REPEATED=0x10,  /*!< First field repeated: pic_struct=5 or 6 in H.264. */
+    MFX_PICSTRUCT_FRAME_DOUBLING=0x20,  /*!< Double the frame for display: pic_struct=7 in H.264. */
+    MFX_PICSTRUCT_FRAME_TRIPLING=0x40,  /*!< Triple the frame for display: pic_struct=8 in H.264. */
+
+    MFX_PICSTRUCT_FIELD_SINGLE      =0x100, /*!< Single field in a picture. */
+    MFX_PICSTRUCT_FIELD_TOP         =MFX_PICSTRUCT_FIELD_SINGLE | MFX_PICSTRUCT_FIELD_TFF, /*!< Top field in a picture: pic_struct = 1 in H.265. */
+    MFX_PICSTRUCT_FIELD_BOTTOM      =MFX_PICSTRUCT_FIELD_SINGLE | MFX_PICSTRUCT_FIELD_BFF, /*!< Bottom field in a picture: pic_struct = 2 in H.265. */
+    MFX_PICSTRUCT_FIELD_PAIRED_PREV =0x200, /*!< Paired with previous field: pic_struct = 9 or 10 in H.265. */
+    MFX_PICSTRUCT_FIELD_PAIRED_NEXT =0x400, /*!< Paired with next field: pic_struct = 11 or 12 in H.265 */
+};
+
+/* The ChromaFormatIdc enumerator itemizes color-sampling formats. */
+enum {
+    MFX_CHROMAFORMAT_MONOCHROME =0, /*!< Monochrome. */
+    MFX_CHROMAFORMAT_YUV420     =1, /*!< 4:2:0 color. */
+    MFX_CHROMAFORMAT_YUV422     =2, /*!< 4:2:2 color. */
+    MFX_CHROMAFORMAT_YUV444     =3, /*!< 4:4:4 color. */
+    MFX_CHROMAFORMAT_YUV400     = MFX_CHROMAFORMAT_MONOCHROME, /*!< Equal to monochrome. */
+    MFX_CHROMAFORMAT_YUV411     = 4, /*!< 4:1:1 color. */
+    MFX_CHROMAFORMAT_YUV422H    = MFX_CHROMAFORMAT_YUV422, /*!< 4:2:2 color, horizontal sub-sampling. It is equal to 4:2:2 color. */
+    MFX_CHROMAFORMAT_YUV422V    = 5, /*!< 4:2:2 color, vertical sub-sampling. */
+    MFX_CHROMAFORMAT_RESERVED1  = 6  /*!< Reserved. */
+};
+
+enum {
+    MFX_TIMESTAMP_UNKNOWN = -1 /*!< Indicates that time stamp is unknown for this frame/bitstream portion. */
+};
+
+enum {
+    MFX_FRAMEORDER_UNKNOWN = -1 /*!< Unused entry or API functions that generate the frame output do not use this frame. */
+};
+
+/* The FrameDataFlag enumerator itemizes DataFlag value in mfxFrameData. */
+enum {
+    MFX_FRAMEDATA_TIMESTAMP_UNKNOWN  = 0x0000,/*!< Indicates the time stamp of this frame is unknown and will be calculated by SDK. */
+    MFX_FRAMEDATA_ORIGINAL_TIMESTAMP = 0x0001 /*!< Indicates the time stamp of this frame is not calculated and is a pass-through of the original time stamp. */
+};
+
+/* Corrupted in mfxFrameData */
+enum {
+    MFX_CORRUPTION_NO              = 0x0000, /*!< No corruption. */
+    MFX_CORRUPTION_MINOR           = 0x0001, /*!< Minor corruption in decoding certain macro-blocks. */
+    MFX_CORRUPTION_MAJOR           = 0x0002, /*!< Major corruption in decoding the frame - incomplete data, for example. */
+    MFX_CORRUPTION_ABSENT_TOP_FIELD           = 0x0004, /*!< Top field of frame is absent in bitstream. Only bottom field has been decoded. */
+    MFX_CORRUPTION_ABSENT_BOTTOM_FIELD           = 0x0008, /*!< Bottom field of frame is absent in bitstream. Only top filed has been decoded. */
+    MFX_CORRUPTION_REFERENCE_FRAME = 0x0010, /*!< Decoding used a corrupted reference frame. A corrupted reference frame was used for decoding this
+                                                frame. For example, if the frame uses a reference frame that was decoded with minor/major corruption flag, then this
+                                                frame is also marked with a reference corruption flag. */
+    MFX_CORRUPTION_REFERENCE_LIST  = 0x0020  /*!< The reference list information of this frame does not match what is specified in the Reference Picture Marking
+                                                  Repetition SEI message. (ITU-T H.264 D.1.8 dec_ref_pic_marking_repetition) */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies "pixel" in Y410 color format. */
+typedef struct
+{
+    mfxU32 U : 10; /*!< U component. */
+    mfxU32 Y : 10; /*!< Y component. */
+    mfxU32 V : 10; /*!< V component. */
+    mfxU32 A :  2; /*!< A component. */
+} mfxY410;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies "pixel" in Y416 color format. */
+typedef struct
+{
+    mfxU32 U : 16; /*!< U component. */
+    mfxU32 Y : 16; /*!< Y component. */
+    mfxU32 V : 16; /*!< V component. */
+    mfxU32 A : 16; /*!< A component. */
+} mfxY416;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies "pixel" in A2RGB10 color format */
+typedef struct
+{
+    mfxU32 B : 10; /*!< B component. */
+    mfxU32 G : 10; /*!< G component. */
+    mfxU32 R : 10; /*!< R component. */
+    mfxU32 A :  2; /*!< A component. */
+} mfxA2RGB10;
+MFX_PACK_END()
+
+/*! Describes frame buffer pointers. */
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+typedef struct {
+    /*!  @name Extension Buffers */
+    /*! @{ */
+    union {
+        mfxExtBuffer **ExtParam; /*!< Points to an array of pointers to the extra configuration structures. See the ExtendedBufferID
+                                      enumerator for a list of extended configurations. */
+        mfxU64       reserved2;
+    };
+    mfxU16  NumExtParam; /*!< The number of extra configuration structures attached to this structure. */
+    /*! @} */
+
+    /*!  @name General members */
+    /*! @{ */
+    mfxU16      reserved[9]; /*!< Reserved for future use. */
+    mfxU16      MemType;     /*!< Allocated memory type. See the ExtMemFrameType enumerator for details. Used for better integration of
+                                  3rd party plugins into the pipeline. */
+    mfxU16      PitchHigh;   /*!< Distance in bytes between the start of two consecutive rows in a frame. */
+
+    mfxU64      TimeStamp;   /*!< Time stamp of the video frame in units of 90KHz. Divide TimeStamp by 90,000 (90 KHz) to obtain the time in seconds.
+                                  A value of MFX_TIMESTAMP_UNKNOWN indicates that there is no time stamp. */
+    mfxU32      FrameOrder;  /*!< Current frame counter for the top field of the current frame. An invalid value of MFX_FRAMEORDER_UNKNOWN indicates that
+                            API functions that generate the frame output do not use this frame. */
+    mfxU16      Locked;      /*!< Counter flag for the application. If Locked is greater than zero then the application locks the frame or field pair.
+                                  Do not move, alter or delete the frame. */
+    union{
+        mfxU16  Pitch;
+        mfxU16  PitchLow;    /*!< Distance in bytes between the start of two consecutive rows in a frame. */
+    };
+    /*! @} */
+
+    /*!
+        @name Color Planes
+        Data pointers to corresponding color channels (planes). The frame buffer pointers must be 16-byte aligned. The application has to specify pointers to
+        all color channels even for packed formats. For example, for YUY2 format the application must specify Y, U, and V pointers.
+        For RGB32 format, the application must specify R, G, B, and A pointers.
+    */
+    /*! @{ */
+    union {
+        mfxU8   *Y; /*!< Y channel. */
+        mfxU16  *Y16; /*!< Y16 channel. */
+        mfxU8   *R; /*!< R channel. */
+    };
+    union {
+        mfxU8   *UV;    /*!< UV channel for UV merged formats. */
+        mfxU8   *VU;    /*!< YU channel for VU merged formats. */
+        mfxU8   *CbCr;  /*!< CbCr channel for CbCr merged formats. */
+        mfxU8   *CrCb;  /*!< CrCb channel for CrCb merged formats. */
+        mfxU8   *Cb;    /*!< Cb channel. */
+        mfxU8   *U;     /*!< U channel. */
+        mfxU16  *U16;   /*!< U16 channel. */
+        mfxU8   *G;     /*!< G channel. */
+        mfxY410 *Y410;  /*!< T410 channel for Y410 format (merged AVYU). */
+        mfxY416 *Y416;  /*!< This format is a packed 16-bit representation that includes 16 bits of alpha. */
+    };
+    union {
+        mfxU8   *Cr;    /*!< Cr channel. */
+        mfxU8   *V;     /*!< V channel. */
+        mfxU16  *V16;   /*!< V16 channel. */
+        mfxU8   *B;     /*!< B channel. */
+        mfxA2RGB10 *A2RGB10; /*!< A2RGB10 channel for A2RGB10 format (merged ARGB). */
+    };
+    mfxU8       *A;     /*!< A channel. */
+    mfxMemId    MemId;  /*!< Memory ID of the data buffers. Ignored if any of the preceding data pointers is non-zero. */
+    /*! @} */
+
+    /*!
+        @name Additional Flags
+    */
+    /*! @{ */
+    mfxU16  Corrupted; /*!< Some part of the frame or field pair is corrupted. See the Corruption enumerator for details. */
+    mfxU16  DataFlag;  /*!< Additional flags to indicate frame data properties. See the FrameDataFlag enumerator for details. */
+    /*! @} */
+} mfxFrameData;
+MFX_PACK_END()
+
+/*! The mfxHandleType enumerator itemizes system handle types that implementations might use. */
+typedef enum {
+    MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9         =1,      /*!< Pointer to the IDirect3DDeviceManager9 interface. See Working with Microsoft* DirectX* Applications for more details on how to use this handle. */
+    MFX_HANDLE_D3D9_DEVICE_MANAGER              = MFX_HANDLE_DIRECT3D_DEVICE_MANAGER9, /*!< Pointer to the IDirect3DDeviceManager9 interface. See Working with Microsoft* DirectX* Applications for more details on how to use this handle. */
+    MFX_HANDLE_RESERVED1                        = 2, /* Reserved.  */
+    MFX_HANDLE_D3D11_DEVICE                     = 3, /*!< Pointer to the ID3D11Device interface. See Working with Microsoft* DirectX* Applications for more details on how to use this handle. */
+    MFX_HANDLE_VA_DISPLAY                       = 4, /*!< Pointer to VADisplay interface. See Working with VA-API Applications for more details on how to use this handle. */
+    MFX_HANDLE_RESERVED3                        = 5, /* Reserved.  */
+    MFX_HANDLE_VA_CONFIG_ID                     = 6, /*!< Pointer to VAConfigID interface. It represents external VA config for Common Encryption usage model. */
+    MFX_HANDLE_VA_CONTEXT_ID                    = 7, /*!< Pointer to VAContextID interface. It represents external VA context for Common Encryption usage model. */
+    MFX_HANDLE_CM_DEVICE                        = 8,  /*!< Pointer to CmDevice interface ( Intel(r) C for Metal Runtime ). */
+    MFX_HANDLE_HDDLUNITE_WORKLOADCONTEXT        = 9,  /*!< Pointer to HddlUnite::WorkloadContext interface. */
+#ifdef ONEVPL_EXPERIMENTAL 
+    MFX_HANDLE_PXP_CONTEXT                      = 10, /*!< Pointer to PXP context for protected content support. */
+#endif
+} mfxHandleType;
+
+/*! The mfxMemoryFlags enumerator specifies memory access mode. */
+typedef enum
+{
+    MFX_MAP_READ  = 0x1, /*!< The surface is mapped for reading. */
+    MFX_MAP_WRITE = 0x2, /*!< The surface is mapped for writing. */
+    MFX_MAP_READ_WRITE = MFX_MAP_READ|MFX_MAP_WRITE, /*!< The surface is mapped for reading and writing.  */
+    /*!
+     * The mapping would be done immediately without any implicit synchronizations.
+     * \attention This flag is optional.
+     */
+    MFX_MAP_NOWAIT = 0x10
+} mfxMemoryFlags;
+
+#define MFX_FRAMESURFACE1_VERSION MFX_STRUCT_VERSION(1, 1)
+
+/* Frame Surface */
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*! Defines the uncompressed frames surface information and data buffers.
+    The frame surface is in the frame or complementary field pairs of pixels up to four color-channels, in two parts:
+    mfxFrameInfo and mfxFrameData.
+*/
+typedef struct {
+    union
+    {
+        struct mfxFrameSurfaceInterface*  FrameInterface;       /*!< Specifies interface to work with surface. */
+        mfxU32  reserved[2];
+    };
+    mfxStructVersion Version; /* Specifies version of mfxFrameSurface1 structure. */
+    mfxU16          reserved1[3];
+    mfxFrameInfo    Info; /*!< Specifies surface properties. */
+    mfxFrameData    Data; /*!< Describes the actual frame buffer. */
+} mfxFrameSurface1;
+MFX_PACK_END()
+
+
+#define MFX_FRAMESURFACEINTERFACE_VERSION MFX_STRUCT_VERSION(1, 0)
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/* Specifies frame surface interface. */
+typedef struct mfxFrameSurfaceInterface {
+    mfxHDL              Context; /*!< The context of the memory interface. User should not touch (change, set, null) this pointer. */
+    mfxStructVersion    Version; /*!< The version of the structure. */
+    mfxU16              reserved1[3];
+    /*! @brief
+    Increments the internal reference counter of the surface. The surface is not destroyed until the surface is released using the mfxFrameSurfaceInterface::Release function.
+    mfxFrameSurfaceInterface::AddRef should be used each time a new link to the surface is created (for example, copy structure) for proper surface management.
+
+    @param[in]  surface  Valid surface.
+
+    @return
+     MFX_ERR_NONE              If no error. \n
+     MFX_ERR_NULL_PTR          If surface is NULL. \n
+     MFX_ERR_INVALID_HANDLE    If mfxFrameSurfaceInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN           Any internal error.
+
+    */
+    mfxStatus           (MFX_CDECL *AddRef)(mfxFrameSurface1* surface);
+    /*! @brief
+    Decrements the internal reference counter of the surface. mfxFrameSurfaceInterface::Release should be called after using the
+    mfxFrameSurfaceInterface::AddRef function to add a surface or when allocation logic requires it. For example, call
+    mfxFrameSurfaceInterface::Release to release a surface obtained with the GetSurfaceForXXX function.
+
+    @param[in]  surface  Valid surface.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If surface is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxFrameSurfaceInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNDEFINED_BEHAVIOR If Reference Counter of surface is zero before call. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *Release)(mfxFrameSurface1* surface);
+
+    /*! @brief
+    Returns current reference counter of mfxFrameSurface1 structure.
+
+    @param[in]   surface  Valid surface.
+    @param[out]  counter  Sets counter to the current reference counter value.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If surface or counter is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxFrameSurfaceInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *GetRefCounter)(mfxFrameSurface1* surface, mfxU32* counter);
+
+    /*! @brief
+    Sets pointers of surface->Info.Data to actual pixel data, providing read-write access.
+
+    In case of video memory, the surface with data in video memory becomes mapped to system memory.
+    An application can map a surface for read access with any value of mfxFrameSurface1::Data::Locked, but can map a surface for write access only when mfxFrameSurface1::Data::Locked equals to 0.
+
+    Note: A surface allows shared read access, but exclusive write access. Consider the following cases:
+    @li Map with Write or Read|Write flags. A request during active another read or write access returns MFX_ERR_LOCK_MEMORY error immediately, without waiting.
+    MFX_MAP_NOWAIT does not impact behavior. This type of request does not lead to any implicit synchronizations.
+    @li Map with Read flag. A request during active write access will wait for resource to become free,
+    or exits immediately with error if MFX_MAP_NOWAIT flag was set. This request may lead to the implicit synchronization (with same logic as Synchronize call)
+    waiting for surface to become ready to use (all dependencies should be resolved and upstream components finished writing to this surface).
+
+    It is guaranteed that read access will be acquired right after synchronization without allowing another thread to acquire this surface for writing.
+
+    If MFX_MAP_NOWAIT was set and the surface is not ready yet (for example the surface has unresolved data dependencies or active processing), the read access request exits immediately with error.
+
+    Read-write access with MFX_MAP_READ_WRITE provides exclusive simultaneous reading and writing access.
+
+    @note Bitwise copying of mfxFrameSurface1 object between map / unmap calls may result in having dangling data pointers in copies.
+
+    @param[in]   surface  Valid surface.
+    @param[out]  flags  Specify mapping mode.
+    @param[out]  surface->Info.Data Pointers set to actual pixel data.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If surface is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxFrameSurfaceInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNSUPPORTED        If flags are invalid. \n
+     MFX_ERR_LOCK_MEMORY        If user wants to map the surface for write and surface->Data.Locked does not equal to 0. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *Map)(mfxFrameSurface1* surface, mfxU32 flags);
+
+    /*! @brief
+    Invalidates pointers of surface->Info.Data and sets them to NULL.
+    In case of video memory, the underlying texture becomes unmapped after last reader or writer unmap.
+
+
+    @param[in]   surface  Valid surface.
+    @param[out]  surface->Info.Data  Pointers set to NULL.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If surface is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxFrameSurfaceInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNSUPPORTED        If surface is already unmapped. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *Unmap)(mfxFrameSurface1* surface);
+
+    /*! @brief
+    Returns a native resource's handle and type. The handle is returned *as-is*, meaning that the reference counter of base resources is not incremented.
+    The native resource is not detached from surface and the library still owns the resource. User must not destroy
+    the native resource or assume that the resource will be alive after mfxFrameSurfaceInterface::Release.
+
+
+
+    @param[in]   surface  Valid surface.
+    @param[out]  resource Pointer is set to the native handle of the resource.
+    @param[out]  resource_type Type of native resource. See mfxResourceType enumeration).
+
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If any of surface, resource or resource_type is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If any of surface, resource or resource_type is not valid object (no native resource was allocated). \n
+     MFX_ERR_UNSUPPORTED        If surface is in system memory. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *GetNativeHandle)(mfxFrameSurface1* surface, mfxHDL* resource, mfxResourceType* resource_type);
+
+    /*! @brief
+    Returns a device abstraction that was used to create that resource.
+    The handle is returned *as-is*, meaning that the reference counter for the device abstraction is not incremented.
+    The native resource is not detached from the surface and the library still has a reference to the resource.
+    User must not destroy the device or assume that the device will be alive after mfxFrameSurfaceInterface::Release.
+
+
+    @param[in]   surface  Valid surface.
+    @param[out]  device_handle Pointer is set to the device which created the resource
+    @param[out]  device_type Type of device (see mfxHandleType enumeration).
+
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If any of surface, device_handle or device_type is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If any of surface, resource or resource_type is not valid object (no native resource was allocated). \n
+     MFX_ERR_UNSUPPORTED        If surface is in system memory. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *GetDeviceHandle)(mfxFrameSurface1* surface, mfxHDL* device_handle, mfxHandleType* device_type);
+
+    /*! @brief
+    Guarantees readiness of both the data (pixels) and any frame's meta information (for example corruption flags) after a function completes.
+
+    Instead of MFXVideoCORE_SyncOperation, users may directly call the mfxFrameSurfaceInterface::Synchronize function after the corresponding
+    Decode or VPP function calls (MFXVideoDECODE_DecodeFrameAsync or MFXVideoVPP_RunFrameVPPAsync).
+    The prerequisites to call the functions are:
+
+    @li The main processing functions return MFX_ERR_NONE.
+    @li A valid mfxFrameSurface1 object.
+
+
+
+    @param[in]   surface  Valid surface.
+    @param[out]  wait  Wait time in milliseconds.
+
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If surface is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If any of surface is not valid object . \n
+     MFX_WRN_IN_EXECUTION       If the given timeout is expired and the surface is not ready. \n
+     MFX_ERR_ABORTED            If the specified asynchronous function aborted due to data dependency on a previous asynchronous function that did not complete. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *Synchronize)(mfxFrameSurface1* surface, mfxU32 wait);
+
+    /*! @brief
+    The library calls the function after complete of associated video operation
+    notifying the application that frame surface is ready.
+
+    @attention This is callback function and intended to be called by
+               the library only.
+
+    It is expected that the function is low-intrusive designed otherwise it may
+    impact performance.
+
+    @param[in] sts  The status of completed operation.
+
+    */
+    void               (MFX_CDECL *OnComplete)(mfxStatus sts);
+    
+   /*! @brief
+    Returns an interface defined by the GUID. If the returned interface is a reference 
+    counted object the caller should release the obtained interface to avoid memory leaks.
+
+    @param[in]  surface   Valid surface.
+    @param[in]  guid      GUID of the requested interface.
+    @param[out] iface     Interface.
+
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If interface or surface is NULL. \n
+     MFX_ERR_UNSUPPORTED        If requested interface is not supported. \n
+     MFX_ERR_NOT_IMPLEMENTED    If requested interface is not implemented. \n
+     MFX_ERR_NOT_INITIALIZED    If requested interface is not available (not created or already deleted). \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *QueryInterface)(mfxFrameSurface1* surface, mfxGUID guid, mfxHDL* iface); 
+
+    mfxHDL              reserved2[2];
+} mfxFrameSurfaceInterface;
+MFX_PACK_END()
+
+/*! The TimeStampCalc enumerator itemizes time-stamp calculation methods. */
+enum {
+    /*! The time stamp calculation is based on the input frame rate if time stamp is not explicitly specified. */
+    MFX_TIMESTAMPCALC_UNKNOWN = 0,
+    /*! Adjust time stamp to 29.97fps on 24fps progressively encoded sequences if telecine attributes are available in the bitstream and
+    time stamp is not explicitly specified. The input frame rate must be specified. */
+    MFX_TIMESTAMPCALC_TELECINE = 1,
+};
+
+/* Transcoding Info */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies configurations for decoding, encoding, and transcoding processes.
+    A zero value in any of these fields indicates that the field is not explicitly specified. */
+typedef struct {
+    mfxU32  reserved[7]; /*!< Reserved for future use. */
+
+    /*! Hint to enable low power consumption mode for encoders. See the CodingOptionValue enumerator for values
+        of this option. Use the Query API function to check if this feature is supported. */
+    mfxU16  LowPower;
+    /*! Specifies a multiplier for bitrate control parameters. Affects the following variables: InitialDelayInKB, BufferSizeInKB,
+        TargetKbps, MaxKbps. If this value is not equal to zero, the encoder calculates BRC parameters as ``value * BRCParamMultiplier``. */
+    mfxU16  BRCParamMultiplier;
+
+    mfxFrameInfo    FrameInfo; /*!< mfxFrameInfo structure that specifies frame parameters. */
+    mfxU32  CodecId;           /*!< Specifies the codec format identifier in the FourCC code; see the CodecFormatFourCC enumerator for details.
+                                    This is a mandated input parameter for the QueryIOSurf and Init API functions. */
+    mfxU16  CodecProfile;      /*!< Specifies the codec profile; see the CodecProfile enumerator for details. Specify the codec profile explicitly or the API functions will determine
+                                    the correct profile from other sources, such as resolution and bitrate. */
+    mfxU16  CodecLevel;        /*!< Codec level; see the CodecLevel enumerator for details. Specify the codec level explicitly or the functions will determine the correct level from other sources,
+                                    such as resolution and bitrate. */
+    mfxU16  NumThread;
+
+    union {
+        struct {   /* Encoding Options */
+            mfxU16  TargetUsage; /*!< Target usage model that guides the encoding process; see the TargetUsage enumerator for details. */
+
+            /*! Number of pictures within the current GOP (Group of Pictures); if GopPicSize = 0, then the GOP size is unspecified. If GopPicSize = 1, only I-frames are used.
+                The following pseudo-code that shows how the library uses this parameter:
+                @code
+                   mfxU16 get_gop_sequence (...) {
+                      pos=display_frame_order;
+                      if (pos == 0)
+                          return MFX_FRAMETYPE_I | MFX_FRAMETYPE_IDR | MFX_FRAMETYPE_REF;
+
+                      If (GopPicSize == 1) // Only I-frames
+                          return MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF;
+
+                      if (GopPicSize == 0)
+                                  frameInGOP = pos;    //Unlimited GOP
+                              else
+                                  frameInGOP = pos%GopPicSize;
+
+                      if (frameInGOP == 0)
+                          return MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF;
+
+                      if (GopRefDist == 1 || GopRefDist == 0)    // Only I,P frames
+                                  return MFX_FRAMETYPE_P | MFX_FRAMETYPE_REF;
+
+                      frameInPattern = (frameInGOP-1)%GopRefDist;
+                      if (frameInPattern == GopRefDist - 1)
+                          return MFX_FRAMETYPE_P | MFX_FRAMETYPE_REF;
+
+                      return MFX_FRAMETYPE_B;
+                    }
+                @endcode */
+            mfxU16  GopPicSize;
+            /*! Distance between I- or P (or GPB) - key frames; if it is zero, the GOP structure is unspecified. Note: If GopRefDist = 1,
+                there are no regular B-frames used (only P or GPB); if mfxExtCodingOption3::GPB is ON, GPB frames (B without backward
+                references) are used instead of P. */
+            mfxU16  GopRefDist;
+            /*! ORs of the GopOptFlag enumerator indicate the additional flags for the GOP specification. */
+            mfxU16  GopOptFlag;
+            /*! For H.264, specifies IDR-frame interval in terms of I-frames.
+                For example:
+                @li If IdrInterval = 0, then every I-frame is an IDR-frame.
+                @li If IdrInterval = 1, then every other I-frame is an IDR-frame.
+
+                For HEVC, if IdrInterval = 0, then only first I-frame is an IDR-frame. For example:
+                @li If IdrInterval = 1, then every I-frame is an IDR-frame.
+                @li If IdrInterval = 2, then every other I-frame is an IDR-frame.
+
+                For MPEG2, IdrInterval defines sequence header interval in terms of I-frames. For example:
+                @li If IdrInterval = 0 (default), then the sequence header is inserted once at the beginning of the stream.
+                @li If IdrInterval = N, then the sequence header is inserted before every Nth I-frame.
+
+
+                If GopPicSize or GopRefDist is zero, IdrInterval is undefined. */
+            mfxU16  IdrInterval;
+
+            mfxU16  RateControlMethod; /*! Rate control method; see the RateControlMethod enumerator for details. */
+            union {
+                /*! Initial size of the Video Buffering Verifier (VBV) buffer.
+                    @note In this context, KB is 1000 bytes and Kbps is 1000 bps. */
+                mfxU16  InitialDelayInKB;
+                /*! Quantization Parameter (QP) for I-frames for constant QP mode (CQP). Zero QP is not valid and means that the default value is assigned by the library.
+                    Non-zero QPI might be clipped to supported QPI range.
+                    @note Default QPI value is implementation dependent and subject to change without additional notice in this document. */
+                mfxU16  QPI;
+                mfxU16  Accuracy; /*!< Specifies accuracy range in the unit of tenth of percent. */
+            };
+            mfxU16  BufferSizeInKB; /*!< Represents the maximum possible size of any compressed frames. */
+            union {
+                /*! Constant bitrate TargetKbps. Used to estimate the targeted frame size by dividing the frame rate by the bitrate. */
+                mfxU16  TargetKbps;
+                /*! Quantization Parameter (QP) for P-frames for constant QP mode (CQP). Zero QP is not valid and means that the default value is assigned by the library.
+                    Non-zero QPP might be clipped to supported QPI range.
+                    @note Default QPP value is implementation dependent and subject to change without additional notice in this document. */
+                mfxU16  QPP;
+                mfxU16  ICQQuality; /*!< Used by the Intelligent Constant Quality (ICQ) bitrate control algorithm. Values are in the 1 to 51 range, where 1 corresponds the best quality. */
+            };
+            union {
+                /*! The maximum bitrate at which the encoded data enters the Video Buffering Verifier (VBV) buffer. */
+                mfxU16  MaxKbps;
+                /*! Quantization Parameter (QP) for B-frames for constant QP mode (CQP). Zero QP is not valid and means that the default value is assigned by the library.
+                    Non-zero QPI might be clipped to supported QPB range.
+                    @note Default QPB value is implementation dependent and subject to change without additional notice in this document. */
+                mfxU16  QPB;
+                mfxU16  Convergence; /*!< Convergence period in the unit of 100 frames. */
+            };
+
+            /*! Number of slices in each video frame. Each slice contains one or more macro-block rows. If NumSlice equals zero, the encoder may choose any slice partitioning
+                allowed by the codec standard. See also mfxExtCodingOption2::NumMbPerSlice. */
+            mfxU16  NumSlice;
+            /*! Max number of all available reference frames (for AVC/HEVC, NumRefFrame defines DPB size). If NumRefFrame = 0, this parameter is not specified.
+                See also NumRefActiveP, NumRefActiveBL0, and NumRefActiveBL1 in the mfxExtCodingOption3 structure, which set a number of active references. */
+            mfxU16  NumRefFrame;
+            /*! If not zero, specifies that ENCODE takes the input surfaces in the encoded order and uses explicit frame type control.
+                The application must still provide GopRefDist and mfxExtCodingOption2::BRefType so the library can pack headers and build reference
+                lists correctly. */
+            mfxU16  EncodedOrder;
+        };
+        struct {   /* Decoding Options */
+            /*! For AVC and HEVC, used to instruct the decoder to return output frames in the decoded order. Must be zero for all other decoders.
+                When enabled, correctness of mfxFrameData::TimeStamp and FrameOrder for output surface is not guaranteed, the application should ignore them. */
+            mfxU16  DecodedOrder;
+            /*! Instructs DECODE to output extended picture structure values for additional display attributes. See the PicStruct description for details. */
+            mfxU16  ExtendedPicStruct;
+            /*! Time stamp calculation method. See the TimeStampCalc description for details. */
+            mfxU16  TimeStampCalc;
+            /*! Nonzero value indicates that slice groups are present in the bitstream. Used only by AVC decoder. */
+            mfxU16  SliceGroupsPresent;
+            /*! Nonzero value specifies the maximum required size of the decoded picture buffer in frames for AVC and HEVC decoders. */
+            mfxU16  MaxDecFrameBuffering;
+            /*! For decoders supporting dynamic resolution change (VP9), set this option to ON to allow MFXVideoDECODE_DecodeFrameAsync
+                return MFX_ERR_REALLOC_SURFACE. See the CodingOptionValue enumerator for values of this option. Use the Query API
+                function to check if this feature is supported. */
+            mfxU16  EnableReallocRequest;
+            /*! Special parameter for AV1 decoder. Indicates presence/absence of film grain parameters in bitstream.
+                Also controls decoding behavior for streams with film grain parameters. MFXVideoDECODE_DecodeHeader returns nonzero FilmGrain
+                for streams with film grain parameters and zero for streams w/o them. Decoding with film grain requires additional output surfaces.
+                If FilmGrain` is non-zero then MFXVideoDECODE_QueryIOSurf will request more surfaces in case of external allocated video memory at decoder output.
+                FilmGrain is passed to MFXVideoDECODE_Init function to control decoding operation for AV1 streams with film grain parameters.
+                If FilmGrain is nonzero decoding of each frame require two output surfaces (one for reconstructed frame and one for output frame with film grain applied).
+                The decoder returns MFX_ERR_MORE_SURFACE from MFXVideoDECODE_DecodeFrameAsync if it has insufficient output surfaces to decode frame.
+                Application can forcibly disable the feature passing zero value of `FilmGrain` to `MFXVideoDECODE_Init`.
+                In this case the decoder will output reconstructed frames w/o film grain applied.
+                Application can retrieve film grain parameters for a frame by attaching extended buffer mfxExtAV1FilmGrainParam to mfxFrameSurface1.
+                If stream has no film grain parameters `FilmGrain` passed to `MFXVideoDECODE_Init` is ignored by the decoder. */
+            mfxU16  FilmGrain;
+            /*! If not zero, it forces SDK to attempt to decode bitstream even if a decoder may not support all features associated with given CodecLevel. Decoder may produce visual artifacts. Only AVC decoder supports this field. */
+            mfxU16  IgnoreLevelConstrain;
+            /*! This flag is used to disable output of main decoding channel. When it's ON SkipOutput = MFX_CODINGOPTION_ON decoder outputs only video processed channels. For pure decode this flag should be always disabled. */
+            mfxU16  SkipOutput;
+            mfxU16  reserved2[4];
+        };
+        struct {   /* JPEG Decoding Options */
+            /*! Specify the chroma sampling format that has been used to encode a JPEG picture. See the ChromaFormat enumerator for details. */
+            mfxU16  JPEGChromaFormat;
+            /*! Rotation option of the output JPEG picture. See the Rotation enumerator for details. */
+            mfxU16  Rotation;
+            /*! Specify the color format that has been used to encode a JPEG picture. See the JPEGColorFormat enumerator for details. */
+            mfxU16  JPEGColorFormat;
+            /*! Specify JPEG scan type for decoder. See the JPEGScanType enumerator for details. */
+            mfxU16  InterleavedDec;
+            mfxU8   SamplingFactorH[4]; /*!< Horizontal sampling factor. */
+            mfxU8   SamplingFactorV[4]; /*!< Vertical sampling factor. */
+            mfxU16  reserved3[5];
+        };
+        struct {   /* JPEG Encoding Options */
+            /*! Specify interleaved or non-interleaved scans. If it is equal to MFX_SCANTYPE_INTERLEAVED then the image is encoded as interleaved,
+                all components are encoded in one scan. See the JPEG Scan Type enumerator for details. */
+            mfxU16  Interleaved;
+            /*! Specifies the image quality if the application does not specified quantization table.
+                The value is from 1 to 100 inclusive. “100” is the best quality. */
+            mfxU16  Quality;
+            /*! Specifies the number of MCU in the restart interval. “0” means no restart interval. */
+            mfxU16  RestartInterval;
+            mfxU16  reserved5[10];
+        };
+    };
+} mfxInfoMFX;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Specifies configurations for video processing. A zero value in any of the fields indicates
+   that the corresponding field is not explicitly specified. */
+typedef struct {
+    mfxU32  reserved[8];
+    mfxFrameInfo    In;  /*!< Input format for video processing. */
+    mfxFrameInfo    Out; /*!< Output format for video processing. */
+} mfxInfoVPP;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! Configuration parameters for encoding, decoding, transcoding, and video processing. */
+typedef struct {
+    /*! Unique component ID that will be passed by the library to mfxFrameAllocRequest. Useful in pipelines where several
+        components of the same type share the same allocator. */
+    mfxU32  AllocId;
+    mfxU32  reserved[2];
+    mfxU16  reserved3;
+    /*! Specifies how many asynchronous operations an application performs before the application explicitly synchronizes the result.
+        If zero, the value is not specified. */
+    mfxU16  AsyncDepth;
+
+    union {
+        mfxInfoMFX  mfx; /*!< Configurations related to encoding, decoding, and transcoding. See the definition of the mfxInfoMFX structure for details. */
+        mfxInfoVPP  vpp; /*!< Configurations related to video processing. See the definition of the mfxInfoVPP structure for details. */
+    };
+    /*! Specifies the content protection mechanism. See the Protected enumerator for a list of supported protection schemes. */
+    mfxU16  Protected;
+    /*! Input and output memory access types for functions. See the enumerator IOPattern for details.
+        The Query API functions return the natively supported IOPattern if the Query input argument is NULL.
+        This parameter is a mandated input for QueryIOSurf and Init API functions. The output pattern must be specified for DECODE.
+        The input pattern must be specified for ENCODE. Both input and output pattern must be specified for VPP. */
+    mfxU16  IOPattern;
+    mfxExtBuffer** ExtParam; /*!< The number of extra configuration structures attached to this structure. */
+    mfxU16  NumExtParam;     /*!< Points to an array of pointers to the extra configuration structures. See the ExtendedBufferID enumerator
+                                  for a list of extended configurations.
+                                  The list of extended buffers should not contain duplicated entries, such as entries of the same type.
+                                  If the  mfxVideoParam structure is used to query library capability, then the list of extended buffers attached to the input
+                                  and output mfxVideoParam structure should be equal, that is, it should contain the same number of extended
+                                  buffers of the same type. */
+    mfxU16  reserved2;
+} mfxVideoParam;
+MFX_PACK_END()
+
+/*! The IOPattern enumerator itemizes memory access patterns for API functions. Use bit-ORed values to specify an input access
+    pattern and an output access pattern. */
+enum {
+    MFX_IOPATTERN_IN_VIDEO_MEMORY   = 0x01, /*!< Input to functions is a video memory surface. */
+    MFX_IOPATTERN_IN_SYSTEM_MEMORY  = 0x02, /*!< Input to functions is a linear buffer directly in system memory or in system memory through an external allocator. */
+    MFX_IOPATTERN_OUT_VIDEO_MEMORY  = 0x10, /*!< Output to functions is a video memory surface.  */
+    MFX_IOPATTERN_OUT_SYSTEM_MEMORY = 0x20 /*!< Output to functions is a linear buffer directly in system memory or in system memory through an external allocator.  */
+};
+
+/*! The CodecFormatFourCC enumerator itemizes codecs in the FourCC format. */
+enum {
+    MFX_CODEC_AVC         =MFX_MAKEFOURCC('A','V','C',' '), /*!< AVC, H.264, or MPEG-4, part 10 codec. */
+    MFX_CODEC_HEVC        =MFX_MAKEFOURCC('H','E','V','C'), /*!< HEVC codec. */
+    MFX_CODEC_MPEG2       =MFX_MAKEFOURCC('M','P','G','2'), /*!< MPEG-2 codec. */
+    MFX_CODEC_VC1         =MFX_MAKEFOURCC('V','C','1',' '), /*!< VC-1 codec. */
+    MFX_CODEC_CAPTURE     =MFX_MAKEFOURCC('C','A','P','T'), /*!<  */
+    MFX_CODEC_VP9         =MFX_MAKEFOURCC('V','P','9',' '), /*!< VP9 codec. */
+    MFX_CODEC_AV1         =MFX_MAKEFOURCC('A','V','1',' ')  /*!< AV1 codec. */
+};
+
+/*!
+The CodecProfile enumerator itemizes codec profiles for all codecs.
+CodecLevel
+*/
+enum {
+    MFX_PROFILE_UNKNOWN                     =0, /*!< Unspecified profile. */
+    MFX_LEVEL_UNKNOWN                       =0, /*!< Unspecified level. */
+
+    /*! @{ */
+    /* Combined with H.264 profile these flags impose additional constrains. See H.264 specification for the list of constrains. */
+    MFX_PROFILE_AVC_CONSTRAINT_SET0     = (0x100 << 0),
+    MFX_PROFILE_AVC_CONSTRAINT_SET1     = (0x100 << 1),
+    MFX_PROFILE_AVC_CONSTRAINT_SET2     = (0x100 << 2),
+    MFX_PROFILE_AVC_CONSTRAINT_SET3     = (0x100 << 3),
+    MFX_PROFILE_AVC_CONSTRAINT_SET4     = (0x100 << 4),
+    MFX_PROFILE_AVC_CONSTRAINT_SET5     = (0x100 << 5),
+    /*! @} */
+
+    /*! @{ */
+    /* H.264 Profiles. */
+    MFX_PROFILE_AVC_BASELINE                =66,
+    MFX_PROFILE_AVC_MAIN                    =77,
+    MFX_PROFILE_AVC_EXTENDED                =88,
+    MFX_PROFILE_AVC_HIGH                    =100,
+    MFX_PROFILE_AVC_HIGH10                  =110,
+    MFX_PROFILE_AVC_HIGH_422                =122,
+    MFX_PROFILE_AVC_CONSTRAINED_BASELINE    =MFX_PROFILE_AVC_BASELINE + MFX_PROFILE_AVC_CONSTRAINT_SET1,
+    MFX_PROFILE_AVC_CONSTRAINED_HIGH        =MFX_PROFILE_AVC_HIGH     + MFX_PROFILE_AVC_CONSTRAINT_SET4
+                                                                      + MFX_PROFILE_AVC_CONSTRAINT_SET5,
+    MFX_PROFILE_AVC_PROGRESSIVE_HIGH        =MFX_PROFILE_AVC_HIGH     + MFX_PROFILE_AVC_CONSTRAINT_SET4,
+    /*! @} */
+
+    /*! @{ */
+    /* H.264 level 1-1.3 */
+    MFX_LEVEL_AVC_1                         =10,
+    MFX_LEVEL_AVC_1b                        =9,
+    MFX_LEVEL_AVC_11                        =11,
+    MFX_LEVEL_AVC_12                        =12,
+    MFX_LEVEL_AVC_13                        =13,
+    /*! @} */
+    /*! @{ */
+    /* H.264 level 2-2.2 */
+    MFX_LEVEL_AVC_2                         =20,
+    MFX_LEVEL_AVC_21                        =21,
+    MFX_LEVEL_AVC_22                        =22,
+    /*! @} */
+    /*! @{ */
+    /* H.264 level 3-3.2 */
+    MFX_LEVEL_AVC_3                         =30,
+    MFX_LEVEL_AVC_31                        =31,
+    MFX_LEVEL_AVC_32                        =32,
+    /*! @} */
+    /*! @{ */
+    /* H.264 level 4-4.2 */
+    MFX_LEVEL_AVC_4                         =40,
+    MFX_LEVEL_AVC_41                        =41,
+    MFX_LEVEL_AVC_42                        =42,
+    /*! @} */
+    /*! @{ */
+    /* H.264 level 5-5.2 */
+    MFX_LEVEL_AVC_5                         =50,
+    MFX_LEVEL_AVC_51                        =51,
+    MFX_LEVEL_AVC_52                        =52,
+    /*! @} */
+    /*! @{ */
+    /* H.264 level 6-6.2 */
+    MFX_LEVEL_AVC_6                         =60,
+    MFX_LEVEL_AVC_61                        =61,
+    MFX_LEVEL_AVC_62                        =62,
+    /*! @} */
+
+    /*! @{ */
+    /* MPEG2 Profiles. */
+    MFX_PROFILE_MPEG2_SIMPLE                =0x50,
+    MFX_PROFILE_MPEG2_MAIN                  =0x40,
+    MFX_PROFILE_MPEG2_HIGH                  =0x10,
+    /*! @} */
+
+    /*! @{ */
+    /* MPEG2 Levels. */
+    MFX_LEVEL_MPEG2_LOW                     =0xA,
+    MFX_LEVEL_MPEG2_MAIN                    =0x8,
+    MFX_LEVEL_MPEG2_HIGH                    =0x4,
+    MFX_LEVEL_MPEG2_HIGH1440                =0x6,
+    /*! @} */
+
+    /*! @{ */
+    /* VC-1 Profiles. */
+    MFX_PROFILE_VC1_SIMPLE                  =(0+1),
+    MFX_PROFILE_VC1_MAIN                    =(4+1),
+    MFX_PROFILE_VC1_ADVANCED                =(12+1),
+    /*! @} */
+
+    /*! @{ */
+    /* VC-1 Level Low (simple & main profiles) */
+    MFX_LEVEL_VC1_LOW                       =(0+1),
+    MFX_LEVEL_VC1_MEDIAN                    =(2+1),
+    MFX_LEVEL_VC1_HIGH                      =(4+1),
+    /*! @} */
+
+    /*! @{ */
+    /* VC-1 advanced profile levels */
+    MFX_LEVEL_VC1_0                         =(0x00+1),
+    MFX_LEVEL_VC1_1                         =(0x01+1),
+    MFX_LEVEL_VC1_2                         =(0x02+1),
+    MFX_LEVEL_VC1_3                         =(0x03+1),
+    MFX_LEVEL_VC1_4                         =(0x04+1),
+    /*! @} */
+
+    /*! @{ */
+    /* HEVC profiles */
+    MFX_PROFILE_HEVC_MAIN             =1,
+    MFX_PROFILE_HEVC_MAIN10           =2,
+    MFX_PROFILE_HEVC_MAINSP           =3,
+    MFX_PROFILE_HEVC_REXT             =4,
+    MFX_PROFILE_HEVC_SCC              =9,
+    /*! @} */
+
+    /*! @{ */
+    /* HEVC levels */
+    MFX_LEVEL_HEVC_1   = 10,
+    MFX_LEVEL_HEVC_2   = 20,
+    MFX_LEVEL_HEVC_21  = 21,
+    MFX_LEVEL_HEVC_3   = 30,
+    MFX_LEVEL_HEVC_31  = 31,
+    MFX_LEVEL_HEVC_4   = 40,
+    MFX_LEVEL_HEVC_41  = 41,
+    MFX_LEVEL_HEVC_5   = 50,
+    MFX_LEVEL_HEVC_51  = 51,
+    MFX_LEVEL_HEVC_52  = 52,
+    MFX_LEVEL_HEVC_6   = 60,
+    MFX_LEVEL_HEVC_61  = 61,
+    MFX_LEVEL_HEVC_62  = 62,
+    /*! @} */
+
+    /*! @{ */
+    /* HEVC tiers */
+    MFX_TIER_HEVC_MAIN  = 0,
+    MFX_TIER_HEVC_HIGH  = 0x100,
+    /*! @} */
+
+    /*! @{ */
+    /* VP9 Profiles */
+    MFX_PROFILE_VP9_0                       = 1,
+    MFX_PROFILE_VP9_1                       = 2,
+    MFX_PROFILE_VP9_2                       = 3,
+    MFX_PROFILE_VP9_3                       = 4,
+    /*! @} */
+
+    /*! @{ */
+    /* AV1 Profiles */
+    MFX_PROFILE_AV1_MAIN                    = 1,
+    MFX_PROFILE_AV1_HIGH                    = 2,
+    MFX_PROFILE_AV1_PRO                     = 3,
+    /*! @} */
+
+    /*! @{ */
+    /* AV1 Levels */
+    MFX_LEVEL_AV1_2                         = 20,
+    MFX_LEVEL_AV1_21                        = 21,
+    MFX_LEVEL_AV1_22                        = 22,
+    MFX_LEVEL_AV1_23                        = 23,
+    MFX_LEVEL_AV1_3                         = 30,
+    MFX_LEVEL_AV1_31                        = 31,
+    MFX_LEVEL_AV1_32                        = 32,
+    MFX_LEVEL_AV1_33                        = 33,
+    MFX_LEVEL_AV1_4                         = 40,
+    MFX_LEVEL_AV1_41                        = 41,
+    MFX_LEVEL_AV1_42                        = 42,
+    MFX_LEVEL_AV1_43                        = 43,
+    MFX_LEVEL_AV1_5                         = 50,
+    MFX_LEVEL_AV1_51                        = 51,
+    MFX_LEVEL_AV1_52                        = 52,
+    MFX_LEVEL_AV1_53                        = 53,
+    MFX_LEVEL_AV1_6                         = 60,
+    MFX_LEVEL_AV1_61                        = 61,
+    MFX_LEVEL_AV1_62                        = 62,
+    MFX_LEVEL_AV1_63                        = 63,
+    MFX_LEVEL_AV1_7                         = 70,
+    MFX_LEVEL_AV1_71                        = 71,
+    MFX_LEVEL_AV1_72                        = 72,
+    MFX_LEVEL_AV1_73                        = 73,
+    /*! @} */
+};
+
+/*! The GopOptFlag enumerator itemizes special properties in the GOP (Group of Pictures) sequence. */
+enum {
+    /*!
+       The encoder generates closed GOP if this flag is set. Frames in this GOP do not use frames in previous GOP as reference.
+
+       The encoder generates open GOP if this flag is not set. In this GOP frames prior to the first frame of GOP in display order may use
+       frames from previous GOP as reference. Frames subsequent to the first frame of GOP in display order do not use frames from previous
+       GOP as reference.
+
+       The AVC encoder ignores this flag if IdrInterval in mfxInfoMFX structure is set to 0, i.e. if every GOP starts from IDR frame.
+       In this case, GOP is encoded as closed.
+
+       This flag does not affect long-term reference frames.
+    */
+    MFX_GOP_CLOSED          =1,
+    /*!
+       The encoder must strictly follow the given GOP structure as defined by parameter GopPicSize, GopRefDist etc in the mfxVideoParam structure.
+       Otherwise, the encoder can adapt the GOP structure for better efficiency, whose range is constrained by parameter GopPicSize and
+       GopRefDist etc. See also description of AdaptiveI and AdaptiveB fields in the mfxExtCodingOption2 structure.
+    */
+    MFX_GOP_STRICT          =2
+};
+
+/*! The TargetUsage enumerator itemizes a range of numbers from MFX_TARGETUSAGE_1, best quality, to MFX_TARGETUSAGE_7, best speed.
+    It indicates trade-offs between quality and speed. The application can use any number in the range. The actual number of supported
+    target usages depends on implementation. If specified target usage is not supported, the encoder will use the closest supported value. */
+enum {
+    MFX_TARGETUSAGE_1    =1, /*!< Best quality */
+    MFX_TARGETUSAGE_2    =2,
+    MFX_TARGETUSAGE_3    =3,
+    MFX_TARGETUSAGE_4    =4, /*!< Balanced quality and speed. */
+    MFX_TARGETUSAGE_5    =5,
+    MFX_TARGETUSAGE_6    =6,
+    MFX_TARGETUSAGE_7    =7, /*!< Best speed */
+
+    MFX_TARGETUSAGE_UNKNOWN         =0, /*!< Unspecified target usage. */
+    MFX_TARGETUSAGE_BEST_QUALITY    =MFX_TARGETUSAGE_1, /*!< Best quality. */
+    MFX_TARGETUSAGE_BALANCED        =MFX_TARGETUSAGE_4, /*!< Balanced quality and speed. */
+    MFX_TARGETUSAGE_BEST_SPEED      =MFX_TARGETUSAGE_7  /*!< Best speed. */
+};
+
+/*! The RateControlMethod enumerator itemizes bitrate control methods. */
+enum {
+    MFX_RATECONTROL_CBR       =1, /*!< Use the constant bitrate control algorithm. */
+    MFX_RATECONTROL_VBR       =2, /*!< Use the variable bitrate control algorithm. */
+    MFX_RATECONTROL_CQP       =3, /*!< Use the constant quantization parameter algorithm. */
+    MFX_RATECONTROL_AVBR      =4, /*!< Use the average variable bitrate control algorithm. */
+    MFX_RATECONTROL_RESERVED1 =5,
+    MFX_RATECONTROL_RESERVED2 =6,
+    MFX_RATECONTROL_RESERVED3 =100,
+    MFX_RATECONTROL_RESERVED4 =7,
+    /*!
+       Use the VBR algorithm with look ahead. It is a special bitrate control mode in the AVC encoder that has been designed
+       to improve encoding quality. It works by performing extensive analysis of several dozen frames before the actual encoding and as a side
+       effect significantly increases encoding delay and memory consumption.
+
+       The only available rate control parameter in this mode is mfxInfoMFX::TargetKbps. Two other parameters, MaxKbps and InitialDelayInKB,
+       are ignored. To control LA depth the application can use mfxExtCodingOption2::LookAheadDepth parameter.
+
+       This method is not HRD compliant.
+    */
+    MFX_RATECONTROL_LA        =8,
+    /*!
+       Use the Intelligent Constant Quality algorithm. This algorithm improves subjective video quality of encoded stream. Depending on content,
+       it may or may not decrease objective video quality. Only one control parameter is used - quality factor, specified by mfxInfoMFX::ICQQuality.
+    */
+    MFX_RATECONTROL_ICQ       =9,
+    /*!
+       Use the Video Conferencing Mode algorithm. This algorithm is similar to the VBR and uses the same set of parameters mfxInfoMFX::InitialDelayInKB,
+       TargetKbpsandMaxKbps. It is tuned for IPPP GOP pattern and streams with strong temporal correlation between frames.
+       It produces better objective and subjective video quality in these conditions than other bitrate control algorithms.
+       It does not support interlaced content, B-frames and produced stream is not HRD compliant.
+    */
+    MFX_RATECONTROL_VCM       =10,
+    /*!
+       Use Intelligent Constant Quality algorithm with look ahead. Quality factor is specified by mfxInfoMFX::ICQQuality.
+       To control LA depth the application can use mfxExtCodingOption2::LookAheadDepth parameter.
+
+       This method is not HRD compliant.
+    */
+    MFX_RATECONTROL_LA_ICQ    =11,
+    /*!
+       MFX_RATECONTROL_LA_EXT has been removed
+    */
+
+    /*! Use HRD compliant look ahead rate control algorithm. */
+    MFX_RATECONTROL_LA_HRD    =13,
+    /*!
+       Use the variable bitrate control algorithm with constant quality. This algorithm trying to achieve the target subjective quality with
+       the minimum number of bits, while the bitrate constraint and HRD compliance are satisfied. It uses the same set of parameters
+       as VBR and quality factor specified by mfxExtCodingOption3::QVBRQuality.
+    */
+    MFX_RATECONTROL_QVBR      =14,
+};
+
+/*!
+   The TrellisControl enumerator is used to control trellis quantization in AVC encoder. The application can turn it on
+   or off for any combination of I-, P- and B-frames by combining different enumerator values. For example, MFX_TRELLIS_I | MFX_TRELLIS_B
+   turns it on for I- and B-frames.
+
+   @note Due to performance reason on some target usages trellis quantization is always turned off and this control is ignored by the encoder.
+*/
+enum {
+    MFX_TRELLIS_UNKNOWN =0,    /*!< Default value, it is up to the encoder to turn trellis quantization on or off. */
+    MFX_TRELLIS_OFF     =0x01, /*!< Turn trellis quantization off for all frame types. */
+    MFX_TRELLIS_I       =0x02, /*!< Turn trellis quantization on for I-frames. */
+    MFX_TRELLIS_P       =0x04, /*!< Turn trellis quantization on for P-frames. */
+    MFX_TRELLIS_B       =0x08  /*!< Turn trellis quantization on for B-frames. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Specifies additional options for encoding.
+
+   The application can attach this extended buffer to the mfxVideoParam structure to configure initialization.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_CODING_OPTION. */
+
+    mfxU16      reserved1;
+    mfxU16      RateDistortionOpt;      /*!< Set this flag if rate distortion optimization is needed. See the CodingOptionValue enumerator for values of this option. */
+    mfxU16      MECostType;             /*!< Motion estimation cost type. This value is reserved and must be zero. */
+    mfxU16      MESearchType;           /*!< Motion estimation search algorithm. This value is reserved and must be zero. */
+    mfxI16Pair  MVSearchWindow;         /*!< Rectangular size of the search window for motion estimation. This parameter is reserved and must be (0, 0). */
+    MFX_DEPRECATED mfxU16      EndOfSequence;          /* Deprecated */
+    mfxU16      FramePicture;           /*!< Set this flag to encode interlaced fields as interlaced frames. This flag does not affect progressive input frames. See the CodingOptionValue enumerator for values of this option. */
+
+    mfxU16      CAVLC;                  /*!< If set, CAVLC is used; if unset, CABAC is used for encoding. See the CodingOptionValue enumerator for values of this option. */
+    mfxU16      reserved2[2];
+    /*!
+       Set this flag to insert the recovery point SEI message at the beginning of every intra refresh cycle. See the description of
+       IntRefType in mfxExtCodingOption2 structure for details on how to enable and configure intra refresh.
+
+       If intra refresh is not enabled then this flag is ignored.
+
+       See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      RecoveryPointSEI;
+    /*!
+       Set this flag to instruct the MVC encoder to output each view in separate bitstream buffer. See the CodingOptionValue enumerator
+       for values of this option and the Multi-View Video Coding section for more details about usage of this flag.
+    */
+    mfxU16      ViewOutput;
+    /*!
+       If this option is turned ON, then AVC encoder produces an HRD conformant bitstream. If it is turned OFF, then the AVC encoder may (but not necessarily) violate HRD conformance. That is, this option can force the encoder to produce an HRD conformant stream, but
+       cannot force it to produce a non-conformant stream.
+
+       See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      NalHrdConformance;
+    /*!
+       If set, encoder puts all SEI messages in the singe NAL unit. It includes messages provided by application and created
+       by encoder. It is a three-states option. See CodingOptionValue enumerator for values of this option. The three states are:
+
+       @li UNKNOWN Put each SEI in its own NAL unit.
+
+       @li ON Put all SEI messages in the same NAL unit.
+
+       @li OFF The same as unknown.
+    */
+    mfxU16      SingleSeiNalUnit;
+    /*!
+       If set and VBR rate control method is used, then VCL HRD parameters are written in bitstream with values identical to the values of the NAL HRD parameters.
+       See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      VuiVclHrdParameters;
+
+    mfxU16      RefPicListReordering;   /*!< Set this flag to activate reference picture list reordering. This value is reserved and must be zero. */
+    mfxU16      ResetRefList;           /*!< Set this flag to reset the reference list to non-IDR I-frames of a GOP sequence. See the CodingOptionValue enumerator for values of this option. */
+    /*!
+       Set this flag to write the reference picture marking repetition SEI message into the output bitstream.
+       See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      RefPicMarkRep;
+    /*!
+       Set this flag to instruct the AVC encoder to output bitstreams immediately after the encoder encodes a field,
+       in the field-encoding mode. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      FieldOutput;
+
+    mfxU16      IntraPredBlockSize;   /*!< Minimum block size of intra-prediction. This value is reserved and must be zero. */
+    mfxU16      InterPredBlockSize;   /*!< Minimum block size of inter-prediction. This value is reserved and must be zero. */
+    mfxU16      MVPrecision;          /*!< Specify the motion estimation precision. This parameter is reserved and must be zero. */
+    mfxU16      MaxDecFrameBuffering; /*!< Specifies the maximum number of frames buffered in a DPB. A value of zero means unspecified. */
+
+    mfxU16      AUDelimiter;            /*!< Set this flag to insert the Access Unit Delimiter NAL. See the CodingOptionValue enumerator for values of this option. */
+    MFX_DEPRECATED mfxU16      EndOfStream;            /* Deprecated */
+    /*!
+       Set this flag to insert the picture timing SEI with pic_struct syntax element. See sub-clauses D.1.2 and D.2.2 of the ISO/IEC 14496-10
+       specification for the definition of this syntax element. See the CodingOptionValue enumerator for values of this option.
+       The default value is ON.
+    */
+    mfxU16      PicTimingSEI;
+    mfxU16      VuiNalHrdParameters;  /*!< Set this flag to insert NAL HRD parameters in the VUI header. See the CodingOptionValue enumerator for values of this option. */
+} mfxExtCodingOption;
+MFX_PACK_END()
+
+/*! The BRefControl enumerator is used to control usage of B-frames as reference in AVC encoder. */
+enum {
+    MFX_B_REF_UNKNOWN = 0, /*!< Default value, it is up to the encoder to use B-frames as reference. */
+    MFX_B_REF_OFF     = 1, /*!< Do not use B-frames as reference. */
+    MFX_B_REF_PYRAMID = 2  /*!< Arrange B-frames in so-called “B pyramid” reference structure. */
+};
+
+/*! The LookAheadDownSampling enumerator is used to control down sampling in look ahead bitrate control mode in AVC encoder. */
+enum {
+    MFX_LOOKAHEAD_DS_UNKNOWN = 0, /*!< Default value, it is up to the encoder what down sampling value to use. */
+    MFX_LOOKAHEAD_DS_OFF     = 1, /*!< Do not use down sampling, perform estimation on original size frames. This is the slowest setting that produces the best quality. */
+    MFX_LOOKAHEAD_DS_2x      = 2, /*!< Down sample frames two times before estimation. */
+    MFX_LOOKAHEAD_DS_4x      = 3  /*!< Down sample frames four times before estimation. This option may significantly degrade quality. */
+};
+
+/*! The BPSEIControl enumerator is used to control insertion of buffering period SEI in the encoded bitstream. */
+enum {
+    MFX_BPSEI_DEFAULT = 0x00, /*!< encoder decides when to insert BP SEI. */
+    MFX_BPSEI_IFRAME  = 0x01  /*!< BP SEI should be inserted with every I-frame */
+};
+
+/*! The SkipFrame enumerator is used to define usage of mfxEncodeCtrl::SkipFrame parameter. */
+enum {
+    MFX_SKIPFRAME_NO_SKIP         = 0, /*!< Frame skipping is disabled, mfxEncodeCtrl::SkipFrame is ignored. */
+    MFX_SKIPFRAME_INSERT_DUMMY    = 1, /*!< Skipping is allowed, when mfxEncodeCtrl::SkipFrame is set encoder inserts into bitstream frame
+                                            where all macroblocks are encoded as skipped. Only non-reference P- and B-frames can be skipped.
+                                            If GopRefDist = 1 and mfxEncodeCtrl::SkipFrame is set for reference P-frame, it will be encoded
+                                            as non-reference. */
+    MFX_SKIPFRAME_INSERT_NOTHING  = 2, /*!< Similar to MFX_SKIPFRAME_INSERT_DUMMY, but when mfxEncodeCtrl::SkipFrame is set encoder inserts nothing into bitstream. */
+    MFX_SKIPFRAME_BRC_ONLY        = 3, /*!< mfxEncodeCtrl::SkipFrame indicates number of missed frames before the current frame. Affects only BRC, current frame will be encoded as usual. */
+};
+
+/*! The IntraRefreshTypes enumerator itemizes types of intra refresh. */
+enum {
+        MFX_REFRESH_NO             = 0, /*!< Encode without refresh. */
+        MFX_REFRESH_VERTICAL       = 1, /*!< Vertical refresh, by column of MBs. */
+        MFX_REFRESH_HORIZONTAL     = 2, /*!< Horizontal refresh, by rows of MBs. */
+        MFX_REFRESH_SLICE          = 3  /*!< Horizontal refresh by slices without overlapping. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used with the mfxExtCodingOption structure to specify additional options for encoding.
+
+   The application can attach this extended buffer to the mfxVideoParam structure to configure initialization and to the mfxEncodeCtrl during runtime.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_CODING_OPTION2. */
+
+    /*!
+       Specifies intra refresh type. See the IntraRefreshTypes. The major goal of intra refresh is improvement of error resilience without
+       significant impact on encoded bitstream size caused by I-frames. The  encoder achieves this by encoding part of each frame in the refresh
+       cycle using intra MBs.
+
+       This parameter is valid during initialization and
+       runtime. When used with temporal scalability, intra refresh applied only to base layer.
+
+       MFX_REFRESH_NO No refresh.
+
+       MFX_REFRESH_VERTICAL Vertical refresh, by column of MBs.
+
+       MFX_REFRESH_HORIZONTAL Horizontal refresh, by rows of MBs.
+
+       MFX_REFRESH_SLICE Horizontal refresh by slices without overlapping.
+
+       MFX_REFRESH_SLICE Library ignores IntRefCycleSize (size of refresh cycle equals number slices).
+    */
+    mfxU16      IntRefType;
+    /*!
+       Specifies number of pictures within refresh cycle starting from 2. 0 and 1 are invalid values. This parameter is valid only during initialization.
+    */
+    mfxU16      IntRefCycleSize;
+    /*!
+       Specifies QP difference for inserted intra MBs. Signed values are in the -51 to 51 range. This parameter is valid during initialization and runtime.
+    */
+    mfxI16      IntRefQPDelta;
+
+    /*!
+       Specify maximum encoded frame size in byte. This parameter is used in VBR based bitrate control modes and ignored in others.
+       The encoder tries to keep frame size below specified limit but minor overshoots are possible to preserve visual quality.
+       This parameter is valid during initialization and runtime. It is recommended to set MaxFrameSize to 5x-10x target frame size
+       ((TargetKbps*1000)/(8* FrameRateExtN/FrameRateExtD)) for I-frames and 2x-4x target frame size for P- and B-frames.
+    */
+    mfxU32      MaxFrameSize;
+    /*!
+       Specify maximum slice size in bytes. If this parameter is specified other controls over number of slices are ignored.
+
+       @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported.
+    */
+    mfxU32      MaxSliceSize;
+
+    /*!
+       Modifies bitrate to be in the range imposed by the encoder. The default value is ON, that is, bitrate is limited. Setting this flag to OFF may lead to violation of HRD conformance.Specifying bitrate below the encoder range might significantly affect quality.
+
+       If set to ON, this option takes effect in non CQP modes:
+       if TargetKbps is not in the range imposed by the encoder, it will be changed to be in the range.
+
+       This parameter is valid only during initialization. Flag works with MFX_CODEC_AVC only, it is ignored with other codecs.
+       See the CodingOptionValue
+       enumerator for values of this option.
+    */
+    mfxU16      BitrateLimit;
+    /*!
+       Setting this flag enables macroblock level bitrate control that generally improves subjective visual quality. Enabling this flag may
+       have negative impact on performance and objective visual quality metric. See the CodingOptionValue enumerator for values of this option.
+       The default value depends on target usage settings.
+    */
+    mfxU16      MBBRC;
+    /*!
+       Set this option to ON to enable external BRC. See the CodingOptionValue enumerator for values of this option.
+       Use the Query API function to check if this feature is supported.
+    */
+    mfxU16      ExtBRC;
+    /*!
+       Specifies the depth of the look ahead rate control algorithm. The depth value is the number of frames that the encoder analyzes before encoding. Values are in the 10 to 100 range, inclusive.
+       To instruct the encoder to use the default value the application should zero this field.
+    */
+    mfxU16      LookAheadDepth;
+    /*!
+       Used to control trellis quantization in AVC encoder. See TrellisControl enumerator for values of this option.
+       This parameter is valid only during initialization.
+    */
+    mfxU16      Trellis;
+    /*!
+       Controls picture parameter set repetition in AVC encoder. Set this flag to ON to repeat PPS with each frame.
+       See the CodingOptionValue enumerator for values of this option. The default value is ON. This parameter is valid only during initialization.
+    */
+    mfxU16      RepeatPPS;
+    /*!
+       Controls usage of B-frames as reference. See BRefControl enumerator for values of this option.
+       This parameter is valid only during initialization.
+    */
+    mfxU16      BRefType;
+    /*!
+       Controls insertion of I-frames by the encoder. Set this flag to ON to allow changing of frame type from P and B to I.
+       This option is ignored if GopOptFlag in mfxInfoMFX structure is equal to MFX_GOP_STRICT. See the CodingOptionValue enumerator
+       for values of this option. This parameter is valid only during initialization.
+    */
+    mfxU16      AdaptiveI;
+    /*!
+       Controls changing of frame type from B to P. Set this flag to ON enable changing of frame type from B to P. This option is ignored if
+       GopOptFlag in mfxInfoMFX structure is equal to MFX_GOP_STRICT. See the CodingOptionValue enumerator for values of this option.
+       This parameter is valid only during initialization.
+    */
+    mfxU16      AdaptiveB;
+    /*!
+       Controls down sampling in look ahead bitrate control mode. See LookAheadDownSampling enumerator for values
+       of this option. This parameter is valid only during initialization.
+    */
+    mfxU16      LookAheadDS;
+    /*!
+       Specifies suggested slice size in number of macroblocks. The library can adjust this number based on platform capability.
+       If this option is specified, that is, if it is not equal to zero, the library ignores mfxInfoMFX::NumSlice parameter.
+    */
+    mfxU16      NumMbPerSlice;
+    /*!
+       Enables usage of mfxEncodeCtrl::SkipFrameparameter. See the SkipFrame enumerator for values of this option.
+       @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported.
+    */
+    mfxU16      SkipFrame;
+    mfxU8       MinQPI; /*!< Minimum allowed QP value for I-frame types. Valid range is 1 to 51 inclusive. Zero means default value, that is, no limitations on QP.
+                             @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    mfxU8       MaxQPI; /*!< Maximum allowed QP value for I-frame types. Valid range is 1 to 51 inclusive. Zero means default value, that is, no limitations on QP.
+                             @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    mfxU8       MinQPP; /*!< Minimum allowed QP value for P-frame types. Valid range is 1 to 51 inclusive. Zero means default value, that is, no limitations on QP.
+                             @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    mfxU8       MaxQPP; /*!< Maximum allowed QP value for P-frame types. Valid range is 1 to 51 inclusive. Zero means default value, that is, no limitations on QP.
+                             @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    mfxU8       MinQPB; /*!< Minimum allowed QP value for B-frame types. Valid range is 1 to 51 inclusive. Zero means default value, that is, no limitations on QP.
+                             @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    mfxU8       MaxQPB; /*!< Maximum allowed QP value for B-frame types. Valid range is 1 to 51 inclusive. Zero means default value, that is, no limitations on QP.
+                             @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported. */
+    /*!
+       Sets fixed_frame_rate_flag in VUI.
+       @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported.
+    */
+    mfxU16      FixedFrameRate;
+    /*! Disables deblocking.
+        @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported.
+    */
+    mfxU16      DisableDeblockingIdc;
+    /*!
+       Completely disables VUI in the output bitstream.
+       @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported.
+    */
+    mfxU16      DisableVUI;
+    /*!
+       Controls insertion of buffering period SEI in the encoded bitstream. It should be one of the following values:
+
+       MFX_BPSEI_DEFAULT   Encoder decides when to insert BP SEI,
+
+       MFX_BPSEI_IFRAME    BP SEI should be inserted with every I-frame.
+    */
+    mfxU16      BufferingPeriodSEI;
+    /*!
+       Set this flag to ON to enable per-frame reporting of Mean Absolute Difference. This parameter is valid only during initialization.
+    */
+    mfxU16      EnableMAD;
+    /*!
+       Set this flag to ON to use raw frames for reference instead of reconstructed frames. This parameter is valid during
+       initialization and runtime (only if was turned ON during initialization).
+       @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported.
+    */
+    mfxU16      UseRawRef;
+} mfxExtCodingOption2;
+MFX_PACK_END()
+
+/*! The WeightedPred enumerator itemizes weighted prediction modes. */
+enum {
+    MFX_WEIGHTED_PRED_UNKNOWN  = 0, /*!< Allow encoder to decide. */
+    MFX_WEIGHTED_PRED_DEFAULT  = 1, /*!< Use default weighted prediction. */
+    MFX_WEIGHTED_PRED_EXPLICIT = 2, /*!< Use explicit weighted prediction. */
+    MFX_WEIGHTED_PRED_IMPLICIT = 3  /*!< Use implicit weighted prediction (for B-frames only). */
+};
+
+/*! The ScenarioInfo enumerator itemizes scenarios for the encoding session. */
+enum {
+    MFX_SCENARIO_UNKNOWN             = 0,
+    MFX_SCENARIO_DISPLAY_REMOTING    = 1,
+    MFX_SCENARIO_VIDEO_CONFERENCE    = 2,
+    MFX_SCENARIO_ARCHIVE             = 3,
+    MFX_SCENARIO_LIVE_STREAMING      = 4,
+    MFX_SCENARIO_CAMERA_CAPTURE      = 5,
+    MFX_SCENARIO_VIDEO_SURVEILLANCE  = 6,
+    MFX_SCENARIO_GAME_STREAMING      = 7,
+    MFX_SCENARIO_REMOTE_GAMING       = 8
+};
+
+/*! The ContentInfo enumerator itemizes content types for the encoding session. */
+enum {
+    MFX_CONTENT_UNKNOWN              = 0,
+    MFX_CONTENT_FULL_SCREEN_VIDEO    = 1,
+    MFX_CONTENT_NON_VIDEO_SCREEN     = 2
+};
+
+/*! The PRefType enumerator itemizes models of reference list construction and DPB management when GopRefDist=1. */
+enum {
+    MFX_P_REF_DEFAULT = 0, /*!< Allow encoder to decide. */
+    MFX_P_REF_SIMPLE  = 1, /*!< Regular sliding window used for DPB removal process. */
+    MFX_P_REF_PYRAMID = 2  /*!< Let N be the max reference list’s size. Encoder treats each N’s frame as a 'strong'
+                                reference and the others as 'weak' references. The encoder uses a 'weak' reference only for
+                                prediction of the next frame and removes it from DPB immediately after use. 'Strong' references are removed from
+                                DPB by a sliding window. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used with mfxExtCodingOption and mfxExtCodingOption2 structures to specify additional options for encoding.
+   The application can attach this extended buffer to the mfxVideoParam structure to configure initialization and to the mfxEncodeCtrl during runtime.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_CODING_OPTION3. */
+
+    mfxU16      NumSliceI; /*!< The number of slices for I-frames.
+                                @note Not all codecs and implementations support these values. Use the Query API function to check if this feature is supported */
+    mfxU16      NumSliceP; /*!< The number of slices for P-frames.
+                                @note Not all codecs and implementations support these values. Use the Query API function to check if this feature is supported */
+    mfxU16      NumSliceB; /*!< The number of slices for B-frames.
+                                @note Not all codecs and implementations support these values. Use the Query API function to check if this feature is supported */
+
+    /*!
+       When rate control method is MFX_RATECONTROL_VBR, MFX_RATECONTROL_LA, MFX_RATECONTROL_LA_HRD, or MFX_RATECONTROL_QVBR this parameter
+       specifies the maximum bitrate averaged over a sliding window specified by WinBRCSize. For MFX_RATECONTROL_CBR this parameter is ignored and
+       equals TargetKbps.
+    */
+    mfxU16      WinBRCMaxAvgKbps;
+    /*!
+       When rate control method is MFX_RATECONTROL_CBR, MFX_RATECONTROL_VBR, MFX_RATECONTROL_LA, MFX_RATECONTROL_LA_HRD, or MFX_RATECONTROL_QVBR
+       this parameter specifies sliding window size in frames. Set this parameter to zero to disable sliding window.
+    */
+    mfxU16      WinBRCSize;
+
+    /*! When rate control method is MFX_RATECONTROL_QVBR, this parameter specifies quality factor.
+        Values are in the 1 to 51 range, where 1 corresponds to the best quality.
+    */
+    mfxU16      QVBRQuality;
+    /*!
+       Set this flag to ON to enable per-macroblock QP control. Rate control method must be MFX_RATECONTROL_CQP. See the CodingOptionValue
+       enumerator for values of this option. This parameter is valid only during initialization.
+    */
+    mfxU16      EnableMBQP;
+    /*!
+       Distance between the beginnings of the intra-refresh cycles in frames. Zero means no distance between cycles.
+    */
+    mfxU16      IntRefCycleDist;
+    /*!
+       Set this flag to ON to enable the ENC mode decision algorithm to bias to fewer B Direct/Skip types. Applies only to B-frames,
+       all other frames will ignore this setting. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      DirectBiasAdjustment;
+    /*!
+       Enables global motion bias. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      GlobalMotionBiasAdjustment;
+    /*!
+       Values are:
+
+       @li 0: Set MV cost to be 0.
+
+       @li 1: Scale MV cost to be 1/2 of the default value.
+
+       @li 2: Scale MV cost to be 1/4 of the default value.
+
+       @li 3: Scale MV cost to be 1/8 of the default value.
+    */
+    mfxU16      MVCostScalingFactor;
+    /*!
+       Set this flag to ON to enable usage of mfxExtMBDisableSkipMap. See the CodingOptionValue enumerator for values of this option.
+       This parameter is valid only during initialization.
+    */
+    mfxU16      MBDisableSkipMap;
+
+    mfxU16      WeightedPred;   /*!< Weighted prediction mode. See the WeightedPred enumerator for values of these options. */
+    mfxU16      WeightedBiPred; /*!< Weighted prediction mode. See the WeightedPred enumerator for values of these options. */
+
+    /*!
+       Instructs encoder whether aspect ratio info should present in VUI parameters. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      AspectRatioInfoPresent;
+    /*!
+       Instructs encoder whether overscan info should present in VUI parameters. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      OverscanInfoPresent;
+    /*!
+       ON indicates that the cropped decoded pictures output are suitable for display using overscan. OFF indicates that the cropped decoded
+       pictures output contain visually important information in the entire region out to the edges of the cropping rectangle of the picture.
+       See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      OverscanAppropriate;
+    /*!
+       Instructs encoder whether frame rate info should present in VUI parameters. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      TimingInfoPresent;
+    /*!
+       Instructs encoder whether bitstream restriction info should present in VUI parameters. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      BitstreamRestriction;
+    /*!
+       Corresponds to AVC syntax element low_delay_hrd_flag (VUI). See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      LowDelayHrd;
+    /*!
+       When set to OFF, no sample outside the picture boundaries and no sample at a fractional sample position for which the sample value
+       is derived using one or more samples outside the picture boundaries is used for inter prediction of any sample.
+
+       When set to ON, one or more samples outside picture boundaries may be used in inter prediction.
+
+       See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      MotionVectorsOverPicBoundaries;
+    mfxU16      reserved1[2];
+
+    mfxU16      ScenarioInfo; /*!< Provides a hint to encoder about the scenario for the encoding session. See the ScenarioInfo enumerator for values of this option. */
+    mfxU16      ContentInfo;  /*!< Provides a hint to encoder about the content for the encoding session. See the ContentInfo enumerator for values of this option. */
+
+    mfxU16      PRefType;     /*!< When GopRefDist=1, specifies the model of reference list construction and DPB management. See the PRefType enumerator for values of this option. */
+    /*!
+       Instructs encoder whether internal fade detection algorithm should be used for calculation of weigh/offset values for pred_weight_table
+       unless application provided mfxExtPredWeightTable for this frame. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      FadeDetection;
+    mfxU16      reserved2[2];
+    /*!
+       Set this flag to OFF to make HEVC encoder use regular P-frames instead of GPB. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      GPB;
+
+    /*!
+       Same as mfxExtCodingOption2::MaxFrameSize but affects only I-frames. MaxFrameSizeI must be set if MaxFrameSizeP is set.
+       If MaxFrameSizeI is not specified or greater than spec limitation, spec limitation will be applied to the sizes of I-frames.
+    */
+    mfxU32      MaxFrameSizeI;
+    /*!
+       Same as mfxExtCodingOption2::MaxFrameSize but affects only P/B-frames. If MaxFrameSizeP equals 0, the library sets MaxFrameSizeP
+       equal to MaxFrameSizeI. If MaxFrameSizeP is not specified or greater than spec limitation, spec limitation will be applied to the
+       sizes of P/B-frames.
+    */
+    mfxU32      MaxFrameSizeP;
+    mfxU32      reserved3[3];
+
+    /*!
+       Enables QPOffset control. See the CodingOptionValue enumerator for values of this option.
+    */
+    mfxU16      EnableQPOffset;
+    /*!
+       Specifies QP offset per pyramid layer when EnableQPOffset is set to ON and RateControlMethod is CQP.
+
+       For B-pyramid, B-frame QP = QPB + QPOffset[layer].
+
+       For P-pyramid, P-frame QP = QPP + QPOffset[layer].
+    */
+    mfxI16      QPOffset[8];              /* FrameQP = QPX + QPOffset[pyramid_layer]; QPX = QPB for B-pyramid, QPP for P-pyramid */
+
+
+    mfxU16      NumRefActiveP[8];   /*!< Max number of active references for P-frames. Array index is pyramid layer. */
+    mfxU16      NumRefActiveBL0[8]; /*!< Max number of active references for B-frames in reference picture list 0. Array index is pyramid layer. */
+    mfxU16      NumRefActiveBL1[8]; /*!< Max number of active references for B-frames in reference picture list 1. Array index is pyramid layer. */
+
+    mfxU16      reserved6;
+    /*!
+       For HEVC if this option is turned ON, the transform_skip_enabled_flag will be set to 1 in PPS. OFF specifies that transform_skip_enabled_flag will be set to 0.
+    */
+    mfxU16      TransformSkip;
+    /*!
+       Minus 1 specifies target encoding chroma format (see ChromaFormatIdc enumerator). May differ from the source format.
+       TargetChromaFormatPlus1 = 0 specifies the default target chroma format which is equal to source (mfxVideoParam::mfx::FrameInfo::ChromaFormat + 1),
+       except RGB4 source format. In case of RGB4 source format default target , chroma format is 4:2:0 (instead of 4:4:4)
+       for the purpose of backward compatibility.
+    */
+    mfxU16      TargetChromaFormatPlus1;
+    /*!
+       Target encoding bit-depth for luma samples. May differ from source bit-depth. 0 specifies a default target bit-depth that is equal to
+       source (mfxVideoParam::mfx::FrameInfo::BitDepthLuma).
+    */
+    mfxU16      TargetBitDepthLuma;
+    /*!
+       Target encoding bit-depth for chroma samples. May differ from source bit-depth. 0 specifies a default target bit-depth that is equal to
+       source (mfxVideoParam::mfx::FrameInfo::BitDepthChroma).
+    */
+    mfxU16      TargetBitDepthChroma;
+    mfxU16      BRCPanicMode; /*!< Controls panic mode in AVC and MPEG2 encoders. */
+
+    /*!
+       When rate control method is MFX_RATECONTROL_VBR, MFX_RATECONTROL_QVBR or MFX_RATECONTROL_VCM this parameter specifies frame size
+       tolerance. Set this parameter to MFX_CODINGOPTION_ON to allow strictly obey average frame size set by MaxKbps, for example cases when
+       MaxFrameSize == (MaxKbps*1000)/(8* FrameRateExtN/FrameRateExtD). Also MaxFrameSizeI and MaxFrameSizeP can be set separately.
+    */
+    mfxU16      LowDelayBRC;
+    /*!
+       Set this flag to ON to enable usage of mfxExtMBForceIntra for AVC encoder. See the CodingOptionValue enumerator
+       for values of this option. This parameter is valid only during initialization.
+    */
+    mfxU16      EnableMBForceIntra;
+    /*!
+       If this flag is set to ON, BRC may decide a larger P- or B-frame size than what MaxFrameSizeP dictates when the scene change is detected.
+       It may benefit the video quality. AdaptiveMaxFrameSize feature is not supported with LowPower ON or if the value of MaxFrameSizeP = 0.
+    */
+    mfxU16      AdaptiveMaxFrameSize;
+
+    /*!
+       Controls AVC encoder attempts to predict from small partitions. Default value allows encoder to choose preferred mode.
+       MFX_CODINGOPTION_ON forces encoder to favor quality and MFX_CODINGOPTION_OFF forces encoder to favor performance.
+    */
+    mfxU16      RepartitionCheckEnable;
+    mfxU16      reserved5[3];
+    mfxU16      EncodedUnitsInfo;          /*!< Set this flag to ON to make encoded units info available in mfxExtEncodedUnitsInfo. */
+    /*!
+       If this flag is set to ON, the HEVC encoder uses the NAL unit type provided by the application in the mfxEncodeCtrl::MfxNalUnitType field.
+       This parameter is valid only during initialization.
+       @note Not all codecs and implementations support this value. Use the Query API function to check if this feature is supported.
+    */
+    mfxU16      EnableNalUnitType;
+
+    union {
+        MFX_DEPRECATED mfxU16      ExtBrcAdaptiveLTR; /* Deprecated */
+        
+        /*!
+            If this flag is set to ON, encoder will mark, modify, or remove LTR frames based on encoding parameters and content          
+            properties. Turn OFF to prevent Adaptive marking of Long Term Reference Frames. 
+        */
+        mfxU16      AdaptiveLTR;
+    };
+    /*!
+       If this flag is set to ON, encoder adaptively selects one of implementation-defined quantization matrices for each frame.
+       Non-default quantization matrices aim to improve subjective visual quality under certain conditions.
+       Their number and definitions are API implementation specific.
+       If this flag is set to OFF, default quantization matrix is used for all frames.
+       This parameter is valid only during initialization.
+    */
+    mfxU16      AdaptiveCQM;
+    /*!
+       If this flag is set to ON, encoder adaptively selects list of reference frames to imrove encoding quality.
+       Enabling of the flag can increase computation complexity and introduce additional delay.
+       If this flag is set to OFF, regular reference frames are used for encoding.
+    */
+    mfxU16      AdaptiveRef;
+  
+#ifdef ONEVPL_EXPERIMENTAL
+    /*!
+       The tri-state option specifies hint for the library to execute encoding tools processing on CPU. 
+       It may give better encoding quality, but leads to higher CPU utilization. 
+       The library can ignore MFX_CODINGOPTION_ON if processing on CPU is not supported.
+    */
+    mfxU16      CPUEncToolsProcessing;
+    mfxU16      reserved[160];
+#else
+    mfxU16      reserved[161];
+#endif     
+  
+} mfxExtCodingOption3;
+MFX_PACK_END()
+
+/*! IntraPredBlockSize/InterPredBlockSize specifies the minimum block size of inter-prediction. */
+enum {
+    MFX_BLOCKSIZE_UNKNOWN   = 0, /*!< Unspecified. */
+    MFX_BLOCKSIZE_MIN_16X16 = 1, /*!< 16x16 minimum block size.              */
+    MFX_BLOCKSIZE_MIN_8X8   = 2, /*!< 8x8 minimum block size. May be 16x16 or 8x8.         */
+    MFX_BLOCKSIZE_MIN_4X4   = 3  /*!< 4x4 minimum block size. May be 16x16, 8x8, or 4x4.    */
+};
+
+/*! The MVPrecision enumerator specifies the motion estimation precision. */
+enum {
+    MFX_MVPRECISION_UNKNOWN    = 0,
+    MFX_MVPRECISION_INTEGER    = (1 << 0),
+    MFX_MVPRECISION_HALFPEL    = (1 << 1),
+    MFX_MVPRECISION_QUARTERPEL = (1 << 2)
+};
+
+/*! The CodingOptionValue enumerator defines a three-state coding option setting. */
+enum {
+    MFX_CODINGOPTION_UNKNOWN    =0,    /*!< Unspecified. */
+    MFX_CODINGOPTION_ON         =0x10, /*!< Coding option set. */
+    MFX_CODINGOPTION_OFF        =0x20, /*!< Coding option not set. */
+    MFX_CODINGOPTION_ADAPTIVE   =0x30  /*!< Reserved. */
+};
+
+/*! The BitstreamDataFlag enumerator uses bit-ORed values to itemize additional information about the bitstream buffer. */
+enum {
+    MFX_BITSTREAM_NO_FLAG           = 0x0000, /*!< The bitstream doesn't contain any flags. */
+    /*!
+       The bitstream buffer contains a complete frame or complementary field pair of data for the bitstream. For decoding, this means
+       that the decoder can proceed with this buffer without waiting for the start of the next frame, which effectively reduces decoding latency.
+       If this flag is set, but the bitstream buffer contains incomplete frame or pair of field, then decoder will produce corrupted output.
+    */
+    MFX_BITSTREAM_COMPLETE_FRAME    = 0x0001,
+    /*!
+       The bitstream buffer contains the end of the stream. For decoding,
+       this means that the application does not have any additional bitstream data to send to decoder.
+    */
+    MFX_BITSTREAM_EOS               = 0x0002
+};
+/*! The ExtendedBufferID enumerator itemizes and defines identifiers (BufferId) for extended buffers or video processing algorithm identifiers. */
+enum {
+    /*!
+       This extended buffer defines additional encoding controls. See the mfxExtCodingOption structure for details.
+       The application can attach this buffer to the structure for encoding initialization.
+    */
+    MFX_EXTBUFF_CODING_OPTION                   = MFX_MAKEFOURCC('C','D','O','P'),
+    /*!
+       This extended buffer defines sequence header and picture header for encoders and decoders. See the mfxExtCodingOptionSPSPPS
+       structure for details. The application can attach this buffer to the mfxVideoParam structure for encoding initialization,
+       and for obtaining raw headers from the decoders and encoders.
+    */
+    MFX_EXTBUFF_CODING_OPTION_SPSPPS            = MFX_MAKEFOURCC('C','O','S','P'),
+    /*!
+       This extended buffer defines a list of VPP algorithms that applications should not use. See the mfxExtVPPDoNotUse structure
+       for details. The application can attach this buffer to the mfxVideoParam structure for video processing initialization.
+    */
+    MFX_EXTBUFF_VPP_DONOTUSE                    = MFX_MAKEFOURCC('N','U','S','E'),
+    /*!
+       This extended buffer defines auxiliary information at the VPP output. See the mfxExtVppAuxData structure for details. The application
+       can attach this buffer to the mfxEncodeCtrl structure for per-frame encoding control.
+    */
+    MFX_EXTBUFF_VPP_AUXDATA                     = MFX_MAKEFOURCC('A','U','X','D'),
+    /*!
+       The extended buffer defines control parameters for the VPP denoise filter algorithm. See the mfxExtVPPDenoise2 structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for video processing initialization.
+    */
+    MFX_EXTBUFF_VPP_DENOISE2                    = MFX_MAKEFOURCC('D','N','I','2'),
+    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_VPP_DENOISE)                     = MFX_MAKEFOURCC('D','N','I','S'), /*!< Deprecated in 2.2 API version.*/
+    MFX_EXTBUFF_VPP_SCENE_ANALYSIS              = MFX_MAKEFOURCC('S','C','L','Y'), /*!< Reserved for future use. */
+    MFX_DEPRECATED_ENUM_FIELD_INSIDE(MFX_EXTBUFF_VPP_SCENE_CHANGE)                = MFX_EXTBUFF_VPP_SCENE_ANALYSIS, /* Deprecated. */
+    /*!
+       The extended buffer defines control parameters for the VPP ProcAmp filter algorithm. See the mfxExtVPPProcAmp structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for video processing initialization or to the mfxFrameData
+       structure in the mfxFrameSurface1 structure of output surface for per-frame processing configuration.
+    */
+    MFX_EXTBUFF_VPP_PROCAMP                     = MFX_MAKEFOURCC('P','A','M','P'),
+    /*!
+       The extended buffer defines control parameters for the VPP detail filter algorithm. See the mfxExtVPPDetail structure for details.
+       The application can attach this buffer to the structure for video processing initialization.
+    */
+    MFX_EXTBUFF_VPP_DETAIL                      = MFX_MAKEFOURCC('D','E','T',' '),
+    /*!
+       This extended buffer defines video signal type. See the mfxExtVideoSignalInfo structure for details. The application can attach this
+       buffer to the mfxVideoParam structure for encoding initialization, and for retrieving such information from the decoders. If video
+       signal info changes per frame, the application can attach this buffer to the mfxFrameData structure for video processing.
+    */
+    MFX_EXTBUFF_VIDEO_SIGNAL_INFO               = MFX_MAKEFOURCC('V','S','I','N'),
+    /*!
+       This extended buffer defines video signal type. See the mfxExtVideoSignalInfo structure for details. The application can attach this
+       buffer to the mfxVideoParam structure for the input of video processing if the input video signal information changes in sequence
+       base.
+    */
+    MFX_EXTBUFF_VIDEO_SIGNAL_INFO_IN            = MFX_MAKEFOURCC('V','S','I','I'),
+    /*!
+       This extended buffer defines video signal type. See the mfxExtVideoSignalInfo structure for details. The application can attach this
+       buffer to the mfxVideoParam structure for the output of video processing if the output video signal information changes in sequence
+       base.
+    */
+    MFX_EXTBUFF_VIDEO_SIGNAL_INFO_OUT           = MFX_MAKEFOURCC('V','S','I','O'),
+    /*!
+       This extended buffer defines a list of VPP algorithms that applications should use. See the mfxExtVPPDoUse structure for details.
+       The application can attach this buffer to the structure for video processing initialization.
+    */
+    MFX_EXTBUFF_VPP_DOUSE                       = MFX_MAKEFOURCC('D','U','S','E'),
+    /*!
+       This extended buffer defines additional encoding controls for reference list. See the mfxExtAVCRefListCtrl structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for encoding & decoding initialization, or the mfxEncodeCtrl
+       structure for per-frame encoding configuration.
+    */
+    MFX_EXTBUFF_AVC_REFLIST_CTRL                = MFX_MAKEFOURCC('R','L','S','T'),
+    /*!
+       This extended buffer defines control parameters for the VPP frame rate conversion algorithm. See the mfxExtVPPFrameRateConversion structure
+       for details. The application can attach this buffer to the mfxVideoParam structure for video processing initialization.
+    */
+    MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION       = MFX_MAKEFOURCC('F','R','C',' '),
+    /*!
+       This extended buffer configures the H.264 picture timing SEI message. See the mfxExtPictureTimingSEI structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for encoding initialization, or the mfxEncodeCtrl structure
+       for per-frame encoding configuration.
+    */
+    MFX_EXTBUFF_PICTURE_TIMING_SEI              = MFX_MAKEFOURCC('P','T','S','E'),
+    /*!
+       This extended buffer configures the structure of temporal layers inside the encoded H.264 bitstream. See the mfxExtAvcTemporalLayers
+       structure for details. The application can attach this buffer to the mfxVideoParam structure for encoding initialization.
+    */
+    MFX_EXTBUFF_AVC_TEMPORAL_LAYERS             = MFX_MAKEFOURCC('A','T','M','L'),
+    /*!
+       This extended buffer defines additional encoding controls. See the mfxExtCodingOption2 structure for details.
+       The application can attach this buffer to the structure for encoding initialization.
+    */
+    MFX_EXTBUFF_CODING_OPTION2                  = MFX_MAKEFOURCC('C','D','O','2'),
+    /*!
+       This extended buffer defines control parameters for the VPP image stabilization filter algorithm. See the mfxExtVPPImageStab structure
+       for details. The application can attach this buffer to the mfxVideoParam structure for video processing initialization.
+    */
+    MFX_EXTBUFF_VPP_IMAGE_STABILIZATION         = MFX_MAKEFOURCC('I','S','T','B'),
+    /*!
+       This extended buffer is used to retrieve encoder capability. See the mfxExtEncoderCapability structure for details.
+       The application can attach this buffer to the mfxVideoParam structure before calling MFXVideoENCODE_Query function.
+    */
+    MFX_EXTBUFF_ENCODER_CAPABILITY              = MFX_MAKEFOURCC('E','N','C','P'),
+    /*!
+       This extended buffer is used to control encoder reset behavior and also to query possible encoder reset outcome.
+       See the mfxExtEncoderResetOption structure for details. The application can attach this buffer to the mfxVideoParam structure
+       before calling MFXVideoENCODE_Query or MFXVideoENCODE_Reset functions.
+    */
+    MFX_EXTBUFF_ENCODER_RESET_OPTION            = MFX_MAKEFOURCC('E','N','R','O'),
+    /*!
+       This extended buffer is used by the encoder to report additional information about encoded picture.
+       See the mfxExtAVCEncodedFrameInfo structure for details. The application can attach this buffer to the mfxBitstream structure
+       before calling MFXVideoENCODE_EncodeFrameAsync function.
+    */
+    MFX_EXTBUFF_ENCODED_FRAME_INFO              = MFX_MAKEFOURCC('E','N','F','I'),
+    /*!
+       This extended buffer is used to control composition of several input surfaces in the one output. In this mode,
+       the VPP skips any other filters. The VPP returns error if any mandatory filter is specified and filter skipped warning
+       for optional filter. The only supported filters are deinterlacing and interlaced scaling.
+    */
+    MFX_EXTBUFF_VPP_COMPOSITE                   = MFX_MAKEFOURCC('V','C','M','P'),
+    /*!
+       This extended buffer is used to control transfer matrix and nominal range of YUV frames.
+       The application should provide it during initialization.
+    */
+    MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO           = MFX_MAKEFOURCC('V','V','S','I'),
+    /*!
+       This extended buffer is used by the application to specify different Region Of Interests during encoding.
+       The application should provide it at initialization or at runtime.
+    */
+    MFX_EXTBUFF_ENCODER_ROI                     = MFX_MAKEFOURCC('E','R','O','I'),
+    /*!
+       This extended buffer is used by the application to specify different deinterlacing algorithms.
+    */
+    MFX_EXTBUFF_VPP_DEINTERLACING               = MFX_MAKEFOURCC('V','P','D','I'),
+    /*!
+       This extended buffer specifies reference lists for the encoder.
+    */
+    MFX_EXTBUFF_AVC_REFLISTS                    = MFX_MAKEFOURCC('R','L','T','S'),
+    /*!
+       See the mfxExtDecVideoProcessing structure for details.
+    */
+    MFX_EXTBUFF_DEC_VIDEO_PROCESSING            = MFX_MAKEFOURCC('D','E','C','V'),
+    /*!
+       The extended buffer defines control parameters for the VPP field-processing algorithm. See the mfxExtVPPFieldProcessing
+       structure for details. The application can attach this buffer to the mfxVideoParam structure for video processing initialization
+       or to the mfxFrameData structure during runtime.
+    */
+    MFX_EXTBUFF_VPP_FIELD_PROCESSING            = MFX_MAKEFOURCC('F','P','R','O'),
+    /*!
+       This extended buffer defines additional encoding controls. See the mfxExtCodingOption3 structure for details.
+       The application can attach this buffer to the structure for encoding initialization.
+    */
+    MFX_EXTBUFF_CODING_OPTION3                  = MFX_MAKEFOURCC('C','D','O','3'),
+    /*!
+       This extended buffer defines chroma samples location information. See the mfxExtChromaLocInfo structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for encoding initialization.
+    */
+    MFX_EXTBUFF_CHROMA_LOC_INFO                 = MFX_MAKEFOURCC('C','L','I','N'),
+    /*!
+       This extended buffer defines per-macroblock QP. See the mfxExtMBQP structure for details.
+       The application can attach this buffer to the mfxEncodeCtrl structure for per-frame encoding configuration.
+    */
+    MFX_EXTBUFF_MBQP                            = MFX_MAKEFOURCC('M','B','Q','P'),
+    /*!
+       This extended buffer defines per-macroblock force intra flag. See the mfxExtMBForceIntra structure for details.
+       The application can attach this buffer to the mfxEncodeCtrl structure for per-frame encoding configuration.
+    */
+    MFX_EXTBUFF_MB_FORCE_INTRA                  = MFX_MAKEFOURCC('M','B','F','I'),
+    /*!
+       This extended buffer defines additional encoding controls for HEVC tiles. See the mfxExtHEVCTiles structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for encoding initialization.
+    */
+    MFX_EXTBUFF_HEVC_TILES                      = MFX_MAKEFOURCC('2','6','5','T'),
+    /*!
+       This extended buffer defines macroblock map for current frame which forces specified macroblocks to be non skip. See the
+       mfxExtMBDisableSkipMap structure for details. The application can attach this buffer to the mfxEncodeCtrl structure for
+       per-frame encoding configuration.
+    */
+    MFX_EXTBUFF_MB_DISABLE_SKIP_MAP             = MFX_MAKEFOURCC('M','D','S','M'),
+    /*!
+       See the mfxExtHEVCParam structure for details.
+    */
+    MFX_EXTBUFF_HEVC_PARAM                      = MFX_MAKEFOURCC('2','6','5','P'),
+    /*!
+       This extended buffer is used by decoders to report additional information about decoded frame. See the
+       mfxExtDecodedFrameInfo structure for more details.
+    */
+    MFX_EXTBUFF_DECODED_FRAME_INFO              = MFX_MAKEFOURCC('D','E','F','I'),
+    /*!
+       See the mfxExtTimeCode structure for more details.
+    */
+    MFX_EXTBUFF_TIME_CODE                       = MFX_MAKEFOURCC('T','M','C','D'),
+    /*!
+       This extended buffer specifies the region to encode. The application can attach this buffer to the
+       mfxVideoParam structure during HEVC encoder initialization.
+    */
+    MFX_EXTBUFF_HEVC_REGION                     = MFX_MAKEFOURCC('2','6','5','R'),
+    /*!
+       See the mfxExtPredWeightTable structure for details.
+    */
+    MFX_EXTBUFF_PRED_WEIGHT_TABLE               = MFX_MAKEFOURCC('E','P','W','T'),
+    /*!
+       See the mfxExtDitrtyRect structure for details.
+    */
+    MFX_EXTBUFF_DIRTY_RECTANGLES                = MFX_MAKEFOURCC('D','R','O','I'),
+    /*!
+       See the mfxExtMoveRect structure for details.
+    */
+    MFX_EXTBUFF_MOVING_RECTANGLES               = MFX_MAKEFOURCC('M','R','O','I'),
+    /*!
+       See the mfxExtCodingOptionVPS structure for details.
+    */
+    MFX_EXTBUFF_CODING_OPTION_VPS               = MFX_MAKEFOURCC('C','O','V','P'),
+    /*!
+       See the mfxExtVPPRotation structure for details.
+    */
+    MFX_EXTBUFF_VPP_ROTATION                    = MFX_MAKEFOURCC('R','O','T',' '),
+    /*!
+       See the mfxExtEncodedSlicesInfo structure for details.
+    */
+    MFX_EXTBUFF_ENCODED_SLICES_INFO             = MFX_MAKEFOURCC('E','N','S','I'),
+    /*!
+       See the mfxExtVPPScaling structure for details.
+    */
+    MFX_EXTBUFF_VPP_SCALING                     = MFX_MAKEFOURCC('V','S','C','L'),
+    /*!
+       This extended buffer defines additional encoding controls for reference list. See the mfxExtAVCRefListCtrl structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for encoding & decoding initialization, or
+       the mfxEncodeCtrl structure for per-frame encoding configuration.
+    */
+    MFX_EXTBUFF_HEVC_REFLIST_CTRL               = MFX_EXTBUFF_AVC_REFLIST_CTRL,
+    /*!
+       This extended buffer specifies reference lists for the encoder.
+    */
+    MFX_EXTBUFF_HEVC_REFLISTS                   = MFX_EXTBUFF_AVC_REFLISTS,
+    /*!
+       This extended buffer configures the structure of temporal layers inside the encoded H.264 bitstream. See the mfxExtAvcTemporalLayers
+       structure for details. The application can attach this buffer to the mfxVideoParam structure for encoding initialization.
+    */
+    MFX_EXTBUFF_HEVC_TEMPORAL_LAYERS            = MFX_EXTBUFF_AVC_TEMPORAL_LAYERS,
+    /*!
+       See the mfxExtVPPMirroring structure for details.
+    */
+    MFX_EXTBUFF_VPP_MIRRORING                   = MFX_MAKEFOURCC('M','I','R','R'),
+    /*!
+       See the mfxExtMVOverPicBoundaries structure for details.
+    */
+    MFX_EXTBUFF_MV_OVER_PIC_BOUNDARIES          = MFX_MAKEFOURCC('M','V','P','B'),
+    /*!
+       See the mfxExtVPPColorFill structure for details.
+    */
+    MFX_EXTBUFF_VPP_COLORFILL                   = MFX_MAKEFOURCC('V','C','L','F'),
+    /*!
+       This extended buffer is used by decoders to report error information before frames get decoded.
+       See the mfxExtDecodeErrorReport structure for more details.
+    */
+    MFX_EXTBUFF_DECODE_ERROR_REPORT             = MFX_MAKEFOURCC('D', 'E', 'R', 'R'),
+    /*!
+       See the mfxExtColorConversion structure for details.
+    */
+    MFX_EXTBUFF_VPP_COLOR_CONVERSION            = MFX_MAKEFOURCC('V', 'C', 'S', 'C'),
+    /*!
+       This extended buffer configures HDR SEI message. See the mfxExtContentLightLevelInfo structure for details.
+    */
+    MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO        = MFX_MAKEFOURCC('L', 'L', 'I', 'S'),
+    /*!
+       This extended buffer configures HDR SEI message. See the mfxExtMasteringDisplayColourVolume structure for details. If colour volume changes
+       per frame, the application can attach this buffer to the mfxFrameData structure for video processing.
+    */
+    MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME = MFX_MAKEFOURCC('D', 'C', 'V', 'S'),
+    /*!
+       This extended buffer configures HDR SEI message. See the mfxExtMasteringDisplayColourVolume structure for details. The application can
+       attach this buffer to the mfxVideoParam structure for the input of video processing if the mastering display colour volume changes per
+       sequence. In this case, this buffer should be together with MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO to indicate the light level and mastering
+       colour volume of the input of video processing. If colour Volume changes per frame instead of per sequence, the application can attach
+       MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME to mfxFrameData for frame based processing.
+    */
+    MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME_IN         = MFX_MAKEFOURCC('D', 'C', 'V', 'I'),
+    /*!
+       This extended buffer configures HDR SEI message. See the mfxExtMasteringDisplayColourVolume structure for details. The application can
+       attach this buffer to the mfxVideoParam structure for the output of video processing if the mastering display colour volume changes per
+       sequence. If colour volume changes per frame instead of per sequence, the application can attach the buffer with MFX_EXTBUFF_MASTERING_
+       DISPLAY_COLOUR_VOLUME to mfxFrameData for frame based processing.
+    */
+    MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME_OUT        = MFX_MAKEFOURCC('D', 'C', 'V', 'O'),
+    /*!
+       See the mfxExtEncodedUnitsInfo structure for details.
+    */
+    MFX_EXTBUFF_ENCODED_UNITS_INFO              = MFX_MAKEFOURCC('E', 'N', 'U', 'I'),
+    /*!
+       This video processing algorithm identifier is used to enable MCTF via mfxExtVPPDoUse and together with mfxExtVppMctf
+    */
+    MFX_EXTBUFF_VPP_MCTF                        = MFX_MAKEFOURCC('M', 'C', 'T', 'F'),
+    /*!
+       Extends mfxVideoParam structure with VP9 segmentation parameters. See the mfxExtVP9Segmentation structure for details.
+    */
+    MFX_EXTBUFF_VP9_SEGMENTATION                = MFX_MAKEFOURCC('9', 'S', 'E', 'G'),
+    /*!
+       Extends mfxVideoParam structure with parameters for VP9 temporal scalability. See the mfxExtVP9TemporalLayers structure for details.
+    */
+    MFX_EXTBUFF_VP9_TEMPORAL_LAYERS             = MFX_MAKEFOURCC('9', 'T', 'M', 'L'),
+    /*!
+       Extends mfxVideoParam structure with VP9-specific parameters. See the mfxExtVP9Param structure for details.
+    */
+    MFX_EXTBUFF_VP9_PARAM                       = MFX_MAKEFOURCC('9', 'P', 'A', 'R'),
+    /*!
+       See the mfxExtAVCRoundingOffset structure for details.
+    */
+    MFX_EXTBUFF_AVC_ROUNDING_OFFSET             = MFX_MAKEFOURCC('R','N','D','O'),
+    /*!
+       See the mfxExtPartialBitstreamParam structure for details.
+    */
+    MFX_EXTBUFF_PARTIAL_BITSTREAM_PARAM         = MFX_MAKEFOURCC('P','B','O','P'),
+
+    /*!
+       See the mfxExtEncoderIPCMArea structure for details.
+    */
+    MFX_EXTBUFF_ENCODER_IPCM_AREA  = MFX_MAKEFOURCC('P', 'C', 'M', 'R'),
+    /*!
+       See the mfxExtInsertHeaders structure for details.
+    */
+    MFX_EXTBUFF_INSERT_HEADERS  = MFX_MAKEFOURCC('S', 'P', 'R', 'E'),
+
+    /*!
+       See the mfxExtDeviceAffinityMask structure for details.
+    */
+    MFX_EXTBUFF_DEVICE_AFFINITY_MASK = MFX_MAKEFOURCC('D', 'A', 'F', 'M'),
+
+    /*!
+       See the mfxExtInCrops structure for details.
+    */
+    MFX_EXTBUFF_CROPS = MFX_MAKEFOURCC('C', 'R', 'O', 'P'),
+
+    /*!
+        See the mfxExtAV1BitstreamParam structure for more details.
+    */
+    MFX_EXTBUFF_AV1_BITSTREAM_PARAM             = MFX_MAKEFOURCC('A', '1', 'B', 'S'),
+
+    /*!
+        See the mfxExtAV1ResolutionParam structure for more details.
+    */
+    MFX_EXTBUFF_AV1_RESOLUTION_PARAM            = MFX_MAKEFOURCC('A', '1', 'R', 'S'),
+
+    /*!
+        See the mfxExtAV1TileParam structure for more details.
+    */
+    MFX_EXTBUFF_AV1_TILE_PARAM                  = MFX_MAKEFOURCC('A', '1', 'T', 'L'),
+
+    /*!
+        See the mfxExtAV1Segmentation structure for more details.
+    */
+    MFX_EXTBUFF_AV1_SEGMENTATION                = MFX_MAKEFOURCC('1', 'S', 'E', 'G'),
+
+    /*!
+       See the mfxExtAV1FilmGrainParam structure for more details.
+    */
+    MFX_EXTBUFF_AV1_FILM_GRAIN_PARAM = MFX_MAKEFOURCC('A','1','F','G'),
+
+    /*!
+       See the mfxExtHyperModeParam structure for more details.
+    */
+    MFX_EXTBUFF_HYPER_MODE_PARAM = MFX_MAKEFOURCC('H', 'Y', 'P', 'M'),
+    /*!
+       See the mfxExtTemporalLayers structure for more details.
+    */
+    MFX_EXTBUFF_UNIVERSAL_TEMPORAL_LAYERS = MFX_MAKEFOURCC('U', 'T', 'M', 'P'),
+#ifdef ONEVPL_EXPERIMENTAL    
+    /*!
+       This extended buffer defines additional encoding controls for reference list. See the mfxExtRefListCtrl structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for encoding & decoding initialization, or
+       the mfxEncodeCtrl structure for per-frame encoding configuration.
+    */
+    MFX_EXTBUFF_UNIVERSAL_REFLIST_CTRL = MFX_EXTBUFF_AVC_REFLIST_CTRL,
+#endif
+    /*!
+       See the mfxExtVPP3DLut structure for more details.
+    */
+    MFX_EXTBUFF_VPP_3DLUT = MFX_MAKEFOURCC('T','D','L','T'),
+
+    /*!
+       See the mfxExtAllocationHints structure for more details.
+    */
+    MFX_EXTBUFF_ALLOCATION_HINTS = MFX_MAKEFOURCC('A','L','C','H'),
+};
+
+/* VPP Conf: Do not use certain algorithms  */
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Tells the VPP not to use certain filters in pipeline. See “Configurable VPP filters” table for complete
+   list of configurable filters. The user can attach this structure to the mfxVideoParam structure when initializing video processing.
+*/
+typedef struct {
+    mfxExtBuffer    Header;  /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_DONOTUSE. */
+    mfxU32          NumAlg;  /*!< Number of filters (algorithms) not to use */
+    mfxU32*         AlgList; /*!< Pointer to a list of filters (algorithms) not to use */
+} mfxExtVPPDoNotUse;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   A hint structure that configures the VPP denoise filter algorithm.
+   @deprecated Deprecated in API version 2.5. Use mfxExtVPPDenoise2 instead.
+*/
+MFX_DEPRECATED typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_DENOISE. */
+    mfxU16  DenoiseFactor;  /*!< Indicates the level of noise to remove. Value range of 0 to 100 (inclusive).  */
+} mfxExtVPPDenoise;
+MFX_PACK_END()
+
+/*! The mfxDenoiseMode enumerator specifies the mode of denoise. */
+typedef enum {
+    MFX_DENOISE_MODE_DEFAULT    = 0,     /*!< Default denoise mode. The library selects the most appropriate denoise mode. */
+    MFX_DENOISE_MODE_VENDOR     = 1000,  /*!< The enumeration to separate common denoise mode above and vendor specific. */
+
+    MFX_DENOISE_MODE_INTEL_HVS_AUTO_BDRATE     = MFX_DENOISE_MODE_VENDOR + 1,  /*!< Indicates auto BD rate improvement in pre-processing before video encoding,
+                                                                                    ignore Strength.*/
+    MFX_DENOISE_MODE_INTEL_HVS_AUTO_SUBJECTIVE = MFX_DENOISE_MODE_VENDOR + 2,  /*!< Indicates auto subjective quality improvement in pre-processing before video encoding,
+                                                                                    ignore Strength.*/
+    MFX_DENOISE_MODE_INTEL_HVS_AUTO_ADJUST     = MFX_DENOISE_MODE_VENDOR + 3,  /*!< Indicates auto adjust subjective quality in post-processing (after decoding) for video playback,
+                                                                                    ignore Strength.*/
+    MFX_DENOISE_MODE_INTEL_HVS_PRE_MANUAL      = MFX_DENOISE_MODE_VENDOR + 4,  /*!< Indicates manual mode for pre-processing before video encoding,
+                                                                                    allow to adjust the denoise strength manually.*/
+    MFX_DENOISE_MODE_INTEL_HVS_POST_MANUAL     = MFX_DENOISE_MODE_VENDOR + 5,  /*!< Indicates manual mode for post-processing for video playback,
+                                                                                    allow to adjust the denoise strength manually.*/
+} mfxDenoiseMode;
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   A hint structure that configures the VPP denoise filter algorithm.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_DENOISE2. */
+    mfxDenoiseMode  Mode;   /*!< Indicates the mode of denoise. mfxDenoiseMode enumerator.  */
+    mfxU16  Strength;       /*!< Denoise strength in manaul mode. Value of 0-100 (inclusive) indicates the strength of denoise.
+                                 The strength of denoise controls degree of possible changes of pixel values; the bigger the strength
+                                 the larger the change is.  */
+    mfxU16  reserved[15];
+} mfxExtVPPDenoise2;
+MFX_PACK_END()
+
+/*! The mfx3DLutChannelMapping enumerator specifies the channel mapping of 3DLUT. */
+typedef enum {
+    MFX_3DLUT_CHANNEL_MAPPING_DEFAULT            = 0,   /*!< Default 3DLUT channel mapping. The library selects the most appropriate 3DLUT channel mapping. */
+    MFX_3DLUT_CHANNEL_MAPPING_RGB_RGB            = 1,   /*!< 3DLUT RGB channels map to RGB channels. */
+    MFX_3DLUT_CHANNEL_MAPPING_YUV_RGB            = 2,   /*!< 3DLUT YUV channels map to RGB channels. */
+    MFX_3DLUT_CHANNEL_MAPPING_VUY_RGB            = 3,   /*!< 3DLUT VUY channels map to RGB channels. */
+} mfx3DLutChannelMapping;
+
+/*! The mfx3DLutMemoryLayout enumerator specifies the memory layout of 3DLUT. */
+typedef enum {
+    MFX_3DLUT_MEMORY_LAYOUT_DEFAULT                        = 0,          /*!< Default 3DLUT memory layout. The library selects the most appropriate 3DLUT memory layout.*/
+
+    MFX_3DLUT_MEMORY_LAYOUT_VENDOR                         = 0x1000,     /*!< The enumeration to separate default above and vendor specific.*/
+    /*!
+       Intel specific memory layout. The enumerator indicates the attributes and memory layout of 3DLUT.
+       3DLUT size is 17(the number of elements per dimension), 4 channels(3 valid channels, 1 channel is reserved), every channel must be 16-bit unsigned integer.
+       3DLUT contains 17x17x32 entries with holes that are not filled. Take RGB as example, the nodes RxGx17 to RxGx31 are not filled, are "don't care" bits, and not accessed for the 17x17x17 nodes.
+    */
+    MFX_3DLUT_MEMORY_LAYOUT_INTEL_17LUT                    = MFX_3DLUT_MEMORY_LAYOUT_VENDOR + 1,
+    /*!
+       Intel specific memory layout. The enumerator indicates the attributes and memory layout of 3DLUT.
+       3DLUT size is 33(the number of elements per dimension), 4 channels(3 valid channels, 1 channel is reserved), every channel must be 16-bit unsigned integer.
+       3DLUT contains 33x33x64 entries with holes that are not filled. Take RGB as example, the nodes RxGx33 to RxGx63 are not filled, are "don't care" bits, and not accessed for the 33x33x33 nodes.
+    */
+    MFX_3DLUT_MEMORY_LAYOUT_INTEL_33LUT                    = MFX_3DLUT_MEMORY_LAYOUT_VENDOR + 2,
+    /*!
+       Intel specific memory layout. The enumerator indicates the attributes and memory layout of 3DLUT.
+       3DLUT size is 65(the number of elements per dimension), 4 channels(3 valid channels, 1 channel is reserved), every channel must be 16-bit unsigned integer.
+       3DLUT contains 65x65x128 entries with holes that are not filled. Take RGB as example, the nodes RxGx65 to RxGx127 are not filled, are "don't care" bits, and not accessed for the 65x65x65 nodes.
+    */
+    MFX_3DLUT_MEMORY_LAYOUT_INTEL_65LUT                    = MFX_3DLUT_MEMORY_LAYOUT_VENDOR + 3,
+} mfx3DLutMemoryLayout;
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+    A hint structure that configures the data channel.
+*/
+typedef struct {
+    mfxDataType  DataType;                /*!< Data type, mfxDataType enumerator.*/
+    mfxU32       Size;                    /*!< Size of Look up table, the number of elements per dimension.*/
+    union
+    {
+        mfxU8*     Data;                  /*!< The pointer to 3DLUT data, 8 bit unsigned integer.*/
+        mfxU16*    Data16;                /*!< The pointer to 3DLUT data, 16 bit unsigned integer.*/
+    };
+    mfxU32       reserved[4];             /*!< Reserved for future extension.*/
+} mfxChannel;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+    A hint structure that configures 3DLUT system buffer.
+*/
+typedef struct {
+    mfxChannel           Channel[3];        /*!< 3 Channels, can be RGB or YUV, mfxChannel structure.*/
+    mfxU32               reserved[8];       /*!< Reserved for future extension.*/
+} mfx3DLutSystemBuffer;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+    A hint structure that configures 3DLUT video buffer.
+*/
+typedef struct {
+    mfxDataType                DataType;       /*!< Data type, mfxDataType enumerator.*/
+    mfx3DLutMemoryLayout       MemLayout;      /*!< Indicates 3DLUT memory layout. mfx3DLutMemoryLayout enumerator.*/
+    mfxMemId                   MemId;          /*!< Memory ID for holding the lookup table data. One MemID is dedicated for one instance of VPP.*/
+    mfxU32                     reserved[8];    /*!< Reserved for future extension.*/
+} mfx3DLutVideoBuffer;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+    A hint structure that configures 3DLUT filter.
+*/
+typedef struct {
+    mfxExtBuffer             Header;           /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_3DLUT..*/
+    mfx3DLutChannelMapping   ChannelMapping;   /*!< Indicates 3DLUT channel mapping. mfx3DLutChannelMapping enumerator.*/
+    mfxResourceType          BufferType;       /*!< Indicates 3DLUT buffer type. mfxResourceType enumerator, can be system memory, VA surface, DX11 texture/buffer etc.*/
+    union
+    {
+        mfx3DLutSystemBuffer SystemBuffer;     /*!< The 3DLUT system buffer. mfx3DLutSystemBuffer structure describes the details of the buffer.*/
+        mfx3DLutVideoBuffer  VideoBuffer;      /*!< The 3DLUT video buffer. mfx3DLutVideoBuffer describes the details of 3DLUT video buffer.*/
+    };
+    mfxU32                   reserved[4];      /*!< Reserved for future extension.*/
+} mfxExtVPP3DLut;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   A hint structure that configures the VPP detail/edge enhancement filter algorithm.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_DETAIL. */
+    mfxU16  DetailFactor;   /*!< Indicates the level of details to be enhanced. Value range of 0 to 100 (inclusive).  */
+} mfxExtVPPDetail;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   A hint structure that configures the VPP ProcAmp filter algorithm.
+   The structure parameters will be clipped to their corresponding range and rounded by their corresponding increment.
+   @note There are no default values for fields in this structure, all settings must be explicitly specified every time this
+         buffer is submitted for processing.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_PROCAMP. */
+    mfxF64   Brightness;    /*!< The brightness parameter is in the range of -100.0F to 100.0F, in increments of 0.1F.
+                                 Setting this field to 0.0F will disable brightness adjustment. */
+    mfxF64   Contrast;      /*!< The contrast parameter in the range of 0.0F to 10.0F, in increments of 0.01F, is used for manual
+                                 contrast adjustment. Setting this field to 1.0F will disable contrast adjustment. If the parameter
+                                 is negative, contrast will be adjusted automatically. */
+    mfxF64   Hue;           /*!< The hue parameter is in the range of -180F to 180F, in increments of 0.1F. Setting this field to 0.0F
+                                 will disable hue adjustment. */
+    mfxF64   Saturation;    /*!< The saturation parameter is in the range of 0.0F to 10.0F, in increments of 0.01F.
+                                 Setting this field to 1.0F will disable saturation adjustment. */
+} mfxExtVPPProcAmp;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   Returns statistics collected during encoding.
+*/
+typedef struct {
+    mfxU32  reserved[16];
+    mfxU32  NumFrame;       /*!< Number of encoded frames. */
+    mfxU64  NumBit;         /*!< Number of bits for all encoded frames. */
+    mfxU32  NumCachedFrame; /*!< Number of internally cached frames. */
+} mfxEncodeStat;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Returns statistics collected during decoding.
+*/
+typedef struct {
+    mfxU32  reserved[16];
+    mfxU32  NumFrame;        /*!< Number of total decoded frames. */
+    mfxU32  NumSkippedFrame; /*!< Number of skipped frames. */
+    mfxU32  NumError;        /*!< Number of errors recovered. */
+    mfxU32  NumCachedFrame;  /*!< Number of internally cached frames. */
+} mfxDecodeStat;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Returns statistics collected during video processing.
+*/
+typedef struct {
+    mfxU32  reserved[16];
+    mfxU32  NumFrame;       /*!< Total number of frames processed. */
+    mfxU32  NumCachedFrame; /*!< Number of internally cached frames. */
+} mfxVPPStat;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Returns auxiliary data generated by the video processing pipeline.
+   The encoding process may use the auxiliary data by attaching this structure to the mfxEncodeCtrl structure.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_AUXDATA. */
+
+    union{
+        struct{
+            MFX_DEPRECATED mfxU32  SpatialComplexity; /* Deprecated */
+            MFX_DEPRECATED mfxU32  TemporalComplexity; /* Deprecated */
+        };
+        struct{
+            /*!
+               Detected picture structure - top field first, bottom field first, progressive or unknown if video processor cannot
+               detect picture structure. See the PicStruct enumerator for definition of these values.
+
+            */
+            mfxU16  PicStruct;
+            mfxU16  reserved[3];
+        };
+    };
+    MFX_DEPRECATED  mfxU16          SceneChangeRate; /* Deprecated */
+    MFX_DEPRECATED  mfxU16          RepeatedFrame;   /* Deprecated */
+} mfxExtVppAuxData;
+MFX_PACK_END()
+
+/*! The PayloadCtrlFlags enumerator itemizes additional payload properties. */
+enum {
+    MFX_PAYLOAD_CTRL_SUFFIX = 0x00000001 /*!< Insert this payload into HEVC Suffix SEI NAL-unit. */
+};
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Describes user data payload in MPEG-2 or SEI message payload in H.264.
+
+   For encoding, these payloads can be
+   inserted into the bitstream. The payload buffer must contain a valid formatted payload.
+
+   For H.264, this is the sei_message() as
+   specified in the section 7.3.2.3.1 'Supplemental enhancement information message syntax' of the ISO/IEC 14496-10 specification.
+
+   For MPEG-2,
+   this is the section 6.2.2.2.2 'User data' of the ISO/IEC 13818-2 specification, excluding the user data start_code.
+
+   For decoding,
+   these payloads can be retrieved as the decoder parses the bitstream and caches them in an internal buffer.
+
+   @internal
+   +-----------+-------------------------------------------+
+   | **Codec** | **Supported Types**                       |
+   +===========+===========================================+
+   | MPEG2     | 0x01B2 //User Data                        |
+   +-----------+-------------------------------------------+
+   | AVC       | 02 //pan_scan_rect                        |
+   |           | 03 //filler_payload                       |
+   |           | 04 //user_data_registered_itu_t_t35       |
+   |           | 05 //user_data_unregistered               |
+   |           | 06 //recovery_point                       |
+   |           | 09 //scene_info                           |
+   |           | 13 //full_frame_freeze                    |
+   |           | 14 //full_frame_freeze_release            |
+   |           | 15 //full_frame_snapshot                  |
+   |           | 16 //progressive_refinement_segment_start |
+   |           | 17 //progressive_refinement_segment_end   |
+   |           | 19 //film_grain_characteristics           |
+   |           | 20 //deblocking_filter_display_preference |
+   |           | 21 //stereo_video_info                    |
+   |           | 45 //frame_packing_arrangement            |
+   +-----------+-------------------------------------------+
+   | HEVC      | All                                       |
+   +-----------+-------------------------------------------+
+   @endinternal
+
+*/
+typedef struct {
+    mfxU32      CtrlFlags;  /*!< Additional payload properties. See the PayloadCtrlFlags enumerator for details. */
+    mfxU32      reserved[3];
+    mfxU8       *Data;      /*!< Pointer to the actual payload data buffer. */
+    mfxU32      NumBit;     /*!< Number of bits in the payload data */
+    mfxU16      Type;       /*!< MPEG-2 user data start code or H.264 SEI message type. */
+    mfxU16      BufSize;    /*!< Payload buffer size in bytes. */
+} mfxPayload;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Contains parameters for per-frame based encoding control.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< This extension buffer doesn't have assigned buffer ID. Ignored. */
+    mfxU32  reserved[4];
+    mfxU16  reserved1;
+    /*!
+       Type of NAL unit that contains encoding frame. All supported values are defined by MfxNalUnitType enumerator. Other values
+       defined in ITU-T H.265 specification are not supported.
+
+       The encoder uses this field only if application sets mfxExtCodingOption3::EnableNalUnitType option to ON during encoder initialization.
+
+       @note Only encoded order is supported. If application specifies this value in display order or uses value inappropriate for current frame or
+             invalid value, then the encoder silently ignores it.
+    */
+    mfxU16  MfxNalUnitType;
+    mfxU16  SkipFrame; /*!< Indicates that current frame should be skipped or the number of missed frames before the current frame. See mfxExtCodingOption2::SkipFrame for details. */
+
+    mfxU16  QP;        /*!< If nonzero, this value overwrites the global QP value for the current frame in the constant QP mode. */
+
+    /*!
+       Encoding frame type. See the FrameType enumerator for details. If the encoder works in the encoded order, the application must
+       specify the frame type. If the encoder works in the display order, only key frames are enforceable.
+    */
+    mfxU16  FrameType;
+    mfxU16  NumExtParam; /*!< Number of extra control buffers. */
+    mfxU16  NumPayload;  /*!< Number of payload records to insert into the bitstream. */
+    mfxU16  reserved2;
+
+    /*!
+       Pointer to an array of pointers to external buffers that provide additional information or control to the encoder for this
+       frame or field pair. A typical use is to pass the VPP auxiliary data generated by the video processing pipeline to the encoder.
+       See the ExtendedBufferID for the list of extended buffers.
+    */
+    mfxExtBuffer    **ExtParam;
+    /*!
+       Pointer to an array of pointers to user data (MPEG-2) or SEI messages (H.264) for insertion into the bitstream. For field pictures,
+       odd payloads are associated with the first field and even payloads are associated with the second field. See the mfxPayload structure
+       for payload definitions.
+    */
+    mfxPayload      **Payload;
+} mfxEncodeCtrl;
+MFX_PACK_END()
+
+/*! The ExtMemBufferType enumerator specifies the buffer type. It is a bit-ORed value of the following. */
+enum {
+    MFX_MEMTYPE_PERSISTENT_MEMORY   =0x0002 /*!< Memory page for persistent use. */
+};
+
+/* Frame Memory Types */
+#define MFX_MEMTYPE_BASE(x) (0x90ff & (x))
+
+/*!
+   The ExtMemFrameType enumerator specifies the memory type of frame. It is a bit-ORed value of the following.
+    \verbatim embed:rst
+    For information on working with video memory surfaces, see the :ref:`Working with Hardware Acceleration section<hw-acceleration>`.
+    \endverbatim
+*/
+enum {
+    MFX_MEMTYPE_DXVA2_DECODER_TARGET       =0x0010, /*!< Frames are in video memory and belong to video decoder render targets. */
+    MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET     =0x0020, /*!< Frames are in video memory and belong to video processor render targets. */
+    MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET   = MFX_MEMTYPE_DXVA2_DECODER_TARGET,  /*!< Frames are in video memory and belong to video decoder render targets. */
+    MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET = MFX_MEMTYPE_DXVA2_PROCESSOR_TARGET,/*!< Frames are in video memory and belong to video processor render targets. */
+    MFX_MEMTYPE_SYSTEM_MEMORY              =0x0040, /*!< The frames are in system memory. */
+    MFX_MEMTYPE_RESERVED1                  =0x0080, /*!<  */
+
+    MFX_MEMTYPE_FROM_ENCODE     = 0x0100, /*!< Allocation request comes from an ENCODE function */
+    MFX_MEMTYPE_FROM_DECODE     = 0x0200, /*!< Allocation request comes from a DECODE function */
+    MFX_MEMTYPE_FROM_VPPIN      = 0x0400, /*!< Allocation request comes from a VPP function for input frame allocation */
+    MFX_MEMTYPE_FROM_VPPOUT     = 0x0800, /*!< Allocation request comes from a VPP function for output frame allocation */
+    MFX_MEMTYPE_FROM_ENC        = 0x2000, /*!< Allocation request comes from an ENC function */
+    MFX_MEMTYPE_FROM_PAK        = 0x4000, /* Reserved */
+
+    MFX_MEMTYPE_INTERNAL_FRAME  = 0x0001, /*!< Allocation request for internal frames */
+    MFX_MEMTYPE_EXTERNAL_FRAME  = 0x0002, /*!< Allocation request for I/O frames */
+    MFX_MEMTYPE_EXPORT_FRAME    = 0x0008, /*!< Application requests frame handle export to some associated object. For Linux frame handle can be
+                                               considered to be exported to DRM Prime FD, DRM FLink or DRM FrameBuffer Handle. Specifics of export
+                                               types and export procedure depends on external frame allocator implementation */
+    MFX_MEMTYPE_SHARED_RESOURCE = MFX_MEMTYPE_EXPORT_FRAME, /*!< For DX11 allocation use shared resource bind flag. */
+    MFX_MEMTYPE_VIDEO_MEMORY_ENCODER_TARGET = 0x1000 /*!< Frames are in video memory and belong to video encoder render targets. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Describes multiple frame allocations when initializing encoders, decoders, and video preprocessors.
+   A range specifies the number of video frames. Applications are free to allocate additional frames. In all cases, the minimum number of
+   frames must be at least NumFrameMin or the called API function will return an error.
+*/
+typedef struct {
+    union {
+        mfxU32  AllocId;       /*!< Unique (within the session) ID of component requested the allocation. */
+        mfxU32  reserved[1];
+    };
+    mfxU32  reserved3[3];
+    mfxFrameInfo    Info;      /*!< Describes the properties of allocated frames. */
+    mfxU16  Type;              /*!< Allocated memory type. See the ExtMemFrameType enumerator for details. */
+    mfxU16  NumFrameMin;       /*!< Minimum number of allocated frames. */
+    mfxU16  NumFrameSuggested; /*!< Suggested number of allocated frames. */
+    mfxU16  reserved2;
+} mfxFrameAllocRequest;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Describes the response to multiple frame allocations. The calling API function returns the number of
+   video frames actually allocated and pointers to their memory IDs.
+*/
+typedef struct {
+    mfxU32      AllocId;        /*!< Unique (within the session) ID of component requested the allocation. */
+    mfxU32      reserved[3];
+    mfxMemId    *mids;          /*!< Pointer to the array of the returned memory IDs. The application allocates or frees this array. */
+    mfxU16      NumFrameActual; /*!< Number of frames actually allocated. */
+    mfxU16      reserved2;
+} mfxFrameAllocResponse;
+MFX_PACK_END()
+
+/*! The FrameType enumerator itemizes frame types. Use bit-ORed values to specify all that apply. */
+enum {
+    MFX_FRAMETYPE_UNKNOWN       =0x0000, /*!< Frame type is unspecified. */
+
+    MFX_FRAMETYPE_I             =0x0001, /*!< This frame or the first field is encoded as an I-frame/field. */
+    MFX_FRAMETYPE_P             =0x0002, /*!< This frame or the first field is encoded as an P-frame/field. */
+    MFX_FRAMETYPE_B             =0x0004, /*!< This frame or the first field is encoded as an B-frame/field. */
+    MFX_FRAMETYPE_S             =0x0008, /*!< This frame or the first field is either an SI- or SP-frame/field. */
+
+    MFX_FRAMETYPE_REF           =0x0040, /*!< This frame or the first field is encoded as a reference. */
+    MFX_FRAMETYPE_IDR           =0x0080, /*!< This frame or the first field is encoded as an IDR. */
+
+    MFX_FRAMETYPE_xI            =0x0100, /*!< The second field is encoded as an I-field. */
+    MFX_FRAMETYPE_xP            =0x0200, /*!< The second field is encoded as an P-field. */
+    MFX_FRAMETYPE_xB            =0x0400, /*!< The second field is encoded as an S-field. */
+    MFX_FRAMETYPE_xS            =0x0800, /*!< The second field is an SI- or SP-field. */
+
+    MFX_FRAMETYPE_xREF          =0x4000, /*!< The second field is encoded as a reference. */
+    MFX_FRAMETYPE_xIDR          =0x8000  /*!< The second field is encoded as an IDR. */
+};
+
+/*!
+   The MfxNalUnitType enumerator specifies NAL unit types supported by the HEVC encoder.
+*/
+enum {
+    MFX_HEVC_NALU_TYPE_UNKNOWN    =      0, /*!< The encoder will decide what NAL unit type to use. */
+    MFX_HEVC_NALU_TYPE_TRAIL_N    = ( 0+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_TRAIL_R    = ( 1+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_RADL_N     = ( 6+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_RADL_R     = ( 7+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_RASL_N     = ( 8+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_RASL_R     = ( 9+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_IDR_W_RADL = (19+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_IDR_N_LP   = (20+1), /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+    MFX_HEVC_NALU_TYPE_CRA_NUT    = (21+1)  /*!< See Table 7-1 of the ITU-T H.265 specification for the definition of these type. */
+};
+
+/*! The mfxSkipMode enumerator describes the decoder skip-mode options. */
+typedef enum {
+    MFX_SKIPMODE_NOSKIP=0, /*! Do not skip any frames. */
+    MFX_SKIPMODE_MORE=1,   /*! Skip more frames. */
+    MFX_SKIPMODE_LESS=2    /*! Skip less frames. */
+} mfxSkipMode;
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Attach this structure as part of the extended buffers to configure the encoder during MFXVideoENCODE_Init. The sequence or picture
+   parameters specified by this structure overwrite any parameters specified by the structure or any other attached extended buffers attached.
+
+   For H.264, SPSBuffer and PPSBuffer must point to valid bitstreams that contain the sequence parameter set and picture parameter set,
+   respectively.
+
+   For MPEG-2, SPSBuffer must point to valid bitstreams that contain the sequence header followed by any sequence header extension. The PPSBuffer pointer is ignored.
+
+   The encoder imports parameters from these buffers. If the encoder does not support the specified parameters,
+   the encoder does not initialize and returns the status code MFX_ERR_INCOMPATIBLE_VIDEO_PARAM.
+
+   Check with the MFXVideoENCODE_Query function for the support of this multiple segment encoding feature. If this feature is not supported,
+   the query returns MFX_ERR_UNSUPPORTED.
+*/
+typedef struct {
+    mfxExtBuffer    Header;     /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_CODING_OPTION_SPSPPS. */
+    mfxU8           *SPSBuffer; /*!< Pointer to a valid bitstream that contains the SPS (sequence parameter set for H.264 or sequence header
+                                     followed by any sequence header extension for MPEG-2) buffer. Can be NULL to skip specifying the SPS. */
+    mfxU8           *PPSBuffer; /*!< Pointer to a valid bitstream that contains the PPS (picture parameter set for H.264 or picture header
+                                     followed by any picture header extension for MPEG-2) buffer. Can be NULL to skip specifying the PPS. */
+    mfxU16          SPSBufSize; /*!< Size of the SPS in bytes. */
+    mfxU16          PPSBufSize; /*!< Size of the PPS in bytes. */
+    mfxU16          SPSId;      /*!< SPS identifier. The value is reserved and must be zero. */
+    mfxU16          PPSId;      /*!< PPS identifier. The value is reserved and must be zero. */
+} mfxExtCodingOptionSPSPPS;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   Attach this structure as part of the extended buffers to configure the encoder during MFXVideoENCODE_Init. The sequence or picture
+   parameters specified by this structure overwrite any parameters specified by the structure or any other attached extended buffers attached.
+
+   If the encoder does not support the specified parameters, the encoder does not initialize and returns the status code
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM.
+
+   Check with the MFXVideoENCODE_Query function for the support of this multiple segment encoding feature. If this feature is not supported,
+   the query returns MFX_ERR_UNSUPPORTED.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_CODING_OPTION_VPS. */
+
+    union {
+        mfxU8       *VPSBuffer; /*!< Pointer to a valid bitstream that contains the VPS (video parameter set for HEVC) buffer. */
+        mfxU64      reserved1;
+    };
+    mfxU16          VPSBufSize; /*!< Size of the VPS in bytes. */
+    mfxU16          VPSId;      /*!< VPS identifier; the value is reserved and must be zero. */
+
+    mfxU16          reserved[6];
+} mfxExtCodingOptionVPS;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Defines the video signal information.
+
+   For H.264, see Annex E of the ISO/IEC 14496-10 specification for the definition of these parameters.
+
+   For MPEG-2, see section 6.3.6 of the ITU* H.262 specification for the definition of these parameters. The field VideoFullRange is ignored.
+
+   For VC-1, see section 6.1.14.5 of the SMPTE* 421M specification. The fields VideoFormat and VideoFullRange are ignored.
+
+   @note If ColourDescriptionPresent is zero, the color description information (including ColourPrimaries, TransferCharacteristics,
+         and MatrixCoefficients) does not present in the bitstream.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VIDEO_SIGNAL_INFO. */
+    mfxU16          VideoFormat;
+    mfxU16          VideoFullRange;
+    mfxU16          ColourDescriptionPresent;
+    mfxU16          ColourPrimaries;
+    mfxU16          TransferCharacteristics;
+    mfxU16          MatrixCoefficients;
+} mfxExtVideoSignalInfo;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Tells the VPP to include certain filters in the pipeline.
+
+   Each filter may be included in the pipeline in one of two different ways:
+
+   @li Adding a filter ID to this structure. In this method,
+   the default filter parameters are used.
+
+   @li Attaching a filter configuration structure directly to the mfxVideoParam structure.
+   In this method, adding filter ID to the mfxExtVPPDoUse structure is optional.
+
+   See Table “Configurable VPP filters” for complete list of
+   configurable filters, their IDs, and configuration structures.
+
+   The user can attach this structure to the mfxVideoParam structure when initializing video processing.
+
+   @note MFX_EXTBUFF_VPP_COMPOSITE cannot be enabled using mfxExtVPPDoUse because default parameters are undefined for this filter.
+         The application must attach the appropriate filter configuration structure directly to the mfxVideoParam structure to enable it.
+*/
+typedef struct {
+    mfxExtBuffer    Header;   /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_DOUSE. */
+    mfxU32          NumAlg;   /*!< Number of filters (algorithms) to use */
+    mfxU32          *AlgList; /*!< Pointer to a list of filters (algorithms) to use */
+} mfxExtVPPDoUse;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures reference frame options for the H.264 encoder.
+    \verbatim embed:rst
+    See the :ref:`Reference List Selection <sec_reference_list_selection>` and :ref:`Long Term Reference Frame <sec_long_term_reference_frame>` sections for more details.
+    \endverbatim
+
+
+   @note Not all implementations of the encoder support LongTermIdx and ApplyLongTermIdx fields in this structure. The application must use
+         query mode 1 to determine if such functionality is supported. To do this, the application must attach this extended buffer to the
+         mfxVideoParam structure and call the MFXVideoENCODE_Query function. If the function returns MFX_ERR_NONE and these fields were set to one,
+         then the functionality is supported. If the function fails or sets fields to zero, then the functionality is not supported.
+
+*/
+typedef struct {
+    mfxExtBuffer    Header;            /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AVC_REFLIST_CTRL. */
+    mfxU16          NumRefIdxL0Active; /*!< Specify the number of reference frames in the active reference list L0. This number should be less or equal to the NumRefFrame parameter from encoding initialization. */
+    mfxU16          NumRefIdxL1Active; /*!< Specify the number of reference frames in the active reference list L1. This number should be less or equal to the NumRefFrame parameter from encoding initialization. */
+
+    struct {
+        /*! @{
+        @name Reference Lists
+        The following structure members are used by the reference lists contained in the parent structure. */
+        mfxU32      FrameOrder;  /*!< Together FrameOrder and PicStruct fields are used to identify reference picture. Use FrameOrder = MFX_FRAMEORDER_UNKNOWN to mark unused entry. */
+        mfxU16      PicStruct;   /*!< Together FrameOrder and PicStruct fields are used to identify reference picture. Use FrameOrder = MFX_FRAMEORDER_UNKNOWN to mark unused entry. */
+        mfxU16      ViewId;      /*!< Reserved and must be zero. */
+        mfxU16      LongTermIdx; /*!< Index that should be used by the encoder to mark long-term reference frame. */
+        mfxU16      reserved[3]; /*!< Reserved */
+        /*! @} */
+    } PreferredRefList[32], /*!< Reference list that specifies the list of frames that should be used to predict the current frame. */
+    RejectedRefList[16], /*!< Reference list that specifies the list of frames that should not be used for prediction. */
+    LongTermRefList[16]; /*!< Reference list that specifies the list of frames that should be marked as long-term reference frame. */
+
+    mfxU16      ApplyLongTermIdx;/*!< If it is equal to zero, the encoder assigns long-term index according to internal algorithm.
+                                      If it is equal to one, the encoder uses LongTermIdx value as long-term index. */
+    mfxU16      reserved[15];
+} mfxExtAVCRefListCtrl;
+MFX_PACK_END()
+
+/*! The FrcAlgm enumerator itemizes frame rate conversion algorithms. See description of mfxExtVPPFrameRateConversion structure for more details. */
+enum {
+    MFX_FRCALGM_PRESERVE_TIMESTAMP    = 0x0001, /*!< Frame dropping/repetition based frame rate conversion algorithm with preserved original
+                                                     time stamps. Any inserted frames will carry MFX_TIMESTAMP_UNKNOWN. */
+    MFX_FRCALGM_DISTRIBUTED_TIMESTAMP = 0x0002, /*!< Frame dropping/repetition based frame rate conversion algorithm with distributed time stamps.
+                                                     The algorithm distributes output time stamps evenly according to the output frame rate. */
+    MFX_FRCALGM_FRAME_INTERPOLATION   = 0x0004  /*!< Frame rate conversion algorithm based on frame interpolation. This flag may be combined with
+                                                     MFX_FRCALGM_PRESERVE_TIMESTAMP or MFX_FRCALGM_DISTRIBUTED_TIMESTAMP flags. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the VPP frame rate conversion filter. The user can attach this structure to the
+   mfxVideoParam structure when initializing, resetting, or querying capability of video processing.
+
+   On some platforms the advanced frame rate conversion algorithm (the algorithm based on frame interpolation) is not supported. To query its support,
+   the application should add the MFX_FRCALGM_FRAME_INTERPOLATION flag to the Algorithm value in the mfxExtVPPFrameRateConversion structure, attach it to the
+   structure, and call the MFXVideoVPP_Query function. If the filter is supported, the function returns a MFX_ERR_NONE status and copies the content of the
+   input structure to the output structure. If an advanced filter is not supported, then a simple filter will be used and the function returns
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM, copies content of the input structure to the output structure, and corrects the Algorithm value.
+
+   If advanced FRC algorithm is not supported, both MFXVideoVPP_Init and MFXVideoVPP_Reset functions return the MFX_WRN_INCOMPATIBLE_VIDEO_PARAM status.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION. */
+    mfxU16      Algorithm;  /*!< See the FrcAlgm enumerator for a list of frame rate conversion algorithms. */
+    mfxU16      reserved;
+    mfxU32      reserved2[15];
+} mfxExtVPPFrameRateConversion;
+MFX_PACK_END()
+
+/*! The ImageStabMode enumerator itemizes image stabilization modes. See description of mfxExtVPPImageStab structure for more details. */
+enum {
+    MFX_IMAGESTAB_MODE_UPSCALE = 0x0001, /*!< Upscale mode. */
+    MFX_IMAGESTAB_MODE_BOXING  = 0x0002  /*!< Boxing mode. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   A hint structure that configures the VPP image stabilization filter.
+
+   On some platforms this filter is not supported. To query its support, the application should use the same approach that it uses
+   to configure VPP filters: adding the filter ID to the mfxExtVPPDoUse structure or by attaching the mfxExtVPPImageStab structure
+   directly to the mfxVideoParam structure and calling the MFXVideoVPP_Query function.
+
+   If this filter is supported, the function returns a MFX_ERR_NONE
+   status and copies the content of the input structure to the output structure. If the filter is not supported, the function returns MFX_WRN_FILTER_SKIPPED, removes the
+   filter from the mfxExtVPPDoUse structure, and zeroes the mfxExtVPPImageStab structure.
+
+   If the image stabilization filter is not supported, both MFXVideoVPP_Init and MFXVideoVPP_Reset functions return a MFX_WRN_FILTER_SKIPPED status.
+
+   The application can retrieve the list of active filters by attaching the mfxExtVPPDoUse structure to the mfxVideoParam structure and calling the
+   MFXVideoVPP_GetVideoParam function. The application must allocate enough memory for the filter list.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_IMAGE_STABILIZATION. */
+    mfxU16  Mode;           /*!< Image stabilization mode. See ImageStabMode enumerator for values. */
+    mfxU16  reserved[11];
+} mfxExtVPPImageStab;
+MFX_PACK_END()
+
+
+/*! The InsertHDRPayload enumerator itemizes HDR payloads insertion rules. */
+enum {
+    MFX_PAYLOAD_OFF = 0, /*!< Do not insert payload. */
+    MFX_PAYLOAD_IDR = 1  /*!< Insert payload on IDR frames. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the HDR SEI message.
+
+   If the application attaches this structure to the mfxEncodeCtrl structure
+   at runtime, the encoder inserts the HDR SEI message for the current frame and ignores InsertPayloadToggle.
+
+   If the application attaches this
+   structure to the mfxVideoParam structure during initialization or reset, the encoder inserts the HDR SEI message based on InsertPayloadToggle.
+
+   If the application attaches this structure for video processing, InsertPayloadToggle will be ignored.
+
+   Field semantics are defined in ITU-T* H.265 Annex D.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME. */
+    mfxU16      reserved[15];
+
+    mfxU16 InsertPayloadToggle;  /*!< InsertHDRPayload enumerator value. */
+    mfxU16 DisplayPrimariesX[3]; /*!< Color primaries for a video source in increments of 0.00002. Consist of RGB x coordinates and
+                                       define how to convert colors from RGB color space to CIE XYZ color space. Fields range is
+                                       0 to 50000. */
+    mfxU16 DisplayPrimariesY[3]; /*!< Color primaries for a video source in increments of 0.00002. Consists of RGB y coordinates and
+                                       defines how to convert colors from RGB color space to CIE XYZ color space. Field range is
+                                       0 to 50000. */
+    mfxU16 WhitePointX;          /*!< White point X coordinate. */
+    mfxU16 WhitePointY;          /*!< White point Y coordinate. */
+    mfxU32 MaxDisplayMasteringLuminance; /*!< Specify maximum luminance of the display on which the content was authored in units of 0.00001
+                                              candelas per square meter. Field range is 1 to 65535. */
+    mfxU32 MinDisplayMasteringLuminance; /*!< Specify minimum luminance of the display on which the content was authored in units of 0.00001
+                                              candelas per square meter. Field range is 1 to 65535. */
+} mfxExtMasteringDisplayColourVolume;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the HDR SEI message.
+
+   If the application attaches this structure to the mfxEncodeCtrl
+   structure at runtime, the encoder inserts the HDR SEI message for the current frame and ignores InsertPayloadToggle.
+
+   If the application
+   attaches this structure to the mfxVideoParam structure during initialization or reset, the encoder inserts the HDR SEI message based on
+   InsertPayloadToggle.
+
+   If the application attaches this structure for video processing, InsertPayloadToggle will be ignored.
+
+   Field semantics are defined in ITU-T* H.265 Annex D.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to EXTBUFF_CONTENT_LIGHT_LEVEL_INFO. */
+    mfxU16      reserved[9];
+
+    mfxU16 InsertPayloadToggle;     /*!< InsertHDRPayload enumerator value. */
+    mfxU16 MaxContentLightLevel;    /*!< Maximum luminance level of the content. Field range is 1 to 65535. */
+    mfxU16 MaxPicAverageLightLevel; /*!< Maximum average per-frame luminance level of the content. Field range is 1 to 65535. */
+} mfxExtContentLightLevelInfo;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the H.264 picture timing SEI message. The encoder ignores it if HRD information in
+   the stream is absent and the PicTimingSEI option in the mfxExtCodingOption structure is turned off. See mfxExtCodingOption for details.
+
+   If the application attaches this structure to the mfxVideoParam structure during initialization, the encoder inserts the picture timing
+   SEI message based on provided template in every access unit of coded bitstream.
+
+   If application attaches this structure to the mfxEncodeCtrl structure at runtime, the encoder inserts the picture timing SEI message
+   based on provided template in access unit that represents current frame.
+
+   These parameters define the picture timing information. An invalid value of 0xFFFF indicates that application does not set the value and
+   encoder must calculate it.
+
+   See Annex D of the ISO*\/IEC* 14496-10 specification for the definition of these parameters.
+*/
+typedef struct {
+  mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_PICTURE_TIMING_SEI. */
+  mfxU32      reserved[14];
+
+  struct {
+      mfxU16    ClockTimestampFlag;
+      mfxU16    CtType;
+      mfxU16    NuitFieldBasedFlag;
+      mfxU16    CountingType;
+      mfxU16    FullTimestampFlag;
+      mfxU16    DiscontinuityFlag;
+      mfxU16    CntDroppedFlag;
+      mfxU16    NFrames;
+      mfxU16    SecondsFlag;
+      mfxU16    MinutesFlag;
+      mfxU16    HoursFlag;
+      mfxU16    SecondsValue;
+      mfxU16    MinutesValue;
+      mfxU16    HoursValue;
+      mfxU32    TimeOffset;
+  } TimeStamp[3];
+} mfxExtPictureTimingSEI;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the H.264 temporal layers hierarchy.
+
+   If the application attaches it to the mfxVideoParam
+   structure during initialization, the encoder generates the temporal layers and inserts the prefix NAL unit before each slice to
+   indicate the temporal and priority IDs of the layer.
+
+   This structure can be used with the display-order encoding mode only.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AVC_TEMPORAL_LAYERS. */
+    mfxU32          reserved1[4];
+    mfxU16          reserved2;
+    mfxU16          BaseLayerPID; /*!< The priority ID of the base layer. The encoder increases the ID for each temporal layer and writes to the prefix NAL unit. */
+
+    struct {
+        mfxU16 Scale;       /*!< The ratio between the frame rates of the current temporal layer and the base layer. */
+        mfxU16 reserved[3];
+    }Layer[8];
+} mfxExtAvcTemporalLayers;  /*!< The array of temporal layers; Use Scale=0 to specify absent layers. */
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used to retrieve encoder capability. See the description of mode 4 of the MFXVideoENCODE_Query function
+   for details on how to use this structure.
+
+   @note Not all implementations of the encoder support this extended buffer. The application must use query mode 1 to determine
+         if the functionality is supported. To do this, the application must attach this extended buffer to the mfxVideoParam structure and
+         call the MFXVideoENCODE_Query function. If the function returns MFX_ERR_NONE then the  functionality is supported.
+*/
+typedef struct {
+    mfxExtBuffer Header;  /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ENCODER_CAPABILITY. */
+
+    mfxU32      MBPerSec; /*!< Specify the maximum processing rate in macro blocks per second. */
+    mfxU16      reserved[58];
+} mfxExtEncoderCapability;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used to control the encoder behavior during reset. By using this structure, the application
+   instructs the encoder to start a new coded sequence after reset or to continue encoding of the current sequence.
+
+   This structure is also used in mode 3 of the MFXVideoENCODE_Query function to check for reset outcome before actual reset. The application
+   should set StartNewSequence to the required behavior and call the query function. If the query fails (see status codes below), then reset is not
+   possible in current encoder state. If the application sets StartNewSequence to MFX_CODINGOPTION_UNKNOWN, then the query function replaces the coding option with the
+   actual reset type: MFX_CODINGOPTION_ON if the encoder will begin a new sequence after reset or MFX_CODINGOPTION_OFF if the encoder will continue the current sequence.
+
+   Using this structure may cause one of the following status codes from the MFXVideoENCODE_Reset and MFXVideoENCODE_Queryfunctions:
+
+   @li MFX_ERR_INVALID_VIDEO_PARAM If a reset is not possible. For example, the application sets StartNewSequence to off and requests resolution change.
+
+   @li MFX_ERR_INCOMPATIBLE_VIDEO_PARAM If the application requests change that leads to memory allocation. For example, the application sets StartNewSequence to on and
+                                        requests resolution change to greater than the initialization value.
+
+   @li MFX_ERR_NONE If reset is possible.
+
+   The following limited list of parameters can be changed without starting a new coded sequence:
+
+   @li The bitrate parameters, TargetKbps and MaxKbps, in the mfxInfoMFX structure.
+
+   @li The number of slices, NumSlice, in the mfxInfoMFX structure. Number of slices should be equal to or less than the number of slices during initialization.
+
+   @li The number of temporal layers in the mfxExtAvcTemporalLayers structure. Reset should be called immediately before encoding of frame from base layer and
+     number of reference frames should be large enough for the new temporal layers structure.
+
+   @li The quantization parameters, QPI, QPP and QPB, in the mfxInfoMFX structure.
+
+   The application should retrieve all cached frames before calling reset. When the Query API function
+   checks for reset outcome, it expects that this requirement be satisfied. If it is not true and there are some cached frames inside the
+ encoder, then the query result may differ from the reset result, because the encoder may insert an IDR frame to produce valid coded sequence.
+   \verbatim embed:rst
+   See the :ref:`Configuration Change <config-change>` section for more information.
+   \endverbatim
+
+   @note Not all implementations of the encoder support this extended buffer. The application must use query mode 1 to determine if the
+         functionality is supported. To do this, the application must attach this extended buffer to the mfxVideoParam structure and call the
+         MFXVideoENCODE_Query function. If the function returns MFX_ERR_NONE, then the functionality is supported.
+
+   \verbatim embed:rst
+   See the :ref:`Streaming and Video Conferencing Features <stream_vid_conf_features>` section for more information.
+   \endverbatim
+
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ENCODER_RESET_OPTION. */
+
+    /*!
+       Instructs encoder to start new sequence after reset. Use one of the CodingOptionValue options:
+
+       @li MFX_CODINGOPTION_ON The encoder completely reset internal state and begins new coded sequence after reset, including
+                             insertion of IDR frame, sequence, and picture headers.
+
+       @li MFX_CODINGOPTION_OFF The encoder continues encoding of current coded sequence after reset, without insertion of IDR frame.
+
+       @li MFX_CODINGOPTION_UNKNOWN Depending on the current encoder state and changes in configuration parameters, the encoder may or may not
+                                  start new coded sequence. This value is also used to query reset outcome.
+    */
+    mfxU16      StartNewSequence;
+    mfxU16      reserved[11];
+} mfxExtEncoderResetOption;
+MFX_PACK_END()
+
+/*! The LongTermIdx specifies long term index of picture control. */
+enum {
+    MFX_LONGTERM_IDX_NO_IDX = 0xFFFF /*!< Long term index of picture is undefined. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the encoder to report additional information about the encoded picture. The application can attach
+   this buffer to the mfxBitstream structure before calling MFXVideoENCODE_EncodeFrameAsync function. For interlaced content the encoder
+   requires two such structures. They correspond to fields in encoded order.
+
+   @note Not all implementations of the encoder support this extended buffer. The application must use query mode 1 to determine if
+         the functionality is supported. To do this, the application must attach this extended buffer to the mfxVideoParam structure and
+         call the MFXVideoENCODE_Query function. If the function returns MFX_ERR_NONE then the functionality is supported.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ENCODED_FRAME_INFO. */
+
+    mfxU32          FrameOrder;        /*!< Frame order of encoded picture. */
+    mfxU16          PicStruct;         /*!< Picture structure of encoded picture. */
+    mfxU16          LongTermIdx;       /*!< Long term index of encoded picture if applicable. */
+    mfxU32          MAD;               /*!< Mean Absolute Difference between original pixels of the frame and motion compensated (for inter macroblocks) or
+                                            spatially predicted (for intra macroblocks) pixels. Only luma component, Y plane, is used in calculation. */
+    mfxU16          BRCPanicMode;      /*!< Bitrate control was not able to allocate enough bits for this frame. Frame quality may be unacceptably low. */
+    mfxU16          QP;                /*!< Luma QP. */
+    mfxU32          SecondFieldOffset; /*!< Offset to second field. Second field starts at mfxBitstream::Data + mfxBitstream::DataOffset + mfxExtAVCEncodedFrameInfo::SecondFieldOffset. */
+    mfxU16          reserved[2];
+
+    struct {
+        /*! @{
+        @name Reference Lists
+        The following structure members are used by the reference lists contained in the parent structure. */
+        mfxU32      FrameOrder;        /*!< Frame order of reference picture. */
+        mfxU16      PicStruct;         /*!< Picture structure of reference picture. */
+        mfxU16      LongTermIdx;       /*!< Long term index of reference picture if applicable. */
+        mfxU16      reserved[4];
+        /*! @} */
+    } UsedRefListL0[32], /*!< Reference list that has been used to encode picture. */
+    UsedRefListL1[32]; /*!< Reference list that has been used to encode picture. */
+} mfxExtAVCEncodedFrameInfo;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used to specify input stream details for composition of several input surfaces in the one output.
+*/
+typedef struct mfxVPPCompInputStream {
+    mfxU32  DstX; /*!< X coordinate of location of input stream in output surface. */
+    mfxU32  DstY; /*!< Y coordinate of location of input stream in output surface. */
+    mfxU32  DstW; /*!< Width of of location of input stream in output surface.*/
+    mfxU32  DstH; /*!< Height of of location of input stream in output surface.*/
+
+    mfxU16  LumaKeyEnable; /*!< Non-zero value enables luma keying for the input stream. Luma keying is used to mark some of the areas
+                                of the frame with specified luma values as transparent. It may, for example, be used for closed captioning. */
+    mfxU16  LumaKeyMin;    /*!< Minimum value of luma key, inclusive. Pixels whose luma values fit in this range are rendered transparent. */
+    mfxU16  LumaKeyMax;    /*!< Maximum value of luma key, inclusive. Pixels whose luma values fit in this range are rendered transparent. */
+
+    mfxU16  GlobalAlphaEnable; /*!< Non-zero value enables global alpha blending for this input stream. */
+    mfxU16  GlobalAlpha;       /*!< Alpha value for this stream. Should be in the range of 0 to 255, where 0 is transparent and 255 is opaque. */
+    mfxU16  PixelAlphaEnable;  /*!< Non-zero value enables per pixel alpha blending for this input stream. The stream should have RGB color format. */
+
+    mfxU16  TileId;        /*!< Specify the tile this video stream is assigned to. Should be in the range of 0 to NumTiles. Valid only if NumTiles > 0. */
+
+    mfxU16  reserved2[17];
+} mfxVPPCompInputStream;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Used to control composition of several input surfaces in one output. In this mode, the VPP skips
+   any other filters. The VPP returns an error if any mandatory filter is specified and returns the filter skipped warning if an optional filter is specified. The only
+   supported filters are deinterlacing and interlaced scaling. The only supported combinations of input and output color formats are:
+
+   - RGB to RGB,
+
+   - NV12 to NV12,
+
+   - RGB and NV12 to NV12, for per the pixel alpha blending use case.
+
+   The VPP returns MFX_ERR_MORE_DATA for additional input until an output is ready. When the output is ready, the VPP returns MFX_ERR_NONE.
+   The application must process the output frame after synchronization.
+
+   The composition process is controlled by:
+
+   - mfxFrameInfo::CropXYWH in the input surface defines the location of the picture in the input frame.
+
+   - InputStream[i].DstXYWH defines the location of the cropped input picture in the output frame.
+
+   - mfxFrameInfo::CropXYWH in the output surface defines the actual part of the output frame. All pixels in the output frame outside this region will be filled by the specified color.
+
+   If the application uses the composition process on video streams with different frame sizes, the application should provide maximum frame size in the
+   mfxVideoParam structure during the initialization, reset, or query operations.
+
+   If the application uses the composition process, the MFXVideoVPP_QueryIOSurf function returns the cumulative number of input surfaces, that is, the number
+   required to process all input video streams. The function sets the frame size in the mfxFrameAllocRequest equal to the size provided by the
+   application in the mfxVideoParam structure.
+
+   The composition process supports all types of surfaces.
+
+   All input surfaces should have the same type and color format, except for the per pixel alpha blending case, where it is allowable to mix NV12 and RGB
+   surfaces.
+
+   There are three different blending use cases:
+
+   - <b>Luma keying.</b> All input surfaces should have the NV12 color format specified during VPP initialization. Part of each surface, including the
+     first one, may be rendered transparent by using LumaKeyEnable, LumaKeyMin, and LumaKeyMax values.
+
+   - <b>Global alpha blending.</b> All input surfaces should have the same color format, NV12 or RGB, specified during VPP initialization. Each input surface, including the first one, can be blended with underlying surfaces by using GlobalAlphaEnable and
+     GlobalAlpha values.
+
+   - <b>Per-pixel alpha blending.</b> It is allowed to mix NV12 and RGB input surfaces. Each RGB input surface, including the first one,
+     can be blended with underlying surfaces by using PixelAlphaEnable value.
+
+   It is not allowed to mix different blending use cases in the same function call.
+
+   In the special case where the destination region of the output surface defined by output crops is fully covered with destination sub-regions of the
+   surfaces, the fast compositing mode can be enabled. The main use case for this mode is a video-wall scenario with a fixed destination surface
+   partition into sub-regions of potentially different size.
+
+   In order to trigger this mode, the application must cluster input surfaces into tiles, defining at least one tile by setting the NumTiles
+   field to be greater than 0, and assigning surfaces to the corresponding tiles by setting the TileId field to the value within the 0 to NumTiles range per
+   input surface. Tiles should also satisfy the following additional constraints:
+
+   - Each tile should not have more than 8 surfaces assigned to it.
+
+   - Tile bounding boxes, as defined by the enclosing rectangles of a union of a surfaces assigned to this tile, should not intersect.
+
+   Background color may be changed dynamically through Reset. There is no default value. YUV black is (0;128;128) or (16;128;128) depending
+   on the sample range. The library uses a YUV or RGB triple depending on output color format.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_COMPOSITE. */
+
+    /* background color*/
+    union {
+        mfxU16   Y; /*!< Y value of the background color. */
+        mfxU16   R; /*!< R value of the background color. */
+    };
+    union {
+        mfxU16   U; /*!< U value of the background color. */
+        mfxU16   G; /*!< G value of the background color. */
+    };
+    union {
+        mfxU16   V; /*!< V value of the background color. */
+        mfxU16   B; /*!< B value of the background color. */
+    };
+    mfxU16       NumTiles;              /*!< Number of input surface clusters grouped together to enable fast compositing. May be changed dynamically
+                                             at runtime through Reset. */
+    mfxU16       reserved1[23];
+
+    mfxU16       NumInputStream;        /*!< Number of input surfaces to compose one output. May be changed dynamically at runtime through Reset. Number of surfaces
+                                             can be decreased or increased, but should not exceed the number specified during initialization. Query mode 2 should be used
+                                             to find the maximum supported number. */
+    mfxVPPCompInputStream *InputStream; /*!< An array of mfxVPPCompInputStream structures that describe composition of input video streams. It should consist of exactly NumInputStream elements. */
+} mfxExtVPPComposite;
+MFX_PACK_END()
+
+/*! The TransferMatrix enumerator itemizes color transfer matrices. */
+enum {
+    MFX_TRANSFERMATRIX_UNKNOWN = 0, /*!< Transfer matrix is not specified */
+    MFX_TRANSFERMATRIX_BT709   = 1, /*!< Transfer matrix from ITU-R BT.709 standard. */
+    MFX_TRANSFERMATRIX_BT601   = 2  /*!< Transfer matrix from ITU-R BT.601 standard. */
+};
+
+/* The NominalRange enumerator itemizes pixel's value nominal range. */
+enum {
+    MFX_NOMINALRANGE_UNKNOWN   = 0, /*!< Range is not defined. */
+    MFX_NOMINALRANGE_0_255     = 1, /*!< Range is from  0 to 255. */
+    MFX_NOMINALRANGE_16_235    = 2  /*!< Range is from 16 to 235. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used to control transfer matrix and nominal range of YUV frames. The application
+   should provide this during initialization. Supported for multiple conversions, for example YUV to YUV, YUV to RGB, and RGB to YUV.
+
+   @note This structure is used by VPP only and is not compatible with mfxExtVideoSignalInfo.
+*/
+typedef struct {
+    mfxExtBuffer    Header;   /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_VIDEO_SIGNAL_INFO. */
+    mfxU16          reserved1[4];
+
+    union {
+        struct { // Init
+            struct  {
+                mfxU16  TransferMatrix; /*!< Transfer matrix. */
+                mfxU16  NominalRange;   /*!< Nominal range. */
+                mfxU16  reserved2[6];
+            } In, Out;
+        };
+        struct { // Runtime<
+            mfxU16  TransferMatrix; /*!< Transfer matrix. */
+            mfxU16  NominalRange;   /*!< Nominal range. */
+            mfxU16  reserved3[14];
+        };
+    };
+} mfxExtVPPVideoSignalInfo;
+MFX_PACK_END()
+
+/*! The ROImode enumerator itemizes QP adjustment mode for ROIs. */
+enum {
+    MFX_ROI_MODE_PRIORITY =  0, /*!< Priority mode. */
+    MFX_ROI_MODE_QP_DELTA =  1,  /*!< QP mode */
+    MFX_ROI_MODE_QP_VALUE =  2 /*!< Absolute QP */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the application to specify different Region Of Interests during encoding. It may be used at
+   initialization or at runtime.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ENCODER_ROI. */
+
+    mfxU16  NumROI;  /*!< Number of ROI descriptions in array. The Query API function mode 2 returns maximum supported value (set it to 256 and
+                         query will update it to maximum supported value). */
+    mfxU16  ROIMode; /*!< QP adjustment mode for ROIs. Defines if Priority or DeltaQP is used during encoding. */
+    mfxU16  reserved1[10];
+
+    struct  {
+        /*! @{
+        @name ROI location rectangle
+        The ROI rectangle definition uses end-point exclusive notation. In other words, the pixel with (Right, Bottom)
+        coordinates lies immediately outside of the ROI. Left, Top, Right, Bottom should be aligned by codec-specific block boundaries
+        (should be dividable by 16 for AVC, or by 32 for HEVC). Every ROI with unaligned coordinates will be expanded by the library to minimal-area
+        block-aligned ROI, enclosing the original one. For example (5, 5, 15, 31) ROI will be expanded to (0, 0, 16, 32) for AVC encoder,
+        or to (0, 0, 32, 32) for HEVC.
+         */
+        mfxU32  Left;   /*!< Left ROI's coordinate. */
+        mfxU32  Top;    /*!< Top ROI's coordinate. */
+        mfxU32  Right;  /*!< Right ROI's coordinate. */
+        mfxU32  Bottom; /*!< Bottom ROI's coordinate. */
+        union {
+            /*! Priority of ROI. Used if ROIMode = MFX_ROI_MODE_PRIORITY.This is an absolute value in the range of -3 to 3,
+                                  which will be added to the MB QP. Priority is deprecated mode and is used only for backward compatibility.
+                                  Bigger value produces better quality. */
+            mfxI16  Priority;
+            /*! Delta QP of ROI. Used if ROIMode = MFX_ROI_MODE_QP_DELTA. This is an absolute value in the range of -51 to 51,
+                                  which will be added to the MB QP. Lesser value produces better quality. */
+            mfxI16  DeltaQP;
+        };
+        mfxU16  reserved2[7];
+        /*! @} */
+    } ROI[256]; /*!< Array of ROIs. Different ROI may overlap each other. If macroblock belongs to several ROI,
+                     Priority from ROI with lowest index is used. */
+} mfxExtEncoderROI;
+MFX_PACK_END()
+
+/*! The DeinterlacingMode enumerator itemizes VPP deinterlacing modes. */
+enum {
+    MFX_DEINTERLACING_BOB                    =  1, /*!< BOB deinterlacing mode. */
+    MFX_DEINTERLACING_ADVANCED               =  2, /*!< Advanced deinterlacing mode. */
+    MFX_DEINTERLACING_AUTO_DOUBLE            =  3, /*!< Auto mode with deinterlacing double frame rate output. */
+    MFX_DEINTERLACING_AUTO_SINGLE            =  4, /*!< Auto mode with deinterlacing single frame rate output. */
+    MFX_DEINTERLACING_FULL_FR_OUT            =  5, /*!< Deinterlace only mode with full frame rate output. */
+    MFX_DEINTERLACING_HALF_FR_OUT            =  6, /*!< Deinterlace only Mode with half frame rate output. */
+    MFX_DEINTERLACING_24FPS_OUT              =  7, /*!< 24 fps fixed output mode. */
+    MFX_DEINTERLACING_FIXED_TELECINE_PATTERN =  8, /*!< Fixed telecine pattern removal mode. */
+    MFX_DEINTERLACING_30FPS_OUT              =  9, /*!< 30 fps fixed output mode. */
+    MFX_DEINTERLACING_DETECT_INTERLACE       = 10, /*!< Only interlace detection. */
+    MFX_DEINTERLACING_ADVANCED_NOREF         = 11, /*!< Advanced deinterlacing mode without using of reference frames. */
+    MFX_DEINTERLACING_ADVANCED_SCD           = 12, /*!< Advanced deinterlacing mode with scene change detection. */
+    MFX_DEINTERLACING_FIELD_WEAVING          = 13  /*!< Field weaving. */
+};
+
+/*! The TelecinePattern enumerator itemizes telecine patterns. */
+enum {
+    MFX_TELECINE_PATTERN_32           = 0, /*!< 3:2 telecine. */
+    MFX_TELECINE_PATTERN_2332         = 1, /*!< 2:3:3:2 telecine. */
+    MFX_TELECINE_PATTERN_FRAME_REPEAT = 2, /*!< One frame repeat telecine. */
+    MFX_TELECINE_PATTERN_41           = 3, /*!< 4:1 telecine. */
+    MFX_TELECINE_POSITION_PROVIDED    = 4  /*!< User must provide position inside a sequence of 5 frames where the artifacts start. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the application to specify different deinterlacing algorithms.
+*/
+typedef struct {
+    mfxExtBuffer    Header;   /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_DEINTERLACING. */
+    mfxU16  Mode;             /*!< Deinterlacing algorithm. See the DeinterlacingMode enumerator for details. */
+    mfxU16  TelecinePattern;  /*!< Specifies telecine pattern when Mode = MFX_DEINTERLACING_FIXED_TELECINE_PATTERN. See the TelecinePattern enumerator for details.*/
+    mfxU16  TelecineLocation; /*!< Specifies position inside a sequence of 5 frames where the artifacts start when TelecinePattern = MFX_TELECINE_POSITION_PROVIDED*/
+    mfxU16  reserved[9];      /*!< Reserved for future use. */
+} mfxExtVPPDeinterlacing;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Specifies reference lists for the encoder. It may be used together with the mfxExtAVCRefListCtrl
+   structure to create customized reference lists. If both structures are used together, then the encoder takes reference lists from the
+   mfxExtAVCRefLists structure and modifies them according to the mfxExtAVCRefListCtrl instructions. In case of interlaced coding,
+   the first mfxExtAVCRefLists structure affects TOP field and the second – BOTTOM field.
+
+   @note Not all implementations of the encoder support this structure. The application must use the Query API function to determine if it is supported.
+*/
+typedef struct {
+    mfxExtBuffer    Header;            /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AVC_REFLISTS. */
+    mfxU16          NumRefIdxL0Active; /*!< Specify the number of reference frames in the active reference list L0. This number should be less than or
+                                            equal to the NumRefFrame parameter from encoding initialization. */
+    mfxU16          NumRefIdxL1Active; /*!< Specify the number of reference frames in the active reference list L1. This number should be less than or
+                                            equal to the NumRefFrame parameter from encoding initialization. */
+    mfxU16          reserved[2];
+
+    /*! Used by the reference lists contained in the parent structure. Together these fields are used to identify reference picture. */
+    struct mfxRefPic{
+        mfxU32      FrameOrder; /*!< Use FrameOrder = MFX_FRAMEORDER_UNKNOWN to mark
+                                     unused entry. */
+        mfxU16      PicStruct;  /*!< Use PicStruct = MFX_PICSTRUCT_FIELD_TFF for TOP field, PicStruct = MFX_PICSTRUCT_FIELD_BFF for
+                                     BOTTOM field. */
+        mfxU16      reserved[5];
+    } RefPicList0[32], /*!< Specify L0 reference list. */
+      RefPicList1[32]; /*!< Specify L1 reference list. */
+
+}mfxExtAVCRefLists;
+MFX_PACK_END()
+
+/*! The VPPFieldProcessingMode enumerator is used to control VPP field processing algorithm. */
+enum {
+    MFX_VPP_COPY_FRAME      =0x01, /*!< Copy the whole frame. */
+    MFX_VPP_COPY_FIELD      =0x02, /*!< Copy only one field. */
+    MFX_VPP_SWAP_FIELDS     =0x03  /*!< Swap top and bottom fields. */
+};
+
+/*! The PicType enumerator itemizes picture type. */
+enum {
+    MFX_PICTYPE_UNKNOWN     =0x00, /*!< Picture type is unknown. */
+    MFX_PICTYPE_FRAME       =0x01, /*!< Picture is a frame. */
+    MFX_PICTYPE_TOPFIELD    =0x02, /*!< Picture is a top field. */
+    MFX_PICTYPE_BOTTOMFIELD =0x04  /*!< Picture is a bottom field. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the VPP field processing algorithm. The application can attach this extended buffer to
+   the mfxVideoParam structure to configure initialization and/or to the mfxFrameData during runtime. Runtime configuration has priority
+   over initialization configuration. If the field processing algorithm was activated via the mfxExtVPPDoUse structure and the mfxExtVPPFieldProcessing
+   extended buffer was not provided during initialization, this buffer must be attached to the mfxFrameData structure of each input surface.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_FIELD_PROCESSING. */
+
+    mfxU16          Mode;     /*!< Specifies the mode of the field processing algorithm. See the VPPFieldProcessingMode enumerator for values of this option. */
+    mfxU16          InField;  /*!< When Mode is MFX_VPP_COPY_FIELD, specifies input field. See the PicType enumerator for values of this parameter. */
+    mfxU16          OutField; /*!< When Mode is MFX_VPP_COPY_FIELD, specifies output field. See the PicType enumerator for values of this parameter. */
+    mfxU16          reserved[25];
+} mfxExtVPPFieldProcessing;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   If attached to the mfxVideoParam structure during the Init stage, this buffer will instruct the decoder to resize output frames via the
+   fixed function resize engine (if supported by hardware), utilizing direct pipe connection and bypassing intermediate memory operations.
+   The main benefits of this mode of pipeline operation are offloading resize operation to a dedicated engine, thus reducing power
+   consumption and memory traffic.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_DEC_VIDEO_PROCESSING. */
+
+    /*! Input surface description. */
+    struct mfxIn{
+        mfxU16  CropX; /*!< X coordinate of region of interest of the input surface. */
+        mfxU16  CropY; /*!< Y coordinate of region of interest of the input surface. */
+        mfxU16  CropW; /*!< Width coordinate of region of interest of the input surface. */
+        mfxU16  CropH; /*!< Height coordinate of region of interest of the input surface. */
+        mfxU16  reserved[12];
+    }In; /*!< Input surface description. */
+
+    /*! Output surface description. */
+    struct mfxOut{
+        mfxU32  FourCC;       /*!< FourCC of output surface Note: Should be MFX_FOURCC_NV12. */
+        mfxU16  ChromaFormat; /*!< Chroma Format of output surface.
+                                   @note Should be MFX_CHROMAFORMAT_YUV420 */
+        mfxU16  reserved1;
+
+        mfxU16  Width;        /*!< Width of output surface. */
+        mfxU16  Height;       /*!< Height of output surface. */
+
+        mfxU16  CropX; /*!< X coordinate of region of interest of the output surface. */
+        mfxU16  CropY; /*!< Y coordinate of region of interest of the output surface. */
+        mfxU16  CropW; /*!< Width coordinate of region of interest of the output surface. */
+        mfxU16  CropH; /*!< Height coordinate of region of interest of the output surface. */
+        mfxU16  reserved[22];
+    }Out; /*!< Output surface description. */
+
+    mfxU16  reserved[13];
+} mfxExtDecVideoProcessing;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Members of this structure define the location of chroma samples information.
+
+   See Annex E of the ISO*\/IEC* 14496-10 specification for the definition of these parameters.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_CHROMA_LOC_INFO. */
+
+    mfxU16       ChromaLocInfoPresentFlag;
+    mfxU16       ChromaSampleLocTypeTopField;
+    mfxU16       ChromaSampleLocTypeBottomField;
+    mfxU16       reserved[9];
+} mfxExtChromaLocInfo;
+MFX_PACK_END()
+
+/*! The MBQPMode enumerator itemizes QP update modes. */
+enum {
+    MFX_MBQP_MODE_QP_VALUE = 0, /*!< QP array contains QP values. */
+    MFX_MBQP_MODE_QP_DELTA = 1,  /*!< QP array contains deltas for QP. */
+    MFX_MBQP_MODE_QP_ADAPTIVE = 2 /*!< QP array contains deltas for QP or absolute QP values. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Specifies per-MB or per-CU mode and QP or deltaQP value depending on the mode type.
+ */
+typedef struct{
+    union {
+          /*!
+           QP for MB or CU. Valid when Mode = MFX_MBQP_MODE_QP_VALUE.
+
+           For AVC, the valid range is 1 to 51.
+
+           For HEVC, the valid range is 1 to 51. The application's provided QP values should be valid, otherwise invalid QP values may cause undefined behavior.
+
+           MBQP map should be aligned for 16x16 block size. The align rule is: (width +15 /16) && (height +15 /16).
+
+           For MPEG2, the valid range is 1 to 112. QP corresponds to quantizer_scale of the ISO*\/IEC* 13818-2 specification.
+           */
+        mfxU8 QP;
+            /*!
+             Per-macroblock QP delta. Valid when Mode = MFX_MBQP_MODE_QP_DELTA.
+             */
+        mfxI8 DeltaQP;
+    };
+    mfxU16 Mode; /*!< Defines QP update mode. Can be equal to MFX_MBQP_MODE_QP_VALUE or MFX_MBQP_MODE_QP_DELTA. */
+} mfxQPandMode;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   Specifies per-macroblock QP for current frame if mfxExtCodingOption3::EnableMBQP was turned ON during
+   encoder initialization. The application can attach this extended buffer to the mfxEncodeCtrl structure during runtime.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MBQP. */
+
+    mfxU32 reserved[10];
+    mfxU16 Mode;        /*!< Defines QP update mode. See MBQPMode enumerator for more details. */
+    mfxU16 BlockSize;   /*!< QP block size, valid for HEVC only during Init and Runtime. */
+    mfxU32 NumQPAlloc;  /*!< Size of allocated by application QP or DeltaQP array. */
+    union {
+        /*!
+           Pointer to a list of per-macroblock QP in raster scan order. In case of interlaced encoding the first half of QP array affects the top
+           field and the second half of QP array affects the bottom field. Valid when Mode = MFX_MBQP_MODE_QP_VALUE.
+
+           For AVC, the valid range is 1 to 51.
+
+           For HEVC, the valid range is 1 to 51. Application’s provided QP values should be valid. Otherwise invalid QP values may cause undefined behavior.
+           MBQP map should be aligned for 16x16 block size. The alignment rule is (width +15 /16) && (height +15 /16).
+
+           For MPEG2, QP corresponds to quantizer_scale of the ISO*\/IEC* 13818-2 specification and has a valid range of 1 to 112.
+        */
+        mfxU8  *QP;
+        mfxI8  *DeltaQP;    /*!< Pointer to a list of per-macroblock QP deltas in raster scan order.
+                                 For block i: QP[i] = BrcQP[i] + DeltaQP[i]. Valid when Mode = MFX_MBQP_MODE_QP_DELTA. */
+        mfxQPandMode *QPmode; /*!< Block-granularity modes when MFX_MBQP_MODE_QP_ADAPTIVE is set. */
+
+        mfxU64 reserved2;
+    };
+} mfxExtMBQP;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Runtime ctrl buffer for SPS/PPS insertion with current encoding frame.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_INSERT_HEADERS. */
+    mfxU16          SPS;      /*!< Tri-state option to insert SPS. */
+    mfxU16          PPS;      /*!< Tri-state option to insert PPS. */
+    mfxU16          reserved[8];
+} mfxExtInsertHeaders;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+  Specifies rectangle areas for IPCM coding mode.
+*/
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ENCODER_IPCM_AREA. */
+    mfxU16          reserve1[10];
+
+    mfxU16          NumArea;  /*! Number of areas */
+    struct area {
+
+        mfxU32      Left; /*!< Left area coordinate. */
+        mfxU32      Top;  /*!< Top area coordinate. */
+        mfxU32      Right; /*!< Right area coordinate. */
+        mfxU32      Bottom; /*!< Bottom area coordinate. */
+
+        mfxU16      reserved2[8];
+
+    } * Areas; /*!< Array of areas. */
+} mfxExtEncoderIPCMArea;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   Specifies macroblock map for current frame which forces specified macroblocks to be encoded as intra
+   if mfxExtCodingOption3::EnableMBForceIntra was turned ON during encoder initialization. The application can attach this extended
+   buffer to the mfxEncodeCtrl structure during runtime.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MB_FORCE_INTRA. */
+
+    mfxU32 reserved[11];
+    mfxU32 MapSize;  /*!< Macroblock map size. */
+    union {
+        mfxU8  *Map; /*!< Pointer to a list of force intra macroblock flags in raster scan order. Each flag is one byte in map. Set flag to 1
+                          to force corresponding macroblock to be encoded as intra. In case of interlaced encoding, the first half of map
+                          affects top field and the second half of map affects the bottom field. */
+        mfxU64  reserved2;
+    };
+} mfxExtMBForceIntra;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures tiles options for the HEVC encoder. The application can attach this extended buffer to the
+   mfxVideoParam structure to configure initialization.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_HEVC_TILES. */
+
+    mfxU16 NumTileRows;    /*!< Number of tile rows. */
+    mfxU16 NumTileColumns; /*!< Number of tile columns. */
+    mfxU16 reserved[74];
+}mfxExtHEVCTiles;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   Specifies macroblock map for current frame which forces specified macroblocks to be non-skip if
+   mfxExtCodingOption3::MBDisableSkipMap was turned ON during encoder initialization. The application can attach this
+   extended buffer to the mfxEncodeCtrl structure during runtime.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MB_DISABLE_SKIP_MAP. */
+
+    mfxU32 reserved[11];
+    mfxU32 MapSize;  /*!< Macroblock map size. */
+    union {
+        mfxU8  *Map; /*!< Pointer to a list of non-skip macroblock flags in raster scan order. Each flag is one byte in map. Set flag to 1 to force
+                          corresponding macroblock to be non-skip. In case of interlaced encoding, the first half of map affects
+                          the top field and the second half of map affects the bottom field. */
+        mfxU64  reserved2;
+    };
+} mfxExtMBDisableSkipMap;
+MFX_PACK_END()
+
+/*! The GeneralConstraintFlags enumerator uses bit-ORed values to itemize HEVC bitstream indications for specific profiles. Each value
+    indicates for format range extensions profiles. 
+    To specify HEVC Main 10 Still Picture profile applications have to set mfxInfoMFX::CodecProfile == MFX_PROFILE_HEVC_MAIN10 and 
+    mfxExtHEVCParam::GeneralConstraintFlags == MFX_HEVC_CONSTR_REXT_ONE_PICTURE_ONLY. */
+enum {
+    /* REXT Profile constraint flags*/
+    MFX_HEVC_CONSTR_REXT_MAX_12BIT          = (1 << 0),
+    MFX_HEVC_CONSTR_REXT_MAX_10BIT          = (1 << 1),
+    MFX_HEVC_CONSTR_REXT_MAX_8BIT           = (1 << 2),
+    MFX_HEVC_CONSTR_REXT_MAX_422CHROMA      = (1 << 3),
+    MFX_HEVC_CONSTR_REXT_MAX_420CHROMA      = (1 << 4),
+    MFX_HEVC_CONSTR_REXT_MAX_MONOCHROME     = (1 << 5),
+    MFX_HEVC_CONSTR_REXT_INTRA              = (1 << 6),
+    MFX_HEVC_CONSTR_REXT_ONE_PICTURE_ONLY   = (1 << 7),
+    MFX_HEVC_CONSTR_REXT_LOWER_BIT_RATE     = (1 << 8)
+};
+
+
+/*! The SampleAdaptiveOffset enumerator uses bit-ORed values to itemize corresponding HEVC encoding feature. */
+enum {
+    MFX_SAO_UNKNOWN       = 0x00, /*!< Use default value for platform/TargetUsage. */
+    MFX_SAO_DISABLE       = 0x01, /*!< Disable SAO. If set during Init leads to SPS sample_adaptive_offset_enabled_flag = 0.
+                                       If set during Runtime, leads to to slice_sao_luma_flag = 0 and slice_sao_chroma_flag = 0
+                                       for current frame. */
+    MFX_SAO_ENABLE_LUMA   = 0x02, /*!< Enable SAO for luma (slice_sao_luma_flag = 1). */
+    MFX_SAO_ENABLE_CHROMA = 0x04  /*!< Enable SAO for chroma (slice_sao_chroma_flag = 1). */
+};
+
+
+/* This struct has 4-byte alignment for binary compatibility with previously released versions of API */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_HEVC_PARAM. */
+
+    mfxU16          PicWidthInLumaSamples;  /*!< Specifies the width of each coded picture in units of luma samples. */
+    mfxU16          PicHeightInLumaSamples; /*!< Specifies the height of each coded picture in units of luma samples. */
+    mfxU64          GeneralConstraintFlags; /*!< Additional flags to specify exact profile and constraints. See the GeneralConstraintFlags enumerator for values of this field. */
+    mfxU16          SampleAdaptiveOffset;   /*!< Controls SampleAdaptiveOffset encoding feature. See the SampleAdaptiveOffset enumerator for supported values
+                                                 (bit-ORed). Valid during encoder Init and Runtime. */
+    mfxU16          LCUSize;                /*!< Specifies largest coding unit size (max luma coding block). Valid during encoder Init. */
+    mfxU16          reserved[116];
+} mfxExtHEVCParam;
+MFX_PACK_END()
+
+/*! The ErrorTypes enumerator uses bit-ORed values to itemize bitstream error types. */
+enum {
+    MFX_ERROR_NO                  =        0,  /*!< No error in bitstream. */
+    MFX_ERROR_PPS                 = (1 << 0),  /*!< Invalid/corrupted PPS. */
+    MFX_ERROR_SPS                 = (1 << 1),  /*!< Invalid/corrupted SPS. */
+    MFX_ERROR_SLICEHEADER         = (1 << 2),  /*!< Invalid/corrupted slice header. */
+    MFX_ERROR_SLICEDATA           = (1 << 3),  /*!< Invalid/corrupted slice data. */
+    MFX_ERROR_FRAME_GAP           = (1 << 4),  /*!< Missed frames. */
+#ifdef ONEVPL_EXPERIMENTAL
+    MFX_ERROR_JPEG_APP0_MARKER    = (1 << 5),  /*!< Invalid/corrupted APP0 marker. */
+    MFX_ERROR_JPEG_APP1_MARKER    = (1 << 6),  /*!< Invalid/corrupted APP1 marker. */
+    MFX_ERROR_JPEG_APP2_MARKER    = (1 << 7),  /*!< Invalid/corrupted APP2 marker. */
+    MFX_ERROR_JPEG_APP3_MARKER    = (1 << 8),  /*!< Invalid/corrupted APP3 marker. */
+    MFX_ERROR_JPEG_APP4_MARKER    = (1 << 9),  /*!< Invalid/corrupted APP4 marker. */
+    MFX_ERROR_JPEG_APP5_MARKER    = (1 << 10), /*!< Invalid/corrupted APP5 marker. */
+    MFX_ERROR_JPEG_APP6_MARKER    = (1 << 11), /*!< Invalid/corrupted APP6 marker. */
+    MFX_ERROR_JPEG_APP7_MARKER    = (1 << 12), /*!< Invalid/corrupted APP7 marker. */
+    MFX_ERROR_JPEG_APP8_MARKER    = (1 << 13), /*!< Invalid/corrupted APP8 marker. */
+    MFX_ERROR_JPEG_APP9_MARKER    = (1 << 14), /*!< Invalid/corrupted APP9 marker. */
+    MFX_ERROR_JPEG_APP10_MARKER   = (1 << 15), /*!< Invalid/corrupted APP10 marker. */
+    MFX_ERROR_JPEG_APP11_MARKER   = (1 << 16), /*!< Invalid/corrupted APP11 marker. */
+    MFX_ERROR_JPEG_APP12_MARKER   = (1 << 17), /*!< Invalid/corrupted APP12 marker. */
+    MFX_ERROR_JPEG_APP13_MARKER   = (1 << 18), /*!< Invalid/corrupted APP13 marker. */
+    MFX_ERROR_JPEG_APP14_MARKER   = (1 << 19), /*!< Invalid/corrupted APP14 marker. */
+    MFX_ERROR_JPEG_DQT_MARKER     = (1 << 20), /*!< Invalid/corrupted DQT marker. */
+    MFX_ERROR_JPEG_SOF0_MARKER    = (1 << 21), /*!< Invalid/corrupted SOF0 marker. */
+    MFX_ERROR_JPEG_DHT_MARKER     = (1 << 22), /*!< Invalid/corrupted DHT marker. */
+    MFX_ERROR_JPEG_DRI_MARKER     = (1 << 23), /*!< Invalid/corrupted DRI marker. */
+    MFX_ERROR_JPEG_SOS_MARKER     = (1 << 24), /*!< Invalid/corrupted SOS marker. */
+    MFX_ERROR_JPEG_UNKNOWN_MARKER = (1 << 25), /*!< Unknown Marker. */
+#endif
+};
+
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the decoders to report bitstream error information right after DecodeHeader or DecodeFrameAsync.
+   The application can attach this extended buffer to the mfxBitstream structure at runtime.
+*/
+typedef struct {
+    mfxExtBuffer    Header;     /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_DECODE_ERROR_REPORT. */
+
+    mfxU32          ErrorTypes; /*!< Bitstream error types (bit-ORed values). See ErrorTypes enumerator for the list of types. */
+    mfxU16          reserved[10];
+} mfxExtDecodeErrorReport;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the decoders to report additional information about a decoded frame. The application can attach this
+   extended buffer to the mfxFrameSurface1::mfxFrameData structure at runtime.
+*/
+typedef struct {
+    mfxExtBuffer Header;    /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_DECODED_FRAME_INFO. */
+
+    mfxU16       FrameType; /*!< Frame type. See FrameType enumerator for the list of types. */
+    mfxU16       reserved[59];
+} mfxExtDecodedFrameInfo;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the library to pass MPEG 2 specific timing information.
+
+   See ISO/IEC 13818-2 and ITU-T H.262, MPEG-2 Part 2 for the definition of these parameters.
+*/
+typedef struct {
+    mfxExtBuffer Header;           /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_TIME_CODE. */
+
+    mfxU16       DropFrameFlag;    /*!< Indicated dropped frame. */
+    mfxU16       TimeCodeHours;    /*!< Hours. */
+    mfxU16       TimeCodeMinutes;  /*!< Minutes. */
+    mfxU16       TimeCodeSeconds;  /*!< Seconds. */
+    mfxU16       TimeCodePictures; /*!< Pictures. */
+    mfxU16       reserved[7];
+} mfxExtTimeCode;
+MFX_PACK_END()
+
+/*! The HEVCRegionType enumerator itemizes type of HEVC region. */
+enum {
+    MFX_HEVC_REGION_SLICE = 0 /*!< Slice type. */
+};
+
+/*! The HEVCRegionEncoding enumerator itemizes HEVC region's encoding. */
+enum {
+    MFX_HEVC_REGION_ENCODING_ON  = 0,
+    MFX_HEVC_REGION_ENCODING_OFF = 1
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Attached to the mfxVideoParam structure during HEVC encoder initialization. Specifies the region to encode.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_HEVC_REGION. */
+
+    mfxU32       RegionId;       /*!< ID of region. */
+    mfxU16       RegionType;     /*!< Type of region. See HEVCRegionType enumerator for the list of types. */
+    mfxU16       RegionEncoding; /*!< Set to MFX_HEVC_REGION_ENCODING_ON to encode only specified region. */
+    mfxU16       reserved[24];
+} mfxExtHEVCRegion;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Specifies weighted prediction table for current frame when all of the following conditions are met:
+
+   @li mfxExtCodingOption3::WeightedPred was set to explicit during encoder Init or Reset .
+
+   @li The current frame is P-frame or mfxExtCodingOption3::WeightedBiPred was set to explicit during encoder Init or Reset.
+
+   @li The current frame is B-frame and is attached to the mfxEncodeCtrl structure.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_PRED_WEIGHT_TABLE. */
+
+    mfxU16       LumaLog2WeightDenom;     /*!< Base 2 logarithm of the denominator for all luma weighting factors. Value must be in the range of 0 to 7, inclusive. */
+    mfxU16       ChromaLog2WeightDenom;   /*!< Base 2 logarithm of the denominator for all chroma weighting factors. Value must be in the range of 0 to 7, inclusive. */
+    mfxU16       LumaWeightFlag[2][32];   /*!< LumaWeightFlag[L][R] equal to 1 specifies that the weighting factors for the luma component are specified for R’s entry of RefPicList L. */
+    mfxU16       ChromaWeightFlag[2][32]; /*!< ChromaWeightFlag[L][R] equal to 1 specifies that the weighting factors for the chroma component are specified for R’s entry of RefPicList L. */
+    mfxI16       Weights[2][32][3][2];    /*!< The values of the weights and offsets used in the encoding processing. The value of Weights[i][j][k][m] is
+                                               interpreted as: i refers to reference picture list 0 or 1; j refers to reference list entry 0-31;
+                                               k refers to data for the luma component when it is 0, the Cb chroma component when it is 1 and
+                                               the Cr chroma component when it is 2; m refers to weight when it is 0 and offset when it is 1 */
+    mfxU16       reserved[58];
+} mfxExtPredWeightTable;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by encoders to set rounding offset parameters for quantization. It is per-frame based encoding control,
+   and can be attached to some frames and skipped for others. When the extension buffer is set the application can attach it to the mfxEncodeCtrl
+   during runtime.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AVC_ROUNDING_OFFSET. */
+
+    mfxU16       EnableRoundingIntra; /*!< Enable rounding offset for intra blocks. See the CodingOptionValue enumerator for values of this option. */
+    mfxU16       RoundingOffsetIntra; /*!< Intra rounding offset. Value must be in the range of 0 to 7, inclusive. */
+    mfxU16       EnableRoundingInter; /*!< Enable rounding offset for inter blocks. See the CodingOptionValue enumerator for values of this option. */
+    mfxU16       RoundingOffsetInter; /*!< Inter rounding offset. Value must be in the range of 0 to 7, inclusive. */
+
+    mfxU16       reserved[24];
+} mfxExtAVCRoundingOffset;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the application to specify dirty regions within a frame during encoding. It may be used at initialization or at runtime.
+
+   Dirty rectangle definition is using end-point exclusive notation. In other words, the pixel with (Right, Bottom) coordinates lies
+   immediately outside of the dirty rectangle. Left, Top, Right, Bottom should be aligned by codec-specific block boundaries (should be
+   dividable by 16 for AVC, or by block size (8, 16, 32 or 64, depends on platform) for HEVC).
+
+   Every dirty rectangle with unaligned
+   coordinates will be expanded to a minimal-area block-aligned dirty rectangle, enclosing the original one.
+   For example, a (5, 5, 15, 31) dirty rectangle will be expanded to (0, 0, 16, 32) for AVC encoder, or to (0, 0, 32, 32) for HEVC,
+   if block size is 32.
+
+   Dirty rectangle (0, 0, 0, 0) is a valid dirty rectangle and means that the frame is not changed.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_DIRTY_RECTANGLES. */
+
+    mfxU16  NumRect;    /*!< Number of dirty rectangles. */
+    mfxU16  reserved1[11];
+
+    struct {
+        /*! @{
+        @name Dirty rectangle coordinates
+        The following structure members are used by the Rect array contained in the parent structure.
+
+         */
+        mfxU32  Left;   /*!< Dirty region left coordinate. */
+        mfxU32  Top;    /*!< Dirty region top coordinate. */
+        mfxU32  Right;  /*!< Dirty region right coordinate. */
+        mfxU32  Bottom; /*!< Dirty region bottom coordinate. */
+
+        mfxU16  reserved2[8];
+        /*! @} */
+    } Rect[256];        /*!< Array of dirty rectangles. */
+} mfxExtDirtyRect;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by the application to specify moving regions within a frame during encoding.
+
+   Destination rectangle location should be aligned to MB boundaries (should be dividable by 16). If not, the encoder
+   truncates it to MB boundaries, for example, both 17 and 31 will be truncated to 16.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MOVING_RECTANGLE. */
+
+    mfxU16  NumRect;        /*!< Number of moving rectangles. */
+    mfxU16  reserved1[11];
+
+    struct {
+        /*! @{
+        @name Destination and source rectangle location
+        The following structure members are used by the Rect array contained in the parent structure.
+         */
+        mfxU32  DestLeft;   /*!< Destination rectangle location. */
+        mfxU32  DestTop;    /*!< Destination rectangle location. */
+        mfxU32  DestRight;  /*!< Destination rectangle location. */
+        mfxU32  DestBottom; /*!< Destination rectangle location. */
+
+        mfxU32  SourceLeft; /*!< Source rectangle location. */
+        mfxU32  SourceTop;  /*!< Source rectangle location. */
+        mfxU16  reserved2[4];
+        /*! @} */
+    } Rect[256];            /*!< Array of moving rectangles. */
+} mfxExtMoveRect;
+MFX_PACK_END()
+
+/*! The Angle enumerator itemizes valid rotation angles. */
+enum {
+    MFX_ANGLE_0     =   0, /*!< 0 degrees. */
+    MFX_ANGLE_90    =  90, /*!< 90 degrees. */
+    MFX_ANGLE_180   = 180, /*!< 180 degrees. */
+    MFX_ANGLE_270   = 270  /*!< 270 degrees. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the VPP Rotation filter algorithm.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_ROTATION. */
+
+    mfxU16 Angle;        /*!< Rotation angle. See Angle enumerator for supported values. */
+    mfxU16 reserved[11];
+} mfxExtVPPRotation;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   Used by the encoder to report additional information about encoded slices. The application can attach this
+   buffer to the mfxBitstream structure before calling the MFXVideoENCODE_EncodeFrameAsync function.
+
+   @note Not all implementations of the encoder support this extended buffer. The application must use query mode 1 to determine if the
+         functionality is supported. To do this, the application must attach this extended buffer to the mfxVideoParam structure and call the
+         MFXVideoENCODE_Query function. If the function returns MFX_ERR_NONE, then the functionality is supported.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ENCODED_SLICES_INFO. */
+
+    mfxU16  SliceSizeOverflow;   /*!< When mfxExtCodingOption2::MaxSliceSize is used, indicates the requested slice size was not met for one or more generated slices. */
+    mfxU16  NumSliceNonCopliant; /*!< When mfxExtCodingOption2::MaxSliceSize is used, indicates the number of generated slices exceeds specification limits. */
+    mfxU16  NumEncodedSlice;     /*!< Number of encoded slices. */
+    mfxU16  NumSliceSizeAlloc;   /*!< SliceSize array allocation size. Must be specified by application. */
+    union {
+        mfxU16  *SliceSize;      /*!< Slice size in bytes. Array must be allocated by application. */
+        mfxU64  reserved1;
+    };
+
+    mfxU16 reserved[20];
+} mfxExtEncodedSlicesInfo;
+MFX_PACK_END()
+
+/*! The ScalingMode enumerator itemizes variants of scaling filter implementation. */
+enum {
+    MFX_SCALING_MODE_DEFAULT    = 0, /*!< Default scaling mode. The library selects the most appropriate scaling method. */
+    MFX_SCALING_MODE_LOWPOWER   = 1, /*!< Low power scaling mode which is applicable for library implementations.
+                                         The exact scaling algorithm is defined by the library. */
+    MFX_SCALING_MODE_QUALITY    = 2, /*!< The best quality scaling mode. */
+    MFX_SCALING_MODE_VENDOR = 1000, /*!< The enumeration to separate common scaling controls above and vendor specific. */ 
+    MFX_SCALING_MODE_INTEL_GEN_COMPUTE  = MFX_SCALING_MODE_VENDOR + 1, /*! The mode to run scaling operation on Execution Units (EUs). */
+    MFX_SCALING_MODE_INTEL_GEN_VDBOX = MFX_SCALING_MODE_VENDOR + 2, /*! The special optimization mode where scaling operation running on SFC (Scaler & Format Converter) is coupled with VDBOX (also known as Multi-Format Codec fixed-function engine). This mode is applicable for DECODE_VPP domain functions. */ 
+    MFX_SCALING_MODE_INTEL_GEN_VEBOX = MFX_SCALING_MODE_VENDOR + 3 /*! The special optimization mode where scaling operation running on SFC is coupled with VEBOX (HW video processing pipe). */ 
+};
+
+/*! The InterpolationMode enumerator specifies type of interpolation method used by VPP scaling filter. */
+enum {
+    MFX_INTERPOLATION_DEFAULT                = 0, /*!< Default interpolation mode for scaling. Library selects the most appropriate
+                                                    scaling method. */
+    MFX_INTERPOLATION_NEAREST_NEIGHBOR       = 1, /*!< Nearest neighbor interpolation method. */
+    MFX_INTERPOLATION_BILINEAR               = 2, /*!< Bilinear interpolation method. */
+    MFX_INTERPOLATION_ADVANCED               = 3  /*!< Advanced interpolation method is defined by each implementation and usually gives best                                                          quality. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the VPP Scaling filter algorithm.
+   Not all combinations of ScalingMode and InterpolationMethod are supported in the library. The application must use the Query API function to determine if a combination is supported.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_SCALING. */
+
+    mfxU16 ScalingMode;  /*!< Scaling mode. See ScalingMode for values. */
+    mfxU16 InterpolationMethod; /*!< Interpolation mode for scaling algorithm. See InterpolationMode for values. */
+    mfxU16 reserved[10];
+} mfxExtVPPScaling;
+MFX_PACK_END()
+
+typedef mfxExtAVCRefListCtrl mfxExtHEVCRefListCtrl;
+typedef mfxExtAVCRefLists mfxExtHEVCRefLists;
+typedef mfxExtAvcTemporalLayers mfxExtHEVCTemporalLayers;
+
+#ifdef ONEVPL_EXPERIMENTAL
+typedef mfxExtAVCRefListCtrl mfxExtRefListCtrl;
+#endif
+
+/* The MirroringType enumerator itemizes mirroring types. */
+enum
+{
+    MFX_MIRRORING_DISABLED   = 0,
+    MFX_MIRRORING_HORIZONTAL = 1,
+    MFX_MIRRORING_VERTICAL   = 2
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the VPP Mirroring filter algorithm.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_MIRRORING. */
+
+    mfxU16 Type;         /*!< Mirroring type. See MirroringType for values. */
+    mfxU16 reserved[11];
+} mfxExtVPPMirroring;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Instructs encoder to use or not use samples over specified picture border for inter prediction. Attached to the mfxVideoParam structure.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_MV_OVER_PIC_BOUNDARIES. */
+
+    mfxU16 StickTop;     /*!< When set to OFF, one or more samples outside corresponding picture boundary may be used in inter prediction.
+                              See the CodingOptionValue enumerator for values of this option. */
+    mfxU16 StickBottom;  /*!< When set to OFF, one or more samples outside corresponding picture boundary may be used in inter prediction.
+                              See the CodingOptionValue enumerator for values of this option. */
+    mfxU16 StickLeft;    /*!< When set to OFF, one or more samples outside corresponding picture boundary may be used in inter prediction.
+                              See the CodingOptionValue enumerator for values of this option. */
+    mfxU16 StickRight;   /*!< When set to OFF, one or more samples outside corresponding picture boundary may be used in inter prediction.
+                              See the CodingOptionValue enumerator for values of this option. */
+    mfxU16 reserved[8];
+} mfxExtMVOverPicBoundaries;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Configures the VPP ColorFill filter algorithm.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_COLORFILL. */
+
+    mfxU16 Enable;       /*!< Set to ON makes VPP fill the area between Width/Height and Crop borders.
+                              See the CodingOptionValue enumerator for values of this option. */
+    mfxU16 reserved[11];
+} mfxExtVPPColorFill;
+MFX_PACK_END()
+
+
+/*! The ChromaSiting enumerator defines chroma location. Use bit-OR’ed values to specify the desired location. */
+enum {
+    MFX_CHROMA_SITING_UNKNOWN             = 0x0000, /*!< Unspecified. */
+    MFX_CHROMA_SITING_VERTICAL_TOP        = 0x0001, /*!< Chroma samples are co-sited vertically on the top with the luma samples. */
+    MFX_CHROMA_SITING_VERTICAL_CENTER     = 0x0002, /*!< Chroma samples are not co-sited vertically with the luma samples. */
+    MFX_CHROMA_SITING_VERTICAL_BOTTOM     = 0x0004, /*!< Chroma samples are co-sited vertically on the bottom with the luma samples. */
+    MFX_CHROMA_SITING_HORIZONTAL_LEFT     = 0x0010, /*!< Chroma samples are co-sited horizontally on the left with the luma samples. */
+    MFX_CHROMA_SITING_HORIZONTAL_CENTER   = 0x0020  /*!< Chroma samples are not co-sited horizontally with the luma samples. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   A hint structure that tunes the VPP Color Conversion algorithm when
+   attached to the mfxVideoParam structure during VPP Init.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_COLOR_CONVERSION. */
+
+    mfxU16 ChromaSiting; /*!< See ChromaSiting enumerator for details. */
+    mfxU16 reserved[27];
+} mfxExtColorConversion;
+MFX_PACK_END()
+
+
+/*! The VP9ReferenceFrame enumerator itemizes reference frame type by mfxVP9SegmentParam::ReferenceFrame parameter.  */
+enum {
+    MFX_VP9_REF_INTRA   = 0, /*!< Intra. */
+    MFX_VP9_REF_LAST    = 1, /*!< Last. */
+    MFX_VP9_REF_GOLDEN  = 2, /*!< Golden. */
+    MFX_VP9_REF_ALTREF  = 3  /*!< Alternative reference. */
+};
+
+/*!
+   The SegmentIdBlockSize enumerator indicates the block size represented by each segment_id in segmentation map.
+   These values are used with the mfxExtVP9Segmentation::SegmentIdBlockSize parameter.
+*/
+enum {
+    MFX_VP9_SEGMENT_ID_BLOCK_SIZE_UNKNOWN =  0, /*!< Unspecified block size. */
+    MFX_VP9_SEGMENT_ID_BLOCK_SIZE_8x8     =  8, /*!<  8x8  block size. */
+    MFX_VP9_SEGMENT_ID_BLOCK_SIZE_16x16   = 16, /*!< 16x16 block size. */
+    MFX_VP9_SEGMENT_ID_BLOCK_SIZE_32x32   = 32, /*!< 32x32 block size. */
+    MFX_VP9_SEGMENT_ID_BLOCK_SIZE_64x64   = 64, /*!< 64x64 block size. */
+};
+
+/*!
+   The SegmentFeature enumerator indicates features enabled for the segment.
+   These values are used with the mfxVP9SegmentParam::FeatureEnabled parameter.
+*/
+enum {
+    MFX_VP9_SEGMENT_FEATURE_QINDEX      = 0x0001, /*!< Quantization index delta. */
+    MFX_VP9_SEGMENT_FEATURE_LOOP_FILTER = 0x0002, /*!< Loop filter level delta. */
+    MFX_VP9_SEGMENT_FEATURE_REFERENCE   = 0x0004, /*!< Reference frame. */
+    MFX_VP9_SEGMENT_FEATURE_SKIP        = 0x0008  /*!< Skip. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Contains features and parameters for the segment.
+*/
+typedef struct {
+    mfxU16  FeatureEnabled;       /*!< Indicates which features are enabled for the segment. See the SegmentFeature enumerator for values for this
+                                       option. Values from the enumerator can be bit-OR’ed. Support of a particular feature depends on underlying
+                                       hardware platform. Application can check which features are supported by calling Query. */
+    mfxI16  QIndexDelta;          /*!< Quantization index delta for the segment. Ignored if MFX_VP9_SEGMENT_FEATURE_QINDEX isn’t set in FeatureEnabled.
+                                       Valid range for this parameter is [-255, 255]. If QIndexDelta is out of this range, it will be ignored.
+                                       If QIndexDelta is within valid range, but sum of base quantization index and QIndexDelta is out of [0, 255],
+                                       QIndexDelta will be clamped. */
+    mfxI16  LoopFilterLevelDelta; /*!< Loop filter level delta for the segment. Ignored if MFX_VP9_SEGMENT_FEATURE_LOOP_FILTER is not set in
+                                       FeatureEnabled. Valid range for this parameter is [-63, 63]. If LoopFilterLevelDelta is out of this range,
+                                       it will be ignored. If LoopFilterLevelDelta is within valid range, but sum of base loop filter level and
+                                       LoopFilterLevelDelta is out of [0, 63], LoopFilterLevelDelta will be clamped. */
+    mfxU16  ReferenceFrame;       /*!< Reference frame for the segment. See VP9ReferenceFrame enumerator for values for this option. Ignored
+                                       if MFX_VP9_SEGMENT_FEATURE_REFERENCE isn’t set in FeatureEnabled. */
+    mfxU16  reserved[12];
+} mfxVP9SegmentParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   In the VP9 encoder it is possible to divide a frame into up to 8 segments and apply particular features (like delta for quantization index or for
+   loop filter level) on a per-segment basis. “Uncompressed header” of every frame indicates if segmentation is enabled for the current frame,
+   and (if segmentation enabled) contains full information about features applied to every segment. Every “Mode info block” of a coded
+   frame has segment_id in the range of 0 to 7.
+
+   To enable Segmentation, the mfxExtVP9Segmentation structure with correct settings should be passed to the encoder. It can be attached to the
+   mfxVideoParam structure during initialization or the MFXVideoENCODE_Reset call (static configuration). If the mfxExtVP9Segmentation buffer isn’t
+   attached during initialization, segmentation is disabled for static configuration. If the buffer isn’t attached for the Reset call, the encoder
+   continues to use static configuration for segmentation which was the default before this Reset call. If the mfxExtVP9Segmentation buffer with
+   NumSegments=0 is provided during initialization or Reset call, segmentation becomes disabled for static configuration.
+
+   The buffer can be attached to the mfxEncodeCtrl structure during runtime (dynamic configuration). Dynamic configuration is applied to the
+   current frame only. After encoding of the current frame, the encoder will switch to the next dynamic configuration or to static configuration if dynamic configuration
+   is not provided for next frame).
+
+   The SegmentIdBlockSize, NumSegmentIdAlloc, and SegmentId parameters represent a segmentation map. Here, the segmentation map is an array of segment_ids (one
+   byte per segment_id) for blocks of size NxN in raster scan order. The size NxN is specified by the application and is constant for the whole frame.
+   If mfxExtVP9Segmentation is attached during initialization and/or during runtime, all three parameters should be set to proper values that do not
+   conflict with each other and with NumSegments. If any of the parameters are not set or any conflict or error in these parameters is detected by the library, the segmentation
+   map will be discarded.
+*/
+typedef struct {
+    mfxExtBuffer        Header;             /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VP9_SEGMENTATION. */
+    mfxU16              NumSegments;        /*!< Number of segments for frame. Value 0 means that segmentation is disabled. Sending 0 for a
+                                                 particular frame will disable segmentation for this frame only. Sending 0 to the Reset API function will
+                                                 disable segmentation permanently. Segmentation can be enabled again by a subsequent Reset call. */
+    mfxVP9SegmentParam  Segment[8];         /*!< Array of mfxVP9SegmentParam structures containing features and parameters for every segment.
+                                                 Entries with indexes bigger than NumSegments-1 are ignored. See the mfxVP9SegmentParam structure for
+                                                 definitions of segment features and their parameters. */
+    mfxU16              SegmentIdBlockSize; /*!< Size of block (NxN) for segmentation map. See SegmentIdBlockSize enumerator for values for this
+                                                 option. An encoded block that is bigger than SegmentIdBlockSize uses segment_id taken from it’s
+                                                 top-left sub-block from the segmentation map. The application can check if a particular block size is
+                                                 supported by calling Query. */
+    mfxU32              NumSegmentIdAlloc;  /*!< Size of buffer allocated for segmentation map (in bytes). Application must assure that
+                                                 NumSegmentIdAlloc is large enough to cover frame resolution with blocks of size SegmentIdBlockSize.
+                                                 Otherwise the segmentation map will be discarded. */
+    union {
+        mfxU8           *SegmentId;         /*!< Pointer to the segmentation map buffer which holds the array of segment_ids in raster scan order. The application
+                                                 is responsible for allocation and release of this memory. The buffer pointed to by SegmentId, provided during
+                                                 initialization or Reset call should be considered in use until another SegmentId is provided via Reset
+                                                 call (if any), or until MFXVideoENCODE_Close is called. The buffer pointed to by SegmentId provided with
+                                                 mfxEncodeCtrl should be considered in use while the input surface is locked by the library. Every segment_id in the
+                                                 map should be in the range of 0 to NumSegments-1. If some segment_id is out of valid range, the
+                                                 segmentation map cannot be applied. If the mfxExtVP9Segmentation buffer is attached to the mfxEncodeCtrl structure in
+                                                 runtime, SegmentId can be zero. In this case, the segmentation map from static configuration will be used. */
+        mfxU64          reserved1;
+    };
+    mfxU16  reserved[52];
+} mfxExtVP9Segmentation;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Specifies temporal layer.
+*/
+typedef struct {
+    mfxU16 FrameRateScale;  /*!< The ratio between the frame rates of the current temporal layer and the base layer. The library treats a particular
+                                 temporal layer as “defined” if it has FrameRateScale > 0. If the base layer is defined, it must have FrameRateScale = 1. FrameRateScale of each subsequent layer (if defined) must be a multiple of and greater than the
+                                 FrameRateScale value of previous layer. */
+    mfxU16 TargetKbps;      /*!< Target bitrate for the current temporal layer. Ignored if RateControlMethod is CQP. If RateControlMethod is not CQP, the
+                                 application must provide TargetKbps for every defined temporal layer. TargetKbps of each subsequent layer (if defined)
+                                 must be greater than the TargetKbps value of the previous layer. */
+    mfxU16 reserved[14];
+} mfxVP9TemporalLayer;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   API allows the encoding of VP9 bitstreams that contain several subset bitstreams that differ in frame rates, also called “temporal layers”.
+
+   When decoding, each temporal layer can be extracted from the coded stream and decoded separately. The mfxExtVP9TemporalLayers structure
+   configures the temporal layers for the VP9 encoder. It can be attached to the mfxVideoParam structure during initialization or the
+   MFXVideoENCODE_Reset call. If the mfxExtVP9TemporalLayers buffer isn’t attached during initialization, temporal scalability is disabled. If the buffer isn’t attached for the Reset call, the encoder continues to use the temporal scalability configuration that was defined before the Reset call.
+
+   In the API, temporal layers are ordered by their frame rates in ascending order. Temporal layer 0 (having the lowest frame rate) is called the base layer.
+   Each subsequent temporal layer includes all previous layers.
+
+   The temporal scalability feature requires a minimum number of allocated reference
+   frames (controlled by the NumRefFrame parameter). If the NumRefFrame value set by the application isn’t enough to build the reference structure for the requested
+   number of temporal layers, the library corrects the NumRefFrame value. The temporal layer structure is reset (re-started) after key-frames.
+*/
+typedef struct {
+    mfxExtBuffer        Header;   /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VP9_TEMPORAL_LAYERS. */
+    /*!
+       The array of temporal layers. Layer[0] specifies the base layer.
+
+       The library reads layers from the array when they are defined (FrameRateScale > 0).
+       All layers starting from first layer with FrameRateScale = 0 are ignored. The last layer that is not ignored is considered the “highest layer”.
+
+       The frame rate of the highest layer is specified in the mfxVideoParam structure. Frame rates of lower layers are calculated using their FrameRateScale.
+
+       TargetKbps of the highest layer should be equal to the TargetKbps value specified in the mfxVideoParam structure. If it is not true, TargetKbps of highest temporal layers has priority.
+
+       If there are no defined layers in the Layer array, the temporal scalability feature is disabled. For example, to disable temporal scalability in runtime, the application should
+       pass mfxExtVP9TemporalLayers buffer to Reset with all FrameRateScales set to 0.
+    */
+    mfxVP9TemporalLayer Layer[8];
+    mfxU16              reserved[60];
+} mfxExtVP9TemporalLayers;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Structure attached to the mfxVideoParam structure. Extends the mfxVideoParam structure with VP9-specific parameters. Used by both decoder and encoder.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VP9_PARAM. */
+
+    mfxU16  FrameWidth;      /*!< Width of the coded frame in pixels. */
+    mfxU16  FrameHeight;     /*!< Height of the coded frame in pixels. */
+
+    mfxU16  WriteIVFHeaders; /*!< Set this option to ON to make the encoder insert IVF container headers to the output stream. The NumFrame field of the IVF
+                                  sequence header will be zero. It is the responsibility of the application to update the NumFrame field  with the correct value. See the
+                                  CodingOptionValue enumerator for values of this option. */
+
+    mfxI16  reserved1[6];
+    mfxI16  QIndexDeltaLumaDC;   /*!< Specifies an offset for a particular quantization parameter. */
+    mfxI16  QIndexDeltaChromaAC; /*!< Specifies an offset for a particular quantization parameter. */
+    mfxI16  QIndexDeltaChromaDC; /*!< Specifies an offset for a particular quantization parameter. */
+    /*!
+       Number of tile rows. Should be power of two. The maximum number of tile rows is 4, per the VP9 specification. In addition, the maximum supported number
+       of tile rows may depend on the underlying library implementation.
+
+       Use the Query API function to check if a particular pair of values (NumTileRows, NumTileColumns)
+       is supported. In VP9, tile rows have dependencies and cannot be encoded or decoded in parallel. Therefore, tile rows are always encoded by the library in
+       serial mode (one-by-one).
+    */
+    mfxU16  NumTileRows;
+    /*!
+       Number of tile columns. Should be power of two. Restricted with maximum and minimum tile width in luma pixels, as defined in the VP9
+       specification (4096 and 256 respectively). In addition, the maximum supported number of tile columns may depend on the underlying library
+       implementation.
+
+       Use the Query API function to check if a particular pair of values (NumTileRows, NumTileColumns) is supported. In VP9,  tile columns do not have
+       dependencies and can be encoded/decoded in parallel. Therefore, tile columns can be encoded by the library in both parallel and serial modes.
+
+       Parallel mode is automatically utilized by the library when NumTileColumns exceeds 1 and does not exceed the number of tile coding engines on the
+       platform. In other cases, serial mode is used. Parallel mode is capable of encoding more than 1 tile row (within limitations provided by VP9
+       specification and particular platform). Serial mode supports only tile grids 1xN and Nx1.
+    */
+    mfxU16  NumTileColumns;
+    mfxU16  reserved[110];
+} mfxExtVP9Param;
+MFX_PACK_END()
+
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used to report encoded unit information.
+*/
+typedef struct {
+    mfxU16 Type;      /*!< Codec-dependent coding unit type (NALU type for AVC/HEVC, start_code for MPEG2 etc). */
+    mfxU16 reserved1;
+    mfxU32 Offset;    /*!< Offset relative to the associated mfxBitstream::DataOffset. */
+    mfxU32 Size;      /*!< Unit size, including delimiter. */
+    mfxU32 reserved[5];
+} mfxEncodedUnitInfo;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_L_TYPE()
+/*!
+   If mfxExtCodingOption3::EncodedUnitsInfo was set to MFX_CODINGOPTION_ON during encoder initialization, the mfxExtEncodedUnitsInfo structure is
+   attached to the mfxBitstream structure during encoding. It is used to report information about coding units in the resulting bitstream.
+
+   The number of filled items in UnitInfo is min(NumUnitsEncoded, NumUnitsAlloc).
+
+   For counting a minimal amount of encoded units you can use the following algorithm:
+   @code
+      nSEI = amountOfApplicationDefinedSEI;
+      if (CodingOption3.NumSlice[IPB] != 0 || mfxVideoParam.mfx.NumSlice != 0)
+        ExpectedAmount = 10 + nSEI + Max(CodingOption3.NumSlice[IPB], mfxVideoParam.mfx.NumSlice);
+      else if (CodingOption2.NumMBPerSlice != 0)
+        ExpectedAmount = 10 + nSEI + (FrameWidth * FrameHeight) / (256 * CodingOption2.NumMBPerSlice);
+      else if (CodingOption2.MaxSliceSize != 0)
+        ExpectedAmount = 10 + nSEI + Round(MaxBitrate / (FrameRate*CodingOption2.MaxSliceSize));
+      else
+        ExpectedAmount = 10 + nSEI;
+
+      if (mfxFrameInfo.PictStruct != MFX_PICSTRUCT_PROGRESSIVE)
+        ExpectedAmount = ExpectedAmount * 2;
+
+      if (temporalScaleabilityEnabled)
+        ExpectedAmount = ExpectedAmount * 2;
+    @endcode
+    @note Only supported by the AVC encoder.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ENCODED_UNITS_INFO. */
+
+    union {
+        mfxEncodedUnitInfo *UnitInfo; /*!< Pointer to an array of mfxEncodedUnitsInfo structures whose size is equal to or greater than NumUnitsAlloc. */
+        mfxU64  reserved1;
+    };
+    mfxU16 NumUnitsAlloc;             /*!< UnitInfo array size. */
+    mfxU16 NumUnitsEncoded;           /*!< Output field. Number of coding units to report. If NumUnitsEncoded is greater than NumUnitsAlloc, the UnitInfo
+                                           array will contain information only for the first NumUnitsAlloc units. User may consider reallocating the
+                                           UnitInfo array to avoid this for subsequent frames. */
+
+    mfxU16 reserved[22];
+} mfxExtEncodedUnitsInfo;
+MFX_PACK_END()
+
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Provides setup for the Motion-Compensated Temporal Filter (MCTF) during the VPP initialization and for control
+   parameters at runtime. By default, MCTF is off. An application may enable it by adding MFX_EXTBUFF_VPP_MCTF to the mfxExtVPPDoUse buffer or by
+   attaching mfxExtVppMctf to the mfxVideoParam structure during initialization or reset.
+*/
+typedef struct {
+    mfxExtBuffer Header;         /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VPP_MCTF. */
+    mfxU16       FilterStrength; /*!< Value in range of 0 to 20 (inclusive) to indicate the filter strength of MCTF.
+
+                                    The strength of the MCTF process controls the degree of possible change of pixel values eligible for MCTF - the greater the strength value, the larger the change. It is a dimensionless quantity - values in the range of 1 to 20 inclusively imply strength; value 0 stands for AUTO mode and is
+                                      valid during initialization or reset only
+
+                                    If an invalid value is given, it is fixed to the default value of 0.
+                                      If the field value is in the range of 1 to 20 inclusive, MCTF operates in fixed-strength mode with the given strength of MCTF process.
+
+                                      At runtime, values of 0 and greater than 20 are ignored. */
+    mfxU16       reserved[27];
+} mfxExtVppMctf;
+MFX_PACK_END()
+
+/*! Describes type of workload passed to MFXQueryAdapters. */
+typedef enum
+{
+    MFX_COMPONENT_ENCODE = 1, /*!< Encode workload. */
+    MFX_COMPONENT_DECODE = 2, /*!< Decode workload. */
+    MFX_COMPONENT_VPP    = 3  /*!< VPP workload. */
+} mfxComponentType;
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Contains workload description, which is accepted by MFXQueryAdapters function.
+*/
+typedef struct
+{
+    mfxComponentType Type;         /*!< Type of workload: Encode, Decode, VPP. See mfxComponentType enumerator for values. */
+    mfxVideoParam    Requirements; /*!< Detailed description of workload. See mfxVideoParam for details. */
+
+    mfxU16           reserved[4];
+} mfxComponentInfo;
+MFX_PACK_END()
+
+/* Adapter description */
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Contains a description of the graphics adapter for the Legacy mode.
+*/
+typedef struct
+{
+    mfxPlatform Platform; /*!< Platform type description. See mfxPlatform for details. */
+    mfxU32      Number;   /*!< Value which uniquely characterizes media adapter. On Windows* this number can be used for initialization through
+                               DXVA interface (see <a href="https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgifactory1-enumadapters1">example</a>). */
+
+    mfxU16      reserved[14];
+} mfxAdapterInfo;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Contains description of all graphics adapters available on the current system.
+*/
+typedef struct
+{
+    mfxAdapterInfo * Adapters;  /*!< Pointer to array of mfxAdapterInfo structs allocated by user. */
+    mfxU32           NumAlloc;  /*!< Length of Adapters array. */
+    mfxU32           NumActual; /*!< Number of Adapters entries filled by MFXQueryAdapters. */
+
+    mfxU16           reserved[4];
+} mfxAdaptersInfo;
+MFX_PACK_END()
+
+
+/*! The PartialBitstreamOutput enumerator indicates flags of partial bitstream output type. */
+enum {
+    MFX_PARTIAL_BITSTREAM_NONE    = 0, /*!< Do not use partial output */
+    MFX_PARTIAL_BITSTREAM_SLICE   = 1, /*!< Partial bitstream output will be aligned to slice granularity */
+    MFX_PARTIAL_BITSTREAM_BLOCK   = 2, /*!< Partial bitstream output will be aligned to user-defined block size granularity */
+    MFX_PARTIAL_BITSTREAM_ANY     = 3  /*!< Partial bitstream output will be return any coded data available at the end of SyncOperation timeout */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+   Used by an encoder to output parts of the bitstream as soon as they are ready. The application can attach this extended buffer to the
+   mfxVideoParam structure at initialization. If this option is turned ON (Granularity != MFX_PARTIAL_BITSTREAM_NONE), then the encoder can output
+   bitstream by part based on the required granularity.
+
+   This parameter is valid only during initialization and reset. Absence of this buffer means default or previously configured bitstream output
+   behavior.
+
+   @note Not all codecs and implementations support this feature. Use the Query API function to check if this feature is supported.
+*/
+typedef struct {
+    mfxExtBuffer    Header;      /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_PARTIAL_BITSTREAM_PARAM. */
+    mfxU32          BlockSize;   /*!< Output block granularity for PartialBitstreamGranularity. Valid only for MFX_PARTIAL_BITSTREAM_BLOCK. */
+    mfxU16          Granularity; /*!< Granularity of the partial bitstream: slice/block/any, all types of granularity state in PartialBitstreamOutput enum. */
+    mfxU16          reserved[8];
+} mfxExtPartialBitstreamParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   The mfxExtDeviceAffinityMask structure is used by the application to specify
+   affinity mask for the device with given device ID. See mfxDeviceDescription
+   for the device ID definition and sub device indexes. If the implementation
+   manages CPU threads for some purpose, the user can set the CPU thread affinity
+   mask by using this structure with DeviceID set to "CPU".
+*/
+typedef struct {
+    /*! Extension buffer header. Header.BufferId must be equal to
+        MFX_EXTBUFF_DEVICE_AFFINITY_MASK. */
+    mfxExtBuffer    Header;
+    /*! Null terminated string with device ID. In case of CPU affinity mask
+        it must be equal to "CPU". */
+    mfxChar         DeviceID[MFX_STRFIELD_LEN];
+    /*! Number of sub devices or threads in case of CPU in the mask. */
+    mfxU32          NumSubDevices;
+    /*! Mask array. Every bit represents sub-device (or thread for CPU).
+        "1" means execution is allowed. "0" means that execution is prohibited on
+        this sub-device (or thread). Length of the array is equal to the:
+        "max_subdevices / 8" and rounded to the closest (from the right) integer.
+        Bits order within each entry of the mask array is LSB: bit 0 holds data
+        for sub device with index 0 and bit 8 for sub device with index 8.
+        Index of sub device is defined by the mfxDeviceDescription structure. */
+    mfxU8           *Mask;
+    mfxU32           reserved[4]; /*! Reserved for future use. */
+} mfxExtDeviceAffinityMask;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The structure is used by AV1 encoder with more parameter control to encode frame. */
+typedef struct {
+    mfxExtBuffer Header;   /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AV1_BITSTREAM_PARAM. */
+
+    mfxU16 WriteIVFHeaders; /*!< Tri-state option to control IVF headers insertion, default is ON.
+                                Writing IVF headers is enabled in the encoder when mfxExtAV1BitstreamParam is attached and its value is ON or zero.
+                                Writing IVF headers is disabled by default in the encoder when mfxExtAV1BitstreamParam is not attached. */
+
+    mfxU16 reserved[31];
+} mfxExtAV1BitstreamParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The structure is used by AV1 encoder with more parameter control to encode frame. */
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AV1_RESOLUTION_PARAM. */
+
+    mfxU32 FrameWidth;   /*!< Width of the coded frame in pixels, default value is from mfxFrameInfo. */
+    mfxU32 FrameHeight;  /*!< Height of the coded frame in pixels, default value is from mfxFrameInfo. */
+
+    mfxU32 reserved[6];
+} mfxExtAV1ResolutionParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+  /*! The structure is used by AV1 encoder with more parameter control to encode frame. */
+typedef struct {
+    mfxExtBuffer Header;   /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AV1_TILE_PARAM. */
+
+    mfxU16 NumTileRows;    /*!< Number of tile rows, default value is 1. */
+    mfxU16 NumTileColumns; /*!< Number of tile columns, default value is 1. */
+    mfxU16 NumTileGroups;  /*!< Number of tile groups, it will be ingored if the tile groups num is invalid, default value is 1. */
+
+    mfxU16 reserved[5];
+} mfxExtAV1TileParam;
+MFX_PACK_END()
+
+/*!
+    The AV1 SegmentIdBlockSize enumerator indicates the block size represented by each segment_id in segmentation map.
+    These values are used with the mfxExtAV1Segmentation::SegmentIdBlockSize parameter.
+*/
+typedef enum {
+    MFX_AV1_SEGMENT_ID_BLOCK_SIZE_UNSPECIFIED = 0,  /*!< Unspecified block size. */
+    MFX_AV1_SEGMENT_ID_BLOCK_SIZE_4x4         = 4,  /*!< block size 4x4 */
+    MFX_AV1_SEGMENT_ID_BLOCK_SIZE_8x8         = 8,  /*!< block size 8x8 */
+    MFX_AV1_SEGMENT_ID_BLOCK_SIZE_16x16       = 16, /*!< block size 16x16 */
+    MFX_AV1_SEGMENT_ID_BLOCK_SIZE_32x32       = 32, /*!< block size 32x32 */
+    MFX_AV1_SEGMENT_ID_BLOCK_SIZE_64x64       = 64, /*!< block size 64x64 */
+    MFX_AV1_SEGMENT_ID_BLOCK_SIZE_128x128     = 128 /*!< block size 128x128 */
+} mfxAV1SegmentIdBlockSize;
+
+/*!
+    The AV1 SegmentFeature enumerator indicates features enabled for the segment.
+    These values are used with the mfxAV1SegmentParam::FeatureEnabled parameter.
+*/
+enum {
+    MFX_AV1_SEGMENT_FEATURE_ALT_QINDEX    = 0x0001, /*!< use alternate Quantizer. */
+    MFX_AV1_SEGMENT_FEATURE_ALT_LF_Y_VERT = 0x0002, /*!< use alternate loop filter value on y plane vertical. */
+    MFX_AV1_SEGMENT_FEATURE_ALT_LF_Y_HORZ = 0x0004, /*!< use alternate loop filter value on y plane horizontal. */
+    MFX_AV1_SEGMENT_FEATURE_ALT_LF_U      = 0x0008, /*!< use alternate loop filter value on u plane. */
+    MFX_AV1_SEGMENT_FEATURE_ALT_LF_V      = 0x0010, /*!< use alternate loop filter value on v plane. */
+    MFX_AV1_SEGMENT_FEATURE_REFERENCE     = 0x0020, /*!< use segment reference frame. */
+    MFX_AV1_SEGMENT_FEATURE_SKIP          = 0x0040, /*!< use segment (0,0) + skip mode. */
+    MFX_AV1_SEGMENT_FEATURE_GLOBALMV      = 0x0080  /*!< use global motion vector. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*!
+    Contains features and parameters for the segment.
+*/
+typedef struct {
+    mfxU16 FeatureEnabled;  /*!< Indicates which features are enabled for the segment. See the AV1 SegmentFeature enumerator for values for
+                                this option. Values from the enumerator can be bit-OR’ed. Support of a particular feature depends on underlying
+                                hardware platform. Application can check which features are supported by calling Query. */
+    mfxI16 AltQIndex;       /*!< Quantization index delta for the segment. Ignored if MFX_AV1_SEGMENT_FEATURE_ALT_QINDEX isn’t set in FeatureEnabled.
+                                Valid range for this parameter is [-255, 255]. If AltQIndex is out of this range, it will be ignored. If AltQIndex
+                                is within valid range, but sum of base quantization index and AltQIndex is out of [0, 255], AltQIndex will be clamped. */
+    mfxU16 reserved[30];
+} mfxAV1SegmentParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+    In the AV1 encoder it is possible to divide a frame into up to 8 segments and apply particular features (like delta for quantization index or for
+    loop filter level) on a per-segment basis. “Uncompressed header” of every frame indicates if segmentation is enabled for the current frame,
+    and (if segmentation enabled) contains full information about features applied to every segment. Every “Mode info block” of a coded
+    frame has segment_id in the range of 0 to 7.
+    To enable Segmentation, the mfxExtAV1Segmentation structure with correct settings should be passed to the encoder. It can be attached to the
+    mfxVideoParam structure during initialization or the MFXVideoENCODE_Reset call (static configuration). If the mfxExtAV1Segmentation buffer isn’t
+    attached during initialization, segmentation is disabled for static configuration. If the buffer isn’t attached for the Reset call, the encoder
+    continues to use static configuration for segmentation which was the default before this Reset call. If the mfxExtAV1Segmentation buffer with
+    NumSegments=0 is provided during initialization or Reset call, segmentation becomes disabled for static configuration.
+    The buffer can be attached to the mfxEncodeCtrl structure during runtime (dynamic configuration). Dynamic configuration is applied to the
+    current frame only. After encoding of the current frame, the encoder will switch to the next dynamic configuration or to static configuration if
+    dynamic configuration is not provided for next frame).
+    The SegmentIdBlockSize, NumSegmentIdAlloc, and SegmentId parameters represent a segmentation map. Here, the segmentation map is an array of
+    segment_ids (one byte per segment_id) for blocks of size NxN in raster scan order. The size NxN is specified by the application and is constant
+    for the whole frame.
+    If mfxExtAV1Segmentation is attached during initialization and/or during runtime, all three parameters should be set to proper values that do not
+    conflict with each other and with NumSegments. If any of the parameters are not set or any conflict or error in these parameters is detected by
+    the library, the segmentation map will be discarded.
+*/
+typedef struct {
+    mfxExtBuffer       Header;            /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AV1_SEGMENTATION. */
+    mfxU8              NumSegments;       /*!< Number of segments for frame. Value 0 means that segmentation is disabled. Sending 0 for a
+                                                particular frame will disable segmentation for this frame only. Sending 0 to the Reset API function will
+                                                disable segmentation permanently. Segmentation can be enabled again by a subsequent Reset call. */
+    mfxU8              reserved1[3];
+    mfxAV1SegmentParam Segment[8];        /*!< Array of mfxAV1SegmentParam structures containing features and parameters for every segment.
+                                                Entries with indexes bigger than NumSegments-1 are ignored. See the mfxAV1SegmentParam structure for
+                                                definitions of segment features and their parameters. */
+    mfxU16             SegmentIdBlockSize;/*!< Size of block (NxN) for segmentation map. See AV1 SegmentIdBlockSize enumerator for values for this
+                                                option. An encoded block that is bigger than AV1 SegmentIdBlockSize uses segment_id taken from it’s
+                                                top-left sub-block from the segmentation map. The application can check if a particular block size is
+                                                supported by calling Query. */
+    mfxU16             reserved2;
+    mfxU32             NumSegmentIdAlloc; /*!< Size of buffer allocated for segmentation map (in bytes). Application must assure that
+                                                NumSegmentIdAlloc is large enough to cover frame resolution with blocks of size SegmentIdBlockSize.
+                                                Otherwise the segmentation map will be discarded. */
+    mfxU8 *            SegmentIds;        /*!< Pointer to the segmentation map buffer which holds the array of segment_ids in raster scan order. The application
+                                                is responsible for allocation and release of this memory. The buffer pointed to by SegmentId, provided during
+                                                initialization or Reset call should be considered in use until another SegmentId is provided via Reset
+                                                call (if any), or until MFXVideoENCODE_Close is called. The buffer pointed to by SegmentId provided with
+                                                mfxEncodeCtrl should be considered in use while the input surface is locked by the library. Every segment_id in the
+                                                map should be in the range of 0 to NumSegments-1. If some segment_id is out of valid range, the
+                                                segmentation map cannot be applied. If the mfxExtAV1Segmentation buffer is attached to the mfxEncodeCtrl structure in
+                                                runtime, SegmentId can be zero. In this case, the segmentation map from static configuration will be used. */
+    mfxU16             reserved[36];
+} mfxExtAV1Segmentation;
+MFX_PACK_END()
+
+/*! The FilmGrainFlags enumerator itemizes flags in AV1 film grain parameters.
+    The flags are equivalent to respective syntax elements from film_grain_params() section of uncompressed header. */
+enum {
+    MFX_FILM_GRAIN_NO                       =       0, /*!< Film grain isn't added to this frame. */
+    MFX_FILM_GRAIN_APPLY                    = (1 << 0), /*!< Film grain is added to this frame. */
+    MFX_FILM_GRAIN_UPDATE                   = (1 << 1), /*!< New set of film grain parameters is sent for this frame. */
+    MFX_FILM_GRAIN_CHROMA_SCALING_FROM_LUMA = (1 << 2), /*!< Chroma scaling is inferred from luma scaling. */
+    MFX_FILM_GRAIN_OVERLAP                  = (1 << 3), /*!< Overlap between film grain blocks is applied. */
+    MFX_FILM_GRAIN_CLIP_TO_RESTRICTED_RANGE = (1 << 4) /*!< Clipping to the restricted (studio) range is applied after adding the film grain. */
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Defines film grain point. */
+typedef struct {
+    mfxU8 Value; /*!<  The x coordinate for the i-th point of the piece-wise linear scaling function for luma/Cb/Cr component. */
+    mfxU8 Scaling; /*!<  The scaling (output) value for the i-th point of the piecewise linear scaling function for luma/Cb/Cr component. */
+} mfxAV1FilmGrainPoint;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The structure is used by AV-1 decoder to report film grain parameters for decoded frame. */
+typedef struct {
+    mfxExtBuffer Header;    /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_AV1_FILM_GRAIN_PARAM. */
+
+    mfxU16 FilmGrainFlags;  /*!< Bit map with bit-ORed flags from FilmGrainFlags enum. */
+    mfxU16 GrainSeed;       /*!< Starting value for pseudo-random numbers used during film grain synthesis. */
+
+    mfxU8  RefIdx;          /*!< Indicate which reference frame contains the film grain parameters to be used for this frame. */
+    mfxU8  NumYPoints;      /*!< The number of points for the piece-wise linear scaling function of the luma component. */
+    mfxU8  NumCbPoints;     /*!< The number of points for the piece-wise linear scaling function of the Cb component. */
+    mfxU8  NumCrPoints;     /*!< The number of points for the piece-wise linear scaling function of the Cr component.*/
+
+    mfxAV1FilmGrainPoint PointY[14]; /*!< The array of points for luma component. */
+    mfxAV1FilmGrainPoint PointCb[10]; /*!< The array of points for Cb component. */
+    mfxAV1FilmGrainPoint PointCr[10]; /*!< The array of points for Cr component. */
+
+    mfxU8 GrainScalingMinus8; /*!< The shift – 8 applied to the values of the chroma component. The grain_scaling_minus_8 can take values of 0..3 and
+                                   determines the range and quantization step of the standard deviation of film grain.*/
+    mfxU8 ArCoeffLag;         /*!< The number of auto-regressive coefficients for luma and chroma.*/
+
+    mfxU8 ArCoeffsYPlus128[24];  /*!< Auto-regressive coefficients used for the Y plane. */
+    mfxU8 ArCoeffsCbPlus128[25]; /*!< Auto-regressive coefficients used for the Cb plane. */
+    mfxU8 ArCoeffsCrPlus128[25]; /*!< The number of points for the piece-wise linear scaling function of the Cr component.*/
+
+    mfxU8 ArCoeffShiftMinus6;  /*!< The range of the auto-regressive coefficients.
+                                    Values of 0, 1, 2, and 3 correspond to the ranges for auto-regressive coefficients of
+                                    [-2, 2), [-1, 1), [-0.5, 0.5) and [-0.25, 0.25) respectively.*/
+    mfxU8 GrainScaleShift;     /*!< Downscaling factor of the grain synthesis process for the Gaussian random numbers .*/
+
+    mfxU8  CbMult;     /*!< The multiplier for the Cb component used in derivation of the input index to the Cb component scaling function.*/
+    mfxU8  CbLumaMult; /*!< The multiplier for the average luma component used in derivation of the input index to the Cb component scaling function. */
+    mfxU16 CbOffset;   /*!< The offset used in derivation of the input index to the Cb component scaling function.*/
+
+    mfxU8  CrMult;     /*!< The multiplier for the Cr component used in derivation of the input index to the Cr component scaling function.*/
+    mfxU8  CrLumaMult; /*!< The multiplier for the average luma component used in derivation of the input index to the Cr component scaling function.*/
+    mfxU16 CrOffset;   /*!< The offset used in derivation of the input index to the Cr component scaling function.*/
+
+    mfxU16 reserved[43];
+} mfxExtAV1FilmGrainParam;
+MFX_PACK_END()
+
+#define MFX_SURFACEARRAY_VERSION MFX_STRUCT_VERSION(1, 0)
+
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! The structure is reference counted object to return array of surfaces allocated and processed by the library. */
+typedef struct mfxSurfaceArray
+{
+    mfxHDL              Context; /*!< The context of the memory interface. User should not touch (change, set, null) this pointer. */
+    mfxStructVersion    Version; /*!< The version of the structure. */
+    mfxU16 reserved[3];
+    /*! @brief
+    Increments the internal reference counter of the surface. The surface is not destroyed until the surface is released using the mfxSurfaceArray::Release function.
+    mfxSurfaceArray::AddRef should be used each time a new link to the surface is created (for example, copy structure) for proper surface management.
+
+    @param[in]  surface  Valid mfxSurfaceArray.
+
+    @return
+     MFX_ERR_NONE              If no error. \n
+     MFX_ERR_NULL_PTR          If surface is NULL. \n
+     MFX_ERR_INVALID_HANDLE    If mfxSurfaceArray->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN           Any internal error.
+
+    */
+    mfxStatus (MFX_CDECL *AddRef)(struct mfxSurfaceArray*  surface_array);
+    /*! @brief
+    Decrements the internal reference counter of the surface. mfxSurfaceArray::Release should be called after
+    using the mfxSurfaceArray::AddRef function to add a surface or when allocation logic requires it.
+
+    @param[in]  surface_array  Valid mfxSurfaceArray.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If surface is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfaceArray->Context is invalid (for example NULL). \n
+     MFX_ERR_UNDEFINED_BEHAVIOR If Reference Counter of surface is zero before call. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus (MFX_CDECL *Release)(struct mfxSurfaceArray*  surface_array);
+
+    /*! @brief
+    Returns current reference counter of mfxSurfaceArray structure.
+
+    @param[in]   surface  Valid surface_array.
+    @param[out]  counter  Sets counter to the current reference counter value.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If surface or counter is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfaceArray->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus (MFX_CDECL *GetRefCounter)(struct mfxSurfaceArray*  surface_array, mfxU32* counter);
+
+    mfxFrameSurface1** Surfaces; /*!< The array of pointers to mfxFrameSurface1. mfxFrameSurface1 surfaces are allocated by the same
+    agent who allocates mfxSurfaceArray. */
+    mfxU32 NumSurfaces; /*!<The size of array of pointers to mfxFrameSurface1. */
+    mfxU32 reserved1;
+} mfxSurfaceArray;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! The structure is used for VPP channels initializtion in Decode_VPP component.  */
+typedef struct {
+    mfxFrameInfo  VPP; /*!< The configuration parameters of VPP filters per each channel. */
+    mfxU16  Protected; /*!< Specifies the content protection mechanism. */
+    mfxU16  IOPattern; /*!< Output memory access types for SDK functions. */
+    mfxExtBuffer** ExtParam; /*!< Points to an array of pointers to the extra configuration structures; see the ExtendedBufferID enumerator for a list of extended configurations. */
+    mfxU16  NumExtParam; /*!< The number of extra configuration structures attached to the structure. */
+    mfxU16  reserved1[7];
+} mfxVideoChannelParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The structure describes rectangle coordinates wat can bse used for ROI or for Cropping. */
+    typedef struct {
+        mfxU16  Left;   /*!< X coordinate of region of top-left corner of rectangle. */
+        mfxU16  Top;    /*!< Y coordinate of region of top-left corner of rectangle. */
+        mfxU16  Right;  /*!< X coordinate of region of bottom-right corner of rectangle. */
+        mfxU16  Bottom; /*!< Y coordinate of region of bottom-right corner of rectangle. */
+    } mfxRect;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The structure contains crop parameters which applied by Decode_VPP component to input surfaces before video processing operation.
+    It is used for letterboxing operations.
+*/
+typedef struct {
+    mfxExtBuffer     Header; /*! Extension buffer header. BufferId must be equal to MFX_EXTBUFF_CROPS. */
+    mfxRect          Crops;  /*!< Crops parameters for letterboxing operations. */
+    mfxU32           reserved[4];
+}mfxExtInCrops;
+MFX_PACK_END()
+
+/*! The mfxHyperMode enumerator describes HyperMode implementation behavior. */
+typedef enum {
+    MFX_HYPERMODE_OFF = 0x0,        /*!< Don't use HyperMode implementation. */
+    MFX_HYPERMODE_ON = 0x1,         /*!< Enable HyperMode implementation and return error if some issue on initialization. */
+    MFX_HYPERMODE_ADAPTIVE = 0x2,   /*!< Enable HyperMode implementation and switch to single fallback if some issue on initialization. */
+} mfxHyperMode;
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The structure is used for HyperMode initialization. */
+typedef struct {
+    mfxExtBuffer    Header; /*!< Extension buffer header. BufferId must be equal to MFX_EXTBUFF_HYPER_MODE_PARAM. */
+    mfxHyperMode    Mode;   /*!< HyperMode implementation behavior. */
+    mfxU16          reserved[19];
+} mfxExtHyperModeParam;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The structure is used for universal temporal layer description. */
+typedef struct {
+    mfxU16 FrameRateScale;  /*!< The ratio between the frame rates of the current temporal layer and the base layer. The library treats a particular
+                                 temporal layer as “defined” if it has FrameRateScale > 0. If the base layer is defined, it must have FrameRateScale = 1. 
+                                 FrameRateScale of each subsequent layer (if defined) must be a multiple of and greater than the
+                                 FrameRateScale value of previous layer. */
+    mfxU16  reserved[3]; /*!< Reserved for future use. */
+                                 
+    union {
+          /*!< Type of bitrate controls is currently the same across all temporal layers and inherits from common parameters. */ 
+          struct {
+            mfxU32  InitialDelayInKB;/*!< Initial size of the Video Buffering Verifier (VBV) buffer for the current temporal layer.
+                                          @note In this context, KB is 1000 bytes and Kbps is 1000 bps. */
+            mfxU32  BufferSizeInKB; /*!< Represents the maximum possible size of any compressed frames for the current temporal layer. */
+            mfxU32  TargetKbps;  /*!< Target bitrate for the current temporal layer. If RateControlMethod is not CQP, the
+                                      application can provide TargetKbps for every defined temporal layer. If TargetKbps per temporal layer is not set then 
+                                      encoder doesn't apply any special bitrate limitations for the layer.  */
+            mfxU32  MaxKbps;  /*!< The maximum bitrate at which the encoded data enters the Video Buffering Verifier (VBV) buffer for the current temporal layer. */
+
+            mfxU32  reserved1[16]; /*!< Reserved for future use. */
+            
+          };
+          struct {
+            mfxI32  QPI;  /*!< Quantization Parameter (QP) for I-frames for constant QP mode (CQP) for the current temporal layer. Zero QP is not valid and means that the default value is assigned by the library.
+                    Non-zero QPI might be clipped to supported QPI range. 
+                    @note Default QPI value is implementation dependent and subject to change without additional notice in this document. */
+            mfxI32  QPP;  /*!< Quantization Parameter (QP) for P-frames for constant QP mode (CQP) for the current temporal layer. Zero QP is not valid and means that the default value is assigned by the library.
+                    Non-zero QPP might be clipped to supported QPI range.
+                    @note Default QPP value is implementation dependent and subject to change without additional notice in this document. */
+            mfxI32  QPB; /*!< Quantization Parameter (QP) for B-frames for constant QP mode (CQP) for the current temporal layer. Zero QP is not valid and means that the default value is assigned by the library.
+                    Non-zero QPI might be clipped to supported QPB range.
+                    @note Default QPB value is implementation dependent and subject to change without additional notice in this document. */
+          };
+    };
+    mfxU16  reserved2[4]; /*!< Reserved for future use. */
+    
+} mfxTemporalLayer;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! The structure is used for universal temporal layers description. */
+typedef struct {
+    mfxExtBuffer     Header;     /*! Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_UNIVERSAL_TEMPORAL_LAYERS. */
+    mfxU16           NumLayers; /*!< The  number of temporal layers. */
+    mfxU16           BaseLayerPID; /*!< The priority ID of the base layer. The encoder increases the ID for each temporal layer and writes to the prefix NAL unit for AVC and HEVC. */
+    mfxU16           reserved[2]; /*!< Reserved for future use. */
+    mfxTemporalLayer *Layers; /*!< The array of temporal layers. */
+    
+    mfxU16 reserved1[8]; /*!< Reserved for future use. */
+} mfxExtTemporalLayers;
+MFX_PACK_END()
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxsurfacepool.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxsurfacepool.h
new file mode 100644 (file)
index 0000000..a8908a6
--- /dev/null
@@ -0,0 +1,183 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFX_SURFACE_POOL_H__
+#define __MFX_SURFACE_POOL_H__
+
+#include "mfxstructures.h"
+
+/*! GUID to obtain mfxSurfacePoolInterface. */
+static const mfxGUID  MFX_GUID_SURFACE_POOL        = {{0x35, 0x24, 0xf3, 0xda, 0x96, 0x4e, 0x47, 0xf1, 0xaf, 0xb4, 0xec, 0xb1, 0x15, 0x08, 0x06, 0xb1}};
+
+//*! Specifies type of pool for VPP component. */
+typedef enum {
+    MFX_VPP_POOL_IN  = 0, /*!< Input pool. */
+    MFX_VPP_POOL_OUT = 1  /*!< Output pool. */
+} mfxVPPPoolType;
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! The extension buffer specifies surface pool management policy.
+    Absence of the attached buffer means MFX_ALLOCATION_UNLIMITED policy: 
+    each call of GetSurfaceForXXX leads to surface allocation.
+*/
+typedef struct {
+    mfxExtBuffer Header; /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_ALLOCATION_HINTS. */
+    mfxPoolAllocationPolicy   AllocationPolicy; /*!< Allocation policy. */
+    /*! How many surfaces to allocate during Init. 
+    It's applicable for any polices set by mfxPoolAllocationPolicy::AllocationPolicy 
+    even if the requested number exceeds recommended size of the pool. */
+    mfxU32                    NumberToPreAllocate;
+    /*! DeltaToAllocateOnTheFly specifies how many surfaces are allocated 
+    in addition to NumberToPreAllocate in MFX_ALLOCATION_LIMITED mode. 
+    Maximum number of allocated frames  will be 
+    NumberToPreAllocate + DeltaToAllocateOnTheFly.
+    */
+    mfxU32                    DeltaToAllocateOnTheFly;  
+    union {
+        mfxVPPPoolType            VPPPoolType; /*!< Defines what VPP pool is targeted - input or ouput. Ignored for other components. */
+        mfxU32                    reserved;
+    };
+    mfxU32                    Wait; /*!< Time in milliseconds for GetSurfaceForXXX() and DecodeFrameAsync functions to wait until surface will be available. */
+    mfxU32                    reserved1[4]; /*!< Reserved for future use */
+} mfxExtAllocationHints;
+MFX_PACK_END()
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*! Specifies the surface pool interface. */
+typedef struct mfxSurfacePoolInterface
+{
+    mfxHDL              Context; /*!< The context of the surface pool interface. User should not touch (change, set, null) this pointer. */
+    
+    /*! @brief
+    Increments the internal reference counter of the mfxSurfacePoolInterface. The mfxSurfacePoolInterface is not destroyed until the 
+    mfxSurfacePoolInterface is destroyed with mfxSurfacePoolInterface::Release function. mfxSurfacePoolInterface::AddRef should be used each time a new link to the 
+    mfxSurfacePoolInterface is created for proper management.
+
+    @param[in]  pool  Valid pool.
+
+    @return
+     MFX_ERR_NONE              If no error. \n
+     MFX_ERR_NULL_PTR          If pool is NULL. \n
+     MFX_ERR_INVALID_HANDLE    If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN           Any internal error.
+
+    */
+    mfxStatus           (MFX_CDECL *AddRef)(struct mfxSurfacePoolInterface *pool);
+    /*! @brief
+    Decrements the internal reference counter of the mfxSurfacePoolInterface. mfxSurfacePoolInterface::Release 
+    should be called after using the mfxSurfacePoolInterface::AddRef function to add a mfxSurfacePoolInterface or when allocation logic requires it. 
+    For example, call mfxSurfacePoolInterface::Release to release a mfxSurfacePoolInterface obtained with 
+    the mfxFrameSurfaceInterface::QueryInterface function.
+
+    @param[in]  pool  Valid pool.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If pool is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNDEFINED_BEHAVIOR If Reference Counter of mfxSurfacePoolInterface is zero before call. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *Release)(struct mfxSurfacePoolInterface *pool);
+    /*! @brief
+    Returns current reference counter of mfxSurfacePoolInterface structure.
+
+    @param[in]   pool  Valid pool.
+    @param[out]  counter  Sets counter to the current reference counter value.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If pool or counter is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus           (MFX_CDECL *GetRefCounter)(struct mfxSurfacePoolInterface *pool, mfxU32* counter);
+    /*! @brief
+    The function should be called by oneVPL components or application to specify how many surfaces it will use concurrently.
+    Internally, oneVPL allocates surfaces in the shared pool according to the component's policy set by mfxPoolAllocationPolicy.
+    The exact moment of surfaces allocation is defined by the component and generally independent from that call. 
+
+    @param[in]  pool  Valid pool.
+    @param[in]  num_surfaces  The number of surfaces required by the component.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If pool is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_WRN_INCOMPATIBLE_VIDEO_PARAM If pool has MFX_ALLOCATION_UNLIMITED or MFX_ALLOCATION_LIMITED policy. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus             (MFX_CDECL *SetNumSurfaces)(struct mfxSurfacePoolInterface *pool, mfxU32 num_surfaces); 
+
+    /*! @brief
+    The function should be called by oneVPL components when component is closed or reset and doesn't need to use pool more. It helps
+    to manage memory accordingly and release redundant memory. Important to specify the same number of surfaces which is requested 
+    during SetNumSurfaces call, otherwise it may lead to the pipeline stalls.
+
+    @param[in]  pool  Valid pool.
+    @param[in]  num_surfaces  The number of surfaces used by the component.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+
+     MFX_WRN_OUT_OF_RANGE       If num_surfaces doesn't equal to num_surfaces requested during SetNumSurfaces call. \n
+
+     MFX_ERR_NULL_PTR           If pool is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_WRN_INCOMPATIBLE_VIDEO_PARAM If pool has MFX_ALLOCATION_UNLIMITED or MFX_ALLOCATION_LIMITED policy. \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus               (MFX_CDECL *RevokeSurfaces)(struct mfxSurfacePoolInterface *pool, mfxU32 num_surfaces);                                 
+    /*! @brief
+    Returns current allocation policy.
+
+    @param[in]   pool  Valid pool.
+    @param[out]  policy  Sets policy to the current allocation policy value.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If pool or policy is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus                (MFX_CDECL *GetAllocationPolicy)(struct mfxSurfacePoolInterface *pool, mfxPoolAllocationPolicy *policy);
+    
+    /*! @brief
+    Returns maximum pool size. In case of mfxPoolAllocationPolicy::MFX_ALLOCATION_UNLIMITED policy 0xFFFFFFFF will be returned.
+
+    @param[in]   pool  Valid pool.
+    @param[out]  size  Sets size to the maximum pool size value.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If pool or size is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus                 (MFX_CDECL *GetMaximumPoolSize)(struct mfxSurfacePoolInterface *pool, mfxU32 *size);
+    
+    /*! @brief
+    Returns current pool size.
+
+    @param[in]   pool  Valid pool.
+    @param[out]  size  Sets size to the current pool size value.
+
+    @return
+     MFX_ERR_NONE               If no error. \n
+     MFX_ERR_NULL_PTR           If pool or size is NULL. \n
+     MFX_ERR_INVALID_HANDLE     If mfxSurfacePoolInterface->Context is invalid (for example NULL). \n
+     MFX_ERR_UNKNOWN            Any internal error.
+    */
+    mfxStatus              (MFX_CDECL *GetCurrentPoolSize)(struct mfxSurfacePoolInterface *pool, mfxU32 *size);
+
+    mfxHDL                 reserved[4]; /*!< Reserved for future use. */
+
+} mfxSurfacePoolInterface;
+MFX_PACK_END()
+
+
+#endif /* __MFX_SURFACE_POOL_H__ */
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvideo++.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvideo++.h
new file mode 100644 (file)
index 0000000..3c3ce45
--- /dev/null
@@ -0,0 +1,298 @@
+/*###########################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ###########################################################################*/
+
+#ifndef __MFXVIDEOPLUSPLUS_H
+#define __MFXVIDEOPLUSPLUS_H
+
+#include "mfxvideo.h"
+
+class MFXVideoSession {
+public:
+    MFXVideoSession(void) {
+        m_session = (mfxSession)0;
+    }
+    virtual ~MFXVideoSession(void) {
+        Close();
+    }
+
+    virtual mfxStatus Init(mfxIMPL impl, mfxVersion *ver) {
+        return MFXInit(impl, ver, &m_session);
+    }
+    virtual mfxStatus InitEx(mfxInitParam par) {
+        return MFXInitEx(par, &m_session);
+    }
+    virtual mfxStatus Close(void) {
+        mfxStatus mfxRes;
+        mfxRes    = MFXClose(m_session);
+        m_session = (mfxSession)0;
+        return mfxRes;
+    }
+
+    virtual mfxStatus QueryIMPL(mfxIMPL *impl) {
+        return MFXQueryIMPL(m_session, impl);
+    }
+    virtual mfxStatus QueryVersion(mfxVersion *version) {
+        return MFXQueryVersion(m_session, version);
+    }
+
+    virtual mfxStatus JoinSession(mfxSession child_session) {
+        return MFXJoinSession(m_session, child_session);
+    }
+    virtual mfxStatus DisjoinSession() {
+        return MFXDisjoinSession(m_session);
+    }
+    virtual mfxStatus CloneSession(mfxSession *clone) {
+        return MFXCloneSession(m_session, clone);
+    }
+    virtual mfxStatus SetPriority(mfxPriority priority) {
+        return MFXSetPriority(m_session, priority);
+    }
+    virtual mfxStatus GetPriority(mfxPriority *priority) {
+        return MFXGetPriority(m_session, priority);
+    }
+
+    virtual mfxStatus SetFrameAllocator(mfxFrameAllocator *allocator) {
+        return MFXVideoCORE_SetFrameAllocator(m_session, allocator);
+    }
+    virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl) {
+        return MFXVideoCORE_SetHandle(m_session, type, hdl);
+    }
+    virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *hdl) {
+        return MFXVideoCORE_GetHandle(m_session, type, hdl);
+    }
+    virtual mfxStatus QueryPlatform(mfxPlatform *platform) {
+        return MFXVideoCORE_QueryPlatform(m_session, platform);
+    }
+
+    virtual mfxStatus SyncOperation(mfxSyncPoint syncp, mfxU32 wait) {
+        return MFXVideoCORE_SyncOperation(m_session, syncp, wait);
+    }
+
+    virtual mfxStatus GetSurfaceForEncode(mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForEncode(m_session, output_surf);
+    }
+    virtual mfxStatus GetSurfaceForDecode(mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForDecode(m_session, output_surf);
+    }
+    virtual mfxStatus GetSurfaceForVPP   (mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForVPP   (m_session, output_surf);
+    }
+    virtual mfxStatus GetSurfaceForVPPOut(mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForVPPOut(m_session, output_surf);
+    }
+
+    virtual operator mfxSession(void) {
+        return m_session;
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+private:
+    MFXVideoSession(const MFXVideoSession &);
+    void operator=(MFXVideoSession &);
+};
+
+class MFXVideoENCODE {
+public:
+    explicit MFXVideoENCODE(mfxSession session) {
+        m_session = session;
+    }
+    virtual ~MFXVideoENCODE(void) {
+        Close();
+    }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) {
+        return MFXVideoENCODE_Query(m_session, in, out);
+    }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) {
+        return MFXVideoENCODE_QueryIOSurf(m_session, par, request);
+    }
+    virtual mfxStatus Init(mfxVideoParam *par) {
+        return MFXVideoENCODE_Init(m_session, par);
+    }
+    virtual mfxStatus Reset(mfxVideoParam *par) {
+        return MFXVideoENCODE_Reset(m_session, par);
+    }
+    virtual mfxStatus Close(void) {
+        return MFXVideoENCODE_Close(m_session);
+    }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) {
+        return MFXVideoENCODE_GetVideoParam(m_session, par);
+    }
+    virtual mfxStatus GetEncodeStat(mfxEncodeStat *stat) {
+        return MFXVideoENCODE_GetEncodeStat(m_session, stat);
+    }
+
+    virtual mfxStatus EncodeFrameAsync(mfxEncodeCtrl *ctrl,
+                                       mfxFrameSurface1 *surface,
+                                       mfxBitstream *bs,
+                                       mfxSyncPoint *syncp) {
+        return MFXVideoENCODE_EncodeFrameAsync(m_session, ctrl, surface, bs, syncp);
+    }
+
+    virtual mfxStatus GetSurface(mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForEncode(m_session, output_surf);
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+};
+
+class MFXVideoDECODE {
+public:
+    explicit MFXVideoDECODE(mfxSession session) {
+        m_session = session;
+    }
+    virtual ~MFXVideoDECODE(void) {
+        Close();
+    }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) {
+        return MFXVideoDECODE_Query(m_session, in, out);
+    }
+    virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) {
+        return MFXVideoDECODE_DecodeHeader(m_session, bs, par);
+    }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) {
+        return MFXVideoDECODE_QueryIOSurf(m_session, par, request);
+    }
+    virtual mfxStatus Init(mfxVideoParam *par) {
+        return MFXVideoDECODE_Init(m_session, par);
+    }
+    virtual mfxStatus Reset(mfxVideoParam *par) {
+        return MFXVideoDECODE_Reset(m_session, par);
+    }
+    virtual mfxStatus Close(void) {
+        return MFXVideoDECODE_Close(m_session);
+    }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) {
+        return MFXVideoDECODE_GetVideoParam(m_session, par);
+    }
+
+    virtual mfxStatus GetDecodeStat(mfxDecodeStat *stat) {
+        return MFXVideoDECODE_GetDecodeStat(m_session, stat);
+    }
+    virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) {
+        return MFXVideoDECODE_GetPayload(m_session, ts, payload);
+    }
+    virtual mfxStatus SetSkipMode(mfxSkipMode mode) {
+        return MFXVideoDECODE_SetSkipMode(m_session, mode);
+    }
+    virtual mfxStatus DecodeFrameAsync(mfxBitstream *bs,
+                                       mfxFrameSurface1 *surface_work,
+                                       mfxFrameSurface1 **surface_out,
+                                       mfxSyncPoint *syncp) {
+        return MFXVideoDECODE_DecodeFrameAsync(m_session, bs, surface_work, surface_out, syncp);
+    }
+
+    virtual mfxStatus GetSurface(mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForDecode(m_session, output_surf);
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+};
+
+class MFXVideoVPP {
+public:
+    explicit MFXVideoVPP(mfxSession session) {
+        m_session = session;
+    }
+    virtual ~MFXVideoVPP(void) {
+        Close();
+    }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) {
+        return MFXVideoVPP_Query(m_session, in, out);
+    }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest request[2]) {
+        return MFXVideoVPP_QueryIOSurf(m_session, par, request);
+    }
+    virtual mfxStatus Init(mfxVideoParam *par) {
+        return MFXVideoVPP_Init(m_session, par);
+    }
+    virtual mfxStatus Reset(mfxVideoParam *par) {
+        return MFXVideoVPP_Reset(m_session, par);
+    }
+    virtual mfxStatus Close(void) {
+        return MFXVideoVPP_Close(m_session);
+    }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) {
+        return MFXVideoVPP_GetVideoParam(m_session, par);
+    }
+    virtual mfxStatus GetVPPStat(mfxVPPStat *stat) {
+        return MFXVideoVPP_GetVPPStat(m_session, stat);
+    }
+    virtual mfxStatus RunFrameVPPAsync(mfxFrameSurface1 *in,
+                                       mfxFrameSurface1 *out,
+                                       mfxExtVppAuxData *aux,
+                                       mfxSyncPoint *syncp) {
+        return MFXVideoVPP_RunFrameVPPAsync(m_session, in, out, aux, syncp);
+    }
+
+    virtual mfxStatus GetSurfaceIn(mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForVPP(m_session, output_surf);
+    }
+    virtual mfxStatus GetSurfaceOut(mfxFrameSurface1** output_surf) {
+        return MFXMemory_GetSurfaceForVPPOut(m_session, output_surf);
+    }
+
+    virtual mfxStatus ProcessFrameAsync(mfxFrameSurface1 *in, mfxFrameSurface1 **out) {
+        return MFXVideoVPP_ProcessFrameAsync(m_session, in, out);
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+};
+
+class MFXVideoDECODE_VPP
+{
+public:
+    explicit MFXVideoDECODE_VPP(mfxSession session) { m_session = session; }
+    virtual ~MFXVideoDECODE_VPP(void) {
+        Close();
+    }
+
+    virtual mfxStatus Init(mfxVideoParam* decode_par, mfxVideoChannelParam** vpp_par_array, mfxU32 num_channel_par) {
+        return MFXVideoDECODE_VPP_Init(m_session, decode_par, vpp_par_array, num_channel_par);
+    }
+    virtual mfxStatus Reset(mfxVideoParam* decode_par, mfxVideoChannelParam** vpp_par_array, mfxU32 num_channel_par) {
+        return MFXVideoDECODE_VPP_Reset(m_session, decode_par, vpp_par_array, num_channel_par);
+    }
+    virtual mfxStatus GetChannelParam(mfxVideoChannelParam *par, mfxU32 channel_id) {
+        return MFXVideoDECODE_VPP_GetChannelParam(m_session, par, channel_id);
+    }
+    virtual mfxStatus DecodeFrameAsync(mfxBitstream *bs, mfxU32* skip_channels, mfxU32 num_skip_channels, mfxSurfaceArray **surf_array_out) {
+        return MFXVideoDECODE_VPP_DecodeFrameAsync(m_session, bs, skip_channels, num_skip_channels, surf_array_out);
+    }
+
+    virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) {
+        return MFXVideoDECODE_VPP_DecodeHeader(m_session, bs, par);
+    }
+    virtual mfxStatus Close(void) {
+        return MFXVideoDECODE_VPP_Close(m_session);
+    }
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) {
+        return MFXVideoDECODE_VPP_GetVideoParam(m_session, par);
+    }
+    virtual mfxStatus GetDecodeStat(mfxDecodeStat *stat) {
+        return MFXVideoDECODE_VPP_GetDecodeStat(m_session, stat);
+    }
+    virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) {
+        return MFXVideoDECODE_VPP_GetPayload(m_session, ts, payload);
+    }
+    virtual mfxStatus SetSkipMode(mfxSkipMode mode) {
+        return MFXVideoDECODE_VPP_SetSkipMode(m_session, mode);
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+};
+
+#endif //__MFXVIDEOPLUSPLUS_H
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvideo.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvideo.h
new file mode 100644 (file)
index 0000000..9852ff1
--- /dev/null
@@ -0,0 +1,1134 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXVIDEO_H__
+#define __MFXVIDEO_H__
+#include "mfxsession.h"
+#include "mfxstructures.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+MFX_PACK_BEGIN_STRUCT_W_PTR()
+/*!
+   Describes the API callback functions Alloc, Lock, Unlock, GetHDL, and Free that the
+   implementation might use for allocating internal frames. Applications that operate on OS-specific video surfaces must
+   implement these API callback functions.
+
+   Using the default allocator implies that frame data passes in or out of functions through pointers,
+   as opposed to using memory IDs.
+
+   Behavior is undefined when using an incompletely defined external allocator. 
+   \verbatim embed:rst
+    See the :ref:`Memory Allocation and External Allocators section <mem-alloc-ext-alloc>` for additional information.
+    \endverbatim
+*/
+typedef struct {
+    mfxU32      reserved[4];
+    mfxHDL      pthis;    /*!< Pointer to the allocator object. */
+
+    /*!
+       @brief Allocates surface frames. For decoders, MFXVideoDECODE_Init calls Alloc only once. That call
+              includes all frame allocation requests. For encoders, MFXVideoENCODE_Init calls Alloc twice: once for the
+              input surfaces and again for the internal reconstructed surfaces.
+
+              If two library components must share DirectX* surfaces, this function should pass the pre-allocated surface
+              chain to the library instead of allocating new DirectX surfaces. 
+              \verbatim embed:rst
+              See the :ref:`Surface Pool Allocation section <surface_pool_alloc>` for additional information.
+              \endverbatim
+
+       @param[in]  pthis    Pointer to the allocator object.
+       @param[in]  request  Pointer to the mfxFrameAllocRequest structure that specifies the type and number of required frames.
+       @param[out] response Pointer to the mfxFrameAllocResponse structure that retrieves frames actually allocated.
+       @return
+             MFX_ERR_NONE               The function successfully allocated the memory block. \n
+             MFX_ERR_MEMORY_ALLOC       The function failed to allocate the video frames. \n
+             MFX_ERR_UNSUPPORTED        The function does not support allocating the specified type of memory.
+    */
+    mfxStatus  (MFX_CDECL  *Alloc)    (mfxHDL pthis, mfxFrameAllocRequest *request, mfxFrameAllocResponse *response);
+
+    /*!
+       @brief Locks a frame and returns its pointer.
+       @param[in]  pthis    Pointer to the allocator object.
+       @param[in]  mid      Memory block ID.
+       @param[out] ptr      Pointer to the returned frame structure.
+       @return
+             MFX_ERR_NONE               The function successfully locked the memory block. \n
+             MFX_ERR_LOCK_MEMORY        This function failed to lock the frame.
+    */
+    mfxStatus  (MFX_CDECL  *Lock)     (mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr);
+
+    /*!
+       @brief Unlocks a frame and invalidates the specified frame structure.
+       @param[in]  pthis    Pointer to the allocator object.
+       @param[in]  mid      Memory block ID.
+       @param[out] ptr      Pointer to the frame structure. This pointer can be NULL.
+       @return
+             MFX_ERR_NONE               The function successfully locked the memory block.
+    */
+    mfxStatus  (MFX_CDECL  *Unlock)   (mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr);
+
+    /*!
+       @brief Returns the OS-specific handle associated with a video frame. If the handle is a COM interface,
+              the reference counter must increase. The library will release the interface afterward.
+       @param[in]  pthis    Pointer to the allocator object.
+       @param[in]  mid      Memory block ID.
+       @param[out] handle   Pointer to the returned OS-specific handle.
+       @return
+             MFX_ERR_NONE               The function successfully returned the OS-specific handle. \n
+             MFX_ERR_UNSUPPORTED        The function does not support obtaining OS-specific handle..
+    */
+    mfxStatus  (MFX_CDECL  *GetHDL)   (mfxHDL pthis, mfxMemId mid, mfxHDL *handle);
+
+    /*!
+       @brief De-allocates all allocated frames.
+       @param[in]  pthis    Pointer to the allocator object.
+       @param[in]  response Pointer to the mfxFrameAllocResponse structure returned by the Alloc function.
+       @return
+             MFX_ERR_NONE               The function successfully de-allocated the memory block.
+    */
+    mfxStatus  (MFX_CDECL  *Free)     (mfxHDL pthis, mfxFrameAllocResponse *response);
+} mfxFrameAllocator;
+MFX_PACK_END()
+
+/*!
+   @brief
+      Sets the external allocator callback structure for frame allocation.
+
+      If the allocator argument is NULL, the library uses the
+      default allocator, which allocates frames from system memory or hardware devices. The behavior of the API is undefined if it uses this
+      function while the previous allocator is in use. A general guideline is to set the allocator immediately after initializing the session.
+
+   @param[in]  session Session handle.
+   @param[in] allocator   Pointer to the mfxFrameAllocator structure
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoCORE_SetFrameAllocator(mfxSession session, mfxFrameAllocator *allocator);
+
+/*!
+   @brief
+    Sets any essential system handle that the library might use.
+
+    If the specified system handle is a COM interface, the reference counter of the COM interface will increase.
+    The counter will decrease when the session closes.
+
+   @param[in] session Session handle.
+   @param[in] type   Handle type
+   @param[in] hdl   Handle to be set
+
+   @returns
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_UNDEFINED_BEHAVIOR The same handle is redefined.
+                              For example, the function has been called twice with the same handle type or an
+                              internal handle has been created before this function call.
+   MFX_ERR_DEVICE_FAILED The SDK cannot initialize using the handle.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoCORE_SetHandle(mfxSession session, mfxHandleType type, mfxHDL hdl);
+
+/*!
+   @brief
+    Obtains system handles previously set by the MFXVideoCORE_SetHandle function.
+
+    If the handler is a COM interface, the reference counter of the interface increases.
+    The calling application must release the COM interface.
+
+   @param[in] session Session handle.
+   @param[in] type   Handle type
+   @param[in] hdl  Pointer to the handle to be set
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_UNDEFINED_BEHAVIOR Specified handle type not found.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoCORE_GetHandle(mfxSession session, mfxHandleType type, mfxHDL *hdl);
+
+/*!
+   @brief
+    Returns information about current hardware platform in the Legacy mode.
+
+   @param[in] session Session handle.
+   @param[out] platform Pointer to the mfxPlatform structure
+
+   @return
+   MFX_ERR_NONE The function completed successfully.
+
+   @since This function is available since API version 1.19.
+*/
+mfxStatus MFX_CDECL MFXVideoCORE_QueryPlatform(mfxSession session, mfxPlatform* platform);
+
+/*!
+   @brief
+    Initiates execution of an asynchronous function not already started and returns the status code after the specified asynchronous operation completes.
+    If wait is zero, the function returns immediately
+
+   @param[in] session Session handle.
+   @param[in] syncp Sync point
+   @param[in] wait  wait time in milliseconds
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_NONE_PARTIAL_OUTPUT   The function completed successfully, bitstream contains a portion of the encoded frame according to required granularity. \n
+   MFX_WRN_IN_EXECUTION   The specified asynchronous function is in execution. \n
+   MFX_ERR_ABORTED  The specified asynchronous function aborted due to data dependency on a previous asynchronous function that did not complete.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoCORE_SyncOperation(mfxSession session, mfxSyncPoint syncp, mfxU32 wait);
+
+/* MFXMemory */
+
+/*!
+   @brief
+      Returns surface which can be used as input for VPP.
+
+      VPP should be initialized before this call.
+      Surface should be released with mfxFrameSurface1::FrameInterface.Release(...) after usage. The value of mfxFrameSurface1::Data.Locked for the returned surface is 0.
+
+
+   @param[in]  session Session handle.
+   @param[out] surface   Pointer is set to valid mfxFrameSurface1 object.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_NULL_PTR If double-pointer to the @p surface is NULL. \n
+   MFX_ERR_INVALID_HANDLE If @p session was not initialized. \n
+   MFX_ERR_NOT_INITIALIZED If VPP was not initialized (allocator needs to know surface size from somewhere). \n
+   MFX_ERR_MEMORY_ALLOC In case of any other internal allocation error. \n
+   MFX_WRN_ALLOC_TIMEOUT_EXPIRED In case of waiting timeout expired (if set with mfxExtAllocationHints).
+
+   @since This function is available since API version 2.0.
+
+*/
+mfxStatus MFX_CDECL MFXMemory_GetSurfaceForVPP(mfxSession session, mfxFrameSurface1** surface);
+
+/*!
+   @brief
+      Returns surface which can be used as output of VPP.
+
+      VPP should be initialized before this call.
+      Surface should be released with mfxFrameSurface1::FrameInterface.Release(...) after usage. The value of mfxFrameSurface1::Data.Locked for the returned surface is 0.
+
+
+   @param[in]  session Session handle.
+   @param[out] surface   Pointer is set to valid mfxFrameSurface1 object.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_NULL_PTR If double-pointer to the @p surface is NULL. \n
+   MFX_ERR_INVALID_HANDLE If @p session was not initialized. \n
+   MFX_ERR_NOT_INITIALIZED If VPP was not initialized (allocator needs to know surface size from somewhere). \n
+   MFX_ERR_MEMORY_ALLOC In case of any other internal allocation error. \n
+   MFX_WRN_ALLOC_TIMEOUT_EXPIRED In case of waiting timeout expired (if set with mfxExtAllocationHints).
+
+   @since This function is available since API version 2.1.
+
+*/
+mfxStatus MFX_CDECL MFXMemory_GetSurfaceForVPPOut(mfxSession session, mfxFrameSurface1** surface);
+
+/*! Alias for MFXMemory_GetSurfaceForVPP function. */
+#define MFXMemory_GetSurfaceForVPPIn MFXMemory_GetSurfaceForVPP
+
+/*!
+   @brief
+    Returns a surface which can be used as input for the encoder.
+
+    Encoder should be initialized before this call.
+    Surface should be released with mfxFrameSurface1::FrameInterface.Release(...) after usage. The value of mfxFrameSurface1::Data.Locked for the returned surface is 0.
+
+
+
+   @param[in]  session Session handle.
+   @param[out] surface   Pointer is set to valid mfxFrameSurface1 object.
+
+   @return
+   MFX_ERR_NONE The function completed successfully.\n
+   MFX_ERR_NULL_PTR If surface is NULL.\n
+   MFX_ERR_INVALID_HANDLE If session was not initialized.\n
+   MFX_ERR_NOT_INITIALIZED If the encoder was not initialized (allocator needs to know surface size from somewhere).\n
+   MFX_ERR_MEMORY_ALLOC In case of any other internal allocation error. \n
+   MFX_WRN_ALLOC_TIMEOUT_EXPIRED In case of waiting timeout expired (if set with mfxExtAllocationHints).
+
+   @since This function is available since API version 2.0.
+
+*/
+mfxStatus MFX_CDECL MFXMemory_GetSurfaceForEncode(mfxSession session, mfxFrameSurface1** surface);
+
+/*!
+   @brief
+    Returns a surface which can be used as output of the decoder.
+
+    Decoder should be initialized before this call.
+    Surface should be released with mfxFrameSurface1::FrameInterface.Release(...) after usage. The value of mfxFrameSurface1::Data.Locked for the returned surface is 0.'
+
+    @note This function was added to simplify transition from legacy surface management to the proposed internal allocation approach.
+    Previously, the user allocated surfaces for the working pool and fed them to the decoder using DecodeFrameAsync calls. With MFXMemory_GetSurfaceForDecode
+    it is possible to change the existing pipeline by just changing the source of work surfaces.
+    Newly developed applications should prefer direct usage of DecodeFrameAsync with internal allocation.
+
+
+   @param[in]  session Session handle.
+   @param[out] surface   Pointer is set to valid mfxFrameSurface1 object.
+
+   @return
+   MFX_ERR_NONE The function completed successfully.\n
+   MFX_ERR_NULL_PTR If surface is NULL.\n
+   MFX_ERR_INVALID_HANDLE If session was not initialized.\n
+   MFX_ERR_NOT_INITIALIZED If the decoder was not initialized (allocator needs to know surface size from somewhere).\n
+   MFX_ERR_MEMORY_ALLOC Other internal allocation error. \n
+   MFX_WRN_ALLOC_TIMEOUT_EXPIRED In case of waiting timeout expired (if set with mfxExtAllocationHints).
+
+   @since This function is available since API version 2.0.
+
+*/
+mfxStatus MFX_CDECL MFXMemory_GetSurfaceForDecode(mfxSession session, mfxFrameSurface1** surface);
+
+/* VideoENCODE */
+
+/*!
+   @brief
+     Works in either of four modes:
+
+     @li If the @p in parameter is zero, the function returns the class configurability in the output structure. The output structure has a non-zero value in each field that the implementation can configure using Init.
+
+     @li If the @p in parameter is non-zero, the function checks the validity of the fields in the input structure. Then the function returns the corrected values in
+     the output structure. If there is insufficient information to determine the validity or correction is impossible, the function zeroes the fields.
+     This feature can verify whether the implementation supports certain profiles, levels or bitrates.
+
+     @li If the @p in parameter is non-zero and mfxExtEncoderResetOption structure is attached to it, the function queries for the outcome of the MFXVideoENCODE_Reset function
+     and returns it in the mfxExtEncoderResetOption structure attached to out. The query function succeeds if a reset is possible and returns an error otherwise. Unlike other
+     modes that are independent of the encoder state, this one checks if reset is possible in the present encoder state.
+     This mode also requires a completely defined mfxVideoParam structure, unlike other modes that support partially defined configurations.
+     See mfxExtEncoderResetOption description for more details.
+
+     @li If the @p in parameter is non-zero and mfxExtEncoderCapability structure is attached to it, the function returns encoder capability in the mfxExtEncoderCapability structure
+     attached to out. It is recommended to fill in the mfxVideoParam structure and set the hardware acceleration device handle before calling the function in this mode.
+
+     The application can call this function before or after it initializes the encoder. The ``CodecId`` field of the output structure is a mandated field (to be filled by the
+     application) to identify the coding standard.
+
+   @param[in] session Session handle.
+   @param[in] in   Pointer to the mfxVideoParam structure as input.
+   @param[out] out  Pointer to the mfxVideoParam structure as output.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_UNSUPPORTED  The function failed to identify a specific implementation for the required features. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The encoding may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+
+/*!
+   @brief
+    Returns minimum and suggested numbers of the input frame surfaces required for encoding initialization and their type.
+
+    Init will call the external allocator for the required frames with the same set of numbers.
+    This function does not validate I/O parameters except those used in calculating the number of input surfaces.
+
+    The use of this function is recommended.
+    \verbatim embed:rst
+    For more information, see the :ref:`Working with Hardware Acceleration section<hw-acceleration>`.
+    \endverbatim
+
+
+   @param[in] session Session handle.
+   @param[in] par     Pointer to the mfxVideoParam structure as input.
+   @param[in] request Pointer to the mfxFrameAllocRequest structure as output.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected invalid video parameters. These parameters may be out of the valid range or the combination of them
+                                resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The encoding may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request);
+
+/*!
+   @brief
+    Allocates memory and prepares tables and necessary structures for encoding.
+
+    This function also does extensive validation to ensure if the
+    configuration, as specified in the input parameters, is supported.
+
+   @param[in] session Session handle.
+   @param[in] par Pointer to the mfxVideoParam structure.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected invalid video parameters. These parameters may be out of the valid range, or the combination of them
+                                resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The encoding may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved. \n
+   MFX_ERR_UNDEFINED_BEHAVIOR  The function is called twice without a close;
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_Init(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Stops the current encoding operation and restores internal structures or parameters for a new encoding operation, possibly with new parameters.
+
+   @param[in] session Session handle.
+   @param[in] par   Pointer to the mfxVideoParam structure.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected invalid video parameters. These parameters may be out of the valid range, or the combination of them
+                                resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM  The function detected that video parameters provided by the application are incompatible with initialization parameters.
+                                     Reset requires additional memory allocation and cannot be executed. The application should close the
+                                     component and then reinitialize it. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_Reset(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Terminates the current encoding operation and de-allocates any internal tables or structures.
+
+   @param[in] session Session handle.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_Close(mfxSession session);
+
+/*!
+   @brief
+    Retrieves current working parameters to the specified output structure.
+
+    If extended buffers are to be returned, the
+    application must allocate those extended buffers and attach them as part of the output structure.
+    The application can retrieve a copy of the bitstream header by attaching the mfxExtCodingOptionSPSPPS structure to the mfxVideoParam structure.
+
+   @param[in] session Session handle.
+   @param[in] par Pointer to the corresponding parameter structure.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_GetVideoParam(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Obtains statistics collected during encoding.
+
+   @param[in] session Session handle.
+   @param[in] stat  Pointer to the mfxEncodeStat structure.
+
+   @return MFX_ERR_NONE The function completed successfully.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_GetEncodeStat(mfxSession session, mfxEncodeStat *stat);
+
+/*!
+   @brief
+    Takes a single input frame in either encoded or display order and generates its output bitstream.
+
+    In the case of encoded ordering, the mfxEncodeCtrl
+    structure must specify the explicit frame type. In the case of display ordering, this function handles frame order shuffling according to the GOP structure
+    parameters specified during initialization.
+
+    Since encoding may process frames differently from the input order, not every call of the function generates output and the function returns MFX_ERR_MORE_DATA.
+    If the encoder needs to cache the frame, the function locks the frame. The application should not alter the frame until the encoder unlocks the frame.
+    If there is output (with return status MFX_ERR_NONE), the return is a frame's worth of bitstream.
+
+    It is the calling application's responsibility to ensure that there is sufficient space in the output buffer. The value ``BufferSizeInKB`` in the
+    mfxVideoParam structure at encoding initialization specifies the maximum possible size for any compressed frames. This value can also be obtained from the
+    MFXVideoENCODE_GetVideoParam function after encoding initialization.
+
+    To mark the end of the encoding sequence, call this function with a NULL surface pointer. Repeat the call to drain any remaining internally cached bitstreams
+    (one frame at a time) until MFX_ERR_MORE_DATA is returned.
+
+    This function is asynchronous.
+
+   @param[in] session Session handle.
+   @param[in] ctrl  Pointer to the mfxEncodeCtrl structure for per-frame encoding control; this parameter is optional (it can be NULL) if the encoder works in the display order mode.
+   @param[in] surface  Pointer to the frame surface structure.
+   @param[out] bs   Pointer to the output bitstream.
+   @param[out] syncp  Pointer to the returned sync point associated with this operation.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_NOT_ENOUGH_BUFFER  The bitstream buffer size is insufficient. \n
+   MFX_ERR_MORE_DATA   The function requires more data to generate any output. \n
+   MFX_ERR_DEVICE_LOST Hardware device was lost.
+   \verbatim embed:rst
+   See the :ref:`Working with Microsoft* DirectX* Applications section<work_ms_directx_app>` for further information.
+   \endverbatim
+   \n
+   MFX_WRN_DEVICE_BUSY  Hardware device is currently busy. Call this function again after MFXVideoCORE_SyncOperation or in a few milliseconds.  \n
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM  Inconsistent parameters detected not conforming to Configuration Parameter Constraints.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoENCODE_EncodeFrameAsync(mfxSession session, mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxSyncPoint *syncp);
+
+/*!
+   @brief
+     Works in one of two modes:
+
+     @li If the @p in parameter is zero, the function returns the class configurability in the output structure. A non-zero value in each field of the output structure
+     indicates that the field is configurable by the implementation with the MFXVideoDECODE_Init function.
+
+     @li If the @p in parameter is non-zero, the function checks the validity of the fields in the input structure. Then the function returns the corrected values to
+     the output structure. If there is insufficient information to determine the validity or correction is impossible, the function zeros the fields. This
+     feature can verify whether the implementation supports certain profiles, levels, or bitrates.
+
+     The application can call this function before or after it initializes the decoder. The ``CodecId`` field of the output structure is a mandated field
+     (to be filled by the application) to identify the coding standard.
+
+   @param[in] session Session handle.
+   @param[in] in   Pointer to the mfxVideoParam structure as input.
+   @param[out] out  Pointer to the mfxVideoParam structure as output.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_UNSUPPORTED  The function failed to identify a specific implementation for the required features. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The decoding may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+
+mfxStatus MFX_CDECL MFXVideoDECODE_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+
+/*!
+   @brief
+    Parses the input bitstream and fills the mfxVideoParam structure with appropriate values, such as resolution and frame rate, for the Init API function.
+
+    The application can then pass the resulting structure to the MFXVideoDECODE_Init function for decoder initialization.
+
+    An application can call this API function at any time before or after decoder initialization. If the library finds a sequence header in the bitstream, the function
+    moves the bitstream pointer to the first bit of the sequence header. Otherwise, the function moves the bitstream pointer close to the end of the bitstream buffer but leaves enough data in the buffer to avoid possible loss of start code.
+
+    The ``CodecId`` field of the mfxVideoParam structure is a mandated field (to be filled by the application) to identify the coding standard.
+
+    The application can retrieve a copy of the bitstream header, by attaching the mfxExtCodingOptionSPSPPS structure to the mfxVideoParam structure.
+
+   @param[in] session Session handle.
+   @param[in] bs   Pointer to the bitstream.
+   @param[in] par  Pointer to the mfxVideoParam structure.
+
+   @return
+    - MFX_ERR_NONE The function successfully filled the structure. It does not mean that the stream can be decoded by the library.
+                The application should call MFXVideoDECODE_Query function to check if decoding of the stream is supported. \n
+    - MFX_ERR_MORE_DATA   The function requires more bitstream data. \n
+    - MFX_ERR_UNSUPPORTED ``CodecId`` field of the mfxVideoParam structure indicates some unsupported codec. \n
+    - MFX_ERR_INVALID_HANDLE  Session is not initialized. \n
+    - MFX_ERR_NULL_PTR @p bs or @p par pointer is NULL.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_DecodeHeader(mfxSession session, mfxBitstream *bs, mfxVideoParam *par);
+
+/*!
+   @brief
+    Returns minimum and suggested numbers of the output frame surfaces required for decoding initialization and their type.
+
+    Init will call the external allocator for the required frames with the same set of numbers.
+    The use of this function is recommended.
+    \verbatim embed:rst
+    For more information, see the :ref:`Working with Hardware Acceleration section<hw-acceleration>`.
+    \endverbatim
+
+    The ``CodecId`` field of the mfxVideoParam structure is a mandated field (to be filled by the application) to identify the coding standard.
+    This function does not validate I/O parameters except those used in calculating the number of output surfaces.
+
+   @param[in] session Session handle.
+   @param[in] par     Pointer to the mfxVideoParam structure as input.
+   @param[in] request Pointer to the mfxFrameAllocRequest structure as output.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected invalid video parameters. These parameters may be out of the valid range, or the combination of them
+                                resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The encoding may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request);
+
+/*!
+   @brief
+    Allocates memory and prepares tables and necessary structures for encoding.
+
+    This function also does extensive validation to ensure if the
+    configuration, as specified in the input parameters, is supported.
+
+   @param[in] session Session handle.
+   @param[in] par Pointer to the mfxVideoParam structure.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected invalid video parameters. These parameters may be out of the valid range, or the combination of them
+                                resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The encoding may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved. \n
+   MFX_ERR_UNDEFINED_BEHAVIOR  The function is called twice without a close.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_Init(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Stops the current decoding operation and restores internal structures or parameters for a new decoding operation.
+
+    Reset serves two purposes:
+
+    @li It recovers the decoder from errors.
+    @li It restarts decoding from a new position
+
+    The function resets the old sequence header (sequence parameter set in H.264, or sequence header in MPEG-2 and VC-1). The decoder will expect a new sequence header
+    before it decodes the next frame and will skip any bitstream before encountering the new sequence header.
+
+   @param[in] session Session handle.
+   @param[in] par   Pointer to the mfxVideoParam structure.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected that video parameters are wrong or they conflict with initialization parameters. Reset is impossible. \n
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM  The function detected that video parameters provided by the application are incompatible with initialization parameters.
+                                     Reset requires additional memory allocation and cannot be executed. The application should close the
+                                     component and then reinitialize it. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_Reset(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Terminates the current decoding operation and de-allocates any internal tables or structures.
+
+   @param[in] session Session handle.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_Close(mfxSession session);
+
+/*!
+   @brief
+    Retrieves current working parameters to the specified output structure.
+
+    If extended buffers are to be returned, the
+    application must allocate those extended buffers and attach them as part of the output structure.
+    The application can retrieve a copy of the bitstream header, by attaching the mfxExtCodingOptionSPSPPS structure to the mfxVideoParam structure.
+
+   @param[in] session Session handle.
+   @param[in] par Pointer to the corresponding parameter structure.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_GetVideoParam(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Obtains statistics collected during decoding.
+
+   @param[in] session Session handle.
+   @param[in] stat  Pointer to the mfxDecodeStat structure.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_GetDecodeStat(mfxSession session, mfxDecodeStat *stat);
+
+/*!
+   @brief
+    Sets the decoder skip mode.
+
+    The application may use this API function to increase decoding performance by sacrificing output quality. Increasing the skip
+    level first results in skipping of some decoding operations like deblocking and then leads to frame skipping; first B, then P. Particular details are platform dependent.
+
+   @param[in] session Session handle.
+   @param[in] mode   Decoder skip mode. See the mfxSkipMode enumerator for details.
+
+   @return
+   MFX_ERR_NONE The function completed successfully and the output surface is ready for decoding \n
+   MFX_WRN_VALUE_NOT_CHANGED   The skip mode is not affected as the maximum or minimum skip range is reached.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_SetSkipMode(mfxSession session, mfxSkipMode mode);
+
+/*!
+   @brief
+    Extracts user data (MPEG-2) or SEI (H.264) messages from the bitstream.
+
+    Internally, the decoder implementation stores encountered user data or
+    SEI messages. The application may call this API function multiple times to retrieve the user data or SEI messages, one at a time.
+
+    If there is no payload available, the function returns with payload->NumBit=0.
+
+   @param[in] session Session handle.
+   @param[in] ts  Pointer to the user data time stamp in units of 90 KHz; divide ts by 90,000 (90 KHz) to obtain the time in seconds; the time stamp matches the payload
+                  with a specific decoded frame.
+   @param[in] payload  Pointer to the mfxPayload structure; the payload contains user data in MPEG-2 or SEI messages in H.264.
+
+   @return
+   MFX_ERR_NONE The function completed successfully and the output buffer is ready for decoding. \n
+   MFX_ERR_NOT_ENOUGH_BUFFER  The payload buffer size is insufficient.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_GetPayload(mfxSession session, mfxU64 *ts, mfxPayload *payload);
+
+/*!
+   @brief
+   Decodes the input bitstream to a single output frame.
+
+   The @p surface_work parameter provides a working frame buffer for the decoder. The application should allocate the working frame buffer, which stores decoded frames.
+   If the function requires caching frames after decoding, it locks the frames and the application must provide a new frame buffer in the next call.
+
+   If, and only if, the function returns MFX_ERR_NONE, the pointer @p surface_out points to the output frame in the display order. If there are no further frames,
+   the function will reset the pointer to zero and return the appropriate status code.
+
+   Before decoding the first frame, a sequence header (sequence parameter set in H.264 or sequence header in MPEG-2 and VC-1) must be present. The function skips any
+   bitstreams before it encounters the new sequence header.
+
+   The input bitstream @p bs can be of any size. If there are not enough bits to decode a frame, the function returns MFX_ERR_MORE_DATA, and consumes all input bits except if
+   a partial start code or sequence header is at the end of the buffer. In this case, the function leaves the last few bytes in the bitstream buffer.
+   If there is more incoming bitstream, the application should append the incoming bitstream to the bitstream buffer. Otherwise, the application should ignore the
+   remaining bytes in the bitstream buffer and apply the end of stream procedure described below.
+
+   The application must set @p bs to NULL to signal end of stream. The application may need to call this API function several times to drain any internally cached frames until the
+   function returns MFX_ERR_MORE_DATA.
+
+   If more than one frame is in the bitstream buffer, the function decodes until the buffer is consumed. The decoding process can be interrupted for events such as if the
+   decoder needs additional working buffers, is readying a frame for retrieval, or encountering a new header. In these cases, the function returns appropriate status code
+   and moves the bitstream pointer to the remaining data.
+
+   The decoder may return MFX_ERR_NONE without taking any data from the input bitstream buffer. If the application appends additional data to the bitstream buffer, it
+   is possible that the bitstream buffer may contain more than one frame. It is recommended that the application invoke the function repeatedly until the function
+   returns MFX_ERR_MORE_DATA, before appending any more data to the bitstream buffer.
+
+   Starting from API 2.0 it is possible to pass NULL instead of surface_work. In such case runtime will allocate output frames internally.
+
+   This function is asynchronous.
+
+   @param[in] session Session handle.
+   @param[in] bs  Pointer to the input bitstream.
+   @param[in] surface_work  Pointer to the working frame buffer for the decoder.
+   @param[out] surface_out   Pointer to the output frame in the display order.
+   @param[out] syncp   Pointer to the sync point associated with this operation.
+
+   @return
+   MFX_ERR_NONE The function completed successfully and the output surface is ready for decoding. \n
+   MFX_ERR_MORE_DATA The function requires more bitstream at input before decoding can proceed. \n
+   MFX_ERR_MORE_SURFACE The function requires more frame surface at output before decoding can proceed. \n
+   MFX_ERR_DEVICE_LOST  Hardware device was lost.
+   \verbatim embed:rst
+   See the :ref:`Working with Microsoft* DirectX* Applications section<work_ms_directx_app>` for further information.
+   \endverbatim 
+   \n
+   MFX_WRN_DEVICE_BUSY  Hardware device is currently busy. Call this function again after MFXVideoCORE_SyncOperation or in a few milliseconds.  \n
+   MFX_WRN_VIDEO_PARAM_CHANGED  The decoder detected a new sequence header in the bitstream. Video parameters may have changed. \n
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM  The decoder detected incompatible video parameters in the bitstream and failed to follow them. \n
+   MFX_ERR_REALLOC_SURFACE  Bigger surface_work required. May be returned only if mfxInfoMFX::EnableReallocRequest was set to ON during initialization. \n
+   MFX_WRN_ALLOC_TIMEOUT_EXPIRED Timeout expired for internal output frame allocation (if set with mfxExtAllocationHints and NULL passed as surface_work). Repeat the call in a few milliseconds or re-initialize decoder with higher surface limit.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoDECODE_DecodeFrameAsync(mfxSession session, mfxBitstream *bs, mfxFrameSurface1 *surface_work, mfxFrameSurface1 **surface_out, mfxSyncPoint *syncp);
+
+/* VideoVPP */
+
+/*!
+   @brief
+     Works in one of two modes:
+
+     @li If the @p in pointer is zero, the function returns the class configurability in the output structure. A non-zero value in a field indicates that the
+       implementation can configure it with Init.
+
+     @li If the @p in parameter is non-zero, the function checks the validity of the fields in the input structure. Then the function returns the corrected values to
+     the output structure. If there is insufficient information to determine the validity or correction is impossible, the function zeroes the fields.
+
+     The application can call this function before or after it initializes the preprocessor.
+
+   @param[in] session Session handle.
+   @param[in] in   Pointer to the mfxVideoParam structure as input.
+   @param[out] out  Pointer to the mfxVideoParam structure as output.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_UNSUPPORTED  The implementation does not support the specified configuration. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The video processing may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_Query(mfxSession session, mfxVideoParam *in, mfxVideoParam *out);
+
+/*!
+   @brief
+    Returns minimum and suggested numbers of the input frame surfaces required for video processing initialization and their type.
+
+    The parameter ``request[0]`` refers to the input requirements; ``request[1]`` refers to output requirements. Init will call the external allocator for the
+    required frames with the same set of numbers.
+    This function does not validate I/O parameters except those used in calculating the number of input surfaces.
+
+    The use of this function is recommended.
+    \verbatim embed:rst
+    For more information, see the :ref:`Working with Hardware Acceleration section<hw-acceleration>`.
+    \endverbatim
+
+   @param[in] session Session handle.
+   @param[in] par     Pointer to the mfxVideoParam structure as input.
+   @param[in] request Pointer to the mfxFrameAllocRequest structure; use ``request[0]`` for input requirements and ``request[1]`` for output requirements for video processing.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected invalid video parameters. These parameters may be out of the valid range, or the combination of them
+                                resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The video processing may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_QueryIOSurf(mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest request[2]);
+
+/*!
+   @brief
+    Allocates memory and prepares tables and necessary structures for video processing.
+
+    This function also does extensive validation to ensure if the
+    configuration, as specified in the input parameters, is supported.
+
+   @param[in] session Session handle.
+   @param[in] par Pointer to the mfxVideoParam structure.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected invalid video parameters. These parameters may be out of the valid range, or the combination of them
+                                resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_WRN_PARTIAL_ACCELERATION  The underlying hardware does not fully support the specified video parameters.
+                                 The video processing may be partially accelerated. Only hardware implementations may return this status code. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved. \n
+   MFX_ERR_UNDEFINED_BEHAVIOR  The function is called twice without a close. \n
+   MFX_WRN_FILTER_SKIPPED    The VPP skipped one or more filters requested by the application.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_Init(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Stops the current video processing operation and restores internal structures or parameters for a new operation
+
+   @param[in] session Session handle.
+   @param[in] par   Pointer to the mfxVideoParam structure.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected that video parameters are wrong or they conflict with initialization parameters. Reset is impossible. \n
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM  The function detected that video parameters provided by the application are incompatible with initialization parameters.
+                                     Reset requires additional memory allocation and cannot be executed. The application should close the
+                                     component and then reinitialize it. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_Reset(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Terminates the current video processing operation and de-allocates any internal tables or structures.
+
+   @param[in] session Session handle.
+
+   @return MFX_ERR_NONE
+   The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_Close(mfxSession session);
+
+/*!
+   @brief
+    Retrieves current working parameters to the specified output structure.
+
+    If extended buffers are to be returned, the
+    application must allocate those extended buffers and attach them as part of the output structure.
+
+   @param[in] session Session handle.
+   @param[in] par Pointer to the corresponding parameter structure.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_GetVideoParam(mfxSession session, mfxVideoParam *par);
+
+/*!
+   @brief
+    Obtains statistics collected during video processing.
+
+   @param[in] session Session handle.
+   @param[in] stat  Pointer to the mfxVPPStat structure.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_GetVPPStat(mfxSession session, mfxVPPStat *stat);
+
+/*!
+   @brief
+    Processes a single input frame to a single output frame.
+
+    Retrieval of the auxiliary data is optional; the encoding process may use it.
+    The video processing process may not generate an instant output given an input.
+    \verbatim embed:rst
+    See the :ref:`Video Processing Procedures section<vid_process_procedure>` for details on how to
+    correctly send input and retrieve output.
+    \endverbatim
+
+
+    At the end of the stream, call this function with the input argument ``in=NULL`` to retrieve any remaining frames, until the function returns MFX_ERR_MORE_DATA.
+    This function is asynchronous.
+
+   @param[in] session Session handle.
+   @param[in] in  Pointer to the input video surface structure.
+   @param[out] out  Pointer to the output video surface structure.
+   @param[in] aux  Optional pointer to the auxiliary data structure.
+   @param[out] syncp  Pointer to the output sync point.
+
+   @return
+   MFX_ERR_NONE The output frame is ready after synchronization. \n
+   MFX_ERR_MORE_DATA Need more input frames before VPP can produce an output. \n
+   MFX_ERR_MORE_SURFACE The output frame is ready after synchronization. Need more surfaces at output for additional output frames available. \n
+   MFX_ERR_DEVICE_LOST  Hardware device was lost.
+   \verbatim embed:rst
+    See the :ref:`Working with Microsoft* DirectX* Applications section<work_ms_directx_app>` for further information.
+    \endverbatim 
+    \n
+   MFX_WRN_DEVICE_BUSY  Hardware device is currently busy. Call this function again after MFXVideoCORE_SyncOperation or in a few milliseconds.
+
+   @since This function is available since API version 1.0.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_RunFrameVPPAsync(mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 *out, mfxExtVppAuxData *aux, mfxSyncPoint *syncp);
+
+/*!
+   @brief
+    The function processes a single input frame to a single output frame with internal allocation of output frame.
+
+       At the end of the stream, call this function with the input argument ``in=NULL`` to retrieve any remaining frames, until the function returns MFX_ERR_MORE_DATA.
+    This function is asynchronous.
+
+   @param[in] session Session handle.
+   @param[in] in  Pointer to the input video surface structure.
+   @param[out] out  Pointer to the output video surface structure which is reference counted object allocated by the library. 
+
+   @return
+   MFX_ERR_NONE The output frame is ready after synchronization. \n
+   MFX_ERR_MORE_DATA Need more input frames before VPP can produce an output. \n
+   MFX_ERR_MEMORY_ALLOC The function failed to allocate output videoframe. \n
+
+   MFX_ERR_DEVICE_LOST  Hardware device was lost.
+   \verbatim embed:rst
+    See the :ref:`Working with Microsoft* DirectX* Applications section<work_ms_directx_app>` for further information.
+    \endverbatim 
+    \n
+   MFX_WRN_DEVICE_BUSY  Hardware device is currently busy. Call this function again after MFXVideoCORE_SyncOperation or in a few milliseconds. \n
+   MFX_WRN_ALLOC_TIMEOUT_EXPIRED Timeout expired for internal output frame allocation (if set with mfxExtAllocationHints). Repeat the call in a few milliseconds or reinitialize VPP with higher surface limit.
+
+   @since This function is available since API version 2.1.
+*/
+mfxStatus MFX_CDECL MFXVideoVPP_ProcessFrameAsync(mfxSession session, mfxFrameSurface1 *in, mfxFrameSurface1 **out);
+
+/*!
+   @brief
+   Initialize the SDK in (decode + vpp) mode. The logic of this function is similar to  MFXVideoDECODE_Init,
+   but application has to provide array of pointers to mfxVideoChannelParam and num_channel_param - number of channels. Application is responsible for    
+   memory allocation for mfxVideoChannelParam parameters and for each channel it should specify channel IDs:    
+   mfxVideoChannelParam::mfxFrameInfo::ChannelId. ChannelId should be unique value within one session. ChannelID equals to the 0
+   is reserved for the orginal decoded frame.
+   The application can attach mfxExtInCrops to mfxVideoChannelParam::ExtParam to annotate input video frame if it wants to enable 
+   letterboxing operation.
+   @param[in] session SDK session handle.
+   @param[in] decode_par Pointer to the mfxVideoParam structure which contains initialization parameters for decoder.
+   @param[in] vpp_par_array Array of pointers to `mfxVideoChannelParam`structures. Each mfxVideoChannelParam contains initialization 
+              parameters for each VPP channel.
+   @param[in] num_vpp_par Size of array of pointers to mfxVideoChannelParam structures.
+
+   @return
+   MFX_ERR_NONE The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM   The function detected invalid video parameters. These parameters may be out of the valid range, or 
+   the combination of them resulted in incompatibility. Incompatibility not resolved. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM The function detected some video parameters were incompatible with others; incompatibility 
+   resolved. \n
+   MFX_ERR_UNDEFINED_BEHAVIOR The component is already initialized. \n
+   MFX_WRN_FILTER_SKIPPED The VPP skipped one or more filters requested by the application.
+
+   @since This function is available since API version 2.1.
+*/
+mfxStatus  MFX_CDECL MFXVideoDECODE_VPP_Init(mfxSession session, mfxVideoParam* decode_par, mfxVideoChannelParam** vpp_par_array, mfxU32 num_vpp_par);
+
+/*!
+   @brief
+   This function is similar to MFXVideoDECODE_DecodeFrameAsync and inherits all bitstream processing logic. As output,
+   it allocates and returns @p surf_array_out array of processed surfaces according to the chain of filters specified
+   by application in MFXVideoDECODE_VPP_Init, including original decoded frames. In the @p surf_array_out, the original
+   decoded frames are returned through surfaces with mfxFrameInfo::ChannelId == 0, followed by each of the subsequent
+   frame surfaces for each of the requested mfxVideoChannelParam entries provided to the MFXVideoCECODE_VPP_Init
+   function. At maximum, the number of frame surfaces return is 1 + the value of @p num_vpp_par to the
+   MFXVideoDECODE_VPP_Init function, but the application must be prepared to the case when some particular filters
+   are not ready to output surfaces, so the length of @p surf_array_out will be less. Application should use
+   mfxFrameInfo::ChannelId parameter to match output surface against configured filter.
+
+   An application must synchronize each output surface from the @p surf_array_out surface array independently.
+
+   @param[in] session SDK session handle.
+   @param[in] bs Pointer to the input bitstream.
+   @param[in] skip_channels Pointer to the array of `ChannelId`s which specifies channels with skip output frames. Memory for 
+   the array is allocated by application.
+   @param[in] num_skip_channels Number of channels addressed by skip_channels. 
+   @param[out] surf_array_out The address of a pointer to the structure with frame surfaces.
+
+   @return
+   MFX_ERR_NONE The function completed successfully and the output surface is ready for decoding. \n
+   MFX_ERR_MORE_DATA The function requires more bitstream at input before decoding can proceed. \n
+   MFX_ERR_MORE_SURFACE The function requires more frame surface at output before decoding can proceed. \n
+   MFX_ERR_DEVICE_LOST  Hardware device was lost.
+   \verbatim embed:rst
+   See the :ref:`Working with Microsoft* DirectX* Applications section<work_ms_directx_app>` for further information.
+   \endverbatim 
+   \n
+   MFX_WRN_DEVICE_BUSY  Hardware device is currently busy. Call this function again after MFXVideoCORE_SyncOperation or in a few milliseconds.  \n
+   MFX_WRN_VIDEO_PARAM_CHANGED  The decoder detected a new sequence header in the bitstream. Video parameters may have changed. \n
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM  The decoder detected incompatible video parameters in the bitstream and failed to follow them. \n
+   MFX_ERR_NULL_PTR num_skip_channels doesn't equal to 0 when skip_channels is NULL.
+
+   @since This function is available since API version 2.1.
+*/
+mfxStatus  MFX_CDECL MFXVideoDECODE_VPP_DecodeFrameAsync(mfxSession session, mfxBitstream *bs, mfxU32* skip_channels, mfxU32 num_skip_channels, mfxSurfaceArray **surf_array_out);
+
+/*!
+   @brief
+   This function is similar to MFXVideoDECODE_Reset and  stops the current decoding and vpp operation, and restores internal 
+   structures or parameters for a new decoding plus vpp operation. It resets the state of the decoder and/or all initialized vpp 
+   channels. Applications have to care about draining of buffered frames for decode and all vpp channels before call this function.
+   The application can attach mfxExtInCrops to mfxVideoChannelParam::ExtParam to annotate input video frame if it wants to enable 
+   letterboxing operation.
+
+   @param[in] session Session handle.
+   @param[in] decode_par   Pointer to the `mfxVideoParam` structure which contains new initialization parameters for decoder. Might 
+   be NULL if application wants to Reset only VPP channels.
+   @param[in] vpp_par_array Array of pointers to mfxVideoChannelParam structures. Each mfxVideoChannelParam contains new 
+   initialization parameters for each VPP channel.
+   @param[in] num_vpp_par Size of array of pointers to mfxVideoChannelParam structures.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_INVALID_VIDEO_PARAM  The function detected that video parameters are wrong or they conflict with initialization parameters. Reset is impossible. \n
+   MFX_ERR_INCOMPATIBLE_VIDEO_PARAM  The function detected that video parameters provided by the application are incompatible with initialization parameters.
+                                     Reset requires additional memory allocation and cannot be executed. The application should close the
+                                     component and then reinitialize it. \n
+   MFX_WRN_INCOMPATIBLE_VIDEO_PARAM  The function detected some video parameters were incompatible with others; incompatibility resolved.
+   MFX_ERR_NULL_PTR  Both pointers decode_par and vpp_par_array` equal to zero.
+
+   @since This function is available since API version 2.1.
+*/
+mfxStatus  MFX_CDECL MFXVideoDECODE_VPP_Reset(mfxSession session, mfxVideoParam* decode_par, mfxVideoChannelParam** vpp_par_array, mfxU32 num_vpp_par);
+
+/*!
+   @brief
+   Returns actual VPP parameters for selected channel which should be specified by application through  
+   mfxVideoChannelParam::mfxFrameInfo::ChannelId.
+
+   @param[in] session Session handle.
+   @param[in] par   Pointer to the `mfxVideoChannelParam` structure which allocated by application 
+   @param[in] channel_id specifies the requested channel's info
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+   MFX_ERR_NULL_PTR  par pointer is NULL. \n
+   MFX_ERR_NOT_FOUND the library is not able to find VPP channel with such channel_id.
+
+   @since This function is available since API version 2.1.
+*/
+mfxStatus  MFX_CDECL MFXVideoDECODE_VPP_GetChannelParam(mfxSession session, mfxVideoChannelParam *par, mfxU32 channel_id);
+
+/*!
+   @brief
+   This function is similar to MFXVideoDECODE_Close. It terminates the current decoding and vpp operation and de-allocates any internal tables or structures.
+
+   @param[in] session Session handle.
+
+   @return
+   MFX_ERR_NONE  The function completed successfully. \n
+
+   @since This function is available since API version 2.1.
+*/
+
+mfxStatus  MFX_CDECL MFXVideoDECODE_VPP_Close(mfxSession session);
+
+/*! Alias for MFXVideoDECODE_DecodeHeader function. */
+#define MFXVideoDECODE_VPP_DecodeHeader     MFXVideoDECODE_DecodeHeader
+
+/*! Alias for MFXVideoDECODE_GetVideoParam function. */
+#define MFXVideoDECODE_VPP_GetVideoParam    MFXVideoDECODE_GetVideoParam
+
+/*! Alias for MFXVideoDECODE_GetDecodeStat function. */
+#define MFXVideoDECODE_VPP_GetDecodeStat    MFXVideoDECODE_GetDecodeStat
+
+/*! Alias for MFXVideoDECODE_SetSkipMode function. */
+#define MFXVideoDECODE_VPP_SetSkipMode      MFXVideoDECODE_SetSkipMode
+
+/*! Alias for MFXVideoDECODE_GetPayload function. */
+#define MFXVideoDECODE_VPP_GetPayload       MFXVideoDECODE_GetPayload
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvp8.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/api/vpl/mfxvp8.h
new file mode 100644 (file)
index 0000000..4049af9
--- /dev/null
@@ -0,0 +1,65 @@
+/*############################################################################
+  # Copyright Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef __MFXVP8_H__
+#define __MFXVP8_H__
+
+#include "mfxdefs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+    MFX_CODEC_VP8 = MFX_MAKEFOURCC('V','P','8',' '),
+};
+
+/* VP8 CodecProfile*/
+enum {
+    MFX_PROFILE_VP8_0                       = 0+1, 
+    MFX_PROFILE_VP8_1                       = 1+1,
+    MFX_PROFILE_VP8_2                       = 2+1,
+    MFX_PROFILE_VP8_3                       = 3+1,
+};
+
+/* Extended Buffer Ids */
+enum {
+    /*!
+       This extended buffer describes VP8 encoder configuration parameters. See the mfxExtVP8CodingOption structure for details.
+       The application can attach this buffer to the mfxVideoParam structure for encoding initialization.
+    */
+    MFX_EXTBUFF_VP8_CODING_OPTION =   MFX_MAKEFOURCC('V','P','8','E'),
+};
+
+MFX_PACK_BEGIN_USUAL_STRUCT()
+/*! Describes VP8 coding options. */
+typedef struct { 
+    mfxExtBuffer    Header;             /*!< Extension buffer header. Header.BufferId must be equal to MFX_EXTBUFF_VP8_CODING_OPTION. */
+
+    mfxU16   Version;                   /*!< Determines the bitstream version. Corresponds to the same VP8 syntax element in frame_tag. */
+    mfxU16   EnableMultipleSegments;    /*!< Set this option to ON to enable segmentation. This is tri-state option. See the CodingOptionValue
+                                             enumerator for values of this option. */
+    mfxU16   LoopFilterType;            /*!< Select the type of filter (normal or simple). Corresponds to VP8 syntax element filter_type. */
+    mfxU16   LoopFilterLevel[4];        /*!< Controls the filter strength. Corresponds to VP8 syntax element loop_filter_level. */
+    mfxU16   SharpnessLevel;            /*!< Controls the filter sensitivity. Corresponds to VP8 syntax element sharpness_level. */
+    mfxU16   NumTokenPartitions;        /*!< Specifies number of token partitions in the coded frame. */
+    mfxI16   LoopFilterRefTypeDelta[4]; /*!< Loop filter level delta for reference type (intra, last, golden, altref). */
+    mfxI16   LoopFilterMbModeDelta[4];  /*!< Loop filter level delta for MB modes. */
+    mfxI16   SegmentQPDelta[4];         /*!< QP delta for segment. */
+    mfxI16   CoeffTypeQPDelta[5];       /*!< QP delta for coefficient type (YDC, Y2AC, Y2DC, UVAC, UVDC). */
+    mfxU16   WriteIVFHeaders;           /*!< Set this option to ON to enable insertion of IVF container headers into bitstream. This is tri-state
+                                             option. See the CodingOptionValue enumerator for values of this option */
+    mfxU32   NumFramesForIVFHeader;     /*!< Specifies number of frames for IVF header when WriteIVFHeaders is ON. */
+    mfxU16   reserved[223];
+} mfxExtVP8CodingOption;
+MFX_PACK_END()
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/device_ids.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/device_ids.h
new file mode 100644 (file)
index 0000000..0f00849
--- /dev/null
@@ -0,0 +1,428 @@
+/*############################################################################
+  # Copyright (C) 2017-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_LINUX_DEVICE_IDS_H_
+#define DISPATCHER_LINUX_DEVICE_IDS_H_
+
+// Tables from:
+//   https://github.com/Intel-Media-SDK/MediaSDK/blob/master/_studio/shared/src/libmfx_core_vaapi.cpp
+//   https://github.com/Intel-Media-SDK/MediaSDK/blob/master/_studio/shared/include/mfxstructures-int.h
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+enum eMFXHWType {
+    MFX_HW_UNKNOWN = 0,
+    MFX_HW_SNB     = 0x300000,
+
+    MFX_HW_IVB = 0x400000,
+
+    MFX_HW_HSW     = 0x500000,
+    MFX_HW_HSW_ULT = 0x500001,
+
+    MFX_HW_VLV = 0x600000,
+
+    MFX_HW_BDW = 0x700000,
+
+    MFX_HW_CHT = 0x800000,
+
+    MFX_HW_SCL = 0x900000,
+
+    MFX_HW_APL = 0x1000000,
+
+    MFX_HW_KBL = 0x1100000,
+    MFX_HW_GLK = MFX_HW_KBL + 1,
+    MFX_HW_CFL = MFX_HW_KBL + 2,
+
+    MFX_HW_CNL    = 0x1200000,
+    MFX_HW_ICL    = 0x1400000,
+    MFX_HW_ICL_LP = MFX_HW_ICL + 1,
+
+    MFX_HW_JSL = 0x1500001,
+    MFX_HW_EHL = 0x1500002,
+};
+
+enum eMFXGTConfig { MFX_GT_UNKNOWN = 0, MFX_GT1 = 1, MFX_GT2 = 2, MFX_GT3 = 3, MFX_GT4 = 4 };
+
+typedef struct {
+    unsigned int device_id;
+    eMFXHWType platform;
+    eMFXGTConfig config;
+} mfx_device_item;
+
+// list of legal dev ID for Intel's graphics
+static const mfx_device_item listLegalDevIDs[] = {
+    /*IVB*/
+    { 0x0156, MFX_HW_IVB, MFX_GT1 }, /* GT1 mobile */
+    { 0x0166, MFX_HW_IVB, MFX_GT2 }, /* GT2 mobile */
+    { 0x0152, MFX_HW_IVB, MFX_GT1 }, /* GT1 desktop */
+    { 0x0162, MFX_HW_IVB, MFX_GT2 }, /* GT2 desktop */
+    { 0x015a, MFX_HW_IVB, MFX_GT1 }, /* GT1 server */
+    { 0x016a, MFX_HW_IVB, MFX_GT2 }, /* GT2 server */
+    /*HSW*/
+    { 0x0402, MFX_HW_HSW, MFX_GT1 }, /* GT1 desktop */
+    { 0x0412, MFX_HW_HSW, MFX_GT2 }, /* GT2 desktop */
+    { 0x0422, MFX_HW_HSW, MFX_GT2 }, /* GT2 desktop */
+    { 0x041e, MFX_HW_HSW, MFX_GT2 }, /* Core i3-4130 */
+    { 0x040a, MFX_HW_HSW, MFX_GT1 }, /* GT1 server */
+    { 0x041a, MFX_HW_HSW, MFX_GT2 }, /* GT2 server */
+    { 0x042a, MFX_HW_HSW, MFX_GT2 }, /* GT2 server */
+    { 0x0406, MFX_HW_HSW, MFX_GT1 }, /* GT1 mobile */
+    { 0x0416, MFX_HW_HSW, MFX_GT2 }, /* GT2 mobile */
+    { 0x0426, MFX_HW_HSW, MFX_GT2 }, /* GT2 mobile */
+    { 0x0C02, MFX_HW_HSW, MFX_GT1 }, /* SDV GT1 desktop */
+    { 0x0C12, MFX_HW_HSW, MFX_GT2 }, /* SDV GT2 desktop */
+    { 0x0C22, MFX_HW_HSW, MFX_GT2 }, /* SDV GT2 desktop */
+    { 0x0C0A, MFX_HW_HSW, MFX_GT1 }, /* SDV GT1 server */
+    { 0x0C1A, MFX_HW_HSW, MFX_GT2 }, /* SDV GT2 server */
+    { 0x0C2A, MFX_HW_HSW, MFX_GT2 }, /* SDV GT2 server */
+    { 0x0C06, MFX_HW_HSW, MFX_GT1 }, /* SDV GT1 mobile */
+    { 0x0C16, MFX_HW_HSW, MFX_GT2 }, /* SDV GT2 mobile */
+    { 0x0C26, MFX_HW_HSW, MFX_GT2 }, /* SDV GT2 mobile */
+    { 0x0A02, MFX_HW_HSW, MFX_GT1 }, /* ULT GT1 desktop */
+    { 0x0A12, MFX_HW_HSW, MFX_GT2 }, /* ULT GT2 desktop */
+    { 0x0A22, MFX_HW_HSW, MFX_GT2 }, /* ULT GT2 desktop */
+    { 0x0A0A, MFX_HW_HSW, MFX_GT1 }, /* ULT GT1 server */
+    { 0x0A1A, MFX_HW_HSW, MFX_GT2 }, /* ULT GT2 server */
+    { 0x0A2A, MFX_HW_HSW, MFX_GT2 }, /* ULT GT2 server */
+    { 0x0A06, MFX_HW_HSW, MFX_GT1 }, /* ULT GT1 mobile */
+    { 0x0A16, MFX_HW_HSW, MFX_GT2 }, /* ULT GT2 mobile */
+    { 0x0A26, MFX_HW_HSW, MFX_GT2 }, /* ULT GT2 mobile */
+    { 0x0D02, MFX_HW_HSW, MFX_GT1 }, /* CRW GT1 desktop */
+    { 0x0D12, MFX_HW_HSW, MFX_GT2 }, /* CRW GT2 desktop */
+    { 0x0D22, MFX_HW_HSW, MFX_GT2 }, /* CRW GT2 desktop */
+    { 0x0D0A, MFX_HW_HSW, MFX_GT1 }, /* CRW GT1 server */
+    { 0x0D1A, MFX_HW_HSW, MFX_GT2 }, /* CRW GT2 server */
+    { 0x0D2A, MFX_HW_HSW, MFX_GT2 }, /* CRW GT2 server */
+    { 0x0D06, MFX_HW_HSW, MFX_GT1 }, /* CRW GT1 mobile */
+    { 0x0D16, MFX_HW_HSW, MFX_GT2 }, /* CRW GT2 mobile */
+    { 0x0D26, MFX_HW_HSW, MFX_GT2 }, /* CRW GT2 mobile */
+    /* this dev IDs added per HSD 5264859 request  */
+    { 0x040B, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_B_GT1 */ /* Reserved */
+    { 0x041B, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_B_GT2*/
+    { 0x042B, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_B_GT3*/
+    { 0x040E, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_E_GT1*/ /* Reserved */
+    { 0x041E, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_E_GT2*/
+    { 0x042E, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_E_GT3*/
+
+    { 0x0C0B, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_SDV_B_GT1*/ /* Reserved */
+    { 0x0C1B, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_SDV_B_GT2*/
+    { 0x0C2B, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_SDV_B_GT3*/
+    { 0x0C0E, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_SDV_B_GT1*/ /* Reserved */
+    { 0x0C1E, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_SDV_B_GT2*/
+    { 0x0C2E, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_SDV_B_GT3*/
+
+    { 0x0A0B, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_ULT_B_GT1*/ /* Reserved */
+    { 0x0A1B, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_ULT_B_GT2*/
+    { 0x0A2B, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_ULT_B_GT3*/
+    { 0x0A0E, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_ULT_E_GT1*/ /* Reserved */
+    { 0x0A1E, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_ULT_E_GT2*/
+    { 0x0A2E, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_ULT_E_GT3*/
+
+    { 0x0D0B, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_CRW_B_GT1*/ /* Reserved */
+    { 0x0D1B, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_CRW_B_GT2*/
+    { 0x0D2B, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_CRW_B_GT3*/
+    { 0x0D0E, MFX_HW_HSW, MFX_GT1 },
+    /*HASWELL_CRW_E_GT1*/ /* Reserved */
+    { 0x0D1E, MFX_HW_HSW, MFX_GT2 }, /*HASWELL_CRW_E_GT2*/
+    { 0x0D2E, MFX_HW_HSW, MFX_GT3 }, /*HASWELL_CRW_E_GT3*/
+
+    /* VLV */
+    { 0x0f30, MFX_HW_VLV, MFX_GT1 }, /* VLV mobile */
+    { 0x0f31, MFX_HW_VLV, MFX_GT1 }, /* VLV mobile */
+    { 0x0f32, MFX_HW_VLV, MFX_GT1 }, /* VLV mobile */
+    { 0x0f33, MFX_HW_VLV, MFX_GT1 }, /* VLV mobile */
+    { 0x0157, MFX_HW_VLV, MFX_GT1 },
+    { 0x0155, MFX_HW_VLV, MFX_GT1 },
+
+    /* BDW */
+    /*GT3: */
+    { 0x162D, MFX_HW_BDW, MFX_GT3 },
+    { 0x162A, MFX_HW_BDW, MFX_GT3 },
+    /*GT2: */
+    { 0x161D, MFX_HW_BDW, MFX_GT2 },
+    { 0x161A, MFX_HW_BDW, MFX_GT2 },
+    /* GT1: */
+    { 0x160D, MFX_HW_BDW, MFX_GT1 },
+    { 0x160A, MFX_HW_BDW, MFX_GT1 },
+    /* BDW-ULT */
+    /* (16x2 - ULT, 16x6 - ULT, 16xB - Iris, 16xE - ULX) */
+    /*GT3: */
+    { 0x162E, MFX_HW_BDW, MFX_GT3 },
+    { 0x162B, MFX_HW_BDW, MFX_GT3 },
+    { 0x1626, MFX_HW_BDW, MFX_GT3 },
+    { 0x1622, MFX_HW_BDW, MFX_GT3 },
+    { 0x1636, MFX_HW_BDW, MFX_GT3 }, /* ULT */
+    { 0x163B, MFX_HW_BDW, MFX_GT3 }, /* Iris */
+    { 0x163E, MFX_HW_BDW, MFX_GT3 }, /* ULX */
+    { 0x1632, MFX_HW_BDW, MFX_GT3 }, /* ULT */
+    { 0x163A, MFX_HW_BDW, MFX_GT3 }, /* Server */
+    { 0x163D, MFX_HW_BDW, MFX_GT3 }, /* Workstation */
+
+    /* GT2: */
+    { 0x161E, MFX_HW_BDW, MFX_GT2 },
+    { 0x161B, MFX_HW_BDW, MFX_GT2 },
+    { 0x1616, MFX_HW_BDW, MFX_GT2 },
+    { 0x1612, MFX_HW_BDW, MFX_GT2 },
+    /* GT1: */
+    { 0x160E, MFX_HW_BDW, MFX_GT1 },
+    { 0x160B, MFX_HW_BDW, MFX_GT1 },
+    { 0x1606, MFX_HW_BDW, MFX_GT1 },
+    { 0x1602, MFX_HW_BDW, MFX_GT1 },
+
+    /* CHT */
+    { 0x22b0, MFX_HW_CHT, MFX_GT1 },
+    { 0x22b1, MFX_HW_CHT, MFX_GT1 },
+    { 0x22b2, MFX_HW_CHT, MFX_GT1 },
+    { 0x22b3, MFX_HW_CHT, MFX_GT1 },
+
+    /* SCL */
+    /* GT1F */
+    { 0x1902, MFX_HW_SCL, MFX_GT1 }, // DT, 2x1F, 510
+    { 0x1906, MFX_HW_SCL, MFX_GT1 }, // U-ULT, 2x1F, 510
+    { 0x190A, MFX_HW_SCL, MFX_GT1 }, // Server, 4x1F
+    { 0x190B, MFX_HW_SCL, MFX_GT1 },
+    { 0x190E, MFX_HW_SCL, MFX_GT1 }, // Y-ULX 2x1F
+    /*GT1.5*/
+    { 0x1913, MFX_HW_SCL, MFX_GT1 }, // U-ULT, 2x1.5
+    { 0x1915, MFX_HW_SCL, MFX_GT1 }, // Y-ULX, 2x1.5
+    { 0x1917, MFX_HW_SCL, MFX_GT1 }, // DT, 2x1.5
+    /* GT2 */
+    { 0x1912, MFX_HW_SCL, MFX_GT2 }, // DT, 2x2, 530
+    { 0x1916, MFX_HW_SCL, MFX_GT2 }, // U-ULD 2x2, 520
+    { 0x191A, MFX_HW_SCL, MFX_GT2 }, // 2x2,4x2, Server
+    { 0x191B, MFX_HW_SCL, MFX_GT2 }, // DT, 2x2, 530
+    { 0x191D, MFX_HW_SCL, MFX_GT2 }, // 4x2, WKS, P530
+    { 0x191E, MFX_HW_SCL, MFX_GT2 }, // Y-ULX, 2x2, P510,515
+    { 0x1921, MFX_HW_SCL, MFX_GT2 }, // U-ULT, 2x2F, 540
+    /* GT3 */
+    { 0x1923, MFX_HW_SCL, MFX_GT3 }, // U-ULT, 2x3, 535
+    { 0x1926, MFX_HW_SCL, MFX_GT3 }, // U-ULT, 2x3, 540 (15W)
+    { 0x1927, MFX_HW_SCL, MFX_GT3 }, // U-ULT, 2x3e, 550 (28W)
+    { 0x192A, MFX_HW_SCL, MFX_GT3 }, // Server, 2x3
+    { 0x192B, MFX_HW_SCL, MFX_GT3 }, // Halo 3e
+    { 0x192D, MFX_HW_SCL, MFX_GT3 },
+    /* GT4e*/
+    { 0x1932, MFX_HW_SCL, MFX_GT4 }, // DT
+    { 0x193A, MFX_HW_SCL, MFX_GT4 }, // SRV
+    { 0x193B, MFX_HW_SCL, MFX_GT4 }, // Halo
+    { 0x193D, MFX_HW_SCL, MFX_GT4 }, // WKS
+
+    /* APL */
+    { 0x0A84, MFX_HW_APL, MFX_GT1 },
+    { 0x0A85, MFX_HW_APL, MFX_GT1 },
+    { 0x0A86, MFX_HW_APL, MFX_GT1 },
+    { 0x0A87, MFX_HW_APL, MFX_GT1 },
+    { 0x1A84, MFX_HW_APL, MFX_GT1 },
+    { 0x1A85, MFX_HW_APL, MFX_GT1 },
+    { 0x5A84, MFX_HW_APL, MFX_GT1 },
+    { 0x5A85, MFX_HW_APL, MFX_GT1 },
+
+    /* KBL */
+    { 0x5902, MFX_HW_KBL, MFX_GT1 }, // DT GT1
+    { 0x5906, MFX_HW_KBL, MFX_GT1 }, // ULT GT1
+    { 0x5908, MFX_HW_KBL, MFX_GT1 }, // HALO GT1F
+    { 0x590A, MFX_HW_KBL, MFX_GT1 }, // SERV GT1
+    { 0x590B, MFX_HW_KBL, MFX_GT1 }, // HALO GT1
+    { 0x590E, MFX_HW_KBL, MFX_GT1 }, // ULX GT1
+    { 0x5912, MFX_HW_KBL, MFX_GT2 }, // DT GT2
+    { 0x5913, MFX_HW_KBL, MFX_GT1 }, // ULT GT1 5
+    { 0x5915, MFX_HW_KBL, MFX_GT1 }, // ULX GT1 5
+    { 0x5916, MFX_HW_KBL, MFX_GT2 }, // ULT GT2
+    { 0x5917, MFX_HW_KBL, MFX_GT2 }, // ULT GT2 R
+    { 0x591A, MFX_HW_KBL, MFX_GT2 }, // SERV GT2
+    { 0x591B, MFX_HW_KBL, MFX_GT2 }, // HALO GT2
+    { 0x591C, MFX_HW_KBL, MFX_GT2 }, // ULX GT2
+    { 0x591D, MFX_HW_KBL, MFX_GT2 }, // WRK GT2
+    { 0x591E, MFX_HW_KBL, MFX_GT2 }, // ULX GT2
+    { 0x5921, MFX_HW_KBL, MFX_GT2 }, // ULT GT2F
+    { 0x5923, MFX_HW_KBL, MFX_GT3 }, // ULT GT3
+    { 0x5926, MFX_HW_KBL, MFX_GT3 }, // ULT GT3 15W
+    { 0x5927, MFX_HW_KBL, MFX_GT3 }, // ULT GT3 28W
+    { 0x592A, MFX_HW_KBL, MFX_GT3 }, // SERV GT3
+    { 0x592B, MFX_HW_KBL, MFX_GT3 }, // HALO GT3
+    { 0x5932, MFX_HW_KBL, MFX_GT4 }, // DT GT4
+    { 0x593A, MFX_HW_KBL, MFX_GT4 }, // SERV GT4
+    { 0x593B, MFX_HW_KBL, MFX_GT4 }, // HALO GT4
+    { 0x593D, MFX_HW_KBL, MFX_GT4 }, // WRK GT4
+    { 0x87C0, MFX_HW_KBL, MFX_GT2 }, // ULX GT2
+
+    /* GLK */
+    { 0x3184, MFX_HW_GLK, MFX_GT1 },
+    { 0x3185, MFX_HW_GLK, MFX_GT1 },
+
+    /* CFL */
+    { 0x3E90, MFX_HW_CFL, MFX_GT1 },
+    { 0x3E91, MFX_HW_CFL, MFX_GT2 },
+    { 0x3E92, MFX_HW_CFL, MFX_GT2 },
+    { 0x3E93, MFX_HW_CFL, MFX_GT1 },
+    { 0x3E94, MFX_HW_CFL, MFX_GT2 },
+    { 0x3E96, MFX_HW_CFL, MFX_GT2 },
+    { 0x3E98, MFX_HW_CFL, MFX_GT2 },
+    { 0x3E99, MFX_HW_CFL, MFX_GT1 },
+    { 0x3E9A, MFX_HW_CFL, MFX_GT2 },
+    { 0x3E9C, MFX_HW_CFL, MFX_GT1 },
+    { 0x3E9B, MFX_HW_CFL, MFX_GT2 },
+    { 0x3EA5, MFX_HW_CFL, MFX_GT3 },
+    { 0x3EA6, MFX_HW_CFL, MFX_GT3 },
+    { 0x3EA7, MFX_HW_CFL, MFX_GT3 },
+    { 0x3EA8, MFX_HW_CFL, MFX_GT3 },
+    { 0x3EA9, MFX_HW_CFL, MFX_GT2 },
+    { 0x87CA, MFX_HW_CFL, MFX_GT2 },
+
+    /* WHL */
+    { 0x3EA0, MFX_HW_CFL, MFX_GT2 },
+    { 0x3EA1, MFX_HW_CFL, MFX_GT1 },
+    { 0x3EA2, MFX_HW_CFL, MFX_GT3 },
+    { 0x3EA3, MFX_HW_CFL, MFX_GT2 },
+    { 0x3EA4, MFX_HW_CFL, MFX_GT1 },
+
+    /* CML GT1 */
+    { 0x9b21, MFX_HW_CFL, MFX_GT1 },
+    { 0x9baa, MFX_HW_CFL, MFX_GT1 },
+    { 0x9bab, MFX_HW_CFL, MFX_GT1 },
+    { 0x9bac, MFX_HW_CFL, MFX_GT1 },
+    { 0x9ba0, MFX_HW_CFL, MFX_GT1 },
+    { 0x9ba5, MFX_HW_CFL, MFX_GT1 },
+    { 0x9ba8, MFX_HW_CFL, MFX_GT1 },
+    { 0x9ba4, MFX_HW_CFL, MFX_GT1 },
+    { 0x9ba2, MFX_HW_CFL, MFX_GT1 },
+
+    /* CML GT2 */
+    { 0x9b41, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bca, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bcb, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bcc, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bc0, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bc5, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bc8, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bc4, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bc2, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bc6, MFX_HW_CFL, MFX_GT2 },
+    { 0x9be6, MFX_HW_CFL, MFX_GT2 },
+    { 0x9bf6, MFX_HW_CFL, MFX_GT2 },
+
+    /* CNL */
+    { 0x5A51, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A52, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A5A, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A40, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A42, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A4A, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A4C, MFX_HW_CNL, MFX_GT1 },
+    { 0x5A50, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A54, MFX_HW_CNL, MFX_GT1 },
+    { 0x5A59, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A5C, MFX_HW_CNL, MFX_GT1 },
+    { 0x5A41, MFX_HW_CNL, MFX_GT2 },
+    { 0x5A44, MFX_HW_CNL, MFX_GT1 },
+    { 0x5A49, MFX_HW_CNL, MFX_GT2 },
+
+    /* ICL LP */
+    { 0xFF05, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A50, MFX_HW_ICL_LP, MFX_GT2 },
+    { 0x8A51, MFX_HW_ICL_LP, MFX_GT2 },
+    { 0x8A52, MFX_HW_ICL_LP, MFX_GT2 },
+    { 0x8A53, MFX_HW_ICL_LP, MFX_GT2 },
+    { 0x8A54, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A56, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A57, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A58, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A59, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A5A, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A5B, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A5C, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A5D, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A70, MFX_HW_ICL_LP, MFX_GT1 },
+    { 0x8A71, MFX_HW_ICL_LP, MFX_GT1 }, // GT05, but 1 ok in this context
+
+    /* JSL */
+    { 0x4E51, MFX_HW_JSL, MFX_GT2 },
+    { 0x4E55, MFX_HW_JSL, MFX_GT2 },
+    { 0x4E61, MFX_HW_JSL, MFX_GT2 },
+    { 0x4E71, MFX_HW_JSL, MFX_GT2 },
+
+    /* EHL */
+    { 0x4500, MFX_HW_EHL, MFX_GT2 },
+    { 0x4541, MFX_HW_EHL, MFX_GT2 },
+    { 0x4551, MFX_HW_EHL, MFX_GT2 },
+    { 0x4555, MFX_HW_EHL, MFX_GT2 },
+    { 0x4569, MFX_HW_EHL, MFX_GT2 },
+    { 0x4571, MFX_HW_EHL, MFX_GT2 },
+};
+
+typedef struct {
+    unsigned int vendor_id;
+    unsigned int device_id;
+    eMFXHWType platform;
+} Device;
+
+static inline eMFXHWType get_platform(unsigned int device_id) {
+    for (unsigned i = 0; i < sizeof(listLegalDevIDs) / sizeof(listLegalDevIDs[0]); ++i) {
+        if (listLegalDevIDs[i].device_id == device_id) {
+            return listLegalDevIDs[i].platform;
+        }
+    }
+    return MFX_HW_UNKNOWN;
+}
+
+static mfxStatus get_devices(std::vector<Device> &allDevices) {
+    const char *dir            = "/sys/class/drm";
+    const char *device_id_file = "/device/device";
+    const char *vendor_id_file = "/device/vendor";
+
+    int i = 0;
+    for (; i < 64; ++i) {
+        int ret;
+        Device device;
+        std::string path = std::string(dir) + "/renderD" + std::to_string(128 + i) + vendor_id_file;
+
+        FILE *file = fopen(path.c_str(), "r");
+        if (!file)
+            continue;
+        ret = fscanf(file, "%x", &device.vendor_id);
+        fclose(file);
+        if (ret != 1)
+            continue;
+
+        // Filter out non-Intel devices
+        if (device.vendor_id != 0x8086)
+            continue;
+
+        path = std::string(dir) + "/renderD" + std::to_string(128 + i) + device_id_file;
+        file = fopen(path.c_str(), "r");
+        if (!file)
+            continue;
+        ret = fscanf(file, "%x", &device.device_id);
+        fclose(file);
+        if (ret != 1)
+            continue;
+
+        device.platform = get_platform(device.device_id);
+
+        allDevices.emplace_back(device);
+    }
+
+    // sort by platform, unknown will appear at beginning
+    std::sort(allDevices.begin(), allDevices.end(), [](const Device &a, const Device &b) {
+        return a.platform < b.platform;
+    });
+
+    if (allDevices.size() == 0)
+        return MFX_ERR_NOT_FOUND;
+
+    return MFX_ERR_NONE;
+}
+
+#endif // DISPATCHER_LINUX_DEVICE_IDS_H_
\ No newline at end of file
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/libvpl.map b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/libvpl.map
new file mode 100644 (file)
index 0000000..dc36d34
--- /dev/null
@@ -0,0 +1,81 @@
+LIBVPL_2.0 {
+  global:
+    MFXInit;
+    MFXClose;
+    MFXQueryIMPL;
+    MFXQueryVersion;
+
+    MFXJoinSession;
+    MFXDisjoinSession;
+    MFXCloneSession;
+    MFXSetPriority;
+    MFXGetPriority;
+
+    MFXVideoCORE_SetFrameAllocator;
+    MFXVideoCORE_SetHandle;
+    MFXVideoCORE_GetHandle;
+    MFXVideoCORE_QueryPlatform;
+    MFXVideoCORE_SyncOperation;
+
+    MFXVideoENCODE_Query;
+    MFXVideoENCODE_QueryIOSurf;
+    MFXVideoENCODE_Init;
+    MFXVideoENCODE_Reset;
+    MFXVideoENCODE_Close;
+    MFXVideoENCODE_GetVideoParam;
+    MFXVideoENCODE_GetEncodeStat;
+    MFXVideoENCODE_EncodeFrameAsync;
+
+    MFXVideoDECODE_Query;
+    MFXVideoDECODE_DecodeHeader;
+    MFXVideoDECODE_QueryIOSurf;
+    MFXVideoDECODE_Init;
+    MFXVideoDECODE_Reset;
+    MFXVideoDECODE_Close;
+    MFXVideoDECODE_GetVideoParam;
+    MFXVideoDECODE_GetDecodeStat;
+    MFXVideoDECODE_SetSkipMode;
+    MFXVideoDECODE_GetPayload;
+    MFXVideoDECODE_DecodeFrameAsync;
+
+    MFXVideoVPP_Query;
+    MFXVideoVPP_QueryIOSurf;
+    MFXVideoVPP_Init;
+    MFXVideoVPP_Reset;
+    MFXVideoVPP_Close;
+
+    MFXVideoVPP_GetVideoParam;
+    MFXVideoVPP_GetVPPStat;
+    MFXVideoVPP_RunFrameVPPAsync;
+
+    MFXInitEx;
+
+    MFXLoad;
+    MFXUnload;
+    MFXCreateConfig;
+    MFXSetConfigFilterProperty;
+    MFXEnumImplementations;
+    MFXCreateSession;
+    MFXDispReleaseImplDescription;
+
+    MFXMemory_GetSurfaceForVPP;
+    MFXMemory_GetSurfaceForEncode;
+    MFXMemory_GetSurfaceForDecode;
+
+  local:
+    *;
+};
+
+LIBVPL_2.1 {
+  global:
+    MFXMemory_GetSurfaceForVPPOut;
+    MFXVideoDECODE_VPP_Init;
+    MFXVideoDECODE_VPP_DecodeFrameAsync;
+    MFXVideoDECODE_VPP_Reset;
+    MFXVideoDECODE_VPP_GetChannelParam;
+    MFXVideoDECODE_VPP_Close;
+    MFXVideoVPP_ProcessFrameAsync;
+
+  local:
+    *;
+} LIBVPL_2.0;
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxloader.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxloader.cpp
new file mode 100644 (file)
index 0000000..6c35d89
--- /dev/null
@@ -0,0 +1,699 @@
+/*############################################################################
+  # Copyright (C) 2017-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <utility>
+#include <vector>
+
+#include "vpl/mfxvideo.h"
+
+#include "linux/device_ids.h"
+#include "linux/mfxloader.h"
+
+namespace MFX {
+
+#if defined(__x86_64__)
+    #define LIBMFXSW "libmfxsw64.so.1"
+    #define LIBMFXHW "libmfxhw64.so.1"
+
+    #define ONEVPLSW "libvplswref64.so.1"
+    #define ONEVPLHW "libmfx-gen.so.1.2"
+#else
+    #error Unsupported architecture
+#endif
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) e##func_name,
+
+enum Function {
+    eMFXInit,
+    eMFXInitEx,
+    eMFXClose,
+    eMFXJoinSession,
+#include "linux/mfxvideo_functions.h"
+    eFunctionsNum,
+    eNoMoreFunctions = eFunctionsNum
+};
+
+// new functions for API 2.x
+enum Function2 {
+    // 2.0
+    eMFXQueryImplsDescription = 0,
+    eMFXReleaseImplDescription,
+    eMFXMemory_GetSurfaceForVPP,
+    eMFXMemory_GetSurfaceForEncode,
+    eMFXMemory_GetSurfaceForDecode,
+    eMFXInitialize,
+
+    // 2.1
+    eMFXMemory_GetSurfaceForVPPOut,
+    eMFXVideoDECODE_VPP_Init,
+    eMFXVideoDECODE_VPP_DecodeFrameAsync,
+    eMFXVideoDECODE_VPP_Reset,
+    eMFXVideoDECODE_VPP_GetChannelParam,
+    eMFXVideoDECODE_VPP_Close,
+    eMFXVideoVPP_ProcessFrameAsync,
+
+    eFunctionsNum2,
+};
+
+struct FunctionsTable {
+    Function id;
+    const char *name;
+    mfxVersion version;
+};
+
+struct FunctionsTable2 {
+    Function2 id;
+    const char *name;
+    mfxVersion version;
+};
+
+#define VERSION(major, minor) \
+    {                         \
+        { minor, major }      \
+    }
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    { e##func_name, #func_name, API_VERSION },
+
+static const FunctionsTable g_mfxFuncTable[] = {
+    { eMFXInit, "MFXInit", VERSION(1, 0) },
+    { eMFXInitEx, "MFXInitEx", VERSION(1, 14) },
+    { eMFXClose, "MFXClose", VERSION(1, 0) },
+    { eMFXJoinSession, "MFXJoinSession", VERSION(1, 1) },
+#include "linux/mfxvideo_functions.h" // NOLINT(build/include)
+    { eNoMoreFunctions }
+};
+
+static const FunctionsTable2 g_mfxFuncTable2[] = {
+    { eMFXQueryImplsDescription, "MFXQueryImplsDescription", VERSION(2, 0) },
+    { eMFXReleaseImplDescription, "MFXReleaseImplDescription", VERSION(2, 0) },
+    { eMFXMemory_GetSurfaceForVPP, "MFXMemory_GetSurfaceForVPP", VERSION(2, 0) },
+    { eMFXMemory_GetSurfaceForEncode, "MFXMemory_GetSurfaceForEncode", VERSION(2, 0) },
+    { eMFXMemory_GetSurfaceForDecode, "MFXMemory_GetSurfaceForDecode", VERSION(2, 0) },
+    { eMFXInitialize, "MFXInitialize", VERSION(2, 0) },
+
+    { eMFXMemory_GetSurfaceForVPPOut, "MFXMemory_GetSurfaceForVPPOut", VERSION(2, 1) },
+    { eMFXVideoDECODE_VPP_Init, "MFXVideoDECODE_VPP_Init", VERSION(2, 1) },
+    { eMFXVideoDECODE_VPP_DecodeFrameAsync, "MFXVideoDECODE_VPP_DecodeFrameAsync", VERSION(2, 1) },
+    { eMFXVideoDECODE_VPP_Reset, "MFXVideoDECODE_VPP_Reset", VERSION(2, 1) },
+    { eMFXVideoDECODE_VPP_GetChannelParam, "MFXVideoDECODE_VPP_GetChannelParam", VERSION(2, 1) },
+    { eMFXVideoDECODE_VPP_Close, "MFXVideoDECODE_VPP_Close", VERSION(2, 1) },
+    { eMFXVideoVPP_ProcessFrameAsync, "MFXVideoVPP_ProcessFrameAsync", VERSION(2, 1) },
+};
+
+class LoaderCtx {
+public:
+    mfxStatus Init(mfxInitParam &par,
+                   mfxInitializationParam &vplParam,
+                   mfxU16 *pDeviceID,
+                   char *dllName);
+    mfxStatus Close();
+
+    inline void *getFunction(Function func) const {
+        return m_table[func];
+    }
+
+    inline void *getFunction2(Function2 func) const {
+        return m_table2[func];
+    }
+
+    inline mfxSession getSession() const {
+        return m_session;
+    }
+
+    inline mfxIMPL getImpl() const {
+        return m_implementation;
+    }
+
+    inline mfxVersion getVersion() const {
+        return m_version;
+    }
+
+private:
+    std::shared_ptr<void> m_dlh;
+    mfxVersion m_version{};
+    mfxIMPL m_implementation{};
+    mfxSession m_session = nullptr;
+    void *m_table[eFunctionsNum]{};
+    void *m_table2[eFunctionsNum2]{};
+};
+
+std::shared_ptr<void> make_dlopen(const char *filename, int flags) {
+    return std::shared_ptr<void>(dlopen(filename, flags), [](void *handle) {
+        if (handle)
+            dlclose(handle);
+    });
+}
+
+mfxStatus LoaderCtx::Init(mfxInitParam &par,
+                          mfxInitializationParam &vplParam,
+                          mfxU16 *pDeviceID,
+                          char *dllName) {
+    mfxStatus mfx_res = MFX_ERR_NONE;
+
+    std::vector<std::string> libs;
+    std::vector<Device> devices;
+    eMFXHWType msdk_platform;
+
+    // query graphics device_id
+    // if it is found on list of legacy devices, load MSDK RT
+    // otherwise load oneVPL RT
+    mfxU16 deviceID = 0;
+    mfx_res         = get_devices(devices);
+    if (mfx_res == MFX_ERR_NOT_FOUND) {
+        // query failed
+        msdk_platform = MFX_HW_UNKNOWN;
+    }
+    else {
+        // query succeeded:
+        //   may be a valid platform from listLegalDevIDs[] or MFX_HW_UNKNOWN
+        //   if underlying device_id is unrecognized (i.e. new platform)
+        msdk_platform = devices[0].platform;
+        deviceID      = devices[0].device_id;
+    }
+
+    if (pDeviceID)
+        *pDeviceID = deviceID;
+
+    if (dllName) {
+        // attempt to load only this DLL, fail if unsuccessful
+        std::string libToLoad(dllName);
+        libs.emplace_back(libToLoad);
+    }
+    else {
+        mfxIMPL implType = MFX_IMPL_BASETYPE(par.Implementation);
+        // add HW lib
+        if (implType == MFX_IMPL_AUTO || implType == MFX_IMPL_AUTO_ANY ||
+            (implType & MFX_IMPL_HARDWARE) || (implType & MFX_IMPL_HARDWARE_ANY)) {
+            if (msdk_platform == MFX_HW_UNKNOWN) {
+                // if not on list of known MSDK platforms, prefer oneVPL
+                libs.emplace_back(ONEVPLHW);
+                libs.emplace_back(MFX_MODULES_DIR "/" ONEVPLHW);
+            }
+
+            // use MSDK (fallback if oneVPL is not installed)
+            libs.emplace_back(LIBMFXHW);
+            libs.emplace_back(MFX_MODULES_DIR "/" LIBMFXHW);
+        }
+
+        // add SW lib (oneVPL only)
+        if (implType == MFX_IMPL_AUTO || implType == MFX_IMPL_AUTO_ANY ||
+            (implType & MFX_IMPL_SOFTWARE)) {
+            libs.emplace_back(ONEVPLSW);
+            libs.emplace_back(MFX_MODULES_DIR "/" ONEVPLSW);
+        }
+    }
+
+    // fail if libs is empty (invalid Implementation)
+    mfx_res = MFX_ERR_UNSUPPORTED;
+
+    for (auto &lib : libs) {
+        std::shared_ptr<void> hdl = make_dlopen(lib.c_str(), RTLD_LOCAL | RTLD_NOW);
+        if (hdl) {
+            do {
+                /* Loading functions table */
+                bool wrong_version = false;
+                for (int i = 0; i < eFunctionsNum; ++i) {
+                    assert(i == g_mfxFuncTable[i].id);
+                    m_table[i] = dlsym(hdl.get(), g_mfxFuncTable[i].name);
+                    if (!m_table[i] && ((g_mfxFuncTable[i].version <= par.Version))) {
+                        wrong_version = true;
+                        break;
+                    }
+                }
+
+                // if version >= 2.0, load these functions as well
+                if (par.Version.Major >= 2) {
+                    for (int i = 0; i < eFunctionsNum2; ++i) {
+                        assert(i == g_mfxFuncTable2[i].id);
+                        m_table2[i] = dlsym(hdl.get(), g_mfxFuncTable2[i].name);
+                        if (!m_table2[i] && (g_mfxFuncTable2[i].version <= par.Version)) {
+                            wrong_version = true;
+                            break;
+                        }
+                    }
+                }
+
+                if (wrong_version) {
+                    mfx_res = MFX_ERR_UNSUPPORTED;
+                    break;
+                }
+
+                if (par.Version.Major >= 2) {
+                    // for API >= 2.0 call MFXInitialize instead of MFXInitEx
+                    mfx_res =
+                        ((decltype(MFXInitialize) *)m_table2[eMFXInitialize])(vplParam, &m_session);
+                }
+                else {
+                    if (m_table[eMFXInitEx]) {
+                        // initialize with MFXInitEx if present (API >= 1.14)
+                        mfx_res = ((decltype(MFXInitEx) *)m_table[eMFXInitEx])(par, &m_session);
+                    }
+                    else {
+                        // initialize with MFXInit for API < 1.14
+                        mfx_res = ((decltype(MFXInit) *)m_table[eMFXInit])(par.Implementation,
+                                                                           &(par.Version),
+                                                                           &m_session);
+                    }
+                }
+
+                if (MFX_ERR_NONE != mfx_res) {
+                    break;
+                }
+
+                // Below we just get some data and double check that we got what we have expected
+                // to get. Some of these checks are done inside mediasdk init function
+                mfx_res =
+                    ((decltype(MFXQueryVersion) *)m_table[eMFXQueryVersion])(m_session, &m_version);
+                if (MFX_ERR_NONE != mfx_res) {
+                    break;
+                }
+
+                if (m_version < par.Version) {
+                    mfx_res = MFX_ERR_UNSUPPORTED;
+                    break;
+                }
+
+                mfx_res = ((decltype(MFXQueryIMPL) *)m_table[eMFXQueryIMPL])(m_session,
+                                                                             &m_implementation);
+                if (MFX_ERR_NONE != mfx_res) {
+                    mfx_res = MFX_ERR_UNSUPPORTED;
+                    break;
+                }
+            } while (false);
+
+            if (MFX_ERR_NONE == mfx_res) {
+                m_dlh = std::move(hdl);
+                break;
+            }
+            else {
+                Close();
+            }
+        }
+    }
+
+    return mfx_res;
+}
+
+mfxStatus LoaderCtx::Close() {
+    auto proc         = (decltype(MFXClose) *)m_table[eMFXClose];
+    mfxStatus mfx_res = (proc) ? (*proc)(m_session) : MFX_ERR_NONE;
+
+    m_implementation = {};
+    m_version        = {};
+    m_session        = nullptr;
+    std::fill(std::begin(m_table), std::end(m_table), nullptr);
+    return mfx_res;
+}
+
+} // namespace MFX
+
+// internal function - load a specific DLL, return unsupported if it fails
+// vplParam is required for API >= 2.0 (load via MFXInitialize)
+mfxStatus MFXInitEx2(mfxVersion version,
+                     mfxInitializationParam vplParam,
+                     mfxIMPL hwImpl,
+                     mfxSession *session,
+                     mfxU16 *deviceID,
+                     char *dllName) {
+    if (!session)
+        return MFX_ERR_NULL_PTR;
+
+    *deviceID = 0;
+
+    // fill minimal 1.x parameters for Init to choose correct initialization path
+    mfxInitParam par = {};
+    par.Version      = version;
+
+    // select first adapter if not specified
+    // only relevant for MSDK-via-MFXLoad path
+    if (!hwImpl)
+        hwImpl = MFX_IMPL_HARDWARE;
+
+    switch (vplParam.AccelerationMode) {
+        case MFX_ACCEL_MODE_NA:
+            par.Implementation = MFX_IMPL_SOFTWARE;
+            break;
+        case MFX_ACCEL_MODE_VIA_D3D9:
+            par.Implementation = hwImpl | MFX_IMPL_VIA_D3D9;
+            break;
+        case MFX_ACCEL_MODE_VIA_D3D11:
+            par.Implementation = hwImpl | MFX_IMPL_VIA_D3D11;
+            break;
+        case MFX_ACCEL_MODE_VIA_VAAPI:
+            par.Implementation = hwImpl | MFX_IMPL_VIA_VAAPI;
+            break;
+        default:
+            par.Implementation = hwImpl;
+            break;
+    }
+
+    // also pass extBuf array (if any) to MFXInitEx for 1.x API
+    par.NumExtParam = vplParam.NumExtParam;
+    par.ExtParam    = (vplParam.NumExtParam ? vplParam.ExtParam : nullptr);
+
+    try {
+        std::unique_ptr<MFX::LoaderCtx> loader;
+
+        loader.reset(new MFX::LoaderCtx{});
+
+        mfxStatus mfx_res = loader->Init(par, vplParam, deviceID, dllName);
+        if (MFX_ERR_NONE == mfx_res) {
+            *session = (mfxSession)loader.release();
+        }
+        else {
+            *session = nullptr;
+        }
+
+        return mfx_res;
+    }
+    catch (...) {
+        return MFX_ERR_MEMORY_ALLOC;
+    }
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+mfxStatus MFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session) {
+    mfxInitParam par{};
+
+    par.Implementation = impl;
+    if (ver) {
+        par.Version = *ver;
+    }
+    else {
+        par.Version = VERSION(MFX_VERSION_MAJOR, MFX_VERSION_MINOR);
+    }
+
+    return MFXInitEx(par, session);
+}
+
+mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session) {
+    if (!session)
+        return MFX_ERR_NULL_PTR;
+
+    const mfxIMPL implMethod        = par.Implementation & (MFX_IMPL_VIA_ANY - 1);
+    mfxInitializationParam vplParam = {};
+    if (implMethod == MFX_IMPL_SOFTWARE) {
+        vplParam.AccelerationMode = MFX_ACCEL_MODE_NA;
+    }
+    else {
+        vplParam.AccelerationMode = MFX_ACCEL_MODE_VIA_VAAPI;
+    }
+
+    try {
+        std::unique_ptr<MFX::LoaderCtx> loader;
+
+        loader.reset(new MFX::LoaderCtx{});
+
+        mfxStatus mfx_res = loader->Init(par, vplParam, nullptr, nullptr);
+        if (MFX_ERR_NONE == mfx_res) {
+            *session = (mfxSession)loader.release();
+        }
+        else {
+            *session = nullptr;
+        }
+
+        return mfx_res;
+    }
+    catch (...) {
+        return MFX_ERR_MEMORY_ALLOC;
+    }
+}
+
+mfxStatus MFXClose(mfxSession session) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    try {
+        std::unique_ptr<MFX::LoaderCtx> loader((MFX::LoaderCtx *)session);
+        mfxStatus mfx_res = loader->Close();
+
+        if (mfx_res == MFX_ERR_UNDEFINED_BEHAVIOR) {
+            // It is possible, that there is an active child session.
+            // Can't unload library in this case.
+            loader.release();
+        }
+        return mfx_res;
+    }
+    catch (...) {
+        return MFX_ERR_MEMORY_ALLOC;
+    }
+}
+
+// passthrough functions to implementation
+mfxStatus MFXMemory_GetSurfaceForVPP(mfxSession session, mfxFrameSurface1 **surface) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc = (decltype(MFXMemory_GetSurfaceForVPP) *)loader->getFunction2(
+        MFX::eMFXMemory_GetSurfaceForVPP);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), surface);
+}
+
+mfxStatus MFXMemory_GetSurfaceForVPPOut(mfxSession session, mfxFrameSurface1 **surface) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc = (decltype(MFXMemory_GetSurfaceForVPPOut) *)loader->getFunction2(
+        MFX::eMFXMemory_GetSurfaceForVPPOut);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), surface);
+}
+
+mfxStatus MFXMemory_GetSurfaceForEncode(mfxSession session, mfxFrameSurface1 **surface) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc = (decltype(MFXMemory_GetSurfaceForEncode) *)loader->getFunction2(
+        MFX::eMFXMemory_GetSurfaceForEncode);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), surface);
+}
+
+mfxStatus MFXMemory_GetSurfaceForDecode(mfxSession session, mfxFrameSurface1 **surface) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc = (decltype(MFXMemory_GetSurfaceForDecode) *)loader->getFunction2(
+        MFX::eMFXMemory_GetSurfaceForDecode);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), surface);
+}
+
+mfxStatus MFXVideoDECODE_VPP_Init(mfxSession session,
+                                  mfxVideoParam *decode_par,
+                                  mfxVideoChannelParam **vpp_par_array,
+                                  mfxU32 num_vpp_par) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc =
+        (decltype(MFXVideoDECODE_VPP_Init) *)loader->getFunction2(MFX::eMFXVideoDECODE_VPP_Init);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), decode_par, vpp_par_array, num_vpp_par);
+}
+
+mfxStatus MFXVideoDECODE_VPP_DecodeFrameAsync(mfxSession session,
+                                              mfxBitstream *bs,
+                                              mfxU32 *skip_channels,
+                                              mfxU32 num_skip_channels,
+                                              mfxSurfaceArray **surf_array_out) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc = (decltype(MFXVideoDECODE_VPP_DecodeFrameAsync) *)loader->getFunction2(
+        MFX::eMFXVideoDECODE_VPP_DecodeFrameAsync);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), bs, skip_channels, num_skip_channels, surf_array_out);
+}
+
+mfxStatus MFXVideoDECODE_VPP_Reset(mfxSession session,
+                                   mfxVideoParam *decode_par,
+                                   mfxVideoChannelParam **vpp_par_array,
+                                   mfxU32 num_vpp_par) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc =
+        (decltype(MFXVideoDECODE_VPP_Reset) *)loader->getFunction2(MFX::eMFXVideoDECODE_VPP_Reset);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), decode_par, vpp_par_array, num_vpp_par);
+}
+
+mfxStatus MFXVideoDECODE_VPP_GetChannelParam(mfxSession session,
+                                             mfxVideoChannelParam *par,
+                                             mfxU32 channel_id) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc = (decltype(MFXVideoDECODE_VPP_GetChannelParam) *)loader->getFunction2(
+        MFX::eMFXVideoDECODE_VPP_GetChannelParam);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), par, channel_id);
+}
+
+mfxStatus MFXVideoDECODE_VPP_Close(mfxSession session) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc =
+        (decltype(MFXVideoDECODE_VPP_Close) *)loader->getFunction2(MFX::eMFXVideoDECODE_VPP_Close);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession());
+}
+
+mfxStatus MFXVideoVPP_ProcessFrameAsync(mfxSession session,
+                                        mfxFrameSurface1 *in,
+                                        mfxFrameSurface1 **out) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+
+    auto proc = (decltype(MFXVideoVPP_ProcessFrameAsync) *)loader->getFunction2(
+        MFX::eMFXVideoVPP_ProcessFrameAsync);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), in, out);
+}
+
+mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session) {
+    if (!session || !child_session) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    MFX::LoaderCtx *loader       = (MFX::LoaderCtx *)session;
+    MFX::LoaderCtx *child_loader = (MFX::LoaderCtx *)child_session;
+
+    if (loader->getVersion().Version != child_loader->getVersion().Version) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    auto proc = (decltype(MFXJoinSession) *)loader->getFunction(MFX::eMFXJoinSession);
+    if (!proc) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    return (*proc)(loader->getSession(), child_loader->getSession());
+}
+
+mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone) {
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
+    mfxVersion version     = loader->getVersion();
+
+    // initialize the clone session
+    // currently supported for 1.x API only
+    // for 2.x runtimes, need to use RT implementation (passthrough)
+    if (version.Major == 1) {
+        mfxStatus mfx_res = MFXInit(loader->getImpl(), &version, clone);
+        if (MFX_ERR_NONE != mfx_res) {
+            return mfx_res;
+        }
+
+        // join the sessions
+        mfx_res = MFXJoinSession(session, *clone);
+        if (MFX_ERR_NONE != mfx_res) {
+            MFXClose(*clone);
+            *clone = nullptr;
+            return mfx_res;
+        }
+    }
+    else {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list)    \
+    return_value MFX_CDECL func_name formal_param_list {                           \
+        /* get the function's address and make a call */                           \
+        if (!session)                                                              \
+            return MFX_ERR_INVALID_HANDLE;                                         \
+                                                                                   \
+        MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;                        \
+                                                                                   \
+        auto proc = (decltype(func_name) *)loader->getFunction(MFX::e##func_name); \
+        if (!proc)                                                                 \
+            return MFX_ERR_INVALID_HANDLE;                                         \
+                                                                                   \
+        /* get the real session pointer */                                         \
+        session = loader->getSession();                                            \
+        /* pass down the call */                                                   \
+        return (*proc)actual_param_list;                                           \
+    }
+
+#include "linux/mfxvideo_functions.h" // NOLINT(build/include)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxloader.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxloader.h
new file mode 100644 (file)
index 0000000..a48bac7
--- /dev/null
@@ -0,0 +1,26 @@
+/*############################################################################
+  # Copyright (C) 2017-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_LINUX_MFXLOADER_H_
+#define DISPATCHER_LINUX_MFXLOADER_H_
+
+#include <limits.h>
+
+#include <list>
+#include <sstream>
+#include <string>
+
+#include "vpl/mfxdefs.h"
+
+inline bool operator<(const mfxVersion &lhs, const mfxVersion &rhs) {
+    return (lhs.Major < rhs.Major || (lhs.Major == rhs.Major && lhs.Minor < rhs.Minor));
+}
+
+inline bool operator<=(const mfxVersion &lhs, const mfxVersion &rhs) {
+    return (lhs < rhs || (lhs.Major == rhs.Major && lhs.Minor == rhs.Minor));
+}
+
+#endif // DISPATCHER_LINUX_MFXLOADER_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxvideo_functions.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/linux/mfxvideo_functions.h
new file mode 100644 (file)
index 0000000..c7a5b8a
--- /dev/null
@@ -0,0 +1,180 @@
+/*############################################################################
+  # Copyright (C) 2017-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+//
+// WARNING:
+// this file doesn't contain an include guard by design.
+// The file may be included into a source file many times.
+// That is why this header doesn't contain any include directive.
+// Please, do no try to fix it.
+//
+// NOLINT(build/header_guard)
+
+// Use define API_VERSION to set the API of functions listed further
+// When new functions are added new section with functions declarations must be started with updated define
+
+//
+// API version 1.0 functions
+//
+
+// API version where a function is added. Minor value should precedes the major value
+#define API_VERSION \
+    {               \
+        { 0, 1 }    \
+    }
+
+FUNCTION(mfxStatus, MFXQueryIMPL, (mfxSession session, mfxIMPL *impl), (session, impl))
+FUNCTION(mfxStatus, MFXQueryVersion, (mfxSession session, mfxVersion *version), (session, version))
+
+// CORE interface functions
+FUNCTION(mfxStatus,
+         MFXVideoCORE_SetFrameAllocator,
+         (mfxSession session, mfxFrameAllocator *allocator),
+         (session, allocator))
+FUNCTION(mfxStatus,
+         MFXVideoCORE_SetHandle,
+         (mfxSession session, mfxHandleType type, mfxHDL hdl),
+         (session, type, hdl))
+FUNCTION(mfxStatus,
+         MFXVideoCORE_GetHandle,
+         (mfxSession session, mfxHandleType type, mfxHDL *hdl),
+         (session, type, hdl))
+
+FUNCTION(mfxStatus,
+         MFXVideoCORE_SyncOperation,
+         (mfxSession session, mfxSyncPoint syncp, mfxU32 wait),
+         (session, syncp, wait))
+
+// ENCODE interface functions
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_Query,
+         (mfxSession session, mfxVideoParam *in, mfxVideoParam *out),
+         (session, in, out))
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_QueryIOSurf,
+         (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request),
+         (session, par, request))
+FUNCTION(mfxStatus, MFXVideoENCODE_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoENCODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoENCODE_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_GetVideoParam,
+         (mfxSession session, mfxVideoParam *par),
+         (session, par))
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_GetEncodeStat,
+         (mfxSession session, mfxEncodeStat *stat),
+         (session, stat))
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_EncodeFrameAsync,
+         (mfxSession session,
+          mfxEncodeCtrl *ctrl,
+          mfxFrameSurface1 *surface,
+          mfxBitstream *bs,
+          mfxSyncPoint *syncp),
+         (session, ctrl, surface, bs, syncp))
+
+// DECODE interface functions
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_Query,
+         (mfxSession session, mfxVideoParam *in, mfxVideoParam *out),
+         (session, in, out))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_DecodeHeader,
+         (mfxSession session, mfxBitstream *bs, mfxVideoParam *par),
+         (session, bs, par))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_QueryIOSurf,
+         (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request),
+         (session, par, request))
+FUNCTION(mfxStatus, MFXVideoDECODE_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_GetVideoParam,
+         (mfxSession session, mfxVideoParam *par),
+         (session, par))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_GetDecodeStat,
+         (mfxSession session, mfxDecodeStat *stat),
+         (session, stat))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_SetSkipMode,
+         (mfxSession session, mfxSkipMode mode),
+         (session, mode))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_GetPayload,
+         (mfxSession session, mfxU64 *ts, mfxPayload *payload),
+         (session, ts, payload))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_DecodeFrameAsync,
+         (mfxSession session,
+          mfxBitstream *bs,
+          mfxFrameSurface1 *surface_work,
+          mfxFrameSurface1 **surface_out,
+          mfxSyncPoint *syncp),
+         (session, bs, surface_work, surface_out, syncp))
+
+// VPP interface functions
+FUNCTION(mfxStatus,
+         MFXVideoVPP_Query,
+         (mfxSession session, mfxVideoParam *in, mfxVideoParam *out),
+         (session, in, out))
+FUNCTION(mfxStatus,
+         MFXVideoVPP_QueryIOSurf,
+         (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request),
+         (session, par, request))
+FUNCTION(mfxStatus, MFXVideoVPP_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus,
+         MFXVideoVPP_GetVideoParam,
+         (mfxSession session, mfxVideoParam *par),
+         (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_GetVPPStat, (mfxSession session, mfxVPPStat *stat), (session, stat))
+FUNCTION(mfxStatus,
+         MFXVideoVPP_RunFrameVPPAsync,
+         (mfxSession session,
+          mfxFrameSurface1 *in,
+          mfxFrameSurface1 *out,
+          mfxExtVppAuxData *aux,
+          mfxSyncPoint *syncp),
+         (session, in, out, aux, syncp))
+
+#undef API_VERSION
+
+//
+// API version 1.1 functions
+//
+
+#define API_VERSION \
+    {               \
+        { 1, 1 }    \
+    }
+
+FUNCTION(mfxStatus, MFXDisjoinSession, (mfxSession session), (session))
+FUNCTION(mfxStatus, MFXSetPriority, (mfxSession session, mfxPriority priority), (session, priority))
+FUNCTION(mfxStatus,
+         MFXGetPriority,
+         (mfxSession session, mfxPriority *priority),
+         (session, priority))
+
+#undef API_VERSION
+
+#define API_VERSION \
+    {               \
+        { 19, 1 }   \
+    }
+
+FUNCTION(mfxStatus,
+         MFXVideoCORE_QueryPlatform,
+         (mfxSession session, mfxPlatform *platform),
+         (session, platform))
+
+#undef API_VERSION
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl.cpp
new file mode 100644 (file)
index 0000000..ad7a763
--- /dev/null
@@ -0,0 +1,189 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "vpl/mfx_dispatcher_vpl.h"
+
+// exported functions for API >= 2.0
+
+// create unique loader context
+mfxLoader MFXLoad() {
+    LoaderCtxVPL *loaderCtx;
+
+    try {
+        std::unique_ptr<LoaderCtxVPL> pLoaderCtx;
+        pLoaderCtx.reset(new LoaderCtxVPL{});
+        loaderCtx = (LoaderCtxVPL *)pLoaderCtx.release();
+    }
+    catch (...) {
+        return nullptr;
+    }
+
+    // initialize logging if appropriate environment variables are set
+    loaderCtx->InitDispatcherLog();
+
+    return (mfxLoader)loaderCtx;
+}
+
+// unload libraries, destroy all created mfxConfig objects, free other memory
+void MFXUnload(mfxLoader loader) {
+    if (loader) {
+        LoaderCtxVPL *loaderCtx = (LoaderCtxVPL *)loader;
+
+        loaderCtx->UnloadAllLibraries();
+
+        loaderCtx->FreeConfigFilters();
+
+        delete loaderCtx;
+    }
+
+    return;
+}
+
+// create config context
+// each loader may have more than one config context
+mfxConfig MFXCreateConfig(mfxLoader loader) {
+    if (!loader)
+        return nullptr;
+
+    LoaderCtxVPL *loaderCtx = (LoaderCtxVPL *)loader;
+    ConfigCtxVPL *configCtx;
+
+    DispatcherLogVPL *dispLog = loaderCtx->GetLogger();
+    DISP_LOG_FUNCTION(dispLog);
+
+    try {
+        configCtx = loaderCtx->AddConfigFilter();
+    }
+    catch (...) {
+        return nullptr;
+    }
+
+    return (mfxConfig)(configCtx);
+}
+
+// set a config proprerty to use in enumerating implementations
+mfxStatus MFXSetConfigFilterProperty(mfxConfig config, const mfxU8 *name, mfxVariant value) {
+    if (!config)
+        return MFX_ERR_NULL_PTR;
+
+    ConfigCtxVPL *configCtx = (ConfigCtxVPL *)config;
+    LoaderCtxVPL *loaderCtx = configCtx->m_parentLoader;
+
+    DispatcherLogVPL *dispLog = loaderCtx->GetLogger();
+    DISP_LOG_FUNCTION(dispLog);
+
+    mfxStatus sts = configCtx->SetFilterProperty(name, value);
+    if (sts)
+        return sts;
+
+    loaderCtx->m_bNeedUpdateValidImpls = true;
+
+    sts = loaderCtx->UpdateLowLatency();
+
+    return sts;
+}
+
+// iterate over available implementations
+// capabilities are returned in idesc
+mfxStatus MFXEnumImplementations(mfxLoader loader,
+                                 mfxU32 i,
+                                 mfxImplCapsDeliveryFormat format,
+                                 mfxHDL *idesc) {
+    if (!loader || !idesc)
+        return MFX_ERR_NULL_PTR;
+
+    LoaderCtxVPL *loaderCtx = (LoaderCtxVPL *)loader;
+
+    DispatcherLogVPL *dispLog = loaderCtx->GetLogger();
+    DISP_LOG_FUNCTION(dispLog);
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    // load and query all libraries
+    if (loaderCtx->m_bNeedFullQuery) {
+        sts = loaderCtx->FullLoadAndQuery();
+        if (sts)
+            return sts;
+    }
+
+    // update list of valid libraries based on updated set of
+    //   mfxConfig properties
+    if (loaderCtx->m_bNeedUpdateValidImpls) {
+        sts = loaderCtx->UpdateValidImplList();
+        if (sts)
+            return sts;
+    }
+
+    sts = loaderCtx->QueryImpl(i, format, idesc);
+
+    return sts;
+}
+
+// create a new session with implementation i
+mfxStatus MFXCreateSession(mfxLoader loader, mfxU32 i, mfxSession *session) {
+    if (!loader || !session)
+        return MFX_ERR_NULL_PTR;
+
+    LoaderCtxVPL *loaderCtx = (LoaderCtxVPL *)loader;
+
+    DispatcherLogVPL *dispLog = loaderCtx->GetLogger();
+    DISP_LOG_FUNCTION(dispLog);
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    if (loaderCtx->m_bLowLatency) {
+        DISP_LOG_MESSAGE(dispLog, "message:  low latency mode enabled");
+
+        if (loaderCtx->m_bNeedLowLatencyQuery) {
+            // load low latency libraries
+            sts = loaderCtx->LoadLibsLowLatency();
+            if (sts != MFX_ERR_NONE)
+                return MFX_ERR_NOT_FOUND;
+
+            // run limited query operations for low latency init
+            sts = loaderCtx->QueryLibraryCaps();
+            if (sts != MFX_ERR_NONE)
+                return MFX_ERR_NOT_FOUND;
+        }
+    }
+    else {
+        DISP_LOG_MESSAGE(dispLog, "message:  low latency mode disabled");
+
+        // load and query all libraries
+        if (loaderCtx->m_bNeedFullQuery) {
+            sts = loaderCtx->FullLoadAndQuery();
+            if (sts)
+                return MFX_ERR_NOT_FOUND;
+        }
+
+        // update list of valid libraries based on updated set of
+        //   mfxConfig properties
+        if (loaderCtx->m_bNeedUpdateValidImpls) {
+            sts = loaderCtx->UpdateValidImplList();
+            if (sts)
+                return MFX_ERR_NOT_FOUND;
+        }
+    }
+
+    sts = loaderCtx->CreateSession(i, session);
+
+    return sts;
+}
+
+// release memory associated with implementation description hdl
+mfxStatus MFXDispReleaseImplDescription(mfxLoader loader, mfxHDL hdl) {
+    if (!loader)
+        return MFX_ERR_NULL_PTR;
+
+    LoaderCtxVPL *loaderCtx = (LoaderCtxVPL *)loader;
+
+    DispatcherLogVPL *dispLog = loaderCtx->GetLogger();
+    DISP_LOG_FUNCTION(dispLog);
+
+    mfxStatus sts = loaderCtx->ReleaseImpl(hdl);
+
+    return sts;
+}
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl.h
new file mode 100644 (file)
index 0000000..3f92b48
--- /dev/null
@@ -0,0 +1,547 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_VPL_MFX_DISPATCHER_VPL_H_
+#define DISPATCHER_VPL_MFX_DISPATCHER_VPL_H_
+
+#include <algorithm>
+#include <cstdlib>
+#include <list>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "vpl/mfxdispatcher.h"
+#include "vpl/mfxvideo.h"
+
+#include "./mfx_dispatcher_vpl_log.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+    #include <windows.h>
+
+    // use wide char on Windows
+    #define MAKE_STRING(x) L##x
+typedef std::wstring STRING_TYPE;
+typedef wchar_t CHAR_TYPE;
+#else
+    #include <dirent.h>
+    #include <dlfcn.h>
+    #include <string.h>
+    #include <unistd.h>
+
+    // use standard char on Linux
+    #define MAKE_STRING(x) x
+typedef std::string STRING_TYPE;
+typedef char CHAR_TYPE;
+#endif
+
+#if defined(_WIN32) || defined(_WIN64)
+    #if defined _M_IX86
+        // Windows x86
+        #define MSDK_LIB_NAME L"libmfxhw32."
+    #else
+        // Windows x64
+        #define MSDK_LIB_NAME L"libmfxhw64."
+    #endif
+    #define ONEVPL_PRIORITY_PATH_VAR L"ONEVPL_PRIORITY_PATH"
+#elif defined(__linux__)
+    // Linux x64
+    #define MSDK_LIB_NAME            "libmfxhw64."
+    #define ONEVPL_PRIORITY_PATH_VAR "ONEVPL_PRIORITY_PATH"
+#endif
+
+#define MSDK_MIN_VERSION_MAJOR 1
+#define MSDK_MIN_VERSION_MINOR 0
+
+#define MAX_MSDK_ACCEL_MODES 16 // see mfxcommon.h --> mfxAccelerationMode
+
+#define MAX_WINDOWS_ADAPTER_ID 3 // check adapterID in range [0,3]
+
+#define MAX_NUM_IMPL_MSDK 4
+
+#define MAX_VPL_SEARCH_PATH 4096
+
+#define MAX_ENV_VAR_LEN 32768
+
+#define DEVICE_ID_UNKNOWN   0xffffffff
+#define ADAPTER_IDX_UNKNOWN 0xffffffff
+
+#define TAB_SIZE(type, tab) (sizeof(tab) / sizeof(type))
+#define MAKE_MFX_VERSION(major, minor) \
+    { (minor), (major) }
+
+// internal function to load dll by full path, fail if unsuccessful
+mfxStatus MFXInitEx2(mfxVersion version,
+                     mfxInitializationParam vplParam,
+                     mfxIMPL hwImpl,
+                     mfxSession *session,
+                     mfxU16 *deviceID,
+                     CHAR_TYPE *dllName);
+
+typedef void(MFX_CDECL *VPLFunctionPtr)(void);
+
+extern const mfxIMPL msdkImplTab[MAX_NUM_IMPL_MSDK];
+
+enum LibType {
+    LibTypeUnknown = -1,
+
+    LibTypeVPL = 0,
+    LibTypeMSDK,
+
+    NumLibTypes
+};
+
+enum VPLFunctionIdx {
+    // 2.0
+    IdxMFXQueryImplsDescription = 0,
+    IdxMFXReleaseImplDescription,
+    IdxMFXMemory_GetSurfaceForVPP,
+    IdxMFXMemory_GetSurfaceForEncode,
+    IdxMFXMemory_GetSurfaceForDecode,
+    IdxMFXInitialize,
+
+    // 2.1
+    IdxMFXMemory_GetSurfaceForVPPOut,
+    IdxMFXVideoDECODE_VPP_Init,
+    IdxMFXVideoDECODE_VPP_DecodeFrameAsync,
+    IdxMFXVideoDECODE_VPP_Reset,
+    IdxMFXVideoDECODE_VPP_GetChannelParam,
+    IdxMFXVideoDECODE_VPP_Close,
+    IdxMFXVideoVPP_ProcessFrameAsync,
+
+    NumVPLFunctions
+};
+
+// select MSDK functions for 1.x style caps query
+enum MSDKCompatFunctionIdx {
+    IdxMFXInitEx = 0,
+    IdxMFXClose,
+
+    NumMSDKFunctions
+};
+
+// both Windows and Linux use char* for function names
+struct VPLFunctionDesc {
+    const char *pName;
+    mfxVersion apiVersion;
+};
+
+// DX adapter info
+struct DXGI1DeviceInfo {
+    mfxU32 vendorID;
+    mfxU32 deviceID;
+    mfxU64 luid;
+};
+
+// priority of runtime loading, based on oneAPI-spec
+enum LibPriority {
+    LIB_PRIORITY_SPECIAL = 0, // highest priority regardless of other priority rules
+
+    LIB_PRIORITY_01 = 1,
+    LIB_PRIORITY_02 = 2,
+    LIB_PRIORITY_03 = 3,
+    LIB_PRIORITY_04 = 4,
+    LIB_PRIORITY_05 = 5,
+
+    LIB_PRIORITY_LEGACY_DRIVERSTORE = 10000,
+    LIB_PRIORITY_LEGACY,
+};
+
+enum CfgPropState {
+    CFG_PROP_STATE_NOT_SET = 0,
+    CFG_PROP_STATE_SUPPORTED,
+    CFG_PROP_STATE_UNSUPPORTED,
+};
+
+enum PropRanges {
+    PROP_RANGE_DEC_W = 0,
+    PROP_RANGE_DEC_H,
+    PROP_RANGE_ENC_W,
+    PROP_RANGE_ENC_H,
+    PROP_RANGE_VPP_W,
+    PROP_RANGE_VPP_H,
+
+    NUM_PROP_RANGES
+};
+
+// must match eProp_TotalProps, is checked with static_assert in _config.cpp
+//   (should throw error at compile time if !=)
+#define NUM_TOTAL_FILTER_PROPS 41
+
+// typedef child structures for easier reading
+typedef struct mfxDecoderDescription::decoder DecCodec;
+typedef struct mfxDecoderDescription::decoder::decprofile DecProfile;
+typedef struct mfxDecoderDescription::decoder::decprofile::decmemdesc DecMemDesc;
+
+typedef struct mfxEncoderDescription::encoder EncCodec;
+typedef struct mfxEncoderDescription::encoder::encprofile EncProfile;
+typedef struct mfxEncoderDescription::encoder::encprofile::encmemdesc EncMemDesc;
+
+typedef struct mfxVPPDescription::filter VPPFilter;
+typedef struct mfxVPPDescription::filter::memdesc VPPMemDesc;
+typedef struct mfxVPPDescription::filter::memdesc::format VPPFormat;
+
+// flattened version of single enc/dec/vpp configs
+// each struct contains all _settable_ props
+//   i.e. not implied values like NumCodecs
+struct DecConfig {
+    mfxU32 CodecID;
+    mfxU16 MaxcodecLevel;
+    mfxU32 Profile;
+    mfxResourceType MemHandleType;
+    mfxRange32U Width;
+    mfxRange32U Height;
+    mfxU32 ColorFormat;
+};
+
+struct EncConfig {
+    mfxU32 CodecID;
+    mfxU16 MaxcodecLevel;
+    mfxU16 BiDirectionalPrediction;
+    mfxU32 Profile;
+    mfxResourceType MemHandleType;
+    mfxRange32U Width;
+    mfxRange32U Height;
+    mfxU32 ColorFormat;
+};
+
+struct VPPConfig {
+    mfxU32 FilterFourCC;
+    mfxU16 MaxDelayInFrames;
+    mfxResourceType MemHandleType;
+    mfxRange32U Width;
+    mfxRange32U Height;
+    mfxU32 InFormat;
+    mfxU32 OutFormat;
+};
+
+// special props which are passed in via MFXSetConfigProperty()
+// these are updated with every call to ValidateConfig() and may
+//   be used in MFXCreateSession()
+struct SpecialConfig {
+    bool bIsSet_deviceHandleType;
+    mfxHandleType deviceHandleType;
+
+    bool bIsSet_deviceHandle;
+    mfxHDL deviceHandle;
+
+    bool bIsSet_accelerationMode;
+    mfxAccelerationMode accelerationMode;
+
+    bool bIsSet_ApiVersion;
+    mfxVersion ApiVersion;
+
+    bool bIsSet_dxgiAdapterIdx;
+    mfxU32 dxgiAdapterIdx;
+
+    bool bIsSet_NumThread;
+    mfxU32 NumThread;
+};
+
+// config class implementation
+class ConfigCtxVPL {
+public:
+    ConfigCtxVPL();
+    ~ConfigCtxVPL();
+
+    // set a single filter property (KV pair)
+    mfxStatus SetFilterProperty(const mfxU8 *name, mfxVariant value);
+
+    static bool CheckLowLatencyConfig(std::list<ConfigCtxVPL *> configCtxList,
+                                      SpecialConfig *specialConfig);
+
+    // compare library caps vs. set of configuration filters
+    static mfxStatus ValidateConfig(const mfxImplDescription *libImplDesc,
+                                    const mfxImplementedFunctions *libImplFuncs,
+                                    std::list<ConfigCtxVPL *> configCtxList,
+                                    LibType libType,
+                                    SpecialConfig *specialConfig);
+
+    // parse deviceID for x86 devices
+    static bool ParseDeviceIDx86(mfxChar *cDeviceID, mfxU32 &deviceID, mfxU32 &adapterIdx);
+
+    // loader object this config is associated with - needed to
+    //   rebuild valid implementation list after each calling
+    //   MFXSetConfigFilterProperty()
+    class LoaderCtxVPL *m_parentLoader;
+
+private:
+    static __inline std::string GetNextProp(std::list<std::string> &s) {
+        if (s.empty())
+            return "";
+        std::string t = s.front();
+        s.pop_front();
+        return t;
+    }
+
+    mfxStatus ValidateAndSetProp(mfxI32 idx, mfxVariant value);
+    mfxStatus SetFilterPropertyDec(std::list<std::string> &propParsedString, mfxVariant value);
+    mfxStatus SetFilterPropertyEnc(std::list<std::string> &propParsedString, mfxVariant value);
+    mfxStatus SetFilterPropertyVPP(std::list<std::string> &propParsedString, mfxVariant value);
+
+    static mfxStatus GetFlatDescriptionsDec(const mfxImplDescription *libImplDesc,
+                                            std::list<DecConfig> &decConfigList);
+
+    static mfxStatus GetFlatDescriptionsEnc(const mfxImplDescription *libImplDesc,
+                                            std::list<EncConfig> &encConfigList);
+
+    static mfxStatus GetFlatDescriptionsVPP(const mfxImplDescription *libImplDesc,
+                                            std::list<VPPConfig> &vppConfigList);
+
+    static mfxStatus CheckPropsGeneral(const mfxVariant cfgPropsAll[],
+                                       const mfxImplDescription *libImplDesc);
+
+    static mfxStatus CheckPropsDec(const mfxVariant cfgPropsAll[],
+                                   std::list<DecConfig> decConfigList);
+
+    static mfxStatus CheckPropsEnc(const mfxVariant cfgPropsAll[],
+                                   std::list<EncConfig> encConfigList);
+
+    static mfxStatus CheckPropsVPP(const mfxVariant cfgPropsAll[],
+                                   std::list<VPPConfig> vppConfigList);
+
+    static mfxStatus CheckPropString(const mfxChar *implString, const std::string filtString);
+
+    mfxVariant m_propVar[NUM_TOTAL_FILTER_PROPS];
+
+    // special containers for properties which are passed by pointer
+    //   (save a copy of the whole object based on property name)
+    mfxRange32U m_propRange32U[NUM_PROP_RANGES];
+    std::string m_implName;
+    std::string m_implLicense;
+    std::string m_implKeywords;
+    std::string m_deviceIdStr;
+    std::string m_implFunctionName;
+};
+
+// MSDK compatibility loader implementation
+class LoaderCtxMSDK {
+public:
+    LoaderCtxMSDK();
+    ~LoaderCtxMSDK();
+
+    // public function to be called by VPL dispatcher
+    // do not allocate any new memory here, so no need for a matching Release functions
+    mfxStatus QueryMSDKCaps(STRING_TYPE libNameFull,
+                            mfxImplDescription **implDesc,
+                            mfxImplementedFunctions **implFuncs,
+                            mfxU32 adapterID,
+                            bool bSkipD3D9Check);
+
+    static mfxStatus QueryAPIVersion(STRING_TYPE libNameFull, mfxVersion *msdkVersion);
+
+    // required by MFXCreateSession
+    mfxIMPL m_msdkAdapter;
+    mfxIMPL m_msdkAdapterD3D9;
+
+private:
+    // session management
+    mfxStatus OpenSession(mfxSession *session,
+                          STRING_TYPE libNameFull,
+                          mfxAccelerationMode accelMode,
+                          mfxIMPL hwImpl);
+    void CloseSession(mfxSession *session);
+
+    // utility functions
+    static mfxAccelerationMode CvtAccelType(mfxIMPL implType, mfxIMPL implMethod);
+    static mfxStatus GetDefaultAccelType(mfxU32 adapterID, mfxIMPL *implDefault, mfxU64 *luid);
+    static mfxStatus CheckD3D9Support(mfxU64 luid, STRING_TYPE libNameFull, mfxIMPL *implD3D9);
+
+    // internal state variables
+    STRING_TYPE m_libNameFull;
+    mfxImplDescription m_id; // base description struct
+    mfxAccelerationMode m_accelMode[MAX_MSDK_ACCEL_MODES];
+    mfxU16 m_loaderDeviceID;
+
+    __inline bool IsVersionSupported(mfxVersion reqVersion, mfxVersion actualVersion) {
+        if (actualVersion.Major > reqVersion.Major) {
+            return true;
+        }
+        else if ((actualVersion.Major == reqVersion.Major) &&
+                 (actualVersion.Minor >= reqVersion.Minor)) {
+            return true;
+        }
+        return false;
+    }
+};
+
+struct LibInfo {
+    // during search store candidate file names
+    //   and priority based on rules in spec
+    STRING_TYPE libNameFull;
+    mfxU32 libPriority;
+    LibType libType;
+
+    // if valid library, store file handle
+    //   and table of exported functions
+    void *hModuleVPL;
+    VPLFunctionPtr vplFuncTable[NumVPLFunctions]; // NOLINT
+
+    // loader context for legacy MSDK
+    LoaderCtxMSDK msdkCtx[MAX_NUM_IMPL_MSDK];
+
+    // API version of legacy MSDK
+    mfxVersion msdkVersion;
+
+    // user-friendly version of path for MFX_IMPLCAPS_IMPLPATH query
+    mfxChar implCapsPath[MAX_VPL_SEARCH_PATH];
+
+    // avoid warnings
+    LibInfo()
+            : libNameFull(),
+              libPriority(0),
+              libType(LibTypeUnknown),
+              hModuleVPL(nullptr),
+              vplFuncTable(),
+              msdkCtx(),
+              msdkVersion(),
+              implCapsPath() {}
+
+private:
+    // make this class non-copyable
+    LibInfo(const LibInfo &);
+    void operator=(const LibInfo &);
+};
+
+struct ImplInfo {
+    // library containing this implementation
+    LibInfo *libInfo;
+
+    // description of implementation
+    mfxHDL implDesc;
+
+    // list of implemented functions
+    mfxHDL implFuncs;
+
+#ifdef ONEVPL_EXPERIMENTAL
+    mfxHDL implExtDeviceID;
+#endif
+
+    // used for session initialization with this implementation
+    mfxInitializationParam vplParam;
+    mfxVersion version;
+
+    // if MSDK library, index of corresponding adapter (i.e. which LoaderCtxMSDK)
+    mfxU32 msdkImplIdx;
+
+    // adapter index in multi-adapter systems
+    mfxU32 adapterIdx;
+
+    // local index for libraries with more than one implementation
+    mfxU32 libImplIdx;
+
+    // index of valid libraries - updates with every call to MFXSetConfigFilterProperty()
+    mfxI32 validImplIdx;
+
+    // avoid warnings
+    ImplInfo()
+            : libInfo(nullptr),
+              implDesc(nullptr),
+              implFuncs(nullptr),
+#ifdef ONEVPL_EXPERIMENTAL
+              implExtDeviceID(nullptr),
+#endif
+              vplParam(),
+              version(),
+              msdkImplIdx(0),
+              adapterIdx(ADAPTER_IDX_UNKNOWN),
+              libImplIdx(0),
+              validImplIdx(-1) {
+    }
+};
+
+// loader class implementation
+class LoaderCtxVPL {
+public:
+    LoaderCtxVPL();
+    ~LoaderCtxVPL();
+
+    // manage library implementations
+    mfxStatus BuildListOfCandidateLibs();
+    mfxU32 CheckValidLibraries();
+    mfxStatus QueryLibraryCaps();
+    mfxStatus UnloadAllLibraries();
+
+    // query capabilities of each implementation
+    mfxStatus FullLoadAndQuery();
+    mfxStatus QueryImpl(mfxU32 idx, mfxImplCapsDeliveryFormat format, mfxHDL *idesc);
+    mfxStatus ReleaseImpl(mfxHDL idesc);
+
+    // update list of valid implementations based on current filter props
+    mfxStatus UpdateValidImplList(void);
+    mfxStatus PrioritizeImplList(void);
+
+    // create mfxSession
+    mfxStatus CreateSession(mfxU32 idx, mfxSession *session);
+
+    // manage configuration filters
+    ConfigCtxVPL *AddConfigFilter();
+    mfxStatus FreeConfigFilters();
+
+    // manage logging
+    mfxStatus InitDispatcherLog();
+    DispatcherLogVPL *GetLogger();
+
+    // low latency initialization
+    mfxStatus LoadLibsLowLatency();
+    mfxStatus UpdateLowLatency();
+
+    bool m_bLowLatency;
+    bool m_bNeedUpdateValidImpls;
+    bool m_bNeedFullQuery;
+    bool m_bNeedLowLatencyQuery;
+    bool m_bPriorityPathEnabled;
+
+private:
+    // helper functions
+    mfxStatus LoadSingleLibrary(LibInfo *libInfo);
+    mfxStatus UnloadSingleLibrary(LibInfo *libInfo);
+    mfxStatus UnloadSingleImplementation(ImplInfo *implInfo);
+    VPLFunctionPtr GetFunctionAddr(void *hModuleVPL, const char *pName);
+
+    mfxU32 GetSearchPathsDriverStore(std::list<STRING_TYPE> &searchDirs, LibType libType);
+    mfxU32 GetSearchPathsSystemDefault(std::list<STRING_TYPE> &searchDirs);
+    mfxU32 GetSearchPathsCurrentExe(std::list<STRING_TYPE> &searchDirs);
+    mfxU32 GetSearchPathsCurrentDir(std::list<STRING_TYPE> &searchDirs);
+    mfxU32 GetSearchPathsLegacy(std::list<STRING_TYPE> &searchDirs);
+
+    mfxU32 ParseEnvSearchPaths(const CHAR_TYPE *envVarName, std::list<STRING_TYPE> &searchDirs);
+    mfxU32 ParseLegacySearchPaths(std::list<STRING_TYPE> &searchDirs);
+
+    mfxStatus SearchDirForLibs(STRING_TYPE searchDir,
+                               std::list<LibInfo *> &libInfoList,
+                               mfxU32 priority);
+
+    mfxU32 LoadAPIExports(LibInfo *libInfo, LibType libType);
+    mfxStatus ValidateAPIExports(VPLFunctionPtr *vplFuncTable, mfxVersion reportedVersion);
+    bool IsValidX86GPU(ImplInfo *implInfo, mfxU32 &deviceID, mfxU32 &adapterIdx);
+    mfxStatus UpdateImplPath(LibInfo *libInfo);
+
+    mfxStatus LoadLibsFromDriverStore(mfxU32 numAdapters,
+                                      const std::vector<DXGI1DeviceInfo> &adapterInfo,
+                                      LibType libType);
+    mfxStatus LoadLibsFromSystemDir(LibType libType);
+
+    LibInfo *AddSingleLibrary(STRING_TYPE libPath, LibType libType);
+    mfxStatus QuerySessionLowLatency(LibInfo *libInfo, mfxU32 adapterID, mfxVersion *ver);
+
+    std::list<LibInfo *> m_libInfoList;
+    std::list<ImplInfo *> m_implInfoList;
+    std::list<ConfigCtxVPL *> m_configCtxList;
+    std::vector<DXGI1DeviceInfo> m_gpuAdapterInfo;
+
+    SpecialConfig m_specialConfig;
+
+    mfxU32 m_implIdxNext;
+    bool m_bKeepCapsUntilUnload;
+    CHAR_TYPE m_envVar[MAX_ENV_VAR_LEN];
+
+    // logger object - enabled with ONEVPL_DISPATCHER_LOG environment variable
+    DispatcherLogVPL m_dispLog;
+};
+
+#endif // DISPATCHER_VPL_MFX_DISPATCHER_VPL_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_config.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_config.cpp
new file mode 100644 (file)
index 0000000..c7cbed1
--- /dev/null
@@ -0,0 +1,1299 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "vpl/mfx_dispatcher_vpl.h"
+
+#include <assert.h>
+
+#include <regex>
+
+// implementation of config context (mfxConfig)
+// each loader instance can have one or more configs
+//   associated with it - used for filtering implementations
+//   based on what they support (codec types, etc.)
+ConfigCtxVPL::ConfigCtxVPL()
+        : m_propVar(),
+          m_propRange32U(),
+          m_implName(),
+          m_implLicense(),
+          m_implKeywords(),
+          m_deviceIdStr(),
+          m_implFunctionName() {
+    // initially set Type = unset (invalid)
+    // if valid property string and value are passed in,
+    //   this will be updated
+    // otherwise loader will ignore this cfg during EnumImplementations
+    for (mfxU32 idx = 0; idx < NUM_TOTAL_FILTER_PROPS; idx++) {
+        m_propVar[idx].Version.Version = MFX_VARIANT_VERSION;
+        m_propVar[idx].Type            = MFX_VARIANT_TYPE_UNSET;
+        m_propVar[idx].Data.U64        = 0;
+    }
+
+    m_parentLoader = nullptr;
+    return;
+}
+
+ConfigCtxVPL::~ConfigCtxVPL() {
+    return;
+}
+
+struct PropVariant {
+    const char *Name;
+    mfxVariantType Type;
+};
+
+enum PropIdx {
+    // settable config properties for mfxImplDescription
+    ePropMain_Impl = 0,
+    ePropMain_AccelerationMode,
+    ePropMain_ApiVersion,
+    ePropMain_ApiVersion_Major,
+    ePropMain_ApiVersion_Minor,
+    ePropMain_ImplName,
+    ePropMain_License,
+    ePropMain_Keywords,
+    ePropMain_VendorID,
+    ePropMain_VendorImplID,
+    ePropMain_PoolAllocationPolicy,
+
+    // settable config properties for mfxDeviceDescription
+    ePropDevice_DeviceID,
+    ePropDevice_DeviceIDStr,
+    ePropDevice_MediaAdapterType,
+
+    // settable config properties for mfxDecoderDescription
+    ePropDec_CodecID,
+    ePropDec_MaxcodecLevel,
+    ePropDec_Profile,
+    ePropDec_MemHandleType,
+    ePropDec_Width,
+    ePropDec_Height,
+    ePropDec_ColorFormats,
+
+    // settable config properties for mfxEncoderDescription
+    ePropEnc_CodecID,
+    ePropEnc_MaxcodecLevel,
+    ePropEnc_BiDirectionalPrediction,
+    ePropEnc_Profile,
+    ePropEnc_MemHandleType,
+    ePropEnc_Width,
+    ePropEnc_Height,
+    ePropEnc_ColorFormats,
+
+    // settable config properties for mfxVPPDescription
+    ePropVPP_FilterFourCC,
+    ePropVPP_MaxDelayInFrames,
+    ePropVPP_MemHandleType,
+    ePropVPP_Width,
+    ePropVPP_Height,
+    ePropVPP_InFormat,
+    ePropVPP_OutFormat,
+
+    // special properties not part of description struct
+    ePropSpecial_HandleType,
+    ePropSpecial_Handle,
+    ePropSpecial_NumThread,
+    ePropSpecial_DXGIAdapterIndex,
+
+    // functions which must report as implemented
+    ePropFunc_FunctionName,
+
+    // number of entries (always last)
+    eProp_TotalProps
+};
+
+// leave table formatting alone
+// clang-format off
+
+// order must align exactly with PropIdx list
+// to avoid mismatches, this should be automated (e.g. pre-processor step)
+static const PropVariant PropIdxTab[] = {
+    { "ePropMain_Impl",                     MFX_VARIANT_TYPE_U32 },
+    { "ePropMain_AccelerationMode",         MFX_VARIANT_TYPE_U32 },
+    { "ePropMain_ApiVersion",               MFX_VARIANT_TYPE_U32 },
+    { "ePropMain_ApiVersion_Major",         MFX_VARIANT_TYPE_U16 },
+    { "ePropMain_ApiVersion_Minor",         MFX_VARIANT_TYPE_U16 },
+    { "ePropMain_ImplName",                 MFX_VARIANT_TYPE_PTR },
+    { "ePropMain_License",                  MFX_VARIANT_TYPE_PTR },
+    { "ePropMain_Keywords",                 MFX_VARIANT_TYPE_PTR },
+    { "ePropMain_VendorID",                 MFX_VARIANT_TYPE_U32 },
+    { "ePropMain_VendorImplID",             MFX_VARIANT_TYPE_U32 },
+    { "ePropMain_PoolAllocationPolicy",     MFX_VARIANT_TYPE_U32 },
+
+    { "ePropDevice_DeviceID",               MFX_VARIANT_TYPE_U16 },
+    { "ePropDevice_DeviceIDStr",            MFX_VARIANT_TYPE_PTR },
+    { "ePropDevice_MediaAdapterType",       MFX_VARIANT_TYPE_U16 },
+
+    { "ePropDec_CodecID",                   MFX_VARIANT_TYPE_U32 },
+    { "ePropDec_MaxcodecLevel",             MFX_VARIANT_TYPE_U16 },
+    { "ePropDec_Profile",                   MFX_VARIANT_TYPE_U32 },
+    { "ePropDec_MemHandleType",             MFX_VARIANT_TYPE_U32 },
+    { "ePropDec_Width",                     MFX_VARIANT_TYPE_PTR },
+    { "ePropDec_Height",                    MFX_VARIANT_TYPE_PTR },
+    { "ePropDec_ColorFormats",              MFX_VARIANT_TYPE_U32 },
+
+    { "ePropEnc_CodecID",                   MFX_VARIANT_TYPE_U32 },
+    { "ePropEnc_MaxcodecLevel",             MFX_VARIANT_TYPE_U16 },
+    { "ePropEnc_BiDirectionalPrediction",   MFX_VARIANT_TYPE_U16 },
+    { "ePropEnc_Profile",                   MFX_VARIANT_TYPE_U32 },
+    { "ePropEnc_MemHandleType",             MFX_VARIANT_TYPE_U32 },
+    { "ePropEnc_Width",                     MFX_VARIANT_TYPE_PTR },
+    { "ePropEnc_Height",                    MFX_VARIANT_TYPE_PTR },
+    { "ePropEnc_ColorFormats",              MFX_VARIANT_TYPE_U32 },
+
+    { "ePropVPP_FilterFourCC",              MFX_VARIANT_TYPE_U32 },
+    { "ePropVPP_MaxDelayInFrames",          MFX_VARIANT_TYPE_U16 },
+    { "ePropVPP_MemHandleType",             MFX_VARIANT_TYPE_U32 },
+    { "ePropVPP_Width",                     MFX_VARIANT_TYPE_PTR },
+    { "ePropVPP_Height",                    MFX_VARIANT_TYPE_PTR },
+    { "ePropVPP_InFormat",                  MFX_VARIANT_TYPE_U32 },
+    { "ePropVPP_OutFormat",                 MFX_VARIANT_TYPE_U32 },
+
+    { "ePropSpecial_HandleType",            MFX_VARIANT_TYPE_U32 },
+    { "ePropSpecial_Handle",                MFX_VARIANT_TYPE_PTR },
+    { "ePropSpecial_NumThread",             MFX_VARIANT_TYPE_U32 },
+    { "ePropSpecial_DXGIAdapterIndex",      MFX_VARIANT_TYPE_U32 },
+
+    { "ePropFunc_FunctionName",             MFX_VARIANT_TYPE_PTR },
+};
+
+// end table formatting
+// clang-format on
+
+// sanity check - property table and indexes must have same number of entries
+static_assert((sizeof(PropIdxTab) / sizeof(PropVariant)) == eProp_TotalProps,
+              "PropIdx and PropIdxTab are misaligned");
+
+static_assert(NUM_TOTAL_FILTER_PROPS == eProp_TotalProps,
+              "NUM_TOTAL_FILTER_PROPS and eProp_TotalProps are misaligned");
+
+mfxStatus ConfigCtxVPL::ValidateAndSetProp(mfxI32 idx, mfxVariant value) {
+    if (idx < 0 || idx >= eProp_TotalProps)
+        return MFX_ERR_NOT_FOUND;
+
+    if (value.Type != PropIdxTab[idx].Type)
+        return MFX_ERR_UNSUPPORTED;
+
+    m_propVar[idx].Version.Version = MFX_VARIANT_VERSION;
+    m_propVar[idx].Type            = value.Type;
+
+    if (value.Type == MFX_VARIANT_TYPE_PTR) {
+        if (value.Data.Ptr == nullptr) {
+            // unset property to avoid possibly dereferencing null if app ignores error code
+            m_propVar[idx].Type = MFX_VARIANT_TYPE_UNSET;
+            return MFX_ERR_NULL_PTR;
+        }
+
+        // save copy of data passed by pointer, into object of the appropriate type
+        switch (idx) {
+            case ePropDec_Width:
+                m_propRange32U[PROP_RANGE_DEC_W] = *((mfxRange32U *)(value.Data.Ptr));
+                m_propVar[idx].Data.Ptr          = &(m_propRange32U[PROP_RANGE_DEC_W]);
+                break;
+            case ePropDec_Height:
+                m_propRange32U[PROP_RANGE_DEC_H] = *((mfxRange32U *)(value.Data.Ptr));
+                m_propVar[idx].Data.Ptr          = &(m_propRange32U[PROP_RANGE_DEC_H]);
+                break;
+            case ePropEnc_Width:
+                m_propRange32U[PROP_RANGE_ENC_W] = *((mfxRange32U *)(value.Data.Ptr));
+                m_propVar[idx].Data.Ptr          = &(m_propRange32U[PROP_RANGE_ENC_W]);
+                break;
+            case ePropEnc_Height:
+                m_propRange32U[PROP_RANGE_ENC_H] = *((mfxRange32U *)(value.Data.Ptr));
+                m_propVar[idx].Data.Ptr          = &(m_propRange32U[PROP_RANGE_ENC_H]);
+                break;
+            case ePropVPP_Width:
+                m_propRange32U[PROP_RANGE_VPP_W] = *((mfxRange32U *)(value.Data.Ptr));
+                m_propVar[idx].Data.Ptr          = &(m_propRange32U[PROP_RANGE_VPP_W]);
+                break;
+            case ePropVPP_Height:
+                m_propRange32U[PROP_RANGE_VPP_H] = *((mfxRange32U *)(value.Data.Ptr));
+                m_propVar[idx].Data.Ptr          = &(m_propRange32U[PROP_RANGE_VPP_H]);
+                break;
+            case ePropSpecial_Handle:
+                m_propVar[idx].Data.Ptr = (mfxHDL)(value.Data.Ptr);
+                break;
+            case ePropMain_ImplName:
+                m_implName              = (char *)(value.Data.Ptr);
+                m_propVar[idx].Data.Ptr = &(m_implName);
+                break;
+            case ePropMain_License:
+                m_implLicense           = (char *)(value.Data.Ptr);
+                m_propVar[idx].Data.Ptr = &(m_implLicense);
+                break;
+            case ePropMain_Keywords:
+                m_implKeywords          = (char *)(value.Data.Ptr);
+                m_propVar[idx].Data.Ptr = &(m_implKeywords);
+                break;
+            case ePropDevice_DeviceIDStr:
+                m_deviceIdStr           = (char *)(value.Data.Ptr);
+                m_propVar[idx].Data.Ptr = &(m_deviceIdStr);
+                break;
+            case ePropFunc_FunctionName:
+                // no need to save Data.Ptr - parsed in main loop
+                m_implFunctionName = (char *)(value.Data.Ptr);
+                break;
+            default:
+                break;
+        }
+    }
+    else {
+        m_propVar[idx].Data = value.Data;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus ConfigCtxVPL::SetFilterPropertyDec(std::list<std::string> &propParsedString,
+                                             mfxVariant value) {
+    std::string nextProp;
+
+    nextProp = GetNextProp(propParsedString);
+
+    // no settable top-level members
+    if (nextProp != "decoder")
+        return MFX_ERR_NOT_FOUND;
+
+    // parse 'decoder'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "CodecID") {
+        return ValidateAndSetProp(ePropDec_CodecID, value);
+    }
+    else if (nextProp == "MaxcodecLevel") {
+        return ValidateAndSetProp(ePropDec_MaxcodecLevel, value);
+    }
+    else if (nextProp != "decprofile") {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // parse 'decprofile'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "Profile") {
+        return ValidateAndSetProp(ePropDec_Profile, value);
+    }
+    else if (nextProp != "decmemdesc") {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // parse 'decmemdesc'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "MemHandleType") {
+        return ValidateAndSetProp(ePropDec_MemHandleType, value);
+    }
+    else if (nextProp == "Width") {
+        return ValidateAndSetProp(ePropDec_Width, value);
+    }
+    else if (nextProp == "Height") {
+        return ValidateAndSetProp(ePropDec_Height, value);
+    }
+    else if (nextProp == "ColorFormat" || nextProp == "ColorFormats") {
+        return ValidateAndSetProp(ePropDec_ColorFormats, value);
+    }
+
+    // end of mfxDecoderDescription options
+    return MFX_ERR_NOT_FOUND;
+}
+
+mfxStatus ConfigCtxVPL::SetFilterPropertyEnc(std::list<std::string> &propParsedString,
+                                             mfxVariant value) {
+    std::string nextProp;
+
+    nextProp = GetNextProp(propParsedString);
+
+    // no settable top-level members
+    if (nextProp != "encoder")
+        return MFX_ERR_NOT_FOUND;
+
+    // parse 'encoder'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "CodecID") {
+        return ValidateAndSetProp(ePropEnc_CodecID, value);
+    }
+    else if (nextProp == "MaxcodecLevel") {
+        return ValidateAndSetProp(ePropEnc_MaxcodecLevel, value);
+    }
+    else if (nextProp == "BiDirectionalPrediction") {
+        return ValidateAndSetProp(ePropEnc_BiDirectionalPrediction, value);
+    }
+    else if (nextProp != "encprofile") {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // parse 'encprofile'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "Profile") {
+        return ValidateAndSetProp(ePropEnc_Profile, value);
+    }
+    else if (nextProp != "encmemdesc") {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // parse 'encmemdesc'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "MemHandleType") {
+        return ValidateAndSetProp(ePropEnc_MemHandleType, value);
+    }
+    else if (nextProp == "Width") {
+        return ValidateAndSetProp(ePropEnc_Width, value);
+    }
+    else if (nextProp == "Height") {
+        return ValidateAndSetProp(ePropEnc_Height, value);
+    }
+    else if (nextProp == "ColorFormat" || nextProp == "ColorFormats") {
+        return ValidateAndSetProp(ePropEnc_ColorFormats, value);
+    }
+
+    // end of mfxEncoderDescription options
+    return MFX_ERR_NOT_FOUND;
+}
+
+mfxStatus ConfigCtxVPL::SetFilterPropertyVPP(std::list<std::string> &propParsedString,
+                                             mfxVariant value) {
+    std::string nextProp;
+
+    nextProp = GetNextProp(propParsedString);
+
+    // no settable top-level members
+    if (nextProp != "filter")
+        return MFX_ERR_NOT_FOUND;
+
+    // parse 'filter'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "FilterFourCC") {
+        return ValidateAndSetProp(ePropVPP_FilterFourCC, value);
+    }
+    else if (nextProp == "MaxDelayInFrames") {
+        return ValidateAndSetProp(ePropVPP_MaxDelayInFrames, value);
+    }
+    else if (nextProp != "memdesc") {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // parse 'memdesc'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "MemHandleType") {
+        return ValidateAndSetProp(ePropVPP_MemHandleType, value);
+    }
+    else if (nextProp == "Width") {
+        return ValidateAndSetProp(ePropVPP_Width, value);
+    }
+    else if (nextProp == "Height") {
+        return ValidateAndSetProp(ePropVPP_Height, value);
+    }
+    else if (nextProp != "format") {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // parse 'format'
+    nextProp = GetNextProp(propParsedString);
+    if (nextProp == "InFormat") {
+        return ValidateAndSetProp(ePropVPP_InFormat, value);
+    }
+    else if (nextProp == "OutFormat" || nextProp == "OutFormats") {
+        return ValidateAndSetProp(ePropVPP_OutFormat, value);
+    }
+
+    // end of mfxVPPDescription options
+    return MFX_ERR_NOT_FOUND;
+}
+
+// return codes (from spec):
+//   MFX_ERR_NOT_FOUND - name contains unknown parameter name
+//   MFX_ERR_UNSUPPORTED - value data type != parameter with provided name
+mfxStatus ConfigCtxVPL::SetFilterProperty(const mfxU8 *name, mfxVariant value) {
+    if (!name)
+        return MFX_ERR_NULL_PTR;
+
+    std::list<std::string> propParsedString;
+
+    // parse property string into individual properties,
+    //   separated by '.'
+    std::stringstream prop((char *)name);
+    std::string s;
+    propParsedString.clear();
+    while (getline(prop, s, '.')) {
+        propParsedString.push_back(s);
+    }
+
+    // get first property descriptor
+    std::string nextProp = GetNextProp(propParsedString);
+
+    // check for special-case properties, not part of mfxImplDescription
+    if (nextProp == "mfxHandleType") {
+        return ValidateAndSetProp(ePropSpecial_HandleType, value);
+    }
+    else if (nextProp == "mfxHDL") {
+        return ValidateAndSetProp(ePropSpecial_Handle, value);
+    }
+    else if (nextProp == "NumThread") {
+        return ValidateAndSetProp(ePropSpecial_NumThread, value);
+    }
+    else if (nextProp == "DXGIAdapterIndex") {
+#if defined(_WIN32) || defined(_WIN64)
+        // this property is only valid on Windows
+        return ValidateAndSetProp(ePropSpecial_DXGIAdapterIndex, value);
+#else
+        return MFX_ERR_NOT_FOUND;
+#endif
+    }
+
+    // to require that a specific function is implemented, use the property name
+    //   "mfxImplementedFunctions.FunctionsName"
+    if (nextProp == "mfxImplementedFunctions") {
+        nextProp = GetNextProp(propParsedString);
+        if (nextProp == "FunctionsName") {
+            return ValidateAndSetProp(ePropFunc_FunctionName, value);
+        }
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // standard properties must begin with "mfxImplDescription"
+    if (nextProp != "mfxImplDescription") {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // get next property descriptor
+    nextProp = GetNextProp(propParsedString);
+
+    // property is a top-level member of mfxImplDescription
+    if (nextProp == "Impl") {
+        return ValidateAndSetProp(ePropMain_Impl, value);
+    }
+    else if (nextProp == "AccelerationMode") {
+        return ValidateAndSetProp(ePropMain_AccelerationMode, value);
+    }
+    else if (nextProp == "mfxSurfacePoolMode") {
+        return ValidateAndSetProp(ePropMain_PoolAllocationPolicy, value);
+    }
+    else if (nextProp == "ApiVersion") {
+        // ApiVersion may be passed as single U32 (Version) or two U16's (Major, Minor)
+        nextProp = GetNextProp(propParsedString);
+        if (nextProp == "Version")
+            return ValidateAndSetProp(ePropMain_ApiVersion, value);
+        else if (nextProp == "Major")
+            return ValidateAndSetProp(ePropMain_ApiVersion_Major, value);
+        else if (nextProp == "Minor")
+            return ValidateAndSetProp(ePropMain_ApiVersion_Minor, value);
+        else
+            return MFX_ERR_NOT_FOUND;
+    }
+    else if (nextProp == "VendorID") {
+        return ValidateAndSetProp(ePropMain_VendorID, value);
+    }
+    else if (nextProp == "ImplName") {
+        return ValidateAndSetProp(ePropMain_ImplName, value);
+    }
+    else if (nextProp == "License") {
+        return ValidateAndSetProp(ePropMain_License, value);
+    }
+    else if (nextProp == "Keywords") {
+        return ValidateAndSetProp(ePropMain_Keywords, value);
+    }
+    else if (nextProp == "VendorImplID") {
+        return ValidateAndSetProp(ePropMain_VendorImplID, value);
+    }
+
+    // property is a member of mfxDeviceDescription
+    if (nextProp == "mfxDeviceDescription") {
+        nextProp = GetNextProp(propParsedString);
+        // old version of table in spec had extra "device", just skip if present
+        if (nextProp == "device")
+            nextProp = GetNextProp(propParsedString);
+
+        // special case - deviceID may be passed as U16 (default) or string (since API 2.4)
+        // for compatibility, both are supported (value.Type distinguishes between them)
+        if (nextProp == "DeviceID") {
+            if (value.Type == MFX_VARIANT_TYPE_PTR)
+                return ValidateAndSetProp(ePropDevice_DeviceIDStr, value);
+            else
+                return ValidateAndSetProp(ePropDevice_DeviceID, value);
+        }
+
+        if (nextProp == "MediaAdapterType") {
+            return ValidateAndSetProp(ePropDevice_MediaAdapterType, value);
+        }
+
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    // property is a member of mfxDecoderDescription
+    if (nextProp == "mfxDecoderDescription") {
+        return SetFilterPropertyDec(propParsedString, value);
+    }
+
+    if (nextProp == "mfxEncoderDescription") {
+        return SetFilterPropertyEnc(propParsedString, value);
+    }
+
+    if (nextProp == "mfxVPPDescription") {
+        return SetFilterPropertyVPP(propParsedString, value);
+    }
+
+    return MFX_ERR_NOT_FOUND;
+}
+
+#define CHECK_IDX(idxA, idxB, numB) \
+    if ((idxB) == (numB)) {         \
+        (idxA)++;                   \
+        (idxB) = 0;                 \
+        continue;                   \
+    }
+
+mfxStatus ConfigCtxVPL::GetFlatDescriptionsDec(const mfxImplDescription *libImplDesc,
+                                               std::list<DecConfig> &decConfigList) {
+    mfxU32 codecIdx   = 0;
+    mfxU32 profileIdx = 0;
+    mfxU32 memIdx     = 0;
+    mfxU32 outFmtIdx  = 0;
+
+    DecCodec *decCodec     = nullptr;
+    DecProfile *decProfile = nullptr;
+    DecMemDesc *decMemDesc = nullptr;
+
+    while (codecIdx < libImplDesc->Dec.NumCodecs) {
+        DecConfig dc = {};
+
+        decCodec         = &(libImplDesc->Dec.Codecs[codecIdx]);
+        dc.CodecID       = decCodec->CodecID;
+        dc.MaxcodecLevel = decCodec->MaxcodecLevel;
+        CHECK_IDX(codecIdx, profileIdx, decCodec->NumProfiles);
+
+        decProfile = &(decCodec->Profiles[profileIdx]);
+        dc.Profile = decProfile->Profile;
+        CHECK_IDX(profileIdx, memIdx, decProfile->NumMemTypes);
+
+        decMemDesc       = &(decProfile->MemDesc[memIdx]);
+        dc.MemHandleType = decMemDesc->MemHandleType;
+        dc.Width         = decMemDesc->Width;
+        dc.Height        = decMemDesc->Height;
+        CHECK_IDX(memIdx, outFmtIdx, decMemDesc->NumColorFormats);
+
+        dc.ColorFormat = decMemDesc->ColorFormats[outFmtIdx];
+        outFmtIdx++;
+
+        // we have a valid, unique description - add to list
+        decConfigList.push_back(dc);
+    }
+
+    if (decConfigList.empty())
+        return MFX_ERR_INVALID_VIDEO_PARAM;
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus ConfigCtxVPL::GetFlatDescriptionsEnc(const mfxImplDescription *libImplDesc,
+                                               std::list<EncConfig> &encConfigList) {
+    mfxU32 codecIdx   = 0;
+    mfxU32 profileIdx = 0;
+    mfxU32 memIdx     = 0;
+    mfxU32 inFmtIdx   = 0;
+
+    EncCodec *encCodec     = nullptr;
+    EncProfile *encProfile = nullptr;
+    EncMemDesc *encMemDesc = nullptr;
+
+    while (codecIdx < libImplDesc->Enc.NumCodecs) {
+        EncConfig ec = {};
+
+        encCodec                   = &(libImplDesc->Enc.Codecs[codecIdx]);
+        ec.CodecID                 = encCodec->CodecID;
+        ec.MaxcodecLevel           = encCodec->MaxcodecLevel;
+        ec.BiDirectionalPrediction = encCodec->BiDirectionalPrediction;
+        CHECK_IDX(codecIdx, profileIdx, encCodec->NumProfiles);
+
+        encProfile = &(encCodec->Profiles[profileIdx]);
+        ec.Profile = encProfile->Profile;
+        CHECK_IDX(profileIdx, memIdx, encProfile->NumMemTypes);
+
+        encMemDesc       = &(encProfile->MemDesc[memIdx]);
+        ec.MemHandleType = encMemDesc->MemHandleType;
+        ec.Width         = encMemDesc->Width;
+        ec.Height        = encMemDesc->Height;
+        CHECK_IDX(memIdx, inFmtIdx, encMemDesc->NumColorFormats);
+
+        ec.ColorFormat = encMemDesc->ColorFormats[inFmtIdx];
+        inFmtIdx++;
+
+        // we have a valid, unique description - add to list
+        encConfigList.push_back(ec);
+    }
+
+    if (encConfigList.empty())
+        return MFX_ERR_INVALID_VIDEO_PARAM;
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus ConfigCtxVPL::GetFlatDescriptionsVPP(const mfxImplDescription *libImplDesc,
+                                               std::list<VPPConfig> &vppConfigList) {
+    mfxU32 filterIdx = 0;
+    mfxU32 memIdx    = 0;
+    mfxU32 inFmtIdx  = 0;
+    mfxU32 outFmtIdx = 0;
+
+    VPPFilter *vppFilter   = nullptr;
+    VPPMemDesc *vppMemDesc = nullptr;
+    VPPFormat *vppFormat   = nullptr;
+
+    while (filterIdx < libImplDesc->VPP.NumFilters) {
+        VPPConfig vc = {};
+
+        vppFilter           = &(libImplDesc->VPP.Filters[filterIdx]);
+        vc.FilterFourCC     = vppFilter->FilterFourCC;
+        vc.MaxDelayInFrames = vppFilter->MaxDelayInFrames;
+        CHECK_IDX(filterIdx, memIdx, vppFilter->NumMemTypes);
+
+        vppMemDesc       = &(vppFilter->MemDesc[memIdx]);
+        vc.MemHandleType = vppMemDesc->MemHandleType;
+        vc.Width         = vppMemDesc->Width;
+        vc.Height        = vppMemDesc->Height;
+        CHECK_IDX(memIdx, inFmtIdx, vppMemDesc->NumInFormats);
+
+        vppFormat   = &(vppMemDesc->Formats[inFmtIdx]);
+        vc.InFormat = vppFormat->InFormat;
+        CHECK_IDX(inFmtIdx, outFmtIdx, vppFormat->NumOutFormat);
+
+        vc.OutFormat = vppFormat->OutFormats[outFmtIdx];
+        outFmtIdx++;
+
+        // we have a valid, unique description - add to list
+        vppConfigList.push_back(vc);
+    }
+
+    if (vppConfigList.empty())
+        return MFX_ERR_INVALID_VIDEO_PARAM;
+
+    return MFX_ERR_NONE;
+}
+
+#define CHECK_PROP(idx, type, val)                             \
+    if ((cfgPropsAll[(idx)].Type != MFX_VARIANT_TYPE_UNSET) && \
+        (cfgPropsAll[(idx)].Data.type != val))                 \
+        isCompatible = false;
+
+mfxStatus ConfigCtxVPL::CheckPropsGeneral(const mfxVariant cfgPropsAll[],
+                                          const mfxImplDescription *libImplDesc) {
+    bool isCompatible = true;
+
+    // check if this implementation includes
+    //   all of the required top-level properties
+    CHECK_PROP(ePropMain_Impl, U32, libImplDesc->Impl);
+    CHECK_PROP(ePropMain_VendorID, U32, libImplDesc->VendorID);
+    CHECK_PROP(ePropMain_VendorImplID, U32, libImplDesc->VendorImplID);
+
+    // check API version in calling function since major and minor may be passed
+    //   in separate cfg objects
+
+    if (libImplDesc->AccelerationModeDescription.NumAccelerationModes > 0) {
+        if (cfgPropsAll[ePropMain_AccelerationMode].Type != MFX_VARIANT_TYPE_UNSET) {
+            // check all supported modes if list is filled out
+            mfxU16 numModes = libImplDesc->AccelerationModeDescription.NumAccelerationModes;
+            mfxAccelerationMode modeRequested =
+                (mfxAccelerationMode)(cfgPropsAll[ePropMain_AccelerationMode].Data.U32);
+            auto *modeTab = libImplDesc->AccelerationModeDescription.Mode;
+
+            auto *m = std::find(modeTab, modeTab + numModes, modeRequested);
+            if (m == modeTab + numModes)
+                isCompatible = false;
+        }
+    }
+    else {
+        // check default mode
+        CHECK_PROP(ePropMain_AccelerationMode, U32, libImplDesc->AccelerationMode);
+    }
+
+    if (cfgPropsAll[ePropMain_PoolAllocationPolicy].Type != MFX_VARIANT_TYPE_UNSET) {
+        // mfxPoolAllocationPolicy added with struct version 1.2
+        mfxU16 numPolicies = 0;
+        if (libImplDesc->Version.Version >= MFX_STRUCT_VERSION(1, 2))
+            numPolicies = libImplDesc->PoolPolicies.NumPoolPolicies;
+
+        // check all supported policies if list is filled out
+        // if structure is not present (old version) numPolicies will be 0, so skipped
+        if (isCompatible == true && numPolicies > 0) {
+            mfxPoolAllocationPolicy policyRequested =
+                (mfxPoolAllocationPolicy)(cfgPropsAll[ePropMain_PoolAllocationPolicy].Data.U32);
+            auto *policyTab = libImplDesc->PoolPolicies.Policy;
+
+            auto *m = std::find(policyTab, policyTab + numPolicies, policyRequested);
+            if (m == policyTab + numPolicies)
+                isCompatible = false;
+        }
+        else {
+            isCompatible = false;
+        }
+    }
+
+    // check string: ImplName (string match)
+    if (cfgPropsAll[ePropMain_ImplName].Type != MFX_VARIANT_TYPE_UNSET) {
+        std::string filtName = *(std::string *)(cfgPropsAll[ePropMain_ImplName].Data.Ptr);
+        std::string implName = libImplDesc->ImplName;
+        if (filtName != implName)
+            isCompatible = false;
+    }
+
+    // check string: License (tokenized)
+    if (cfgPropsAll[ePropMain_License].Type != MFX_VARIANT_TYPE_UNSET) {
+        std::string license = *(std::string *)(cfgPropsAll[ePropMain_License].Data.Ptr);
+        if (CheckPropString(libImplDesc->License, license) != MFX_ERR_NONE)
+            isCompatible = false;
+    }
+
+    // check string: Keywords (tokenized)
+    if (cfgPropsAll[ePropMain_Keywords].Type != MFX_VARIANT_TYPE_UNSET) {
+        std::string keywords = *(std::string *)(cfgPropsAll[ePropMain_Keywords].Data.Ptr);
+        if (CheckPropString(libImplDesc->Keywords, keywords) != MFX_ERR_NONE)
+            isCompatible = false;
+    }
+
+    // check DeviceID - stored as char*, but passed in for filtering as U16
+    // convert both to unsigned ints and compare
+    if (cfgPropsAll[ePropDevice_DeviceID].Type != MFX_VARIANT_TYPE_UNSET) {
+        unsigned int implDeviceID = 0;
+        try {
+            implDeviceID = std::stoi(libImplDesc->Dev.DeviceID, 0, 16);
+        }
+        catch (...) {
+            return MFX_ERR_UNSUPPORTED;
+        }
+
+        unsigned int filtDeviceID = (unsigned int)(cfgPropsAll[ePropDevice_DeviceID].Data.U16);
+        if (implDeviceID != filtDeviceID)
+            isCompatible = false;
+    }
+
+    if (cfgPropsAll[ePropDevice_DeviceIDStr].Type != MFX_VARIANT_TYPE_UNSET) {
+        // since API 2.4 - pass DeviceID as string (do string match)
+        std::string filtDeviceID = *(std::string *)(cfgPropsAll[ePropDevice_DeviceIDStr].Data.Ptr);
+        std::string implDeviceID = libImplDesc->Dev.DeviceID;
+        if (filtDeviceID != implDeviceID)
+            isCompatible = false;
+    }
+
+    // mfxDeviceDescription.MediaAdapterType introduced in API 2.5, structure version 1.1
+    // do not check this for MSDK libs (allow it to pass)
+    if (libImplDesc->ApiVersion.Major >= 2) {
+        if (cfgPropsAll[ePropDevice_MediaAdapterType].Type != MFX_VARIANT_TYPE_UNSET) {
+            if (libImplDesc->Dev.Version.Version < MFX_STRUCT_VERSION(1, 1))
+                isCompatible = false;
+
+            CHECK_PROP(ePropDevice_MediaAdapterType, U16, libImplDesc->Dev.MediaAdapterType);
+        }
+    }
+
+    if (isCompatible == true)
+        return MFX_ERR_NONE;
+
+    return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus ConfigCtxVPL::CheckPropsDec(const mfxVariant cfgPropsAll[],
+                                      std::list<DecConfig> decConfigList) {
+    auto it = decConfigList.begin();
+    while (it != decConfigList.end()) {
+        DecConfig dc      = (DecConfig)(*it);
+        bool isCompatible = true;
+
+        // check if this decode description includes
+        //   all of the required decoder properties
+        CHECK_PROP(ePropDec_CodecID, U32, dc.CodecID);
+        CHECK_PROP(ePropDec_MaxcodecLevel, U16, dc.MaxcodecLevel);
+        CHECK_PROP(ePropDec_Profile, U32, dc.Profile);
+        CHECK_PROP(ePropDec_MemHandleType, U32, dc.MemHandleType);
+        CHECK_PROP(ePropDec_ColorFormats, U32, dc.ColorFormat);
+
+        // special handling for properties passed via pointer
+        if (cfgPropsAll[ePropDec_Width].Type != MFX_VARIANT_TYPE_UNSET) {
+            mfxRange32U width = {};
+            if (cfgPropsAll[ePropDec_Width].Data.Ptr)
+                width = *((mfxRange32U *)(cfgPropsAll[ePropDec_Width].Data.Ptr));
+
+            if ((width.Max > dc.Width.Max) || (width.Min < dc.Width.Min) ||
+                (width.Step < dc.Width.Step))
+                isCompatible = false;
+        }
+
+        if (cfgPropsAll[ePropDec_Height].Type != MFX_VARIANT_TYPE_UNSET) {
+            mfxRange32U height = {};
+            if (cfgPropsAll[ePropDec_Height].Data.Ptr)
+                height = *((mfxRange32U *)(cfgPropsAll[ePropDec_Height].Data.Ptr));
+
+            if ((height.Max > dc.Height.Max) || (height.Min < dc.Height.Min) ||
+                (height.Step < dc.Height.Step))
+                isCompatible = false;
+        }
+
+        if (isCompatible == true)
+            return MFX_ERR_NONE;
+
+        it++;
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus ConfigCtxVPL::CheckPropsEnc(const mfxVariant cfgPropsAll[],
+                                      std::list<EncConfig> encConfigList) {
+    auto it = encConfigList.begin();
+    while (it != encConfigList.end()) {
+        EncConfig ec      = (EncConfig)(*it);
+        bool isCompatible = true;
+
+        // check if this encode description includes
+        //   all of the required encoder properties
+        CHECK_PROP(ePropEnc_CodecID, U32, ec.CodecID);
+        CHECK_PROP(ePropEnc_MaxcodecLevel, U16, ec.MaxcodecLevel);
+        CHECK_PROP(ePropEnc_BiDirectionalPrediction, U16, ec.BiDirectionalPrediction);
+        CHECK_PROP(ePropEnc_Profile, U32, ec.Profile);
+        CHECK_PROP(ePropEnc_MemHandleType, U32, ec.MemHandleType);
+        CHECK_PROP(ePropEnc_ColorFormats, U32, ec.ColorFormat);
+
+        // special handling for properties passed via pointer
+        if (cfgPropsAll[ePropEnc_Width].Type != MFX_VARIANT_TYPE_UNSET) {
+            mfxRange32U width = {};
+            if (cfgPropsAll[ePropEnc_Width].Data.Ptr)
+                width = *((mfxRange32U *)(cfgPropsAll[ePropEnc_Width].Data.Ptr));
+
+            if ((width.Max > ec.Width.Max) || (width.Min < ec.Width.Min) ||
+                (width.Step < ec.Width.Step))
+                isCompatible = false;
+        }
+
+        if (cfgPropsAll[ePropEnc_Height].Type != MFX_VARIANT_TYPE_UNSET) {
+            mfxRange32U height = {};
+            if (cfgPropsAll[ePropEnc_Height].Data.Ptr)
+                height = *((mfxRange32U *)(cfgPropsAll[ePropEnc_Height].Data.Ptr));
+
+            if ((height.Max > ec.Height.Max) || (height.Min < ec.Height.Min) ||
+                (height.Step < ec.Height.Step))
+                isCompatible = false;
+        }
+
+        if (isCompatible == true)
+            return MFX_ERR_NONE;
+
+        it++;
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus ConfigCtxVPL::CheckPropsVPP(const mfxVariant cfgPropsAll[],
+                                      std::list<VPPConfig> vppConfigList) {
+    auto it = vppConfigList.begin();
+    while (it != vppConfigList.end()) {
+        VPPConfig vc      = (VPPConfig)(*it);
+        bool isCompatible = true;
+
+        // check if this filter description includes
+        //   all of the required VPP properties
+        CHECK_PROP(ePropVPP_FilterFourCC, U32, vc.FilterFourCC);
+        CHECK_PROP(ePropVPP_MaxDelayInFrames, U16, vc.MaxDelayInFrames);
+        CHECK_PROP(ePropVPP_MemHandleType, U32, vc.MemHandleType);
+        CHECK_PROP(ePropVPP_InFormat, U32, vc.InFormat);
+        CHECK_PROP(ePropVPP_OutFormat, U32, vc.OutFormat);
+
+        // special handling for properties passed via pointer
+        if (cfgPropsAll[ePropVPP_Width].Type != MFX_VARIANT_TYPE_UNSET) {
+            mfxRange32U width = {};
+            if (cfgPropsAll[ePropVPP_Width].Data.Ptr)
+                width = *((mfxRange32U *)(cfgPropsAll[ePropVPP_Width].Data.Ptr));
+
+            if ((width.Max > vc.Width.Max) || (width.Min < vc.Width.Min) ||
+                (width.Step < vc.Width.Step))
+                isCompatible = false;
+        }
+
+        if (cfgPropsAll[ePropVPP_Height].Type != MFX_VARIANT_TYPE_UNSET) {
+            mfxRange32U height = {};
+            if (cfgPropsAll[ePropVPP_Height].Data.Ptr)
+                height = *((mfxRange32U *)(cfgPropsAll[ePropVPP_Height].Data.Ptr));
+
+            if ((height.Max > vc.Height.Max) || (height.Min < vc.Height.Min) ||
+                (height.Step < vc.Height.Step))
+                isCompatible = false;
+        }
+
+        if (isCompatible == true)
+            return MFX_ERR_NONE;
+
+        it++;
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+}
+
+// implString = string from implDesc - one or more comma-separated tokens
+// filtString = string user is looking for - one or more comma-separated tokens
+// we parse filtString into tokens, then check if all of them are present in implString
+mfxStatus ConfigCtxVPL::CheckPropString(const mfxChar *implString, const std::string filtString) {
+    std::list<std::string> tokenString;
+    std::string s;
+
+    // parse implString string into tokens, separated by ','
+    std::stringstream implSS((char *)implString);
+    while (getline(implSS, s, ',')) {
+        tokenString.push_back(s);
+    }
+
+    // parse filtString string into tokens, separated by ','
+    // check that each token is present in implString, otherwise return error
+    std::stringstream filtSS(filtString);
+    while (getline(filtSS, s, ',')) {
+        if (std::find(tokenString.begin(), tokenString.end(), s) == tokenString.end())
+            return MFX_ERR_UNSUPPORTED;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus ConfigCtxVPL::ValidateConfig(const mfxImplDescription *libImplDesc,
+                                       const mfxImplementedFunctions *libImplFuncs,
+                                       std::list<ConfigCtxVPL *> configCtxList,
+                                       LibType libType,
+                                       SpecialConfig *specialConfig) {
+    mfxU32 idx;
+    bool decRequested = false;
+    bool encRequested = false;
+    bool vppRequested = false;
+
+    bool bImplValid = true;
+
+    if (!libImplDesc)
+        return MFX_ERR_NULL_PTR;
+
+    std::list<DecConfig> decConfigList;
+    std::list<EncConfig> encConfigList;
+    std::list<VPPConfig> vppConfigList;
+
+    // generate "flat" descriptions of each combination
+    //   (e.g. multiple profiles from the same codec)
+    GetFlatDescriptionsDec(libImplDesc, decConfigList);
+    GetFlatDescriptionsEnc(libImplDesc, encConfigList);
+    GetFlatDescriptionsVPP(libImplDesc, vppConfigList);
+
+    // list of functions required to be implemented
+    std::list<std::string> implFunctionList;
+    implFunctionList.clear();
+
+    // check requested API version
+    mfxVersion reqVersion = {};
+    bool bVerSetMajor     = false;
+    bool bVerSetMinor     = false;
+
+    // iterate through all filters and populate cfgPropsAll
+    auto it = configCtxList.begin();
+
+    while (it != configCtxList.end()) {
+        ConfigCtxVPL *config = (*it);
+        it++;
+
+        // initially all properties are unset
+        mfxVariant cfgPropsAll[eProp_TotalProps] = {};
+        for (idx = 0; idx < eProp_TotalProps; idx++) {
+            cfgPropsAll[idx].Type = MFX_VARIANT_TYPE_UNSET;
+        }
+
+        for (idx = 0; idx < eProp_TotalProps; idx++) {
+            // ignore unset properties
+            if (config->m_propVar[idx].Type == MFX_VARIANT_TYPE_UNSET)
+                continue;
+
+            // if property is required function, add to list which will be checked below
+            if (idx == ePropFunc_FunctionName) {
+                implFunctionList.push_back(config->m_implFunctionName);
+                continue;
+            }
+
+            cfgPropsAll[idx].Type = config->m_propVar[idx].Type;
+            cfgPropsAll[idx].Data = config->m_propVar[idx].Data;
+
+            if (idx >= ePropDec_CodecID && idx <= ePropDec_ColorFormats)
+                decRequested = true;
+            else if (idx >= ePropEnc_CodecID && idx <= ePropEnc_ColorFormats)
+                encRequested = true;
+            else if (idx >= ePropVPP_FilterFourCC && idx <= ePropVPP_OutFormat)
+                vppRequested = true;
+        }
+
+        // if already marked invalid, no need to check props again
+        // however we still need to iterate over all of the config objects
+        //   to get any non-filtering properties (returned in SpecialConfig)
+        if (bImplValid == true) {
+            if (CheckPropsGeneral(cfgPropsAll, libImplDesc))
+                bImplValid = false;
+
+            // MSDK RT compatibility mode (1.x) does not provide Dec/Enc/VPP caps
+            // ignore these filters if set (do not use them to _exclude_ the library)
+            if (libType != LibTypeMSDK) {
+                if (decRequested && CheckPropsDec(cfgPropsAll, decConfigList))
+                    bImplValid = false;
+
+                if (encRequested && CheckPropsEnc(cfgPropsAll, encConfigList))
+                    bImplValid = false;
+
+                if (vppRequested && CheckPropsVPP(cfgPropsAll, vppConfigList))
+                    bImplValid = false;
+            }
+        }
+
+        // update any special (including non-filtering) properties, for use by caller
+        // if multiple cfg objects set the same non-filtering property, the last (most recent) one is used
+        if (cfgPropsAll[ePropSpecial_HandleType].Type != MFX_VARIANT_TYPE_UNSET) {
+            specialConfig->deviceHandleType =
+                (mfxHandleType)cfgPropsAll[ePropSpecial_HandleType].Data.U32;
+            specialConfig->bIsSet_deviceHandleType = true;
+        }
+
+        if (cfgPropsAll[ePropSpecial_Handle].Type != MFX_VARIANT_TYPE_UNSET) {
+            specialConfig->deviceHandle        = (mfxHDL)cfgPropsAll[ePropSpecial_Handle].Data.Ptr;
+            specialConfig->bIsSet_deviceHandle = true;
+        }
+
+        if (cfgPropsAll[ePropSpecial_NumThread].Type != MFX_VARIANT_TYPE_UNSET) {
+            specialConfig->NumThread        = cfgPropsAll[ePropSpecial_NumThread].Data.U32;
+            specialConfig->bIsSet_NumThread = true;
+        }
+
+        if (cfgPropsAll[ePropSpecial_DXGIAdapterIndex].Type != MFX_VARIANT_TYPE_UNSET) {
+            specialConfig->dxgiAdapterIdx =
+                (mfxU32)cfgPropsAll[ePropSpecial_DXGIAdapterIndex].Data.U32;
+            specialConfig->bIsSet_dxgiAdapterIdx = true;
+        }
+
+        if (cfgPropsAll[ePropMain_AccelerationMode].Type != MFX_VARIANT_TYPE_UNSET) {
+            specialConfig->accelerationMode =
+                (mfxAccelerationMode)cfgPropsAll[ePropMain_AccelerationMode].Data.U32;
+            specialConfig->bIsSet_accelerationMode = true;
+        }
+
+        // special handling for API version which may be passed either as single U32 (Version)
+        //   or two U16 (Major, Minor) which could come in separate cfg objects
+        if (cfgPropsAll[ePropMain_ApiVersion].Type != MFX_VARIANT_TYPE_UNSET) {
+            reqVersion.Version = (mfxU32)cfgPropsAll[ePropMain_ApiVersion].Data.U32;
+            bVerSetMajor       = true;
+            bVerSetMinor       = true;
+        }
+        else {
+            if (cfgPropsAll[ePropMain_ApiVersion_Major].Type != MFX_VARIANT_TYPE_UNSET) {
+                reqVersion.Major = (mfxU32)cfgPropsAll[ePropMain_ApiVersion_Major].Data.U16;
+                bVerSetMajor     = true;
+            }
+
+            if (cfgPropsAll[ePropMain_ApiVersion_Minor].Type != MFX_VARIANT_TYPE_UNSET) {
+                reqVersion.Minor = (mfxU32)cfgPropsAll[ePropMain_ApiVersion_Minor].Data.U16;
+                bVerSetMinor     = true;
+            }
+        }
+    }
+
+    if (bVerSetMajor && bVerSetMinor) {
+        // require both Major and Minor to be set if filtering this way
+        if (libImplDesc->ApiVersion.Version < reqVersion.Version)
+            bImplValid = false;
+
+        specialConfig->ApiVersion.Version = reqVersion.Version;
+        specialConfig->bIsSet_ApiVersion  = true;
+    }
+
+    if (bImplValid == false)
+        return MFX_ERR_UNSUPPORTED;
+
+    // check whether required functions are implemented
+    if (!implFunctionList.empty()) {
+        if (!libImplFuncs) {
+            // library did not provide list of implemented functions
+            return MFX_ERR_UNSUPPORTED;
+        }
+
+        auto fn = implFunctionList.begin();
+        while (fn != implFunctionList.end()) {
+            std::string fnName = (*fn++);
+            mfxU32 fnIdx;
+
+            // search for fnName in list of implemented functions
+            for (fnIdx = 0; fnIdx < libImplFuncs->NumFunctions; fnIdx++) {
+                if (fnName == libImplFuncs->FunctionsName[fnIdx])
+                    break;
+            }
+
+            if (fnIdx == libImplFuncs->NumFunctions)
+                return MFX_ERR_UNSUPPORTED;
+        }
+    }
+
+    return MFX_ERR_NONE;
+}
+
+bool ConfigCtxVPL::CheckLowLatencyConfig(std::list<ConfigCtxVPL *> configCtxList,
+                                         SpecialConfig *specialConfig) {
+    mfxU32 idx;
+    bool bLowLatency = true;
+
+    // initially all properties are unset
+    mfxVariant cfgPropsAll[eProp_TotalProps] = {};
+    for (idx = 0; idx < eProp_TotalProps; idx++)
+        cfgPropsAll[idx].Type = MFX_VARIANT_TYPE_UNSET;
+
+    // iterate through all filters and populate cfgPropsAll
+    // for purposes of low-latency enabling, we check the last (most recent) value of each filter
+    //   property, in the case that multiple mfxConfig objects were created
+    // preferred usage is just to create one mfxConfig and set all of the required props in it
+
+    auto it = configCtxList.begin();
+    while (it != configCtxList.end()) {
+        ConfigCtxVPL *config = (*it);
+        it++;
+
+        for (idx = 0; idx < eProp_TotalProps; idx++) {
+            // ignore unset properties
+            if (config->m_propVar[idx].Type == MFX_VARIANT_TYPE_UNSET)
+                continue;
+
+            cfgPropsAll[idx].Type = config->m_propVar[idx].Type;
+            cfgPropsAll[idx].Data = config->m_propVar[idx].Data;
+        }
+    }
+
+    for (mfxU32 idx = 0; idx < eProp_TotalProps; idx++) {
+        switch (idx) {
+            case ePropMain_Impl:
+                if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
+                    if (cfgPropsAll[idx].Data.U32 == MFX_IMPL_TYPE_HARDWARE)
+                        continue;
+                }
+                bLowLatency = false;
+                break;
+
+            case ePropMain_ImplName:
+                if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_PTR && cfgPropsAll[idx].Data.Ptr) {
+                    std::string s = *(std::string *)(cfgPropsAll[idx].Data.Ptr);
+                    if (s == "mfx-gen")
+                        continue;
+                }
+                bLowLatency = false;
+                break;
+
+            case ePropMain_VendorID:
+                if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
+                    if (cfgPropsAll[idx].Data.U32 == 0x8086)
+                        continue;
+                }
+                bLowLatency = false;
+                break;
+
+            // application must set AccelerationMode for lowlatency - will be passed to RT in MFXInitialize()
+            case ePropMain_AccelerationMode:
+                if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
+                    specialConfig->accelerationMode =
+                        (mfxAccelerationMode)cfgPropsAll[ePropMain_AccelerationMode].Data.U32;
+                    specialConfig->bIsSet_accelerationMode = true;
+                    continue;
+                }
+                bLowLatency = false;
+                break;
+
+            // application may set ApiVersion with lowlatency, but not required
+            case ePropMain_ApiVersion:
+                if (cfgPropsAll[ePropMain_ApiVersion].Type != MFX_VARIANT_TYPE_UNSET) {
+                    specialConfig->ApiVersion.Version =
+                        (mfxU32)cfgPropsAll[ePropMain_ApiVersion].Data.U32;
+                    specialConfig->bIsSet_ApiVersion = true;
+                }
+                break;
+
+            // following are non-filtering properties - they may be set here or not (don't affect low latency)
+            case ePropSpecial_HandleType:
+                if (cfgPropsAll[ePropSpecial_HandleType].Type != MFX_VARIANT_TYPE_UNSET) {
+                    specialConfig->deviceHandleType =
+                        (mfxHandleType)cfgPropsAll[ePropSpecial_HandleType].Data.U32;
+                    specialConfig->bIsSet_deviceHandleType = true;
+                }
+                break;
+
+            case ePropSpecial_Handle:
+                if (cfgPropsAll[ePropSpecial_Handle].Type != MFX_VARIANT_TYPE_UNSET) {
+                    specialConfig->deviceHandle = (mfxHDL)cfgPropsAll[ePropSpecial_Handle].Data.Ptr;
+                    specialConfig->bIsSet_deviceHandle = true;
+                }
+                break;
+
+            case ePropSpecial_NumThread:
+                if (cfgPropsAll[ePropSpecial_NumThread].Type != MFX_VARIANT_TYPE_UNSET) {
+                    specialConfig->NumThread        = cfgPropsAll[ePropSpecial_NumThread].Data.U32;
+                    specialConfig->bIsSet_NumThread = true;
+                }
+                break;
+
+            // will be passed to RT in MFXInitialize(), if unset will be 0
+            case ePropSpecial_DXGIAdapterIndex:
+                if (cfgPropsAll[idx].Type == MFX_VARIANT_TYPE_U32) {
+                    specialConfig->dxgiAdapterIdx =
+                        (mfxU32)cfgPropsAll[ePropSpecial_DXGIAdapterIndex].Data.U32;
+                    specialConfig->bIsSet_dxgiAdapterIdx = true;
+                    continue;
+                }
+                break;
+
+            default:
+                if (cfgPropsAll[idx].Type != MFX_VARIANT_TYPE_UNSET)
+                    bLowLatency = false;
+                break;
+        }
+    }
+
+    return bLowLatency;
+}
+
+bool ConfigCtxVPL::ParseDeviceIDx86(mfxChar *cDeviceID, mfxU32 &deviceID, mfxU32 &adapterIdx) {
+    std::string strDevID(cDeviceID);
+    std::regex reDevIDAll("[0-9a-fA-F]+/[0-9]+");
+    std::regex reDevIDMin("[0-9a-fA-F]+");
+
+    deviceID   = DEVICE_ID_UNKNOWN;
+    adapterIdx = ADAPTER_IDX_UNKNOWN;
+
+    bool bHasAdapterIdx = false;
+    if (std::regex_match(strDevID, reDevIDAll)) {
+        // check for DeviceID in format "devID/adapterIdx"
+        //   devID = hex value
+        //   adapterIdx = decimal integer
+        bHasAdapterIdx = true;
+    }
+    else if (std::regex_match(strDevID, reDevIDMin)) {
+        // check for DeviceID in format "devID"
+        //   (no adpaterIdx)
+        bHasAdapterIdx = false;
+    }
+    else {
+        // invalid format
+        return false;
+    }
+
+    // get deviceID (value before the slash, if present)
+    try {
+        deviceID = std::stoi(strDevID, 0, 16);
+    }
+    catch (...) {
+        return false;
+    }
+
+    if (bHasAdapterIdx) {
+        // get adapter index (value after the slash)
+        size_t idx = strDevID.rfind('/');
+        if (idx == std::string::npos)
+            return false;
+
+        try {
+            adapterIdx = std::stoi(strDevID.substr(idx + 1));
+        }
+        catch (...) {
+            return false;
+        }
+    }
+
+    return true;
+}
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_loader.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_loader.cpp
new file mode 100644 (file)
index 0000000..e9371b4
--- /dev/null
@@ -0,0 +1,1669 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include <algorithm>
+
+#include "vpl/mfx_dispatcher_vpl.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+    #include "vpl/mfx_dispatcher_vpl_win.h"
+#endif
+
+// leave table formatting alone
+// clang-format off
+
+// new functions for API >= 2.0
+static const VPLFunctionDesc FunctionDesc2[NumVPLFunctions] = {
+    { "MFXQueryImplsDescription",               { {  0, 2 } } },
+    { "MFXReleaseImplDescription",              { {  0, 2 } } },
+    { "MFXMemory_GetSurfaceForVPP",             { {  0, 2 } } },
+    { "MFXMemory_GetSurfaceForEncode",          { {  0, 2 } } },
+    { "MFXMemory_GetSurfaceForDecode",          { {  0, 2 } } },
+    { "MFXInitialize",                          { {  0, 2 } } },
+
+    { "MFXMemory_GetSurfaceForVPPOut",          { {  1, 2 } } },
+    { "MFXVideoDECODE_VPP_Init",                { {  1, 2 } } },
+    { "MFXVideoDECODE_VPP_DecodeFrameAsync",    { {  1, 2 } } },
+    { "MFXVideoDECODE_VPP_Reset",               { {  1, 2 } } },
+    { "MFXVideoDECODE_VPP_GetChannelParam",     { {  1, 2 } } },
+    { "MFXVideoDECODE_VPP_Close",               { {  1, 2 } } },
+    { "MFXVideoVPP_ProcessFrameAsync",          { {  1, 2 } } },
+};
+
+static const VPLFunctionDesc MSDKCompatFunctions[NumMSDKFunctions] = {
+    { "MFXInitEx",                              { { 14, 1 } } },
+    { "MFXClose" ,                              { {  0, 1 } } },
+};
+
+// end table formatting
+// clang-format on
+
+// implementation of loader context (mfxLoader)
+// each loader instance will build a list of valid runtimes and allow
+// application to create sessions with them
+LoaderCtxVPL::LoaderCtxVPL()
+        : m_libInfoList(),
+          m_implInfoList(),
+          m_configCtxList(),
+          m_gpuAdapterInfo(),
+          m_specialConfig(),
+          m_implIdxNext(0),
+          m_bKeepCapsUntilUnload(true),
+          m_envVar(),
+          m_dispLog() {
+    // allow loader to distinguish between property value of 0
+    //   and property not set
+    m_specialConfig.bIsSet_deviceHandleType = false;
+    m_specialConfig.bIsSet_deviceHandle     = false;
+    m_specialConfig.bIsSet_accelerationMode = false;
+    m_specialConfig.bIsSet_ApiVersion       = false;
+    m_specialConfig.bIsSet_dxgiAdapterIdx   = false;
+
+    // initial state
+    m_bLowLatency           = false;
+    m_bNeedUpdateValidImpls = true;
+    m_bNeedFullQuery        = true;
+    m_bNeedLowLatencyQuery  = true;
+    m_bPriorityPathEnabled  = false;
+
+    return;
+}
+
+LoaderCtxVPL::~LoaderCtxVPL() {
+    return;
+}
+
+mfxStatus LoaderCtxVPL::FullLoadAndQuery() {
+    // disable low latency mode
+    m_bLowLatency = false;
+
+    // search directories for candidate implementations based on search order in
+    // spec
+    mfxStatus sts = BuildListOfCandidateLibs();
+    if (MFX_ERR_NONE != sts)
+        return sts;
+
+    // prune libraries which are not actually implementations, filling function
+    // ptr table for each library which is
+    mfxU32 numLibs = CheckValidLibraries();
+    if (numLibs == 0)
+        return MFX_ERR_UNSUPPORTED;
+
+    // query capabilities of each implementation
+    // may be more than one implementation per library
+    sts = QueryLibraryCaps();
+    if (MFX_ERR_NONE != sts)
+        return sts;
+
+    m_bNeedFullQuery        = false;
+    m_bNeedUpdateValidImpls = true;
+
+    return MFX_ERR_NONE;
+}
+
+// creates ordered list of user-specified directories to search
+mfxU32 LoaderCtxVPL::ParseEnvSearchPaths(const CHAR_TYPE *envVarName,
+                                         std::list<STRING_TYPE> &searchDirs) {
+    searchDirs.clear();
+
+#if defined(_WIN32) || defined(_WIN64)
+    DWORD err;
+    m_envVar[0] = 0;
+
+    err = GetEnvironmentVariableW(envVarName, m_envVar, MAX_ENV_VAR_LEN);
+    if (err == 0 || err >= MAX_ENV_VAR_LEN)
+        return 0; // environment variable not defined or string too long
+
+    // parse env variable into individual directories
+    std::wstringstream envPath((CHAR_TYPE *)m_envVar);
+    STRING_TYPE s;
+    while (std::getline(envPath, s, L';')) {
+        searchDirs.push_back(s);
+    }
+#else
+    CHAR_TYPE *envVar = getenv(envVarName);
+    if (!envVar)
+        return 0; // environment variable not defined
+
+    // parse env variable into individual directories
+    std::stringstream envPath((CHAR_TYPE *)envVar);
+    STRING_TYPE s;
+    while (std::getline(envPath, s, ':')) {
+        searchDirs.push_back(s);
+    }
+#endif
+
+    return (mfxU32)searchDirs.size();
+}
+
+#define NUM_LIB_PREFIXES 2
+
+mfxStatus LoaderCtxVPL::SearchDirForLibs(STRING_TYPE searchDir,
+                                         std::list<LibInfo *> &libInfoList,
+                                         mfxU32 priority) {
+    // okay to call with empty searchDir
+    if (searchDir.empty())
+        return MFX_ERR_NONE;
+
+#if defined(_WIN32) || defined(_WIN64)
+    HANDLE hTestFile = nullptr;
+    WIN32_FIND_DATAW testFileData;
+    DWORD err;
+    STRING_TYPE testFileName[NUM_LIB_PREFIXES] = { searchDir + MAKE_STRING("/libvpl*.dll"),
+                                                   searchDir + MAKE_STRING("/libmfx*.dll") };
+
+    CHAR_TYPE currDir[MAX_VPL_SEARCH_PATH] = L"";
+    if (GetCurrentDirectoryW(MAX_VPL_SEARCH_PATH, currDir))
+        SetCurrentDirectoryW(searchDir.c_str());
+
+    // iterate over all candidate files in directory
+    for (mfxU32 i = 0; i < NUM_LIB_PREFIXES; i++) {
+        hTestFile = FindFirstFileW(testFileName[i].c_str(), &testFileData);
+        if (hTestFile != INVALID_HANDLE_VALUE) {
+            do {
+                wchar_t libNameFull[MAX_VPL_SEARCH_PATH];
+                wchar_t *libNameBase;
+
+                // special case: do not include dispatcher itself (libmfx.dll, libvpl.dll)
+                if (wcsstr(testFileData.cFileName, L"libmfx.dll") ||
+                    wcsstr(testFileData.cFileName, L"libvpl.dll") ||
+                    wcsstr(testFileData.cFileName, L"libvpld.dll"))
+                    continue;
+
+                err = GetFullPathNameW(testFileData.cFileName,
+                                       MAX_VPL_SEARCH_PATH,
+                                       libNameFull,
+                                       &libNameBase);
+                // unknown error - skip it and move on to next file
+                if (!err)
+                    continue;
+
+                // skip duplicates
+                auto libFound =
+                    std::find_if(libInfoList.begin(), libInfoList.end(), [&](LibInfo *li) {
+                        return (li->libNameFull == libNameFull);
+                    });
+                if (libFound != libInfoList.end())
+                    continue;
+
+                LibInfo *libInfo = new LibInfo;
+                if (!libInfo)
+                    return MFX_ERR_MEMORY_ALLOC;
+
+                libInfo->libNameFull = libNameFull;
+                libInfo->libPriority = priority;
+
+                // add to list
+                libInfoList.push_back(libInfo);
+            } while (FindNextFileW(hTestFile, &testFileData));
+
+            FindClose(hTestFile);
+        }
+    }
+
+    // restore current directory
+    if (currDir[0])
+        SetCurrentDirectoryW(currDir);
+
+#else
+    DIR *pSearchDir;
+    struct dirent *currFile;
+
+    pSearchDir = opendir(searchDir.c_str());
+    if (pSearchDir) {
+        while (1) {
+            currFile = readdir(pSearchDir);
+            if (!currFile)
+                break;
+
+            // save files with ".so" (including .so.1, etc.)
+            if (strstr(currFile->d_name, ".so")) {
+                // library names must begin with "libvpl*" or "libmfx*"
+                if ((strstr(currFile->d_name, "libvpl") != currFile->d_name) &&
+                    (strstr(currFile->d_name, "libmfx") != currFile->d_name))
+                    continue;
+
+                // special case: do not include dispatcher itself (libmfx.so*, libvpl.so*) or tracer library
+                if (strstr(currFile->d_name, "libmfx.so") ||
+                    strstr(currFile->d_name, "libvpl.so") ||
+                    strstr(currFile->d_name, "libmfx-tracer"))
+                    continue;
+
+                char filePathC[MAX_VPL_SEARCH_PATH];
+
+                // get full path to found library
+                snprintf(filePathC,
+                         MAX_VPL_SEARCH_PATH,
+                         "%s/%s",
+                         searchDir.c_str(),
+                         currFile->d_name);
+                char *fullPath = realpath(filePathC, NULL);
+
+                // unknown error - skip it and move on to next file
+                if (!fullPath)
+                    continue;
+
+                // skip duplicates
+                auto libFound =
+                    std::find_if(libInfoList.begin(), libInfoList.end(), [&](LibInfo *li) {
+                        return (li->libNameFull == fullPath);
+                    });
+                if (libFound != libInfoList.end()) {
+                    free(fullPath);
+                    continue;
+                }
+
+                LibInfo *libInfo = new LibInfo;
+                if (!libInfo)
+                    return MFX_ERR_MEMORY_ALLOC;
+
+                libInfo->libNameFull = fullPath;
+                libInfo->libPriority = priority;
+                free(fullPath);
+
+                // add to list
+                libInfoList.push_back(libInfo);
+            }
+        }
+        closedir(pSearchDir);
+    }
+#endif
+
+    return MFX_ERR_NONE;
+}
+
+// fill in m_gpuAdapterInfo before calling
+mfxU32 LoaderCtxVPL::GetSearchPathsDriverStore(std::list<STRING_TYPE> &searchDirs,
+                                               LibType libType) {
+    searchDirs.clear();
+
+#if defined(_WIN32) || defined(_WIN64)
+    mfxStatus sts = MFX_ERR_UNSUPPORTED;
+    STRING_TYPE vplPath;
+
+    int storageID = MFX::MFX_DRIVER_STORE_ONEVPL;
+    if (libType == LibTypeMSDK)
+        storageID = MFX::MFX_DRIVER_STORE;
+
+    // get path to Windows driver store (if any) for each adapter
+    for (mfxU32 adapterID = 0; adapterID < (mfxU32)m_gpuAdapterInfo.size(); adapterID++) {
+        vplPath.clear();
+        sts = MFX::MFXLibraryIterator::GetDriverStoreDir(vplPath,
+                                                         MAX_VPL_SEARCH_PATH,
+                                                         m_gpuAdapterInfo[adapterID].deviceID,
+                                                         storageID);
+        if (sts == MFX_ERR_NONE)
+            searchDirs.push_back(vplPath);
+    }
+#endif
+
+    return (mfxU32)searchDirs.size();
+}
+
+mfxU32 LoaderCtxVPL::GetSearchPathsCurrentExe(std::list<STRING_TYPE> &searchDirs) {
+    searchDirs.clear();
+
+#if defined(_WIN32) || defined(_WIN64)
+    // get path to location of current executable
+    wchar_t implPath[MFX::msdk_disp_path_len];
+    MFX::GetImplPath(MFX::MFX_APP_FOLDER, implPath);
+    STRING_TYPE exePath = implPath;
+
+    // strip trailing backslash
+    size_t exePathLen = exePath.find_last_of(L"\\");
+    if (exePathLen > 0)
+        exePath.erase(exePathLen);
+
+    if (!exePath.empty())
+        searchDirs.push_back(exePath);
+
+#endif
+
+    return (mfxU32)searchDirs.size();
+}
+
+mfxU32 LoaderCtxVPL::GetSearchPathsCurrentDir(std::list<STRING_TYPE> &searchDirs) {
+    searchDirs.clear();
+
+#if defined(_WIN32) || defined(_WIN64)
+    CHAR_TYPE currDir[MAX_VPL_SEARCH_PATH] = L"";
+    if (GetCurrentDirectoryW(MAX_VPL_SEARCH_PATH, currDir)) {
+        searchDirs.push_back(currDir);
+    }
+#else
+    CHAR_TYPE currDir[MAX_VPL_SEARCH_PATH] = "";
+    if (getcwd(currDir, MAX_VPL_SEARCH_PATH)) {
+        searchDirs.push_back(currDir);
+    }
+#endif
+
+    return (mfxU32)searchDirs.size();
+}
+
+// get legacy MSDK dispatcher search paths
+// see "oneVPL Session" section in spec
+mfxU32 LoaderCtxVPL::GetSearchPathsLegacy(std::list<STRING_TYPE> &searchDirs) {
+    searchDirs.clear();
+
+#if defined(_WIN32) || defined(_WIN64)
+    mfxStatus sts = MFX_ERR_UNSUPPORTED;
+    STRING_TYPE msdkPath;
+
+    // get path via dispatcher regkey - HKCU
+    msdkPath.clear();
+    sts = MFX::MFXLibraryIterator::GetRegkeyDir(msdkPath,
+                                                MAX_VPL_SEARCH_PATH,
+                                                MFX::MFX_CURRENT_USER_KEY);
+    if (sts == MFX_ERR_NONE)
+        searchDirs.push_back(msdkPath);
+
+    // get path via dispatcher regkey - HKLM
+    msdkPath.clear();
+    sts = MFX::MFXLibraryIterator::GetRegkeyDir(msdkPath,
+                                                MAX_VPL_SEARCH_PATH,
+                                                MFX::MFX_LOCAL_MACHINE_KEY);
+    if (sts == MFX_ERR_NONE)
+        searchDirs.push_back(msdkPath);
+
+    // get path to %windir%\system32 and %windir%\syswow64
+    std::list<STRING_TYPE> winSysDir;
+    ParseEnvSearchPaths(L"windir", winSysDir);
+
+    // should resolve to a single directory, otherwise something went wrong
+    if (winSysDir.size() == 1) {
+        msdkPath = winSysDir.front() + L"\\system32";
+        searchDirs.push_back(msdkPath);
+
+        msdkPath = winSysDir.front() + L"\\syswow64";
+        searchDirs.push_back(msdkPath);
+    }
+
+#else
+    // MSDK open-source installation directories
+    searchDirs.push_back("/opt/intel/mediasdk/lib");
+    searchDirs.push_back("/opt/intel/mediasdk/lib64");
+#endif
+
+    return (mfxU32)searchDirs.size();
+}
+
+mfxU32 LoaderCtxVPL::GetSearchPathsSystemDefault(std::list<STRING_TYPE> &searchDirs) {
+    searchDirs.clear();
+
+#ifdef __linux__
+    // Add the standard path for libmfx1 install in Ubuntu
+    searchDirs.push_back("/usr/lib/x86_64-linux-gnu");
+
+    // Add other default paths
+    searchDirs.push_back("/lib");
+    searchDirs.push_back("/usr/lib");
+    searchDirs.push_back("/lib64");
+    searchDirs.push_back("/usr/lib64");
+#endif
+
+    return (mfxU32)searchDirs.size();
+}
+
+// search for implementations of oneAPI Video Processing Library (oneVPL)
+//   according to the rules in the spec
+mfxStatus LoaderCtxVPL::BuildListOfCandidateLibs() {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    STRING_TYPE emptyPath; // default construction = empty
+    std::list<STRING_TYPE> searchDirList;
+    std::list<STRING_TYPE>::iterator it;
+
+    // special case: ONEVPL_PRIORITY_PATH may be used to specify user-defined path
+    //   and bypass priority sorting (API >= 2.6)
+    searchDirList.clear();
+    ParseEnvSearchPaths(ONEVPL_PRIORITY_PATH_VAR, searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_SPECIAL);
+        it++;
+    }
+
+    if (searchDirList.size() > 0)
+        m_bPriorityPathEnabled = true;
+
+#if defined(_WIN32) || defined(_WIN64)
+    // retrieve list of DX11 graphics adapters (lightweight)
+    // used for both VPL and legacy driver store search
+    m_gpuAdapterInfo.clear();
+    bool bEnumSuccess = MFX::DXGI1Device::GetAdapterList(m_gpuAdapterInfo);
+
+    // unknown error or no adapters found - clear list
+    if (!bEnumSuccess)
+        m_gpuAdapterInfo.clear();
+
+    // first priority: Windows driver store
+    searchDirList.clear();
+    GetSearchPathsDriverStore(searchDirList, LibTypeVPL);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_01);
+        it++;
+    }
+
+    // second priority: path to current executable
+    searchDirList.clear();
+    GetSearchPathsCurrentExe(searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_02);
+        it++;
+    }
+
+    // third priority: current working directory
+    searchDirList.clear();
+    GetSearchPathsCurrentDir(searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_03);
+        it++;
+    }
+
+    // fourth priority: PATH environment variable
+    searchDirList.clear();
+    ParseEnvSearchPaths(L"PATH", searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_04);
+        it++;
+    }
+
+    // fifth priority: ONEVPL_SEARCH_PATH environment variable
+    searchDirList.clear();
+    ParseEnvSearchPaths(L"ONEVPL_SEARCH_PATH", searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_05);
+        it++;
+    }
+
+    // legacy MSDK installation: DriverStore has priority
+    searchDirList.clear();
+    GetSearchPathsDriverStore(searchDirList, LibTypeMSDK);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_LEGACY_DRIVERSTORE);
+        it++;
+    }
+
+    // lowest priority: other legacy search paths
+    searchDirList.clear();
+    GetSearchPathsLegacy(searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_LEGACY);
+        it++;
+    }
+#else
+    // first priority: LD_LIBRARY_PATH environment variable
+    searchDirList.clear();
+    ParseEnvSearchPaths("LD_LIBRARY_PATH", searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_01);
+        it++;
+    }
+
+    // second priority: Linux default paths
+    searchDirList.clear();
+    GetSearchPathsSystemDefault(searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_03);
+        it++;
+    }
+
+    // third priority: current working directory
+    searchDirList.clear();
+    GetSearchPathsCurrentDir(searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_04);
+        it++;
+    }
+
+    // fourth priority: ONEVPL_SEARCH_PATH environment variable
+    searchDirList.clear();
+    ParseEnvSearchPaths("ONEVPL_SEARCH_PATH", searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_05);
+        it++;
+    }
+
+    // lowest priority: legacy MSDK installation
+    searchDirList.clear();
+    GetSearchPathsLegacy(searchDirList);
+    it = searchDirList.begin();
+    while (it != searchDirList.end()) {
+        STRING_TYPE nextDir = (*it);
+        sts                 = SearchDirForLibs(nextDir, m_libInfoList, LIB_PRIORITY_LEGACY);
+        it++;
+    }
+#endif
+
+    return sts;
+}
+
+// return number of valid libraries found
+mfxU32 LoaderCtxVPL::CheckValidLibraries() {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    LibInfo *msdkLibBest   = nullptr;
+    LibInfo *msdkLibBestDS = nullptr;
+
+    // load all libraries
+    std::list<LibInfo *>::iterator it = m_libInfoList.begin();
+    while (it != m_libInfoList.end()) {
+        LibInfo *libInfo = (*it);
+        mfxStatus sts    = MFX_ERR_NONE;
+
+        // load DLL
+        sts = LoadSingleLibrary(libInfo);
+
+        // load video functions: pointers to exposed functions
+        // not all function pointers may be filled in (depends on API version)
+        if (sts == MFX_ERR_NONE && libInfo->hModuleVPL)
+            LoadAPIExports(libInfo, LibTypeVPL);
+
+        // all runtime libraries with API >= 2.0 must export MFXInitialize()
+        // validation of additional functions vs. API version takes place
+        //   during UpdateValidImplList() since the minimum API version requested
+        //   by application is not known yet (use SetConfigFilterProperty)
+        if (libInfo->vplFuncTable[IdxMFXInitialize] &&
+            libInfo->libPriority < LIB_PRIORITY_LEGACY_DRIVERSTORE) {
+            libInfo->libType = LibTypeVPL;
+            it++;
+            continue;
+        }
+
+        // not a valid 2.x runtime - check for 1.x API (legacy caps query)
+        mfxU32 numFunctions = 0;
+        if (sts == MFX_ERR_NONE && libInfo->hModuleVPL) {
+            if (libInfo->libNameFull.find(MSDK_LIB_NAME) != std::string::npos) {
+                // legacy runtime must be named libmfxhw64 (or 32)
+                // MSDK must export all of the required functions
+                numFunctions = LoadAPIExports(libInfo, LibTypeMSDK);
+            }
+        }
+
+        // check if all of the required MSDK functions were found
+        //   and this is valid library (can create session, query version)
+        if (numFunctions == NumMSDKFunctions) {
+            sts = LoaderCtxMSDK::QueryAPIVersion(libInfo->libNameFull, &(libInfo->msdkVersion));
+
+            if (sts == MFX_ERR_NONE) {
+                libInfo->libType = LibTypeMSDK;
+                if (msdkLibBest == nullptr ||
+                    (libInfo->msdkVersion.Version > msdkLibBest->msdkVersion.Version)) {
+                    msdkLibBest = libInfo;
+                }
+
+                if (libInfo->libPriority == LIB_PRIORITY_LEGACY_DRIVERSTORE) {
+                    if (msdkLibBestDS == nullptr ||
+                        (libInfo->msdkVersion.Version > msdkLibBestDS->msdkVersion.Version)) {
+                        msdkLibBestDS = libInfo;
+                    }
+                }
+
+#if defined(_WIN32) || defined(_WIN64)
+                // workaround for double-init issue in old versions of MSDK runtime
+                //   (allow DLL to be fully unloaded after each call to MFXClose)
+                // apply to MSDK with API version <= 1.27
+                if (libInfo->hModuleVPL && (libInfo->msdkVersion.Major == 1) &&
+                    (libInfo->msdkVersion.Minor <= 27)) {
+                    MFX::mfx_dll_free(libInfo->hModuleVPL);
+                    libInfo->hModuleVPL = nullptr;
+                }
+#endif
+
+                it++;
+                continue;
+            }
+        }
+
+        // required functions missing from DLL, or DLL failed to load
+        // remove this library from the list of options
+        UnloadSingleLibrary(libInfo);
+        it = m_libInfoList.erase(it);
+    }
+
+    if (msdkLibBestDS)
+        msdkLibBest = msdkLibBestDS;
+
+    // prune duplicate MSDK libraries (only keep one with highest API version)
+    it = m_libInfoList.begin();
+    while (it != m_libInfoList.end()) {
+        LibInfo *libInfo = (*it);
+
+        if (libInfo->libType == LibTypeMSDK && libInfo != msdkLibBest) {
+            UnloadSingleLibrary(libInfo);
+            it = m_libInfoList.erase(it);
+        }
+        else {
+            it++;
+        }
+    }
+
+    // number of valid oneVPL libs
+    return (mfxU32)m_libInfoList.size();
+}
+
+VPLFunctionPtr LoaderCtxVPL::GetFunctionAddr(void *hModuleVPL, const char *pName) {
+    VPLFunctionPtr pProc = nullptr;
+
+    if (hModuleVPL) {
+#if defined(_WIN32) || defined(_WIN64)
+        pProc = (VPLFunctionPtr)MFX::mfx_dll_get_addr(hModuleVPL, pName);
+#else
+        pProc = (VPLFunctionPtr)dlsym(hModuleVPL, pName);
+#endif
+    }
+
+    return pProc;
+}
+
+// load single runtime
+mfxStatus LoaderCtxVPL::LoadSingleLibrary(LibInfo *libInfo) {
+    if (!libInfo)
+        return MFX_ERR_NULL_PTR;
+
+#if defined(_WIN32) || defined(_WIN64)
+    libInfo->hModuleVPL = MFX::mfx_dll_load(libInfo->libNameFull.c_str());
+#else
+    libInfo->hModuleVPL = dlopen(libInfo->libNameFull.c_str(), RTLD_LOCAL | RTLD_NOW);
+#endif
+
+    if (!libInfo->hModuleVPL)
+        return MFX_ERR_NOT_FOUND;
+
+    return MFX_ERR_NONE;
+}
+
+// unload single runtime
+mfxStatus LoaderCtxVPL::UnloadSingleLibrary(LibInfo *libInfo) {
+    if (libInfo) {
+        if (libInfo->hModuleVPL) {
+#if defined(_WIN32) || defined(_WIN64)
+            MFX::mfx_dll_free(libInfo->hModuleVPL);
+#else
+            dlclose(libInfo->hModuleVPL);
+#endif
+        }
+        delete libInfo;
+        return MFX_ERR_NONE;
+    }
+    else {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+}
+
+// iterate over all implementation runtimes
+// unload DLL's and free memory
+mfxStatus LoaderCtxVPL::UnloadAllLibraries() {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    std::list<ImplInfo *>::iterator it2 = m_implInfoList.begin();
+    while (it2 != m_implInfoList.end()) {
+        ImplInfo *implInfo = (*it2);
+
+        if (implInfo) {
+            UnloadSingleImplementation(implInfo);
+        }
+        it2++;
+    }
+
+    // lastly, unload and destroy LibInfo for each library
+    std::list<LibInfo *>::iterator it = m_libInfoList.begin();
+    while (it != m_libInfoList.end()) {
+        LibInfo *libInfo = (*it);
+
+        if (libInfo) {
+            UnloadSingleLibrary(libInfo);
+        }
+        it++;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+// unload single implementation
+// each runtime library may contain 1 or more implementations
+mfxStatus LoaderCtxVPL::UnloadSingleImplementation(ImplInfo *implInfo) {
+    if (implInfo && implInfo->libInfo) {
+        LibInfo *libInfo     = implInfo->libInfo;
+        VPLFunctionPtr pFunc = libInfo->vplFuncTable[IdxMFXReleaseImplDescription];
+
+        // call MFXReleaseImplDescription() for this implementation if it
+        //   was never called by the application
+        // this is a valid scenario, e.g. app did not call MFXEnumImplementations()
+        //   and just used the first available implementation provided by dispatcher
+        if (libInfo->libType == LibTypeVPL) {
+            if (implInfo->implDesc) {
+                // MFX_IMPLCAPS_IMPLDESCSTRUCTURE;
+                (*(mfxStatus(MFX_CDECL *)(mfxHDL))pFunc)(implInfo->implDesc);
+                implInfo->implDesc = nullptr;
+            }
+
+            if (implInfo->implFuncs) {
+                // MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS;
+                (*(mfxStatus(MFX_CDECL *)(mfxHDL))pFunc)(implInfo->implFuncs);
+                implInfo->implFuncs = nullptr;
+            }
+#ifdef ONEVPL_EXPERIMENTAL
+            if (implInfo->implExtDeviceID) {
+                // MFX_IMPLCAPS_DEVICE_ID_EXTENDED;
+                (*(mfxStatus(MFX_CDECL *)(mfxHDL))pFunc)(implInfo->implExtDeviceID);
+                implInfo->implExtDeviceID = nullptr;
+            }
+#endif
+
+            // nothing to do if (capsFormat == MFX_IMPLCAPS_IMPLPATH) since no new memory was allocated
+        }
+        delete implInfo;
+        return MFX_ERR_NONE;
+    }
+    else {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+}
+
+// return number of functions loaded
+mfxU32 LoaderCtxVPL::LoadAPIExports(LibInfo *libInfo, LibType libType) {
+    mfxU32 i, numFunctions = 0;
+
+    if (libType == LibTypeVPL) {
+        for (i = 0; i < NumVPLFunctions; i += 1) {
+            VPLFunctionPtr pProc =
+                (VPLFunctionPtr)GetFunctionAddr(libInfo->hModuleVPL, FunctionDesc2[i].pName);
+            if (pProc) {
+                libInfo->vplFuncTable[i] = pProc;
+                numFunctions++;
+            }
+        }
+    }
+    else if (libType == LibTypeMSDK) {
+        // don't actually need to save the function pointers for MSDK, just check if they are defined
+        for (i = 0; i < NumMSDKFunctions; i += 1) {
+            VPLFunctionPtr pProc =
+                (VPLFunctionPtr)GetFunctionAddr(libInfo->hModuleVPL, MSDKCompatFunctions[i].pName);
+            if (pProc) {
+                numFunctions++;
+            }
+        }
+    }
+
+    return numFunctions;
+}
+
+// check that all functions for this API version are available in library
+mfxStatus LoaderCtxVPL::ValidateAPIExports(VPLFunctionPtr *vplFuncTable,
+                                           mfxVersion reportedVersion) {
+    for (mfxU32 i = 0; i < NumVPLFunctions; i += 1) {
+        if (!vplFuncTable[i] && (FunctionDesc2[i].apiVersion.Version <= reportedVersion.Version))
+            return MFX_ERR_UNSUPPORTED;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+// convert full path into char* for MFX_IMPLCAPS_IMPLPATH query
+mfxStatus LoaderCtxVPL::UpdateImplPath(LibInfo *libInfo) {
+#if defined(_WIN32) || defined(_WIN64)
+    // Windows - strings are 16-bit
+    size_t nCvt = 0;
+    if (wcstombs_s(&nCvt,
+                   libInfo->implCapsPath,
+                   sizeof(libInfo->implCapsPath),
+                   libInfo->libNameFull.c_str(),
+                   _TRUNCATE)) {
+        // unknown error - set to empty string
+        libInfo->implCapsPath[0] = 0;
+        return MFX_ERR_UNSUPPORTED;
+    }
+#else
+    // Linux - strings are 8-bit
+    strncpy(libInfo->implCapsPath, libInfo->libNameFull.c_str(), sizeof(libInfo->implCapsPath) - 1);
+#endif
+
+    return MFX_ERR_NONE;
+}
+
+bool LoaderCtxVPL::IsValidX86GPU(ImplInfo *implInfo, mfxU32 &deviceID, mfxU32 &adapterIdx) {
+    mfxImplDescription *implDesc = (mfxImplDescription *)(implInfo->implDesc);
+
+    // may be null in low-latency mode, ID unknown
+    if (!implDesc)
+        return false;
+
+    if (implInfo->validImplIdx >= 0 && implDesc->VendorID == 0x8086 &&
+        implDesc->Impl == MFX_IMPL_TYPE_HARDWARE) {
+        // verify that DeviceID is a valid format for x86 GPU
+        // either "DeviceID" (hex) or "DeviceID/AdapterIdx" (hex/dec)
+        return ConfigCtxVPL::ParseDeviceIDx86(implDesc->Dev.DeviceID, deviceID, adapterIdx);
+    }
+
+    return false;
+}
+
+// query capabilities of all valid libraries
+//   and add to list for future calls to EnumImplementations()
+//   as well as filtering by functionality
+// assume MFX_IMPLCAPS_IMPLDESCSTRUCTURE is the only format supported
+mfxStatus LoaderCtxVPL::QueryLibraryCaps() {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    std::list<LibInfo *>::iterator it = m_libInfoList.begin();
+    while (it != m_libInfoList.end()) {
+        LibInfo *libInfo = (*it);
+
+        if (libInfo->libType == LibTypeVPL) {
+            VPLFunctionPtr pFunc = libInfo->vplFuncTable[IdxMFXQueryImplsDescription];
+
+            // handle to implDesc structure, null in low-latency mode (no query)
+            mfxHDL *hImpl   = nullptr;
+            mfxU32 numImpls = 0;
+
+#ifdef ONEVPL_EXPERIMENTAL
+            mfxHDL *hImplExtDeviceID   = nullptr;
+            mfxU32 numImplsExtDeviceID = 0;
+#endif
+
+            if (m_bLowLatency == false) {
+                // call MFXQueryImplsDescription() for this implementation
+                // return handle to description in requested format
+                hImpl = (*(mfxHDL * (MFX_CDECL *)(mfxImplCapsDeliveryFormat, mfxU32 *))
+                             pFunc)(MFX_IMPLCAPS_IMPLDESCSTRUCTURE, &numImpls);
+
+                // validate description pointer for each implementation
+                bool b_isValidDesc = true;
+                if (!hImpl) {
+                    b_isValidDesc = false;
+                }
+                else {
+                    for (mfxU32 i = 0; i < numImpls; i++) {
+                        if (!hImpl[i]) {
+                            b_isValidDesc = false;
+                            break;
+                        }
+                    }
+                }
+
+                if (!b_isValidDesc) {
+                    // the required function is implemented incorrectly
+                    // remove this library from the list of valid libraries
+                    UnloadSingleLibrary(libInfo);
+                    it = m_libInfoList.erase(it);
+                    continue;
+                }
+
+#ifdef ONEVPL_EXPERIMENTAL
+                hImplExtDeviceID =
+                    (*(mfxHDL * (MFX_CDECL *)(mfxImplCapsDeliveryFormat, mfxU32 *))
+                         pFunc)(MFX_IMPLCAPS_DEVICE_ID_EXTENDED, &numImplsExtDeviceID);
+#endif
+            }
+
+            // query for list of implemented functions
+            // prior to API 2.2, this will return null since the format was not defined yet
+            //   so we need to check whether the returned handle is valid before attempting to use it
+            mfxHDL *hImplFuncs   = nullptr;
+            mfxU32 numImplsFuncs = 0;
+            hImplFuncs           = (*(mfxHDL * (MFX_CDECL *)(mfxImplCapsDeliveryFormat, mfxU32 *))
+                              pFunc)(MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS, &numImplsFuncs);
+
+            // only report single impl, but application may still attempt to create session using
+            //    any of VendorImplID via the DXGIAdapterIndex filter property
+            if (m_bLowLatency == true)
+                numImpls = 1;
+
+            // save user-friendly path for MFX_IMPLCAPS_IMPLPATH query (API >= 2.4)
+            UpdateImplPath(libInfo);
+
+            for (mfxU32 i = 0; i < numImpls; i++) {
+                ImplInfo *implInfo = new ImplInfo;
+                if (!implInfo)
+                    return MFX_ERR_MEMORY_ALLOC;
+
+                // library which contains this implementation
+                implInfo->libInfo = libInfo;
+
+#ifdef ONEVPL_EXPERIMENTAL
+                if (hImplExtDeviceID && i < numImplsExtDeviceID)
+                    implInfo->implExtDeviceID = hImplExtDeviceID[i];
+#endif
+
+                // implemented function description, if available
+                if (hImplFuncs && i < numImplsFuncs)
+                    implInfo->implFuncs = hImplFuncs[i];
+
+                // fill out mfxInitializationParam for use in CreateSession (MFXInitialize path)
+                memset(&(implInfo->vplParam), 0, sizeof(mfxInitializationParam));
+
+                if (m_bLowLatency == false) {
+                    // implementation descriptor returned from runtime
+                    implInfo->implDesc = hImpl[i];
+
+                    // fill out mfxInitParam struct for when we call MFXInitEx
+                    //   in CreateSession()
+                    mfxImplDescription *implDesc = reinterpret_cast<mfxImplDescription *>(hImpl[i]);
+
+                    // default mode for this impl
+                    // this may be changed later by MFXSetConfigFilterProperty(AccelerationMode)
+                    implInfo->vplParam.AccelerationMode = implDesc->AccelerationMode;
+
+                    implInfo->version = implDesc->ApiVersion;
+                }
+                else {
+                    implInfo->implDesc = nullptr;
+
+                    // application must set requested mode using MFXSetConfigFilterProperty()
+                    // will be updated during CreateSession
+                    implInfo->vplParam.AccelerationMode = MFX_ACCEL_MODE_NA;
+
+                    mfxVersion queryVersion = {};
+
+                    // create test session to get API version
+                    sts = QuerySessionLowLatency(libInfo, i, &queryVersion);
+                    if (sts != MFX_ERR_NONE) {
+                        UnloadSingleImplementation(implInfo);
+                        continue;
+                    }
+                    implInfo->version.Version = queryVersion.Version;
+                }
+
+                // save local index for this library
+                implInfo->libImplIdx = i;
+
+                // validate that library exports all required functions for the reported API version
+                if (ValidateAPIExports(libInfo->vplFuncTable, implInfo->version)) {
+                    UnloadSingleImplementation(implInfo);
+                    continue;
+                }
+
+                // initially all libraries have a valid, sequential value (>= 0)
+                // list of valid libraries is updated with every call to MFXSetConfigFilterProperty()
+                //   (see UpdateValidImplList)
+                // libraries that do not support all the required props get a value of -1, and
+                //   indexing of the valid libs is recalculated from 0,1,...
+                implInfo->validImplIdx = m_implIdxNext++;
+
+                // add implementation to overall list
+                m_implInfoList.push_back(implInfo);
+            }
+        }
+        else if (libInfo->libType == LibTypeMSDK) {
+            // save user-friendly path for MFX_IMPLCAPS_IMPLPATH query (API >= 2.4)
+            UpdateImplPath(libInfo);
+
+            mfxU32 maxImplMSDK = MAX_NUM_IMPL_MSDK;
+
+            // call once on adapter 0 to get MSDK API version (same for any adapter)
+            mfxVersion queryVersion = {};
+            if (m_bLowLatency) {
+                sts = LoaderCtxMSDK::QueryAPIVersion(libInfo->libNameFull, &queryVersion);
+                if (sts != MFX_ERR_NONE)
+                    queryVersion.Version = 0;
+
+                // only report single impl, but application may still attempt to create session using
+                //    any of MFX_IMPL_HARDWAREx via the DXGIAdapterIndex filter property
+                maxImplMSDK = 1;
+            }
+
+            mfxU32 numImplMSDK = 0;
+            for (mfxU32 i = 0; i < maxImplMSDK; i++) {
+                mfxImplDescription *implDesc       = nullptr;
+                mfxImplementedFunctions *implFuncs = nullptr;
+
+                LoaderCtxMSDK *msdkCtx = &(libInfo->msdkCtx[i]);
+                if (m_bLowLatency == false) {
+                    // perf. optimization: if app requested bIsSet_accelerationMode other than D3D9, don't test whether MSDK supports D3D9
+                    bool bSkipD3D9Check = false;
+                    if (m_specialConfig.bIsSet_accelerationMode &&
+                        m_specialConfig.accelerationMode != MFX_ACCEL_MODE_VIA_D3D9) {
+                        bSkipD3D9Check = true;
+                    }
+
+                    sts = msdkCtx->QueryMSDKCaps(libInfo->libNameFull,
+                                                 &implDesc,
+                                                 &implFuncs,
+                                                 i,
+                                                 bSkipD3D9Check);
+
+                    if (sts || !implDesc || !implFuncs) {
+                        // this adapter (i) is not supported
+                        continue;
+                    }
+                }
+                else {
+                    // unknown API - unable to create session on any adapter
+                    if (queryVersion.Version == 0)
+                        continue;
+
+                    // these are the only values filled in for msdkCtx in low latency mode
+                    // used during CreateSession
+                    msdkCtx->m_msdkAdapter     = msdkImplTab[i];
+                    msdkCtx->m_msdkAdapterD3D9 = msdkImplTab[i];
+                }
+
+                ImplInfo *implInfo = new ImplInfo;
+                if (!implInfo)
+                    return MFX_ERR_MEMORY_ALLOC;
+
+                // library which contains this implementation
+                implInfo->libInfo = libInfo;
+
+                // implemented function description, if available
+                implInfo->implFuncs = implFuncs;
+
+                // fill out mfxInitializationParam for use in CreateSession (MFXInitialize path)
+                memset(&(implInfo->vplParam), 0, sizeof(mfxInitializationParam));
+
+                if (m_bLowLatency == false) {
+                    // implementation descriptor returned from runtime
+                    implInfo->implDesc = implDesc;
+
+                    // default mode for this impl
+                    // this may be changed later by MFXSetConfigFilterProperty(AccelerationMode)
+                    implInfo->vplParam.AccelerationMode = implDesc->AccelerationMode;
+
+                    implInfo->version = implDesc->ApiVersion;
+                }
+                else {
+                    implInfo->implDesc = nullptr;
+
+                    // application must set requested mode using MFXSetConfigFilterProperty()
+                    // will be updated during CreateSession
+                    implInfo->vplParam.AccelerationMode = MFX_ACCEL_MODE_NA;
+
+                    // save API version from creating test MSDK session above
+                    implInfo->version.Version = queryVersion.Version;
+                }
+
+                // adapter number
+                implInfo->msdkImplIdx = i;
+
+                // save local index for this library
+                implInfo->libImplIdx = 0;
+
+                // initially all libraries have a valid, sequential value (>= 0)
+                // list of valid libraries is updated with every call to MFXSetConfigFilterProperty()
+                //   (see UpdateValidImplList)
+                // libraries that do not support all the required props get a value of -1, and
+                //   indexing of the valid libs is recalculated from 0,1,...
+                implInfo->validImplIdx = m_implIdxNext++;
+
+                // add implementation to overall list
+                m_implInfoList.push_back(implInfo);
+
+                // update number of valid MSDK adapters
+                numImplMSDK++;
+
+#ifdef __linux__
+                // currently only one adapter on Linux (avoid multiple copies)
+                break;
+#endif
+            }
+
+            if (numImplMSDK == 0) {
+                // error loading MSDK library in compatibility mode - remove from list
+                UnloadSingleLibrary(libInfo);
+                it = m_libInfoList.erase(it);
+                continue;
+            }
+        }
+        it++;
+    }
+
+    if (m_bLowLatency == false && !m_implInfoList.empty()) {
+        std::list<ImplInfo *>::iterator it2 = m_implInfoList.begin();
+        while (it2 != m_implInfoList.end()) {
+            ImplInfo *implInfo = (*it2);
+
+            mfxU32 deviceID   = 0;
+            mfxU32 adapterIdx = 0;
+            if (IsValidX86GPU(implInfo, deviceID, adapterIdx)) {
+                // save the adapterIdx for any x86 GPU devices (may be used later for filtering)
+                implInfo->adapterIdx = adapterIdx;
+            }
+
+            // per spec: if both VPL (HW) and MSDK are installed on the same system, only load
+            //   the VPL library (mark MSDK as invalid)
+            if (implInfo->libInfo->libType == LibTypeMSDK) {
+                auto vplIdx = std::find_if(
+                    m_implInfoList.begin(),
+                    m_implInfoList.end(),
+
+                    [](const ImplInfo *t) {
+                        mfxImplDescription *implDesc = (mfxImplDescription *)(t->implDesc);
+
+                        return (t->libInfo->libType == LibTypeVPL && implDesc != nullptr &&
+                                implDesc->Impl == MFX_IMPL_TYPE_HARDWARE);
+                    });
+
+                if (vplIdx != m_implInfoList.end())
+                    implInfo->validImplIdx = -1;
+            }
+
+            if (implInfo->libInfo->libType == LibTypeVPL && !implInfo->implDesc) {
+                //library was loaded in low-delay mode, need to query caps for it
+                mfxU32 numImpls      = 0;
+                VPLFunctionPtr pFunc = implInfo->libInfo->vplFuncTable[IdxMFXQueryImplsDescription];
+                mfxHDL *hImpl = (*(mfxHDL * (MFX_CDECL *)(mfxImplCapsDeliveryFormat, mfxU32 *))
+                                     pFunc)(MFX_IMPLCAPS_IMPLDESCSTRUCTURE, &numImpls);
+
+                //only single impl was reported
+                implInfo->implDesc = reinterpret_cast<mfxImplDescription *>(hImpl[0]);
+            }
+            else if (implInfo->libInfo->libType == LibTypeMSDK && !implInfo->implDesc) {
+                mfxImplDescription *implDesc       = nullptr;
+                mfxImplementedFunctions *implFuncs = nullptr;
+
+                LoaderCtxMSDK *msdkCtx = &(implInfo->libInfo->msdkCtx[0]);
+
+                // perf. optimization: if app requested bIsSet_accelerationMode other than D3D9, don't test whether MSDK supports D3D9
+                bool bSkipD3D9Check = false;
+                if (m_specialConfig.bIsSet_accelerationMode &&
+                    m_specialConfig.accelerationMode != MFX_ACCEL_MODE_VIA_D3D9) {
+                    bSkipD3D9Check = true;
+                }
+
+                sts = msdkCtx->QueryMSDKCaps(implInfo->libInfo->libNameFull,
+                                             &implDesc,
+                                             &implFuncs,
+                                             0,
+                                             bSkipD3D9Check);
+
+                if (sts || !implDesc || !implFuncs) {
+                    // this adapter (i) is not supported
+                    continue;
+                }
+                implInfo->implDesc  = implDesc;
+                implInfo->implFuncs = implFuncs;
+            }
+
+            it2++;
+        }
+
+        // sort valid implementations according to priority rules in spec
+        PrioritizeImplList();
+    }
+
+    return m_implInfoList.empty() ? MFX_ERR_UNSUPPORTED : MFX_ERR_NONE;
+}
+
+// query implementation i
+mfxStatus LoaderCtxVPL::QueryImpl(mfxU32 idx, mfxImplCapsDeliveryFormat format, mfxHDL *idesc) {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    *idesc = nullptr;
+
+    std::list<ImplInfo *>::iterator it = m_implInfoList.begin();
+    while (it != m_implInfoList.end()) {
+        ImplInfo *implInfo = (*it);
+        if (implInfo->validImplIdx == (mfxI32)idx) {
+            if (format == MFX_IMPLCAPS_IMPLDESCSTRUCTURE) {
+                *idesc = implInfo->implDesc;
+            }
+            else if (format == MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS) {
+                *idesc = implInfo->implFuncs;
+            }
+            else if (format == MFX_IMPLCAPS_IMPLPATH) {
+                *idesc = implInfo->libInfo->implCapsPath;
+            }
+#ifdef ONEVPL_EXPERIMENTAL
+            else if (format == MFX_IMPLCAPS_DEVICE_ID_EXTENDED) {
+                *idesc = implInfo->implExtDeviceID;
+            }
+#endif
+
+            // implementation found, but requested query format is not supported
+            if (*idesc == nullptr)
+                return MFX_ERR_UNSUPPORTED;
+
+            return MFX_ERR_NONE;
+        }
+        it++;
+    }
+
+    // invalid idx
+    return MFX_ERR_NOT_FOUND;
+}
+
+mfxStatus LoaderCtxVPL::ReleaseImpl(mfxHDL idesc) {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    if (idesc == nullptr)
+        return MFX_ERR_NULL_PTR;
+
+    // all we get from the application is a handle to the descriptor,
+    //   not the implementation associated with it, so we search
+    //   through the full list until we find a match
+    std::list<ImplInfo *>::iterator it = m_implInfoList.begin();
+    while (it != m_implInfoList.end()) {
+        ImplInfo *implInfo                   = (*it);
+        mfxImplCapsDeliveryFormat capsFormat = (mfxImplCapsDeliveryFormat)0; // unknown format
+
+        // in low latency mode implDesc will be empty
+        if (implInfo->implDesc == nullptr)
+            continue;
+
+        // determine type of descriptor so we know which handle to
+        //   invalidate in the Loader context
+        if (implInfo->implDesc == idesc) {
+            capsFormat = MFX_IMPLCAPS_IMPLDESCSTRUCTURE;
+        }
+        else if (implInfo->implFuncs == idesc) {
+            capsFormat = MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS;
+        }
+        else if (implInfo->libInfo->implCapsPath == idesc) {
+            capsFormat = MFX_IMPLCAPS_IMPLPATH;
+        }
+#ifdef ONEVPL_EXPERIMENTAL
+        else if (implInfo->implExtDeviceID == idesc) {
+            capsFormat = MFX_IMPLCAPS_DEVICE_ID_EXTENDED;
+        }
+#endif
+        else {
+            // no match - try next implementation
+            it++;
+            continue;
+        }
+
+        // if true, do not actually call ReleaseImplDescription() until
+        //   MFXUnload() --> UnloadAllLibraries()
+        // this permits the application to call Enum/CreateSession/DispRelease multiple
+        //   times on the same implementation
+        if (m_bKeepCapsUntilUnload)
+            return MFX_ERR_NONE;
+
+        // LibTypeMSDK does not require calling a release function
+        if (implInfo->libInfo->libType == LibTypeVPL) {
+            // call MFXReleaseImplDescription() for this implementation
+            VPLFunctionPtr pFunc = implInfo->libInfo->vplFuncTable[IdxMFXReleaseImplDescription];
+
+            if (capsFormat == MFX_IMPLCAPS_IMPLDESCSTRUCTURE) {
+                sts                = (*(mfxStatus(MFX_CDECL *)(mfxHDL))pFunc)(implInfo->implDesc);
+                implInfo->implDesc = nullptr;
+            }
+            else if (capsFormat == MFX_IMPLCAPS_IMPLEMENTEDFUNCTIONS) {
+                sts                 = (*(mfxStatus(MFX_CDECL *)(mfxHDL))pFunc)(implInfo->implFuncs);
+                implInfo->implFuncs = nullptr;
+            }
+#ifdef ONEVPL_EXPERIMENTAL
+            else if (capsFormat == MFX_IMPLCAPS_DEVICE_ID_EXTENDED) {
+                sts = (*(mfxStatus(MFX_CDECL *)(mfxHDL))pFunc)(implInfo->implExtDeviceID);
+                implInfo->implExtDeviceID = nullptr;
+            }
+#endif
+
+            // nothing to do if (capsFormat == MFX_IMPLCAPS_IMPLPATH) since no new memory was allocated
+        }
+
+        return sts;
+    }
+
+    // did not find a matching handle - should not happen
+    return MFX_ERR_INVALID_HANDLE;
+}
+
+mfxStatus LoaderCtxVPL::UpdateLowLatency() {
+    m_bLowLatency = false;
+
+#if defined(_WIN32) || defined(_WIN64)
+    // only supported on Windows currently
+    m_bLowLatency = ConfigCtxVPL::CheckLowLatencyConfig(m_configCtxList, &m_specialConfig);
+#endif
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus LoaderCtxVPL::UpdateValidImplList(void) {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    mfxI32 validImplIdx = 0;
+
+    // iterate over all libraries and update list of those that
+    //   meet current current set of config props
+    std::list<ImplInfo *>::iterator it = m_implInfoList.begin();
+    while (it != m_implInfoList.end()) {
+        ImplInfo *implInfo = (*it);
+
+        // already invalidated by previous filter
+        if (implInfo->validImplIdx == -1) {
+            it++;
+            continue;
+        }
+
+        // compare caps from this library vs. config filters
+        sts = ConfigCtxVPL::ValidateConfig((mfxImplDescription *)implInfo->implDesc,
+                                           (mfxImplementedFunctions *)implInfo->implFuncs,
+                                           m_configCtxList,
+                                           implInfo->libInfo->libType,
+                                           &m_specialConfig);
+
+        // check special filter properties which are not part of mfxImplDescription
+        if (m_specialConfig.bIsSet_dxgiAdapterIdx &&
+            (m_specialConfig.dxgiAdapterIdx != implInfo->adapterIdx)) {
+            sts = MFX_ERR_UNSUPPORTED;
+        }
+
+        if (sts == MFX_ERR_NONE) {
+            // library supports all required properties
+            implInfo->validImplIdx = validImplIdx++;
+        }
+        else {
+            // library does not support required props, do not include in list for
+            //   MFXEnumImplementations() or MFXCreateSession()
+            implInfo->validImplIdx = -1;
+        }
+
+        it++;
+    }
+
+    // re-sort valid implementations according to priority rules in spec
+    PrioritizeImplList();
+
+    m_bNeedUpdateValidImpls = false;
+
+    return MFX_ERR_NONE;
+}
+
+// From specification section "oneVPL Session":
+//
+// When the dispatcher searches for the implementation, it uses the following priority rules
+//  1) Hardware implementation has priority over software implementation.
+//  2) General hardware implementation has priority over VSI hardware implementation.
+//  3) Highest API version has higher priority over lower API version.
+//  4) Search path priority: lower values = higher priority
+mfxStatus LoaderCtxVPL::PrioritizeImplList(void) {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    // API 2.6 introduced special search location ONEVPL_PRIORITY_PATH
+    // Libs here always have highest priority = LIB_PRIORITY_SPECIAL
+    //   and are not sorted by the other priority rules,
+    //   so we move them to a temporary list before priority sorting and
+    //   then add back to the full implementation list at the end.
+    std::list<ImplInfo *> implInfoListPriority;
+    if (m_bPriorityPathEnabled) {
+        auto it = m_implInfoList.begin();
+        while (it != m_implInfoList.end()) {
+            ImplInfo *implInfo = (*it);
+
+            auto it2 = std::next(it, 1);
+            if (implInfo->libInfo->libPriority == LIB_PRIORITY_SPECIAL)
+                implInfoListPriority.splice(implInfoListPriority.end(), m_implInfoList, it);
+
+            it = it2;
+        }
+    }
+
+    // stable sort - work from lowest to highest priority conditions
+
+    // 4 - sort by search path priority
+    m_implInfoList.sort([](const ImplInfo *impl1, const ImplInfo *impl2) {
+        // prioritize lowest value for libPriority (1 = highest priority)
+        return (impl1->libInfo->libPriority < impl2->libInfo->libPriority);
+    });
+
+    // 3 - sort by API version
+    m_implInfoList.sort([](const ImplInfo *impl1, const ImplInfo *impl2) {
+        mfxImplDescription *implDesc1 = (mfxImplDescription *)(impl1->implDesc);
+        mfxImplDescription *implDesc2 = (mfxImplDescription *)(impl2->implDesc);
+
+        // prioritize greatest API version
+        return (implDesc1->ApiVersion.Version > implDesc2->ApiVersion.Version);
+    });
+
+    // 2 - sort by general HW vs. VSI
+    m_implInfoList.sort([](const ImplInfo *impl1, const ImplInfo *impl2) {
+        mfxImplDescription *implDesc1 = (mfxImplDescription *)(impl1->implDesc);
+        mfxImplDescription *implDesc2 = (mfxImplDescription *)(impl2->implDesc);
+
+        // prioritize general HW accelerator over VSI (if none, i.e. SW, will be sorted in final step)
+        return (implDesc1->AccelerationMode != MFX_ACCEL_MODE_VIA_HDDLUNITE &&
+                implDesc2->AccelerationMode == MFX_ACCEL_MODE_VIA_HDDLUNITE);
+    });
+
+    // 1 - sort by implementation type (HW > SW)
+    m_implInfoList.sort([](const ImplInfo *impl1, const ImplInfo *impl2) {
+        mfxImplDescription *implDesc1 = (mfxImplDescription *)(impl1->implDesc);
+        mfxImplDescription *implDesc2 = (mfxImplDescription *)(impl2->implDesc);
+
+        // prioritize greatest Impl value (HW = 2, SW = 1)
+        return (implDesc1->Impl > implDesc2->Impl);
+    });
+
+    if (m_bPriorityPathEnabled) {
+        // add back unsorted ONEVPL_PRIORITY_PATH libs to beginning of list
+        m_implInfoList.splice(m_implInfoList.begin(), implInfoListPriority);
+    }
+
+    // final pass - update index to match new priority order
+    // validImplIdx will be the index associated with MFXEnumImplememntations()
+    mfxI32 validImplIdx                = 0;
+    std::list<ImplInfo *>::iterator it = m_implInfoList.begin();
+    while (it != m_implInfoList.end()) {
+        ImplInfo *implInfo = (*it);
+
+        if (implInfo->validImplIdx >= 0) {
+            implInfo->validImplIdx = validImplIdx++;
+        }
+        it++;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus LoaderCtxVPL::CreateSession(mfxU32 idx, mfxSession *session) {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    // find library with given implementation index
+    // list of valid implementations (and associated indices) is updated
+    //   every time a filter property is added/modified
+    std::list<ImplInfo *>::iterator it = m_implInfoList.begin();
+    while (it != m_implInfoList.end()) {
+        ImplInfo *implInfo = (*it);
+
+        if (implInfo->validImplIdx == (mfxI32)idx) {
+            LibInfo *libInfo = implInfo->libInfo;
+            mfxU16 deviceID  = 0;
+
+            // pass VendorImplID for this implementation (disambiguate if one
+            //   library contains multiple implementations)
+            // NOTE: implDesc may be null in low latency mode (RT query not called)
+            //   so this value will not be available
+            mfxImplDescription *implDesc = (mfxImplDescription *)(implInfo->implDesc);
+            if (implDesc) {
+                implInfo->vplParam.VendorImplID = implDesc->VendorImplID;
+            }
+
+            // set any special parameters passed in via SetConfigProperty
+            // if application did not specify accelerationMode, use default
+            if (m_specialConfig.bIsSet_accelerationMode)
+                implInfo->vplParam.AccelerationMode = m_specialConfig.accelerationMode;
+
+            // in low latency mode there was no implementation filtering, so check here
+            //   for minimum API version
+            if (m_bLowLatency && m_specialConfig.bIsSet_ApiVersion) {
+                if (implInfo->version.Version < m_specialConfig.ApiVersion.Version)
+                    return MFX_ERR_NOT_FOUND;
+            }
+
+            mfxIMPL msdkImpl = 0;
+            if (libInfo->libType == LibTypeMSDK) {
+                if (implInfo->vplParam.AccelerationMode == MFX_ACCEL_MODE_VIA_D3D9)
+                    msdkImpl = libInfo->msdkCtx[implInfo->msdkImplIdx].m_msdkAdapterD3D9;
+                else
+                    msdkImpl = libInfo->msdkCtx[implInfo->msdkImplIdx].m_msdkAdapter;
+            }
+
+            // in low latency mode implDesc is not available, but application may set adapter number via DXGIAdapterIndex filter
+            if (m_bLowLatency) {
+                if (m_specialConfig.bIsSet_dxgiAdapterIdx && libInfo->libType == LibTypeVPL)
+                    implInfo->vplParam.VendorImplID = m_specialConfig.dxgiAdapterIdx;
+                else if (m_specialConfig.bIsSet_dxgiAdapterIdx && libInfo->libType == LibTypeMSDK)
+                    msdkImpl = msdkImplTab[m_specialConfig.dxgiAdapterIdx];
+            }
+
+            // add any extension buffers set via special filter properties
+            std::vector<mfxExtBuffer *> extBufs;
+
+            // pass NumThread via mfxExtThreadsParam
+            mfxExtThreadsParam extThreadsParam = {};
+            if (m_specialConfig.bIsSet_NumThread) {
+                DISP_LOG_MESSAGE(&m_dispLog,
+                                 "message:  extBuf enabled -- NumThread (%d)",
+                                 m_specialConfig.NumThread);
+
+                extThreadsParam.Header.BufferId = MFX_EXTBUFF_THREADS_PARAM;
+                extThreadsParam.Header.BufferSz = sizeof(mfxExtThreadsParam);
+                extThreadsParam.NumThread       = m_specialConfig.NumThread;
+
+                extBufs.push_back((mfxExtBuffer *)&extThreadsParam);
+            }
+
+            // attach vector of extBufs to mfxInitializationParam
+            implInfo->vplParam.NumExtParam = static_cast<mfxU16>(extBufs.size());
+            implInfo->vplParam.ExtParam =
+                (implInfo->vplParam.NumExtParam ? extBufs.data() : nullptr);
+
+            // initialize this library via MFXInitialize or else fail
+            //   (specify full path to library)
+            sts = MFXInitEx2(implInfo->version,
+                             implInfo->vplParam,
+                             msdkImpl,
+                             session,
+                             &deviceID,
+                             (CHAR_TYPE *)libInfo->libNameFull.c_str());
+
+            // optionally call MFXSetHandle() if present via SetConfigProperty
+            if (sts == MFX_ERR_NONE && m_specialConfig.bIsSet_deviceHandleType &&
+                m_specialConfig.bIsSet_deviceHandle && m_specialConfig.deviceHandleType &&
+                m_specialConfig.deviceHandle) {
+                sts = MFXVideoCORE_SetHandle(*session,
+                                             m_specialConfig.deviceHandleType,
+                                             m_specialConfig.deviceHandle);
+            }
+
+            return sts;
+        }
+        it++;
+    }
+
+    // invalid idx
+    return MFX_ERR_NOT_FOUND;
+}
+
+ConfigCtxVPL *LoaderCtxVPL::AddConfigFilter() {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    // create new config filter context and add
+    //   to list associated with this loader
+    std::unique_ptr<ConfigCtxVPL> configCtx;
+    try {
+        configCtx.reset(new ConfigCtxVPL{});
+    }
+    catch (...) {
+        return nullptr;
+    }
+
+    ConfigCtxVPL *config   = (ConfigCtxVPL *)(configCtx.release());
+    config->m_parentLoader = this;
+
+    m_configCtxList.push_back(config);
+
+    return config;
+}
+
+mfxStatus LoaderCtxVPL::FreeConfigFilters() {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+    std::list<ConfigCtxVPL *>::iterator it = m_configCtxList.begin();
+
+    while (it != m_configCtxList.end()) {
+        ConfigCtxVPL *config = (*it);
+        if (config)
+            delete config;
+        it++;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus LoaderCtxVPL::InitDispatcherLog() {
+    std::string strLogEnabled, strLogFile;
+
+#if defined(_WIN32) || defined(_WIN64)
+    DWORD err;
+
+    char logEnabled[MAX_VPL_SEARCH_PATH] = "";
+    err = GetEnvironmentVariable("ONEVPL_DISPATCHER_LOG", logEnabled, MAX_VPL_SEARCH_PATH);
+    if (err == 0 || err >= MAX_VPL_SEARCH_PATH)
+        return MFX_ERR_UNSUPPORTED; // environment variable not defined or string too long
+
+    strLogEnabled = logEnabled;
+
+    char logFile[MAX_VPL_SEARCH_PATH] = "";
+    err = GetEnvironmentVariable("ONEVPL_DISPATCHER_LOG_FILE", logFile, MAX_VPL_SEARCH_PATH);
+    if (err == 0 || err >= MAX_VPL_SEARCH_PATH) {
+        // nothing to do - strLogFile is an empty string
+    }
+    else {
+        strLogFile = logFile;
+    }
+
+#else
+    const char *logEnabled = std::getenv("ONEVPL_DISPATCHER_LOG");
+    if (!logEnabled)
+        return MFX_ERR_UNSUPPORTED;
+
+    strLogEnabled = logEnabled;
+
+    const char *logFile = std::getenv("ONEVPL_DISPATCHER_LOG_FILE");
+    if (logFile)
+        strLogFile = logFile;
+#endif
+
+    if (strLogEnabled != "ON")
+        return MFX_ERR_UNSUPPORTED;
+
+    // currently logLevel is either 0 or non-zero
+    // additional levels will be added with future API updates
+    return m_dispLog.Init(1, strLogFile);
+}
+
+// public function to return logger object
+// allows logging from C API functions outside of loaderCtx
+DispatcherLogVPL *LoaderCtxVPL::GetLogger() {
+    return &m_dispLog;
+}
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_log.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_log.cpp
new file mode 100644 (file)
index 0000000..1337724
--- /dev/null
@@ -0,0 +1,63 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "vpl/mfx_dispatcher_vpl_log.h"
+
+DispatcherLogVPL::DispatcherLogVPL() : m_logLevel(0), m_logFileName(), m_logFile(nullptr) {}
+
+DispatcherLogVPL::~DispatcherLogVPL() {
+    if (!m_logFileName.empty() && m_logFile)
+        fclose(m_logFile);
+    m_logFile = nullptr;
+}
+
+mfxStatus DispatcherLogVPL::Init(mfxU32 logLevel, const std::string &logFileName) {
+    // avoid leaking file handle if Init is accidentally called more than once
+    if (m_logFile)
+        return MFX_ERR_UNSUPPORTED;
+
+    m_logLevel    = logLevel;
+    m_logFileName = logFileName;
+
+    // append to file if it already exists, otherwise create a new one
+    // m_logFile will be closed in dtor
+    if (m_logLevel) {
+        if (m_logFileName.empty()) {
+            m_logFile = stdout;
+        }
+        else {
+#if defined(_WIN32) || defined(_WIN64)
+            fopen_s(&m_logFile, m_logFileName.c_str(), "a");
+#else
+            m_logFile = fopen(m_logFileName.c_str(), "a");
+#endif
+            if (!m_logFile) {
+                m_logFile = stdout;
+                fprintf(m_logFile,
+                        "Warning - unable to create logfile %s\n",
+                        m_logFileName.c_str());
+                fprintf(m_logFile, "Log output will be sent to stdout\n");
+                m_logFileName.clear();
+            }
+        }
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus DispatcherLogVPL::LogMessage(const char *msg, ...) {
+    if (!m_logLevel || !m_logFile)
+        return MFX_ERR_NONE;
+
+    va_list args;
+    va_start(args, msg);
+    vfprintf(m_logFile, msg, args);
+    va_end(args);
+
+    fprintf(m_logFile, "\n");
+
+    return MFX_ERR_NONE;
+}
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_log.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_log.h
new file mode 100644 (file)
index 0000000..55770dd
--- /dev/null
@@ -0,0 +1,81 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_VPL_MFX_DISPATCHER_VPL_LOG_H_
+#define DISPATCHER_VPL_MFX_DISPATCHER_VPL_LOG_H_
+
+/* oneVPL Dispatcher Debug Log
+ * The debug output of the dispatcher is controlled with the ONEVPL_DISPATCHER_LOG environment variable.
+ * To enable log output, set the ONEVPL_DISPATCHER_LOG environment variable value equals to "ON".
+ * 
+ * By default, oneVPL dispatcher prints all log messages to the console.
+ * To redirect log output to the desired file, set the ONEVPL_DISPATCHER_LOG_FILE environmental 
+ *   variable with the file name of the log file.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <string>
+
+#include "vpl/mfxdispatcher.h"
+#include "vpl/mfxvideo.h"
+
+#ifndef __FUNC_NAME__
+    #if defined(_WIN32) || defined(_WIN64)
+        #define __FUNC_NAME__ __FUNCTION__
+    #else
+        #define __FUNC_NAME__ __PRETTY_FUNCTION__
+    #endif
+#endif
+
+class DispatcherLogVPL {
+public:
+    DispatcherLogVPL();
+    ~DispatcherLogVPL();
+
+    mfxStatus Init(mfxU32 logLevel, const std::string &logFileName);
+    mfxStatus LogMessage(const char *msdk, ...);
+
+    mfxU32 m_logLevel;
+
+private:
+    std::string m_logFileName;
+    FILE *m_logFile;
+};
+
+class DispatcherLogVPLFunction {
+public:
+    DispatcherLogVPLFunction(DispatcherLogVPL *dispLog, const char *fnName)
+            : m_dispLog(),
+              m_fnName() {
+        m_dispLog = dispLog;
+
+        if (m_dispLog && m_dispLog->m_logLevel) {
+            m_fnName = fnName;
+            m_dispLog->LogMessage("function: %s (enter)", m_fnName.c_str());
+        }
+    }
+
+    ~DispatcherLogVPLFunction() {
+        if (m_dispLog && m_dispLog->m_logLevel)
+            m_dispLog->LogMessage("function: %s (return)", m_fnName.c_str());
+    }
+
+private:
+    DispatcherLogVPL *m_dispLog;
+    std::string m_fnName;
+};
+
+#define DISP_LOG_FUNCTION(dispLog) DispatcherLogVPLFunction _dispLogFn(dispLog, __FUNC_NAME__);
+#define DISP_LOG_MESSAGE(dispLog, ...)          \
+    {                                           \
+        if (dispLog) {                          \
+            (dispLog)->LogMessage(__VA_ARGS__); \
+        }                                       \
+    }
+
+#endif // DISPATCHER_VPL_MFX_DISPATCHER_VPL_LOG_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_lowlatency.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_lowlatency.cpp
new file mode 100644 (file)
index 0000000..7264dc0
--- /dev/null
@@ -0,0 +1,327 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "vpl/mfx_dispatcher_vpl.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+    #include "vpl/mfx_dispatcher_vpl_win.h"
+
+    #if defined _M_IX86
+        // Windows x86
+        #define LIB_ONEVPL L"libmfx32-gen.dll"
+        #define LIB_MSDK   L"libmfxhw32.dll"
+    #else
+        // Windows x64
+        #define LIB_ONEVPL L"libmfx64-gen.dll"
+        #define LIB_MSDK   L"libmfxhw64.dll"
+    #endif
+#elif defined(__linux__)
+    // Linux x64
+    #define LIB_ONEVPL "libmfx-gen.so.1.2"
+    #define LIB_MSDK   "libmfxhw64.so.1"
+#endif
+
+// For Windows:
+//  VPL - load from Driver Store, look only for libmfx64-gen.dll (32)
+//  MSDK - load from Driver Store, look only for libmfxhw64.dll (32)
+//  MSDK - fallback, load from %windir%\system32 or %windir%\syswow64
+
+// remove this #ifdef if Linux path is implemented (avoid unused variable warnings)
+#if defined(_WIN32) || defined(_WIN64)
+// library names
+static const CHAR_TYPE *libNameVPL  = LIB_ONEVPL;
+static const CHAR_TYPE *libNameMSDK = LIB_MSDK;
+
+// required exports
+static const char *reqFuncVPL  = "MFXInitialize";
+static const char *reqFuncMSDK = "MFXInitEx";
+#endif
+
+LibInfo *LoaderCtxVPL::AddSingleLibrary(STRING_TYPE libPath, LibType libType) {
+    LibInfo *libInfo = nullptr;
+
+#if defined(_WIN32) || defined(_WIN64)
+    // try to open library
+    mfxModuleHandle hLib = MFX::mfx_dll_load(libPath.c_str());
+    if (!hLib)
+        return nullptr;
+
+    // check for required entrypoint function
+    const char *reqFunc  = (libType == LibTypeVPL ? reqFuncVPL : reqFuncMSDK);
+    VPLFunctionPtr pProc = (VPLFunctionPtr)MFX::mfx_dll_get_addr(hLib, reqFunc);
+    MFX::mfx_dll_free(hLib);
+
+    // entrypoint function missing - invalid library
+    if (!pProc)
+        return nullptr;
+#else
+    // Linux - not supported
+    return nullptr;
+#endif
+
+    // create new LibInfo and add to list
+    libInfo = new LibInfo;
+    if (!libInfo)
+        return nullptr;
+
+    libInfo->libNameFull = libPath;
+    libInfo->libType     = libType;
+    libInfo->libPriority = (libType == LibTypeVPL ? LIB_PRIORITY_01 : LIB_PRIORITY_LEGACY);
+
+    return libInfo;
+}
+
+mfxStatus LoaderCtxVPL::LoadLibsFromDriverStore(mfxU32 numAdapters,
+                                                const std::vector<DXGI1DeviceInfo> &adapterInfo,
+                                                LibType libType) {
+#if defined(_WIN32) || defined(_WIN64)
+    mfxStatus sts = MFX_ERR_NONE;
+
+    mfxI32 storageID         = MFX::MFX_UNKNOWN_KEY;
+    const CHAR_TYPE *libName = nullptr;
+    const char *reqFunc      = nullptr;
+
+    if (libType == LibTypeVPL) {
+        storageID = MFX::MFX_DRIVER_STORE_ONEVPL;
+        libName   = libNameVPL;
+        reqFunc   = reqFuncVPL;
+    }
+    else if (libType == LibTypeMSDK) {
+        storageID = MFX::MFX_DRIVER_STORE;
+        libName   = libNameMSDK;
+        reqFunc   = reqFuncMSDK;
+    }
+    else {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // get path to Windows driver store
+    STRING_TYPE libPath;
+    mfxU32 adapterID;
+    for (adapterID = 0; adapterID < numAdapters; adapterID++) {
+        // get driver store path for this adapter
+        libPath.clear();
+        sts = MFX::MFXLibraryIterator::GetDriverStoreDir(libPath,
+                                                         MAX_VPL_SEARCH_PATH,
+                                                         adapterInfo[adapterID].deviceID,
+                                                         storageID);
+        if (sts != MFX_ERR_NONE || libPath.size() == 0)
+            continue;
+
+        // try to open library
+        libPath += libName;
+        LibInfo *libInfo = AddSingleLibrary(libPath, libType);
+
+        // if successful, add to list and return (stop at first
+        if (libInfo) {
+            m_libInfoList.push_back(libInfo);
+            return MFX_ERR_NONE;
+        }
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+#else
+    // Linux - not supported
+    return MFX_ERR_UNSUPPORTED;
+#endif
+}
+
+mfxStatus LoaderCtxVPL::LoadLibsFromSystemDir(LibType libType) {
+#if defined(_WIN32) || defined(_WIN64)
+    mfxStatus sts = MFX_ERR_NONE;
+
+    const CHAR_TYPE *libName = nullptr;
+    const char *reqFunc      = nullptr;
+
+    if (libType == LibTypeVPL) {
+        libName = libNameVPL;
+        reqFunc = reqFuncVPL;
+    }
+    else if (libType == LibTypeMSDK) {
+        libName = libNameMSDK;
+        reqFunc = reqFuncMSDK;
+    }
+    else {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // get path to Windows system dir
+    STRING_TYPE libPath;
+    libPath.clear();
+
+    std::list<STRING_TYPE> winSysDir;
+    ParseEnvSearchPaths(L"windir", winSysDir);
+
+    // should resolve to a single directory, otherwise something went wrong
+    if (winSysDir.size() == 1) {
+    #if defined _M_IX86
+        libPath = winSysDir.front() + L"\\syswow64\\";
+    #else
+        libPath = winSysDir.front() + L"\\system32\\";
+    #endif
+    }
+    else {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // try to open library
+    libPath += libName;
+    LibInfo *libInfo = AddSingleLibrary(libPath, libType);
+
+    // if successful, add to list and return (stop at first
+    if (libInfo) {
+        m_libInfoList.push_back(libInfo);
+        return MFX_ERR_NONE;
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+#else
+    // Linux - not supported
+    return MFX_ERR_UNSUPPORTED;
+#endif
+}
+
+mfxStatus LoaderCtxVPL::LoadLibsLowLatency() {
+    DISP_LOG_FUNCTION(&m_dispLog);
+
+#if defined(_WIN32) || defined(_WIN64)
+    mfxStatus sts = MFX_ERR_NONE;
+
+    // check driver store
+    mfxU32 numAdapters = 0;
+
+    std::vector<DXGI1DeviceInfo> adapterInfo;
+    bool bEnumSuccess = MFX::DXGI1Device::GetAdapterList(adapterInfo);
+    numAdapters       = (mfxU32)adapterInfo.size();
+
+    // error - no graphics adapters found
+    if (!bEnumSuccess || numAdapters == 0)
+        return MFX_ERR_UNSUPPORTED;
+
+    // try loading oneVPL from driver store
+    sts = LoadLibsFromDriverStore(numAdapters, adapterInfo, LibTypeVPL);
+    if (sts == MFX_ERR_NONE) {
+        LibInfo *libInfo = m_libInfoList.back();
+
+        sts = LoadSingleLibrary(libInfo);
+        if (sts == MFX_ERR_NONE) {
+            LoadAPIExports(libInfo, LibTypeVPL);
+            m_bNeedLowLatencyQuery = false;
+            return MFX_ERR_NONE;
+        }
+        UnloadSingleLibrary(libInfo); // failed - unload and move to next location
+    }
+
+    // try loading MSDK from driver store
+    sts = LoadLibsFromDriverStore(numAdapters, adapterInfo, LibTypeMSDK);
+    if (sts == MFX_ERR_NONE) {
+        LibInfo *libInfo = m_libInfoList.back();
+
+        sts = LoadSingleLibrary(libInfo);
+        if (sts == MFX_ERR_NONE) {
+            mfxU32 numFunctions = LoadAPIExports(libInfo, LibTypeMSDK);
+
+            if (numFunctions == NumMSDKFunctions) {
+                mfxVariant var = {};
+                var.Type       = MFX_VARIANT_TYPE_PTR;
+                var.Data.Ptr   = (mfxHDL) "mfxhw64";
+
+                auto it = m_configCtxList.begin();
+
+                while (it != m_configCtxList.end()) {
+                    ConfigCtxVPL *config = (*it);
+                    sts = config->SetFilterProperty((const mfxU8 *)"mfxImplDescription.ImplName",
+                                                    var);
+                    if (sts != MFX_ERR_NONE)
+                        return MFX_ERR_UNSUPPORTED;
+                    it++;
+                }
+
+                m_bNeedLowLatencyQuery = false;
+                return MFX_ERR_NONE;
+            }
+        }
+        UnloadSingleLibrary(libInfo); // failed - unload and move to next location
+    }
+
+    // try loading MSDK from sysdir %windir%\system32 and %windir%\syswow64
+    sts = LoadLibsFromSystemDir(LibTypeMSDK);
+    if (sts == MFX_ERR_NONE) {
+        LibInfo *libInfo = m_libInfoList.front();
+
+        sts = LoadSingleLibrary(libInfo);
+        if (sts == MFX_ERR_NONE) {
+            mfxU32 numFunctions = LoadAPIExports(libInfo, LibTypeMSDK);
+
+            if (numFunctions == NumMSDKFunctions) {
+                mfxVariant var = {};
+                var.Type       = MFX_VARIANT_TYPE_PTR;
+                var.Data.Ptr   = (mfxHDL) "mfxhw64";
+
+                auto it = m_configCtxList.begin();
+
+                while (it != m_configCtxList.end()) {
+                    ConfigCtxVPL *config = (*it);
+                    sts = config->SetFilterProperty((const mfxU8 *)"mfxImplDescription.ImplName",
+                                                    var);
+                    if (sts != MFX_ERR_NONE)
+                        return MFX_ERR_UNSUPPORTED;
+                    it++;
+                }
+                m_bNeedLowLatencyQuery = false;
+                return MFX_ERR_NONE;
+            }
+        }
+        UnloadSingleLibrary(libInfo); // failed - unload and move to next location
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+#else
+    // Linux - not supported
+    return MFX_ERR_UNSUPPORTED;
+#endif
+}
+
+// try creating a session in order to get runtime API version
+mfxStatus LoaderCtxVPL::QuerySessionLowLatency(LibInfo *libInfo,
+                                               mfxU32 adapterID,
+                                               mfxVersion *ver) {
+    mfxStatus sts;
+    mfxSession session = nullptr;
+
+    mfxVersion reqVersion;
+    if (libInfo->libType == LibTypeVPL) {
+        reqVersion.Major = 2;
+        reqVersion.Minor = 0;
+    }
+    else {
+        reqVersion.Major = 1;
+        reqVersion.Minor = 0;
+    }
+
+    // set acceleration mode
+    mfxInitializationParam vplParam = {};
+    vplParam.AccelerationMode       = m_specialConfig.accelerationMode;
+
+    // set adapter ID for both MSDK and VPL
+    vplParam.VendorImplID = adapterID;
+    mfxIMPL hwImpl        = msdkImplTab[adapterID];
+
+    mfxU16 deviceID;
+    sts = MFXInitEx2(reqVersion,
+                     vplParam,
+                     hwImpl,
+                     &session,
+                     &deviceID,
+                     (CHAR_TYPE *)libInfo->libNameFull.c_str());
+
+    if (sts == MFX_ERR_NONE) {
+        sts = MFXQueryVersion(session, ver);
+        MFXClose(session);
+    }
+
+    return sts;
+}
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_msdk.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_msdk.cpp
new file mode 100644 (file)
index 0000000..99fc05f
--- /dev/null
@@ -0,0 +1,430 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "vpl/mfx_dispatcher_vpl.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+    #include "vpl/mfx_dispatcher_vpl_win.h"
+#endif
+
+#ifdef __linux__
+    #include <pthread.h>
+    #define strncpy_s(dst, size, src, cnt) strcpy((dst), (src)) // NOLINT
+#endif
+
+// leave table formatting alone
+// clang-format off
+
+static const mfxChar strImplName[MFX_IMPL_NAME_LEN] = "mfxhw64";
+static const mfxChar strLicense[MFX_STRFIELD_LEN]   = "";
+
+#if defined _M_IX86
+static const mfxChar strKeywords[MFX_STRFIELD_LEN] = "MSDK,x86";
+#else
+static const mfxChar strKeywords[MFX_STRFIELD_LEN] = "MSDK,x64";
+#endif
+
+// also used in main loader routine
+const mfxIMPL msdkImplTab[MAX_NUM_IMPL_MSDK] = {
+    MFX_IMPL_HARDWARE,
+    MFX_IMPL_HARDWARE2,
+    MFX_IMPL_HARDWARE3,
+    MFX_IMPL_HARDWARE4,
+};
+
+// not relevant for 1.x runtimes (no internal memory management)
+#define NUM_POOL_POLICIES_MSDK 0
+
+static const mfxPoolPolicyDescription PoolPolicies = {
+    { 0, 1 },                   // struct Version
+    {},                         // reserved
+    NUM_POOL_POLICIES_MSDK,     // NumPoolPolicies
+    nullptr,
+};
+
+// 1.x function names should match list in enum eFunc
+static const mfxChar* msdkImplFuncsNames[] = {
+    "MFXInit",
+    "MFXClose",
+    "MFXQueryIMPL",
+    "MFXQueryVersion",
+    "MFXJoinSession",
+    "MFXDisjoinSession",
+    "MFXCloneSession",
+    "MFXSetPriority",
+    "MFXGetPriority",
+    "MFXInitEx",
+    "MFXVideoCORE_SetFrameAllocator",
+    "MFXVideoCORE_SetHandle",
+    "MFXVideoCORE_GetHandle",
+    "MFXVideoCORE_SyncOperation",
+    "MFXVideoENCODE_Query",
+    "MFXVideoENCODE_QueryIOSurf",
+    "MFXVideoENCODE_Init",
+    "MFXVideoENCODE_Reset",
+    "MFXVideoENCODE_Close",
+    "MFXVideoENCODE_GetVideoParam",
+    "MFXVideoENCODE_GetEncodeStat",
+    "MFXVideoENCODE_EncodeFrameAsync",
+    "MFXVideoDECODE_Query",
+    "MFXVideoDECODE_DecodeHeader",
+    "MFXVideoDECODE_QueryIOSurf",
+    "MFXVideoDECODE_Init",
+    "MFXVideoDECODE_Reset",
+    "MFXVideoDECODE_Close",
+    "MFXVideoDECODE_GetVideoParam",
+    "MFXVideoDECODE_GetDecodeStat",
+    "MFXVideoDECODE_SetSkipMode",
+    "MFXVideoDECODE_GetPayload",
+    "MFXVideoDECODE_DecodeFrameAsync",
+    "MFXVideoVPP_Query",
+    "MFXVideoVPP_QueryIOSurf",
+    "MFXVideoVPP_Init",
+    "MFXVideoVPP_Reset",
+    "MFXVideoVPP_Close",
+    "MFXVideoVPP_GetVideoParam",
+    "MFXVideoVPP_GetVPPStat",
+    "MFXVideoVPP_RunFrameVPPAsync",
+    "MFXVideoCORE_QueryPlatform",
+};
+
+static const mfxImplementedFunctions msdkImplFuncs = {
+    sizeof(msdkImplFuncsNames) / sizeof(mfxChar*),
+    (mfxChar**)msdkImplFuncsNames
+};
+
+// end table formatting
+// clang-format on
+
+LoaderCtxMSDK::LoaderCtxMSDK()
+        : m_msdkAdapter(),
+          m_msdkAdapterD3D9(),
+          m_libNameFull(),
+          m_id(),
+          m_accelMode(),
+          m_loaderDeviceID(0) {}
+
+LoaderCtxMSDK::~LoaderCtxMSDK() {}
+
+mfxStatus LoaderCtxMSDK::OpenSession(mfxSession *session,
+                                     STRING_TYPE libNameFull,
+                                     mfxAccelerationMode accelMode,
+                                     mfxIMPL hwImpl) {
+    // require API 1.0 or later (both MFXInit and MFXInitEx supported)
+    mfxVersion reqVersion;
+    reqVersion.Major = MSDK_MIN_VERSION_MAJOR;
+    reqVersion.Minor = MSDK_MIN_VERSION_MINOR;
+
+    // set acceleration mode - will be mapped to 1.x API
+    mfxInitializationParam vplParam = {};
+    vplParam.AccelerationMode       = accelMode;
+
+    return MFXInitEx2(reqVersion,
+                      vplParam,
+                      hwImpl,
+                      session,
+                      &m_loaderDeviceID,
+                      (CHAR_TYPE *)libNameFull.c_str());
+}
+
+// safe to call more than once (sets/checks for null session)
+void LoaderCtxMSDK::CloseSession(mfxSession *session) {
+    if (*session)
+        MFXClose(*session);
+
+    *session = nullptr;
+}
+
+// map mfxIMPL (1.x) to mfxAccelerationMode (2.x)
+mfxAccelerationMode LoaderCtxMSDK::CvtAccelType(mfxIMPL implType, mfxIMPL implMethod) {
+    if (implType == MFX_IMPL_HARDWARE) {
+        switch (implMethod) {
+            case MFX_IMPL_VIA_D3D9:
+                return MFX_ACCEL_MODE_VIA_D3D9;
+            case MFX_IMPL_VIA_D3D11:
+                return MFX_ACCEL_MODE_VIA_D3D11;
+            case MFX_IMPL_VIA_VAAPI:
+                return MFX_ACCEL_MODE_VIA_VAAPI;
+        }
+    }
+
+    return MFX_ACCEL_MODE_NA;
+}
+
+mfxStatus LoaderCtxMSDK::GetDefaultAccelType(mfxU32 adapterID, mfxIMPL *implDefault, mfxU64 *luid) {
+#ifdef __linux__
+    // VAAPI only
+    *implDefault = MFX_IMPL_VIA_VAAPI;
+    *luid        = 0;
+    return MFX_ERR_NONE;
+#else
+    // Windows - D3D11 only
+    mfxU32 VendorID = 0, DeviceID = 0;
+    mfxIMPL implTest;
+    mfxStatus sts;
+
+    // check whether adapterID supports D3D11 and has correct VendorID
+    implTest = MFX_IMPL_VIA_D3D11;
+    sts      = MFX::SelectImplementationType(adapterID, &implTest, &VendorID, &DeviceID, luid);
+
+    if (sts != MFX_ERR_NONE || VendorID != 0x8086) {
+        implTest = MFX_IMPL_UNSUPPORTED;
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    *implDefault = implTest;
+
+    return MFX_ERR_NONE;
+#endif
+}
+
+mfxStatus LoaderCtxMSDK::QueryAPIVersion(STRING_TYPE libNameFull, mfxVersion *msdkVersion) {
+    mfxStatus sts;
+    mfxSession session = nullptr;
+
+    mfxVersion reqVersion;
+    reqVersion.Major = MSDK_MIN_VERSION_MAJOR;
+    reqVersion.Minor = MSDK_MIN_VERSION_MINOR;
+
+    // try creating a session with each adapter in order to get MSDK API version
+    // stop with first successful session creation
+    for (mfxU32 adapterID = 0; adapterID < MAX_NUM_IMPL_MSDK; adapterID++) {
+        // try HW session, default acceleration mode
+        mfxIMPL hwImpl      = msdkImplTab[adapterID];
+        mfxIMPL implDefault = MFX_IMPL_UNSUPPORTED;
+        mfxU64 luid;
+
+        // if not a valid HW device, try next adapter
+        sts = GetDefaultAccelType(adapterID, &implDefault, &luid);
+        if (sts != MFX_ERR_NONE)
+            continue;
+
+        // set acceleration mode - will be mapped to 1.x API
+        mfxInitializationParam vplParam = {};
+        vplParam.AccelerationMode =
+            (mfxAccelerationMode)CvtAccelType(MFX_IMPL_HARDWARE, implDefault & 0xFF00);
+
+        mfxU16 deviceID;
+        sts = MFXInitEx2(reqVersion,
+                         vplParam,
+                         hwImpl,
+                         &session,
+                         &deviceID,
+                         (CHAR_TYPE *)libNameFull.c_str());
+
+        if (sts == MFX_ERR_NONE) {
+            sts = MFXQueryVersion(session, msdkVersion);
+            MFXClose(session);
+
+            if (sts == MFX_ERR_NONE)
+                return sts;
+        }
+    }
+
+    return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus LoaderCtxMSDK::QueryMSDKCaps(STRING_TYPE libNameFull,
+                                       mfxImplDescription **implDesc,
+                                       mfxImplementedFunctions **implFuncs,
+                                       mfxU32 adapterID,
+                                       bool bSkipD3D9Check) {
+#ifdef DISABLE_MSDK_COMPAT
+    // disable support for legacy MSDK
+    return MFX_ERR_UNSUPPORTED;
+#endif
+
+    mfxStatus sts;
+    mfxSession session = nullptr;
+
+    m_libNameFull = libNameFull;
+
+#ifdef __linux__
+    // require pthreads to be linked in for MSDK RT to load
+    pthread_key_t pkey;
+    if (pthread_key_create(&pkey, NULL) == 0) {
+        pthread_key_delete(pkey);
+    }
+#endif
+
+    // try HW session, default acceleration mode
+    mfxIMPL hwImpl      = msdkImplTab[adapterID];
+    mfxIMPL implDefault = MFX_IMPL_UNSUPPORTED;
+    mfxU64 luid         = 0;
+
+    sts = GetDefaultAccelType(adapterID, &implDefault, &luid);
+    if (sts != MFX_ERR_NONE)
+        return MFX_ERR_UNSUPPORTED;
+
+    sts = OpenSession(&session,
+                      m_libNameFull,
+                      (mfxAccelerationMode)CvtAccelType(MFX_IMPL_HARDWARE, implDefault & 0xFF00),
+                      hwImpl);
+
+    // adapter unsupported
+    if (sts != MFX_ERR_NONE)
+        return MFX_ERR_UNSUPPORTED;
+
+    // return list of implemented functions
+    *implFuncs = (mfxImplementedFunctions *)(&msdkImplFuncs);
+
+    // clear new 2.0 style description struct
+    memset(&m_id, 0, sizeof(mfxImplDescription));
+    *implDesc = &m_id;
+
+    // fill in top-level capabilities
+    m_id.Version.Version = MFX_IMPLDESCRIPTION_VERSION;
+    m_id.Impl            = MFX_IMPL_TYPE_HARDWARE;
+
+    // query API version
+    sts = MFXQueryVersion(session, &m_id.ApiVersion);
+    if (sts != MFX_ERR_NONE) {
+        CloseSession(&session);
+        return sts;
+    }
+
+    // set default acceleration mode
+    m_id.AccelerationMode = CvtAccelType(MFX_IMPL_HARDWARE, implDefault & 0xFF00);
+
+    // fill in acceleration description struct
+    mfxAccelerationModeDescription *accelDesc = &(m_id.AccelerationModeDescription);
+    accelDesc->Version.Version                = MFX_ACCELERATIONMODESCRIPTION_VERSION;
+
+    // fill in mode description with just the single (default) mode
+    accelDesc->NumAccelerationModes = 1;
+    accelDesc->Mode                 = m_accelMode;
+    accelDesc->Mode[0]              = m_id.AccelerationMode;
+
+    // return HW accelerator - required by MFXCreateSession
+    m_msdkAdapter = hwImpl;
+
+    // map MFX HW number to VendorImplID
+    m_id.VendorImplID = 0;
+    switch (hwImpl) {
+        case MFX_IMPL_HARDWARE:
+            m_id.VendorImplID = 0;
+            break;
+        case MFX_IMPL_HARDWARE2:
+            m_id.VendorImplID = 1;
+            break;
+        case MFX_IMPL_HARDWARE3:
+            m_id.VendorImplID = 2;
+            break;
+        case MFX_IMPL_HARDWARE4:
+            m_id.VendorImplID = 3;
+            break;
+    }
+
+    // fill in strings
+    strncpy_s(m_id.ImplName, sizeof(m_id.ImplName), strImplName, sizeof(strImplName));
+    strncpy_s(m_id.License, sizeof(m_id.License), strLicense, sizeof(strLicense));
+    strncpy_s(m_id.Keywords, sizeof(m_id.Keywords), strKeywords, sizeof(strKeywords));
+
+    m_id.VendorID    = 0x8086;
+    m_id.NumExtParam = 0;
+
+    // fill in pool policies
+    m_id.PoolPolicies = PoolPolicies;
+
+    // fill in device description
+    mfxDeviceDescription *Dev = &(m_id.Dev);
+    memset(Dev, 0, sizeof(mfxDeviceDescription)); // initially empty
+    Dev->MediaAdapterType = MFX_MEDIA_UNKNOWN;
+
+    // query for underlying deviceID (requires API >= 1.19)
+    mfxU16 deviceID = 0x0000;
+    if (IsVersionSupported(MAKE_MFX_VERSION(1, 19), m_id.ApiVersion)) {
+        mfxPlatform platform = {};
+
+        sts = MFXVideoCORE_QueryPlatform(session, &platform);
+        if (sts == MFX_ERR_NONE)
+            deviceID = platform.DeviceId;
+
+        // mfxPlatform::MediaAdapterType was added in API 1.31
+        if (IsVersionSupported(MAKE_MFX_VERSION(1, 31), m_id.ApiVersion)) {
+            Dev->MediaAdapterType = platform.MediaAdapterType;
+        }
+    }
+
+    // if QueryPlatform did not return deviceID, we may have received
+    //   it from the loader (MFXInitEx2)
+    if (deviceID == 0)
+        deviceID = m_loaderDeviceID;
+
+    // store DeviceID as "DevID" (hex) / "AdapterIdx" (dec) to match GPU RT
+    Dev->Version.Version = MFX_DEVICEDESCRIPTION_VERSION;
+    snprintf(Dev->DeviceID, sizeof(Dev->DeviceID), "%x/%d", deviceID, m_id.VendorImplID);
+    Dev->NumSubDevices = 0;
+
+    CloseSession(&session);
+
+#if defined(_WIN32) || defined(_WIN64)
+    if (bSkipD3D9Check == false) {
+        mfxIMPL implD3D9;
+        m_msdkAdapterD3D9 = MFX_IMPL_UNSUPPORTED;
+
+        sts = CheckD3D9Support(luid, libNameFull, &implD3D9);
+        if (sts == MFX_ERR_NONE) {
+            m_msdkAdapterD3D9 = implD3D9;
+
+            accelDesc->Mode[accelDesc->NumAccelerationModes] = MFX_ACCEL_MODE_VIA_D3D9;
+            accelDesc->NumAccelerationModes++;
+        }
+    }
+#endif
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus LoaderCtxMSDK::CheckD3D9Support(mfxU64 luid, STRING_TYPE libNameFull, mfxIMPL *implD3D9) {
+#if defined(_WIN32) || defined(_WIN64)
+    mfxU32 VendorID = 0, DeviceID = 0;
+    mfxIMPL implTest = MFX_IMPL_VIA_D3D9;
+
+    mfxStatus sts;
+    mfxSession session = nullptr;
+
+    mfxVersion reqVersion;
+    reqVersion.Major = MSDK_MIN_VERSION_MAJOR;
+    reqVersion.Minor = MSDK_MIN_VERSION_MINOR;
+
+    *implD3D9 = MFX_IMPL_UNSUPPORTED;
+
+    mfxU32 idx;
+    for (idx = 0; idx < MAX_NUM_IMPL_MSDK; idx++) {
+        mfxU64 luidD3D9 = 0;
+        sts = MFX::SelectImplementationType(idx, &implTest, &VendorID, &DeviceID, &luidD3D9);
+
+        if (sts != MFX_ERR_NONE || VendorID != 0x8086 || luid != luidD3D9)
+            continue;
+
+        // matching LUID - try creating a D3D9 session
+        mfxInitializationParam vplParam = {};
+        vplParam.AccelerationMode       = MFX_ACCEL_MODE_VIA_D3D9;
+
+        mfxU16 deviceID;
+        sts = MFXInitEx2(reqVersion,
+                         vplParam,
+                         msdkImplTab[idx],
+                         &session,
+                         &deviceID,
+                         (CHAR_TYPE *)libNameFull.c_str());
+
+        if (sts == MFX_ERR_NONE) {
+            *implD3D9 = msdkImplTab[idx];
+            MFXClose(session);
+            return MFX_ERR_NONE;
+        }
+
+        break; // D3D9 not supported
+    }
+
+    // this adapter (input luid) does not support D3D9
+    return MFX_ERR_UNSUPPORTED;
+#else
+    return MFX_ERR_UNSUPPORTED;
+#endif
+}
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_win.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/vpl/mfx_dispatcher_vpl_win.h
new file mode 100644 (file)
index 0000000..a114985
--- /dev/null
@@ -0,0 +1,19 @@
+/*############################################################################
+  # Copyright (C) Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_VPL_MFX_DISPATCHER_VPL_WIN_H_
+#define DISPATCHER_VPL_MFX_DISPATCHER_VPL_WIN_H_
+
+// headers for Windows legacy dispatcher
+#if defined(_WIN32) || defined(_WIN64)
+    #include "windows/mfx_dispatcher.h"
+    #include "windows/mfx_dispatcher_defs.h"
+    #include "windows/mfx_dxva2_device.h"
+    #include "windows/mfx_library_iterator.h"
+    #include "windows/mfx_load_dll.h"
+#endif
+
+#endif // DISPATCHER_VPL_MFX_DISPATCHER_VPL_WIN_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/libmfx.def b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/libmfx.def
new file mode 100644 (file)
index 0000000..c924a80
--- /dev/null
@@ -0,0 +1,76 @@
+EXPORTS
+    MFXInit
+    MFXClose
+    MFXQueryIMPL
+    MFXQueryVersion
+
+    MFXJoinSession
+    MFXDisjoinSession
+    MFXCloneSession
+    MFXSetPriority
+    MFXGetPriority
+
+    MFXVideoCORE_SetFrameAllocator
+    MFXVideoCORE_SetHandle
+    MFXVideoCORE_GetHandle
+    MFXVideoCORE_QueryPlatform
+    MFXVideoCORE_SyncOperation
+
+    MFXVideoENCODE_Query
+    MFXVideoENCODE_QueryIOSurf
+    MFXVideoENCODE_Init
+    MFXVideoENCODE_Reset
+    MFXVideoENCODE_Close
+    MFXVideoENCODE_GetVideoParam
+    MFXVideoENCODE_GetEncodeStat
+    MFXVideoENCODE_EncodeFrameAsync
+
+    MFXVideoDECODE_Query
+    MFXVideoDECODE_DecodeHeader
+    MFXVideoDECODE_QueryIOSurf
+    MFXVideoDECODE_Init
+    MFXVideoDECODE_Reset
+    MFXVideoDECODE_Close
+    MFXVideoDECODE_GetVideoParam
+    MFXVideoDECODE_GetDecodeStat
+    MFXVideoDECODE_SetSkipMode
+    MFXVideoDECODE_GetPayload
+    MFXVideoDECODE_DecodeFrameAsync
+
+    MFXVideoVPP_Query
+    MFXVideoVPP_QueryIOSurf
+    MFXVideoVPP_Init
+    MFXVideoVPP_Reset
+    MFXVideoVPP_Close
+
+    MFXVideoVPP_GetVideoParam
+    MFXVideoVPP_GetVPPStat
+    MFXVideoVPP_RunFrameVPPAsync
+
+    MFXInitEx
+
+    MFXQueryAdapters
+    MFXQueryAdaptersNumber
+    MFXQueryAdaptersDecode
+
+    MFXLoad
+    MFXUnload
+    MFXCreateConfig
+    MFXSetConfigFilterProperty
+    MFXEnumImplementations
+    MFXCreateSession
+    MFXDispReleaseImplDescription
+
+    MFXMemory_GetSurfaceForVPP
+    MFXMemory_GetSurfaceForEncode
+    MFXMemory_GetSurfaceForDecode
+
+    MFXMemory_GetSurfaceForVPPOut
+    MFXVideoDECODE_VPP_Init
+    MFXVideoDECODE_VPP_DecodeFrameAsync
+    MFXVideoDECODE_VPP_Reset
+    MFXVideoDECODE_VPP_GetChannelParam
+    MFXVideoDECODE_VPP_Close
+    MFXVideoVPP_ProcessFrameAsync
+
+
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/main.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/main.cpp
new file mode 100644 (file)
index 0000000..8396359
--- /dev/null
@@ -0,0 +1,1071 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include <windows.h>
+
+#include <stringapiset.h>
+
+#include <memory>
+#include <new>
+
+#include "windows/mfx_critical_section.h"
+#include "windows/mfx_dispatcher.h"
+#include "windows/mfx_dispatcher_log.h"
+#include "windows/mfx_library_iterator.h"
+#include "windows/mfx_load_dll.h"
+
+#include "windows/mfx_vector.h"
+
+#if defined(MEDIASDK_UWP_DISPATCHER)
+    #include "windows/mfx_driver_store_loader.h"
+#endif
+
+#include <string.h> /* for memset on Linux */
+
+#include <stdlib.h> /* for qsort on Linux */
+
+// module-local definitions
+namespace {
+
+const struct {
+    // instance implementation type
+    eMfxImplType implType;
+    // real implementation
+    mfxIMPL impl;
+    // adapter numbers
+    mfxU32 adapterID;
+
+} implTypes[] = {
+    // MFX_IMPL_AUTO case
+    { MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0 },
+    { MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0 },
+
+    // MFX_IMPL_ANY case
+    { MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE, 0 },
+    { MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE2, 1 },
+    { MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE3, 2 },
+    { MFX_LIB_HARDWARE, MFX_IMPL_HARDWARE4, 3 },
+    { MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0 },
+    { MFX_LIB_SOFTWARE, MFX_IMPL_SOFTWARE, 0 }, // unused - was MFX_IMPL_AUDIO
+};
+
+const struct {
+    // start index in implTypes table for specified implementation
+    mfxU32 minIndex;
+    // last index in implTypes table for specified implementation
+    mfxU32 maxIndex;
+
+} implTypesRange[] = {
+    { 0, 1 }, // MFX_IMPL_AUTO
+    { 1, 1 }, // MFX_IMPL_SOFTWARE
+    { 0, 0 }, // MFX_IMPL_HARDWARE
+    { 2, 6 }, // MFX_IMPL_AUTO_ANY
+    { 2, 5 }, // MFX_IMPL_HARDWARE_ANY
+    { 3, 3 }, // MFX_IMPL_HARDWARE2
+    { 4, 4 }, // MFX_IMPL_HARDWARE3
+    { 5, 5 }, // MFX_IMPL_HARDWARE4
+    { 2, 6 }, // MFX_IMPL_RUNTIME, same as MFX_IMPL_HARDWARE_ANY
+};
+
+MFX::mfxCriticalSection dispGuard = 0;
+
+} // namespace
+
+using namespace MFX;
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+
+//
+// Implement DLL exposed functions. MFXInit and MFXClose have to do
+// slightly more than other. They require to be implemented explicitly.
+// All other functions are implemented implicitly.
+//
+
+typedef MFXVector<MFX_DISP_HANDLE_EX *> HandleVector;
+typedef MFXVector<mfxStatus> StatusVector;
+
+struct VectorHandleGuard {
+    explicit VectorHandleGuard(HandleVector &aVector) : m_vector(aVector) {}
+    ~VectorHandleGuard() {
+        HandleVector::iterator it = m_vector.begin(), et = m_vector.end();
+        for (; it != et; ++it) {
+            delete *it;
+        }
+    }
+
+    HandleVector &m_vector;
+
+private:
+    void operator=(const VectorHandleGuard &);
+};
+
+static int HandleSort(const void *plhs, const void *prhs) {
+    const MFX_DISP_HANDLE_EX *lhs   = *(const MFX_DISP_HANDLE_EX **)plhs;
+    const MFX_DISP_HANDLE_EX *rhs   = *(const MFX_DISP_HANDLE_EX **)prhs;
+    const mfxVersion vplInitVersion = { 255, 1 };
+
+    // prefer oneVPL runtime (API = 1.255)
+    if ((lhs->actualApiVersion.Version == vplInitVersion.Version) &&
+        (rhs->actualApiVersion < lhs->actualApiVersion)) {
+        return -1;
+    }
+    if ((rhs->actualApiVersion.Version == vplInitVersion.Version) &&
+        (lhs->actualApiVersion < rhs->actualApiVersion)) {
+        return 1;
+    }
+
+    // prefer HW implementation
+    if (lhs->implType != MFX_LIB_HARDWARE && rhs->implType == MFX_LIB_HARDWARE) {
+        return 1;
+    }
+    if (lhs->implType == MFX_LIB_HARDWARE && rhs->implType != MFX_LIB_HARDWARE) {
+        return -1;
+    }
+
+    // prefer integrated GPU
+    if (lhs->mediaAdapterType != MFX_MEDIA_INTEGRATED &&
+        rhs->mediaAdapterType == MFX_MEDIA_INTEGRATED) {
+        return 1;
+    }
+    if (lhs->mediaAdapterType == MFX_MEDIA_INTEGRATED &&
+        rhs->mediaAdapterType != MFX_MEDIA_INTEGRATED) {
+        return -1;
+    }
+
+    // prefer dll with lower API version
+    if (lhs->actualApiVersion < rhs->actualApiVersion) {
+        return -1;
+    }
+    if (rhs->actualApiVersion < lhs->actualApiVersion) {
+        return 1;
+    }
+
+    // if versions are equal prefer library with HW
+    if (lhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION && rhs->loadStatus == MFX_ERR_NONE) {
+        return 1;
+    }
+    if (lhs->loadStatus == MFX_ERR_NONE && rhs->loadStatus == MFX_WRN_PARTIAL_ACCELERATION) {
+        return -1;
+    }
+
+    return 0;
+}
+
+mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session) {
+    MFX::MFXAutomaticCriticalSection guard(&dispGuard);
+
+    DISPATCHER_LOG_BLOCK(("MFXInitEx (impl=%s, pVer=%d.%d, ExternalThreads=%d session=0x%p\n",
+                          DispatcherLog_GetMFXImplString(par.Implementation).c_str(),
+                          par.Version.Major,
+                          par.Version.Minor,
+                          par.ExternalThreads,
+                          session));
+
+    mfxStatus mfxRes = MFX_ERR_UNSUPPORTED;
+    HandleVector allocatedHandle;
+    VectorHandleGuard handleGuard(allocatedHandle);
+
+    MFX_DISP_HANDLE_EX *pHandle;
+    wchar_t dllName[MFX_MAX_DLL_PATH] = { 0 };
+    MFX::MFXLibraryIterator libIterator;
+
+    // there iterators are used only if the caller specified implicit type like AUTO
+    mfxU32 curImplIdx, maxImplIdx;
+    // implementation method masked from the input parameter
+    // special case for audio library
+    const mfxIMPL implMethod = par.Implementation & (MFX_IMPL_VIA_ANY - 1);
+
+    // implementation interface masked from the input parameter
+    mfxIMPL implInterface      = par.Implementation & -MFX_IMPL_VIA_ANY;
+    mfxIMPL implInterfaceOrig  = implInterface;
+    mfxVersion requiredVersion = { { MFX_VERSION_MINOR, MFX_VERSION_MAJOR } };
+
+    mfxInitializationParam vplParam = {};
+    if (implMethod == MFX_IMPL_SOFTWARE) {
+        vplParam.AccelerationMode = MFX_ACCEL_MODE_NA;
+    }
+    else {
+        // hardware - D3D11 by default
+        if (implInterface == MFX_IMPL_VIA_D3D9)
+            vplParam.AccelerationMode = MFX_ACCEL_MODE_VIA_D3D9;
+        else
+            vplParam.AccelerationMode = MFX_ACCEL_MODE_VIA_D3D11;
+    }
+
+    // check error(s)
+    if (NULL == session) {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    if (((MFX_IMPL_AUTO > implMethod) || (MFX_IMPL_RUNTIME < implMethod))) {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // set the minimal required version
+    requiredVersion = par.Version;
+
+    try {
+        // reset the session value
+        *session = 0;
+
+        // allocate the dispatching handle and call-table
+        pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
+    }
+    catch (...) {
+        return MFX_ERR_MEMORY_ALLOC;
+    }
+
+    DISPATCHER_LOG_INFO(
+        (("Required API version is %u.%u\n"), requiredVersion.Major, requiredVersion.Minor));
+    // particular implementation value
+    mfxIMPL curImpl;
+
+    // Load HW library or RT from system location
+    curImplIdx = implTypesRange[implMethod].minIndex;
+    maxImplIdx = implTypesRange[implMethod].maxIndex;
+    do {
+        int currentStorage = MFX::MFX_STORAGE_ID_FIRST;
+        implInterface      = implInterfaceOrig;
+        do {
+            // this storage will be checked below
+            if (currentStorage == MFX::MFX_APP_FOLDER) {
+                currentStorage += 1;
+                continue;
+            }
+
+            // initialize the library iterator
+            mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
+                                      implInterface,
+                                      implTypes[curImplIdx].adapterID,
+                                      currentStorage);
+
+            // look through the list of installed SDK version,
+            // looking for a suitable library with higher merit value.
+            if (MFX_ERR_NONE == mfxRes) {
+                if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType &&
+                    (!implInterface || MFX_IMPL_VIA_ANY == implInterface)) {
+                    implInterface = libIterator.GetImplementationType();
+                }
+
+                do {
+                    eMfxImplType implType = implTypes[curImplIdx].implType;
+
+                    // select a desired DLL
+                    mfxRes = libIterator.SelectDLLVersion(dllName,
+                                                          sizeof(dllName) / sizeof(dllName[0]),
+                                                          &implType,
+                                                          pHandle->apiVersion);
+                    if (MFX_ERR_NONE != mfxRes) {
+                        break;
+                    }
+                    DISPATCHER_LOG_INFO((("loading library %S\n"), dllName));
+                    // try to load the selected DLL
+                    curImpl = implTypes[curImplIdx].impl;
+                    mfxRes  = pHandle->LoadSelectedDLL(dllName,
+                                                      implType,
+                                                      curImpl,
+                                                      implInterface,
+                                                      par,
+                                                      vplParam);
+                    // unload the failed DLL
+                    if (MFX_ERR_NONE != mfxRes) {
+                        pHandle->Close();
+                        continue;
+                    }
+
+                    mfxPlatform platform = { MFX_PLATFORM_UNKNOWN, 0, MFX_MEDIA_UNKNOWN };
+                    if (pHandle->callTable[eMFXVideoCORE_QueryPlatform]) {
+                        mfxRes = MFXVideoCORE_QueryPlatform((mfxSession)pHandle, &platform);
+                        if (MFX_ERR_NONE != mfxRes) {
+                            DISPATCHER_LOG_WRN(
+                                ("MFXVideoCORE_QueryPlatform failed, rejecting loaded library\n"));
+                            pHandle->Close();
+                            continue;
+                        }
+                    }
+                    pHandle->mediaAdapterType = platform.MediaAdapterType;
+                    DISPATCHER_LOG_INFO(
+                        (("media adapter type is %d\n"), pHandle->mediaAdapterType));
+
+                    libIterator.GetSubKeyName(
+                        pHandle->subkeyName,
+                        sizeof(pHandle->subkeyName) / sizeof(pHandle->subkeyName[0]));
+                    pHandle->storageID = libIterator.GetStorageID();
+                    allocatedHandle.push_back(pHandle);
+                    pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
+                } while (MFX_ERR_NONE != mfxRes);
+            }
+
+            // select another place for loading engine
+            currentStorage += 1;
+
+        } while ((MFX_ERR_NONE != mfxRes) && (MFX::MFX_STORAGE_ID_LAST >= currentStorage));
+
+    } while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx));
+
+    curImplIdx = implTypesRange[implMethod].minIndex;
+    maxImplIdx = implTypesRange[implMethod].maxIndex;
+
+    // Load RT from app folder (libmfxsw64 with API >= 1.10)
+    do {
+        implInterface = implInterfaceOrig;
+        // initialize the library iterator
+        mfxRes = libIterator.Init(implTypes[curImplIdx].implType,
+                                  implInterface,
+                                  implTypes[curImplIdx].adapterID,
+                                  MFX::MFX_APP_FOLDER);
+
+        if (MFX_ERR_NONE == mfxRes) {
+            if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType &&
+                (!implInterface || MFX_IMPL_VIA_ANY == implInterface)) {
+                implInterface = libIterator.GetImplementationType();
+            }
+
+            do {
+                eMfxImplType implType;
+
+                // select a desired DLL
+                mfxRes = libIterator.SelectDLLVersion(dllName,
+                                                      sizeof(dllName) / sizeof(dllName[0]),
+                                                      &implType,
+                                                      pHandle->apiVersion);
+                if (MFX_ERR_NONE != mfxRes) {
+                    break;
+                }
+                DISPATCHER_LOG_INFO((("loading library %S\n"), dllName));
+
+                // try to load the selected DLL
+                curImpl = implTypes[curImplIdx].impl;
+                mfxRes  = pHandle->LoadSelectedDLL(dllName,
+                                                  implType,
+                                                  curImpl,
+                                                  implInterface,
+                                                  par,
+                                                  vplParam);
+                // unload the failed DLL
+                if (MFX_ERR_NONE != mfxRes) {
+                    pHandle->Close();
+                }
+                else {
+                    if (pHandle->actualApiVersion.Major == 1 &&
+                        pHandle->actualApiVersion.Minor <= 9) {
+                        // this is not RT, skip it
+                        mfxRes = MFX_ERR_ABORTED;
+                        break;
+                    }
+                    pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
+                    allocatedHandle.push_back(pHandle);
+                    pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
+                }
+
+            } while (MFX_ERR_NONE != mfxRes);
+        }
+    } while ((MFX_ERR_NONE != mfxRes) && (++curImplIdx <= maxImplIdx));
+
+    // Load HW and SW libraries using legacy default DLL search mechanism
+    // set current library index again
+    curImplIdx = implTypesRange[implMethod].minIndex;
+    do {
+        implInterface = implInterfaceOrig;
+
+        mfxRes = MFX::mfx_get_default_dll_name(dllName,
+                                               sizeof(dllName) / sizeof(dllName[0]),
+                                               implTypes[curImplIdx].implType);
+
+        if (MFX_ERR_NONE == mfxRes) {
+            DISPATCHER_LOG_INFO((("loading default library %S\n"), dllName))
+
+            // try to load the selected DLL using default DLL search mechanism
+            if (MFX_LIB_HARDWARE == implTypes[curImplIdx].implType) {
+                if (!implInterface) {
+                    implInterface = MFX_IMPL_VIA_ANY;
+                }
+                mfxU32 curVendorID = 0, curDeviceID = 0;
+                mfxRes = MFX::SelectImplementationType(implTypes[curImplIdx].adapterID,
+                                                       &implInterface,
+                                                       &curVendorID,
+                                                       &curDeviceID);
+                if (curVendorID != INTEL_VENDOR_ID)
+                    mfxRes = MFX_ERR_UNKNOWN;
+            }
+            if (MFX_ERR_NONE == mfxRes) {
+                // try to load the selected DLL using default DLL search mechanism
+                mfxRes = pHandle->LoadSelectedDLL(dllName,
+                                                  implTypes[curImplIdx].implType,
+                                                  implTypes[curImplIdx].impl,
+                                                  implInterface,
+                                                  par,
+                                                  vplParam);
+            }
+            // unload the failed DLL
+            if ((MFX_ERR_NONE != mfxRes) && (MFX_WRN_PARTIAL_ACCELERATION != mfxRes)) {
+                pHandle->Close();
+            }
+            else {
+                pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
+                allocatedHandle.push_back(pHandle);
+                pHandle = new MFX_DISP_HANDLE_EX(requiredVersion);
+            }
+        }
+    } while ((MFX_ERR_NONE > mfxRes) && (++curImplIdx <= maxImplIdx));
+    delete pHandle;
+
+    if (allocatedHandle.size() == 0)
+        return MFX_ERR_UNSUPPORTED;
+
+    { // sort candidate list
+        bool NeedSort                = false;
+        HandleVector::iterator first = allocatedHandle.begin(), it = allocatedHandle.begin(),
+                               et = allocatedHandle.end();
+        for (it++; it != et; ++it)
+            if (HandleSort(&(*first), &(*it)) != 0)
+                NeedSort = true;
+
+        // sort allocatedHandle so that the most preferred dll is at the beginning
+        if (NeedSort)
+            qsort(&(*allocatedHandle.begin()),
+                  allocatedHandle.size(),
+                  sizeof(MFX_DISP_HANDLE_EX *),
+                  &HandleSort);
+    }
+    HandleVector::iterator candidate = allocatedHandle.begin();
+    // check the final result of loading
+    try {
+        pHandle = *candidate;
+        //pulling up current mediasdk version, that required to match plugin version
+        //block for now to avoid KW scanning failure (UNUSED)
+        //mfxVersion apiVerActual = { { 0, 0 } };
+        //mfxStatus stsQueryVersion =
+        //    MFXQueryVersion((mfxSession)pHandle, &apiVerActual);
+    }
+    catch (...) {
+        DISPATCHER_LOG_ERROR((("unknown exception while loading plugins\n")))
+    }
+
+    // everything is OK. Save pointers to the output variable
+    *candidate = 0; // keep this one safe from guard destructor
+
+    //===================================
+
+    // MFXVideoCORE_QueryPlatform call creates d3d device handle, so we have handle right after MFXInit and can't accept external handle
+    // This is a workaround which calls close-init to remove that handle
+
+    mfxFunctionPointer *actualTable = pHandle->callTable;
+    mfxFunctionPointer pFunc;
+
+    pFunc  = actualTable[eMFXClose];
+    mfxRes = (*(mfxStatus(MFX_CDECL *)(mfxSession))pFunc)(pHandle->session);
+    if (mfxRes != MFX_ERR_NONE)
+        return mfxRes;
+
+    pHandle->session = 0;
+    bool callOldInit = !actualTable[eMFXInitEx];
+    pFunc            = actualTable[(callOldInit) ? eMFXInit : eMFXInitEx];
+
+    mfxVersion version(pHandle->apiVersion);
+    if (callOldInit) {
+        pHandle->loadStatus = (*(mfxStatus(MFX_CDECL *)(mfxIMPL, mfxVersion *, mfxSession *))pFunc)(
+            pHandle->impl | pHandle->implInterface,
+            &version,
+            &pHandle->session);
+    }
+    else {
+        mfxInitParam initPar   = par;
+        initPar.Implementation = pHandle->impl | pHandle->implInterface;
+        initPar.Version        = version;
+        pHandle->loadStatus =
+            (*(mfxStatus(MFX_CDECL *)(mfxInitParam, mfxSession *))pFunc)(initPar,
+                                                                         &pHandle->session);
+    }
+
+    //===================================
+
+    *((MFX_DISP_HANDLE_EX **)session) = pHandle;
+
+    return pHandle->loadStatus;
+
+} // mfxStatus MFXInitEx(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
+
+// internal function - load a specific DLL, return unsupported if it fails
+// vplParam is required for API >= 2.0 (load via MFXInitialize)
+mfxStatus MFXInitEx2(mfxVersion version,
+                     mfxInitializationParam vplParam,
+                     mfxIMPL hwImpl,
+                     mfxSession *session,
+                     mfxU16 *deviceID,
+                     wchar_t *dllName) {
+    MFX::MFXAutomaticCriticalSection guard(&dispGuard);
+
+    mfxStatus mfxRes = MFX_ERR_NONE;
+    HandleVector allocatedHandle;
+    VectorHandleGuard handleGuard(allocatedHandle);
+
+    MFX_DISP_HANDLE *pHandle;
+
+    *deviceID = 0;
+
+    // fill minimal 1.x parameters for LoadSelectedDLL to choose correct initialization path
+    mfxInitParam par = {};
+    par.Version      = version;
+
+    // select first adapter if not specified
+    // only relevant for MSDK-via-MFXLoad path
+    if (!hwImpl)
+        hwImpl = MFX_IMPL_HARDWARE;
+
+    switch (vplParam.AccelerationMode) {
+        case MFX_ACCEL_MODE_NA:
+            par.Implementation = MFX_IMPL_SOFTWARE;
+            break;
+        case MFX_ACCEL_MODE_VIA_D3D9:
+            par.Implementation = hwImpl | MFX_IMPL_VIA_D3D9;
+            break;
+        case MFX_ACCEL_MODE_VIA_D3D11:
+            par.Implementation = hwImpl | MFX_IMPL_VIA_D3D11;
+            break;
+        case MFX_ACCEL_MODE_VIA_VAAPI:
+            par.Implementation = hwImpl | MFX_IMPL_VIA_VAAPI;
+            break;
+        default:
+            par.Implementation = hwImpl;
+            break;
+    }
+
+    // also pass extBuf array (if any) to MFXInitEx for 1.x API
+    par.NumExtParam = vplParam.NumExtParam;
+    par.ExtParam    = (vplParam.NumExtParam ? vplParam.ExtParam : nullptr);
+
+    eMfxImplType implType =
+        (par.Implementation == MFX_IMPL_SOFTWARE ? MFX_LIB_SOFTWARE : MFX_LIB_HARDWARE);
+    mfxIMPL implInterface    = par.Implementation & -MFX_IMPL_VIA_ANY;
+    const mfxIMPL implMethod = par.Implementation & (MFX_IMPL_VIA_ANY - 1);
+
+    // check error(s)
+    if (NULL == session || NULL == dllName) {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    try {
+        // reset the session value
+        *session = 0;
+
+        // allocate the dispatching handle and call-table
+        pHandle = new MFX_DISP_HANDLE(par.Version);
+    }
+    catch (...) {
+        return MFX_ERR_MEMORY_ALLOC;
+    }
+
+    if (MFX_ERR_NONE == mfxRes) {
+        DISPATCHER_LOG_INFO((("loading default library %S\n"), dllName))
+
+        if (MFX_ERR_NONE == mfxRes) {
+            // try to load the selected DLL using given DLL name
+            mfxRes = pHandle->LoadSelectedDLL(dllName,
+                                              implType,
+                                              implMethod,
+                                              implInterface,
+                                              par,
+                                              vplParam);
+        }
+        // unload the failed DLL
+        if (MFX_ERR_NONE != mfxRes) {
+            pHandle->Close();
+            delete pHandle;
+            return MFX_ERR_UNSUPPORTED;
+        }
+        else {
+            pHandle->storageID = MFX::MFX_UNKNOWN_KEY;
+        }
+    }
+
+    // everything is OK. Save pointers to the output variable
+    *((MFX_DISP_HANDLE **)session) = pHandle;
+
+    return pHandle->loadStatus;
+}
+
+mfxStatus MFXClose(mfxSession session) {
+    MFX::MFXAutomaticCriticalSection guard(&dispGuard);
+
+    mfxStatus mfxRes         = MFX_ERR_INVALID_HANDLE;
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *)session;
+
+    // check error(s)
+    if (pHandle) {
+        try {
+            // unload the DLL library
+            mfxRes = pHandle->Close();
+
+            // it is possible, that there is an active child session.
+            // can't unload library in that case.
+            if (MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes) {
+                // release the handle
+                delete pHandle;
+            }
+        }
+        catch (...) {
+            mfxRes = MFX_ERR_INVALID_HANDLE;
+        }
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFXClose(mfxSession session)
+
+#else // relates to !defined (MEDIASDK_UWP_DISPATCHER), i.e. #else part as if MEDIASDK_UWP_DISPATCHER defined
+
+static mfxModuleHandle hModule;
+
+// for the UWP_DISPATCHER purposes implementation of MFXinitEx is calling
+// InitialiseMediaSession() implemented in intel_gfx_api.dll
+mfxStatus MFXInitEx(mfxInitParam par, mfxSession *session) {
+    #if defined(MEDIASDK_ARM_LOADER)
+
+    return MFX_ERR_UNSUPPORTED;
+
+    #else
+
+    wchar_t IntelGFXAPIdllName[MFX_MAX_DLL_PATH] = { 0 };
+    mfxI32 adapterNum                            = -1;
+
+    switch (par.Implementation & 0xf) {
+        case MFX_IMPL_SOFTWARE:
+        #if (MFX_VERSION >= MFX_VERSION_NEXT)
+        case MFX_IMPL_SINGLE_THREAD:
+        #endif
+            return MFX_ERR_UNSUPPORTED;
+        case MFX_IMPL_AUTO:
+        case MFX_IMPL_HARDWARE:
+            adapterNum = 0;
+            break;
+        case MFX_IMPL_HARDWARE2:
+            adapterNum = 1;
+            break;
+        case MFX_IMPL_HARDWARE3:
+            adapterNum = 2;
+            break;
+        case MFX_IMPL_HARDWARE4:
+            adapterNum = 3;
+            break;
+        default:
+            return GfxApiInitPriorityIntegrated(par, session, hModule);
+    }
+
+    return GfxApiInitByAdapterNum(par, adapterNum, session, hModule);
+
+    #endif
+}
+
+// for the UWP_DISPATCHER purposes implementation of MFXClose is calling
+// DisposeMediaSession() implemented in intel_gfx_api.dll
+mfxStatus MFXClose(mfxSession session) {
+    if (NULL == session) {
+        return MFX_ERR_INVALID_HANDLE;
+    }
+
+    mfxStatus sts = MFX_ERR_NONE;
+
+    #if defined(MEDIASDK_ARM_LOADER)
+
+    sts = MFX_ERR_UNSUPPORTED;
+
+    #else
+
+    sts = GfxApiClose(session, hModule);
+
+    #endif
+
+    session = (mfxSession)NULL;
+    return sts;
+}
+
+    #undef FUNCTION
+    #define FUNCTION(return_value, func_name, formal_param_list, actual_param_list)               \
+        return_value func_name formal_param_list {                                                \
+            mfxStatus mfxRes = MFX_ERR_INVALID_HANDLE;                                            \
+                                                                                                  \
+            _mfxSession *pHandle = (_mfxSession *)session;                                        \
+                                                                                                  \
+            /* get the function's address and make a call */                                      \
+            if (pHandle) {                                                                        \
+                mfxFunctionPointer pFunc = pHandle->callPlugInsTable[e##func_name];               \
+                if (pFunc) {                                                                      \
+                    /* pass down the call */                                                      \
+                    mfxRes = (*(mfxStatus(MFX_CDECL *) formal_param_list)pFunc)actual_param_list; \
+                }                                                                                 \
+            }                                                                                     \
+            return mfxRes;                                                                        \
+        }
+
+FUNCTION(mfxStatus,
+         MFXVideoUSER_Load,
+         (mfxSession session, const mfxPluginUID *uid, mfxU32 version),
+         (session, uid, version))
+FUNCTION(
+    mfxStatus,
+    MFXVideoUSER_LoadByPath,
+    (mfxSession session, const mfxPluginUID *uid, mfxU32 version, const mfxChar *path, mfxU32 len),
+    (session, uid, version, path, len))
+FUNCTION(mfxStatus,
+         MFXVideoUSER_UnLoad,
+         (mfxSession session, const mfxPluginUID *uid),
+         (session, uid))
+FUNCTION(mfxStatus,
+         MFXAudioUSER_Load,
+         (mfxSession session, const mfxPluginUID *uid, mfxU32 version),
+         (session, uid, version))
+FUNCTION(mfxStatus,
+         MFXAudioUSER_UnLoad,
+         (mfxSession session, const mfxPluginUID *uid),
+         (session, uid))
+
+#endif //!defined(MEDIASDK_UWP_DISPATCHER)
+
+mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session) {
+    mfxStatus mfxRes              = MFX_ERR_INVALID_HANDLE;
+    MFX_DISP_HANDLE *pHandle      = (MFX_DISP_HANDLE *)session;
+    MFX_DISP_HANDLE *pChildHandle = (MFX_DISP_HANDLE *)child_session;
+
+    // get the function's address and make a call
+    if ((pHandle) && (pChildHandle) &&
+        (pHandle->actualApiVersion == pChildHandle->actualApiVersion)) {
+        /* check whether it is audio session or video */
+        int tableIndex = eMFXJoinSession;
+        mfxFunctionPointer pFunc;
+        pFunc = pHandle->callTable[tableIndex];
+
+        if (pFunc) {
+            // pass down the call
+            mfxRes =
+                (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxSession))pFunc)(pHandle->session,
+                                                                         pChildHandle->session);
+        }
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFXJoinSession(mfxSession session, mfxSession child_session)
+
+mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone) {
+    mfxStatus mfxRes         = MFX_ERR_INVALID_HANDLE;
+    MFX_DISP_HANDLE *pHandle = (MFX_DISP_HANDLE *)session;
+    mfxVersion apiVersion;
+    mfxIMPL impl;
+
+    // check error(s)
+    if (pHandle) {
+        // initialize the clone session
+        // currently supported for 1.x API only
+        // for 2.x runtimes, need to use RT implementation (passthrough)
+        apiVersion = pHandle->apiVersion;
+        if (apiVersion.Major == 1) {
+            impl   = pHandle->impl | pHandle->implInterface;
+            mfxRes = MFXInit(impl, &apiVersion, clone);
+            if (MFX_ERR_NONE != mfxRes) {
+                return mfxRes;
+            }
+
+            // join the sessions
+            mfxRes = MFXJoinSession(session, *clone);
+            if (MFX_ERR_NONE != mfxRes) {
+                MFXClose(*clone);
+                *clone = NULL;
+                return mfxRes;
+            }
+        }
+        else {
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone)
+
+mfxStatus MFXInit(mfxIMPL impl, mfxVersion *pVer, mfxSession *session) {
+    mfxInitParam par = {};
+
+    par.Implementation = impl;
+    if (pVer) {
+        par.Version = *pVer;
+    }
+    else {
+        par.Version.Major = DEFAULT_API_VERSION_MAJOR;
+        par.Version.Minor = DEFAULT_API_VERSION_MINOR;
+    }
+    par.ExternalThreads = 0;
+
+    return MFXInitEx(par, session);
+}
+
+// passthrough functions to implementation
+mfxStatus MFXMemory_GetSurfaceForVPP(mfxSession session, mfxFrameSurface1 **surface) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForVPP];
+    if (pFunc) {
+        session = pHandle->session;
+        sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXMemory_GetSurfaceForVPPOut(mfxSession session, mfxFrameSurface1 **surface) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForVPPOut];
+    if (pFunc) {
+        session = pHandle->session;
+        sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXMemory_GetSurfaceForEncode(mfxSession session, mfxFrameSurface1 **surface) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForEncode];
+    if (pFunc) {
+        session = pHandle->session;
+        sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXMemory_GetSurfaceForDecode(mfxSession session, mfxFrameSurface1 **surface) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXMemory_GetSurfaceForDecode];
+    if (pFunc) {
+        session = pHandle->session;
+        sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 **))pFunc)(session, surface);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXVideoDECODE_VPP_Init(mfxSession session,
+                                  mfxVideoParam *decode_par,
+                                  mfxVideoChannelParam **vpp_par_array,
+                                  mfxU32 num_vpp_par) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_Init];
+    if (pFunc) {
+        session = pHandle->session;
+        sts =
+            (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxVideoParam *, mfxVideoChannelParam **, mfxU32))
+                 pFunc)(session, decode_par, vpp_par_array, num_vpp_par);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXVideoDECODE_VPP_DecodeFrameAsync(mfxSession session,
+                                              mfxBitstream *bs,
+                                              mfxU32 *skip_channels,
+                                              mfxU32 num_skip_channels,
+                                              mfxSurfaceArray **surf_array_out) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_DecodeFrameAsync];
+    if (pFunc) {
+        session = pHandle->session;
+        sts     = (*(mfxStatus(
+            MFX_CDECL *)(mfxSession, mfxBitstream *, mfxU32 *, mfxU32, mfxSurfaceArray **))
+                   pFunc)(session, bs, skip_channels, num_skip_channels, surf_array_out);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXVideoDECODE_VPP_Reset(mfxSession session,
+                                   mfxVideoParam *decode_par,
+                                   mfxVideoChannelParam **vpp_par_array,
+                                   mfxU32 num_vpp_par) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_Reset];
+    if (pFunc) {
+        session = pHandle->session;
+        sts =
+            (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxVideoParam *, mfxVideoChannelParam **, mfxU32))
+                 pFunc)(session, decode_par, vpp_par_array, num_vpp_par);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXVideoDECODE_VPP_GetChannelParam(mfxSession session,
+                                             mfxVideoChannelParam *par,
+                                             mfxU32 channel_id) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_GetChannelParam];
+    if (pFunc) {
+        session = pHandle->session;
+        sts     = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxVideoChannelParam *, mfxU32))pFunc)(
+            session,
+            par,
+            channel_id);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXVideoDECODE_VPP_Close(mfxSession session) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXVideoDECODE_VPP_Close];
+    if (pFunc) {
+        session = pHandle->session;
+        sts     = (*(mfxStatus(MFX_CDECL *)(mfxSession))pFunc)(session);
+    }
+
+    return sts;
+}
+
+mfxStatus MFXVideoVPP_ProcessFrameAsync(mfxSession session,
+                                        mfxFrameSurface1 *in,
+                                        mfxFrameSurface1 **out) {
+    mfxStatus sts = MFX_ERR_INVALID_HANDLE;
+
+    if (!session)
+        return MFX_ERR_INVALID_HANDLE;
+
+    struct _mfxSession *pHandle = (struct _mfxSession *)session;
+
+    mfxFunctionPointer pFunc;
+    pFunc = pHandle->callVideoTable2[eMFXVideoVPP_ProcessFrameAsync];
+    if (pFunc) {
+        session = pHandle->session;
+        sts = (*(mfxStatus(MFX_CDECL *)(mfxSession, mfxFrameSurface1 *, mfxFrameSurface1 **))pFunc)(
+            session,
+            in,
+            out);
+    }
+
+    return sts;
+}
+
+//
+//
+// implement all other calling functions.
+// They just call a procedure of DLL library from the table.
+//
+
+// define for common functions (from mfxsession.h)
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list)               \
+    return_value func_name formal_param_list {                                                \
+        mfxStatus mfxRes     = MFX_ERR_INVALID_HANDLE;                                        \
+        _mfxSession *pHandle = (_mfxSession *)session;                                        \
+        /* get the function's address and make a call */                                      \
+        if (pHandle) {                                                                        \
+            /* check whether it is audio session or video */                                  \
+            int tableIndex = e##func_name;                                                    \
+            mfxFunctionPointer pFunc;                                                         \
+            pFunc = pHandle->callTable[tableIndex];                                           \
+            if (pFunc) {                                                                      \
+                /* get the real session pointer */                                            \
+                session = pHandle->session;                                                   \
+                /* pass down the call */                                                      \
+                mfxRes = (*(mfxStatus(MFX_CDECL *) formal_param_list)pFunc)actual_param_list; \
+            }                                                                                 \
+        }                                                                                     \
+        return mfxRes;                                                                        \
+    }
+
+FUNCTION(mfxStatus, MFXQueryIMPL, (mfxSession session, mfxIMPL *impl), (session, impl))
+FUNCTION(mfxStatus, MFXQueryVersion, (mfxSession session, mfxVersion *version), (session, version))
+
+// these functions are not necessary in LOADER part of dispatcher and
+// need to be included only in in SOLID dispatcher or PROCTABLE part of dispatcher
+
+FUNCTION(mfxStatus, MFXDisjoinSession, (mfxSession session), (session))
+FUNCTION(mfxStatus, MFXSetPriority, (mfxSession session, mfxPriority priority), (session, priority))
+FUNCTION(mfxStatus,
+         MFXGetPriority,
+         (mfxSession session, mfxPriority *priority),
+         (session, priority))
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list)               \
+    return_value func_name formal_param_list {                                                \
+        mfxStatus mfxRes     = MFX_ERR_INVALID_HANDLE;                                        \
+        _mfxSession *pHandle = (_mfxSession *)session;                                        \
+        /* get the function's address and make a call */                                      \
+        if (pHandle) {                                                                        \
+            mfxFunctionPointer pFunc = pHandle->callTable[e##func_name];                      \
+            if (pFunc) {                                                                      \
+                /* get the real session pointer */                                            \
+                session = pHandle->session;                                                   \
+                /* pass down the call */                                                      \
+                mfxRes = (*(mfxStatus(MFX_CDECL *) formal_param_list)pFunc)actual_param_list; \
+            }                                                                                 \
+        }                                                                                     \
+        return mfxRes;                                                                        \
+    }
+
+#include "windows/mfx_exposed_functions_list.h"
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_critical_section.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_critical_section.cpp
new file mode 100644 (file)
index 0000000..7e37214
--- /dev/null
@@ -0,0 +1,49 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "windows/mfx_critical_section.h"
+
+#include <windows.h>
+// SDK re-declares the following functions with different call declarator.
+// We don't need them. Just redefine them to nothing.
+#define _interlockedbittestandset     fake_set
+#define _interlockedbittestandreset   fake_reset
+#define _interlockedbittestandset64   fake_set64
+#define _interlockedbittestandreset64 fake_reset64
+#include <intrin.h>
+
+#define MFX_WAIT() SwitchToThread()
+
+// static section of the file
+namespace {
+
+enum { MFX_SC_IS_FREE = 0, MFX_SC_IS_TAKEN = 1 };
+
+} // namespace
+
+namespace MFX {
+
+mfxU32 mfxInterlockedCas32(mfxCriticalSection *pCSection,
+                           mfxU32 value_to_exchange,
+                           mfxU32 value_to_compare) {
+    return _InterlockedCompareExchange(pCSection, value_to_exchange, value_to_compare);
+}
+
+mfxU32 mfxInterlockedXchg32(mfxCriticalSection *pCSection, mfxU32 value) {
+    return _InterlockedExchange(pCSection, value);
+}
+
+void mfxEnterCriticalSection(mfxCriticalSection *pCSection) {
+    while (MFX_SC_IS_TAKEN == mfxInterlockedCas32(pCSection, MFX_SC_IS_TAKEN, MFX_SC_IS_FREE)) {
+        MFX_WAIT();
+    }
+} // void mfxEnterCriticalSection(mfxCriticalSection *pCSection)
+
+void mfxLeaveCriticalSection(mfxCriticalSection *pCSection) {
+    mfxInterlockedXchg32(pCSection, MFX_SC_IS_FREE);
+} // void mfxLeaveCriticalSection(mfxCriticalSection *pCSection)
+
+} // namespace MFX
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_critical_section.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_critical_section.h
new file mode 100644 (file)
index 0000000..cdb5a8f
--- /dev/null
@@ -0,0 +1,48 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFX_CRITICAL_SECTION_H_
+#define DISPATCHER_WINDOWS_MFX_CRITICAL_SECTION_H_
+
+#include "vpl/mfxdefs.h"
+
+namespace MFX {
+
+// Just set "critical section" instance to zero for initialization.
+typedef volatile mfxL32 mfxCriticalSection;
+
+// Enter the global critical section.
+void mfxEnterCriticalSection(mfxCriticalSection *pCSection);
+
+// Leave the global critical section.
+void mfxLeaveCriticalSection(mfxCriticalSection *pCSection);
+
+class MFXAutomaticCriticalSection {
+public:
+    // Constructor
+    explicit MFXAutomaticCriticalSection(mfxCriticalSection *pCSection) {
+        m_pCSection = pCSection;
+        mfxEnterCriticalSection(m_pCSection);
+    }
+
+    // Destructor
+    ~MFXAutomaticCriticalSection() {
+        mfxLeaveCriticalSection(m_pCSection);
+    }
+
+protected:
+    // Pointer to a critical section
+    mfxCriticalSection *m_pCSection;
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    MFXAutomaticCriticalSection(const MFXAutomaticCriticalSection &);
+    void operator=(const MFXAutomaticCriticalSection &);
+};
+
+} // namespace MFX
+
+#endif // DISPATCHER_WINDOWS_MFX_CRITICAL_SECTION_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher.cpp
new file mode 100644 (file)
index 0000000..1453e57
--- /dev/null
@@ -0,0 +1,600 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "windows/mfx_dispatcher.h"
+#include "windows/mfx_dispatcher_log.h"
+#include "windows/mfx_load_dll.h"
+
+#include <assert.h>
+
+#include <string.h>
+#include <windows.h>
+
+#include <algorithm>
+#include "vpl/mfxadapter.h"
+#include "windows/mfx_dxva2_device.h"
+#include "windows/mfx_vector.h"
+#include "windows/mfxvideo++.h"
+
+#if _MSC_VER
+    #pragma warning(disable : 4355)
+#endif
+
+MFX_DISP_HANDLE::MFX_DISP_HANDLE(const mfxVersion requiredVersion)
+        : _mfxSession(),
+          apiVersion(requiredVersion) {
+    actualApiVersion.Version = 0;
+    implType                 = MFX_LIB_SOFTWARE;
+    impl                     = MFX_IMPL_SOFTWARE;
+    loadStatus               = MFX_ERR_NOT_FOUND;
+    dispVersion.Major        = MFX_DISPATCHER_VERSION_MAJOR;
+    dispVersion.Minor        = MFX_DISPATCHER_VERSION_MINOR;
+    storageID                = 0;
+    implInterface            = MFX_IMPL_HARDWARE_ANY;
+
+    hModule = (mfxModuleHandle)0;
+
+} // MFX_DISP_HANDLE::MFX_DISP_HANDLE(const mfxVersion requiredVersion)
+
+MFX_DISP_HANDLE::~MFX_DISP_HANDLE(void) {
+    Close();
+
+} // MFX_DISP_HANDLE::~MFX_DISP_HANDLE(void)
+
+mfxStatus MFX_DISP_HANDLE::Close(void) {
+    mfxStatus mfxRes;
+
+    mfxRes = UnLoadSelectedDLL();
+
+    // need to reset dispatcher state after unloading dll
+    if (MFX_ERR_NONE == mfxRes) {
+        implType                          = MFX_LIB_SOFTWARE;
+        impl                              = MFX_IMPL_SOFTWARE;
+        loadStatus                        = MFX_ERR_NOT_FOUND;
+        dispVersion.Major                 = MFX_DISPATCHER_VERSION_MAJOR;
+        dispVersion.Minor                 = MFX_DISPATCHER_VERSION_MINOR;
+        *static_cast<_mfxSession *>(this) = _mfxSession();
+        hModule                           = (mfxModuleHandle)0;
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFX_DISP_HANDLE::Close(void)
+
+mfxStatus MFX_DISP_HANDLE::LoadSelectedDLL(const wchar_t *pPath,
+                                           eMfxImplType reqImplType,
+                                           mfxIMPL reqImpl,
+                                           mfxIMPL reqImplInterface,
+                                           mfxInitParam &par,
+                                           mfxInitializationParam &vplParam) {
+    mfxStatus mfxRes = MFX_ERR_NONE;
+
+    // check error(s)
+    if ((MFX_LIB_SOFTWARE != reqImplType) && (MFX_LIB_HARDWARE != reqImplType)) {
+        DISPATCHER_LOG_ERROR(
+            (("implType == %s, should be either MFX_LIB_SOFTWARE ot MFX_LIB_HARDWARE\n"),
+             DispatcherLog_GetMFXImplString(reqImplType).c_str()));
+        loadStatus = MFX_ERR_ABORTED;
+        return loadStatus;
+    }
+    // only exact types of implementation is allowed
+    if ((MFX_IMPL_SOFTWARE != reqImpl) && (MFX_IMPL_HARDWARE != reqImpl) &&
+        (MFX_IMPL_HARDWARE2 != reqImpl) && (MFX_IMPL_HARDWARE3 != reqImpl) &&
+        (MFX_IMPL_HARDWARE4 != reqImpl)) {
+        DISPATCHER_LOG_ERROR((("invalid implementation impl == %s\n"),
+                              DispatcherLog_GetMFXImplString(impl).c_str()));
+        loadStatus = MFX_ERR_ABORTED;
+        return loadStatus;
+    }
+    // only mfxExtThreadsParam is allowed
+    if (par.NumExtParam) {
+        if ((par.NumExtParam > 1) || !par.ExtParam) {
+            loadStatus = MFX_ERR_ABORTED;
+            return loadStatus;
+        }
+        if ((par.ExtParam[0]->BufferId != MFX_EXTBUFF_THREADS_PARAM) ||
+            (par.ExtParam[0]->BufferSz != sizeof(mfxExtThreadsParam))) {
+            loadStatus = MFX_ERR_ABORTED;
+            return loadStatus;
+        }
+    }
+
+    // close the handle before initialization
+    Close();
+
+    // save the library's type
+    this->implType      = reqImplType;
+    this->impl          = reqImpl;
+    this->implInterface = reqImplInterface;
+
+    {
+        assert(hModule == (mfxModuleHandle)0);
+        DISPATCHER_LOG_BLOCK(("invoking LoadLibrary(%S)\n", pPath));
+
+        // load the DLL into the memory
+        hModule = MFX::mfx_dll_load(pPath);
+
+        if (hModule) {
+            int i;
+
+            DISPATCHER_LOG_OPERATION({
+                wchar_t modulePath[1024];
+                GetModuleFileNameW((HMODULE)hModule,
+                                   modulePath,
+                                   sizeof(modulePath) / sizeof(modulePath[0]));
+                DISPATCHER_LOG_INFO((("loaded module %S\n"), modulePath))
+            });
+
+            // load video functions: pointers to exposed functions
+            for (i = 0; i < eVideoFuncTotal; i += 1) {
+                mfxFunctionPointer pProc =
+                    (mfxFunctionPointer)MFX::mfx_dll_get_addr(hModule, APIFunc[i].pName);
+                if (pProc) {
+                    // function exists in the library,
+                    // save the pointer.
+                    callTable[i] = pProc;
+                }
+                else {
+                    // The library doesn't contain the function
+                    DISPATCHER_LOG_WRN((("Can't find API function \"%s\"\n"), APIFunc[i].pName));
+                    if (apiVersion.Version >= APIFunc[i].apiVersion.Version) {
+                        DISPATCHER_LOG_ERROR((("\"%s\" is required for API %u.%u\n"),
+                                              APIFunc[i].pName,
+                                              apiVersion.Major,
+                                              apiVersion.Minor));
+                        mfxRes = MFX_ERR_UNSUPPORTED;
+                        break;
+                    }
+                }
+            }
+
+            // if version >= 2.0, load these functions as well
+            if (apiVersion.Major >= 2) {
+                for (i = 0; i < eVideoFunc2Total; i += 1) {
+                    mfxFunctionPointer pProc =
+                        (mfxFunctionPointer)MFX::mfx_dll_get_addr(hModule, APIVideoFunc2[i].pName);
+                    if (pProc) {
+                        // function exists in the library,
+                        // save the pointer.
+                        callVideoTable2[i] = pProc;
+                    }
+                    else {
+                        // The library doesn't contain the function
+                        DISPATCHER_LOG_WRN(
+                            (("Can't find API function \"%s\"\n"), APIVideoFunc2[i].pName));
+                        if (apiVersion.Version >= APIVideoFunc2[i].apiVersion.Version) {
+                            DISPATCHER_LOG_ERROR((("\"%s\" is required for API %u.%u\n"),
+                                                  APIVideoFunc2[i].pName,
+                                                  apiVersion.Major,
+                                                  apiVersion.Minor));
+                            mfxRes = MFX_ERR_UNSUPPORTED;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        else {
+            DISPATCHER_LOG_WRN((("can't find DLL: GetLastErr()=0x%x\n"), GetLastError()))
+            mfxRes = MFX_ERR_UNSUPPORTED;
+        }
+    }
+
+    // initialize the loaded DLL
+    if (MFX_ERR_NONE == mfxRes) {
+        mfxVersion version(apiVersion);
+
+        if (version.Major >= 2) {
+            // for API >= 2.0 call MFXInitialize instead of MFXInitEx
+            int tableIndex           = eMFXInitialize;
+            mfxFunctionPointer pFunc = callVideoTable2[tableIndex];
+
+            // filled-in mfxInitializationParam must be provided for MFXInitialize path
+            mfxRes =
+                (*(mfxStatus(MFX_CDECL *)(mfxInitializationParam, mfxSession *))pFunc)(vplParam,
+                                                                                       &session);
+        }
+        else {
+            // Call old-style MFXInit init for older libraries
+            bool callOldInit =
+                !callTable[eMFXInitEx]; // if true call eMFXInit, if false - eMFXInitEx
+            int tableIndex           = (callOldInit) ? eMFXInit : eMFXInitEx;
+            mfxFunctionPointer pFunc = callTable[tableIndex];
+
+            if (callOldInit) {
+                DISPATCHER_LOG_BLOCK(("MFXInit(%s,ver=%u.%u,session=0x%p)\n",
+                                      DispatcherLog_GetMFXImplString(impl | implInterface).c_str(),
+                                      apiVersion.Major,
+                                      apiVersion.Minor,
+                                      &session));
+
+                mfxRes = (*(mfxStatus(MFX_CDECL *)(mfxIMPL, mfxVersion *, mfxSession *))pFunc)(
+                    impl | implInterface,
+                    &version,
+                    &session);
+            }
+            else {
+                DISPATCHER_LOG_BLOCK(("MFXInitEx(%s,ver=%u.%u,ExtThreads=%d,session=0x%p)\n",
+                                      DispatcherLog_GetMFXImplString(impl | implInterface).c_str(),
+                                      apiVersion.Major,
+                                      apiVersion.Minor,
+                                      par.ExternalThreads,
+                                      &session));
+
+                mfxInitParam initPar = par;
+                // adjusting user parameters
+                initPar.Implementation = impl | implInterface;
+                initPar.Version        = version;
+                mfxRes =
+                    (*(mfxStatus(MFX_CDECL *)(mfxInitParam, mfxSession *))pFunc)(initPar, &session);
+            }
+        }
+
+        if (MFX_ERR_NONE != mfxRes) {
+            DISPATCHER_LOG_WRN((("library can't be load. MFXInit returned %s \n"),
+                                DispatcherLog_GetMFXStatusString(mfxRes)))
+        }
+        else {
+            mfxRes = MFXQueryVersion((mfxSession)this, &actualApiVersion);
+
+            if (MFX_ERR_NONE != mfxRes) {
+                DISPATCHER_LOG_ERROR(
+                    (("MFXQueryVersion returned: %d, skiped this library\n"), mfxRes))
+            }
+            else {
+                DISPATCHER_LOG_INFO((("MFXQueryVersion returned API: %d.%d\n"),
+                                     actualApiVersion.Major,
+                                     actualApiVersion.Minor))
+                //special hook for applications that uses sink api to get loaded library path
+                DISPATCHER_LOG_LIBRARY(("%p", hModule));
+                DISPATCHER_LOG_INFO(("library loaded succesfully\n"))
+            }
+        }
+    }
+
+    loadStatus = mfxRes;
+    return mfxRes;
+
+} // mfxStatus MFX_DISP_HANDLE::LoadSelectedDLL(const wchar_t* pPath, eMfxImplType reqImplType, mfxIMPL reqImpl, mfxIMPL reqImplInterface, mfxInitParam& par, mfxInitializationParam &vplParam)
+
+mfxStatus MFX_DISP_HANDLE::UnLoadSelectedDLL(void) {
+    mfxStatus mfxRes = MFX_ERR_NONE;
+
+    // close the loaded DLL
+    if (session) {
+        /* check whether it is audio session or video */
+        int tableIndex = eMFXClose;
+        mfxFunctionPointer pFunc;
+        pFunc = callTable[tableIndex];
+
+        mfxRes = (*(mfxStatus(MFX_CDECL *)(mfxSession))pFunc)(session);
+        if (MFX_ERR_NONE == mfxRes) {
+            session = (mfxSession)0;
+        }
+
+        DISPATCHER_LOG_INFO((("MFXClose(0x%x) returned %d\n"), session, mfxRes));
+        // actually, the return value is required to pass outside only.
+    }
+
+    // it is possible, that there is an active child session.
+    // can't unload library in that case.
+    if ((MFX_ERR_UNDEFINED_BEHAVIOR != mfxRes) && (hModule)) {
+        // unload the library.
+        if (!MFX::mfx_dll_free(hModule)) {
+            mfxRes = MFX_ERR_UNDEFINED_BEHAVIOR;
+        }
+        hModule = (mfxModuleHandle)0;
+    }
+
+    return mfxRes;
+
+} // mfxStatus MFX_DISP_HANDLE::UnLoadSelectedDLL(void)
+
+MFX_DISP_HANDLE_EX::MFX_DISP_HANDLE_EX(const mfxVersion requiredVersion)
+        : MFX_DISP_HANDLE(requiredVersion),
+          mediaAdapterType(MFX_MEDIA_UNKNOWN) {}
+
+#if (defined(_WIN64) || defined(_WIN32)) && (MFX_VERSION >= 1031)
+static mfxStatus InitDummySession(mfxU32 adapter_n, MFXVideoSession &dummy_session) {
+    mfxInitParam initPar;
+    memset(&initPar, 0, sizeof(initPar));
+
+    initPar.Version.Major = 1;
+    initPar.Version.Minor = 0;
+
+    switch (adapter_n) {
+        case 0:
+            initPar.Implementation = MFX_IMPL_HARDWARE;
+            break;
+        case 1:
+            initPar.Implementation = MFX_IMPL_HARDWARE2;
+            break;
+        case 2:
+            initPar.Implementation = MFX_IMPL_HARDWARE3;
+            break;
+        case 3:
+            initPar.Implementation = MFX_IMPL_HARDWARE4;
+            break;
+
+        default:
+            // try searching on all display adapters
+            initPar.Implementation = MFX_IMPL_HARDWARE_ANY;
+            break;
+    }
+
+    initPar.Implementation |= MFX_IMPL_VIA_D3D11;
+
+    return dummy_session.InitEx(initPar);
+}
+
+static inline bool is_iGPU(const mfxAdapterInfo &adapter_info) {
+    return adapter_info.Platform.MediaAdapterType == MFX_MEDIA_INTEGRATED;
+}
+
+static inline bool is_dGPU(const mfxAdapterInfo &adapter_info) {
+    return adapter_info.Platform.MediaAdapterType == MFX_MEDIA_DISCRETE;
+}
+
+// This function implies that iGPU has higher priority
+static inline mfxI32 iGPU_priority(const void *ll, const void *rr) {
+    const mfxAdapterInfo &l = *(reinterpret_cast<const mfxAdapterInfo *>(ll));
+    const mfxAdapterInfo &r = *(reinterpret_cast<const mfxAdapterInfo *>(rr));
+
+    if ((is_iGPU(l) && is_iGPU(r)) || (is_dGPU(l) && is_dGPU(r)))
+        return 0;
+
+    if (is_iGPU(l) && is_dGPU(r))
+        return -1;
+
+    // The only combination left is_dGPU(l) && is_iGPU(r))
+    return 1;
+}
+
+static void RearrangeInPriorityOrder(const mfxComponentInfo &info,
+                                     MFX::MFXVector<mfxAdapterInfo> &vec) {
+    (void)info;
+    {
+        // Move iGPU to top priority
+        qsort(vec.data(), vec.size(), sizeof(mfxAdapterInfo), &iGPU_priority);
+    }
+}
+
+static mfxStatus PrepareAdaptersInfo(const mfxComponentInfo *info,
+                                     MFX::MFXVector<mfxAdapterInfo> &vec,
+                                     mfxAdaptersInfo &adapters) {
+    // No suitable adapters on system to handle user's workload
+    if (vec.empty()) {
+        adapters.NumActual = 0;
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    if (info) {
+        RearrangeInPriorityOrder(*info, vec);
+    }
+
+    mfxU32 num_to_copy = (std::min)(mfxU32(vec.size()), adapters.NumAlloc);
+    for (mfxU32 i = 0; i < num_to_copy; ++i) {
+        adapters.Adapters[i] = vec[i];
+    }
+
+    adapters.NumActual = num_to_copy;
+
+    if (vec.size() > adapters.NumAlloc) {
+        return MFX_WRN_OUT_OF_RANGE;
+    }
+
+    return MFX_ERR_NONE;
+}
+
+static inline bool QueryAdapterInfo(mfxU32 adapter_n, mfxU32 &VendorID, mfxU32 &DeviceID) {
+    MFX::DXVA2Device dxvaDevice;
+
+    if (!dxvaDevice.InitDXGI1(adapter_n))
+        return false;
+
+    VendorID = dxvaDevice.GetVendorID();
+    DeviceID = dxvaDevice.GetDeviceID();
+
+    return true;
+}
+
+static inline mfxU32 MakeVersion(mfxU16 major, mfxU16 minor) {
+    return major * 1000 + minor;
+}
+
+mfxStatus MFXQueryAdaptersDecode(mfxBitstream *bitstream,
+                                 mfxU32 codec_id,
+                                 mfxAdaptersInfo *adapters) {
+    if (!adapters || !bitstream)
+        return MFX_ERR_NULL_PTR;
+
+    MFX::MFXVector<mfxAdapterInfo> obtained_info;
+
+    mfxU32 adapter_n = 0, VendorID, DeviceID;
+
+    mfxComponentInfo input_info;
+    memset(&input_info, 0, sizeof(input_info));
+    input_info.Type                     = mfxComponentType::MFX_COMPONENT_DECODE;
+    input_info.Requirements.mfx.CodecId = codec_id;
+
+    for (;;) {
+        if (!QueryAdapterInfo(adapter_n, VendorID, DeviceID))
+            break;
+
+        ++adapter_n;
+
+        if (VendorID != INTEL_VENDOR_ID)
+            continue;
+
+        // Check if requested capabilities are supported
+        MFXVideoSession dummy_session;
+
+        mfxStatus sts = InitDummySession(adapter_n - 1, dummy_session);
+        if (sts != MFX_ERR_NONE) {
+            continue;
+        }
+
+        mfxVideoParam stream_params, out;
+        memset(&out, 0, sizeof(out));
+        memset(&stream_params, 0, sizeof(stream_params));
+        out.mfx.CodecId = stream_params.mfx.CodecId = codec_id;
+
+        sts = MFXVideoDECODE_DecodeHeader(dummy_session.operator mfxSession(),
+                                          bitstream,
+                                          &stream_params);
+
+        if (sts != MFX_ERR_NONE) {
+            continue;
+        }
+
+        sts = MFXVideoDECODE_Query(dummy_session.operator mfxSession(), &stream_params, &out);
+
+        if (sts !=
+            MFX_ERR_NONE) // skip MFX_ERR_UNSUPPORTED as well as MFX_WRN_INCOMPATIBLE_VIDEO_PARAM
+            continue;
+
+        mfxAdapterInfo info;
+        memset(&info, 0, sizeof(info));
+
+        //WA for initialization when application built w/ new API, but lib w/ old one.
+        mfxVersion apiVersion;
+        sts = dummy_session.QueryVersion(&apiVersion);
+        if (sts != MFX_ERR_NONE)
+            continue;
+
+        mfxU32 version = MakeVersion(apiVersion.Major, apiVersion.Minor);
+
+        if (version >= 1019) {
+            sts = MFXVideoCORE_QueryPlatform(dummy_session.operator mfxSession(), &info.Platform);
+
+            if (sts != MFX_ERR_NONE) {
+                continue;
+            }
+        }
+        else {
+            // for API versions greater than 1.19 Device id is set inside QueryPlatform call
+            info.Platform.DeviceId = static_cast<mfxU16>(DeviceID);
+        }
+
+        info.Number = adapter_n - 1;
+
+        obtained_info.push_back(info);
+    }
+
+    return PrepareAdaptersInfo(&input_info, obtained_info, *adapters);
+}
+
+mfxStatus MFXQueryAdapters(mfxComponentInfo *input_info, mfxAdaptersInfo *adapters) {
+    if (!adapters)
+        return MFX_ERR_NULL_PTR;
+
+    MFX::MFXVector<mfxAdapterInfo> obtained_info;
+    //obtained_info.reserve(adapters->NumAdaptersAlloc);
+
+    mfxU32 adapter_n = 0, VendorID, DeviceID;
+
+    for (;;) {
+        if (!QueryAdapterInfo(adapter_n, VendorID, DeviceID))
+            break;
+
+        ++adapter_n;
+
+        if (VendorID != INTEL_VENDOR_ID)
+            continue;
+
+        // Check if requested capabilities are supported
+        MFXVideoSession dummy_session;
+
+        mfxStatus sts = InitDummySession(adapter_n - 1, dummy_session);
+        if (sts != MFX_ERR_NONE) {
+            continue;
+        }
+
+        // If input_info is NULL just return all Intel adapters and information about them
+        if (input_info) {
+            mfxVideoParam out;
+            memset(&out, 0, sizeof(out));
+
+            switch (input_info->Type) {
+                case mfxComponentType::MFX_COMPONENT_ENCODE: {
+                    out.mfx.CodecId = input_info->Requirements.mfx.CodecId;
+
+                    sts = MFXVideoENCODE_Query(dummy_session.operator mfxSession(),
+                                               &input_info->Requirements,
+                                               &out);
+                } break;
+                case mfxComponentType::MFX_COMPONENT_DECODE: {
+                    out.mfx.CodecId = input_info->Requirements.mfx.CodecId;
+
+                    sts = MFXVideoDECODE_Query(dummy_session.operator mfxSession(),
+                                               &input_info->Requirements,
+                                               &out);
+                } break;
+                case mfxComponentType::MFX_COMPONENT_VPP: {
+                    sts = MFXVideoVPP_Query(dummy_session.operator mfxSession(),
+                                            &input_info->Requirements,
+                                            &out);
+                } break;
+                default:
+                    sts = MFX_ERR_UNSUPPORTED;
+            }
+        }
+
+        if (sts !=
+            MFX_ERR_NONE) // skip MFX_ERR_UNSUPPORTED as well as MFX_WRN_INCOMPATIBLE_VIDEO_PARAM
+            continue;
+
+        mfxAdapterInfo info;
+        memset(&info, 0, sizeof(info));
+
+        //WA for initialization when application built w/ new API, but lib w/ old one.
+        mfxVersion apiVersion;
+        sts = dummy_session.QueryVersion(&apiVersion);
+        if (sts != MFX_ERR_NONE)
+            continue;
+
+        mfxU32 version = MakeVersion(apiVersion.Major, apiVersion.Minor);
+
+        if (version >= 1019) {
+            sts = MFXVideoCORE_QueryPlatform(dummy_session.operator mfxSession(), &info.Platform);
+
+            if (sts != MFX_ERR_NONE) {
+                continue;
+            }
+        }
+        else {
+            // for API versions greater than 1.19 Device id is set inside QueryPlatform call
+            info.Platform.DeviceId = static_cast<mfxU16>(DeviceID);
+        }
+
+        info.Number = adapter_n - 1;
+
+        obtained_info.push_back(info);
+    }
+
+    return PrepareAdaptersInfo(input_info, obtained_info, *adapters);
+}
+
+mfxStatus MFXQueryAdaptersNumber(mfxU32 *num_adapters) {
+    if (!num_adapters)
+        return MFX_ERR_NULL_PTR;
+
+    mfxU32 intel_adapter_count = 0, VendorID, DeviceID;
+
+    for (mfxU32 cur_adapter = 0;; ++cur_adapter) {
+        if (!QueryAdapterInfo(cur_adapter, VendorID, DeviceID))
+            break;
+
+        if (VendorID == INTEL_VENDOR_ID)
+            ++intel_adapter_count;
+    }
+
+    *num_adapters = intel_adapter_count;
+
+    return MFX_ERR_NONE;
+}
+
+#endif // (defined(_WIN64) || defined(_WIN32)) && (MFX_VERSION >= 1031)
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher.h
new file mode 100644 (file)
index 0000000..eabc6ad
--- /dev/null
@@ -0,0 +1,201 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFX_DISPATCHER_H_
+#define DISPATCHER_WINDOWS_MFX_DISPATCHER_H_
+
+#include <stddef.h>
+
+#include "vpl/mfxdispatcher.h"
+#include "vpl/mfxvideo.h"
+
+#include "windows/mfx_dispatcher_defs.h"
+
+#define INTEL_VENDOR_ID 0x8086
+
+mfxStatus MFXQueryVersion(mfxSession session, mfxVersion *version);
+
+enum {
+    // to avoid code changing versions are just inherited
+    // from the API header file.
+    DEFAULT_API_VERSION_MAJOR = MFX_VERSION_MAJOR,
+    DEFAULT_API_VERSION_MINOR = MFX_VERSION_MINOR
+};
+
+enum { VPL_MINIMUM_VERSION_MAJOR = 2, VPL_MINIMUM_VERSION_MINOR = 0 };
+
+//
+// declare functions' integer identifiers.
+//
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) e##func_name,
+
+enum eFunc {
+    eMFXInit,
+    eMFXClose,
+    eMFXQueryIMPL,
+    eMFXQueryVersion,
+    eMFXJoinSession,
+    eMFXDisjoinSession,
+    eMFXCloneSession,
+    eMFXSetPriority,
+    eMFXGetPriority,
+    eMFXInitEx,
+#include "windows/mfx_exposed_functions_list.h"
+    eVideoFuncTotal
+};
+
+enum ePluginFunc {
+    eMFXVideoUSER_Load,
+    eMFXVideoUSER_LoadByPath,
+    eMFXVideoUSER_UnLoad,
+    eMFXAudioUSER_Load,
+    eMFXAudioUSER_UnLoad,
+    ePluginFuncTotal
+};
+
+enum eVideoFunc2 {
+    // 2.0
+    eMFXQueryImplsDescription,
+    eMFXReleaseImplDescription,
+    eMFXMemory_GetSurfaceForVPP,
+    eMFXMemory_GetSurfaceForEncode,
+    eMFXMemory_GetSurfaceForDecode,
+    eMFXInitialize,
+
+    // 2.1
+    eMFXMemory_GetSurfaceForVPPOut,
+    eMFXVideoDECODE_VPP_Init,
+    eMFXVideoDECODE_VPP_DecodeFrameAsync,
+    eMFXVideoDECODE_VPP_Reset,
+    eMFXVideoDECODE_VPP_GetChannelParam,
+    eMFXVideoDECODE_VPP_Close,
+    eMFXVideoVPP_ProcessFrameAsync,
+
+    eVideoFunc2Total
+};
+
+// declare max buffer length for regsitry key name
+enum { MFX_MAX_REGISTRY_KEY_NAME = 256 };
+
+// declare the maximum DLL path
+enum { MFX_MAX_DLL_PATH = 1024 };
+
+// declare library's implementation types
+enum eMfxImplType {
+    MFX_LIB_HARDWARE = 0,
+    MFX_LIB_SOFTWARE = 1,
+    MFX_LIB_PSEUDO   = 2,
+
+    MFX_LIB_IMPL_TYPES
+};
+
+// declare dispatcher's version
+enum { MFX_DISPATCHER_VERSION_MAJOR = 1, MFX_DISPATCHER_VERSION_MINOR = 3 };
+
+struct _mfxSession {
+    // A real handle from MFX engine passed to a called function
+    mfxSession session;
+
+    mfxFunctionPointer callTable[eVideoFuncTotal]; // NOLINT(runtime/arrays)
+    mfxFunctionPointer callPlugInsTable[ePluginFuncTotal]; // NOLINT(runtime/arrays)
+    mfxFunctionPointer callVideoTable2[eVideoFunc2Total]; // NOLINT(runtime/arrays)
+
+    // Current library's implementation (exact implementation)
+    mfxIMPL impl;
+};
+
+// declare a dispatcher's handle
+struct MFX_DISP_HANDLE : public _mfxSession {
+    // Default constructor
+    explicit MFX_DISP_HANDLE(const mfxVersion requiredVersion);
+    // Destructor
+    ~MFX_DISP_HANDLE(void);
+
+    // Load the library's module
+    mfxStatus LoadSelectedDLL(const wchar_t *pPath,
+                              eMfxImplType implType,
+                              mfxIMPL impl,
+                              mfxIMPL implInterface,
+                              mfxInitParam &par,
+                              mfxInitializationParam &vplParam);
+    // Unload the library's module
+    mfxStatus UnLoadSelectedDLL(void);
+
+    // Close the handle
+    mfxStatus Close(void);
+
+    // NOTE: changing order of struct's members can make different version of
+    // dispatchers incompatible. Think of different modules (e.g. MFT filters)
+    // within a single application.
+
+    // Library's implementation type (hardware or software)
+    eMfxImplType implType;
+    // Current library's VIA interface
+    mfxIMPL implInterface;
+    // Dispatcher's version. If version is 1.1 or lower, then old dispatcher's
+    // architecture is used. Otherwise it means current dispatcher's version.
+    mfxVersion dispVersion;
+    // Required API version of session initialized
+    const mfxVersion apiVersion;
+    // Actual library API version
+    mfxVersion actualApiVersion;
+    // Status of loaded dll
+    mfxStatus loadStatus;
+    // Resgistry subkey name for windows version
+    wchar_t subkeyName[MFX_MAX_REGISTRY_KEY_NAME];
+    // Storage ID for windows version
+    int storageID;
+
+    // Library's module handle
+    mfxModuleHandle hModule;
+
+private:
+    // Declare assignment operator and copy constructor to prevent occasional assignment
+    MFX_DISP_HANDLE(const MFX_DISP_HANDLE &);
+    MFX_DISP_HANDLE &operator=(const MFX_DISP_HANDLE &);
+};
+
+// This struct extends MFX_DISP_HANDLE, we cannot extend MFX_DISP_HANDLE itself due to possible compatibility issues
+// This struct was added in dispatcher version 1.3
+// Check dispatcher handle's version when you cast session struct which came from outside of MSDK API function to this
+struct MFX_DISP_HANDLE_EX : public MFX_DISP_HANDLE {
+    explicit MFX_DISP_HANDLE_EX(const mfxVersion requiredVersion);
+
+    mfxU16 mediaAdapterType;
+    mfxU16 reserved[10];
+};
+
+// declare comparison operator
+inline bool operator==(const mfxVersion &one, const mfxVersion &two) {
+    return (one.Version == two.Version);
+}
+
+inline bool operator<(const mfxVersion &one, const mfxVersion &two) {
+    return (one.Major < two.Major) || ((one.Major == two.Major) && (one.Minor < two.Minor));
+}
+
+inline bool operator<=(const mfxVersion &one, const mfxVersion &two) {
+    return (one == two) || (one < two);
+}
+
+//
+// declare a table with functions descriptions
+//
+
+typedef struct FUNCTION_DESCRIPTION {
+    // Literal function's name
+    const char *pName;
+    // API version when function appeared first time
+    mfxVersion apiVersion;
+} FUNCTION_DESCRIPTION;
+
+extern const FUNCTION_DESCRIPTION APIFunc[eVideoFuncTotal];
+
+extern const FUNCTION_DESCRIPTION APIVideoFunc2[eVideoFunc2Total];
+
+#endif // DISPATCHER_WINDOWS_MFX_DISPATCHER_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_defs.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_defs.h
new file mode 100644 (file)
index 0000000..fc148c6
--- /dev/null
@@ -0,0 +1,37 @@
+/*############################################################################
+  # Copyright (C) 2013-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#pragma once
+#include <cstdio>
+#include <cstring>
+#include "vpl/mfxdefs.h"
+
+#if defined(MFX_DISPATCHER_LOG)
+    #include <string.h>
+    #include <string>
+#endif
+
+#define MAX_PLUGIN_PATH 4096
+#define MAX_PLUGIN_NAME 4096
+
+#if _MSC_VER < 1400
+    #define wcscpy_s(to, to_size, from) \
+        (void)(to_size);                \
+        wcscpy(to, from)
+    #define wcscat_s(to, to_size, from) \
+        (void)(to_size);                \
+        wcscat(to, from)
+#endif
+
+// declare library module's handle
+typedef void *mfxModuleHandle;
+
+typedef void(MFX_CDECL *mfxFunctionPointer)(void);
+
+// Tracer uses lib loading from Program Files logic (via Dispatch reg key) to make dispatcher load tracer dll.
+// With DriverStore loading put at 1st place, dispatcher loads real lib before it finds tracer dll.
+// This workaround explicitly checks tracer presence in Dispatch reg key and loads tracer dll before the search for lib in all other places.
+#define MFX_TRACER_WA_FOR_DS 1
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_log.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_log.cpp
new file mode 100644 (file)
index 0000000..6465e4f
--- /dev/null
@@ -0,0 +1,366 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#if defined(MFX_DISPATCHER_LOG)
+
+    #include "windows/mfx_dispatcher_log.h"
+    #include <windows.h>
+    #include "vpl/mfxstructures.h"
+    #if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+        #include <evntprov.h>
+        #include <winmeta.h>
+    #endif
+    #include <stdarg.h>
+    #include <algorithm>
+    #include <sstream>
+    #include <string>
+
+struct CodeStringTable {
+    int code;
+    const char *string;
+} LevelStrings[] = { { DL_INFO, "INFO:   " }, { DL_WRN, "WARNING:" }, { DL_ERROR, "ERROR:  " } };
+
+    #define DEFINE_CODE(code) \
+        { code, #code }
+
+static CodeStringTable StringsOfImpl[] = {
+    DEFINE_CODE(MFX_IMPL_AUTO),         DEFINE_CODE(MFX_IMPL_SOFTWARE),
+    DEFINE_CODE(MFX_IMPL_HARDWARE),     DEFINE_CODE(MFX_IMPL_AUTO_ANY),
+    DEFINE_CODE(MFX_IMPL_HARDWARE_ANY), DEFINE_CODE(MFX_IMPL_HARDWARE2),
+    DEFINE_CODE(MFX_IMPL_HARDWARE3),    DEFINE_CODE(MFX_IMPL_HARDWARE4),
+
+    DEFINE_CODE(MFX_IMPL_UNSUPPORTED)
+};
+
+static CodeStringTable StringsOfImplVIA[] = {
+    DEFINE_CODE(MFX_IMPL_VIA_ANY),
+    DEFINE_CODE(MFX_IMPL_VIA_D3D9),
+    DEFINE_CODE(MFX_IMPL_VIA_D3D11),
+};
+
+static CodeStringTable StringsOfStatus[] = {
+    DEFINE_CODE(MFX_ERR_NONE),
+    DEFINE_CODE(MFX_ERR_UNKNOWN),
+    DEFINE_CODE(MFX_ERR_NULL_PTR),
+    DEFINE_CODE(MFX_ERR_UNSUPPORTED),
+    DEFINE_CODE(MFX_ERR_MEMORY_ALLOC),
+    DEFINE_CODE(MFX_ERR_NOT_ENOUGH_BUFFER),
+    DEFINE_CODE(MFX_ERR_INVALID_HANDLE),
+    DEFINE_CODE(MFX_ERR_LOCK_MEMORY),
+    DEFINE_CODE(MFX_ERR_NOT_INITIALIZED),
+    DEFINE_CODE(MFX_ERR_NOT_FOUND),
+    DEFINE_CODE(MFX_ERR_MORE_DATA),
+    DEFINE_CODE(MFX_ERR_MORE_SURFACE),
+    DEFINE_CODE(MFX_ERR_ABORTED),
+    DEFINE_CODE(MFX_ERR_DEVICE_LOST),
+    DEFINE_CODE(MFX_ERR_INCOMPATIBLE_VIDEO_PARAM),
+    DEFINE_CODE(MFX_ERR_INVALID_VIDEO_PARAM),
+    DEFINE_CODE(MFX_ERR_UNDEFINED_BEHAVIOR),
+    DEFINE_CODE(MFX_ERR_DEVICE_FAILED),
+    DEFINE_CODE(MFX_WRN_IN_EXECUTION),
+    DEFINE_CODE(MFX_WRN_DEVICE_BUSY),
+    DEFINE_CODE(MFX_WRN_VIDEO_PARAM_CHANGED),
+    DEFINE_CODE(MFX_WRN_PARTIAL_ACCELERATION),
+    DEFINE_CODE(MFX_WRN_INCOMPATIBLE_VIDEO_PARAM),
+    DEFINE_CODE(MFX_WRN_VALUE_NOT_CHANGED),
+    DEFINE_CODE(MFX_WRN_OUT_OF_RANGE),
+
+};
+
+    #define CODE_TO_STRING(code, array) CodeToString(code, array, sizeof(array) / sizeof(array[0]))
+
+const char *CodeToString(int code, CodeStringTable array[], int len) {
+    for (int i = 0; i < len; i++) {
+        if (array[i].code == code)
+            return array[i].string;
+    }
+    return "undef";
+}
+
+std::string DispatcherLog_GetMFXImplString(int impl) {
+    std::string str1 = CODE_TO_STRING(impl & ~(-MFX_IMPL_VIA_ANY), StringsOfImpl);
+    std::string str2 = CODE_TO_STRING(impl & (-MFX_IMPL_VIA_ANY), StringsOfImplVIA);
+
+    return str1 + (str2 == "undef" ? "" : "|" + str2);
+}
+
+const char *DispatcherLog_GetMFXStatusString(int sts) {
+    return CODE_TO_STRING(sts, StringsOfStatus);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+void DispatcherLogBracketsHelper::Write(const char *str, ...) {
+    va_list argsptr;
+    va_start(argsptr, str);
+    DispatchLog::get().Write(m_level, m_opcode, str, argsptr);
+    va_end(argsptr);
+}
+
+void DispatchLogBlockHelper::Write(const char *str, ...) {
+    va_list argsptr;
+    va_start(argsptr, str);
+    DispatchLog::get().Write(m_level, DL_EVENT_START, str, argsptr);
+    va_end(argsptr);
+}
+
+DispatchLogBlockHelper::~DispatchLogBlockHelper() {
+    DispatchLog::get().Write(m_level, DL_EVENT_STOP, NULL, NULL);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+DispatchLog::DispatchLog() : m_DispatcherLogSink(DL_SINK_PRINTF) {}
+
+void DispatchLog::SetSink(int nSink, IMsgHandler *pHandler) {
+    DetachAllSinks();
+    AttachSink(nSink, pHandler);
+}
+
+void DispatchLog::AttachSink(int nsink, IMsgHandler *pHandler) {
+    m_DispatcherLogSink |= nsink;
+    if (NULL != pHandler)
+        m_Recepients.push_back(pHandler);
+}
+
+void DispatchLog::DetachSink(int nsink, IMsgHandler *pHandler) {
+    if (nsink & DL_SINK_IMsgHandler) {
+        m_Recepients.remove(pHandler);
+    }
+
+    m_DispatcherLogSink &= ~nsink;
+}
+
+void DispatchLog::ExchangeSink(int nsink, IMsgHandler *oldHdl, IMsgHandler *newHdl) {
+    if (nsink & DL_SINK_IMsgHandler) {
+        std::list<IMsgHandler *>::iterator it =
+            std::find(m_Recepients.begin(), m_Recepients.end(), oldHdl);
+
+        //cannot exchange in that case
+        if (m_Recepients.end() == it)
+            return;
+
+        *it = newHdl;
+    }
+}
+
+void DispatchLog::DetachAllSinks() {
+    m_Recepients.clear();
+    m_DispatcherLogSink = DL_SINK_NULL;
+}
+
+void DispatchLog::Write(int level, int opcode, const char *msg, va_list argptr) {
+    int sinkTable[] = {
+        DL_SINK_PRINTF,
+        DL_SINK_IMsgHandler,
+    };
+
+    for (size_t i = 0; i < sizeof(sinkTable) / sizeof(sinkTable[0]); i++) {
+        switch (m_DispatcherLogSink & sinkTable[i]) {
+            case DL_SINK_NULL:
+                break;
+
+            case DL_SINK_PRINTF: {
+                char msg_formated[8048] = { 0 };
+
+                if (NULL != msg && level != DL_LOADED_LIBRARY) {
+    #if _MSC_VER >= 1400
+                    vsprintf_s(msg_formated,
+                               sizeof(msg_formated) / sizeof(msg_formated[0]),
+                               msg,
+                               argptr);
+    #else
+                    vsnprintf(msg_formated,
+                              sizeof(msg_formated) / sizeof(msg_formated[0]),
+                              msg,
+                              argptr);
+    #endif
+                    //TODO(XX): improve this , add opcode handling
+                    printf("%s %s", CODE_TO_STRING(level, LevelStrings), msg_formated);
+                }
+                break;
+            }
+
+            case DL_SINK_IMsgHandler: {
+                std::list<IMsgHandler *>::iterator it;
+
+                for (it = m_Recepients.begin(); it != m_Recepients.end(); ++it) {
+                    (*it)->Write(level, opcode, msg, argptr);
+                }
+                break;
+            }
+        }
+    }
+}
+
+    #if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+class ETWHandler : public IMsgHandler {
+public:
+    explicit ETWHandler(const wchar_t *guid_str)
+            : m_bUseFormatter(DISPATCHER_LOG_USE_FORMATING),
+              m_EventHandle(),
+              m_bProviderEnable() {
+        GUID rguid = GUID_NULL;
+        if (FAILED(CLSIDFromString(guid_str, &rguid))) {
+            return;
+        }
+
+        EventRegister(&rguid, NULL, NULL, &m_EventHandle);
+
+        m_bProviderEnable = 0 != EventProviderEnabled(m_EventHandle, 1, 0);
+    }
+
+    ~ETWHandler() {
+        if (m_EventHandle) {
+            EventUnregister(m_EventHandle);
+        }
+    }
+
+    virtual void Write(int level, int opcode, const char *msg, va_list argptr) {
+        //event not registered
+        if (0 == m_EventHandle) {
+            return;
+        }
+        if (!m_bProviderEnable) {
+            return;
+        }
+        if (level == DL_LOADED_LIBRARY) {
+            return;
+        }
+
+        char msg_formated[1024];
+        EVENT_DESCRIPTOR descriptor;
+        EVENT_DATA_DESCRIPTOR data_descriptor;
+
+        EventDescZero(&descriptor);
+
+        descriptor.Opcode = (UCHAR)opcode;
+        descriptor.Level  = (UCHAR)level;
+
+        if (m_bUseFormatter) {
+            if (NULL != msg) {
+        #if _MSC_VER >= 1400
+                vsprintf_s(msg_formated,
+                           sizeof(msg_formated) / sizeof(msg_formated[0]),
+                           msg,
+                           argptr);
+        #else
+                vsnprintf(msg_formated,
+                          sizeof(msg_formated) / sizeof(msg_formated[0]),
+                          msg,
+                          argptr);
+        #endif
+                EventDataDescCreate(&data_descriptor,
+                                    msg_formated,
+                                    (ULONG)(strlen(msg_formated) + 1));
+            }
+            else {
+                EventDataDescCreate(&data_descriptor, NULL, 0);
+            }
+        }
+        else {
+            //TODO(XX): non formated events supports under zbb
+        }
+
+        EventWrite(m_EventHandle, &descriptor, 1, &data_descriptor);
+    }
+
+protected:
+    //we may not use formatter in some cases described in dispatch_log macro
+    //it significantly increases performance by eliminating any vsprintf operations
+    bool m_bUseFormatter;
+    //consumer is attached, dispatcher trace to reduce formating overhead
+    //submits event only if consumer attached
+    bool m_bProviderEnable;
+    REGHANDLE m_EventHandle;
+};
+//
+
+IMsgHandler *ETWHandlerFactory::GetSink(const wchar_t *sguid) {
+    _storage_type::iterator it;
+    it = m_storage.find(sguid);
+    if (it == m_storage.end()) {
+        ETWHandler *handler = new ETWHandler(sguid);
+        _storage_type::_Pairib it_bool =
+            m_storage.insert(_storage_type::value_type(sguid, handler));
+        it = it_bool.first;
+    }
+
+    return it->second;
+}
+
+ETWHandlerFactory::~ETWHandlerFactory() {
+    for
+        each(_storage_type::value_type val in m_storage) {
+            delete val.second;
+        }
+}
+
+class EventRegistrator : public IMsgHandler {
+    const wchar_t *m_sguid;
+
+public:
+    explicit EventRegistrator(const wchar_t *sguid = DISPATCHER_LOG_EVENT_GUID) : m_sguid(sguid) {
+        DispatchLog::get().AttachSink(DL_SINK_IMsgHandler, this);
+    }
+
+    virtual void Write(int level, int opcode, const char *msg, va_list argptr) {
+        //we cannot call attach sink since we may have been called from iteration
+        //we axchanging preserve that placeholding
+        IMsgHandler *pSink = NULL;
+        DispatchLog::get().ExchangeSink(DL_SINK_IMsgHandler,
+                                        this,
+                                        pSink = ETWHandlerFactory::get().GetSink(m_sguid));
+        //need to call only once here all next calls will be done inside dispatcherlog
+        if (NULL != pSink) {
+            pSink->Write(level, opcode, msg, argptr);
+        }
+    }
+};
+    #endif
+
+template <class TSink>
+class SinkRegistrator {};
+
+    #if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+template <>
+class SinkRegistrator<ETWHandlerFactory> {
+public:
+    explicit SinkRegistrator(const wchar_t *sguid = DISPATCHER_LOG_EVENT_GUID) {
+        DispatchLog::get().AttachSink(DL_SINK_IMsgHandler, ETWHandlerFactory::get().GetSink(sguid));
+    }
+};
+    #endif
+
+    #if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER)
+template <>
+class SinkRegistrator<FileSink> {
+public:
+    SinkRegistrator() {
+        DispatchLog::get().AttachSink(DL_SINK_IMsgHandler, &FileSink::get(DISPACTHER_LOG_FW_PATH));
+    }
+};
+
+void FileSink::Write(int level, int /*opcode*/, const char *msg, va_list argptr) {
+    if (NULL != m_hdl && NULL != msg) {
+        fprintf(m_hdl, "%s", CODE_TO_STRING(level, LevelStrings));
+        vfprintf(m_hdl, msg, argptr);
+    }
+}
+    #endif
+
+//////////////////////////////////////////////////////////////////////////
+//singletons initialization section
+
+    #ifdef DISPATCHER_LOG_REGISTER_EVENT_PROVIDER
+static SinkRegistrator<ETWHandlerFactory> g_registrator1;
+    #endif
+
+    #ifdef DISPATCHER_LOG_REGISTER_FILE_WRITER
+static SinkRegistrator<FileSink> g_registrator2;
+    #endif
+
+#endif //(MFX_DISPATCHER_LOG)
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_log.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dispatcher_log.h
new file mode 100644 (file)
index 0000000..1fe31b3
--- /dev/null
@@ -0,0 +1,225 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_
+#define DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_
+
+//////////////////////////////////////////////////////////////////////////
+//dispatcher log (DL) level
+#define DL_INFO           1
+#define DL_WRN            2
+#define DL_ERROR          4
+#define DL_LOADED_LIBRARY 8
+//////////////////////////////////////////////////////////////////////////
+//opcodes used only in events
+enum { DL_EVENT_START = 1, DL_EVENT_STOP, DL_EVENT_MSG };
+//////////////////////////////////////////////////////////////////////////
+#define DL_SINK_NULL        0
+#define DL_SINK_PRINTF      1
+#define DL_SINK_IMsgHandler 2
+
+#define MFXFOURCCTYPE()      "%c%c%c%c"
+#define ZERO_OR_SPACE(value) ((0 == (value)) ? '0' : (value))
+#define MFXU32TOFOURCC(mfxu32)                                                         \
+    ZERO_OR_SPACE((char)(mfxu32 & 0xFF)), ZERO_OR_SPACE((char)((mfxu32 >> 8) & 0xFF)), \
+        ZERO_OR_SPACE((char)((mfxu32 >> 16) & 0xFF)), ZERO_OR_SPACE((char)((mfxu32 >> 24) & 0xFF))
+
+#define MFXGUIDTYPE() "%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X-%X"
+
+#define MFXGUIDTOHEX(guid)                                                                        \
+    (guid)->Data[0], (guid)->Data[1], (guid)->Data[2], (guid)->Data[3], (guid)->Data[4],          \
+        (guid)->Data[5], (guid)->Data[6], (guid)->Data[7], (guid)->Data[8], (guid)->Data[9],      \
+        (guid)->Data[10], (guid)->Data[11], (guid)->Data[12], (guid)->Data[13], (guid)->Data[14], \
+        (guid)->Data[15]
+
+#if defined(MFX_DISPATCHER_LOG)
+
+    //---------------------------setup section------------------------
+    //using of formating instead of variadic macro with NULL end,
+    //leads to more flexibility in format, however constructing string
+    //with vsprintf_s is a time wasting
+    #define DISPATCHER_LOG_USE_FORMATING 1
+
+    //creates unique object, event guid registration, factories on heap
+    //heap reduce stack allocation and reduce reservation time at startup
+    //is a vital if mediasdk wont use
+    #define DISPATCHER_LOG_HEAP_SINGLETONES
+
+    // guid for all dispatcher events
+    #define DISPATCHER_LOG_EVENT_GUID L"{EB0538CC-4FEE-484d-ACEE-1182E9F37A57}"
+
+    //puts a sink into listeners list
+    //#define DISPATCHER_LOG_REGISTER_EVENT_PROVIDER
+
+    //puts a sink into listeners list
+    //#define DISPATCHER_LOG_REGISTER_FILE_WRITER
+    #define DISPACTHER_LOG_FW_PATH "c:\\dispatcher.log"
+
+    #include <stdarg.h>
+    #include <stdio.h>
+
+//callback interface for intercept logging messages
+class IMsgHandler {
+public:
+    virtual ~IMsgHandler() {}
+    virtual void Write(int level, int opcode, const char *msg, va_list argptr) = 0;
+};
+
+    #if DISPATCHER_LOG_USE_FORMATING
+
+        #define DISPATCHER_LOG(lvl, opcode, str)              \
+            {                                                 \
+                DispatcherLogBracketsHelper wrt(lvl, opcode); \
+                wrt.Write str;                                \
+            }
+    #else
+        #define DISPATCHER_LOG_VA_ARGS(...) wrt.Write(__VA_ARGS__, NULL)
+        //WARNING: don't use types that occupy more that 4 bytes in memory
+        //WARNING: don't use %s in format specifier
+        #define DISPATCHER_LOG(lvl, opcode, str)              \
+            {                                                 \
+                DispatcherLogBracketsHelper wrt(lvl, opcode); \
+                DISPATCHER_LOG_VA_ARGS str;                   \
+            }
+    #endif //DISPATCHER_LOG_USE_FORMATING
+
+    #define DISPATCHER_LOG_OPERATION(operation) operation
+
+    #define __name_from_line(name, line) name##line
+    #define _name_from_line(name, line)  __name_from_line(name, line)
+    #define name_from_line(name)         _name_from_line(name, __LINE__)
+
+    #define DISPATCHER_LOG_AUTO(lvl, msg)                        \
+        DispatchLogBlockHelper name_from_line(__auto_log_)(lvl); \
+        name_from_line(__auto_log_).Write msg;
+
+    #include <list>
+    #include <map>
+    #include <memory>
+    #include <string>
+
+template <class T>
+class DSSingleTone {
+public:
+    template <class TParam1>
+    inline static T &get(TParam1 par1) {
+        T *pstored;
+        if (NULL == (pstored = store_or_load())) {
+            return *store_or_load(new T(par1));
+        }
+        return *pstored;
+    }
+
+    inline static T &get() {
+        T *pstored;
+        if (NULL == (pstored = store_or_load())) {
+            return *store_or_load(new T());
+        }
+        return *pstored;
+    }
+
+private:
+    //if obj == NULL, then it load
+    //if obj != NULL then it store obj
+    inline static T *store_or_load(T *obj = NULL) {
+        static std::unique_ptr<T> instance;
+        if (NULL != obj) {
+            instance.reset(obj);
+        }
+        return instance.get();
+    }
+};
+
+class DispatchLog : public DSSingleTone<DispatchLog> {
+    friend class DSSingleTone<DispatchLog>;
+    std::list<IMsgHandler *> m_Recepients;
+    int m_DispatcherLogSink;
+
+public:
+    //sets current sink
+    void SetSink(int nsink, IMsgHandler *pHandler);
+    void AttachSink(int nsink, IMsgHandler *pHandler);
+    void DetachSink(int nsink, IMsgHandler *pHandler);
+    void ExchangeSink(int nsink, IMsgHandler *pOld, IMsgHandler *pNew);
+    void DetachAllSinks();
+    void Write(int level, int opcode, const char *msg, va_list argptr);
+
+protected:
+    DispatchLog();
+};
+
+//allows to push arguments on the stack without declaring them as function parameters
+struct DispatcherLogBracketsHelper {
+    int m_level;
+    int m_opcode;
+    DispatcherLogBracketsHelper(int level, int opcode) : m_level(level), m_opcode(opcode) {}
+    void Write(const char *str, ...);
+};
+
+//auto log on ctor dtor
+struct DispatchLogBlockHelper {
+    int m_level;
+    void Write(const char *str, ...);
+    explicit DispatchLogBlockHelper(int level) : m_level(level) {}
+    ~DispatchLogBlockHelper();
+};
+
+    //----utility sinks-----
+    #if defined(DISPATCHER_LOG_REGISTER_EVENT_PROVIDER)
+class ETWHandlerFactory : public DSSingleTone<ETWHandlerFactory> {
+    friend class DSSingleTone<ETWHandlerFactory>;
+    typedef std::map<std::wstring, IMsgHandler *> _storage_type;
+    _storage_type m_storage;
+
+public:
+    ~ETWHandlerFactory();
+    IMsgHandler *GetSink(const wchar_t *sguid = DISPATCHER_LOG_EVENT_GUID);
+
+protected:
+    ETWHandlerFactory() {}
+};
+    #endif
+
+    #if defined(DISPATCHER_LOG_REGISTER_FILE_WRITER)
+class FileSink : public DSSingleTone<FileSink>, public IMsgHandler {
+    friend class DSSingleTone<FileSink>;
+
+public:
+    virtual void Write(int level, int opcode, const char *msg, va_list argptr);
+    FileSink() : m_hdl(NULL) {}
+    ~FileSink() {
+        if (NULL != m_hdl)
+            fclose(m_hdl);
+    }
+
+private:
+    FILE *m_hdl;
+    explicit FileSink(const std::string &log_file) {
+        fopen_s(&m_hdl, log_file.c_str(), "a");
+    }
+};
+    #endif
+
+//-----utility functions
+//since they are not called outside of macro we can define them here
+std::string DispatcherLog_GetMFXImplString(int impl);
+const char *DispatcherLog_GetMFXStatusString(int sts);
+
+#else // !defined(MFX_DISPATCHER_LOG)
+
+    #define DISPATCHER_LOG(level, opcode, message)
+    #define DISPATCHER_LOG_AUTO(level, message)
+    #define DISPATCHER_LOG_OPERATION(operation)
+
+#endif // !defined(MFX_DISPATCHER_LOG)
+
+#define DISPATCHER_LOG_INFO(msg)    DISPATCHER_LOG(DL_INFO, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_WRN(msg)     DISPATCHER_LOG(DL_WRN, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_ERROR(msg)   DISPATCHER_LOG(DL_ERROR, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_LIBRARY(msg) DISPATCHER_LOG(DL_LOADED_LIBRARY, DL_EVENT_MSG, msg)
+#define DISPATCHER_LOG_BLOCK(msg)   DISPATCHER_LOG_AUTO(DL_INFO, msg)
+
+#endif // DISPATCHER_WINDOWS_MFX_DISPATCHER_LOG_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_driver_store_loader.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_driver_store_loader.cpp
new file mode 100644 (file)
index 0000000..8f27648
--- /dev/null
@@ -0,0 +1,192 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include <tchar.h>
+
+#include "windows/mfx_dispatcher_log.h"
+#include "windows/mfx_driver_store_loader.h"
+#include "windows/mfx_load_dll.h"
+#include "windows/mfx_vector.h"
+
+namespace MFX {
+
+inline bool IsIntelDeviceInstanceID(const wchar_t *DeviceID) {
+    return wcsstr(DeviceID, L"VEN_8086") || wcsstr(DeviceID, L"ven_8086");
+}
+
+inline bool ExctractDeviceID(const wchar_t *descrString, mfxU32 &deviceID) {
+    const wchar_t *begin = wcsstr(descrString, L"DEV_");
+
+    if (!begin) {
+        begin = wcsstr(descrString, L"dev_");
+        if (!begin) {
+            DISPATCHER_LOG_WRN(("exctracting device id: failed to find device id substring\n"));
+            return false;
+        }
+    }
+
+    begin += wcslen(L"DEV_");
+    deviceID = wcstoul(begin, NULL, 16);
+    if (!deviceID) {
+        DISPATCHER_LOG_WRN(("exctracting device id: failed to convert device id str to int\n"));
+        return false;
+    }
+
+    return true;
+}
+
+DriverStoreLoader::DriverStoreLoader(void)
+        : m_moduleCfgMgr(NULL),
+          m_pCM_Get_Device_ID_List_Size(NULL),
+          m_pCM_Get_Device_ID_List(NULL),
+          m_pCM_Locate_DevNode(NULL),
+          m_pCM_Open_DevNode_Key(NULL) {}
+
+DriverStoreLoader::~DriverStoreLoader(void) {}
+
+bool DriverStoreLoader::GetDriverStorePath(wchar_t *path,
+                                           DWORD dwPathSize,
+                                           mfxU32 deviceID,
+                                           const wchar_t *driverKey) {
+    if (path == NULL || dwPathSize == 0) {
+        return false;
+    }
+
+    // Obtain a PnP handle to the Intel graphics adapter
+    CONFIGRET result       = CR_SUCCESS;
+    ULONG DeviceIDListSize = 0;
+    MFXVector<WCHAR> DeviceIDList;
+    wchar_t DisplayGUID[40];
+    DEVINST DeviceInst;
+
+    DISPATCHER_LOG_INFO(("Looking for MediaSDK in DriverStore\n"));
+
+    if (!LoadCfgMgr() || !LoadCmFuncs()) {
+        return false;
+    }
+
+    if (StringFromGUID2(GUID_DEVCLASS_DISPLAY, DisplayGUID, sizeof(DisplayGUID)) == 0) {
+        DISPATCHER_LOG_WRN(("Couldn't prepare string from GUID\n"));
+        return false;
+    }
+
+    do {
+        result =
+            m_pCM_Get_Device_ID_List_Size(&DeviceIDListSize,
+                                          DisplayGUID,
+                                          CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT);
+        if (result != CR_SUCCESS) {
+            break;
+        }
+
+        try {
+            DeviceIDList.resize(DeviceIDListSize);
+        }
+        catch (...) {
+            return false;
+        }
+        result = m_pCM_Get_Device_ID_List(DisplayGUID,
+                                          DeviceIDList.data(),
+                                          DeviceIDListSize,
+                                          CM_GETIDLIST_FILTER_CLASS | CM_GETIDLIST_FILTER_PRESENT);
+
+    } while (result == CR_BUFFER_SMALL);
+
+    if (result != CR_SUCCESS) {
+        return false;
+    }
+
+    //Look for MediaSDK record
+    wchar_t *begin = DeviceIDList.data();
+    wchar_t *end   = begin + DeviceIDList.size();
+    size_t len     = 0;
+
+    for (; (begin < end) && (len = wcslen(begin)) > 0; begin += len + 1) {
+        if (IsIntelDeviceInstanceID(begin)) {
+            mfxU32 curDeviceID = 0;
+            if (!ExctractDeviceID(begin, curDeviceID) || curDeviceID != deviceID) {
+                continue;
+            }
+
+            result = m_pCM_Locate_DevNode(&DeviceInst, begin, CM_LOCATE_DEVNODE_NORMAL);
+            if (result != CR_SUCCESS) {
+                continue;
+            }
+
+            HKEY hKey_sw;
+            result = m_pCM_Open_DevNode_Key(DeviceInst,
+                                            KEY_READ,
+                                            0,
+                                            RegDisposition_OpenExisting,
+                                            &hKey_sw,
+                                            CM_REGISTRY_SOFTWARE);
+            if (result != CR_SUCCESS) {
+                continue;
+            }
+
+            ULONG nError;
+
+            DWORD pathSize = dwPathSize;
+
+            nError = RegQueryValueExW(hKey_sw, driverKey, 0, NULL, (LPBYTE)path, &pathSize);
+
+            RegCloseKey(hKey_sw);
+
+            if (ERROR_SUCCESS == nError) {
+                if (path[wcslen(path) - 1] != '/' && path[wcslen(path) - 1] != '\\') {
+                    wcscat_s(path, MFX_MAX_DLL_PATH, L"\\");
+                }
+                DISPATCHER_LOG_INFO(("DriverStore path is found\n"));
+                return true;
+            }
+        }
+    }
+
+    DISPATCHER_LOG_INFO(("DriverStore path isn't found\n"));
+    return false;
+
+} // bool DriverStoreLoader::GetDriverStorePath(wchar_t * path, DWORD dwPathSize, wchar_t *driverKey)
+
+bool DriverStoreLoader::LoadCfgMgr() {
+    if (!m_moduleCfgMgr) {
+        m_moduleCfgMgr = mfx_dll_load(L"cfgmgr32.dll");
+
+        if (!m_moduleCfgMgr) {
+            DISPATCHER_LOG_WRN(("cfgmgr32.dll couldn't be loaded\n"));
+            return false;
+        }
+    }
+
+    return true;
+
+} // bool DriverStoreLoader::LoadCfgMgr()
+
+bool DriverStoreLoader::LoadCmFuncs() {
+    if (!m_pCM_Get_Device_ID_List || !m_pCM_Get_Device_ID_List_Size || !m_pCM_Locate_DevNode ||
+        !m_pCM_Open_DevNode_Key) {
+        m_pCM_Get_Device_ID_List =
+            (Func_CM_Get_Device_ID_ListW)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
+                                                          "CM_Get_Device_ID_ListW");
+        m_pCM_Get_Device_ID_List_Size =
+            (Func_CM_Get_Device_ID_List_SizeW)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
+                                                               "CM_Get_Device_ID_List_SizeW");
+        m_pCM_Locate_DevNode   = (Func_CM_Locate_DevNodeW)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
+                                                                         "CM_Locate_DevNodeW");
+        m_pCM_Open_DevNode_Key = (Func_CM_Open_DevNode_Key)mfx_dll_get_addr((HMODULE)m_moduleCfgMgr,
+                                                                            "CM_Open_DevNode_Key");
+
+        if (!m_pCM_Get_Device_ID_List || !m_pCM_Get_Device_ID_List_Size || !m_pCM_Locate_DevNode ||
+            !m_pCM_Open_DevNode_Key) {
+            DISPATCHER_LOG_WRN(("One of cfgmgr32.dll function isn't found\n"));
+            return false;
+        }
+    }
+
+    return true;
+
+} // bool DriverStoreLoader::LoadCmFuncs()
+
+} // namespace MFX
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_driver_store_loader.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_driver_store_loader.h
new file mode 100644 (file)
index 0000000..26dcc28
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (c) 2019-2020 Intel Corporation
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+#ifndef DISPATCHER_WINDOWS_MFX_DRIVER_STORE_LOADER_H_
+#define DISPATCHER_WINDOWS_MFX_DRIVER_STORE_LOADER_H_
+
+#include <windows.h>
+
+#include <cfgmgr32.h>
+
+// support building in MinGW environments with older versions of cfgmgr32
+#ifdef __MINGW32__
+    #if !defined(CM_GETIDLIST_FILTER_PRESENT)
+        #define CM_GETIDLIST_FILTER_PRESENT 0x00000100
+    #endif
+    #if !defined(CM_GETIDLIST_FILTER_CLASS)
+        #define CM_GETIDLIST_FILTER_CLASS 0x00000200
+    #endif
+#endif
+
+#include <devguid.h>
+
+#include "windows/mfx_dispatcher_defs.h"
+
+namespace MFX {
+
+typedef CONFIGRET(WINAPI *Func_CM_Get_Device_ID_List_SizeW)(PULONG pulLen,
+                                                            PCWSTR pszFilter,
+                                                            ULONG ulFlags);
+typedef CONFIGRET(WINAPI *Func_CM_Get_Device_ID_ListW)(PCWSTR pszFilter,
+                                                       PZZWSTR Buffer,
+                                                       ULONG BufferLen,
+                                                       ULONG ulFlags);
+typedef CONFIGRET(WINAPI *Func_CM_Locate_DevNodeW)(PDEVINST pdnDevInst,
+                                                   DEVINSTID_W pDeviceID,
+                                                   ULONG ulFlags);
+typedef CONFIGRET(WINAPI *Func_CM_Open_DevNode_Key)(DEVINST dnDevNode,
+                                                    REGSAM samDesired,
+                                                    ULONG ulHardwareProfile,
+                                                    REGDISPOSITION Disposition,
+                                                    PHKEY phkDevice,
+                                                    ULONG ulFlags);
+
+class DriverStoreLoader {
+public:
+    DriverStoreLoader(void);
+    ~DriverStoreLoader(void);
+
+    bool GetDriverStorePath(wchar_t *path,
+                            DWORD dwPathSize,
+                            mfxU32 deviceID,
+                            const wchar_t *driverKey);
+
+protected:
+    bool LoadCfgMgr();
+    bool LoadCmFuncs();
+
+    mfxModuleHandle m_moduleCfgMgr;
+    Func_CM_Get_Device_ID_List_SizeW m_pCM_Get_Device_ID_List_Size;
+    Func_CM_Get_Device_ID_ListW m_pCM_Get_Device_ID_List;
+    Func_CM_Locate_DevNodeW m_pCM_Locate_DevNode;
+    Func_CM_Open_DevNode_Key m_pCM_Open_DevNode_Key;
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    DriverStoreLoader(const DriverStoreLoader &);
+    void operator=(const DriverStoreLoader &);
+};
+
+} // namespace MFX
+
+#endif // DISPATCHER_WINDOWS_MFX_DRIVER_STORE_LOADER_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dxva2_device.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dxva2_device.cpp
new file mode 100644 (file)
index 0000000..32e2639
--- /dev/null
@@ -0,0 +1,553 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#define INITGUID
+#include <d3d9.h>
+#include <dxgi.h>
+
+#include "windows/mfx_dxva2_device.h"
+#include "windows/mfx_load_dll.h"
+
+using namespace MFX;
+
+// convert LUID to mfxU64
+mfxU64 LUIDtomfxU64(LUID luid) {
+    return (((mfxU64)luid.HighPart << 32) | ((mfxU64)luid.LowPart));
+}
+
+DXDevice::DXDevice(void) {
+    m_hModule = (HMODULE)0;
+
+    m_numAdapters = 0;
+
+    m_vendorID      = 0;
+    m_deviceID      = 0;
+    m_driverVersion = 0;
+    m_luid          = {};
+
+} // DXDevice::DXDevice(void)
+
+DXDevice::~DXDevice(void) {
+    Close();
+
+    // free DX library only when device is destroyed
+    UnloadDLLModule();
+
+} // DXDevice::~DXDevice(void)
+
+mfxU32 DXDevice::GetVendorID(void) const {
+    return m_vendorID;
+
+} // mfxU32 DXDevice::GetVendorID(void) const
+
+mfxU32 DXDevice::GetDeviceID(void) const {
+    return m_deviceID;
+
+} // mfxU32 DXDevice::GetDeviceID(void) const
+
+mfxU64 DXDevice::GetDriverVersion(void) const {
+    return m_driverVersion;
+
+} // mfxU64 DXDevice::GetDriverVersion(void) const
+
+mfxU64 DXDevice::GetLUID(void) const {
+    return m_luid;
+
+} // mfxU64 DXDevice::GetLUID(void) const
+
+mfxU32 DXDevice::GetAdapterCount(void) const {
+    return m_numAdapters;
+
+} // mfxU32 DXDevice::GetAdapterCount(void) const
+
+void DXDevice::Close(void) {
+    m_numAdapters = 0;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+    m_luid     = {};
+
+} // void DXDevice::Close(void)
+
+void DXDevice::LoadDLLModule(const wchar_t *pModuleName) {
+    // unload the module if it is required
+    UnloadDLLModule();
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    DWORD prevErrorMode = 0;
+    // set the silent error mode
+    #if (_WIN32_WINNT >= 0x0600)
+    SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode);
+    #else
+    prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+    #endif
+#endif // !defined(MEDIASDK_UWP_DISPATCHER)
+
+    // load specified library
+    m_hModule = LoadLibraryExW(pModuleName, NULL, 0);
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    // set the previous error mode
+    #if (_WIN32_WINNT >= 0x0600)
+    SetThreadErrorMode(prevErrorMode, NULL);
+    #else
+    SetErrorMode(prevErrorMode);
+    #endif
+#endif // !defined(MEDIASDK_UWP_DISPATCHER)
+
+} // void LoadDLLModule(const wchar_t *pModuleName)
+
+void DXDevice::UnloadDLLModule(void) {
+    if (m_hModule) {
+        FreeLibrary(m_hModule);
+        m_hModule = (HMODULE)0;
+    }
+
+} // void DXDevice::UnloaDLLdModule(void)
+
+#ifdef MFX_D3D9_ENABLED
+D3D9Device::D3D9Device(void) {
+    m_pD3D9   = (void *)0;
+    m_pD3D9Ex = (void *)0;
+
+} // D3D9Device::D3D9Device(void)
+
+D3D9Device::~D3D9Device(void) {
+    Close();
+
+} // D3D9Device::~D3D9Device(void)
+
+void D3D9Device::Close(void) {
+    // release the interfaces
+    if (m_pD3D9Ex) {
+        ((IDirect3D9Ex *)m_pD3D9Ex)->Release();
+    }
+
+    // release the interfaces
+    if (m_pD3D9) {
+        ((IDirect3D9 *)m_pD3D9)->Release();
+    }
+
+    m_pD3D9   = (void *)0;
+    m_pD3D9Ex = (void *)0;
+
+} // void D3D9Device::Close(void)
+
+typedef IDirect3D9 *(WINAPI *D3DCreateFunctionPtr_t)(UINT);
+
+typedef HRESULT(WINAPI *D3DExCreateFunctionPtr_t)(UINT, IDirect3D9Ex **);
+
+bool D3D9Device::Init(const mfxU32 adapterNum) {
+    // close the device before initialization
+    Close();
+
+    // load the library
+    if (NULL == m_hModule) {
+        LoadDLLModule(L"d3d9.dll");
+    }
+
+    if (m_hModule) {
+        D3DCreateFunctionPtr_t pFunc;
+
+        // load address of procedure to create D3D device
+        pFunc = (D3DCreateFunctionPtr_t)GetProcAddress(m_hModule, "Direct3DCreate9");
+        if (pFunc) {
+            D3DADAPTER_IDENTIFIER9 adapterIdent;
+            IDirect3D9 *pD3D9;
+            HRESULT hRes;
+
+            // create D3D object
+            m_pD3D9 = pFunc(D3D_SDK_VERSION);
+
+            if (NULL == m_pD3D9) {
+                DXVA2DEVICE_TRACE(("FAIL: Direct3DCreate9(%d) : GetLastError()=0x%x",
+                                   D3D_SDK_VERSION,
+                                   GetLastError()));
+                return false;
+            }
+
+            // cast the interface
+            pD3D9 = (IDirect3D9 *)m_pD3D9;
+
+            m_numAdapters = pD3D9->GetAdapterCount();
+            if (adapterNum >= m_numAdapters) {
+                return false;
+            }
+
+            // get the card's parameters
+            hRes = pD3D9->GetAdapterIdentifier(adapterNum, 0, &adapterIdent);
+            if (D3D_OK != hRes) {
+                DXVA2DEVICE_TRACE(("FAIL: GetAdapterIdentifier(%d) = 0x%x \n", adapterNum, hRes));
+                return false;
+            }
+
+            m_vendorID      = adapterIdent.VendorId;
+            m_deviceID      = adapterIdent.DeviceId;
+            m_driverVersion = (mfxU64)adapterIdent.DriverVersion.QuadPart;
+
+            // load LUID
+            IDirect3D9Ex *pD3D9Ex;
+            D3DExCreateFunctionPtr_t pFuncEx;
+            LUID d3d9LUID;
+
+            // find the appropriate function
+            pFuncEx = (D3DExCreateFunctionPtr_t)GetProcAddress(m_hModule, "Direct3DCreate9Ex");
+            if (NULL == pFuncEx) {
+                // the extended interface is not supported
+                return true;
+            }
+
+            // create extended interface
+            hRes = pFuncEx(D3D_SDK_VERSION, &pD3D9Ex);
+            if (FAILED(hRes)) {
+                // can't create extended interface
+                return true;
+            }
+            m_pD3D9Ex = pD3D9Ex;
+
+            // obtain D3D9 device LUID
+            hRes = pD3D9Ex->GetAdapterLUID(adapterNum, &d3d9LUID);
+            if (FAILED(hRes)) {
+                // can't get LUID
+                return true;
+            }
+            // copy the LUID
+            m_luid = LUIDtomfxU64(d3d9LUID);
+        }
+        else {
+            DXVA2DEVICE_TRACE_OPERATION({
+                wchar_t path[1024];
+                DWORD lastErr = GetLastError();
+                GetModuleFileNameW(m_hModule, path, sizeof(path) / sizeof(path[0]));
+                DXVA2DEVICE_TRACE((
+                    "FAIL: invoking GetProcAddress(Direct3DCreate9) in %S : GetLastError()==0x%x\n",
+                    path,
+                    lastErr));
+            });
+            return false;
+        }
+    }
+    else {
+        DXVA2DEVICE_TRACE(
+            ("FAIL: invoking LoadLibrary(\"d3d9.dll\") : GetLastError()==0x%x\n", GetLastError()));
+        return false;
+    }
+
+    return true;
+
+} // bool D3D9Device::Init(const mfxU32 adapterNum)
+#endif //MFX_D3D9_ENABLED
+
+typedef HRESULT(WINAPI *DXGICreateFactoryFunc)(REFIID riid, void **ppFactory);
+
+DXGI1Device::DXGI1Device(void) {
+    m_pDXGIFactory1 = (void *)0;
+    m_pDXGIAdapter1 = (void *)0;
+
+} // DXGI1Device::DXGI1Device(void)
+
+DXGI1Device::~DXGI1Device(void) {
+    Close();
+
+} // DXGI1Device::~DXGI1Device(void)
+
+void DXGI1Device::Close(void) {
+    // release the interfaces
+    if (m_pDXGIAdapter1) {
+        ((IDXGIAdapter1 *)m_pDXGIAdapter1)->Release();
+    }
+
+    if (m_pDXGIFactory1) {
+        ((IDXGIFactory1 *)m_pDXGIFactory1)->Release();
+    }
+
+    m_pDXGIFactory1 = (void *)0;
+    m_pDXGIAdapter1 = (void *)0;
+
+} // void DXGI1Device::Close(void)
+
+bool DXGI1Device::Init(const mfxU32 adapterNum) {
+    // release the object before initialization
+    Close();
+
+    IDXGIFactory1 *pFactory = NULL;
+    IDXGIAdapter1 *pAdapter = NULL;
+    DXGI_ADAPTER_DESC1 desc = { 0 };
+    mfxU32 curAdapter       = 0;
+    mfxU32 maxAdapters      = 0;
+    HRESULT hRes            = E_FAIL;
+
+    DXGICreateFactoryFunc pFunc = NULL;
+
+    // load up the library if it is not loaded
+    if (NULL == m_hModule) {
+        LoadDLLModule(L"dxgi.dll");
+    }
+
+    if (m_hModule) {
+        // load address of procedure to create DXGI 1.1 factory
+        pFunc = (DXGICreateFactoryFunc)GetProcAddress(m_hModule, "CreateDXGIFactory1");
+    }
+
+    if (NULL == pFunc) {
+        return false;
+    }
+
+    // create the factory
+#if _MSC_VER >= 1400
+    hRes = pFunc(__uuidof(IDXGIFactory1), (void **)(&pFactory));
+#else
+    hRes = pFunc(IID_IDXGIFactory1, (void **)(&pFactory));
+#endif
+
+    if (FAILED(hRes)) {
+        return false;
+    }
+    m_pDXGIFactory1 = pFactory;
+
+    // get the number of adapters
+    curAdapter  = 0;
+    maxAdapters = 0;
+    do {
+        // get the required adapted
+        hRes = pFactory->EnumAdapters1(curAdapter, &pAdapter);
+        if (FAILED(hRes)) {
+            break;
+        }
+
+        // if it is the required adapter, save the interface
+        if (curAdapter == adapterNum) {
+            m_pDXGIAdapter1 = pAdapter;
+        }
+        else {
+            pAdapter->Release();
+        }
+
+        // get the next adapter
+        curAdapter += 1;
+
+    } while (SUCCEEDED(hRes));
+    maxAdapters = curAdapter;
+
+    m_numAdapters = maxAdapters;
+
+    // there is no required adapter
+    if (adapterNum >= maxAdapters) {
+        return false;
+    }
+    pAdapter = (IDXGIAdapter1 *)m_pDXGIAdapter1;
+
+    // get the adapter's parameters
+    hRes = pAdapter->GetDesc1(&desc);
+    if (FAILED(hRes)) {
+        return false;
+    }
+
+    // save the parameters
+    m_vendorID = desc.VendorId;
+    m_deviceID = desc.DeviceId;
+    m_luid     = LUIDtomfxU64(desc.AdapterLuid);
+
+    return true;
+
+} // bool DXGI1Device::Init(const mfxU32 adapterNum)
+
+bool DXGI1Device::GetAdapterList(std::vector<DXGI1DeviceInfo> &adapterInfo) {
+    mfxModuleHandle hModule = MFX::mfx_dll_load(L"dxgi.dll");
+    if (!hModule)
+        return false;
+
+    DXGICreateFactoryFunc pFactoryFunc = NULL;
+    pFactoryFunc = (DXGICreateFactoryFunc)MFX::mfx_dll_get_addr(hModule, "CreateDXGIFactory1");
+    if (pFactoryFunc == NULL)
+        return false;
+
+    IDXGIFactory1 *pFactory = NULL;
+    IDXGIAdapter1 *pAdapter = NULL;
+
+    HRESULT hRes = pFactoryFunc(__uuidof(IDXGIFactory1), (void **)(&pFactory));
+    if (FAILED(hRes))
+        return false;
+
+    bool bEnumSuccess = false;
+    mfxU32 curAdapter = 0;
+    while (pFactory->EnumAdapters1(curAdapter, &pAdapter) == S_OK) {
+        curAdapter++;
+
+        DXGI_ADAPTER_DESC1 desc = {};
+        DXGI1DeviceInfo devInfo = {};
+        if (pAdapter->GetDesc1(&desc) == S_OK) {
+            // save minimal descriptive info
+            devInfo.vendorID = desc.VendorId;
+            devInfo.deviceID = desc.DeviceId;
+            devInfo.luid     = LUIDtomfxU64(desc.AdapterLuid);
+
+            // add to list
+            adapterInfo.emplace_back(devInfo);
+
+            // at least one valid adapter found
+            bEnumSuccess = true;
+        }
+
+        pAdapter->Release();
+    }
+    pFactory->Release();
+
+    mfx_dll_free(hModule);
+
+    return bEnumSuccess;
+}
+
+DXVA2Device::DXVA2Device(void) {
+    m_numAdapters = 0;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+    m_driverVersion = 0;
+
+    m_luid = {};
+} // DXVA2Device::DXVA2Device(void)
+
+DXVA2Device::~DXVA2Device(void) {
+    Close();
+
+} // DXVA2Device::~DXVA2Device(void)
+
+void DXVA2Device::Close(void) {
+    m_numAdapters = 0;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+    m_driverVersion = 0;
+} // void DXVA2Device::Close(void)
+
+#ifdef MFX_D3D9_ENABLED
+bool DXVA2Device::InitD3D9(const mfxU32 adapterNum) {
+    D3D9Device d3d9Device;
+    bool bRes;
+
+    // release the object before initialization
+    Close();
+
+    // create 'old fashion' device
+    bRes = d3d9Device.Init(adapterNum);
+    if (false == bRes) {
+        return false;
+    }
+
+    m_numAdapters = d3d9Device.GetAdapterCount();
+
+    // check if the application is under Remote Desktop
+    if ((0 == d3d9Device.GetVendorID()) || (0 == d3d9Device.GetDeviceID())) {
+        // get the required parameters alternative way and ...
+        UseAlternativeWay(&d3d9Device);
+    }
+    else {
+        // save the parameters and ...
+        m_vendorID      = d3d9Device.GetVendorID();
+        m_deviceID      = d3d9Device.GetDeviceID();
+        m_driverVersion = d3d9Device.GetDriverVersion();
+        m_luid          = d3d9Device.GetLUID();
+    }
+
+    // ... say goodbye
+    return true;
+} // bool InitD3D9(const mfxU32 adapterNum)
+#else // MFX_D3D9_ENABLED
+bool DXVA2Device::InitD3D9(const mfxU32 adapterNum) {
+    (void)adapterNum;
+    return false;
+}
+#endif // MFX_D3D9_ENABLED
+
+bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum) {
+    DXGI1Device dxgi1Device;
+    bool bRes;
+
+    // release the object before initialization
+    Close();
+
+    // create modern DXGI device
+    bRes = dxgi1Device.Init(adapterNum);
+    if (false == bRes) {
+        return false;
+    }
+
+    // save the parameters and ...
+    m_vendorID    = dxgi1Device.GetVendorID();
+    m_deviceID    = dxgi1Device.GetDeviceID();
+    m_numAdapters = dxgi1Device.GetAdapterCount();
+    m_luid        = dxgi1Device.GetLUID();
+
+    // ... say goodbye
+    return true;
+
+} // bool DXVA2Device::InitDXGI1(const mfxU32 adapterNum)
+
+#ifdef MFX_D3D9_ENABLED
+void DXVA2Device::UseAlternativeWay(const D3D9Device *pD3D9Device) {
+    mfxU64 d3d9LUID     = pD3D9Device->GetLUID();
+    mfxU64 kInvalidLUID = {};
+    // work only with valid LUIDs
+    if (kInvalidLUID == d3d9LUID) {
+        return;
+    }
+    DXGI1Device dxgi1Device;
+    mfxU32 curDevice = 0;
+    bool bRes        = false;
+
+    do {
+        // initialize the next DXGI1 or DXGI device
+        bRes = dxgi1Device.Init(curDevice);
+        if (false == bRes) {
+            // there is no more devices
+            break;
+        }
+
+        // is it required device ?
+        if (d3d9LUID == dxgi1Device.GetLUID()) {
+            m_vendorID      = dxgi1Device.GetVendorID();
+            m_deviceID      = dxgi1Device.GetDeviceID();
+            m_driverVersion = dxgi1Device.GetDriverVersion();
+            m_luid          = dxgi1Device.GetLUID();
+            return;
+        }
+
+        // get the next device
+        curDevice += 1;
+
+    } while (bRes);
+
+    dxgi1Device.Close();
+    // we need to match a DXGI(1) device to the D3D9 device
+
+} // void DXVA2Device::UseAlternativeWay(const D3D9Device *pD3D9Device)
+#endif // MFX_D3D9_ENABLED
+
+mfxU32 DXVA2Device::GetVendorID(void) const {
+    return m_vendorID;
+
+} // mfxU32 DXVA2Device::GetVendorID(void) const
+
+mfxU32 DXVA2Device::GetDeviceID(void) const {
+    return m_deviceID;
+
+} // mfxU32 DXVA2Device::GetDeviceID(void) const
+
+mfxU64 DXVA2Device::GetDriverVersion(void) const {
+    return m_driverVersion;
+} // mfxU64 DXVA2Device::GetDriverVersion(void) const
+
+mfxU32 DXVA2Device::GetAdapterCount(void) const {
+    return m_numAdapters;
+
+} // mfxU32 DXVA2Device::GetAdapterCount(void) const
+
+mfxU64 DXVA2Device::GetLUID(void) const {
+    return m_luid;
+} // mfxU64 DXVA2Device::GetLUID(void) const
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dxva2_device.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_dxva2_device.h
new file mode 100644 (file)
index 0000000..0fb15bf
--- /dev/null
@@ -0,0 +1,196 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFX_DXVA2_DEVICE_H_
+#define DISPATCHER_WINDOWS_MFX_DXVA2_DEVICE_H_
+
+#include <windows.h>
+
+#include <vector>
+
+#include "vpl/mfx_dispatcher_vpl.h"
+
+#define TOSTRING(L)  #L
+#define STRINGIFY(L) TOSTRING(L)
+
+#if defined(MEDIASDK_UWP_DISPATCHER)
+    #if defined(MFX_D3D9_ENABLED) && !defined(MFX_FORCE_D3D9_ENABLED)
+        #undef MFX_D3D9_ENABLED
+        #pragma message("\n\nATTENTION:\nin file\n\t" __FILE__ \
+                        " (" STRINGIFY(__LINE__) "):\nUsing of D3D9 disabled for UWP!\n\n")
+    #endif
+    #if defined(MFX_FORCE_D3D9_ENABLED)
+        #define MFX_D3D9_ENABLED
+    #endif
+#else
+    #define MFX_D3D9_ENABLED
+    #pragma message("\n\nATTENTION:\nin file\n\t" __FILE__ \
+                    " (" STRINGIFY(__LINE__) "):\nUsing of D3D9 enabled!\n\n")
+#endif
+
+#include "vpl/mfxdefs.h"
+
+#ifdef DXVA2DEVICE_LOG
+    #include <stdio.h>
+    #define DXVA2DEVICE_TRACE(expr)           printf expr;
+    #define DXVA2DEVICE_TRACE_OPERATION(expr) expr;
+#else
+    #define DXVA2DEVICE_TRACE(expr)
+    #define DXVA2DEVICE_TRACE_OPERATION(expr)
+#endif
+
+namespace MFX {
+
+// compare LUIDs
+inline bool operator==(const LUID &lhs, const LUID &rhs) {
+    return (lhs.LowPart == rhs.LowPart && lhs.HighPart == rhs.HighPart);
+}
+
+class DXDevice {
+public:
+    // Default constructor
+    DXDevice(void);
+    // Destructor
+    virtual ~DXDevice(void) = 0;
+
+    // Initialize device using DXGI 1.1 or VAAPI interface
+    virtual bool Init(const mfxU32 adapterNum) = 0;
+
+    // Obtain graphic card's parameter
+    mfxU32 GetVendorID(void) const;
+    mfxU32 GetDeviceID(void) const;
+    mfxU64 GetDriverVersion(void) const;
+    mfxU64 GetLUID(void) const;
+
+    // Provide the number of available adapters
+    mfxU32 GetAdapterCount(void) const;
+
+    // Close the object
+    virtual void Close(void);
+
+    // Load the required DLL module
+    void LoadDLLModule(const wchar_t *pModuleName);
+
+protected:
+    // Free DLL module
+    void UnloadDLLModule(void);
+
+    // Handle to the DLL library
+    HMODULE m_hModule;
+
+    // Number of adapters available
+    mfxU32 m_numAdapters;
+
+    // Vendor ID
+    mfxU32 m_vendorID;
+    // Device ID
+    mfxU32 m_deviceID;
+    // x.x.x.x each x of two bytes
+    mfxU64 m_driverVersion;
+    // LUID
+    mfxU64 m_luid;
+
+private:
+    // unimplemented by intent to make this class and its descendants non-copyable
+    DXDevice(const DXDevice &);
+    void operator=(const DXDevice &);
+};
+
+#ifdef MFX_D3D9_ENABLED
+class D3D9Device : public DXDevice {
+public:
+    // Default constructor
+    D3D9Device(void);
+    // Destructor
+    virtual ~D3D9Device(void);
+
+    // Initialize device using D3D v9 interface
+    virtual bool Init(const mfxU32 adapterNum);
+
+    // Close the object
+    virtual void Close(void);
+
+protected:
+    // Pointer to the D3D v9 interface
+    void *m_pD3D9;
+    // Pointer to the D3D v9 extended interface
+    void *m_pD3D9Ex;
+};
+#endif // MFX_D3D9_ENABLED
+
+class DXGI1Device : public DXDevice {
+public:
+    // Default constructor
+    DXGI1Device(void);
+    // Destructor
+    virtual ~DXGI1Device(void);
+
+    // Initialize device
+    virtual bool Init(const mfxU32 adapterNum);
+
+    // Close the object
+    virtual void Close(void);
+
+    // lightweight method to get list of adapters
+    static bool GetAdapterList(std::vector<DXGI1DeviceInfo> &adapterInfo);
+
+protected:
+    // Pointer to the DXGI1 factory
+    void *m_pDXGIFactory1;
+    // Pointer to the current DXGI1 adapter
+    void *m_pDXGIAdapter1;
+};
+
+class DXVA2Device {
+public:
+    // Default constructor
+    DXVA2Device(void);
+    // Destructor
+    ~DXVA2Device(void);
+
+    // Initialize device using D3D v9 interface
+    bool InitD3D9(const mfxU32 adapterNum);
+
+    // Initialize device using DXGI 1.1 interface
+    bool InitDXGI1(const mfxU32 adapterNum);
+
+    // Obtain graphic card's parameter
+    mfxU32 GetVendorID(void) const;
+    mfxU32 GetDeviceID(void) const;
+    mfxU64 GetDriverVersion(void) const;
+    mfxU64 GetLUID(void) const;
+
+    // Provide the number of available adapters
+    mfxU32 GetAdapterCount(void) const;
+
+    void Close(void);
+
+protected:
+#ifdef MFX_D3D9_ENABLED
+    // Get vendor & device IDs by alternative way (D3D9 in Remote Desktop sessions)
+    void UseAlternativeWay(const D3D9Device *pD3D9Device);
+#endif // MFX_D3D9_ENABLED
+    // Number of adapters available
+    mfxU32 m_numAdapters;
+
+    // Vendor ID
+    mfxU32 m_vendorID;
+    // Device ID
+    mfxU32 m_deviceID;
+    //x.x.x.x
+    mfxU64 m_driverVersion;
+    // LUID
+    mfxU64 m_luid;
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    DXVA2Device(const DXVA2Device &);
+    void operator=(const DXVA2Device &);
+};
+
+} // namespace MFX
+
+#endif // DISPATCHER_WINDOWS_MFX_DXVA2_DEVICE_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_exposed_functions_list.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_exposed_functions_list.h
new file mode 100644 (file)
index 0000000..9ea0d29
--- /dev/null
@@ -0,0 +1,159 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+//
+// WARNING:
+// this file doesn't contain an include guard by design.
+// The file may be included into a source file many times.
+// That is why this header doesn't contain any include directive.
+// Please, do no try to fix it.
+//
+// NOLINT(build/header_guard)
+
+// Use define API_VERSION to set the API of functions listed further
+// When new functions are added new section with functions declarations must be started with updated define
+
+//
+// API version 1.0 functions
+//
+
+// API version where a function is added. Minor value should precedes the major value
+#define API_VERSION \
+    {               \
+        { 0, 1 }    \
+    }
+
+// CORE interface functions
+FUNCTION(mfxStatus,
+         MFXVideoCORE_SetFrameAllocator,
+         (mfxSession session, mfxFrameAllocator *allocator),
+         (session, allocator))
+FUNCTION(mfxStatus,
+         MFXVideoCORE_SetHandle,
+         (mfxSession session, mfxHandleType type, mfxHDL hdl),
+         (session, type, hdl))
+FUNCTION(mfxStatus,
+         MFXVideoCORE_GetHandle,
+         (mfxSession session, mfxHandleType type, mfxHDL *hdl),
+         (session, type, hdl))
+
+FUNCTION(mfxStatus,
+         MFXVideoCORE_SyncOperation,
+         (mfxSession session, mfxSyncPoint syncp, mfxU32 wait),
+         (session, syncp, wait))
+
+// ENCODE interface functions
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_Query,
+         (mfxSession session, mfxVideoParam *in, mfxVideoParam *out),
+         (session, in, out))
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_QueryIOSurf,
+         (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request),
+         (session, par, request))
+FUNCTION(mfxStatus, MFXVideoENCODE_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoENCODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoENCODE_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_GetVideoParam,
+         (mfxSession session, mfxVideoParam *par),
+         (session, par))
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_GetEncodeStat,
+         (mfxSession session, mfxEncodeStat *stat),
+         (session, stat))
+FUNCTION(mfxStatus,
+         MFXVideoENCODE_EncodeFrameAsync,
+         (mfxSession session,
+          mfxEncodeCtrl *ctrl,
+          mfxFrameSurface1 *surface,
+          mfxBitstream *bs,
+          mfxSyncPoint *syncp),
+         (session, ctrl, surface, bs, syncp))
+
+// DECODE interface functions
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_Query,
+         (mfxSession session, mfxVideoParam *in, mfxVideoParam *out),
+         (session, in, out))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_DecodeHeader,
+         (mfxSession session, mfxBitstream *bs, mfxVideoParam *par),
+         (session, bs, par))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_QueryIOSurf,
+         (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request),
+         (session, par, request))
+FUNCTION(mfxStatus, MFXVideoDECODE_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoDECODE_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_GetVideoParam,
+         (mfxSession session, mfxVideoParam *par),
+         (session, par))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_GetDecodeStat,
+         (mfxSession session, mfxDecodeStat *stat),
+         (session, stat))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_SetSkipMode,
+         (mfxSession session, mfxSkipMode mode),
+         (session, mode))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_GetPayload,
+         (mfxSession session, mfxU64 *ts, mfxPayload *payload),
+         (session, ts, payload))
+FUNCTION(mfxStatus,
+         MFXVideoDECODE_DecodeFrameAsync,
+         (mfxSession session,
+          mfxBitstream *bs,
+          mfxFrameSurface1 *surface_work,
+          mfxFrameSurface1 **surface_out,
+          mfxSyncPoint *syncp),
+         (session, bs, surface_work, surface_out, syncp))
+
+// VPP interface functions
+FUNCTION(mfxStatus,
+         MFXVideoVPP_Query,
+         (mfxSession session, mfxVideoParam *in, mfxVideoParam *out),
+         (session, in, out))
+FUNCTION(mfxStatus,
+         MFXVideoVPP_QueryIOSurf,
+         (mfxSession session, mfxVideoParam *par, mfxFrameAllocRequest *request),
+         (session, par, request))
+FUNCTION(mfxStatus, MFXVideoVPP_Init, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_Reset, (mfxSession session, mfxVideoParam *par), (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_Close, (mfxSession session), (session))
+
+FUNCTION(mfxStatus,
+         MFXVideoVPP_GetVideoParam,
+         (mfxSession session, mfxVideoParam *par),
+         (session, par))
+FUNCTION(mfxStatus, MFXVideoVPP_GetVPPStat, (mfxSession session, mfxVPPStat *stat), (session, stat))
+FUNCTION(mfxStatus,
+         MFXVideoVPP_RunFrameVPPAsync,
+         (mfxSession session,
+          mfxFrameSurface1 *in,
+          mfxFrameSurface1 *out,
+          mfxExtVppAuxData *aux,
+          mfxSyncPoint *syncp),
+         (session, in, out, aux, syncp))
+
+#undef API_VERSION
+
+#define API_VERSION \
+    {               \
+        { 19, 1 }   \
+    }
+
+FUNCTION(mfxStatus,
+         MFXVideoCORE_QueryPlatform,
+         (mfxSession session, mfxPlatform *platform),
+         (session, platform))
+
+#undef API_VERSION
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_function_table.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_function_table.cpp
new file mode 100644 (file)
index 0000000..8c4b03e
--- /dev/null
@@ -0,0 +1,110 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "windows/mfx_dispatcher.h"
+
+//
+// implement a table with functions names
+//
+#ifdef __GNUC__
+    #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    { #func_name, API_VERSION },
+
+const FUNCTION_DESCRIPTION APIFunc[eVideoFuncTotal] = {
+    { "MFXInit", { { 0, 1 } } },         { "MFXClose", { { 0, 1 } } },
+    { "MFXQueryIMPL", { { 0, 1 } } },    { "MFXQueryVersion", { { 0, 1 } } },
+
+    { "MFXJoinSession", { { 1, 1 } } },  { "MFXDisjoinSession", { { 1, 1 } } },
+    { "MFXCloneSession", { { 1, 1 } } }, { "MFXSetPriority", { { 1, 1 } } },
+    { "MFXGetPriority", { { 1, 1 } } },
+
+    { "MFXInitEx", { { 14, 1 } } },
+
+#include "windows/mfx_exposed_functions_list.h"
+};
+
+// new functions for API >= 2.0
+const FUNCTION_DESCRIPTION APIVideoFunc2[eVideoFunc2Total] = {
+    { "MFXQueryImplsDescription", { { 0, 2 } } },
+    { "MFXReleaseImplDescription", { { 0, 2 } } },
+    { "MFXMemory_GetSurfaceForVPP", { { 0, 2 } } },
+    { "MFXMemory_GetSurfaceForEncode", { { 0, 2 } } },
+    { "MFXMemory_GetSurfaceForDecode", { { 0, 2 } } },
+    { "MFXInitialize", { { 0, 2 } } },
+
+    { "MFXMemory_GetSurfaceForVPPOut", { { 1, 2 } } },
+    { "MFXVideoDECODE_VPP_Init", { { 1, 2 } } },
+    { "MFXVideoDECODE_VPP_DecodeFrameAsync", { { 1, 2 } } },
+    { "MFXVideoDECODE_VPP_Reset", { { 1, 2 } } },
+    { "MFXVideoDECODE_VPP_GetChannelParam", { { 1, 2 } } },
+    { "MFXVideoDECODE_VPP_Close", { { 1, 2 } } },
+    { "MFXVideoVPP_ProcessFrameAsync", { { 1, 2 } } },
+};
+
+// static section of the file
+namespace {
+
+//
+// declare pseudo-functions.
+// they are used as default values for call-tables.
+//
+
+mfxStatus pseudoMFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session) {
+    // touch unreferenced parameters
+    (void)impl;
+    (void)ver;
+    (void)session;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXInit(mfxIMPL impl, mfxVersion *ver, mfxSession *session)
+
+mfxStatus pseudoMFXClose(mfxSession session) {
+    // touch unreferenced parameters
+    (void)session;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXClose(mfxSession session)
+
+mfxStatus pseudoMFXJoinSession(mfxSession session, mfxSession child_session) {
+    // touch unreferenced parameters
+    (void)session;
+    (void)child_session;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXJoinSession(mfxSession session, mfxSession child_session)
+
+mfxStatus pseudoMFXCloneSession(mfxSession session, mfxSession *clone) {
+    // touch unreferenced parameters
+    (void)session;
+    (void)clone;
+
+    return MFX_ERR_UNKNOWN;
+
+} // mfxStatus pseudoMFXCloneSession(mfxSession session, mfxSession *clone)
+
+void SuppressWarnings(...) {
+    // this functions is suppose to suppress warnings.
+    // Actually it does nothing.
+
+} // void SuppressWarnings(...)
+
+#undef FUNCTION
+#define FUNCTION(return_value, func_name, formal_param_list, actual_param_list) \
+    return_value pseudo##func_name formal_param_list {                          \
+        SuppressWarnings actual_param_list;                                     \
+        return MFX_ERR_UNKNOWN;                                                 \
+    }
+
+#include "windows/mfx_exposed_functions_list.h" // NOLINT(build/include)
+
+} // namespace
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_library_iterator.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_library_iterator.cpp
new file mode 100644 (file)
index 0000000..89ff652
--- /dev/null
@@ -0,0 +1,646 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "windows/mfx_library_iterator.h"
+
+#include "windows/mfx_dispatcher.h"
+#include "windows/mfx_dispatcher_log.h"
+
+#include "windows/mfx_dxva2_device.h"
+#include "windows/mfx_load_dll.h"
+
+#include <tchar.h>
+#include <windows.h>
+
+#include <vector>
+
+namespace MFX {
+
+enum { MFX_MAX_MERIT = 0x7fffffff };
+
+//
+// declare registry keys
+//
+
+const wchar_t rootDispPath[]    = L"Software\\Intel\\MediaSDK\\Dispatch";
+const wchar_t vendorIDKeyName[] = L"VendorID";
+const wchar_t deviceIDKeyName[] = L"DeviceID";
+const wchar_t meritKeyName[]    = L"Merit";
+const wchar_t pathKeyName[]     = L"Path";
+const wchar_t apiVersionName[]  = L"APIVersion";
+
+mfxStatus SelectImplementationType(const mfxU32 adapterNum,
+                                   mfxIMPL *pImplInterface,
+                                   mfxU32 *pVendorID,
+                                   mfxU32 *pDeviceID,
+                                   mfxU64 *pLUID) {
+    if (NULL == pImplInterface) {
+        return MFX_ERR_NULL_PTR;
+    }
+    mfxIMPL impl_via = *pImplInterface;
+
+    DXVA2Device dxvaDevice;
+    if (MFX_IMPL_VIA_D3D9 == impl_via) {
+        // try to create the Direct3D 9 device and find right adapter
+        if (!dxvaDevice.InitD3D9(adapterNum)) {
+            DISPATCHER_LOG_INFO((("dxvaDevice.InitD3D9(%d) Failed "), adapterNum));
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+    else if (MFX_IMPL_VIA_D3D11 == impl_via) {
+        // try to open DXGI 1.1 device to get hardware ID
+        if (!dxvaDevice.InitDXGI1(adapterNum)) {
+            DISPATCHER_LOG_INFO((("dxvaDevice.InitDXGI1(%d) Failed "), adapterNum));
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+    else if (MFX_IMPL_VIA_ANY == impl_via) {
+        // try the Direct3D 9 device
+        if (dxvaDevice.InitD3D9(adapterNum)) {
+            *pImplInterface = MFX_IMPL_VIA_D3D9; // store value for GetImplementationType() call
+        }
+        // else try to open DXGI 1.1 device to get hardware ID
+        else if (dxvaDevice.InitDXGI1(adapterNum)) {
+            *pImplInterface = MFX_IMPL_VIA_D3D11; // store value for GetImplementationType() call
+        }
+        else {
+            DISPATCHER_LOG_INFO((("Unsupported adapter %d "), adapterNum));
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+    else {
+        DISPATCHER_LOG_ERROR((("Unknown implementation type %d "), *pImplInterface));
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // obtain card's parameters
+    if (pVendorID && pDeviceID) {
+        *pVendorID = dxvaDevice.GetVendorID();
+        *pDeviceID = dxvaDevice.GetDeviceID();
+    }
+
+    if (pLUID) {
+        *pLUID = dxvaDevice.GetLUID();
+    }
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus SelectImplementationType(const mfxU32 adapterNum,
+                                   mfxIMPL *pImplInterface,
+                                   mfxU32 *pVendorID,
+                                   mfxU32 *pDeviceID) {
+    // do not return LUID
+    return SelectImplementationType(adapterNum, pImplInterface, pVendorID, pDeviceID, nullptr);
+}
+
+MFXLibraryIterator::MFXLibraryIterator(void)
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+        : m_baseRegKey()
+#endif
+{
+    m_implType      = MFX_LIB_PSEUDO;
+    m_implInterface = MFX_IMPL_UNSUPPORTED;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+    m_lastLibIndex = 0;
+    m_lastLibMerit = MFX_MAX_MERIT;
+
+    m_bIsSubKeyValid = 0;
+    m_StorageID      = 0;
+
+    m_SubKeyName[0]     = 0;
+    m_driverStoreDir[0] = 0;
+} // MFXLibraryIterator::MFXLibraryIterator(void)
+
+MFXLibraryIterator::~MFXLibraryIterator(void) {
+    Release();
+
+} // MFXLibraryIterator::~MFXLibraryIterator(void)
+
+void MFXLibraryIterator::Release(void) {
+    m_implType      = MFX_LIB_PSEUDO;
+    m_implInterface = MFX_IMPL_UNSUPPORTED;
+
+    m_vendorID = 0;
+    m_deviceID = 0;
+
+    m_lastLibIndex  = 0;
+    m_lastLibMerit  = MFX_MAX_MERIT;
+    m_SubKeyName[0] = 0;
+
+} // void MFXLibraryIterator::Release(void)
+
+DECLSPEC_NOINLINE HMODULE GetThisDllModuleHandle() {
+    HMODULE hDll = NULL;
+
+    GetModuleHandleExW(
+        GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+        reinterpret_cast<LPCWSTR>(&GetThisDllModuleHandle),
+        &hDll);
+    return hDll;
+}
+
+// wchar_t* sImplPath must be allocated with size not less then msdk_disp_path_len
+bool GetImplPath(int storageID, wchar_t *sImplPath) {
+    HMODULE hModule = NULL;
+
+    sImplPath[0] = L'\0';
+
+    switch (storageID) {
+        case MFX_APP_FOLDER:
+            hModule = 0;
+            break;
+        case MFX_PATH_MSDK_FOLDER:
+            hModule           = GetThisDllModuleHandle();
+            HMODULE exeModule = GetModuleHandleW(NULL);
+            //It should works only if Dispatcher is linked with Dynamic Linked Library
+            if (!hModule || !exeModule || hModule == exeModule)
+                return false;
+            break;
+    }
+
+    DWORD nSize     = 0;
+    DWORD allocSize = msdk_disp_path_len;
+
+    nSize = GetModuleFileNameW(hModule, &sImplPath[0], allocSize);
+
+    if (nSize == 0 || nSize == allocSize) {
+        // nSize == 0 meanse that system can't get this info for hModule
+        // nSize == allocSize buffer is too small
+        return false;
+    }
+
+    // for any case because WinXP implementation of GetModuleFileName does not add \0 to the end of string
+    sImplPath[nSize] = L'\0';
+
+    wchar_t *dirSeparator = wcsrchr(sImplPath, L'\\');
+    if (dirSeparator != NULL && dirSeparator < (sImplPath + msdk_disp_path_len)) {
+        *++dirSeparator = 0;
+    }
+    return true;
+}
+
+mfxStatus MFXLibraryIterator::Init(eMfxImplType implType,
+                                   mfxIMPL implInterface,
+                                   const mfxU32 adapterNum,
+                                   int storageID) {
+    // check error(s)
+    if ((MFX_LIB_SOFTWARE != implType) && (MFX_LIB_HARDWARE != implType)) {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // release the object before initialization
+    Release();
+    m_StorageID     = storageID;
+    m_lastLibIndex  = 0;
+    m_implType      = implType;
+    m_implInterface = implInterface != 0 ? implInterface : MFX_IMPL_VIA_ANY;
+
+    // for HW impl check impl interface, check adapter, obtain deviceID and vendorID
+    if (m_implType != MFX_LIB_SOFTWARE) {
+        mfxStatus mfxRes =
+            MFX::SelectImplementationType(adapterNum, &m_implInterface, &m_vendorID, &m_deviceID);
+        if (MFX_ERR_NONE != mfxRes) {
+            return mfxRes;
+        }
+    }
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    if (storageID == MFX_CURRENT_USER_KEY || storageID == MFX_LOCAL_MACHINE_KEY ||
+        storageID == MFX_CURRENT_USER_KEY_ONEVPL || storageID == MFX_LOCAL_MACHINE_KEY_ONEVPL) {
+        return InitRegistry(storageID);
+    }
+
+    #if defined(MFX_TRACER_WA_FOR_DS)
+    if (storageID == MFX_TRACER) {
+        return InitRegistryTracer();
+    }
+    #endif
+
+#endif
+    if (storageID == MFX_DRIVER_STORE) {
+        m_driverStoreDir[0] = 0;
+        if (!m_driverStoreLoader.GetDriverStorePath(m_driverStoreDir,
+                                                    sizeof(m_driverStoreDir),
+                                                    m_deviceID,
+                                                    L"DriverStorePathForMediaSDK")) {
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+    else if (storageID == MFX_DRIVER_STORE_ONEVPL || storageID == MFX_DRIVER_STORE_ONEVPL_MFXINIT) {
+        // get path to runtime directory only (without library name)
+        m_driverStoreDir[0] = 0;
+        if (!m_driverStoreLoader.GetDriverStorePath(m_driverStoreDir,
+                                                    sizeof(m_driverStoreDir),
+                                                    m_deviceID,
+                                                    L"DriverStorePathForVPL")) {
+            return MFX_ERR_UNSUPPORTED;
+        }
+    }
+    else if (!GetImplPath(storageID, m_driverStoreDir)) {
+        return MFX_ERR_UNSUPPORTED;
+    }
+
+    // only need the path for oneVPL loader
+    if (storageID == MFX_DRIVER_STORE_ONEVPL || storageID == MFX_CURRENT_USER_KEY_ONEVPL ||
+        storageID == MFX_LOCAL_MACHINE_KEY_ONEVPL) {
+        return MFX_ERR_NONE;
+    }
+
+    return InitFolder(implType, m_driverStoreDir, storageID);
+
+} // mfxStatus MFXLibraryIterator::Init(eMfxImplType implType, const mfxU32 adapterNum, int storageID)
+
+mfxStatus MFXLibraryIterator::InitRegistry(int storageID) {
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    HKEY rootHKey;
+    bool bRes;
+
+    // open required registry key
+    switch (storageID) {
+        case MFX_LOCAL_MACHINE_KEY:
+        case MFX_LOCAL_MACHINE_KEY_ONEVPL:
+            rootHKey = HKEY_LOCAL_MACHINE;
+            break;
+        default:
+            rootHKey = HKEY_CURRENT_USER;
+            break;
+    }
+
+    bRes = m_baseRegKey.Open(rootHKey, rootDispPath, KEY_READ);
+    if (false == bRes) {
+        DISPATCHER_LOG_WRN(
+            (("Can't open %s\\%S : RegOpenKeyExA()==0x%x\n"),
+             (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
+             rootDispPath,
+             GetLastError()))
+        return MFX_ERR_UNKNOWN;
+    }
+
+    DISPATCHER_LOG_INFO(
+        (("Inspecting %s\\%S\n"),
+         (MFX_LOCAL_MACHINE_KEY == storageID) ? ("HKEY_LOCAL_MACHINE") : ("HKEY_CURRENT_USER"),
+         rootDispPath))
+
+    return MFX_ERR_NONE;
+#else
+    (void)storageID;
+    return MFX_ERR_UNSUPPORTED;
+#endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
+
+} // mfxStatus MFXLibraryIterator::InitRegistry(int storageID)
+
+#if defined(MFX_TRACER_WA_FOR_DS)
+mfxStatus MFXLibraryIterator::InitRegistryTracer() {
+    #if !defined(MEDIASDK_UWP_DISPATCHER)
+
+    const wchar_t tracerRegKeyPath[] = L"Software\\Intel\\MediaSDK\\Dispatch\\tracer";
+
+    if (!m_baseRegKey.Open(HKEY_LOCAL_MACHINE, tracerRegKeyPath, KEY_READ) &&
+        !m_baseRegKey.Open(HKEY_CURRENT_USER, tracerRegKeyPath, KEY_READ)) {
+        DISPATCHER_LOG_WRN(("can't find tracer registry key\n"))
+        return MFX_ERR_UNKNOWN;
+    }
+
+    DISPATCHER_LOG_INFO(("found tracer registry key\n"))
+    return MFX_ERR_NONE;
+
+    #else
+    return MFX_ERR_UNSUPPORTED;
+    #endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
+
+} // mfxStatus MFXLibraryIterator::InitRegistryTracer()
+#endif
+
+mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType,
+                                         const wchar_t *path,
+                                         const int storageID) {
+    const int maxPathLen = sizeof(m_path) / sizeof(m_path[0]);
+    m_path[0]            = 0;
+    wcscpy_s(m_path, maxPathLen, path);
+    size_t pathLen = wcslen(m_path);
+
+    if (storageID == MFX_APP_FOLDER) {
+        // we looking for runtime in application folder, it should be named libmfxsw64 or libmfxsw32
+        mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, MFX_LIB_SOFTWARE);
+    }
+    else if (storageID == MFX_DRIVER_STORE_ONEVPL_MFXINIT) {
+        mfx_get_default_onevpl_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen);
+    }
+    else {
+        mfx_get_default_dll_name(m_path + pathLen, msdk_disp_path_len - pathLen, implType);
+    }
+
+    return MFX_ERR_NONE;
+} // mfxStatus MFXLibraryIterator::InitFolder(eMfxImplType implType, const wchar_t * path, const int storageID)
+
+mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath,
+                                               size_t pathSize,
+                                               eMfxImplType *pImplType,
+                                               mfxVersion minVersion) {
+    UNREFERENCED_PARAMETER(minVersion);
+
+    if (m_StorageID == MFX_APP_FOLDER) {
+        if (m_lastLibIndex != 0)
+            return MFX_ERR_NOT_FOUND;
+        if (m_vendorID != INTEL_VENDOR_ID)
+            return MFX_ERR_UNKNOWN;
+
+        m_lastLibIndex = 1;
+        wcscpy_s(pPath, pathSize, m_path);
+        *pImplType = MFX_LIB_SOFTWARE;
+        return MFX_ERR_NONE;
+    }
+
+    if (m_StorageID == MFX_PATH_MSDK_FOLDER || m_StorageID == MFX_DRIVER_STORE ||
+        m_StorageID == MFX_DRIVER_STORE_ONEVPL_MFXINIT) {
+        if (m_lastLibIndex != 0)
+            return MFX_ERR_NOT_FOUND;
+        if (m_vendorID != INTEL_VENDOR_ID)
+            return MFX_ERR_UNKNOWN;
+
+        m_lastLibIndex = 1;
+        wcscpy_s(pPath, pathSize, m_path);
+        // do not change impl type
+        return MFX_ERR_NONE;
+    }
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+
+    #if defined(MFX_TRACER_WA_FOR_DS)
+    if (m_StorageID == MFX_TRACER) {
+        if (m_lastLibIndex != 0)
+            return MFX_ERR_NOT_FOUND;
+        if (m_vendorID != INTEL_VENDOR_ID)
+            return MFX_ERR_UNKNOWN;
+
+        m_lastLibIndex = 1;
+
+        if (m_baseRegKey.Query(pathKeyName, REG_SZ, (LPBYTE)pPath, (DWORD *)&pathSize)) {
+            DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, pPath));
+        }
+        else {
+            DISPATCHER_LOG_WRN(
+                (("error querying %S : RegQueryValueExA()==0x%x\n"), pathKeyName, GetLastError()));
+        }
+        return MFX_ERR_NONE;
+    }
+    #endif
+
+    wchar_t libPath[MFX_MAX_DLL_PATH] = L"";
+    DWORD libIndex                    = 0;
+    DWORD libMerit                    = 0;
+    DWORD index;
+    bool enumRes;
+
+    // main query cycle
+    index            = 0;
+    m_bIsSubKeyValid = false;
+    do {
+        WinRegKey subKey;
+        wchar_t subKeyName[MFX_MAX_REGISTRY_KEY_NAME] = { 0 };
+        DWORD subKeyNameSize                          = sizeof(subKeyName) / sizeof(subKeyName[0]);
+
+        // query next value name
+        enumRes = m_baseRegKey.EnumKey(index, subKeyName, &subKeyNameSize);
+        if (!enumRes) {
+            DISPATCHER_LOG_WRN((("no more subkeys : RegEnumKeyExA()==0x%x\n"), GetLastError()))
+        }
+        else {
+            DISPATCHER_LOG_INFO((("found subkey: %S\n"), subKeyName))
+
+            bool bRes;
+
+            // open the sub key
+            bRes = subKey.Open(m_baseRegKey, subKeyName, KEY_READ);
+            if (!bRes) {
+                DISPATCHER_LOG_WRN((("error opening key %S :RegOpenKeyExA()==0x%x\n"),
+                                    subKeyName,
+                                    GetLastError()));
+            }
+            else {
+                DISPATCHER_LOG_INFO((("opened key: %S\n"), subKeyName));
+
+                mfxU32 vendorID = 0, deviceID = 0, merit = 0;
+                DWORD size;
+
+                // query vendor and device IDs
+                size = sizeof(vendorID);
+                bRes = subKey.Query(vendorIDKeyName, REG_DWORD, (LPBYTE)&vendorID, &size);
+                DISPATCHER_LOG_OPERATION({
+                    if (bRes) {
+                        DISPATCHER_LOG_INFO((("loaded %S : 0x%x\n"), vendorIDKeyName, vendorID));
+                    }
+                    else {
+                        DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"),
+                                            vendorIDKeyName,
+                                            GetLastError()));
+                    }
+                })
+
+                if (bRes) {
+                    size = sizeof(deviceID);
+                    bRes = subKey.Query(deviceIDKeyName, REG_DWORD, (LPBYTE)&deviceID, &size);
+                    DISPATCHER_LOG_OPERATION({
+                        if (bRes) {
+                            DISPATCHER_LOG_INFO(
+                                (("loaded %S : 0x%x\n"), deviceIDKeyName, deviceID));
+                        }
+                        else {
+                            DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"),
+                                                deviceIDKeyName,
+                                                GetLastError()));
+                        }
+                    })
+                }
+                // query merit value
+                if (bRes) {
+                    size = sizeof(merit);
+                    bRes = subKey.Query(meritKeyName, REG_DWORD, (LPBYTE)&merit, &size);
+                    DISPATCHER_LOG_OPERATION({
+                        if (bRes) {
+                            DISPATCHER_LOG_INFO((("loaded %S : %d\n"), meritKeyName, merit));
+                        }
+                        else {
+                            DISPATCHER_LOG_WRN((("querying %S : RegQueryValueExA()==0x%x\n"),
+                                                meritKeyName,
+                                                GetLastError()));
+                        }
+                    })
+                }
+
+                // if the library fits required parameters,
+                // query the library's path
+                if (bRes) {
+                    // compare device's and library's IDs
+                    if (MFX_LIB_HARDWARE == m_implType) {
+                        if (m_vendorID != vendorID) {
+                            bRes = false;
+                            DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"),
+                                                vendorIDKeyName,
+                                                m_vendorID,
+                                                vendorID));
+                        }
+                        if (bRes && m_deviceID != deviceID) {
+                            bRes = false;
+                            DISPATCHER_LOG_WRN((("%S conflict, actual = 0x%x : required = 0x%x\n"),
+                                                deviceIDKeyName,
+                                                m_deviceID,
+                                                deviceID));
+                        }
+                    }
+
+                    DISPATCHER_LOG_OPERATION({
+                        if (bRes) {
+                            if (!(((m_lastLibMerit > merit) ||
+                                   ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
+                                  (libMerit < merit))) {
+                                DISPATCHER_LOG_WRN((
+                                    ("merit conflict: lastMerit = 0x%x, requiredMerit = 0x%x, libraryMerit = 0x%x, lastindex = %d, index = %d\n"),
+                                    m_lastLibMerit,
+                                    merit,
+                                    libMerit,
+                                    m_lastLibIndex,
+                                    index));
+                            }
+                        }
+                    })
+
+                    if ((bRes) &&
+                        ((m_lastLibMerit > merit) ||
+                         ((m_lastLibMerit == merit) && (m_lastLibIndex < index))) &&
+                        (libMerit < merit)) {
+                        wchar_t tmpPath[MFX_MAX_DLL_PATH];
+                        DWORD tmpPathSize = sizeof(tmpPath);
+
+                        bRes = subKey.Query(pathKeyName, REG_SZ, (LPBYTE)tmpPath, &tmpPathSize);
+                        if (!bRes) {
+                            DISPATCHER_LOG_WRN((("error querying %S : RegQueryValueExA()==0x%x\n"),
+                                                pathKeyName,
+                                                GetLastError()));
+                        }
+                        else {
+                            DISPATCHER_LOG_INFO((("loaded %S : %S\n"), pathKeyName, tmpPath));
+
+                            wcscpy_s(libPath, sizeof(libPath) / sizeof(libPath[0]), tmpPath);
+                            wcscpy_s(m_SubKeyName,
+                                     sizeof(m_SubKeyName) / sizeof(m_SubKeyName[0]),
+                                     subKeyName);
+
+                            libMerit = merit;
+                            libIndex = index;
+
+                            // set the library's type
+                            if ((0 == vendorID) || (0 == deviceID)) {
+                                *pImplType = MFX_LIB_SOFTWARE;
+                                DISPATCHER_LOG_INFO((("Library type is MFX_LIB_SOFTWARE\n")));
+                            }
+                            else {
+                                *pImplType = MFX_LIB_HARDWARE;
+                                DISPATCHER_LOG_INFO((("Library type is MFX_LIB_HARDWARE\n")));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // advance key index
+        index += 1;
+
+    } while (enumRes);
+
+    // if the library's path was successfully read,
+    // the merit variable holds valid value
+    if (0 == libMerit) {
+        return MFX_ERR_NOT_FOUND;
+    }
+
+    wcscpy_s(pPath, pathSize, libPath);
+
+    m_lastLibIndex   = libIndex;
+    m_lastLibMerit   = libMerit;
+    m_bIsSubKeyValid = true;
+
+#endif
+
+    return MFX_ERR_NONE;
+
+} // mfxStatus MFXLibraryIterator::SelectDLLVersion(wchar_t *pPath, size_t pathSize, eMfxImplType *pImplType, mfxVersion minVersion)
+
+mfxIMPL MFXLibraryIterator::GetImplementationType() {
+    return m_implInterface;
+} // mfxIMPL MFXLibraryIterator::GetImplementationType()
+
+bool MFXLibraryIterator::GetSubKeyName(wchar_t *subKeyName, size_t length) const {
+    wcscpy_s(subKeyName, length, m_SubKeyName);
+    return m_bIsSubKeyValid;
+}
+
+// lightweight implementation that takes deviceID as an argument, avoiding need to init the adapter
+mfxStatus MFXLibraryIterator::GetDriverStoreDir(std::wstring &driverStoreDir,
+                                                size_t length,
+                                                mfxU32 deviceID,
+                                                int storageID) {
+    wchar_t wcDir[MFX_MAX_DLL_PATH];
+    wcDir[0] = 0;
+
+    DriverStoreLoader dsLoader;
+
+    if (storageID == MFX_DRIVER_STORE_ONEVPL) {
+        // pass size of wcDir in bytes (see implementation of GetDriverStorePath)
+        if (!dsLoader.GetDriverStorePath(wcDir, sizeof(wcDir), deviceID, L"DriverStorePathForVPL"))
+            return MFX_ERR_UNSUPPORTED;
+    }
+    else if (storageID == MFX_DRIVER_STORE) {
+        if (!dsLoader.GetDriverStorePath(wcDir,
+                                         sizeof(wcDir),
+                                         deviceID,
+                                         L"DriverStorePathForMediaSDK"))
+            return MFX_ERR_UNSUPPORTED;
+    }
+
+    if (wcslen(wcDir) == 0)
+        return MFX_ERR_UNSUPPORTED;
+
+    // return path to driverStorDir
+    driverStoreDir = wcDir;
+
+    return MFX_ERR_NONE;
+}
+
+mfxStatus MFXLibraryIterator::GetRegkeyDir(std::wstring &regDir, size_t length, int storageID) {
+    mfxStatus sts = MFX_ERR_UNSUPPORTED;
+    MFX::MFXLibraryIterator libIterator;
+    wchar_t wRegDir[MFX_MAX_DLL_PATH];
+
+    regDir.clear();
+    sts = libIterator.Init(MFX_LIB_HARDWARE, MFX_IMPL_VIA_D3D11, 0, storageID);
+    if (sts)
+        return MFX_ERR_UNSUPPORTED;
+
+    eMfxImplType implType = MFX_LIB_HARDWARE;
+    mfxVersion ver        = { 0, 1 };
+    sts =
+        libIterator.SelectDLLVersion(wRegDir, sizeof(wRegDir) / sizeof(wRegDir[0]), &implType, ver);
+    if (sts)
+        return MFX_ERR_UNSUPPORTED;
+
+    // remove DLL name - only need the path
+    std::wstring s = wRegDir;
+    size_t f       = s.find_last_of('\\');
+    if (f == std::string::npos)
+        return MFX_ERR_UNSUPPORTED;
+
+    regDir = s.substr(0, f);
+
+    return MFX_ERR_NONE;
+}
+
+} // namespace MFX
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_library_iterator.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_library_iterator.h
new file mode 100644 (file)
index 0000000..801ba99
--- /dev/null
@@ -0,0 +1,145 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFX_LIBRARY_ITERATOR_H_
+#define DISPATCHER_WINDOWS_MFX_LIBRARY_ITERATOR_H_
+
+#include <string>
+
+#include "vpl/mfxvideo.h"
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    #include "mfx_win_reg_key.h"
+#endif
+
+#include "windows/mfx_dispatcher.h"
+#include "windows/mfx_driver_store_loader.h"
+
+namespace MFX {
+
+// declare desired storage ID
+enum {
+#if defined(MFX_TRACER_WA_FOR_DS)
+    MFX_UNKNOWN_KEY                 = -1,
+    MFX_TRACER                      = 0,
+    MFX_DRIVER_STORE_ONEVPL_MFXINIT = 1,
+    MFX_DRIVER_STORE                = 2,
+    MFX_CURRENT_USER_KEY            = 3,
+    MFX_LOCAL_MACHINE_KEY           = 4,
+    MFX_APP_FOLDER                  = 5,
+    MFX_PATH_MSDK_FOLDER            = 6,
+    MFX_STORAGE_ID_FIRST            = MFX_TRACER,
+    MFX_STORAGE_ID_LAST             = MFX_PATH_MSDK_FOLDER,
+#else
+    MFX_UNKNOWN_KEY       = -1,
+    MFX_DRIVER_STORE      = 0,
+    MFX_CURRENT_USER_KEY  = 1,
+    MFX_LOCAL_MACHINE_KEY = 2,
+    MFX_APP_FOLDER        = 3,
+    MFX_PATH_MSDK_FOLDER  = 4,
+    MFX_STORAGE_ID_FIRST  = MFX_DRIVER_STORE,
+    MFX_STORAGE_ID_LAST   = MFX_PATH_MSDK_FOLDER,
+#endif
+    MFX_DRIVER_STORE_ONEVPL      = 1001,
+    MFX_CURRENT_USER_KEY_ONEVPL  = 1002,
+    MFX_LOCAL_MACHINE_KEY_ONEVPL = 1003,
+};
+
+// Try to initialize using given implementation type. Select appropriate type automatically in case of MFX_IMPL_VIA_ANY.
+// Params: adapterNum - in, pImplInterface - in/out, pVendorID - out, pDeviceID - out, pLUID - out (optional)
+mfxStatus SelectImplementationType(const mfxU32 adapterNum,
+                                   mfxIMPL *pImplInterface,
+                                   mfxU32 *pVendorID,
+                                   mfxU32 *pDeviceID);
+
+mfxStatus SelectImplementationType(const mfxU32 adapterNum,
+                                   mfxIMPL *pImplInterface,
+                                   mfxU32 *pVendorID,
+                                   mfxU32 *pDeviceID,
+                                   mfxU64 *pLUID);
+
+bool GetImplPath(int storageID, wchar_t *sImplPath);
+
+const mfxU32 msdk_disp_path_len = 1024;
+
+class MFXLibraryIterator {
+public:
+    // Default constructor
+    MFXLibraryIterator(void);
+    // Destructor
+    ~MFXLibraryIterator(void);
+
+    // Initialize the iterator
+    mfxStatus Init(eMfxImplType implType,
+                   mfxIMPL implInterface,
+                   const mfxU32 adapterNum,
+                   int storageID);
+
+    // Get the next library path
+    mfxStatus SelectDLLVersion(wchar_t *pPath,
+                               size_t pathSize,
+                               eMfxImplType *pImplType,
+                               mfxVersion minVersion);
+
+    // Return interface type on which Intel adapter was found (if any): D3D9 or D3D11
+    mfxIMPL GetImplementationType();
+
+    // Retrun registry subkey name on which dll was selected after sucesfull call to selectDllVesion
+    bool GetSubKeyName(wchar_t *subKeyName, size_t length) const;
+
+    int GetStorageID() const {
+        return m_StorageID;
+    }
+
+    static mfxStatus GetDriverStoreDir(std::wstring &driverStoreDir,
+                                       size_t length,
+                                       mfxU32 deviceID,
+                                       int storageID);
+    static mfxStatus GetRegkeyDir(std::wstring &regDir, size_t length, int storageID);
+
+protected:
+    // Release the iterator
+    void Release(void);
+
+    // Initialize the registry iterator
+    mfxStatus InitRegistry(int storageID);
+#if defined(MFX_TRACER_WA_FOR_DS)
+    // Initialize the registry iterator for searching for tracer
+    mfxStatus InitRegistryTracer();
+#endif
+    // Initialize the app/module folder iterator
+    mfxStatus InitFolder(eMfxImplType implType, const wchar_t *path, const int storageID);
+
+    eMfxImplType m_implType; // Required library implementation
+    mfxIMPL m_implInterface; // Required interface (D3D9, D3D11)
+
+    mfxU32 m_vendorID; // (mfxU32) property of used graphic card
+    mfxU32 m_deviceID; // (mfxU32) property of used graphic card
+    bool m_bIsSubKeyValid;
+    wchar_t m_SubKeyName[MFX_MAX_REGISTRY_KEY_NAME]; // registry subkey for selected module loaded
+    int m_StorageID;
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    WinRegKey m_baseRegKey; // (WinRegKey) main registry key
+#endif
+
+    mfxU32 m_lastLibIndex; // (mfxU32) index of previously returned library
+    mfxU32 m_lastLibMerit; // (mfxU32) merit of previously returned library
+
+    wchar_t m_path[msdk_disp_path_len]; //NOLINT(runtime/arrays)
+    wchar_t m_driverStoreDir[msdk_disp_path_len]; //NOLINT(runtime/arrays)
+
+    DriverStoreLoader m_driverStoreLoader; // for loading MediaSDK from DriverStore
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    MFXLibraryIterator(const MFXLibraryIterator &);
+    void operator=(const MFXLibraryIterator &);
+};
+
+} // namespace MFX
+
+#endif // DISPATCHER_WINDOWS_MFX_LIBRARY_ITERATOR_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_load_dll.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_load_dll.cpp
new file mode 100644 (file)
index 0000000..bee4dcc
--- /dev/null
@@ -0,0 +1,196 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#include "windows/mfx_load_dll.h"
+#include "windows/mfx_dispatcher.h"
+
+#include <string.h>
+#include <wchar.h>
+#include <windows.h>
+
+#if defined(_WIN64)
+const wchar_t *const defaultDLLName[2]      = { L"libmfxhw64.dll", L"libvplswref64.dll" };
+const wchar_t *const defaultAudioDLLName[2] = { L"libmfxaudiosw64.dll", L"libmfxaudiosw64.dll" };
+const wchar_t *const defaultOneVPLDLLName   = { L"libmfx64-gen.dll" };
+
+const wchar_t *const defaultPluginDLLName[2] = { L"mfxplugin64_hw.dll", L"mfxplugin64_sw.dll" };
+    #if defined(MEDIASDK_UWP_DISPATCHER)
+const wchar_t *const IntelGFXAPIDLLName = { L"intel_gfx_api-x64.dll" };
+    #endif
+
+#elif defined(_WIN32)
+const wchar_t *const defaultDLLName[2] = { L"libmfxhw32.dll", L"libvplswref32.dll" };
+
+const wchar_t *const defaultAudioDLLName[2] = { L"libmfxaudiosw32.dll", L"libmfxaudiosw32.dll" };
+
+const wchar_t *const defaultOneVPLDLLName = { L"libmfx32-gen.dll" };
+
+const wchar_t *const defaultPluginDLLName[2] = { L"mfxplugin32_hw.dll", L"mfxplugin32_sw.dll" };
+
+    #if defined(MEDIASDK_UWP_DISPATCHER)
+const wchar_t *const IntelGFXAPIDLLName      = { L"intel_gfx_api-x86.dll" };
+    #endif
+
+#endif // (defined(_WIN64))
+
+namespace MFX {
+
+mfxStatus mfx_get_default_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType) {
+    if (!pPath) {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    // there are only 2 implementation with default DLL names
+#if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, defaultDLLName[implType & 1]) ? MFX_ERR_NONE
+                                                                        : MFX_ERR_UNKNOWN;
+#else
+    wcscpy(pPath, defaultDLLName[implType & 1]);
+    return MFX_ERR_NONE;
+#endif
+} // mfxStatus mfx_get_default_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType)
+
+mfxStatus mfx_get_default_onevpl_dll_name(wchar_t *pPath, size_t pathSize) {
+    if (!pPath) {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    // there are only 2 implementation with default DLL names
+#if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, defaultOneVPLDLLName) ? MFX_ERR_NONE : MFX_ERR_UNKNOWN;
+#else
+    wcscpy(pPath, defaultOneVPLDLLName);
+    return MFX_ERR_NONE;
+#endif
+} // mfxStatus mfx_get_default_onevpl_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType)
+
+#if defined(MEDIASDK_UWP_DISPATCHER)
+mfxStatus mfx_get_default_intel_gfx_api_dll_name(wchar_t *pPath, size_t pathSize) {
+    if (!pPath) {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    #if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, IntelGFXAPIDLLName) ? MFX_ERR_NONE : MFX_ERR_UNKNOWN;
+    #else
+    wcscpy(pPath, IntelGFXAPIDLLName);
+    return MFX_ERR_NONE;
+    #endif
+} // mfx_get_default_intel_gfx_api_dll_name(wchar_t *pPath, size_t pathSize)
+#endif
+
+mfxStatus mfx_get_default_plugin_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType) {
+    if (!pPath) {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    // there are only 2 implementation with default DLL names
+#if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, defaultPluginDLLName[implType & 1]) ? MFX_ERR_NONE
+                                                                              : MFX_ERR_UNKNOWN;
+#else
+    wcscpy(pPath, defaultPluginDLLName[implType & 1]);
+    return MFX_ERR_NONE;
+#endif
+}
+
+mfxStatus mfx_get_default_audio_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType) {
+    if (!pPath) {
+        return MFX_ERR_NULL_PTR;
+    }
+
+    // there are only 2 implementation with default DLL names
+#if _MSC_VER >= 1400
+    return 0 == wcscpy_s(pPath, pathSize, defaultAudioDLLName[implType & 1]) ? MFX_ERR_NONE
+                                                                             : MFX_ERR_UNKNOWN;
+#else
+    wcscpy(pPath, defaultAudioDLLName[implType & 1]);
+    return MFX_ERR_NONE;
+#endif
+} // mfxStatus mfx_get_default_audio_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType)
+
+mfxModuleHandle mfx_dll_load(const wchar_t *pFileName) {
+    mfxModuleHandle hModule = (mfxModuleHandle)0;
+
+    // check error(s)
+    if (NULL == pFileName) {
+        return NULL;
+    }
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    // set the silent error mode
+    DWORD prevErrorMode = 0;
+    #if (_WIN32_WINNT >= 0x0600)
+    SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode);
+    #else
+    prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+    #endif
+#endif // !defined(MEDIASDK_UWP_DISPATCHER)
+
+    // load the library's module
+#if !defined(MEDIASDK_ARM_LOADER)
+    hModule = LoadLibraryExW(pFileName, NULL, 0);
+#endif
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    // set the previous error mode
+    #if (_WIN32_WINNT >= 0x0600)
+    SetThreadErrorMode(prevErrorMode, NULL);
+    #else
+    SetErrorMode(prevErrorMode);
+    #endif
+#endif // !defined(MEDIASDK_UWP_DISPATCHER)
+
+    return hModule;
+
+} // mfxModuleHandle mfx_dll_load(const wchar_t *pFileName)
+
+mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *pFunctionName) {
+    if (NULL == handle) {
+        return NULL;
+    }
+
+    return (mfxFunctionPointer)GetProcAddress((HMODULE)handle, pFunctionName);
+} // mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *pFunctionName)
+
+bool mfx_dll_free(mfxModuleHandle handle) {
+    if (NULL == handle) {
+        return true;
+    }
+
+    BOOL bRes = FreeLibrary((HMODULE)handle);
+
+    return !!bRes;
+} // bool mfx_dll_free(mfxModuleHandle handle)
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+mfxModuleHandle mfx_get_dll_handle(const wchar_t *pFileName) {
+    mfxModuleHandle hModule = (mfxModuleHandle)0;
+
+    // check error(s)
+    if (NULL == pFileName) {
+        return NULL;
+    }
+
+    // set the silent error mode
+    DWORD prevErrorMode = 0;
+    #if (_WIN32_WINNT >= 0x0600)
+    SetThreadErrorMode(SEM_FAILCRITICALERRORS, &prevErrorMode);
+    #else
+    prevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
+    #endif
+    // load the library's module
+    GetModuleHandleExW(0, pFileName, (HMODULE *)&hModule);
+    // set the previous error mode
+    #if (_WIN32_WINNT >= 0x0600)
+    SetThreadErrorMode(prevErrorMode, NULL);
+    #else
+    SetErrorMode(prevErrorMode);
+    #endif
+    return hModule;
+}
+#endif //!defined(MEDIASDK_UWP_DISPATCHER)
+
+} // namespace MFX
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_load_dll.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_load_dll.h
new file mode 100644 (file)
index 0000000..fd4908b
--- /dev/null
@@ -0,0 +1,36 @@
+/*############################################################################
+  # Copyright (C) 2013-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFX_LOAD_DLL_H_
+#define DISPATCHER_WINDOWS_MFX_LOAD_DLL_H_
+
+#include "windows/mfx_dispatcher.h"
+
+namespace MFX {
+
+//
+// declare DLL loading routines
+//
+
+mfxStatus mfx_get_rt_dll_name(wchar_t *pPath, size_t pathSize);
+mfxStatus mfx_get_default_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType);
+mfxStatus mfx_get_default_onevpl_dll_name(wchar_t *pPath, size_t pathSize);
+mfxStatus mfx_get_default_plugin_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType);
+#if defined(MEDIASDK_UWP_DISPATCHER)
+mfxStatus mfx_get_default_intel_gfx_api_dll_name(wchar_t *pPath, size_t pathSize);
+#endif
+
+mfxStatus mfx_get_default_audio_dll_name(wchar_t *pPath, size_t pathSize, eMfxImplType implType);
+
+mfxModuleHandle mfx_dll_load(const wchar_t *file_name);
+//increments reference counter
+mfxModuleHandle mfx_get_dll_handle(const wchar_t *file_name);
+mfxFunctionPointer mfx_dll_get_addr(mfxModuleHandle handle, const char *func_name);
+bool mfx_dll_free(mfxModuleHandle handle);
+
+} // namespace MFX
+
+#endif // DISPATCHER_WINDOWS_MFX_LOAD_DLL_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_vector.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_vector.h
new file mode 100644 (file)
index 0000000..e1f4170
--- /dev/null
@@ -0,0 +1,159 @@
+/*############################################################################
+  # Copyright (C) 2013-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#pragma once
+#include <exception>
+#include "vpl/mfxstructures.h"
+
+namespace MFX {
+template <class T>
+class iterator_tmpl {
+    template <class U>
+    friend class MFXVector;
+    mfxU32 mIndex;
+    T *mRecords;
+    iterator_tmpl(mfxU32 index, T *records) : mIndex(index), mRecords(records) {}
+
+public:
+    iterator_tmpl() : mIndex(), mRecords() {}
+    bool operator==(const iterator_tmpl<T> &that) const {
+        return mIndex == that.mIndex;
+    }
+    bool operator!=(const iterator_tmpl<T> &that) const {
+        return mIndex != that.mIndex;
+    }
+    mfxU32 operator-(const iterator_tmpl<T> &that) const {
+        return mIndex - that.mIndex;
+    }
+    iterator_tmpl<T> &operator++() {
+        mIndex++;
+        return *this;
+    }
+    iterator_tmpl<T> &operator++(int) {
+        mIndex++;
+        return *this;
+    }
+    T &operator*() {
+        return mRecords[mIndex];
+    }
+    T *operator->() {
+        return mRecords + mIndex;
+    }
+};
+
+class MFXVectorRangeError : public std::exception {};
+
+template <class T>
+class MFXVector {
+    T *mRecords;
+    mfxU32 mNrecords;
+
+public:
+    MFXVector() : mRecords(), mNrecords() {}
+    MFXVector(const MFXVector &rhs) : mRecords(), mNrecords() {
+        insert(end(), rhs.begin(), rhs.end());
+    }
+    MFXVector &operator=(const MFXVector &rhs) {
+        if (this != &rhs) {
+            clear();
+            insert(end(), rhs.begin(), rhs.end());
+        }
+        return *this;
+    }
+    virtual ~MFXVector() {
+        clear();
+    }
+    typedef iterator_tmpl<T> iterator;
+
+    iterator begin() const {
+        return iterator(0u, mRecords);
+    }
+    iterator end() const {
+        return iterator(mNrecords, mRecords);
+    }
+    void insert(iterator where, iterator beg_iter, iterator end_iter) {
+        mfxU32 elementsToInsert = (end_iter - beg_iter);
+        if (!elementsToInsert) {
+            return;
+        }
+        if (where.mIndex > mNrecords) {
+            throw MFXVectorRangeError();
+        }
+
+        T *newRecords = new T[mNrecords + elementsToInsert]();
+        mfxU32 i      = 0;
+
+        // save left
+        for (; i < where.mIndex; i++) {
+            newRecords[i] = mRecords[i];
+        }
+        // insert
+        for (; beg_iter != end_iter; beg_iter++, i++) {
+            newRecords[i] = *beg_iter;
+        }
+
+        //save right
+        for (; i < mNrecords + elementsToInsert; i++) {
+            newRecords[i] = mRecords[i - elementsToInsert];
+        }
+
+        delete[] mRecords;
+
+        mRecords  = newRecords;
+        mNrecords = i;
+    }
+    T &operator[](mfxU32 idx) {
+        return mRecords[idx];
+    }
+    void push_back(const T &obj) {
+        T *newRecords = new T[mNrecords + 1]();
+        mfxU32 i      = 0;
+        for (; i < mNrecords; i++) {
+            newRecords[i] = mRecords[i];
+        }
+        newRecords[i] = obj;
+        delete[] mRecords;
+
+        mRecords  = newRecords;
+        mNrecords = i + 1;
+    }
+    void erase(iterator at) {
+        if (at.mIndex >= mNrecords) {
+            throw MFXVectorRangeError();
+        }
+        mNrecords--;
+        mfxU32 i = at.mIndex;
+        for (; i != mNrecords; i++) {
+            mRecords[i] = mRecords[i + 1];
+        }
+        //destroy last element
+        mRecords[i] = T();
+    }
+    void resize(mfxU32 nSize) {
+        T *newRecords = new T[nSize]();
+        for (mfxU32 i = 0; i < mNrecords; i++) {
+            newRecords[i] = mRecords[i];
+        }
+        delete[] mRecords;
+        mRecords  = newRecords;
+        mNrecords = nSize;
+    }
+    mfxU32 size() const {
+        return mNrecords;
+    }
+    void clear() {
+        delete[] mRecords;
+        mRecords  = 0;
+        mNrecords = 0;
+    }
+    bool empty() {
+        return !mRecords;
+    }
+    T *data() const {
+        return mRecords;
+    }
+};
+} // namespace MFX
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_win_reg_key.cpp b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_win_reg_key.cpp
new file mode 100644 (file)
index 0000000..8c46ab0
--- /dev/null
@@ -0,0 +1,198 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+    #include "windows/mfx_win_reg_key.h"
+    #include "windows/mfx_dispatcher_log.h"
+
+    #define TRACE_WINREG_ERROR(str, ...) DISPATCHER_LOG_ERROR((("[WINREG]: " str), __VA_ARGS__))
+
+namespace MFX {
+
+WinRegKey::WinRegKey(void) {
+    m_hKey = (HKEY)0;
+
+} // WinRegKey::WinRegKey(void)
+
+WinRegKey::~WinRegKey(void) {
+    Release();
+
+} // WinRegKey::~WinRegKey(void)
+
+void WinRegKey::Release(void) {
+    // close the opened key
+    if (m_hKey) {
+        RegCloseKey(m_hKey);
+    }
+
+    m_hKey = (HKEY)0;
+
+} // void WinRegKey::Release(void)
+
+bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired) {
+    LONG lRes;
+    HKEY hTemp;
+
+    //
+    // All operation are performed in this order by intention.
+    // It makes possible to reopen the keys, using itself as a base.
+    //
+
+    // try to the open registry key
+    lRes = RegOpenKeyExW(hRootKey, pSubKey, 0, samDesired, &hTemp);
+    if (ERROR_SUCCESS != lRes) {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR(
+            "Opening key \"%s\\%S\" : RegOpenKeyExW()==0x%x\n",
+            (HKEY_LOCAL_MACHINE == hRootKey)
+                ? ("HKEY_LOCAL_MACHINE")
+                : (HKEY_CURRENT_USER == hRootKey) ? ("HKEY_CURRENT_USER") : "UNSUPPORTED_KEY",
+            pSubKey,
+            GetLastError());
+        return false;
+    }
+
+    // release the object before initialization
+    Release();
+
+    // save the handle
+    m_hKey = hTemp;
+
+    return true;
+
+} // bool WinRegKey::Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired)
+
+bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired) {
+    return Open(rootKey.m_hKey, pSubKey, samDesired);
+
+} // bool WinRegKey::Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired)
+
+bool WinRegKey::QueryValueSize(const wchar_t *pValueName, DWORD type, LPDWORD pcbData) {
+    DWORD keyType = type;
+    LONG lRes;
+
+    // query the value
+    lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, 0, pcbData);
+    if (ERROR_SUCCESS != lRes) {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n",
+                           pValueName,
+                           GetLastError());
+        return false;
+    }
+
+    return true;
+}
+
+bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData) {
+    DWORD keyType = type;
+    LONG lRes;
+    DWORD dstSize = (pcbData) ? (*pcbData) : (0);
+
+    // query the value
+    lRes = RegQueryValueExW(m_hKey, pValueName, NULL, &keyType, pData, pcbData);
+    if (ERROR_SUCCESS != lRes) {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR("Querying \"%S\" : RegQueryValueExA()==0x%x\n",
+                           pValueName,
+                           GetLastError());
+        return false;
+    }
+
+    // check the type
+    if (keyType != type) {
+        TRACE_WINREG_ERROR("Querying \"%S\" : expectedType=%d, returned=%d\n",
+                           pValueName,
+                           type,
+                           keyType);
+        return false;
+    }
+
+    // terminate the string only if pointers not NULL
+    if ((REG_SZ == type || REG_EXPAND_SZ == type) && NULL != pData && NULL != pcbData) {
+        wchar_t *pString           = (wchar_t *)pData;
+        size_t NullEndingSizeBytes = sizeof(wchar_t); // size of string termination null character
+        if (dstSize < NullEndingSizeBytes) {
+            TRACE_WINREG_ERROR("Querying \"%S\" : buffer is too small for null-terminated string",
+                               pValueName);
+            return false;
+        }
+        size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes;
+        size_t maxStringIndex       = dstSize / sizeof(wchar_t) - 1;
+
+        size_t lastIndex =
+            (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t);
+
+        pString[lastIndex] = (wchar_t)0;
+    }
+    else if (REG_MULTI_SZ == type && NULL != pData && NULL != pcbData) {
+        wchar_t *pString = (wchar_t *)pData;
+        size_t NullEndingSizeBytes =
+            sizeof(wchar_t) * 2; // size of string termination null characters
+        if (dstSize < NullEndingSizeBytes) {
+            TRACE_WINREG_ERROR(
+                "Querying \"%S\" : buffer is too small for multi-line null-terminated string",
+                pValueName);
+            return false;
+        }
+        size_t maxStringLengthBytes = dstSize - NullEndingSizeBytes;
+        size_t maxStringIndex       = dstSize / sizeof(wchar_t) - 1;
+
+        size_t lastIndex =
+            (maxStringLengthBytes < *pcbData) ? (maxStringIndex) : (*pcbData) / sizeof(wchar_t) + 1;
+
+        // last 2 bytes should be 0 in case of REG_MULTI_SZ
+        pString[lastIndex] = pString[lastIndex - 1] = (wchar_t)0;
+    }
+
+    return true;
+
+} // bool WinRegKey::Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData)
+
+bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType) {
+    LONG lRes;
+
+    // enum the values
+    lRes = RegEnumValueW(m_hKey, index, pValueName, pcchValueName, 0, pType, NULL, NULL);
+    if (ERROR_SUCCESS != lRes) {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        return false;
+    }
+
+    return true;
+
+} // bool WinRegKey::EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType)
+
+bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName) {
+    LONG lRes;
+
+    // enum the keys
+    lRes = RegEnumKeyExW(m_hKey, index, pValueName, pcchValueName, NULL, NULL, NULL, NULL);
+    if (ERROR_SUCCESS != lRes) {
+        DISPATCHER_LOG_OPERATION(SetLastError(lRes));
+        TRACE_WINREG_ERROR("EnumKey with index=%d: RegEnumKeyExW()==0x%x\n", index, GetLastError());
+        return false;
+    }
+
+    return true;
+
+} // bool WinRegKey::EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName)
+
+bool WinRegKey::QueryInfo(LPDWORD lpcSubkeys) {
+    LONG lRes;
+
+    lRes = RegQueryInfoKeyW(m_hKey, NULL, 0, 0, lpcSubkeys, 0, 0, 0, 0, 0, 0, 0);
+    if (ERROR_SUCCESS != lRes) {
+        TRACE_WINREG_ERROR("RegQueryInfoKeyW()==0x%x\n", lRes);
+        return false;
+    }
+    return true;
+
+} //bool QueryInfo(LPDWORD lpcSubkeys);
+
+} // namespace MFX
+
+#endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_win_reg_key.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfx_win_reg_key.h
new file mode 100644 (file)
index 0000000..70d144e
--- /dev/null
@@ -0,0 +1,99 @@
+/*############################################################################
+  # Copyright (C) 2012-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFX_WIN_REG_KEY_H_
+#define DISPATCHER_WINDOWS_MFX_WIN_REG_KEY_H_
+
+#include <windows.h>
+#include "vpl/mfxcommon.h"
+#include "windows/mfx_dispatcher_log.h"
+
+#if !defined(MEDIASDK_UWP_DISPATCHER)
+namespace MFX {
+
+template <class T>
+struct RegKey {};
+template <>
+struct RegKey<bool> {
+    enum { type = REG_DWORD };
+};
+template <>
+struct RegKey<mfxU32> {
+    enum { type = REG_DWORD };
+};
+template <>
+struct RegKey<mfxVersion> {
+    enum { type = REG_DWORD };
+};
+template <>
+struct RegKey<char *> {
+    enum { type = REG_SZ };
+};
+template <>
+struct RegKey<wchar_t *> {
+    enum { type = REG_SZ };
+};
+
+class WinRegKey {
+public:
+    // Default constructor
+    WinRegKey(void);
+    // Destructor
+    ~WinRegKey(void);
+
+    // Open a registry key
+    bool Open(HKEY hRootKey, const wchar_t *pSubKey, REGSAM samDesired);
+    bool Open(WinRegKey &rootKey, const wchar_t *pSubKey, REGSAM samDesired);
+
+    // Query value
+    bool QueryInfo(LPDWORD lpcSubkeys);
+
+    bool QueryValueSize(const wchar_t *pValueName, DWORD type, LPDWORD pcbData);
+    bool Query(const wchar_t *pValueName, DWORD type, LPBYTE pData, LPDWORD pcbData);
+
+    bool Query(const wchar_t *pValueName, wchar_t *pData, mfxU32 &nData) {
+        DWORD dw = (DWORD)nData;
+        if (!Query(pValueName, RegKey<wchar_t *>::type, (LPBYTE)pData, &dw)) {
+            return false;
+        }
+        nData = dw;
+        return true;
+    }
+
+    // Enumerate value names
+    bool EnumValue(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName, LPDWORD pType);
+    bool EnumKey(DWORD index, wchar_t *pValueName, LPDWORD pcchValueName);
+
+protected:
+    // Release the object
+    void Release(void);
+
+    HKEY m_hKey; // (HKEY) handle to the opened key
+
+private:
+    // unimplemented by intent to make this class non-copyable
+    WinRegKey(const WinRegKey &);
+    void operator=(const WinRegKey &);
+};
+
+template <class T>
+inline bool QueryKey(WinRegKey &key, const wchar_t *pValueName, T &data) {
+    DWORD size = sizeof(data);
+    return key.Query(pValueName, RegKey<T>::type, (LPBYTE)&data, &size);
+}
+
+template <>
+inline bool QueryKey<bool>(WinRegKey &key, const wchar_t *pValueName, bool &data) {
+    mfxU32 value = 0;
+    bool bRes    = QueryKey(key, pValueName, value);
+    data         = (1 == value);
+    return bRes;
+}
+
+} // namespace MFX
+#endif // #if !defined(MEDIASDK_UWP_DISPATCHER)
+
+#endif // DISPATCHER_WINDOWS_MFX_WIN_REG_KEY_H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfxvideo++.h b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/mfxvideo++.h
new file mode 100644 (file)
index 0000000..ae3fd01
--- /dev/null
@@ -0,0 +1,222 @@
+/*############################################################################
+  # Copyright (C) 2017-2020 Intel Corporation
+  #
+  # SPDX-License-Identifier: MIT
+  ############################################################################*/
+
+#ifndef DISPATCHER_WINDOWS_MFXVIDEO___H_
+#define DISPATCHER_WINDOWS_MFXVIDEO___H_
+
+#include "vpl/mfxvideo.h"
+
+class MFXVideoSession {
+public:
+    MFXVideoSession(void) {
+        m_session = (mfxSession)0;
+    }
+    virtual ~MFXVideoSession(void) {
+        Close();
+    }
+
+    virtual mfxStatus Init(mfxIMPL impl, mfxVersion *ver) {
+        return MFXInit(impl, ver, &m_session);
+    }
+    virtual mfxStatus InitEx(mfxInitParam par) {
+        return MFXInitEx(par, &m_session);
+    }
+    virtual mfxStatus Close(void) {
+        mfxStatus mfxRes;
+        mfxRes    = MFXClose(m_session);
+        m_session = (mfxSession)0;
+        return mfxRes;
+    }
+
+    virtual mfxStatus QueryIMPL(mfxIMPL *impl) {
+        return MFXQueryIMPL(m_session, impl);
+    }
+    virtual mfxStatus QueryVersion(mfxVersion *version) {
+        return MFXQueryVersion(m_session, version);
+    }
+
+    virtual mfxStatus JoinSession(mfxSession child_session) {
+        return MFXJoinSession(m_session, child_session);
+    }
+    virtual mfxStatus DisjoinSession() {
+        return MFXDisjoinSession(m_session);
+    }
+    virtual mfxStatus CloneSession(mfxSession *clone) {
+        return MFXCloneSession(m_session, clone);
+    }
+    virtual mfxStatus SetPriority(mfxPriority priority) {
+        return MFXSetPriority(m_session, priority);
+    }
+    virtual mfxStatus GetPriority(mfxPriority *priority) {
+        return MFXGetPriority(m_session, priority);
+    }
+
+    virtual mfxStatus SetFrameAllocator(mfxFrameAllocator *allocator) {
+        return MFXVideoCORE_SetFrameAllocator(m_session, allocator);
+    }
+    virtual mfxStatus SetHandle(mfxHandleType type, mfxHDL hdl) {
+        return MFXVideoCORE_SetHandle(m_session, type, hdl);
+    }
+    virtual mfxStatus GetHandle(mfxHandleType type, mfxHDL *hdl) {
+        return MFXVideoCORE_GetHandle(m_session, type, hdl);
+    }
+    virtual mfxStatus QueryPlatform(mfxPlatform *platform) {
+        return MFXVideoCORE_QueryPlatform(m_session, platform);
+    }
+
+    virtual mfxStatus SyncOperation(mfxSyncPoint syncp, mfxU32 wait) {
+        return MFXVideoCORE_SyncOperation(m_session, syncp, wait);
+    }
+
+    virtual operator mfxSession(void) {
+        return m_session;
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+private:
+    MFXVideoSession(const MFXVideoSession &);
+    void operator=(MFXVideoSession &);
+};
+
+class MFXVideoENCODE {
+public:
+    explicit MFXVideoENCODE(mfxSession session) {
+        m_session = session;
+    }
+    virtual ~MFXVideoENCODE(void) {
+        Close();
+    }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) {
+        return MFXVideoENCODE_Query(m_session, in, out);
+    }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) {
+        return MFXVideoENCODE_QueryIOSurf(m_session, par, request);
+    }
+    virtual mfxStatus Init(mfxVideoParam *par) {
+        return MFXVideoENCODE_Init(m_session, par);
+    }
+    virtual mfxStatus Reset(mfxVideoParam *par) {
+        return MFXVideoENCODE_Reset(m_session, par);
+    }
+    virtual mfxStatus Close(void) {
+        return MFXVideoENCODE_Close(m_session);
+    }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) {
+        return MFXVideoENCODE_GetVideoParam(m_session, par);
+    }
+    virtual mfxStatus GetEncodeStat(mfxEncodeStat *stat) {
+        return MFXVideoENCODE_GetEncodeStat(m_session, stat);
+    }
+
+    virtual mfxStatus EncodeFrameAsync(mfxEncodeCtrl *ctrl,
+                                       mfxFrameSurface1 *surface,
+                                       mfxBitstream *bs,
+                                       mfxSyncPoint *syncp) {
+        return MFXVideoENCODE_EncodeFrameAsync(m_session, ctrl, surface, bs, syncp);
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+};
+
+class MFXVideoDECODE {
+public:
+    explicit MFXVideoDECODE(mfxSession session) {
+        m_session = session;
+    }
+    virtual ~MFXVideoDECODE(void) {
+        Close();
+    }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) {
+        return MFXVideoDECODE_Query(m_session, in, out);
+    }
+    virtual mfxStatus DecodeHeader(mfxBitstream *bs, mfxVideoParam *par) {
+        return MFXVideoDECODE_DecodeHeader(m_session, bs, par);
+    }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest *request) {
+        return MFXVideoDECODE_QueryIOSurf(m_session, par, request);
+    }
+    virtual mfxStatus Init(mfxVideoParam *par) {
+        return MFXVideoDECODE_Init(m_session, par);
+    }
+    virtual mfxStatus Reset(mfxVideoParam *par) {
+        return MFXVideoDECODE_Reset(m_session, par);
+    }
+    virtual mfxStatus Close(void) {
+        return MFXVideoDECODE_Close(m_session);
+    }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) {
+        return MFXVideoDECODE_GetVideoParam(m_session, par);
+    }
+
+    virtual mfxStatus GetDecodeStat(mfxDecodeStat *stat) {
+        return MFXVideoDECODE_GetDecodeStat(m_session, stat);
+    }
+    virtual mfxStatus GetPayload(mfxU64 *ts, mfxPayload *payload) {
+        return MFXVideoDECODE_GetPayload(m_session, ts, payload);
+    }
+    virtual mfxStatus SetSkipMode(mfxSkipMode mode) {
+        return MFXVideoDECODE_SetSkipMode(m_session, mode);
+    }
+    virtual mfxStatus DecodeFrameAsync(mfxBitstream *bs,
+                                       mfxFrameSurface1 *surface_work,
+                                       mfxFrameSurface1 **surface_out,
+                                       mfxSyncPoint *syncp) {
+        return MFXVideoDECODE_DecodeFrameAsync(m_session, bs, surface_work, surface_out, syncp);
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+};
+
+class MFXVideoVPP {
+public:
+    explicit MFXVideoVPP(mfxSession session) {
+        m_session = session;
+    }
+    virtual ~MFXVideoVPP(void) {
+        Close();
+    }
+
+    virtual mfxStatus Query(mfxVideoParam *in, mfxVideoParam *out) {
+        return MFXVideoVPP_Query(m_session, in, out);
+    }
+    virtual mfxStatus QueryIOSurf(mfxVideoParam *par, mfxFrameAllocRequest request[2]) {
+        return MFXVideoVPP_QueryIOSurf(m_session, par, request);
+    }
+    virtual mfxStatus Init(mfxVideoParam *par) {
+        return MFXVideoVPP_Init(m_session, par);
+    }
+    virtual mfxStatus Reset(mfxVideoParam *par) {
+        return MFXVideoVPP_Reset(m_session, par);
+    }
+    virtual mfxStatus Close(void) {
+        return MFXVideoVPP_Close(m_session);
+    }
+
+    virtual mfxStatus GetVideoParam(mfxVideoParam *par) {
+        return MFXVideoVPP_GetVideoParam(m_session, par);
+    }
+    virtual mfxStatus GetVPPStat(mfxVPPStat *stat) {
+        return MFXVideoVPP_GetVPPStat(m_session, stat);
+    }
+    virtual mfxStatus RunFrameVPPAsync(mfxFrameSurface1 *in,
+                                       mfxFrameSurface1 *out,
+                                       mfxExtVppAuxData *aux,
+                                       mfxSyncPoint *syncp) {
+        return MFXVideoVPP_RunFrameVPPAsync(m_session, in, out, aux, syncp);
+    }
+
+protected:
+    mfxSession m_session; // (mfxSession) handle to the owning session
+};
+
+#endif // DISPATCHER_WINDOWS_MFXVIDEO___H_
diff --git a/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/version.rc.in b/subprojects/gst-plugins-bad/sys/qsv/libmfx/dispatcher/windows/version.rc.in
new file mode 100644 (file)
index 0000000..12e8a68
--- /dev/null
@@ -0,0 +1,30 @@
+#include "winver.h"
+#define VER_FILEVERSION             @API_VERSION_MAJOR@,@API_VERSION_MINOR@,0,0
+#define VER_FILEVERSION_STR         "@API_VERSION_MAJOR@.@API_VERSION_MINOR@.0.0\0"
+
+#define VER_PRODUCTVERSION          @oneVPL_VERSION_MAJOR@,@oneVPL_VERSION_MINOR@,0,0
+#define VER_PRODUCTVERSION_STR      "@oneVPL_VERSION_MAJOR@.@oneVPL_VERSION_MINOR@\0"
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION     VER_FILEVERSION
+PRODUCTVERSION  VER_PRODUCTVERSION
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904E4"
+        BEGIN
+            VALUE "CompanyName",      "Intel\0"
+            VALUE "FileDescription",  "oneVPL Dispatcher\0"
+            VALUE "FileVersion",      VER_FILEVERSION_STR
+            // Copyright year is the first publication date. Subsequent dates are optional
+            VALUE "LegalCopyright",   "Copyright (C) 2021 Intel Corporation\0"
+            VALUE "ProductName",      "VPL\0"
+            VALUE "ProductVersion",   VER_PRODUCTVERSION_STR
+        END
+    END
+
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1252
+    END
+END
\ No newline at end of file