Sfoglia il codice sorgente

obs-qsv11: Add VPL changes

Gale 2 anni fa
parent
commit
dbbbcd8c57

+ 115 - 19
cmake/Modules/FindVPL.cmake

@@ -1,47 +1,143 @@
-# * Try to find libvpl
-#
-# Once done this will define
-#
-# VPL_FOUND - system has intel media sdk VPL_INCLUDE_DIRS - the intel media sdk include directory VPL_LIBRARIES - the
-# libraries needed to use intel media sdk VPL_DEFINITIONS - Compiler switches required for using intel media sdk
+#[=======================================================================[.rst
+FindVPL
+-------
 
-# Use pkg-config to get the directories and then use these values in the find_path() and find_library() calls
+FindModule for VPL and associated headers
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.0
+
+This module defines the :prop_tgt:`IMPORTED` target ``VPL::VPL``.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module sets the following variables:
+
+``VPL_FOUND``
+  True, if headers were found.
+``VPL_VERSION``
+  Detected version of found VPL headers.
+``VPL_LIBRARIES``
+  Libraries needed to link to VPL.
+
+Cache variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``VPL_INCLUDE_DIR``
+  Directory containing ``mfxdispatcher.h``.
+``VPL_LIBRARY_RELEASE``
+  Path to the library component of VPL in non-debug configuration.
+``VPL_LIBRARY_DEBUG``
+  Optional path to the library component of VPL in debug configuration.
+
+#]=======================================================================]
+
+# cmake-format: off
+# cmake-lint: disable=C0103
+# cmake-lint: disable=C0301
+# cmake-format: on
 
 find_package(PkgConfig QUIET)
 if(PKG_CONFIG_FOUND)
-  pkg_check_modules(_VPL vpl)
+  pkg_search_module(_VPL QUIET vpl)
 endif()
 
 find_path(
   VPL_INCLUDE_DIR
-  NAMES mfxstructures.h
+  NAMES vpl/mfxstructures.h
   HINTS ${_VPL_INCLUDE_DIRS} ${_VPL_INCLUDE_DIRS}
   PATHS /usr/include /usr/local/include /opt/local/include /sw/include
-  PATH_SUFFIXES vpl/)
+  DOC "VPL include directory")
 
 find_library(
-  VPL_LIB
+  VPL_LIBRARY_RELEASE
   NAMES ${_VPL_LIBRARIES} ${_VPL_LIBRARIES} vpl
   HINTS ${_VPL_LIBRARY_DIRS} ${_VPL_LIBRARY_DIRS}
-  PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib)
+  PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib
+  DOC "VPL library location")
+
+find_library(
+  VPL_LIBRARY_DEBUG
+  NAMES ${_VPL_LIBRARIES} ${_VPL_LIBRARIES} vpld
+  HINTS ${_VPL_LIBRARY_DIRS} ${_VPL_LIBRARY_DIRS}
+  PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib
+  DOC "VPL debug library location")
+
+include(SelectLibraryConfigurations)
+select_library_configurations(VPL)
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(VPL REQUIRED_VARS VPL_LIB VPL_INCLUDE_DIR)
-mark_as_advanced(VPL_INCLUDE_DIR VPL_LIB)
+find_package_handle_standard_args(
+  VPL
+  REQUIRED_VARS VPL_LIBRARY VPL_INCLUDE_DIR
+  VERSION_VAR VPL_VERSION REASON_FAILURE_MESSAGE "${VPL_ERROR_REASON}")
+mark_as_advanced(VPL_INCLUDE_DIR VPL_LIBRARY)
+unset(VPL_ERROR_REASON)
+
+if(EXISTS "${VPL_INCLUDE_DIR}/vpl/mfxdefs.h")
+  file(STRINGS "${VPL_INCLUDE_DIR}/vpl/mfxdefs.h" _version_string REGEX "^.*VERSION_(MAJOR|MINOR)[ \t]+[0-9]+[ \t]*$")
+
+  string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}")
+  string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}")
+
+  set(VPL_VERSION "${_version_major}.${_version_minor}")
+  unset(_version_major)
+  unset(_version_minor)
+else()
+  if(NOT VPL_FIND_QUIETLY)
+    message(AUTHOR_WARNING "Failed to find VPL version.")
+  endif()
+  set(VPL_VERSION 0.0.0)
+endif()
+
+if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows")
+  set(VPL_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.")
+elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD")
+  set(VPL_ERROR_REASON "Ensure VPL headers are available in local library paths.")
+endif()
 
 if(VPL_FOUND)
   set(VPL_INCLUDE_DIRS ${VPL_INCLUDE_DIR})
-  set(VPL_LIBRARIES ${VPL_LIB})
+  set(VPL_LIBRARIES ${VPL_LIBRARY})
 
   if(NOT TARGET VPL::VPL)
-    if(IS_ABSOLUTE "${VPL_LIBRARIES}")
+    if(IS_ABSOLUTE "${VPL_LIBRARY_RELEASE}")
       add_library(VPL::VPL UNKNOWN IMPORTED)
-      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LOCATION "${VPL_LIBRARIES}")
+      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LOCATION "${VPL_LIBRARY_RELEASE}")
     else()
       add_library(VPL::VPL INTERFACE IMPORTED)
-      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LIBNAME "${VPL_LIBRARIES}")
+      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LIBNAME "${VPL_LIBRARY_RELEASE}")
     endif()
 
-    set_target_properties(VPL::VPL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${VPL_INCLUDE_DIRS}")
+    set_target_properties(
+      VPL::VPL
+      PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${VPL_INCLUDE_DIRS}"
+                 VERSION ${VPL_VERSION}
+                 IMPORTED_CONFIGURATIONS Release)
+
+    if(VPL_LIBRARY_DEBUG)
+      if(IS_ABSOLUTE "${VPL_LIBRARY_DEBUG}")
+        set_target_properties(VPL::VPL PROPERTIES IMPORTED_LOCATION_DEBUG "${VPL_LIBRARY_DEBUG}")
+      else()
+        set_target_properties(VPL::VPL PROPERTIES IMPORTED_LIBNAME_DEBUG "${VPL_LIBRARY_DEBUG}")
+      endif()
+      set_property(
+        TARGET VPL::VPL
+        APPEND
+        PROPERTY IMPORTED_CONFIGURATIONS Debug)
+    endif()
   endif()
 endif()
+
+include(FeatureSummary)
+set_package_properties(
+  VPL PROPERTIES
+  URL "https://github.com/oneapi-src/oneVPL"
+  DESCRIPTION
+    "Intel® oneAPI Video Processing Library (oneVPL) supports AI visual inference, media delivery, cloud gaming, and virtual desktop infrastructure use cases by providing access to hardware accelerated video decode, encode, and frame processing capabilities on Intel® GPUs."
+)

+ 143 - 0
cmake/finders/FindVPL.cmake

@@ -0,0 +1,143 @@
+#[=======================================================================[.rst
+FindVPL
+-------
+
+FindModule for VPL and associated headers
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.0
+
+This module defines the :prop_tgt:`IMPORTED` target ``VPL::VPL``.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module sets the following variables:
+
+``VPL_FOUND``
+  True, if headers were found.
+``VPL_VERSION``
+  Detected version of found VPL headers.
+``VPL_LIBRARIES``
+  Libraries needed to link to VPL.
+
+Cache variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``VPL_INCLUDE_DIR``
+  Directory containing ``mfxdispatcher.h``.
+``VPL_LIBRARY_RELEASE``
+  Path to the library component of VPL in non-debug configuration.
+``VPL_LIBRARY_DEBUG``
+  Optional path to the library component of VPL in debug configuration.
+
+#]=======================================================================]
+
+# cmake-format: off
+# cmake-lint: disable=C0103
+# cmake-lint: disable=C0301
+# cmake-format: on
+
+find_package(PkgConfig QUIET)
+if(PKG_CONFIG_FOUND)
+  pkg_search_module(_VPL QUIET vpl)
+endif()
+
+find_path(
+  VPL_INCLUDE_DIR
+  NAMES vpl/mfxstructures.h
+  HINTS ${_VPL_INCLUDE_DIRS} ${_VPL_INCLUDE_DIRS}
+  PATHS /usr/include /usr/local/include /opt/local/include /sw/include
+  DOC "VPL include directory")
+
+find_library(
+  VPL_LIBRARY_RELEASE
+  NAMES ${_VPL_LIBRARIES} ${_VPL_LIBRARIES} vpl
+  HINTS ${_VPL_LIBRARY_DIRS} ${_VPL_LIBRARY_DIRS}
+  PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib
+  DOC "VPL library location")
+
+find_library(
+  VPL_LIBRARY_DEBUG
+  NAMES ${_VPL_LIBRARIES} ${_VPL_LIBRARIES} vpld
+  HINTS ${_VPL_LIBRARY_DIRS} ${_VPL_LIBRARY_DIRS}
+  PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib
+  DOC "VPL debug library location")
+
+include(SelectLibraryConfigurations)
+select_library_configurations(VPL)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  VPL
+  REQUIRED_VARS VPL_LIBRARY VPL_INCLUDE_DIR
+  VERSION_VAR VPL_VERSION REASON_FAILURE_MESSAGE "${VPL_ERROR_REASON}")
+mark_as_advanced(VPL_INCLUDE_DIR VPL_LIBRARY)
+unset(VPL_ERROR_REASON)
+
+if(EXISTS "${VPL_INCLUDE_DIR}/vpl/mfxdefs.h")
+  file(STRINGS "${VPL_INCLUDE_DIR}/vpl/mfxdefs.h" _version_string REGEX "^.*VERSION_(MAJOR|MINOR)[ \t]+[0-9]+[ \t]*$")
+
+  string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}")
+  string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}")
+
+  set(VPL_VERSION "${_version_major}.${_version_minor}")
+  unset(_version_major)
+  unset(_version_minor)
+else()
+  if(NOT VPL_FIND_QUIETLY)
+    message(AUTHOR_WARNING "Failed to find VPL version.")
+  endif()
+  set(VPL_VERSION 0.0.0)
+endif()
+
+if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows")
+  set(VPL_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.")
+elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD")
+  set(VPL_ERROR_REASON "Ensure VPL headers are available in local library paths.")
+endif()
+
+if(VPL_FOUND)
+  set(VPL_INCLUDE_DIRS ${VPL_INCLUDE_DIR})
+  set(VPL_LIBRARIES ${VPL_LIBRARY})
+
+  if(NOT TARGET VPL::VPL)
+    if(IS_ABSOLUTE "${VPL_LIBRARY_RELEASE}")
+      add_library(VPL::VPL UNKNOWN IMPORTED)
+      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LOCATION "${VPL_LIBRARY_RELEASE}")
+    else()
+      add_library(VPL::VPL INTERFACE IMPORTED)
+      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LIBNAME "${VPL_LIBRARY_RELEASE}")
+    endif()
+
+    set_target_properties(
+      VPL::VPL
+      PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${VPL_INCLUDE_DIRS}"
+                 VERSION ${VPL_VERSION}
+                 IMPORTED_CONFIGURATIONS Release)
+
+    if(VPL_LIBRARY_DEBUG)
+      if(IS_ABSOLUTE "${VPL_LIBRARY_DEBUG}")
+        set_target_properties(VPL::VPL PROPERTIES IMPORTED_LOCATION_DEBUG "${VPL_LIBRARY_DEBUG}")
+      else()
+        set_target_properties(VPL::VPL PROPERTIES IMPORTED_LIBNAME_DEBUG "${VPL_LIBRARY_DEBUG}")
+      endif()
+      set_property(
+        TARGET VPL::VPL
+        APPEND
+        PROPERTY IMPORTED_CONFIGURATIONS Debug)
+    endif()
+  endif()
+endif()
+
+include(FeatureSummary)
+set_package_properties(
+  VPL PROPERTIES
+  URL "https://github.com/oneapi-src/oneVPL"
+  DESCRIPTION
+    "Intel® oneAPI Video Processing Library (oneVPL) supports AI visual inference, media delivery, cloud gaming, and virtual desktop infrastructure use cases by providing access to hardware accelerated video decode, encode, and frame processing capabilities on Intel® GPUs."
+)

+ 6 - 66
plugins/obs-qsv11/CMakeLists.txt

@@ -12,6 +12,8 @@ endif()
 add_library(obs-qsv11 MODULE)
 add_library(OBS::qsv11 ALIAS obs-qsv11)
 
+find_package(VPL 2.6 REQUIRED)
+
 target_sources(
   obs-qsv11
   PRIVATE # cmake-format: sortable
@@ -24,7 +26,7 @@ target_sources(
           QSV_Encoder_Internal.cpp
           QSV_Encoder_Internal.h)
 
-target_link_libraries(obs-qsv11 PRIVATE OBS::libobs)
+target_link_libraries(obs-qsv11 PRIVATE OBS::libobs VPL::VPL)
 
 # cmake-format: off
 set_target_properties_obs(obs-qsv11 PROPERTIES FOLDER plugins/obs-qsv11 PREFIX "")
@@ -33,62 +35,6 @@ set_target_properties_obs(obs-qsv11 PROPERTIES FOLDER plugins/obs-qsv11 PREFIX "
 if(OS_WINDOWS)
   add_subdirectory(obs-qsv-test)
 
-  add_library(libmfx INTERFACE)
-  add_library(OBS::libmfx ALIAS libmfx)
-
-  target_sources(
-    libmfx
-    INTERFACE # cmake-format: sortable
-              libmfx/include/mfx_critical_section.h
-              libmfx/include/mfx_dispatcher.h
-              libmfx/include/mfx_dispatcher_defs.h
-              libmfx/include/mfx_dispatcher_log.h
-              libmfx/include/mfx_driver_store_loader.h
-              libmfx/include/mfx_dxva2_device.h
-              libmfx/include/mfx_exposed_functions_list.h
-              libmfx/include/mfx_library_iterator.h
-              libmfx/include/mfx_load_dll.h
-              libmfx/include/mfx_load_plugin.h
-              libmfx/include/mfx_plugin_hive.h
-              libmfx/include/mfx_vector.h
-              libmfx/include/mfx_win_reg_key.h
-              libmfx/include/mfxaudio_exposed_functions_list.h
-              libmfx/include/msdk/include/mfxadapter.h
-              libmfx/include/msdk/include/mfxastructures.h
-              libmfx/include/msdk/include/mfxaudio++.h
-              libmfx/include/msdk/include/mfxaudio.h
-              libmfx/include/msdk/include/mfxcommon.h
-              libmfx/include/msdk/include/mfxdefs.h
-              libmfx/include/msdk/include/mfxjpeg.h
-              libmfx/include/msdk/include/mfxmvc.h
-              libmfx/include/msdk/include/mfxplugin++.h
-              libmfx/include/msdk/include/mfxplugin.h
-              libmfx/include/msdk/include/mfxsession.h
-              libmfx/include/msdk/include/mfxstructures.h
-              libmfx/include/msdk/include/mfxvideo++.h
-              libmfx/include/msdk/include/mfxvideo.h
-              libmfx/include/msdk/include/mfxvstructures.h
-              libmfx/src/main.cpp
-              libmfx/src/mfx_critical_section.cpp
-              libmfx/src/mfx_dispatcher.cpp
-              libmfx/src/mfx_dispatcher_log.cpp
-              libmfx/src/mfx_driver_store_loader.cpp
-              libmfx/src/mfx_dxva2_device.cpp
-              libmfx/src/mfx_function_table.cpp
-              libmfx/src/mfx_library_iterator.cpp
-              libmfx/src/mfx_load_dll.cpp
-              libmfx/src/mfx_load_plugin.cpp
-              libmfx/src/mfx_plugin_hive.cpp
-              libmfx/src/mfx_win_reg_key.cpp)
-
-  target_include_directories(libmfx INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include/msdk/include"
-                                              "${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include")
-  get_target_property(mfx_sources libmfx SOURCES)
-  list(FILTER mfx_sources INCLUDE REGEX ".*\\.(m|c[cp]?p?|swift)")
-  list(FILTER mfx_headers INCLUDE REGEX ".*\\.h(pp)?")
-  source_group("libmfx\\Source Files" FILES ${mfx_sources})
-  source_group("libmfx\\Header Files" FILES ${mfx_headers})
-
   configure_file(cmake/windows/obs-module.rc.in obs-qsv11.rc)
   target_sources(obs-qsv11 PRIVATE obs-qsv11.rc)
 
@@ -105,18 +51,12 @@ if(OS_WINDOWS)
             device_directx9.cpp
             device_directx9.h)
 
-  target_link_libraries(obs-qsv11 PRIVATE OBS::libmfx d3d9 d3d11 dxva2 dxgi dxguid)
+  target_link_libraries(obs-qsv11 PRIVATE d3d9 d3d11 dxva2 dxgi dxguid)
+  target_link_options(obs-qsv11 PRIVATE /IGNORE:4099)
 elseif(OS_LINUX)
-  find_package(VPL REQUIRED)
   find_package(Libva REQUIRED)
 
   target_sources(obs-qsv11 PRIVATE common_utils_linux.cpp)
 
-  target_link_libraries(obs-qsv11 PRIVATE Libva::va Libva::drm VPL::VPL)
+  target_link_libraries(obs-qsv11 PRIVATE Libva::va Libva::drm)
 endif()
-
-get_target_property(target_sources obs-qsv11 SOURCES)
-list(FILTER target_sources INCLUDE REGEX ".*\\.(m|c[cp]?p?|swift)")
-list(FILTER target_headers INCLUDE REGEX ".*\\.h(pp)?")
-source_group("obs-qsv11\\Source Files" FILES ${target_sources})
-source_group("obs-qsv11\\Header Files" FILES ${target_headers})

+ 1 - 6
plugins/obs-qsv11/QSV_Encoder.cpp

@@ -79,9 +79,6 @@ void qsv_encoder_version(unsigned short *major, unsigned short *minor)
 
 qsv_t *qsv_encoder_open(qsv_param_t *pParams, enum qsv_codec codec)
 {
-	mfxIMPL impl_list[4] = {MFX_IMPL_HARDWARE, MFX_IMPL_HARDWARE2,
-				MFX_IMPL_HARDWARE3, MFX_IMPL_HARDWARE4};
-
 	obs_video_info ovi;
 	obs_get_video_info(&ovi);
 	size_t adapter_idx = ovi.adapter;
@@ -104,10 +101,8 @@ qsv_t *qsv_encoder_open(qsv_param_t *pParams, enum qsv_codec codec)
 	}
 
 	bool isDGPU = adapters[adapter_idx].is_dgpu;
-	impl = impl_list[adapter_idx];
 
-	QSV_Encoder_Internal *pEncoder =
-		new QSV_Encoder_Internal(impl, ver, isDGPU);
+	QSV_Encoder_Internal *pEncoder = new QSV_Encoder_Internal(ver, isDGPU);
 	mfxStatus sts = pEncoder->Open(pParams, codec);
 	if (sts != MFX_ERR_NONE) {
 

+ 2 - 1
plugins/obs-qsv11/QSV_Encoder.h

@@ -56,7 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #pragma once
 
-#include <mfxadapter.h>
+#include <vpl/mfxstructures.h>
+#include <vpl/mfxadapter.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <stddef.h>

+ 67 - 32
plugins/obs-qsv11/QSV_Encoder_Internal.cpp

@@ -56,7 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "QSV_Encoder_Internal.h"
 #include "QSV_Encoder.h"
-#include <mfxvideo++.h>
+#include <vpl/mfxstructures.h>
+#include <vpl/mfxvideo++.h>
+#include <vpl/mfxdispatcher.h>
 #include <obs-module.h>
 
 #define do_log(level, format, ...) \
@@ -69,8 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 mfxHDL QSV_Encoder_Internal::g_DX_Handle = NULL;
 mfxU16 QSV_Encoder_Internal::g_numEncodersOpen = 0;
 
-QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version,
-					   bool isDGPU)
+QSV_Encoder_Internal::QSV_Encoder_Internal(mfxVersion &version, bool isDGPU)
 	: m_pmfxSurfaces(NULL),
 	  m_pmfxENC(NULL),
 	  m_nSPSBufferSize(1024),
@@ -82,32 +83,48 @@ QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version,
 	  m_outBitstream(),
 	  m_isDGPU(isDGPU)
 {
-	mfxIMPL tempImpl;
+	mfxVariant tempImpl;
 	mfxStatus sts;
 
+	mfxLoader loader = MFXLoad();
+	mfxConfig cfg = MFXCreateConfig(loader);
+
+	tempImpl.Type = MFX_VARIANT_TYPE_U32;
+	tempImpl.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.Impl", tempImpl);
+
+	tempImpl.Type = MFX_VARIANT_TYPE_U32;
+	tempImpl.Data.U32 = INTEL_VENDOR_ID;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.VendorID", tempImpl);
 #if defined(_WIN32)
 	m_bUseD3D11 = true;
 	m_bD3D9HACK = true;
 	m_bUseTexAlloc = true;
 
-	tempImpl = impl | MFX_IMPL_VIA_D3D11;
-	const char *sImpl = "D3D11";
+	tempImpl.Type = MFX_VARIANT_TYPE_U32;
+	tempImpl.Data.U32 = MFX_ACCEL_MODE_VIA_D3D11;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.AccelerationMode",
+		tempImpl);
 #else
 	m_bUseTexAlloc = false;
-	tempImpl = impl | MFX_IMPL_VIA_VAAPI;
-	const char *sImpl = "VAAPI";
+	tempImpl.Type = MFX_VARIANT_TYPE_U32;
+	tempImpl.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.AccelerationMode",
+		tempImpl);
 #endif
-	sts = m_session.Init(tempImpl, &version);
+	sts = MFXCreateSession(loader, 0, &m_session);
 	if (sts == MFX_ERR_NONE) {
-		m_session.QueryVersion(&version);
-		m_session.Close();
+		MFXQueryVersion(m_session, &version);
+		MFXClose(m_session);
+		MFXUnload(loader);
 
-		blog(LOG_INFO,
-		     "\timpl:           %s\n"
-		     "\tsurf:           %s",
-		     sImpl, m_bUseTexAlloc ? "Texture" : "SysMem");
+		blog(LOG_INFO, "\tsurf:           %s",
+		     m_bUseTexAlloc ? "Texture" : "SysMem");
 
-		m_impl = tempImpl;
 		m_ver = version;
 		return;
 	}
@@ -115,16 +132,34 @@ QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version,
 #if defined(_WIN32)
 	// D3D11 failed at this point.
 	m_bUseD3D11 = false;
-	tempImpl = impl | MFX_IMPL_VIA_D3D9;
-	sts = m_session.Init(tempImpl, &version);
+	loader = MFXLoad();
+	cfg = MFXCreateConfig(loader);
+
+	tempImpl.Type = MFX_VARIANT_TYPE_U32;
+	tempImpl.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.Impl", tempImpl);
+
+	tempImpl.Type = MFX_VARIANT_TYPE_U32;
+	tempImpl.Data.U32 = INTEL_VENDOR_ID;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.VendorID", tempImpl);
+
+	tempImpl.Type = MFX_VARIANT_TYPE_U32;
+	tempImpl.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.AccelerationMode",
+		tempImpl);
+
+	sts = MFXCreateSession(loader, 0, &m_session);
 	if (sts == MFX_ERR_NONE) {
-		m_session.QueryVersion(&version);
-		m_session.Close();
+		MFXQueryVersion(m_session, &version);
+		MFXClose(m_session);
+		MFXUnload(loader);
 
 		blog(LOG_INFO, "\timpl:           D3D09\n"
 			       "\tsurf:           SysMem");
 
-		m_impl = tempImpl;
 		m_ver = version;
 		m_bUseD3D11 = false;
 	}
@@ -144,16 +179,16 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams, enum qsv_codec codec)
 #if defined(_WIN32)
 	if (m_bUseD3D11)
 		// Use D3D11 surface
-		sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator,
+		sts = Initialize(m_ver, &m_session, &m_mfxAllocator,
 				 &g_DX_Handle, false, false);
 	else if (m_bD3D9HACK)
 		// Use hack
-		sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator,
+		sts = Initialize(m_ver, &m_session, &m_mfxAllocator,
 				 &g_DX_Handle, false, true);
 	else
-		sts = Initialize(m_impl, m_ver, &m_session, NULL);
+		sts = Initialize(m_ver, &m_session, NULL, NULL, NULL, NULL);
 #else
-	sts = Initialize(m_impl, m_ver, &m_session, NULL, NULL, false, false);
+	sts = Initialize(m_ver, &m_session, NULL, NULL, false, false);
 #endif
 
 	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
@@ -721,8 +756,8 @@ mfxStatus QSV_Encoder_Internal::Encode(uint64_t ts, uint8_t *pDataY,
 
 	while (MFX_ERR_NOT_FOUND == nTaskIdx || MFX_ERR_NOT_FOUND == nSurfIdx) {
 		// No more free tasks or surfaces, need to sync
-		sts = m_session.SyncOperation(
-			m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
+		sts = MFXVideoCORE_SyncOperation(
+			m_session, m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 		mfxU8 *pTemp = m_outBitstream.Data;
@@ -811,8 +846,8 @@ mfxStatus QSV_Encoder_Internal::Encode_tex(uint64_t ts, uint32_t tex_handle,
 
 	while (MFX_ERR_NOT_FOUND == nTaskIdx || MFX_ERR_NOT_FOUND == nSurfIdx) {
 		// No more free tasks or surfaces, need to sync
-		sts = m_session.SyncOperation(
-			m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
+		sts = MFXVideoCORE_SyncOperation(
+			m_session, m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 		mfxU8 *pTemp = m_outBitstream.Data;
@@ -869,8 +904,8 @@ mfxStatus QSV_Encoder_Internal::Drain()
 	mfxStatus sts = MFX_ERR_NONE;
 
 	while (m_pTaskPool && m_pTaskPool[m_nFirstSyncTask].syncp) {
-		sts = m_session.SyncOperation(
-			m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
+		sts = MFXVideoCORE_SyncOperation(
+			m_session, m_pTaskPool[m_nFirstSyncTask].syncp, 60000);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 		m_pTaskPool[m_nFirstSyncTask].syncp = NULL;
@@ -923,7 +958,7 @@ mfxStatus QSV_Encoder_Internal::ClearData()
 		Release();
 		g_DX_Handle = NULL;
 	}
-	m_session.Close();
+	MFXVideoENCODE_Close(m_session);
 	return sts;
 }
 

+ 4 - 4
plugins/obs-qsv11/QSV_Encoder_Internal.h

@@ -54,7 +54,8 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 #pragma once
-#include <mfxvideo++.h>
+#include <vpl/mfxstructures.h>
+#include <vpl/mfxvideo++.h>
 #include "QSV_Encoder.h"
 #include "common_utils.h"
 
@@ -62,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 class QSV_Encoder_Internal {
 public:
-	QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version, bool isDGPU);
+	QSV_Encoder_Internal(mfxVersion &version, bool isDGPU);
 	~QSV_Encoder_Internal();
 
 	mfxStatus Open(qsv_param_t *pParams, enum qsv_codec codec);
@@ -98,9 +99,8 @@ protected:
 	int GetFreeTaskIndex(Task *pTaskPool, mfxU16 nPoolSize);
 
 private:
-	mfxIMPL m_impl;
 	mfxVersion m_ver;
-	MFXVideoSession m_session;
+	mfxSession m_session;
 	mfxFrameAllocator m_mfxAllocator;
 	mfxVideoParam m_mfxEncParams;
 	mfxFrameAllocResponse m_mfxResponse;

+ 5 - 64
plugins/obs-qsv11/cmake/legacy.cmake

@@ -10,55 +10,7 @@ project(obs-qsv11)
 add_library(obs-qsv11 MODULE)
 add_library(OBS::qsv11 ALIAS obs-qsv11)
 
-add_library(libmfx INTERFACE)
-add_library(OBS::libmfx ALIAS libmfx)
-
-target_sources(
-  libmfx
-  INTERFACE libmfx/src/main.cpp
-            libmfx/src/mfx_critical_section.cpp
-            libmfx/src/mfx_dispatcher.cpp
-            libmfx/src/mfx_dispatcher_log.cpp
-            libmfx/src/mfx_driver_store_loader.cpp
-            libmfx/src/mfx_dxva2_device.cpp
-            libmfx/src/mfx_function_table.cpp
-            libmfx/src/mfx_library_iterator.cpp
-            libmfx/src/mfx_load_dll.cpp
-            libmfx/src/mfx_load_plugin.cpp
-            libmfx/src/mfx_plugin_hive.cpp
-            libmfx/src/mfx_win_reg_key.cpp
-            libmfx/include/msdk/include/mfxadapter.h
-            libmfx/include/msdk/include/mfxastructures.h
-            libmfx/include/msdk/include/mfxaudio.h
-            libmfx/include/msdk/include/mfxaudio++.h
-            libmfx/include/msdk/include/mfxcommon.h
-            libmfx/include/msdk/include/mfxdefs.h
-            libmfx/include/msdk/include/mfxjpeg.h
-            libmfx/include/msdk/include/mfxmvc.h
-            libmfx/include/msdk/include/mfxplugin.h
-            libmfx/include/msdk/include/mfxplugin++.h
-            libmfx/include/msdk/include/mfxsession.h
-            libmfx/include/msdk/include/mfxstructures.h
-            libmfx/include/msdk/include/mfxvideo.h
-            libmfx/include/msdk/include/mfxvideo++.h
-            libmfx/include/msdk/include/mfxvstructures.h
-            libmfx/include/mfx_critical_section.h
-            libmfx/include/mfx_dispatcher.h
-            libmfx/include/mfx_dispatcher_defs.h
-            libmfx/include/mfx_dispatcher_log.h
-            libmfx/include/mfx_driver_store_loader.h
-            libmfx/include/mfx_dxva2_device.h
-            libmfx/include/mfx_exposed_functions_list.h
-            libmfx/include/mfx_library_iterator.h
-            libmfx/include/mfx_load_dll.h
-            libmfx/include/mfx_load_plugin.h
-            libmfx/include/mfx_plugin_hive.h
-            libmfx/include/mfx_vector.h
-            libmfx/include/mfx_win_reg_key.h
-            libmfx/include/mfxaudio_exposed_functions_list.h)
-
-target_include_directories(libmfx INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include/msdk/include
-                                            ${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include)
+find_package(VPL 2.6 REQUIRED)
 
 target_sources(
   obs-qsv11
@@ -73,7 +25,7 @@ target_sources(
           bits/linux_defs.h
           bits/windows_defs.h)
 
-target_link_libraries(obs-qsv11 PRIVATE OBS::libobs)
+target_link_libraries(obs-qsv11 PRIVATE OBS::libobs VPL::VPL)
 
 if(OS_WINDOWS)
   add_subdirectory(obs-qsv-test)
@@ -94,16 +46,16 @@ if(OS_WINDOWS)
             device_directx9.cpp
             device_directx9.h)
 
-  target_link_libraries(obs-qsv11 PRIVATE OBS::libmfx d3d9 d3d11 dxva2 dxgi dxguid)
+  target_link_libraries(obs-qsv11 PRIVATE d3d9 d3d11 dxva2 dxgi dxguid)
+  target_link_options(obs-qsv11 PRIVATE /IGNORE:4099)
 
   target_compile_definitions(obs-qsv11 PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS)
 elseif(OS_LINUX)
-  find_package(VPL REQUIRED)
   find_package(Libva REQUIRED)
 
   target_sources(obs-qsv11 PRIVATE common_utils_linux.cpp)
 
-  target_link_libraries(obs-qsv11 PRIVATE Libva::va Libva::drm VPL::VPL)
+  target_link_libraries(obs-qsv11 PRIVATE Libva::va Libva::drm)
 endif()
 
 set_target_properties(obs-qsv11 PROPERTIES FOLDER "plugins/obs-qsv11")
@@ -114,15 +66,4 @@ file(GLOB _OBS_QSV11_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURREN
 source_group("obs-qsv11\\Source Files" FILES ${_OBS_QSV11_SOURCE_FILES})
 source_group("obs-qsv11\\Header Files" FILES ${_OBS_QSV11_HEADER_FILES})
 
-get_target_property(_LIBMFX_SOURCES OBS::libmfx INTERFACE_SOURCES)
-
-foreach(_LIBMFX_SOURCE ${_LIBMFX_SOURCES})
-  get_filename_component(_EXT ${_LIBMFX_SOURCE} EXT)
-  if(${_EXT} STREQUAL "hpp" OR ${_EXT} STREQUAL "h")
-    source_group("libmfx\\Header Files" FILES ${_LIBMFX_SOURCE})
-  elseif(${_EXT} STREQUAL "cpp" OR ${_EXT} STREQUAL "c")
-    source_group("libmfx\\Source Files" FILES ${_LIBMFX_SOURCE})
-  endif()
-endforeach()
-
 setup_plugin_target(obs-qsv11)

+ 0 - 2
plugins/obs-qsv11/common_directx9.cpp

@@ -141,8 +141,6 @@ D3DFORMAT ConvertMfxFourccToD3dFormat(mfxU32 fourcc)
 		return D3DFMT_YV12;
 	case MFX_FOURCC_YUY2:
 		return D3DFMT_YUY2;
-	case MFX_FOURCC_RGB3:
-		return D3DFMT_R8G8B8;
 	case MFX_FOURCC_RGB4:
 		return D3DFMT_A8R8G8B8;
 	case MFX_FOURCC_P8:

+ 10 - 8
plugins/obs-qsv11/common_utils.h

@@ -5,7 +5,10 @@
 // Most of this file shouldnt be accessed from C.
 #ifdef __cplusplus
 
-#include <mfxvideo++.h>
+#include <vpl/mfxvideo++.h>
+#include <vpl/mfxdispatcher.h>
+
+constexpr inline int INTEL_VENDOR_ID = 0x8086;
 
 // =================================================================
 // OS-specific definitions of types, macro, etc...
@@ -80,7 +83,7 @@
 #define WILL_WRITE 0x2000
 
 // =================================================================
-// Intel Media SDK memory allocator entrypoints....
+// Intel VPL memory allocator entrypoints....
 // Implementation of this functions is OS/Memory type specific.
 mfxStatus simple_alloc(mfxHDL pthis, mfxFrameAllocRequest *request,
 		       mfxFrameAllocResponse *response);
@@ -92,7 +95,7 @@ mfxStatus simple_copytex(mfxHDL pthis, mfxMemId mid, mfxU32 tex_handle,
 			 mfxU64 lock_key, mfxU64 *next_key);
 
 // =================================================================
-// Utility functions, not directly tied to Media SDK functionality
+// Utility functions, not directly tied to VPL functionality
 //
 
 void PrintErrString(int err, const char *filestr, int line);
@@ -130,11 +133,10 @@ typedef struct {
 // Get free task
 int GetFreeTaskIndex(Task *pTaskPool, mfxU16 nPoolSize);
 
-// Initialize Intel Media SDK Session, device/display and memory manager
-mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession *pSession,
-		     mfxFrameAllocator *pmfxAllocator,
-		     mfxHDL *deviceHandle = NULL,
-		     bool bCreateSharedHandles = false, bool dx9hack = false);
+// Initialize Intel VPL Session, device/display and memory manager
+mfxStatus Initialize(mfxVersion ver, mfxSession *pSession,
+		     mfxFrameAllocator *pmfxAllocator, mfxHDL *deviceHandle,
+		     bool bCreateSharedHandles, bool dx9hack); //vpl change
 
 // Release resources (device/display)
 void Release();

+ 26 - 4
plugins/obs-qsv11/common_utils_linux.cpp

@@ -69,20 +69,42 @@ void ClearYUVSurfaceVMem(mfxMemId memId);
 void ClearRGBSurfaceVMem(mfxMemId memId);
 #endif
 
-// Initialize Intel Media SDK Session, device/display and memory manager
-mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession *pSession,
+// Initialize Intel VPL Session, device/display and memory manager
+mfxStatus Initialize(mfxVersion ver, mfxSession *pSession,
 		     mfxFrameAllocator *pmfxAllocator, mfxHDL *deviceHandle,
 		     bool bCreateSharedHandles, bool dx9hack)
 {
+	UNUSED_PARAMETER(ver);
 	UNUSED_PARAMETER(pmfxAllocator);
 	UNUSED_PARAMETER(deviceHandle);
 	UNUSED_PARAMETER(bCreateSharedHandles);
 	UNUSED_PARAMETER(dx9hack);
 	mfxStatus sts = MFX_ERR_NONE;
+	mfxVariant impl;
 
-	// Initialize Intel Media SDK Session
-	sts = pSession->Init(impl, &ver);
+	// Initialize Intel VPL Session
+	mfxLoader loader = MFXLoad();
+	mfxConfig cfg = MFXCreateConfig(loader);
+
+	impl.Type = MFX_VARIANT_TYPE_U32;
+	impl.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.Impl", impl);
+
+	impl.Type = MFX_VARIANT_TYPE_U32;
+	impl.Data.U32 = INTEL_VENDOR_ID;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.VendorID", impl);
+
+	impl.Type = MFX_VARIANT_TYPE_U32;
+	impl.Data.U32 = MFX_ACCEL_MODE_VIA_VAAPI_DRM_RENDER_NODE;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.AccelerationMode",
+		impl);
+
+	sts = MFXCreateSession(loader, 0, pSession);
 	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+
 	return sts;
 }
 

+ 83 - 18
plugins/obs-qsv11/common_utils_windows.cpp

@@ -22,7 +22,7 @@
  * Windows implementation of OS-specific utility functions
  */
 
-mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession *pSession,
+mfxStatus Initialize(mfxVersion ver, mfxSession *pSession,
 		     mfxFrameAllocator *pmfxAllocator, mfxHDL *deviceHandle,
 		     bool bCreateSharedHandles, bool dx9hack)
 {
@@ -30,11 +30,33 @@ mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession *pSession,
 	pmfxAllocator;        // (Lain) Currently unused
 
 	mfxStatus sts = MFX_ERR_NONE;
+	mfxVariant impl;
 
 	// If mfxFrameAllocator is provided it means we need to setup DirectX device and memory allocator
 	if (pmfxAllocator && !dx9hack) {
-		// Initialize Intel Media SDK Session
-		sts = pSession->Init(impl, &ver);
+		// Initialize Intel VPL Session
+		mfxLoader loader = MFXLoad();
+		mfxConfig cfg = MFXCreateConfig(loader);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
+		MFXSetConfigFilterProperty(
+			cfg, (const mfxU8 *)"mfxImplDescription.Impl", impl);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = INTEL_VENDOR_ID;
+		MFXSetConfigFilterProperty(
+			cfg, (const mfxU8 *)"mfxImplDescription.VendorID",
+			impl);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = MFX_ACCEL_MODE_VIA_D3D11;
+		MFXSetConfigFilterProperty(
+			cfg,
+			(const mfxU8 *)"mfxImplDescription.AccelerationMode",
+			impl);
+
+		sts = MFXCreateSession(loader, 0, pSession);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 		// Create DirectX device context
@@ -47,25 +69,47 @@ mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession *pSession,
 		if (deviceHandle == NULL || *deviceHandle == NULL)
 			return MFX_ERR_DEVICE_FAILED;
 
-		// Provide device manager to Media SDK
-		sts = pSession->SetHandle(DEVICE_MGR_TYPE, *deviceHandle);
+		// Provide device manager to VPL
+		sts = MFXVideoCORE_SetHandle(*pSession, DEVICE_MGR_TYPE,
+					     *deviceHandle);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 		pmfxAllocator->pthis =
-			*pSession; // We use Media SDK session ID as the allocation identifier
+			*pSession; // We use VPL session ID as the allocation identifier
 		pmfxAllocator->Alloc = simple_alloc;
 		pmfxAllocator->Free = simple_free;
 		pmfxAllocator->Lock = simple_lock;
 		pmfxAllocator->Unlock = simple_unlock;
 		pmfxAllocator->GetHDL = simple_gethdl;
 
-		// Since we are using video memory we must provide Media SDK with an external allocator
-		sts = pSession->SetFrameAllocator(pmfxAllocator);
+		// Since we are using video memory we must provide VPL with an external allocator
+		sts = MFXVideoCORE_SetFrameAllocator(*pSession, pmfxAllocator);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 	} else if (pmfxAllocator && dx9hack) {
-		// Initialize Intel Media SDK Session
-		sts = pSession->Init(impl, &ver);
+		// Initialize Intel VPL Session
+		mfxLoader loader = MFXLoad();
+		mfxConfig cfg = MFXCreateConfig(loader);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
+		MFXSetConfigFilterProperty(
+			cfg, (const mfxU8 *)"mfxImplDescription.Impl", impl);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = INTEL_VENDOR_ID;
+		MFXSetConfigFilterProperty(
+			cfg, (const mfxU8 *)"mfxImplDescription.VendorID",
+			impl);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9;
+		MFXSetConfigFilterProperty(
+			cfg,
+			(const mfxU8 *)"mfxImplDescription.AccelerationMode",
+			impl);
+
+		sts = MFXCreateSession(loader, 0, pSession);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 		// Create DirectX device context
@@ -77,26 +121,47 @@ mfxStatus Initialize(mfxIMPL impl, mfxVersion ver, MFXVideoSession *pSession,
 		if (*deviceHandle == NULL)
 			return MFX_ERR_DEVICE_FAILED;
 
-		// Provide device manager to Media SDK
-		sts = pSession->SetHandle(MFX_HANDLE_D3D9_DEVICE_MANAGER,
-					  *deviceHandle);
+		// Provide device manager to VPL
+		sts = MFXVideoCORE_SetHandle(*pSession, DEVICE_MGR_TYPE,
+					     *deviceHandle);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 		pmfxAllocator->pthis =
-			*pSession; // We use Media SDK session ID as the allocation identifier
+			*pSession; // We use VPL session ID as the allocation identifier
 		pmfxAllocator->Alloc = dx9_simple_alloc;
 		pmfxAllocator->Free = dx9_simple_free;
 		pmfxAllocator->Lock = dx9_simple_lock;
 		pmfxAllocator->Unlock = dx9_simple_unlock;
 		pmfxAllocator->GetHDL = dx9_simple_gethdl;
 
-		// Since we are using video memory we must provide Media SDK with an external allocator
-		sts = pSession->SetFrameAllocator(pmfxAllocator);
+		// Since we are using video memory we must provide VPL with an external allocator
+		sts = MFXVideoCORE_SetFrameAllocator(*pSession, pmfxAllocator);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 	} else {
-		// Initialize Intel Media SDK Session
-		sts = pSession->Init(impl, &ver);
+		// Initialize Intel VPL Session
+		mfxLoader loader = MFXLoad();
+		mfxConfig cfg = MFXCreateConfig(loader);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
+		MFXSetConfigFilterProperty(
+			cfg, (const mfxU8 *)"mfxImplDescription.Impl", impl);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = INTEL_VENDOR_ID;
+		MFXSetConfigFilterProperty(
+			cfg, (const mfxU8 *)"mfxImplDescription.VendorID",
+			impl);
+
+		impl.Type = MFX_VARIANT_TYPE_U32;
+		impl.Data.U32 = MFX_ACCEL_MODE_VIA_D3D9;
+		MFXSetConfigFilterProperty(
+			cfg,
+			(const mfxU8 *)"mfxImplDescription.AccelerationMode",
+			impl);
+
+		sts = MFXCreateSession(loader, 0, pSession);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 	}
 	return sts;

+ 4 - 1
plugins/obs-qsv11/obs-qsv-test/CMakeLists.txt

@@ -4,9 +4,12 @@ legacy_check()
 
 add_executable(obs-qsv-test)
 
+find_package(VPL 2.6 REQUIRED)
+
 target_sources(obs-qsv-test PRIVATE obs-qsv-test.cpp)
 target_compile_definitions(obs-qsv-test PRIVATE "$<$<BOOL:${ENABLE_HEVC}>:ENABLE_HEVC>")
-target_link_libraries(obs-qsv-test d3d11 dxgi dxguid OBS::libmfx OBS::COMutils)
+target_link_libraries(obs-qsv-test d3d11 dxgi dxguid VPL::VPL OBS::COMutils)
+target_link_options(obs-qsv-test PRIVATE /IGNORE:4099)
 
 # cmake-format: off
 set_target_properties_obs(obs-qsv-test PROPERTIES FOLDER plugins/obs-qsv11 PREFIX "")

+ 5 - 1
plugins/obs-qsv11/obs-qsv-test/cmake/legacy.cmake

@@ -3,8 +3,12 @@ project(obs-qsv-test)
 include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/libobs)
 
 add_executable(obs-qsv-test)
+
+find_package(VPL 2.6 REQUIRED)
+
 target_sources(obs-qsv-test PRIVATE obs-qsv-test.cpp)
-target_link_libraries(obs-qsv-test d3d11 dxgi dxguid OBS::libmfx)
+target_link_libraries(obs-qsv-test d3d11 dxgi dxguid VPL::VPL)
+target_link_options(obs-qsv-test PRIVATE /IGNORE:4099)
 
 set_target_properties(obs-qsv-test PROPERTIES FOLDER "plugins/obs-qsv11")
 

+ 58 - 24
plugins/obs-qsv11/obs-qsv-test/obs-qsv-test.cpp

@@ -1,6 +1,6 @@
-#include "mfxstructures.h"
-#include "mfxadapter.h"
-#include "mfxvideo++.h"
+#include <vpl/mfxstructures.h>
+#include <vpl/mfxadapter.h>
+#include <vpl/mfxvideo++.h>
 #include "../common_utils.h"
 
 #include <util/windows/ComPtr.hpp>
@@ -18,8 +18,6 @@ extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 1;
 extern "C" __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
 #endif
 
-#define INTEL_VENDOR_ID 0x8086
-
 struct adapter_caps {
 	bool is_intel = false;
 	bool is_dgpu = false;
@@ -30,14 +28,9 @@ struct adapter_caps {
 static std::vector<uint64_t> luid_order;
 static std::map<uint32_t, adapter_caps> adapter_info;
 
-static bool has_encoder(mfxIMPL impl, mfxU32 codec_id)
+static bool has_encoder(mfxSession m_session, mfxU32 codec_id)
 {
-	MFXVideoSession session;
-	mfxInitParam init_param = {};
-	init_param.Implementation = impl;
-	init_param.Version.Major = 1;
-	init_param.Version.Minor = 0;
-	mfxStatus sts = session.InitEx(init_param);
+	MFXVideoENCODE *session = new MFXVideoENCODE(m_session);
 
 	mfxVideoParam video_param;
 	memset(&video_param, 0, sizeof(video_param));
@@ -46,8 +39,8 @@ static bool has_encoder(mfxIMPL impl, mfxU32 codec_id)
 	video_param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
 	video_param.mfx.FrameInfo.Width = MSDK_ALIGN16(1280);
 	video_param.mfx.FrameInfo.Height = MSDK_ALIGN16(720);
-	sts = MFXVideoENCODE_Query(session, &video_param, &video_param);
-	session.Close();
+	mfxStatus sts = session->Query(&video_param, &video_param);
+	session->Close();
 
 	return sts == MFX_ERR_NONE;
 }
@@ -63,10 +56,9 @@ static inline uint32_t get_adapter_idx(uint32_t adapter_idx, LUID luid)
 	return adapter_idx;
 }
 
-static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
+static bool get_adapter_caps(IDXGIFactory *factory, mfxLoader loader,
+			     mfxSession m_session, uint32_t adapter_idx)
 {
-	mfxIMPL impls[4] = {MFX_IMPL_HARDWARE, MFX_IMPL_HARDWARE2,
-			    MFX_IMPL_HARDWARE3, MFX_IMPL_HARDWARE4};
 	HRESULT hr;
 
 	ComPtr<IDXGIAdapter> adapter;
@@ -82,15 +74,41 @@ static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
 	if (desc.VendorId != INTEL_VENDOR_ID)
 		return true;
 
-	bool dgpu = desc.DedicatedVideoMemory > 512 * 1024 * 1024;
-	mfxIMPL impl = impls[adapter_idx];
-
 	caps.is_intel = true;
-	caps.is_dgpu = dgpu;
-	caps.supports_av1 = has_encoder(impl, MFX_CODEC_AV1);
+
+	mfxImplDescription *idesc;
+	mfxStatus sts = MFXEnumImplementations(
+		loader, adapter_idx, MFX_IMPLCAPS_IMPLDESCSTRUCTURE,
+		reinterpret_cast<mfxHDL *>(&idesc));
+
+	if (sts != MFX_ERR_NONE)
+		return false;
+
+	caps.is_dgpu = false;
+	if (idesc->Dev.MediaAdapterType == MFX_MEDIA_DISCRETE)
+		caps.is_dgpu = true;
+
+	caps.supports_av1 = false;
+	caps.supports_hevc = false;
+	mfxEncoderDescription *enc = &idesc->Enc;
+	if (enc->NumCodecs != 0) {
+		for (int codec = 0; codec < enc->NumCodecs; codec++) {
+			if (enc->Codecs[codec].CodecID == MFX_CODEC_AV1)
+				caps.supports_av1 = true;
 #if ENABLE_HEVC
-	caps.supports_hevc = has_encoder(impl, MFX_CODEC_HEVC);
+			if (enc->Codecs[codec].CodecID == MFX_CODEC_HEVC)
+				caps.supports_hevc = true;
 #endif
+		}
+	} else {
+		// Encoder information is not available before TGL for VPL, so the MSDK legacy approach is taken
+		caps.supports_av1 = has_encoder(m_session, MFX_CODEC_AV1);
+#if ENABLE_HEVC
+		caps.supports_hevc = has_encoder(m_session, MFX_CODEC_HEVC);
+#endif
+	}
+
+	MFXDispReleaseImplDescription(loader, idesc);
 
 	return true;
 }
@@ -139,10 +157,26 @@ try {
 	if (FAILED(hr))
 		throw "CreateDXGIFactory1 failed";
 
+	mfxLoader loader = MFXLoad();
+	mfxConfig cfg = MFXCreateConfig(loader);
+	mfxVariant impl;
+
+	// Low latency is disabled due to encoding capabilities not being provided before TGL for VPL
+	impl.Type = MFX_VARIANT_TYPE_U32;
+	impl.Data.U32 = MFX_IMPL_TYPE_HARDWARE;
+	MFXSetConfigFilterProperty(
+		cfg, (const mfxU8 *)"mfxImplDescription.Impl", impl);
+
+	mfxSession m_session;
+	mfxStatus sts = MFXCreateSession(loader, 0, &m_session);
+
 	uint32_t idx = 0;
-	while (get_adapter_caps(factory, idx++) && idx < 4)
+	while (get_adapter_caps(factory, loader, m_session, idx++) == true)
 		;
 
+	MFXClose(m_session);
+	MFXUnload(loader);
+
 	for (auto &[idx, caps] : adapter_info) {
 		printf("[%u]\n", idx);
 		printf("is_intel=%s\n", caps.is_intel ? "true" : "false");