浏览代码

obs-qsv11: Add a Linux implementation

This adds a CMake module for finding the QSV SDK (libmfx/onevpl) and an
the required platform components to initialize QSV with the VA-API
platform.
Kurt Kartaltepe 2 年之前
父节点
当前提交
c6b470de9a

+ 3 - 2
CI/linux/01_install_dependencies.sh

@@ -93,13 +93,14 @@ install_dependencies() {
          libswscale-dev libx264-dev libcurl4-openssl-dev libmbedtls-dev libgl1-mesa-dev libjansson-dev \
          libswscale-dev libx264-dev libcurl4-openssl-dev libmbedtls-dev libgl1-mesa-dev libjansson-dev \
          libluajit-5.1-dev python3-dev libx11-dev libxcb-randr0-dev libxcb-shm0-dev libxcb-xinerama0-dev \
          libluajit-5.1-dev python3-dev libx11-dev libxcb-randr0-dev libxcb-shm0-dev libxcb-xinerama0-dev \
          libxcb-composite0-dev libxinerama-dev libxcb1-dev libx11-xcb-dev libxcb-xfixes0-dev swig libcmocka-dev \
          libxcb-composite0-dev libxinerama-dev libxcb1-dev libx11-xcb-dev libxcb-xfixes0-dev swig libcmocka-dev \
-         libpci-dev libxss-dev libglvnd-dev libgles2-mesa libgles2-mesa-dev libwayland-dev libxkbcommon-dev"
+         libpci-dev libxss-dev libglvnd-dev libgles2-mesa libgles2-mesa-dev libwayland-dev \
+         libxkbcommon-dev"
         "qt5-deps qtbase5-dev qtbase5-private-dev libqt5svg5-dev qtwayland5"
         "qt5-deps qtbase5-dev qtbase5-private-dev libqt5svg5-dev qtwayland5"
         "qt6-deps qt6-base-dev qt6-base-private-dev libqt6svg6-dev qt6-wayland"
         "qt6-deps qt6-base-dev qt6-base-private-dev libqt6svg6-dev qt6-wayland"
         "cef ${LINUX_CEF_BUILD_VERSION:-${CI_LINUX_CEF_VERSION}}"
         "cef ${LINUX_CEF_BUILD_VERSION:-${CI_LINUX_CEF_VERSION}}"
         "plugin-deps libasound2-dev libfdk-aac-dev libfontconfig-dev libfreetype6-dev libjack-jackd2-dev \
         "plugin-deps libasound2-dev libfdk-aac-dev libfontconfig-dev libfreetype6-dev libjack-jackd2-dev \
          libpulse-dev libsndio-dev libspeexdsp-dev libudev-dev libv4l-dev libva-dev libvlc-dev libdrm-dev \
          libpulse-dev libsndio-dev libspeexdsp-dev libudev-dev libv4l-dev libva-dev libvlc-dev libdrm-dev \
-         nlohmann-json3-dev libwebsocketpp-dev libasio-dev"
+         nlohmann-json3-dev libwebsocketpp-dev libasio-dev libvpl-dev"
     )
     )
 
 
     sudo apt-get -qq update
     sudo apt-get -qq update

+ 6 - 0
CI/linux/02_build_obs.sh

@@ -53,6 +53,10 @@ _configure_obs() {
         PIPEWIRE_OPTION="-DENABLE_PIPEWIRE=OFF"
         PIPEWIRE_OPTION="-DENABLE_PIPEWIRE=OFF"
     fi
     fi
 
 
+    if [ "${DISABLE_QSV}" ]; then
+        QSV_OPTION="-DENABLE_QSV11=OFF"
+    fi
+
     cmake -S . -B ${BUILD_DIR} -G Ninja \
     cmake -S . -B ${BUILD_DIR} -G Ninja \
         -DCEF_ROOT_DIR="${DEPS_BUILD_DIR}/cef_binary_${LINUX_CEF_BUILD_VERSION:-${CI_LINUX_CEF_VERSION}}_linux64" \
         -DCEF_ROOT_DIR="${DEPS_BUILD_DIR}/cef_binary_${LINUX_CEF_BUILD_VERSION:-${CI_LINUX_CEF_VERSION}}_linux64" \
         -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \
         -DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \
@@ -61,6 +65,7 @@ _configure_obs() {
         -DENABLE_NEW_MPEGTS_OUTPUT=OFF \
         -DENABLE_NEW_MPEGTS_OUTPUT=OFF \
         -DENABLE_WEBRTC=OFF \
         -DENABLE_WEBRTC=OFF \
         ${PIPEWIRE_OPTION} \
         ${PIPEWIRE_OPTION} \
+        ${QSV_OPTION} \
         ${YOUTUBE_OPTIONS} \
         ${YOUTUBE_OPTIONS} \
         ${TWITCH_OPTIONS} \
         ${TWITCH_OPTIONS} \
         ${RESTREAM_OPTIONS} \
         ${RESTREAM_OPTIONS} \
@@ -116,6 +121,7 @@ build-obs-main() {
                 -v | --verbose ) export VERBOSE=TRUE; shift ;;
                 -v | --verbose ) export VERBOSE=TRUE; shift ;;
                 -p | --portable ) export PORTABLE=TRUE; shift ;;
                 -p | --portable ) export PORTABLE=TRUE; shift ;;
                 --disable-pipewire ) DISABLE_PIPEWIRE=TRUE; shift ;;
                 --disable-pipewire ) DISABLE_PIPEWIRE=TRUE; shift ;;
+                --disable-qsv ) DISABLE_QSV=TRUE; shift ;;
                 --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
                 --build-dir ) BUILD_DIR="${2}"; shift 2 ;;
                 -- ) shift; break ;;
                 -- ) shift; break ;;
                 * ) break ;;
                 * ) break ;;

+ 2 - 1
build-aux/com.obsproject.Studio.json

@@ -81,7 +81,8 @@
                 "-DENABLE_RTMPS=ON",
                 "-DENABLE_RTMPS=ON",
                 "-DENABLE_VLC=OFF",
                 "-DENABLE_VLC=OFF",
                 "-DENABLE_AJA=ON",
                 "-DENABLE_AJA=ON",
-                "-DENABLE_LIBFDK=ON"
+                "-DENABLE_LIBFDK=ON",
+                "-DENABLE_QSV11=OFF"
             ],
             ],
             "secret-opts": [
             "secret-opts": [
                 "-DRESTREAM_CLIENTID=$RESTREAM_CLIENTID",
                 "-DRESTREAM_CLIENTID=$RESTREAM_CLIENTID",

+ 47 - 0
cmake/Modules/FindVPL.cmake

@@ -0,0 +1,47 @@
+# * 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
+
+# Use pkg-config to get the directories and then use these values in the find_path() and find_library() calls
+
+find_package(PkgConfig QUIET)
+if(PKG_CONFIG_FOUND)
+  pkg_check_modules(_VPL vpl)
+endif()
+
+find_path(
+  VPL_INCLUDE_DIR
+  NAMES mfxstructures.h
+  HINTS ${_VPL_INCLUDE_DIRS} ${_VPL_INCLUDE_DIRS}
+  PATHS /usr/include /usr/local/include /opt/local/include /sw/include
+  PATH_SUFFIXES vpl/)
+
+find_library(
+  VPL_LIB
+  NAMES ${_VPL_LIBRARIES} ${_VPL_LIBRARIES} vpl
+  HINTS ${_VPL_LIBRARY_DIRS} ${_VPL_LIBRARY_DIRS}
+  PATHS /usr/lib /usr/local/lib /opt/local/lib /sw/lib)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(VPL REQUIRED_VARS VPL_LIB VPL_INCLUDE_DIR)
+mark_as_advanced(VPL_INCLUDE_DIR VPL_LIB)
+
+if(VPL_FOUND)
+  set(VPL_INCLUDE_DIRS ${VPL_INCLUDE_DIR})
+  set(VPL_LIBRARIES ${VPL_LIB})
+
+  if(NOT TARGET VPL::VPL)
+    if(IS_ABSOLUTE "${VPL_LIBRARIES}")
+      add_library(VPL::VPL UNKNOWN IMPORTED)
+      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LOCATION "${VPL_LIBRARIES}")
+    else()
+      add_library(VPL::VPL INTERFACE IMPORTED)
+      set_target_properties(VPL::VPL PROPERTIES IMPORTED_LIBNAME "${VPL_LIBRARIES}")
+    endif()
+
+    set_target_properties(VPL::VPL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${VPL_INCLUDE_DIRS}")
+  endif()
+endif()

+ 1 - 0
plugins/CMakeLists.txt

@@ -153,6 +153,7 @@ elseif(OS_LINUX)
   add_subdirectory(vlc-video)
   add_subdirectory(vlc-video)
   add_subdirectory(sndio)
   add_subdirectory(sndio)
   add_subdirectory(obs-vst)
   add_subdirectory(obs-vst)
+  add_subdirectory(obs-qsv11)
 
 
   check_obs_browser()
   check_obs_browser()
 elseif(OS_FREEBSD)
 elseif(OS_FREEBSD)

+ 88 - 79
plugins/obs-qsv11/CMakeLists.txt

@@ -9,74 +9,14 @@ if(NOT ENABLE_QSV11)
   return()
   return()
 endif()
 endif()
 
 
-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")
-
 add_library(obs-qsv11 MODULE)
 add_library(obs-qsv11 MODULE)
 add_library(OBS::qsv11 ALIAS obs-qsv11)
 add_library(OBS::qsv11 ALIAS obs-qsv11)
 
 
 target_sources(
 target_sources(
   obs-qsv11
   obs-qsv11
   PRIVATE # cmake-format: sortable
   PRIVATE # cmake-format: sortable
-          bits/linux_defs.h
-          bits/windows_defs.h
-          common_directx11.cpp
-          common_directx11.h
-          common_directx9.cpp
-          common_directx9.h
           common_utils.cpp
           common_utils.cpp
           common_utils.h
           common_utils.h
-          common_utils_windows.cpp
-          device_directx9.cpp
-          device_directx9.h
           obs-qsv11-plugin-main.c
           obs-qsv11-plugin-main.c
           obs-qsv11.c
           obs-qsv11.c
           QSV_Encoder.cpp
           QSV_Encoder.cpp
@@ -84,29 +24,98 @@ target_sources(
           QSV_Encoder_Internal.cpp
           QSV_Encoder_Internal.cpp
           QSV_Encoder_Internal.h)
           QSV_Encoder_Internal.h)
 
 
-configure_file(cmake/windows/obs-module.rc.in obs-qsv11.rc)
-target_sources(obs-qsv11 PRIVATE obs-qsv11.rc)
-
-target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D)
-
-target_link_libraries(
-  obs-qsv11
-  PRIVATE OBS::libobs
-          OBS::libmfx
-          d3d9
-          d3d11
-          dxva2
-          dxgi
-          dxguid)
-
-add_subdirectory(obs-qsv-test)
+target_link_libraries(obs-qsv11 PRIVATE OBS::libobs)
 
 
 # cmake-format: off
 # cmake-format: off
 set_target_properties_obs(obs-qsv11 PROPERTIES FOLDER plugins/obs-qsv11 PREFIX "")
 set_target_properties_obs(obs-qsv11 PROPERTIES FOLDER plugins/obs-qsv11 PREFIX "")
 # cmake-format: on
 # cmake-format: on
 
 
-get_target_property(target_sources libmfx SOURCES)
+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)
+
+  target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D)
+
+  target_sources(
+    obs-qsv11
+    PRIVATE # cmake-format: sortable
+            common_directx11.cpp
+            common_directx11.h
+            common_directx9.cpp
+            common_directx9.h
+            common_utils_windows.cpp
+            device_directx9.cpp
+            device_directx9.h)
+
+  target_link_libraries(obs-qsv11 PRIVATE OBS::libmfx d3d9 d3d11 dxva2 dxgi dxguid)
+elseif(OS_LINUX)
+  find_package(VPL REQUIRED)
+
+  target_sources(obs-qsv11 PRIVATE common_utils_linux.cpp)
+
+  target_link_libraries(obs-qsv11 PRIVATE VPL::VPL)
+endif()
+
+get_target_property(target_sources obs-qsv11 SOURCES)
 list(FILTER target_sources INCLUDE REGEX ".*\\.(m|c[cp]?p?|swift)")
 list(FILTER target_sources INCLUDE REGEX ".*\\.(m|c[cp]?p?|swift)")
 list(FILTER target_headers INCLUDE REGEX ".*\\.h(pp)?")
 list(FILTER target_headers INCLUDE REGEX ".*\\.h(pp)?")
-source_group("libmfx\\Source Files" FILES ${target_sources})
-source_group("libmfx\\Header Files" FILES ${target_headers})
+source_group("obs-qsv11\\Source Files" FILES ${target_sources})
+source_group("obs-qsv11\\Header Files" FILES ${target_headers})

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

@@ -56,10 +56,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #pragma once
 #pragma once
 
 
-#include "mfxstructures.h"
-#include "mfxadapter.h"
+#include <mfxadapter.h>
 #include <stdint.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdbool.h>
+#include <stddef.h>
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {

+ 27 - 5
plugins/obs-qsv11/QSV_Encoder_Internal.cpp

@@ -56,8 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include "QSV_Encoder_Internal.h"
 #include "QSV_Encoder_Internal.h"
 #include "QSV_Encoder.h"
 #include "QSV_Encoder.h"
-#include "mfxastructures.h"
-#include "mfxvideo++.h"
+#include <mfxvideo++.h>
 #include <obs-module.h>
 #include <obs-module.h>
 
 
 #define do_log(level, format, ...) \
 #define do_log(level, format, ...) \
@@ -86,25 +85,36 @@ QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version,
 	mfxIMPL tempImpl;
 	mfxIMPL tempImpl;
 	mfxStatus sts;
 	mfxStatus sts;
 
 
+#if defined(_WIN32)
 	m_bUseD3D11 = true;
 	m_bUseD3D11 = true;
 	m_bD3D9HACK = true;
 	m_bD3D9HACK = true;
 	m_bUseTexAlloc = true;
 	m_bUseTexAlloc = true;
 
 
 	tempImpl = impl | MFX_IMPL_VIA_D3D11;
 	tempImpl = impl | MFX_IMPL_VIA_D3D11;
+	const char *sImpl = "D3D11";
+#else
+	m_bUseTexAlloc = false;
+	tempImpl = impl | MFX_IMPL_VIA_VAAPI;
+	const char *sImpl = "VAAPI";
+#endif
 	sts = m_session.Init(tempImpl, &version);
 	sts = m_session.Init(tempImpl, &version);
 	if (sts == MFX_ERR_NONE) {
 	if (sts == MFX_ERR_NONE) {
 		m_session.QueryVersion(&version);
 		m_session.QueryVersion(&version);
 		m_session.Close();
 		m_session.Close();
 
 
-		blog(LOG_INFO, "\timpl:           D3D11\n"
-			       "\tsurf:           D3D11");
+		blog(LOG_INFO,
+		     "\timpl:           %s\n"
+		     "\tsurf:           %s",
+		     sImpl, m_bUseTexAlloc ? "Texture" : "SysMem");
 
 
 		m_impl = tempImpl;
 		m_impl = tempImpl;
 		m_ver = version;
 		m_ver = version;
 		return;
 		return;
 	}
 	}
 
 
+#if defined(_WIN32)
 	// D3D11 failed at this point.
 	// D3D11 failed at this point.
+	m_bUseD3D11 = false;
 	tempImpl = impl | MFX_IMPL_VIA_D3D9;
 	tempImpl = impl | MFX_IMPL_VIA_D3D9;
 	sts = m_session.Init(tempImpl, &version);
 	sts = m_session.Init(tempImpl, &version);
 	if (sts == MFX_ERR_NONE) {
 	if (sts == MFX_ERR_NONE) {
@@ -118,6 +128,7 @@ QSV_Encoder_Internal::QSV_Encoder_Internal(mfxIMPL &impl, mfxVersion &version,
 		m_ver = version;
 		m_ver = version;
 		m_bUseD3D11 = false;
 		m_bUseD3D11 = false;
 	}
 	}
+#endif
 }
 }
 
 
 QSV_Encoder_Internal::~QSV_Encoder_Internal()
 QSV_Encoder_Internal::~QSV_Encoder_Internal()
@@ -130,6 +141,7 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams, enum qsv_codec codec)
 {
 {
 	mfxStatus sts = MFX_ERR_NONE;
 	mfxStatus sts = MFX_ERR_NONE;
 
 
+#if defined(_WIN32)
 	if (m_bUseD3D11)
 	if (m_bUseD3D11)
 		// Use D3D11 surface
 		// Use D3D11 surface
 		sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator,
 		sts = Initialize(m_impl, m_ver, &m_session, &m_mfxAllocator,
@@ -140,6 +152,9 @@ mfxStatus QSV_Encoder_Internal::Open(qsv_param_t *pParams, enum qsv_codec codec)
 				 &g_DX_Handle, false, true);
 				 &g_DX_Handle, false, true);
 	else
 	else
 		sts = Initialize(m_impl, m_ver, &m_session, NULL);
 		sts = Initialize(m_impl, m_ver, &m_session, NULL);
+#else
+	sts = Initialize(m_impl, m_ver, &m_session, NULL, NULL, false, false);
+#endif
 
 
 	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 
 
@@ -215,6 +230,8 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
 	if (codec == QSV_CODEC_HEVC)
 	if (codec == QSV_CODEC_HEVC)
 		m_mfxEncParams.mfx.LowPower = MFX_CODINGOPTION_OFF;
 		m_mfxEncParams.mfx.LowPower = MFX_CODINGOPTION_OFF;
 
 
+#if defined(_WIN32)
+	// TODO: Why isn't LowPower coding supported on VAAPI backend.
 	enum qsv_cpu_platform qsv_platform = qsv_get_cpu_platform();
 	enum qsv_cpu_platform qsv_platform = qsv_get_cpu_platform();
 	if ((m_isDGPU || qsv_platform >= QSV_CPU_PLATFORM_ICL ||
 	if ((m_isDGPU || qsv_platform >= QSV_CPU_PLATFORM_ICL ||
 	     qsv_platform == QSV_CPU_PLATFORM_UNKNOWN) &&
 	     qsv_platform == QSV_CPU_PLATFORM_UNKNOWN) &&
@@ -226,6 +243,7 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
 		    pParams->nRateControl == MFX_RATECONTROL_LA)
 		    pParams->nRateControl == MFX_RATECONTROL_LA)
 			pParams->nRateControl = MFX_RATECONTROL_VBR;
 			pParams->nRateControl = MFX_RATECONTROL_VBR;
 	}
 	}
+#endif
 
 
 	m_mfxEncParams.mfx.RateControlMethod = pParams->nRateControl;
 	m_mfxEncParams.mfx.RateControlMethod = pParams->nRateControl;
 
 
@@ -322,6 +340,8 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
 		}
 		}
 	}
 	}
 
 
+#if defined(_WIN32)
+	// TODO: Ask about this one on VAAPI too.
 	memset(&m_ExtVideoSignalInfo, 0, sizeof(m_ExtVideoSignalInfo));
 	memset(&m_ExtVideoSignalInfo, 0, sizeof(m_ExtVideoSignalInfo));
 	m_ExtVideoSignalInfo.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO;
 	m_ExtVideoSignalInfo.Header.BufferId = MFX_EXTBUFF_VIDEO_SIGNAL_INFO;
 	m_ExtVideoSignalInfo.Header.BufferSz = sizeof(m_ExtVideoSignalInfo);
 	m_ExtVideoSignalInfo.Header.BufferSz = sizeof(m_ExtVideoSignalInfo);
@@ -333,6 +353,7 @@ mfxStatus QSV_Encoder_Internal::InitParams(qsv_param_t *pParams,
 		pParams->TransferCharacteristics;
 		pParams->TransferCharacteristics;
 	m_ExtVideoSignalInfo.MatrixCoefficients = pParams->MatrixCoefficients;
 	m_ExtVideoSignalInfo.MatrixCoefficients = pParams->MatrixCoefficients;
 	extendedBuffers.push_back((mfxExtBuffer *)&m_ExtVideoSignalInfo);
 	extendedBuffers.push_back((mfxExtBuffer *)&m_ExtVideoSignalInfo);
+#endif
 
 
 /* TODO: Ask Intel why this is MFX_ERR_UNSUPPORTED */
 /* TODO: Ask Intel why this is MFX_ERR_UNSUPPORTED */
 #if 0
 #if 0
@@ -813,8 +834,9 @@ mfxStatus QSV_Encoder_Internal::Encode_tex(uint64_t ts, uint32_t tex_handle,
 	//copy to default surface directly
 	//copy to default surface directly
 	pSurface->Data.TimeStamp = ts;
 	pSurface->Data.TimeStamp = ts;
 	if (m_bUseTexAlloc) {
 	if (m_bUseTexAlloc) {
+		// mfxU64 isn't consistent with stdint, requiring a cast to be multi-platform.
 		sts = simple_copytex(m_mfxAllocator.pthis, pSurface->Data.MemId,
 		sts = simple_copytex(m_mfxAllocator.pthis, pSurface->Data.MemId,
-				     tex_handle, lock_key, next_key);
+				     tex_handle, lock_key, (mfxU64 *)next_key);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 		MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
 	}
 	}
 
 

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

@@ -54,8 +54,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 */
 #pragma once
 #pragma once
-#include "mfxastructures.h"
-#include "mfxvideo++.h"
+#include <mfxvideo++.h>
 #include "QSV_Encoder.h"
 #include "QSV_Encoder.h"
 #include "common_utils.h"
 #include "common_utils.h"
 
 

+ 1 - 1
plugins/obs-qsv11/bits/linux_defs.h

@@ -6,4 +6,4 @@
 #define MSDK_FOPEN(FH, FN, M)           { FH=fopen(FN,M); }
 #define MSDK_FOPEN(FH, FN, M)           { FH=fopen(FN,M); }
 #define MSDK_SLEEP(X)                   { usleep(1000*(X)); }
 #define MSDK_SLEEP(X)                   { usleep(1000*(X)); }
 
 
-typedef timespec mfxTime;
+typedef struct timespec mfxTime;

+ 21 - 19
plugins/obs-qsv11/cmake/legacy.cmake

@@ -64,15 +64,8 @@ target_sources(
   obs-qsv11
   obs-qsv11
   PRIVATE obs-qsv11.c
   PRIVATE obs-qsv11.c
           obs-qsv11-plugin-main.c
           obs-qsv11-plugin-main.c
-          common_directx9.cpp
-          common_directx9.h
-          common_directx11.cpp
-          common_directx11.h
           common_utils.cpp
           common_utils.cpp
           common_utils.h
           common_utils.h
-          common_utils_windows.cpp
-          device_directx9.cpp
-          device_directx9.h
           QSV_Encoder.cpp
           QSV_Encoder.cpp
           QSV_Encoder.h
           QSV_Encoder.h
           QSV_Encoder_Internal.cpp
           QSV_Encoder_Internal.cpp
@@ -80,27 +73,36 @@ target_sources(
           bits/linux_defs.h
           bits/linux_defs.h
           bits/windows_defs.h)
           bits/windows_defs.h)
 
 
-target_link_libraries(
-  obs-qsv11
-  PRIVATE OBS::libobs
-          OBS::libmfx
-          d3d9
-          d3d11
-          dxva2
-          dxgi
-          dxguid)
-
-target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D)
+target_link_libraries(obs-qsv11 PRIVATE OBS::libobs)
 
 
 if(OS_WINDOWS)
 if(OS_WINDOWS)
   add_subdirectory(obs-qsv-test)
   add_subdirectory(obs-qsv-test)
 
 
+  target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D)
+
   set(MODULE_DESCRIPTION "OBS QSV encoder")
   set(MODULE_DESCRIPTION "OBS QSV encoder")
   configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in obs-qsv11.rc)
   configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in obs-qsv11.rc)
 
 
-  target_sources(obs-qsv11 PRIVATE obs-qsv11.rc)
+  target_sources(
+    obs-qsv11
+    PRIVATE obs-qsv11.rc
+            common_directx9.cpp
+            common_directx9.h
+            common_directx11.cpp
+            common_directx11.h
+            common_utils_windows.cpp
+            device_directx9.cpp
+            device_directx9.h)
+
+  target_link_libraries(obs-qsv11 PRIVATE OBS::libmfx d3d9 d3d11 dxva2 dxgi dxguid)
 
 
   target_compile_definitions(obs-qsv11 PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS)
   target_compile_definitions(obs-qsv11 PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS)
+elseif(OS_LINUX)
+  find_package(VPL REQUIRED)
+
+  target_sources(obs-qsv11 PRIVATE common_utils_linux.cpp)
+
+  target_link_libraries(obs-qsv11 PRIVATE VPL::VPL)
 endif()
 endif()
 
 
 set_target_properties(obs-qsv11 PROPERTIES FOLDER "plugins/obs-qsv11")
 set_target_properties(obs-qsv11 PROPERTIES FOLDER "plugins/obs-qsv11")

+ 1 - 1
plugins/obs-qsv11/common_utils.h

@@ -2,7 +2,7 @@
 
 
 #include <stdio.h>
 #include <stdio.h>
 
 
-#include "mfxvideo++.h"
+#include <mfxvideo++.h>
 
 
 // =================================================================
 // =================================================================
 // OS-specific definitions of types, macro, etc...
 // OS-specific definitions of types, macro, etc...

+ 100 - 0
plugins/obs-qsv11/common_utils_linux.cpp

@@ -0,0 +1,100 @@
+#include "common_utils.h"
+#include <time.h>
+#include <cpuid.h>
+#include <util/c99defs.h>
+
+mfxStatus simple_alloc(mfxHDL pthis, mfxFrameAllocRequest *request,
+		       mfxFrameAllocResponse *response)
+{
+	UNUSED_PARAMETER(pthis);
+	UNUSED_PARAMETER(request);
+	UNUSED_PARAMETER(response);
+	return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus simple_lock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
+{
+	UNUSED_PARAMETER(pthis);
+	UNUSED_PARAMETER(mid);
+	UNUSED_PARAMETER(ptr);
+	return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus simple_unlock(mfxHDL pthis, mfxMemId mid, mfxFrameData *ptr)
+{
+	UNUSED_PARAMETER(pthis);
+	UNUSED_PARAMETER(mid);
+	UNUSED_PARAMETER(ptr);
+	return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus simple_gethdl(mfxHDL pthis, mfxMemId mid, mfxHDL *handle)
+{
+	UNUSED_PARAMETER(pthis);
+	UNUSED_PARAMETER(mid);
+	UNUSED_PARAMETER(handle);
+	return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus simple_free(mfxHDL pthis, mfxFrameAllocResponse *response)
+{
+	UNUSED_PARAMETER(pthis);
+	UNUSED_PARAMETER(response);
+	return MFX_ERR_UNSUPPORTED;
+}
+
+mfxStatus simple_copytex(mfxHDL pthis, mfxMemId mid, mfxU32 tex_handle,
+			 mfxU64 lock_key, mfxU64 *next_key)
+{
+	UNUSED_PARAMETER(pthis);
+	UNUSED_PARAMETER(mid);
+	UNUSED_PARAMETER(tex_handle);
+	UNUSED_PARAMETER(lock_key);
+	UNUSED_PARAMETER(next_key);
+	return MFX_ERR_UNSUPPORTED;
+}
+
+#if 0
+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,
+		     mfxFrameAllocator *pmfxAllocator, mfxHDL *deviceHandle,
+		     bool bCreateSharedHandles, bool dx9hack)
+{
+	UNUSED_PARAMETER(pmfxAllocator);
+	UNUSED_PARAMETER(deviceHandle);
+	UNUSED_PARAMETER(bCreateSharedHandles);
+	UNUSED_PARAMETER(dx9hack);
+	mfxStatus sts = MFX_ERR_NONE;
+
+	// Initialize Intel Media SDK Session
+	sts = pSession->Init(impl, &ver);
+	MSDK_CHECK_RESULT(sts, MFX_ERR_NONE, sts);
+	return sts;
+}
+
+// Release resources (device/display)
+void Release(){};
+
+void mfxGetTime(mfxTime *timestamp)
+{
+	clock_gettime(CLOCK_MONOTONIC, timestamp);
+}
+
+double TimeDiffMsec(mfxTime tfinish, mfxTime tstart)
+{
+	UNUSED_PARAMETER(tfinish);
+	UNUSED_PARAMETER(tstart);
+	//TODO, unused so far it seems
+	return 0.0;
+}
+
+extern "C" void util_cpuid(int cpuinfo[4], int level)
+{
+	__get_cpuid(level, (unsigned int *)&cpuinfo[0],
+		    (unsigned int *)&cpuinfo[1], (unsigned int *)&cpuinfo[2],
+		    (unsigned int *)&cpuinfo[3]);
+}

+ 15 - 0
plugins/obs-qsv11/obs-qsv11-plugin-main.c

@@ -93,6 +93,7 @@ static bool enum_luids(void *param, uint32_t idx, uint64_t luid)
 
 
 bool obs_module_load(void)
 bool obs_module_load(void)
 {
 {
+#if defined(_WIN32)
 	char *test_exe = os_get_executable_path_ptr("obs-qsv-test.exe");
 	char *test_exe = os_get_executable_path_ptr("obs-qsv-test.exe");
 	struct dstr cmd = {0};
 	struct dstr cmd = {0};
 	struct dstr caps_str = {0};
 	struct dstr caps_str = {0};
@@ -161,6 +162,18 @@ bool obs_module_load(void)
 		av1_supported |= adapter->supports_av1;
 		av1_supported |= adapter->supports_av1;
 		hevc_supported |= adapter->supports_hevc;
 		hevc_supported |= adapter->supports_hevc;
 	}
 	}
+#else
+	// We could lift the VA-API query from obs-ffmpeg here.
+	adapter_count = 1;
+	struct adapter_info *adapter = &adapters[0];
+	adapter->is_intel = true;
+	adapter->is_dgpu = true;
+	adapter->supports_av1 = true;
+	adapter->supports_hevc = true;
+	bool avc_supported = true;
+	bool hevc_supported = true;
+	bool av1_supported = true;
+#endif
 
 
 	if (avc_supported) {
 	if (avc_supported) {
 		obs_register_encoder(&obs_qsv_encoder_tex_v2);
 		obs_register_encoder(&obs_qsv_encoder_tex_v2);
@@ -180,11 +193,13 @@ bool obs_module_load(void)
 #endif
 #endif
 
 
 fail:
 fail:
+#if defined(_WIN32)
 	config_close(config);
 	config_close(config);
 	dstr_free(&caps_str);
 	dstr_free(&caps_str);
 	dstr_free(&cmd);
 	dstr_free(&cmd);
 	os_process_pipe_destroy(pp);
 	os_process_pipe_destroy(pp);
 	bfree(test_exe);
 	bfree(test_exe);
+#endif
 
 
 	return true;
 	return true;
 }
 }

+ 4 - 0
plugins/obs-qsv11/obs-qsv11.c

@@ -75,6 +75,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
 #define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__)
 #define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
 #define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
 
 
+#ifndef GS_INVALID_HANDLE
+#define GS_INVALID_HANDLE (uint32_t) - 1
+#endif
+
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */
 
 
 struct obs_qsv {
 struct obs_qsv {