feat(encode): native QSV backend — libvpl-sys + qsv.rs (Phases 0-3 of design/native-qsv-encoder.md)
Vendored MIT VPL dispatcher (static, trimmed tree, pin 674d015b/v2.17.0) built via cmake+bindgen behind new feature 'qsv' (pf-encode + punktfunk-host forward). qsv.rs: dispatcher session on the capture adapter (LUID-matched), SetHandle D3D11, AsyncDepth=1/GopRefDist=1/VDEnc/CBR + HRD-off low-latency config, GetSurfaceForEncode + GPU CopySubresourceRegion input (zero-copy, no readback path), bounded sync-point poll, in-place reset with teardown escalation, no-IDR bitrate retarget (Reset + StartNewSequence=OFF), 10-bit P010 HEVC-Main10/AV1, HDR mastering/CLL SEI-OBU at IDR + BT.2020/PQ VSI, LTR-RFI via mfxExtRefListCtrl (AMF slot policy port, Query-gated per codec, wire-index FrameOrder pinning). Dispatch: native-first with ffmpeg fallback + PUNKTFUNK_QSV_FFMPEG hatch; probes (can_encode_10bit / windows_codec_support / windows_backend_is_probed) now answer natively for QSV. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
# ##############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
# ##############################################################################
|
||||
cmake_minimum_required(VERSION 3.13.0)
|
||||
set(TARGET VPL)
|
||||
set(OUTPUT_NAME "vpl")
|
||||
set(DLL_PREFIX "lib")
|
||||
|
||||
if(WIN32)
|
||||
set(SOURCES
|
||||
src/windows/main.cpp
|
||||
src/windows/mfx_critical_section.cpp
|
||||
src/windows/mfx_dispatcher.cpp
|
||||
src/windows/mfx_dispatcher_log.cpp
|
||||
src/windows/mfx_driver_store_loader.cpp
|
||||
src/windows/mfx_dxva2_device.cpp
|
||||
src/windows/mfx_function_table.cpp
|
||||
src/windows/mfx_library_iterator.cpp
|
||||
src/windows/mfx_load_dll.cpp
|
||||
src/windows/mfx_win_reg_key.cpp
|
||||
src/windows/libmfx.def)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
configure_file(src/windows/version.rc.in src/windows/version.rc @ONLY)
|
||||
list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/src/windows/version.rc)
|
||||
endif()
|
||||
endif()
|
||||
if(UNIX)
|
||||
set(SOURCES src/linux/mfxloader.cpp)
|
||||
|
||||
if(NOT DEFINED MFX_MODULES_DIR)
|
||||
set(MFX_MODULES_DIR ${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
endif()
|
||||
add_definitions(-DMFX_MODULES_DIR="${MFX_MODULES_DIR}")
|
||||
message(STATUS "MFX_MODULES_DIR=${MFX_MODULES_DIR}")
|
||||
endif()
|
||||
|
||||
if(BUILD_EXPERIMENTAL)
|
||||
add_definitions(-DONEVPL_EXPERIMENTAL)
|
||||
endif()
|
||||
|
||||
list(
|
||||
APPEND
|
||||
SOURCES
|
||||
src/mfx_dispatcher_vpl.cpp
|
||||
src/mfx_dispatcher_vpl_loader.cpp
|
||||
src/mfx_dispatcher_vpl_config.cpp
|
||||
src/mfx_dispatcher_vpl_lowlatency.cpp
|
||||
src/mfx_dispatcher_vpl_log.cpp
|
||||
src/mfx_dispatcher_vpl_msdk.cpp
|
||||
src/mfx_config_interface/mfx_config_interface.cpp
|
||||
src/mfx_config_interface/mfx_config_interface_string_api.cpp)
|
||||
|
||||
add_library(${TARGET} "")
|
||||
|
||||
# disable warnings for dispatcher library itself but not subprojects (unit
|
||||
# tests)
|
||||
set_target_properties(${TARGET} PROPERTIES COMPILE_DEFINITIONS
|
||||
"MFX_DEPRECATED_OFF")
|
||||
|
||||
# optionally include the install location of dispatcher dll in the runtime
|
||||
# search process
|
||||
if(UNIX)
|
||||
if(ENABLE_LIBDIR_IN_RUNTIME_SEARCH)
|
||||
file(TO_CMAKE_PATH "${CMAKE_INSTALL_FULL_LIBDIR}" _install_libdir_search)
|
||||
target_compile_definitions(
|
||||
${TARGET} PRIVATE INSTALL_LIBDIR_SEARCH=\"${_install_libdir_search}\")
|
||||
message(STATUS "Enabled install libdir search: ${_install_libdir_search}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# force libxxx style sharedlib name on Windows
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set_target_properties(${TARGET} PROPERTIES PREFIX ${DLL_PREFIX})
|
||||
endif()
|
||||
set(SHLIB_FILE_NAME ${DLL_PREFIX}${OUTPUT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set(SHLIB_FILE_NAME_DEBUG
|
||||
${DLL_PREFIX}${OUTPUT_NAME}${CMAKE_DEBUG_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
)
|
||||
|
||||
else()
|
||||
# use version script on Linux
|
||||
set_target_properties(
|
||||
${TARGET}
|
||||
PROPERTIES
|
||||
LINK_FLAGS
|
||||
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/src/linux/libvpl.map")
|
||||
set(SHLIB_FILE_NAME
|
||||
${CMAKE_SHARED_LIBRARY_PREFIX}${OUTPUT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}.${API_VERSION_MAJOR}
|
||||
)
|
||||
set(SHLIB_FILE_NAME_DEBUG ${SHLIB_FILE_NAME})
|
||||
endif()
|
||||
|
||||
set(LIB_FILE_NAME
|
||||
${CMAKE_STATIC_LIBRARY_PREFIX}${OUTPUT_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
set(IMPLIB_FILE_NAME
|
||||
${CMAKE_IMPORT_LIBRARY_PREFIX}${OUTPUT_NAME}${CMAKE_IMPORT_LIBRARY_SUFFIX})
|
||||
set(LIB_FILE_NAME_DEBUG
|
||||
${CMAKE_STATIC_LIBRARY_PREFIX}${OUTPUT_NAME}${CMAKE_DEBUG_POSTFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}
|
||||
)
|
||||
set(IMPLIB_FILE_NAME_DEBUG
|
||||
${CMAKE_IMPORT_LIBRARY_PREFIX}${OUTPUT_NAME}${CMAKE_DEBUG_POSTFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
${TARGET}
|
||||
PROPERTIES OUTPUT_NAME ${OUTPUT_NAME} SOVERSION ${API_VERSION_MAJOR}
|
||||
VERSION ${API_VERSION_MAJOR}.${API_VERSION_MINOR})
|
||||
|
||||
target_sources(${TARGET} PRIVATE ${SOURCES})
|
||||
|
||||
if(UNIX)
|
||||
# require pthreads for loading legacy MSDK runtimes
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_link_libraries(${TARGET} PRIVATE Threads::Threads)
|
||||
else()
|
||||
target_link_libraries(${TARGET} PUBLIC Threads::Threads)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TARGET} PUBLIC vpl-api)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_link_libraries(${TARGET} PRIVATE ${CMAKE_DL_LIBS})
|
||||
else()
|
||||
target_link_libraries(${TARGET} PUBLIC ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if(INSTALL_LIB)
|
||||
install(
|
||||
TARGETS ${TARGET}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT ${VPL_COMPONENT_LIB}
|
||||
NAMELINK_SKIP
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${VPL_COMPONENT_LIB})
|
||||
endif()
|
||||
|
||||
if(INSTALL_DEV)
|
||||
install(
|
||||
TARGETS ${TARGET}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT ${VPL_COMPONENT_DEV}
|
||||
NAMELINK_ONLY)
|
||||
if(WIN32)
|
||||
install(TARGETS ${TARGET} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT ${VPL_COMPONENT_DEV})
|
||||
endif()
|
||||
|
||||
file(RELATIVE_PATH cmake_rel_prefix ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/vpl
|
||||
${CMAKE_INSTALL_PREFIX})
|
||||
file(RELATIVE_PATH cmake_rel_libdir ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/vpl
|
||||
${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
file(RELATIVE_PATH cmake_rel_incdir ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/vpl
|
||||
${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
file(RELATIVE_PATH cmake_rel_bindir ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/vpl
|
||||
${CMAKE_INSTALL_FULL_BINDIR})
|
||||
|
||||
configure_file(cmake/VPLConfig.cmake.in cmake/VPLConfig.cmake @ONLY)
|
||||
configure_file(cmake/VPLConfigVersion.cmake.in cmake/VPLConfigVersion.cmake
|
||||
@ONLY)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/cmake/VPLConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake/VPLConfigVersion.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/vpl"
|
||||
COMPONENT ${VPL_COMPONENT_DEV})
|
||||
|
||||
file(RELATIVE_PATH pc_rel_prefix ${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig
|
||||
${CMAKE_INSTALL_PREFIX})
|
||||
file(RELATIVE_PATH pc_rel_libdir ${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig
|
||||
${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
file(RELATIVE_PATH pc_rel_incdir ${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig
|
||||
${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
set(pc_rel_prefix "$\{pcfiledir}/${pc_rel_prefix}")
|
||||
set(pc_rel_libdir "$\{pcfiledir}/${pc_rel_libdir}")
|
||||
set(pc_rel_incdir "$\{pcfiledir}/${pc_rel_incdir}")
|
||||
|
||||
if(CMAKE_DL_LIBS)
|
||||
set(DL_LIBS "-l${CMAKE_DL_LIBS}")
|
||||
endif()
|
||||
if(MINGW)
|
||||
# being conservative by restricting to MinGW, these are probably ok for
|
||||
# WIN32 in general
|
||||
set(MINGW_LIBS "-lole32 -lgdi32 -luuid")
|
||||
endif()
|
||||
set(VPL_PKGCONFIG_DEPENDENT_LIBS
|
||||
"${DL_LIBS} ${CMAKE_THREAD_LIBS_INIT} ${MINGW_LIBS} ${CXX_LIB}")
|
||||
configure_file("pkgconfig/vpl.pc.in" "pkgconfig/vpl.pc" @ONLY)
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/vpl.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
|
||||
COMPONENT ${VPL_COMPONENT_DEV})
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif()
|
||||
@@ -0,0 +1,146 @@
|
||||
# ##############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
# ##############################################################################
|
||||
|
||||
# * Config file for the VPL package It defines the following variables
|
||||
# VPL_<component>_FOUND VPL_IMPORTED_TARGETS
|
||||
#
|
||||
# VPLConfigVersion.cmake defines VPL_VERSION
|
||||
|
||||
option(VPL_SHARED "Use shared instead of static version of dispatcher."
|
||||
@BUILD_SHARED_LIBS@)
|
||||
|
||||
# Initialize to default values
|
||||
set(VPL_INTERFACE_VERSION @API_VERSION_MAJOR@)
|
||||
get_filename_component(_vpl_config_file
|
||||
"${CMAKE_CURRENT_LIST_DIR}/VPLConfig.cmake" REALPATH)
|
||||
get_filename_component(_vpl_config_dir "${_vpl_config_file}" DIRECTORY)
|
||||
get_filename_component(_vpl_install_prefix
|
||||
"${_vpl_config_dir}/@cmake_rel_prefix@" REALPATH)
|
||||
|
||||
get_filename_component(VPL_LIB_DIR "${_vpl_config_dir}/@cmake_rel_libdir@"
|
||||
ABSOLUTE)
|
||||
get_filename_component(VPL_INCLUDE_DIR "${_vpl_config_dir}/@cmake_rel_incdir@"
|
||||
ABSOLUTE)
|
||||
get_filename_component(VPL_BIN_DIR "${_vpl_config_dir}/@cmake_rel_bindir@"
|
||||
ABSOLUTE)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES Windows)
|
||||
set(VPL_SHLIB_DIR ${VPL_BIN_DIR})
|
||||
else()
|
||||
set(VPL_SHLIB_DIR ${VPL_LIB_DIR})
|
||||
endif()
|
||||
|
||||
if(NOT VPL_IMPORTED_TARGETS)
|
||||
set(VPL_IMPORTED_TARGETS "")
|
||||
endif()
|
||||
|
||||
if(NOT VPL_FIND_COMPONENTS)
|
||||
set(VPL_FIND_COMPONENTS "dispatcher;api")
|
||||
foreach(_vpl_component ${VPL_FIND_COMPONENTS})
|
||||
set(VPL_FIND_REQUIRED_${_vpl_component} 1)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# VPL::dispatcher
|
||||
set(VPL_dispatcher_FOUND 0)
|
||||
|
||||
get_filename_component(_dispatcher_shlib "${VPL_SHLIB_DIR}/@SHLIB_FILE_NAME@"
|
||||
ABSOLUTE)
|
||||
get_filename_component(_dispatcher_debug_shlib
|
||||
"${VPL_SHLIB_DIR}/@SHLIB_FILE_NAME_DEBUG@" ABSOLUTE)
|
||||
get_filename_component(_dispatcher_lib "${VPL_LIB_DIR}/@LIB_FILE_NAME@"
|
||||
ABSOLUTE)
|
||||
get_filename_component(_dispatcher_debug_lib
|
||||
"${VPL_LIB_DIR}/@LIB_FILE_NAME_DEBUG@" ABSOLUTE)
|
||||
get_filename_component(_dispatcher_implib "${VPL_LIB_DIR}/@LIB_FILE_NAME@"
|
||||
ABSOLUTE)
|
||||
get_filename_component(_dispatcher_debug_implib
|
||||
"${VPL_LIB_DIR}/@LIB_FILE_NAME_DEBUG@" ABSOLUTE)
|
||||
|
||||
if(TARGET VPL::dispatcher)
|
||||
list(APPEND VPL_IMPORTED_TARGETS VPL::dispatcher)
|
||||
set(VPL_dispatcher_FOUND 1)
|
||||
else()
|
||||
if(VPL_SHARED)
|
||||
if(EXISTS "${_dispatcher_shlib}" OR EXISTS "${_dispatcher_debug_shlib}")
|
||||
list(APPEND VPL_IMPORTED_TARGETS VPL::dispatcher)
|
||||
set(VPL_dispatcher_FOUND 1)
|
||||
|
||||
add_library(VPL::dispatcher SHARED IMPORTED)
|
||||
set_target_properties(
|
||||
VPL::dispatcher
|
||||
PROPERTIES IMPORTED_LOCATION_RELEASE ${_dispatcher_shlib}
|
||||
IMPORTED_LOCATION_RELWITHDEBINFO ${_dispatcher_shlib}
|
||||
IMPORTED_LOCATION_MINSIZEREL ${_dispatcher_shlib}
|
||||
IMPORTED_LOCATION_DEBUG ${_dispatcher_debug_shlib}
|
||||
IMPORTED_LOCATION_RELWITHDEBRT ${_dispatcher_debug_shlib})
|
||||
if(CMAKE_SYSTEM_NAME MATCHES Windows)
|
||||
set_target_properties(
|
||||
VPL::dispatcher
|
||||
PROPERTIES IMPORTED_IMPLIB_RELEASE ${_dispatcher_implib}
|
||||
IMPORTED_IMPLIB_RELWITHDEBINFO ${_dispatcher_implib}
|
||||
IMPORTED_IMPLIB_MINSIZEREL ${_dispatcher_implib}
|
||||
IMPORTED_IMPLIB_DEBUG ${_dispatcher_debug_implib}
|
||||
IMPORTED_IMPLIB_RELWITHDEBRT ${_dispatcher_debug_implib})
|
||||
endif()
|
||||
elseif(VPL_FIND_REQUIRED AND VPL_FIND_REQUIRED_dispatcher)
|
||||
message(STATUS "Unable to find required VPL component: dispatcher")
|
||||
set(VPL_FOUND FALSE)
|
||||
endif()
|
||||
else()
|
||||
if(EXISTS "${_dispatcher_lib}" OR EXISTS "${_dispatcher_debug_lib}")
|
||||
list(APPEND VPL_IMPORTED_TARGETS VPL::dispatcher)
|
||||
set(VPL_dispatcher_FOUND 1)
|
||||
add_library(VPL::dispatcher STATIC IMPORTED)
|
||||
set_target_properties(
|
||||
VPL::dispatcher
|
||||
PROPERTIES IMPORTED_LOCATION_RELEASE ${_dispatcher_lib}
|
||||
IMPORTED_LOCATION_RELWITHDEBINFO ${_dispatcher_lib}
|
||||
IMPORTED_LOCATION_MINSIZEREL ${_dispatcher_lib}
|
||||
IMPORTED_LOCATION_DEBUG ${_dispatcher_debug_lib}
|
||||
IMPORTED_LOCATION_RELWITHDEBRT ${_dispatcher_debug_lib})
|
||||
if(UNIX)
|
||||
# require pthreads for loading legacy MSDK runtimes
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(VPL::dispatcher INTERFACE Threads::Threads)
|
||||
endif()
|
||||
target_link_libraries(VPL::dispatcher INTERFACE ${CMAKE_DL_LIBS})
|
||||
elseif(VPL_FIND_REQUIRED AND VPL_FIND_REQUIRED_dispatcher)
|
||||
message(STATUS "Unable to find required VPL component: dispatcher")
|
||||
set(VPL_FOUND FALSE)
|
||||
endif()
|
||||
endif()
|
||||
set_target_properties(VPL::dispatcher PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${VPL_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
unset(_dispatcher_shlib)
|
||||
|
||||
# VPL::api
|
||||
set(VPL_api_FOUND 0)
|
||||
if(EXISTS ${VPL_INCLUDE_DIR})
|
||||
if(NOT TARGET VPL::api)
|
||||
add_library(VPL::api INTERFACE IMPORTED)
|
||||
set_target_properties(VPL::api PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${VPL_INCLUDE_DIR}")
|
||||
endif()
|
||||
list(APPEND VPL_IMPORTED_TARGETS VPL::api)
|
||||
set(VPL_api_FOUND 1)
|
||||
endif()
|
||||
|
||||
# VPL::cppapi
|
||||
set(VPL_cppapi_FOUND 0)
|
||||
if(EXISTS ${VPL_INCLUDE_DIR})
|
||||
if(NOT TARGET VPL::cppapi)
|
||||
add_library(VPL::cppapi INTERFACE IMPORTED)
|
||||
set_target_properties(VPL::cppapi PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${VPL_INCLUDE_DIR}")
|
||||
endif()
|
||||
list(APPEND VPL_IMPORTED_TARGETS VPL::cppapi)
|
||||
set(VPL_cppapi_FOUND 1)
|
||||
endif()
|
||||
@@ -0,0 +1,17 @@
|
||||
# ##############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
# ##############################################################################
|
||||
|
||||
set(PACKAGE_VERSION "@API_VERSION_MAJOR@.@API_VERSION_MINOR@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,12 @@
|
||||
prefix=@pc_rel_prefix@
|
||||
libdir=@pc_rel_libdir@
|
||||
includedir=@pc_rel_incdir@
|
||||
|
||||
Name: Intel(R) Video Processing Library
|
||||
Description: Accelerated video decode, encode, and frame processing capabilities on Intel(R) GPUs
|
||||
Version: @API_VERSION_MAJOR@.@API_VERSION_MINOR@
|
||||
URL: https://github.com/intel/libvpl
|
||||
|
||||
Libs: -L${libdir} -l@OUTPUT_NAME@ @VPL_PKGCONFIG_DEPENDENT_LIBS@
|
||||
Libs.private: @VPL_PKGCONFIG_PRIVATE_LIBS@
|
||||
Cflags: -I${includedir} -I${includedir}/vpl
|
||||
@@ -0,0 +1,448 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_LINUX_DEVICE_IDS_H_
|
||||
#define LIBVPL_SRC_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 <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "vpl/mfxvideo.h"
|
||||
|
||||
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) {
|
||||
Device device;
|
||||
std::string path = std::string(dir) + "/renderD" + std::to_string(128 + i) + vendor_id_file;
|
||||
std::string line;
|
||||
std::ifstream dev_str;
|
||||
|
||||
dev_str.open(path);
|
||||
if (!dev_str.is_open()) {
|
||||
continue;
|
||||
}
|
||||
std::getline(dev_str, line);
|
||||
dev_str.close();
|
||||
try {
|
||||
device.vendor_id = std::stoul(line, 0, 16);
|
||||
}
|
||||
catch (std::invalid_argument &) {
|
||||
continue;
|
||||
}
|
||||
catch (std::out_of_range &) {
|
||||
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;
|
||||
dev_str.open(path);
|
||||
if (!dev_str.is_open()) {
|
||||
continue;
|
||||
}
|
||||
std::getline(dev_str, line);
|
||||
dev_str.close();
|
||||
try {
|
||||
device.device_id = std::stoul(line, 0, 16);
|
||||
}
|
||||
catch (std::invalid_argument &) {
|
||||
continue;
|
||||
}
|
||||
catch (std::out_of_range &) {
|
||||
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 // LIBVPL_SRC_LINUX_DEVICE_IDS_H_
|
||||
@@ -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;
|
||||
@@ -0,0 +1,842 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) 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"
|
||||
|
||||
// internal implementation of mfxConfigInterface
|
||||
#include "src/mfx_config_interface/mfx_config_interface.h"
|
||||
|
||||
#include "src/linux/device_ids.h"
|
||||
#include "src/linux/mfxloader.h"
|
||||
|
||||
namespace MFX {
|
||||
|
||||
#if defined(__x86_64__) || (INTPTR_MAX == INT64_MAX)
|
||||
#define LIBMFXSW "libmfxsw64.so.1"
|
||||
#define LIBMFXHW "libmfxhw64.so.1"
|
||||
|
||||
#define ONEVPLSW "libvplswref64.so.1"
|
||||
#define ONEVPLHW "libmfx-gen.so.1.2"
|
||||
#elif defined(__i386__) || (INTPTR_MAX == INT32_MAX)
|
||||
#define LIBMFXSW "libmfxsw32.so.1"
|
||||
#define LIBMFXHW "libmfxhw32.so.1"
|
||||
|
||||
#define ONEVPLSW "libvplswref32.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,
|
||||
eMFXVideoCORE_GetHandle,
|
||||
#include "src/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) },
|
||||
{ eMFXVideoCORE_GetHandle, "MFXVideoCORE_GetHandle", VERSION(1, 0) },
|
||||
#include "src/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,
|
||||
bool bCloneSession = false);
|
||||
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;
|
||||
}
|
||||
|
||||
inline void *getHandle() const {
|
||||
return m_dlh.get();
|
||||
}
|
||||
|
||||
inline const char *getLibPath() const {
|
||||
return m_libToLoad.c_str();
|
||||
}
|
||||
|
||||
// special operations to set session pointer and version from MFXCloneSession()
|
||||
inline void setSession(const mfxSession session) {
|
||||
m_session = session;
|
||||
}
|
||||
|
||||
inline void setVersion(const mfxVersion version) {
|
||||
m_version = 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::string m_libToLoad;
|
||||
};
|
||||
|
||||
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,
|
||||
bool bCloneSession) {
|
||||
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 Intel® Video Processing Library (Intel® VPL) 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
|
||||
// this may also be used later by MFXCloneSession()
|
||||
m_libToLoad = dllName;
|
||||
libs.emplace_back(m_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 Intel® VPL
|
||||
libs.emplace_back(ONEVPLHW);
|
||||
libs.emplace_back(MFX_MODULES_DIR "/" ONEVPLHW);
|
||||
}
|
||||
|
||||
// use MSDK (fallback if Intel® VPL is not installed)
|
||||
libs.emplace_back(LIBMFXHW);
|
||||
libs.emplace_back(MFX_MODULES_DIR "/" LIBMFXHW);
|
||||
}
|
||||
|
||||
// add SW lib (Intel® VPL 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 (bCloneSession == true) {
|
||||
// success - exit loop since caller will create session with MFXCloneSession()
|
||||
mfx_res = MFX_ERR_NONE;
|
||||
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);
|
||||
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
// if GPUCopy is enabled via MFXSetConfigProperty(DeviceCopy), set corresponding
|
||||
// flag in mfxInitParam for legacy RTs
|
||||
par.GPUCopy = vplParam.DeviceCopy;
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// implement as a non-passthrough function so that we can catch dispatcher-level interface query requests
|
||||
mfxStatus MFXVideoCORE_GetHandle(mfxSession session, mfxHandleType type, mfxHDL *hdl) {
|
||||
if (!session)
|
||||
return MFX_ERR_INVALID_HANDLE;
|
||||
|
||||
MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
|
||||
|
||||
// first check if handle type points to an interface implemented inside the dispatcher
|
||||
if (type == MFX_HANDLE_CONFIG_INTERFACE) {
|
||||
if (!hdl)
|
||||
return MFX_ERR_NULL_PTR;
|
||||
|
||||
*hdl = (mfxHDL)(&(MFX_CONFIG_INTERFACE::g_dispatcher_mfxConfigInterface));
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
// passthrough to runtime
|
||||
auto proc =
|
||||
(decltype(MFXVideoCORE_GetHandle) *)loader->getFunction(MFX::eMFXVideoCORE_GetHandle);
|
||||
if (!proc) {
|
||||
return MFX_ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return (*proc)(loader->getSession(), type, hdl);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
static mfxStatus AllocateCloneLoader(MFX::LoaderCtx *parentLoader, MFX::LoaderCtx **cloneLoader) {
|
||||
// initialization param structs are not used when bCloneSession == true
|
||||
mfxInitParam par = {};
|
||||
mfxInitializationParam vplParam = {};
|
||||
mfxU16 deviceID = 0;
|
||||
|
||||
// initialization extBufs are not saved at this level
|
||||
// the RT should save these when the parent session is created and may use
|
||||
// them when creating the cloned session
|
||||
par.NumExtParam = 0;
|
||||
|
||||
try {
|
||||
std::unique_ptr<MFX::LoaderCtx> cl;
|
||||
|
||||
cl.reset(new MFX::LoaderCtx{});
|
||||
|
||||
mfxStatus mfx_res =
|
||||
cl->Init(par, vplParam, &deviceID, (char *)parentLoader->getLibPath(), true);
|
||||
if (MFX_ERR_NONE == mfx_res) {
|
||||
*cloneLoader = cl.release();
|
||||
}
|
||||
else {
|
||||
*cloneLoader = nullptr;
|
||||
}
|
||||
|
||||
return mfx_res;
|
||||
}
|
||||
catch (...) {
|
||||
return MFX_ERR_MEMORY_ALLOC;
|
||||
}
|
||||
}
|
||||
|
||||
mfxStatus MFXCloneSession(mfxSession session, mfxSession *clone) {
|
||||
if (!session || !clone)
|
||||
return MFX_ERR_INVALID_HANDLE;
|
||||
|
||||
MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
|
||||
mfxVersion version = loader->getVersion();
|
||||
*clone = nullptr;
|
||||
|
||||
// initialize the clone session
|
||||
// for runtimes with 1.x API, call MFXInit followed by MFXJoinSession
|
||||
// for runtimes with 2.x API, use RT implementation of MFXCloneSession (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 if (version.Major == 2) {
|
||||
MFX::LoaderCtx *loader = (MFX::LoaderCtx *)session;
|
||||
|
||||
// MFXCloneSession not included in function pointer search during init
|
||||
// for bwd-compat, check for it here and fail gracefully if missing
|
||||
void *libHandle = loader->getHandle();
|
||||
auto proc = (decltype(MFXCloneSession) *)(dlsym(libHandle, "MFXCloneSession"));
|
||||
if (!proc)
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
|
||||
// allocate new dispatcher-level session object and copy
|
||||
// state from parent session (function pointer tables, impl type, etc.)
|
||||
MFX::LoaderCtx *cloneLoader;
|
||||
mfxStatus mfx_res = AllocateCloneLoader(loader, &cloneLoader);
|
||||
if (mfx_res != MFX_ERR_NONE)
|
||||
return mfx_res;
|
||||
|
||||
// call RT implementation of MFXCloneSession
|
||||
mfxSession cloneRT;
|
||||
mfx_res = (*proc)(loader->getSession(), &cloneRT);
|
||||
|
||||
if (mfx_res != MFX_ERR_NONE || cloneRT == NULL) {
|
||||
// RT call failed, delete cloned loader (no valid session created)
|
||||
delete cloneLoader;
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
cloneLoader->setSession(cloneRT);
|
||||
|
||||
// get version of cloned session
|
||||
mfxVersion cloneVersion = {};
|
||||
mfx_res = MFXQueryVersion((mfxSession)cloneLoader, &cloneVersion);
|
||||
cloneLoader->setVersion(cloneVersion);
|
||||
if (mfx_res != MFX_ERR_NONE) {
|
||||
MFXClose((mfxSession)cloneLoader);
|
||||
return mfx_res;
|
||||
}
|
||||
|
||||
*clone = (mfxSession)cloneLoader;
|
||||
}
|
||||
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 "src/linux/mfxvideo_functions.h" // NOLINT(build/include)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_LINUX_MFXLOADER_H_
|
||||
#define LIBVPL_SRC_LINUX_MFXLOADER_H_
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "vpl/mfxvideo.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));
|
||||
}
|
||||
|
||||
inline bool operator==(mfxGUID const &l, mfxGUID const &r) {
|
||||
return std::equal(l.Data, l.Data + 16, r.Data);
|
||||
}
|
||||
|
||||
#endif // LIBVPL_SRC_LINUX_MFXLOADER_H_
|
||||
@@ -0,0 +1,176 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) 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_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
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignConsecutiveMacros: true
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: None
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 150
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 8
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^<ext/.*\.h>'
|
||||
Priority: 2
|
||||
- Regex: '^<.*\.h>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Right
|
||||
RawStringFormats:
|
||||
- Language: Cpp
|
||||
Delimiters:
|
||||
- cc
|
||||
- CC
|
||||
- cpp
|
||||
- Cpp
|
||||
- CPP
|
||||
- 'c++'
|
||||
- 'C++'
|
||||
CanonicalDelimiter: ''
|
||||
BasedOnStyle: google
|
||||
- Language: TextProto
|
||||
Delimiters:
|
||||
- pb
|
||||
- PB
|
||||
- proto
|
||||
- PROTO
|
||||
EnclosingFunctions:
|
||||
- EqualsProto
|
||||
- EquivToProto
|
||||
- PARSE_PARTIAL_TEXT_PROTO
|
||||
- PARSE_TEST_PROTO
|
||||
- PARSE_TEXT_PROTO
|
||||
- ParseTextOrDie
|
||||
- ParseTextProtoOrDie
|
||||
CanonicalDelimiter: ''
|
||||
BasedOnStyle: google
|
||||
ReflowComments: false
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 1
|
||||
UseTab: Never
|
||||
...
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/mfx_config_interface/mfx_config_interface.h"
|
||||
|
||||
namespace MFX_CONFIG_INTERFACE {
|
||||
|
||||
// leave table formatting alone
|
||||
// clang-format off
|
||||
|
||||
// Dispatcher-level implementation of mfxConfigInterface.
|
||||
// Current implementation is stateless (string API only) so set Context to a special key.
|
||||
// We could replace Context with pointer to mfxSession (or some object within mfxSession)
|
||||
// if future extensions require access to the session state.
|
||||
// The application is not permitted to modify or dereference Context (see struct definition)
|
||||
// so we can set this to whatever we need.
|
||||
const mfxConfigInterface g_dispatcher_mfxConfigInterface = {
|
||||
MFX_CONFIG_INTERFACE_CONTEXT, // Context
|
||||
{ { 0, 1 } }, // Version
|
||||
|
||||
MFX_CONFIG_INTERFACE::ExtSetParameter, // SetParameter (callback function)
|
||||
|
||||
{}, // reserved
|
||||
};
|
||||
|
||||
// end table formatting
|
||||
// clang-format on
|
||||
|
||||
// callback function - set mfxConfigInterface::SetParameter to this
|
||||
// this has to be static since it's returned as function pointer, so cast session to _mfxSession
|
||||
// to access session-specific state (current implementation is stateless)
|
||||
mfxStatus ExtSetParameter(struct mfxConfigInterface *config_interface,
|
||||
const mfxU8 *key,
|
||||
const mfxU8 *value,
|
||||
mfxStructureType struct_type,
|
||||
mfxHDL structure,
|
||||
mfxExtBuffer *ext_buffer) {
|
||||
if (struct_type == MFX_STRUCTURE_TYPE_VIDEO_PARAM) {
|
||||
return SetParameter(key, value, (mfxVideoParam *)structure, ext_buffer);
|
||||
}
|
||||
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// validate key and value input strings
|
||||
mfxStatus ValidateKVPair(const mfxU8 *key, const mfxU8 *value, KVPair &kvStr) {
|
||||
mfxU32 lengthKey, lengthValue;
|
||||
|
||||
// manually check length of key string
|
||||
for (lengthKey = 0; lengthKey < MAX_PARAM_STRING_LENGTH; lengthKey++) {
|
||||
if (!key[lengthKey])
|
||||
break;
|
||||
}
|
||||
if (lengthKey == 0 || lengthKey == MAX_PARAM_STRING_LENGTH)
|
||||
return MFX_ERR_INVALID_VIDEO_PARAM;
|
||||
|
||||
// manually check length of value string
|
||||
for (lengthValue = 0; lengthValue < MAX_PARAM_STRING_LENGTH; lengthValue++) {
|
||||
if (!value[lengthValue])
|
||||
break;
|
||||
}
|
||||
if (lengthValue == 0 || lengthValue == MAX_PARAM_STRING_LENGTH)
|
||||
return MFX_ERR_INVALID_VIDEO_PARAM;
|
||||
|
||||
kvStr.first = (const char *)key;
|
||||
kvStr.second = (const char *)value;
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
mfxStatus SetParameter(const mfxU8 *key, const mfxU8 *value, mfxVideoParam *videoParam, mfxExtBuffer *extBuf) {
|
||||
if (!key || !value || !videoParam || !extBuf)
|
||||
return MFX_ERR_NULL_PTR;
|
||||
|
||||
*extBuf = {}; // clear extBuf, will be filled in if new extBuf is required from caller
|
||||
|
||||
mfxStatus sts = MFX_ERR_NOT_FOUND; // default if no valid parameters
|
||||
|
||||
// validate C-style key and value strings
|
||||
// output is a pair of std::string's in kvStr
|
||||
KVPair kvStr;
|
||||
sts = ValidateKVPair(key, value, kvStr);
|
||||
if (sts != MFX_ERR_NONE)
|
||||
return sts;
|
||||
|
||||
if (IsExtBuf(kvStr)) {
|
||||
mfxExtBuffer extBufRequired = {};
|
||||
|
||||
// key maps to a parameter in an extension buffer
|
||||
sts = UpdateExtBufParam(kvStr, videoParam, &extBufRequired);
|
||||
|
||||
// if required extension buffer is not attached, we request the app to allocate it
|
||||
// and then call the SetParameter function again
|
||||
if (sts == MFX_ERR_MORE_EXTBUFFER) {
|
||||
extBuf->BufferId = extBufRequired.BufferId;
|
||||
extBuf->BufferSz = extBufRequired.BufferSz;
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
// key maps to a parameter in mfxVideoParam
|
||||
sts = UpdateVideoParam(kvStr, videoParam);
|
||||
return sts;
|
||||
}
|
||||
|
||||
} // namespace MFX_CONFIG_INTERFACE
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_MFX_CONFIG_INTERFACE_MFX_CONFIG_INTERFACE_H_
|
||||
#define LIBVPL_SRC_MFX_CONFIG_INTERFACE_MFX_CONFIG_INTERFACE_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "vpl/mfxvideo.h"
|
||||
|
||||
// special key to indicate Context is not a real context, as it is a stateless interface
|
||||
#define MFX_CONFIG_INTERFACE_CONTEXT ((mfxHDL)(-1))
|
||||
|
||||
namespace MFX_CONFIG_INTERFACE {
|
||||
|
||||
// dispatcher returns this interface from call to MFXVideoCORE_GetHandle(type = MFX_HANDLE_CONFIG_INTERFACE)
|
||||
extern const mfxConfigInterface g_dispatcher_mfxConfigInterface;
|
||||
|
||||
// string K-V pairs, each key may only have a single value
|
||||
typedef std::pair<std::string, std::string> KVPair;
|
||||
|
||||
mfxStatus MFX_CDECL ExtSetParameter(struct mfxConfigInterface *config_interface,
|
||||
const mfxU8 *key,
|
||||
const mfxU8 *value,
|
||||
mfxStructureType struct_type,
|
||||
mfxHDL structure,
|
||||
mfxExtBuffer *ext_buffer);
|
||||
|
||||
mfxStatus SetParameter(const mfxU8 *key, const mfxU8 *value, mfxVideoParam *videoParam, mfxExtBuffer *extBuf);
|
||||
|
||||
mfxStatus UpdateVideoParam(const KVPair &kvStr, mfxVideoParam *videoParam);
|
||||
mfxStatus UpdateExtBufParam(const KVPair &kvStr, mfxVideoParam *videoParam, mfxExtBuffer *extBufRequired);
|
||||
bool IsExtBuf(const KVPair &kvStr);
|
||||
|
||||
mfxStatus ValidateKVPair(const mfxU8 *key, const mfxU8 *value, KVPair &kvStr);
|
||||
mfxStatus SetExtBufParam(mfxExtBuffer *extBufActual, KVPair &kvStrParsed);
|
||||
mfxStatus GetExtBufType(const KVPair &kvStr, mfxExtBuffer *extBufHeader, KVPair &kvStrParsed);
|
||||
|
||||
}; // namespace MFX_CONFIG_INTERFACE
|
||||
|
||||
#endif // LIBVPL_SRC_MFX_CONFIG_INTERFACE_MFX_CONFIG_INTERFACE_H_
|
||||
Vendored
+1464
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,229 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/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{});
|
||||
|
||||
// initialize logging if appropriate environment variables are set
|
||||
pLoaderCtx->InitDispatcherLog();
|
||||
|
||||
loaderCtx = (LoaderCtxVPL *)pLoaderCtx.release();
|
||||
}
|
||||
catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return (mfxLoader)loaderCtx;
|
||||
}
|
||||
|
||||
// unload libraries, destroy all created mfxConfig objects, free other memory
|
||||
void MFXUnload(mfxLoader loader) {
|
||||
try {
|
||||
if (!loader)
|
||||
return;
|
||||
|
||||
LoaderCtxVPL *loaderCtx = (LoaderCtxVPL *)loader;
|
||||
|
||||
loaderCtx->UnloadAllLibraries();
|
||||
|
||||
loaderCtx->FreeConfigFilters();
|
||||
|
||||
delete loaderCtx;
|
||||
}
|
||||
catch (...) {
|
||||
// nothing to return
|
||||
}
|
||||
}
|
||||
|
||||
// create config context
|
||||
// each loader may have more than one config context
|
||||
mfxConfig MFXCreateConfig(mfxLoader loader) {
|
||||
try {
|
||||
if (!loader)
|
||||
return nullptr;
|
||||
|
||||
LoaderCtxVPL *loaderCtx = (LoaderCtxVPL *)loader;
|
||||
ConfigCtxVPL *configCtx;
|
||||
|
||||
DispatcherLogVPL *dispLog = loaderCtx->GetLogger();
|
||||
DISP_LOG_FUNCTION(dispLog);
|
||||
|
||||
configCtx = loaderCtx->AddConfigFilter();
|
||||
|
||||
return (mfxConfig)(configCtx);
|
||||
}
|
||||
catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// set a config property to use in enumerating implementations
|
||||
mfxStatus MFXSetConfigFilterProperty(mfxConfig config, const mfxU8 *name, mfxVariant value) {
|
||||
try {
|
||||
if (!config)
|
||||
return MFX_ERR_NULL_PTR;
|
||||
|
||||
ConfigCtxVPL *configCtx = (ConfigCtxVPL *)config;
|
||||
LoaderCtxVPL *loaderCtx = configCtx->m_parentLoader;
|
||||
|
||||
if (!loaderCtx)
|
||||
return MFX_ERR_NULL_PTR; // should never happen - always set during MFXCreateConfig()
|
||||
|
||||
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();
|
||||
if (sts)
|
||||
return sts;
|
||||
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
sts = loaderCtx->UpdatePropsQuery();
|
||||
#endif
|
||||
|
||||
return sts;
|
||||
}
|
||||
catch (...) {
|
||||
return MFX_ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over available implementations
|
||||
// capabilities are returned in idesc
|
||||
mfxStatus MFXEnumImplementations(mfxLoader loader,
|
||||
mfxU32 i,
|
||||
mfxImplCapsDeliveryFormat format,
|
||||
mfxHDL *idesc) {
|
||||
try {
|
||||
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) {
|
||||
// if a session was already created in low-latency mode, unload all implementations
|
||||
// before running full load and query
|
||||
if (loaderCtx->m_bLowLatency && !loaderCtx->m_bNeedLowLatencyQuery) {
|
||||
loaderCtx->UnloadAllLibraries();
|
||||
}
|
||||
|
||||
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->QueryImpl(i, format, idesc);
|
||||
|
||||
return sts;
|
||||
}
|
||||
catch (...) {
|
||||
return MFX_ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// create a new session with implementation i
|
||||
mfxStatus MFXCreateSession(mfxLoader loader, mfxU32 i, mfxSession *session) {
|
||||
try {
|
||||
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;
|
||||
}
|
||||
catch (...) {
|
||||
return MFX_ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// release memory associated with implementation description hdl
|
||||
mfxStatus MFXDispReleaseImplDescription(mfxLoader loader, mfxHDL hdl) {
|
||||
try {
|
||||
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;
|
||||
}
|
||||
catch (...) {
|
||||
return MFX_ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,669 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_MFX_DISPATCHER_VPL_H_
|
||||
#define LIBVPL_SRC_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
|
||||
};
|
||||
|
||||
enum VPLOptionalFunctionIdx {
|
||||
// 2.15
|
||||
IdxMFXQueryImplsProperties = 0,
|
||||
|
||||
NumVPLOptionalFunctions
|
||||
};
|
||||
|
||||
// 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
|
||||
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_9999 = 9999, // lowest priority for 2.x libs
|
||||
|
||||
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 !=)
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
#define NUM_TOTAL_FILTER_PROPS 62
|
||||
#else
|
||||
#define NUM_TOTAL_FILTER_PROPS 58
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
struct SurfaceConfig {
|
||||
mfxU32 SurfaceType;
|
||||
mfxU32 SurfaceComponent;
|
||||
mfxU32 SurfaceFlags;
|
||||
};
|
||||
|
||||
// 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;
|
||||
|
||||
bool bIsSet_DeviceCopy;
|
||||
mfxU16 DeviceCopy;
|
||||
|
||||
bool bIsSet_ExtBuffer;
|
||||
std::vector<mfxExtBuffer *> ExtBuffers;
|
||||
};
|
||||
|
||||
struct mfxVariantWrapper : mfxVariant {
|
||||
public:
|
||||
bool bPropsQuery = false;
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
static bool UpdatePropsQueryConfig(std::list<ConfigCtxVPL *> configCtxList,
|
||||
std::vector<mfxQueryProperty> &queryProps);
|
||||
#endif
|
||||
|
||||
// compare library caps vs. set of configuration filters
|
||||
static mfxStatus ValidateConfig(const mfxImplDescription *libImplDesc,
|
||||
const mfxImplementedFunctions *libImplFuncs,
|
||||
const mfxExtendedDeviceId *libImplExtDevID,
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
const mfxSurfaceTypesSupported *libImplSurfTypes,
|
||||
#endif
|
||||
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);
|
||||
mfxStatus SetFilterPropertySurface(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);
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
static mfxStatus GetFlatDescriptionsSurface(const mfxSurfaceTypesSupported *libSurfaceTypes,
|
||||
std::list<SurfaceConfig> &surfaceConfigList);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
static mfxStatus CheckPropsExtDevID(const mfxVariant cfgPropsAll[],
|
||||
const mfxExtendedDeviceId *libImplExtDevID);
|
||||
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
static mfxStatus CheckPropsSurface(const mfxVariant cfgPropsAll[],
|
||||
std::list<SurfaceConfig> surfaceConfigList);
|
||||
#endif
|
||||
|
||||
mfxVariantWrapper 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;
|
||||
|
||||
mfxU8 m_extDevLUID8U[8];
|
||||
std::string m_extDevNameStr;
|
||||
|
||||
std::vector<mfxU8> m_extBuf;
|
||||
|
||||
__inline bool SetExtBuf(mfxExtBuffer *extBuf) {
|
||||
if (!extBuf)
|
||||
return false;
|
||||
|
||||
mfxU32 BufferSz = extBuf->BufferSz;
|
||||
if (BufferSz > 0) {
|
||||
m_extBuf.resize(BufferSz);
|
||||
std::copy((mfxU8 *)extBuf, (mfxU8 *)extBuf + BufferSz, m_extBuf.begin());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
__inline bool GetExtBuf(mfxExtBuffer **extBuf) {
|
||||
if (!extBuf)
|
||||
return false;
|
||||
|
||||
*extBuf = nullptr;
|
||||
if (!m_extBuf.empty()) {
|
||||
*extBuf = (mfxExtBuffer *)m_extBuf.data();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
__inline void ClearExtBuf() {
|
||||
m_extBuf.clear();
|
||||
}
|
||||
};
|
||||
|
||||
// MSDK compatibility loader implementation
|
||||
class LoaderCtxMSDK {
|
||||
public:
|
||||
LoaderCtxMSDK();
|
||||
~LoaderCtxMSDK();
|
||||
|
||||
// public function to be called the 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);
|
||||
|
||||
static mfxStatus QueryExtDeviceID(mfxExtendedDeviceId *extDeviceID,
|
||||
mfxU32 adapterID,
|
||||
mfxU16 deviceID,
|
||||
mfxU64 luid);
|
||||
|
||||
// required by MFXCreateSession
|
||||
mfxIMPL m_msdkAdapter;
|
||||
mfxIMPL m_msdkAdapterD3D9;
|
||||
|
||||
mfxU16 m_deviceID;
|
||||
mfxU64 m_luid;
|
||||
mfxExtendedDeviceId m_extDeviceID;
|
||||
|
||||
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);
|
||||
static mfxStatus GetRenderNodeDescription(mfxU32 adapterID, mfxU32 &vendorID, mfxU16 &deviceID);
|
||||
|
||||
// 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
|
||||
|
||||
// optional functions which RT may or may not export
|
||||
VPLFunctionPtr vplOptionalFuncTable[NumVPLOptionalFunctions]; // 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(),
|
||||
vplOptionalFuncTable(),
|
||||
msdkCtx(),
|
||||
msdkVersion(),
|
||||
implCapsPath() {}
|
||||
|
||||
virtual ~LibInfo() {}
|
||||
|
||||
private:
|
||||
// make this class non-copyable
|
||||
LibInfo(const LibInfo &);
|
||||
LibInfo &operator=(const LibInfo &);
|
||||
};
|
||||
|
||||
struct ImplInfo {
|
||||
// library containing this implementation
|
||||
LibInfo *libInfo;
|
||||
|
||||
// description of implementation
|
||||
mfxHDL implDesc;
|
||||
|
||||
// list of implemented functions
|
||||
mfxHDL implFuncs;
|
||||
|
||||
mfxHDL implExtDeviceID;
|
||||
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
mfxHDL implSurfTypes;
|
||||
#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),
|
||||
implExtDeviceID(nullptr),
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
implSurfTypes(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;
|
||||
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
bool m_bEnablePropsQuery;
|
||||
mfxStatus UpdatePropsQuery();
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#if defined INSTALL_LIBDIR_SEARCH
|
||||
mfxU32 GetSearchPathsInstallDir(std::list<STRING_TYPE> &searchDirs);
|
||||
#endif
|
||||
|
||||
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,
|
||||
bool bLoadVPLOnly = false);
|
||||
|
||||
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);
|
||||
mfxStatus LoadLibsFromMultipleDirs(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;
|
||||
|
||||
#ifdef ONEVPL_EXPERIMENTAL
|
||||
std::vector<mfxQueryProperty> m_queryProps;
|
||||
#endif
|
||||
|
||||
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 // LIBVPL_SRC_MFX_DISPATCHER_VPL_H_
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/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;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_MFX_DISPATCHER_VPL_LOG_H_
|
||||
#define LIBVPL_SRC_MFX_DISPATCHER_VPL_LOG_H_
|
||||
|
||||
/* Intel® Video Processing Library (Intel® VPL) 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, Intel® VPL 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;
|
||||
DispatcherLogVPL(const DispatcherLogVPL &other);
|
||||
DispatcherLogVPL &operator=(const DispatcherLogVPL &other);
|
||||
};
|
||||
|
||||
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;
|
||||
DispatcherLogVPLFunction(const DispatcherLogVPLFunction &other);
|
||||
DispatcherLogVPLFunction &operator=(const DispatcherLogVPLFunction &other);
|
||||
};
|
||||
|
||||
#define DISP_LOG_FUNCTION(dispLog) DispatcherLogVPLFunction _dispLogFn(dispLog, __FUNC_NAME__);
|
||||
#define DISP_LOG_MESSAGE(dispLog, ...) \
|
||||
{ \
|
||||
if (dispLog) { \
|
||||
(dispLog)->LogMessage(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif // LIBVPL_SRC_MFX_DISPATCHER_VPL_LOG_H_
|
||||
+432
@@ -0,0 +1,432 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/mfx_dispatcher_vpl.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include "src/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
|
||||
|
||||
//Intel® Video Processing Library (Intel® VPL) low latency dispatcher
|
||||
|
||||
// For Windows:
|
||||
// Intel® 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
|
||||
|
||||
// For Linux:
|
||||
// Intel® VPL - load from system paths in LoadLibsFromMultipleDirs(), look only for libmfx-gen.so.1.2
|
||||
// MSDK - load from system paths in LoadLibsFromMultipleDirs(), look only for libmfxhw64.so.1
|
||||
|
||||
// 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";
|
||||
|
||||
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
|
||||
// try to open library
|
||||
void *hLib = dlopen(libPath.c_str(), RTLD_LOCAL | RTLD_NOW);
|
||||
if (!hLib)
|
||||
return nullptr;
|
||||
|
||||
// check for required entrypoint function
|
||||
const char *reqFunc = (libType == LibTypeVPL ? reqFuncVPL : reqFuncMSDK);
|
||||
VPLFunctionPtr pProc = (VPLFunctionPtr)dlsym(hLib, reqFunc);
|
||||
dlclose(hLib);
|
||||
|
||||
// entrypoint function missing - invalid library
|
||||
if (!pProc)
|
||||
return nullptr;
|
||||
#endif
|
||||
|
||||
// create new LibInfo and add to list
|
||||
libInfo = new (std::nothrow) 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;
|
||||
|
||||
if (libType == LibTypeVPL) {
|
||||
storageID = MFX::MFX_DRIVER_STORE_ONEVPL;
|
||||
libName = libNameVPL;
|
||||
}
|
||||
else if (libType == LibTypeMSDK) {
|
||||
storageID = MFX::MFX_DRIVER_STORE;
|
||||
libName = libNameMSDK;
|
||||
}
|
||||
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)
|
||||
const CHAR_TYPE *libName = nullptr;
|
||||
|
||||
if (libType == LibTypeVPL) {
|
||||
libName = libNameVPL;
|
||||
}
|
||||
else if (libType == LibTypeMSDK) {
|
||||
libName = libNameMSDK;
|
||||
}
|
||||
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::LoadLibsFromMultipleDirs(LibType libType) {
|
||||
#ifdef __linux__
|
||||
// clang-format off
|
||||
|
||||
// standard paths for RT installation on Linux
|
||||
std::vector<std::string> llSearchDir = {
|
||||
"/usr/lib/x86_64-linux-gnu",
|
||||
"/lib",
|
||||
"/usr/lib",
|
||||
"/lib64",
|
||||
"/usr/lib64",
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
const CHAR_TYPE *libName = nullptr;
|
||||
|
||||
if (libType == LibTypeVPL) {
|
||||
libName = libNameVPL;
|
||||
}
|
||||
else if (libType == LibTypeMSDK) {
|
||||
libName = libNameMSDK;
|
||||
|
||||
// additional search directories for MSDK
|
||||
llSearchDir.push_back("/opt/intel/mediasdk/lib");
|
||||
llSearchDir.push_back("/opt/intel/mediasdk/lib64");
|
||||
}
|
||||
else {
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
for (const auto &searchDir : llSearchDir) {
|
||||
STRING_TYPE libPath;
|
||||
libPath = searchDir;
|
||||
libPath += "/";
|
||||
libPath += libName;
|
||||
|
||||
// try to open library
|
||||
LibInfo *libInfo = AddSingleLibrary(libPath, libType);
|
||||
|
||||
// if successful, add to list and return (stop at first success)
|
||||
if (libInfo) {
|
||||
m_libInfoList.push_back(libInfo);
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
#else
|
||||
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 Intel® VPL 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
|
||||
mfxStatus sts = MFX_ERR_NONE;
|
||||
|
||||
// try loading Intel® VPL from Linux system directories
|
||||
sts = LoadLibsFromMultipleDirs(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 Linux system directories
|
||||
sts = LoadLibsFromMultipleDirs(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
|
||||
}
|
||||
|
||||
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 Intel® 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;
|
||||
}
|
||||
@@ -0,0 +1,594 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include <fstream>
|
||||
#include "src/mfx_dispatcher_vpl.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include "src/mfx_dispatcher_vpl_win.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <pthread.h>
|
||||
#define strncpy_s(dst, size, src, cnt) strncpy((dst), (src), (cnt)) // 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
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
// optional extBuf to limit threads created in MSDK session creation
|
||||
// to enable, set vplParam.NumExtParam and vplParam.ExtParam before calling MFXInitEx2()
|
||||
static const mfxExtThreadsParam extThreadParam = {
|
||||
{MFX_EXTBUFF_THREADS_PARAM, sizeof(mfxExtThreadsParam)},
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
{},
|
||||
};
|
||||
|
||||
static const mfxExtBuffer* extParams[1] = {
|
||||
(mfxExtBuffer *)&extThreadParam,
|
||||
};
|
||||
#endif
|
||||
|
||||
// end table formatting
|
||||
// clang-format on
|
||||
|
||||
LoaderCtxMSDK::LoaderCtxMSDK()
|
||||
: m_msdkAdapter(),
|
||||
m_msdkAdapterD3D9(),
|
||||
m_deviceID(0),
|
||||
m_luid(0),
|
||||
m_extDeviceID(),
|
||||
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;
|
||||
|
||||
#ifdef __linux__
|
||||
vplParam.ExtParam = (mfxExtBuffer **)&extParams;
|
||||
vplParam.NumExtParam = 1;
|
||||
#else
|
||||
vplParam.ExtParam = nullptr;
|
||||
vplParam.NumExtParam = 0;
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __linux__
|
||||
vplParam.ExtParam = (mfxExtBuffer **)&extParams;
|
||||
vplParam.NumExtParam = 1;
|
||||
#else
|
||||
vplParam.ExtParam = nullptr;
|
||||
vplParam.NumExtParam = 0;
|
||||
#endif
|
||||
|
||||
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;
|
||||
m_deviceID = 0;
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
mfxU32 vendorID = 0;
|
||||
mfxU16 deviceID = 0;
|
||||
sts = GetRenderNodeDescription(adapterID, vendorID, deviceID);
|
||||
if (sts != MFX_ERR_NONE)
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
|
||||
// on Linux read deviceID from the render node path
|
||||
m_deviceID = deviceID;
|
||||
#endif
|
||||
|
||||
// try HW session, default acceleration mode
|
||||
mfxIMPL hwImpl = msdkImplTab[adapterID];
|
||||
mfxIMPL implDefault = MFX_IMPL_UNSUPPORTED;
|
||||
|
||||
sts = GetDefaultAccelType(adapterID, &implDefault, &m_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));
|
||||
m_id.ImplName[sizeof(m_id.ImplName) - 1] = 0;
|
||||
strncpy_s(m_id.License, sizeof(m_id.License), strLicense, sizeof(strLicense));
|
||||
m_id.License[sizeof(m_id.License) - 1] = 0;
|
||||
strncpy_s(m_id.Keywords, sizeof(m_id.Keywords), strKeywords, sizeof(strKeywords));
|
||||
m_id.Keywords[sizeof(m_id.Keywords) - 1] = 0;
|
||||
|
||||
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)
|
||||
// for Linux, we may already have the deviceID from parsing render node path earlier
|
||||
if (m_deviceID == 0) {
|
||||
if (IsVersionSupported(MAKE_MFX_VERSION(1, 19), m_id.ApiVersion)) {
|
||||
mfxPlatform platform = {};
|
||||
|
||||
sts = MFXVideoCORE_QueryPlatform(session, &platform);
|
||||
if (sts == MFX_ERR_NONE)
|
||||
m_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 (m_deviceID == 0)
|
||||
m_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", m_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(m_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;
|
||||
|
||||
// thread limit not enabled on Windows
|
||||
vplParam.ExtParam = nullptr;
|
||||
vplParam.NumExtParam = 0;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
mfxU32 read_device_file(std::string &path) {
|
||||
mfxU32 result = 0;
|
||||
std::string line;
|
||||
std::ifstream dev_str(path);
|
||||
if (!dev_str.is_open()) {
|
||||
return 0;
|
||||
}
|
||||
std::getline(dev_str, line);
|
||||
dev_str.close();
|
||||
try {
|
||||
result = std::stoul(line, 0, 16);
|
||||
}
|
||||
catch (std::invalid_argument &) {
|
||||
return 0;
|
||||
}
|
||||
catch (std::out_of_range &) {
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
mfxStatus LoaderCtxMSDK::GetRenderNodeDescription(mfxU32 adapterID,
|
||||
mfxU32 &vendorID,
|
||||
mfxU16 &deviceID) {
|
||||
vendorID = 0;
|
||||
deviceID = 0;
|
||||
|
||||
#if defined(__linux__)
|
||||
mfxU32 DRMRenderNodeNum = 128 + adapterID;
|
||||
std::string nodeStr = std::to_string(DRMRenderNodeNum);
|
||||
|
||||
std::string vendorPath = "/sys/class/drm/renderD" + nodeStr + "/device/vendor";
|
||||
std::string devPath = "/sys/class/drm/renderD" + nodeStr + "/device/device";
|
||||
|
||||
vendorID = read_device_file(vendorPath);
|
||||
|
||||
if (vendorID != 0x8086)
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
|
||||
deviceID = read_device_file(devPath);
|
||||
|
||||
if (deviceID == 0)
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
#else
|
||||
return MFX_ERR_UNSUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
// avoid confusing #ifdef indentation
|
||||
// clang-format off
|
||||
|
||||
mfxStatus LoaderCtxMSDK::QueryExtDeviceID(mfxExtendedDeviceId *extDeviceID,
|
||||
mfxU32 adapterID,
|
||||
mfxU16 deviceID,
|
||||
mfxU64 luid) {
|
||||
// fill extended device ID struct (API >= 2.6)
|
||||
memset(extDeviceID, 0, sizeof(mfxExtendedDeviceId));
|
||||
|
||||
// common properties
|
||||
extDeviceID->Version.Version = MFX_EXTENDEDDEVICEID_VERSION;
|
||||
extDeviceID->VendorID = 0x8086;
|
||||
extDeviceID->DeviceID = deviceID;
|
||||
|
||||
// default - no PCI info
|
||||
// additional dependencies required to obtain these props
|
||||
extDeviceID->PCIDomain = 0xFFFFFFFF;
|
||||
extDeviceID->PCIBus = 0xFFFFFFFF;
|
||||
extDeviceID->PCIDevice = 0xFFFFFFFF;
|
||||
extDeviceID->PCIFunction = 0xFFFFFFFF;
|
||||
|
||||
// default - no LUID
|
||||
extDeviceID->LUIDDeviceNodeMask = 0;
|
||||
extDeviceID->LUIDValid = 0;
|
||||
for (mfxU32 idx = 0; idx < 8; idx++)
|
||||
extDeviceID->DeviceLUID[idx] = 0;
|
||||
|
||||
// default - no DRM node
|
||||
extDeviceID->DRMRenderNodeNum = 0;
|
||||
extDeviceID->DRMPrimaryNodeNum = 0x7FFFFFFF;
|
||||
|
||||
// default - no PCI RevisionID
|
||||
extDeviceID->RevisionID = 0xFFFF;
|
||||
|
||||
snprintf(extDeviceID->DeviceName, sizeof(extDeviceID->DeviceName), "%s", strImplName);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
// fill in Windows-specific properties
|
||||
if (luid) {
|
||||
extDeviceID->LUIDDeviceNodeMask = 1;
|
||||
extDeviceID->LUIDValid = 1;
|
||||
|
||||
// map 64-bit LUID into mfxU8[8]
|
||||
mfxU64 luidArr = luid;
|
||||
for (mfxU32 idx = 0; idx < 8; idx++) {
|
||||
extDeviceID->DeviceLUID[idx] = mfxU8((luidArr)&0xFF);
|
||||
luidArr >>= 8;
|
||||
}
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
extDeviceID->DRMPrimaryNodeNum = adapterID;
|
||||
extDeviceID->DRMRenderNodeNum = 128 + adapterID;
|
||||
#endif
|
||||
|
||||
return MFX_ERR_NONE;
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
@@ -0,0 +1,19 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_MFX_DISPATCHER_VPL_WIN_H_
|
||||
#define LIBVPL_SRC_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 // LIBVPL_SRC_MFX_DISPATCHER_VPL_WIN_H_
|
||||
@@ -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
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/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
|
||||
@@ -0,0 +1,48 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_CRITICAL_SECTION_H_
|
||||
#define LIBVPL_SRC_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 // LIBVPL_SRC_WINDOWS_MFX_CRITICAL_SECTION_H_
|
||||
@@ -0,0 +1,594 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/windows/mfx_dispatcher.h"
|
||||
#include "src/windows/mfx_dispatcher_log.h"
|
||||
#include "src/windows/mfx_load_dll.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include "src/windows/mfx_dxva2_device.h"
|
||||
#include "src/windows/mfx_vector.h"
|
||||
#include "src/windows/mfxvideo++.h"
|
||||
#include "vpl/mfxadapter.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,
|
||||
bool bCloneSession) {
|
||||
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 or 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (bCloneSession == true) {
|
||||
loadStatus = mfxRes;
|
||||
return mfxRes;
|
||||
}
|
||||
|
||||
// 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, skipped 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 successfully\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)
|
||||
@@ -0,0 +1,218 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_DISPATCHER_H_
|
||||
#define LIBVPL_SRC_WINDOWS_MFX_DISPATCHER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "vpl/mfxdispatcher.h"
|
||||
#include "vpl/mfxvideo.h"
|
||||
|
||||
#include "src/windows/mfx_dispatcher_defs.h"
|
||||
|
||||
// internal implementation of mfxConfigInterface
|
||||
#include "src/mfx_config_interface/mfx_config_interface.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,
|
||||
eMFXVideoCORE_GetHandle,
|
||||
eMFXJoinSession,
|
||||
eMFXDisjoinSession,
|
||||
eMFXCloneSession,
|
||||
eMFXSetPriority,
|
||||
eMFXGetPriority,
|
||||
eMFXInitEx,
|
||||
#include "src/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,
|
||||
bool bCloneSession = false);
|
||||
// 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.
|
||||
//
|
||||
// FOR THIS IMPLEMENTATION: order should not matter. Dispatcher is now built
|
||||
// as a DLL and installed in %WINDIR%\system32. Thus all applications on the
|
||||
// system should use same dispatcher. Even if an app loads a different
|
||||
// dispatcher version, initializing an mfxSession with one library then
|
||||
// using it in a different library is not a supported use case.
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
inline bool operator==(mfxGUID const &l, mfxGUID const &r) {
|
||||
return std::equal(l.Data, l.Data + 16, r.Data);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 // LIBVPL_SRC_WINDOWS_MFX_DISPATCHER_H_
|
||||
@@ -0,0 +1,37 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) 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
|
||||
@@ -0,0 +1,366 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#if defined(MFX_DISPATCHER_LOG)
|
||||
|
||||
#include "src/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)
|
||||
@@ -0,0 +1,225 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_DISPATCHER_LOG_H_
|
||||
#define LIBVPL_SRC_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 // LIBVPL_SRC_WINDOWS_MFX_DISPATCHER_LOG_H_
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include <tchar.h>
|
||||
|
||||
#include "src/windows/mfx_dispatcher_log.h"
|
||||
#include "src/windows/mfx_driver_store_loader.h"
|
||||
#include "src/windows/mfx_load_dll.h"
|
||||
#include "src/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, _countof(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
|
||||
@@ -0,0 +1,75 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_DRIVER_STORE_LOADER_H_
|
||||
#define LIBVPL_SRC_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 "src/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 // LIBVPL_SRC_WINDOWS_MFX_DRIVER_STORE_LOADER_H_
|
||||
@@ -0,0 +1,553 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#define INITGUID
|
||||
#include <d3d9.h>
|
||||
#include <dxgi.h>
|
||||
|
||||
#include "src/windows/mfx_dxva2_device.h"
|
||||
#include "src/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
|
||||
@@ -0,0 +1,202 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_DXVA2_DEVICE_H_
|
||||
#define LIBVPL_SRC_WINDOWS_MFX_DXVA2_DEVICE_H_
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "src/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
|
||||
#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;
|
||||
|
||||
private:
|
||||
D3D9Device(const D3D9Device &other);
|
||||
D3D9Device &operator=(const D3D9Device &other);
|
||||
};
|
||||
#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;
|
||||
|
||||
private:
|
||||
DXGI1Device(const DXGI1Device &other);
|
||||
DXGI1Device &operator=(const DXGI1Device &other);
|
||||
};
|
||||
|
||||
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 // LIBVPL_SRC_WINDOWS_MFX_DXVA2_DEVICE_H_
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) 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_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
|
||||
@@ -0,0 +1,115 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/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 } } },
|
||||
{ "MFXVideoCORE_GetHandle", { { 0, 1 } } },
|
||||
|
||||
{ "MFXJoinSession", { { 1, 1 } } },
|
||||
{ "MFXDisjoinSession", { { 1, 1 } } },
|
||||
{ "MFXCloneSession", { { 1, 1 } } },
|
||||
{ "MFXSetPriority", { { 1, 1 } } },
|
||||
{ "MFXGetPriority", { { 1, 1 } } },
|
||||
|
||||
{ "MFXInitEx", { { 14, 1 } } },
|
||||
|
||||
#include "src/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 "src/windows/mfx_exposed_functions_list.h" // NOLINT(build/include)
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,646 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/windows/mfx_library_iterator.h"
|
||||
|
||||
#include "src/windows/mfx_dispatcher.h"
|
||||
#include "src/windows/mfx_dispatcher_log.h"
|
||||
|
||||
#include "src/windows/mfx_dxva2_device.h"
|
||||
#include "src/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 Intel® Video Processing Library (Intel® VPL) 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_vpl_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 ®Dir, 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
|
||||
@@ -0,0 +1,145 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_LIBRARY_ITERATOR_H_
|
||||
#define LIBVPL_SRC_WINDOWS_MFX_LIBRARY_ITERATOR_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "vpl/mfxvideo.h"
|
||||
|
||||
#if !defined(MEDIASDK_UWP_DISPATCHER)
|
||||
#include "mfx_win_reg_key.h"
|
||||
#endif
|
||||
|
||||
#include "src/windows/mfx_dispatcher.h"
|
||||
#include "src/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 ®Dir, 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 // LIBVPL_SRC_WINDOWS_MFX_LIBRARY_ITERATOR_H_
|
||||
@@ -0,0 +1,196 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#include "src/windows/mfx_load_dll.h"
|
||||
#include "src/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_vpl_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_vpl_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
|
||||
@@ -0,0 +1,36 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_LOAD_DLL_H_
|
||||
#define LIBVPL_SRC_WINDOWS_MFX_LOAD_DLL_H_
|
||||
|
||||
#include "src/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_vpl_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 // LIBVPL_SRC_WINDOWS_MFX_LOAD_DLL_H_
|
||||
@@ -0,0 +1,159 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) 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
|
||||
@@ -0,0 +1,201 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#if !defined(MEDIASDK_UWP_DISPATCHER)
|
||||
#include "src/windows/mfx_win_reg_key.h"
|
||||
#include "src/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);
|
||||
|
||||
// According to docs for RegQueryValueExW: "The lpcbData parameter can be NULL only if lpData is NULL."
|
||||
if (pData && !pcbData)
|
||||
return false;
|
||||
|
||||
// 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)
|
||||
@@ -0,0 +1,99 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFX_WIN_REG_KEY_H_
|
||||
#define LIBVPL_SRC_WINDOWS_MFX_WIN_REG_KEY_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include "src/windows/mfx_dispatcher_log.h"
|
||||
#include "vpl/mfxcommon.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 // LIBVPL_SRC_WINDOWS_MFX_WIN_REG_KEY_H_
|
||||
@@ -0,0 +1,231 @@
|
||||
/*############################################################################
|
||||
# Copyright (C) Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
############################################################################*/
|
||||
|
||||
#ifndef LIBVPL_SRC_WINDOWS_MFXVIDEO___H_
|
||||
#define LIBVPL_SRC_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
|
||||
private:
|
||||
MFXVideoENCODE(const MFXVideoENCODE &other);
|
||||
MFXVideoENCODE &operator=(const MFXVideoENCODE &other);
|
||||
};
|
||||
|
||||
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
|
||||
private:
|
||||
MFXVideoDECODE(const MFXVideoDECODE &other);
|
||||
MFXVideoDECODE &operator=(const MFXVideoDECODE &other);
|
||||
};
|
||||
|
||||
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
|
||||
private:
|
||||
MFXVideoVPP(const MFXVideoVPP &other);
|
||||
MFXVideoVPP &operator=(const MFXVideoVPP &other);
|
||||
};
|
||||
|
||||
#endif // LIBVPL_SRC_WINDOWS_MFXVIDEO___H_
|
||||
@@ -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 @CMAKE_PROJECT_VERSION_MAJOR@,@CMAKE_PROJECT_VERSION_MINOR@,0,0
|
||||
#define VER_PRODUCTVERSION_STR "@CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_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", "Intel® VPL 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
|
||||
Reference in New Issue
Block a user