mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-01 00:53:31 +00:00
Compare commits
4 commits
35b14436b4
...
58921f2aa8
Author | SHA1 | Date | |
---|---|---|---|
|
58921f2aa8 | ||
|
9d67bf2662 | ||
|
411f873a56 | ||
|
eb98d6759a |
97
cmake/Modules/FindWIL.cmake
Normal file
97
cmake/Modules/FindWIL.cmake
Normal file
|
@ -0,0 +1,97 @@
|
|||
#[=======================================================================[.rst
|
||||
FindWIL
|
||||
-------
|
||||
|
||||
FindModule for WIL and associated headers
|
||||
|
||||
Imported Targets
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 3.0
|
||||
|
||||
This module defines the :prop_tgt:`IMPORTED` target ``WIL::WIL``.
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module sets the following variables:
|
||||
|
||||
``WIL_FOUND``
|
||||
True, if headers were found.
|
||||
``WIL_VERSION``
|
||||
Detected version of found WIL headers.
|
||||
|
||||
Cache variables
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The following cache variables may also be set:
|
||||
|
||||
``WIL_INCLUDE_DIR``
|
||||
Directory containing ``cppwinrt.h``.
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
# cmake-format: off
|
||||
# cmake-lint: disable=C0103
|
||||
# cmake-lint: disable=C0301
|
||||
# cmake-format: on
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_search_module(_WIL QUIET wil)
|
||||
endif()
|
||||
|
||||
find_path(
|
||||
WIL_INCLUDE_DIR
|
||||
NAMES wil/cppwinrt.h
|
||||
HINTS ${_WI_INCLUDE_DIRS} ${_WIL_INCLUDE_DIRS}
|
||||
PATHS /usr/include /usr/local/include /opt/local/include /sw/include
|
||||
DOC "WIL include directory")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
WIL
|
||||
REQUIRED_VARS WIL_INCLUDE_DIR
|
||||
VERSION_VAR WIL_VERSION REASON_FAILURE_MESSAGE "${WIL_ERROR_REASON}")
|
||||
mark_as_advanced(WIL_INCLUDE_DIR)
|
||||
unset(WIL_ERROR_REASON)
|
||||
|
||||
if(EXISTS "${WIL_INCLUDE_DIR}/wil/cppwinrt.h")
|
||||
file(STRINGS "${WIL_INCLUDE_DIR}/wil/cppwinrt.h" _version_string REGEX "^.*VERSION_(MAJOR|MINOR)[ \t]+[0-9]+[ \t]*$")
|
||||
|
||||
string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}")
|
||||
string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}")
|
||||
|
||||
set(WIL_VERSION "${_version_major}.${_version_minor}")
|
||||
unset(_version_major)
|
||||
unset(_version_minor)
|
||||
else()
|
||||
if(NOT WIL_FIND_QUIETLY)
|
||||
message(AUTHOR_WARNING "Failed to find WIL version.")
|
||||
endif()
|
||||
set(WIL_VERSION 0.0.0)
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows")
|
||||
set(WIL_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD")
|
||||
set(WIL_ERROR_REASON "Ensure WIL headers are available in local library paths.")
|
||||
endif()
|
||||
|
||||
if(WIL_FOUND)
|
||||
set(WIL_INCLUDE_DIRS ${WIL_INCLUDE_DIR})
|
||||
|
||||
if(NOT TARGET WIL::WIL)
|
||||
add_library(WIL::WIL INTERFACE IMPORTED)
|
||||
set_target_properties(WIL::WIL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WIL_INCLUDE_DIRS}")
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FeatureSummary)
|
||||
set_package_properties(
|
||||
WIL PROPERTIES
|
||||
URL "https://github.com/microsoft/wil.git"
|
||||
DESCRIPTION
|
||||
"The Windows Implementation Libraries (WIL) is a header-only C++ library created to make life easier for developers on Windows through readable type-safe C++ interfaces for common Windows coding patterns."
|
||||
)
|
97
cmake/finders/FindWIL.cmake
Normal file
97
cmake/finders/FindWIL.cmake
Normal file
|
@ -0,0 +1,97 @@
|
|||
#[=======================================================================[.rst
|
||||
FindWIL
|
||||
-------
|
||||
|
||||
FindModule for WIL and associated headers
|
||||
|
||||
Imported Targets
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 3.0
|
||||
|
||||
This module defines the :prop_tgt:`IMPORTED` target ``WIL::WIL``.
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module sets the following variables:
|
||||
|
||||
``WIL_FOUND``
|
||||
True, if headers were found.
|
||||
``WIL_VERSION``
|
||||
Detected version of found WIL headers.
|
||||
|
||||
Cache variables
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The following cache variables may also be set:
|
||||
|
||||
``WIL_INCLUDE_DIR``
|
||||
Directory containing ``cppwinrt.h``.
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
# cmake-format: off
|
||||
# cmake-lint: disable=C0103
|
||||
# cmake-lint: disable=C0301
|
||||
# cmake-format: on
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_search_module(_WIL QUIET wil)
|
||||
endif()
|
||||
|
||||
find_path(
|
||||
WIL_INCLUDE_DIR
|
||||
NAMES wil/cppwinrt.h
|
||||
HINTS ${_WI_INCLUDE_DIRS} ${_WIL_INCLUDE_DIRS}
|
||||
PATHS /usr/include /usr/local/include /opt/local/include /sw/include
|
||||
DOC "WIL include directory")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
WIL
|
||||
REQUIRED_VARS WIL_INCLUDE_DIR
|
||||
VERSION_VAR WIL_VERSION REASON_FAILURE_MESSAGE "${WIL_ERROR_REASON}")
|
||||
mark_as_advanced(WIL_INCLUDE_DIR)
|
||||
unset(WIL_ERROR_REASON)
|
||||
|
||||
if(EXISTS "${WIL_INCLUDE_DIR}/wil/cppwinrt.h")
|
||||
file(STRINGS "${WIL_INCLUDE_DIR}/wil/cppwinrt.h" _version_string REGEX "^.*VERSION_(MAJOR|MINOR)[ \t]+[0-9]+[ \t]*$")
|
||||
|
||||
string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}")
|
||||
string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}")
|
||||
|
||||
set(WIL_VERSION "${_version_major}.${_version_minor}")
|
||||
unset(_version_major)
|
||||
unset(_version_minor)
|
||||
else()
|
||||
if(NOT WIL_FIND_QUIETLY)
|
||||
message(AUTHOR_WARNING "Failed to find WIL version.")
|
||||
endif()
|
||||
set(WIL_VERSION 0.0.0)
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows")
|
||||
set(WIL_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD")
|
||||
set(WIL_ERROR_REASON "Ensure WIL headers are available in local library paths.")
|
||||
endif()
|
||||
|
||||
if(WIL_FOUND)
|
||||
set(WIL_INCLUDE_DIRS ${WIL_INCLUDE_DIR})
|
||||
|
||||
if(NOT TARGET WIL::WIL)
|
||||
add_library(WIL::WIL INTERFACE IMPORTED)
|
||||
set_target_properties(WIL::WIL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${WIL_INCLUDE_DIRS}")
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FeatureSummary)
|
||||
set_package_properties(
|
||||
WIL PROPERTIES
|
||||
URL "https://github.com/microsoft/wil.git"
|
||||
DESCRIPTION
|
||||
"The Windows Implementation Libraries (WIL) is a header-only C++ library created to make life easier for developers on Windows through readable type-safe C++ interfaces for common Windows coding patterns."
|
||||
)
|
|
@ -72,6 +72,7 @@ if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0)
|
|||
add_obs_plugin(vlc-video WITH_MESSAGE)
|
||||
add_obs_plugin(win-capture PLATFORMS WINDOWS)
|
||||
add_obs_plugin(win-dshow PLATFORMS WINDOWS)
|
||||
add_obs_plugin(win-mf PLATFORMS WINDOWS)
|
||||
add_obs_plugin(win-wasapi PLATFORMS WINDOWS)
|
||||
|
||||
return()
|
||||
|
@ -94,6 +95,7 @@ endfunction()
|
|||
if(OS_WINDOWS)
|
||||
add_subdirectory(coreaudio-encoder)
|
||||
add_subdirectory(win-wasapi)
|
||||
add_subdirectory(win-mf)
|
||||
add_subdirectory(win-dshow)
|
||||
add_subdirectory(win-capture)
|
||||
add_subdirectory(decklink)
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
#endif
|
||||
|
||||
enum AVHWDeviceType hw_priority[] = {
|
||||
AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2,
|
||||
AV_HWDEVICE_TYPE_QSV, AV_HWDEVICE_TYPE_NONE,
|
||||
AV_HWDEVICE_TYPE_D3D11VA,
|
||||
AV_HWDEVICE_TYPE_DXVA2,
|
||||
AV_HWDEVICE_TYPE_QSV,
|
||||
AV_HWDEVICE_TYPE_NONE,
|
||||
};
|
||||
|
||||
static bool has_hw_type(const AVCodec *c, enum AVHWDeviceType type)
|
||||
|
|
41
plugins/win-mf/CMakeLists.txt
Normal file
41
plugins/win-mf/CMakeLists.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
cmake_minimum_required(VERSION 3.24...3.25)
|
||||
|
||||
legacy_check()
|
||||
|
||||
find_package(FFmpeg REQUIRED avcodec avutil)
|
||||
find_package(WIL REQUIRED)
|
||||
|
||||
add_library(win-mf MODULE)
|
||||
add_library(OBS::mf ALIAS win-mf)
|
||||
|
||||
target_sources(win-mf PUBLIC mf-plugin.cpp win-mf.cpp)
|
||||
|
||||
add_library(libmfcapture INTERFACE)
|
||||
add_library(OBS::libmfcapture ALIAS libmfcapture)
|
||||
|
||||
target_include_directories(libmfcapture INTERFACE libmfcapture libmfcapture/source)
|
||||
|
||||
target_sources(libmfcapture INTERFACE libmfcapture/source/DeviceControlChangeListener.cpp
|
||||
libmfcapture/source/mfcapture.cpp libmfcapture/source/PhysicalCamera.cpp)
|
||||
|
||||
configure_file(cmake/windows/obs-module.rc.in win-mf.rc)
|
||||
target_sources(win-mf PRIVATE win-mf.rc)
|
||||
|
||||
target_precompile_headers(win-mf PRIVATE <wil/cppwinrt.h> <wil/result.h> <wil/com.h>)
|
||||
|
||||
target_link_libraries(
|
||||
win-mf
|
||||
PRIVATE OBS::libobs
|
||||
OBS::w32-pthreads
|
||||
OBS::winrt-headers
|
||||
FFmpeg::avcodec
|
||||
FFmpeg::avutil
|
||||
strmiids
|
||||
winmm
|
||||
dxcore
|
||||
dxguid
|
||||
libmfcapture)
|
||||
|
||||
# cmake-format: off
|
||||
set_target_properties_obs(win-mf PROPERTIES FOLDER plugins/win-mf PREFIX "")
|
||||
# cmake-format: on
|
64
plugins/win-mf/cmake/legacy.cmake
Normal file
64
plugins/win-mf/cmake/legacy.cmake
Normal file
|
@ -0,0 +1,64 @@
|
|||
project(win-mf)
|
||||
|
||||
find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil)
|
||||
find_package(WIL REQUIRED)
|
||||
|
||||
add_library(win-mf MODULE)
|
||||
add_library(OBS::mf ALIAS win-mf)
|
||||
|
||||
target_sources(win-mf PRIVATE mf-plugin.cpp plugin-macros.generated.h win-mf.cpp)
|
||||
|
||||
add_library(libmfcapture INTERFACE)
|
||||
add_library(OBS::libmfcapture ALIAS libmfcapture)
|
||||
|
||||
target_sources(
|
||||
libmfcapture
|
||||
INTERFACE libmfcapture/mfcapture.hpp
|
||||
libmfcapture/source/DeviceControlChangeListener.cpp
|
||||
libmfcapture/source/DeviceControlChangeListener.hpp
|
||||
libmfcapture/source/mfcapture.cpp
|
||||
libmfcapture/source/framework.hpp
|
||||
libmfcapture/source/mfcapture.rc
|
||||
libmfcapture/source/PhysicalCamera.cpp
|
||||
libmfcapture/source/PhysicalCamera.hpp
|
||||
libmfcapture/source/resource.hpp)
|
||||
|
||||
target_include_directories(libmfcapture INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libmfcapture)
|
||||
|
||||
target_compile_definitions(libmfcapture INTERFACE _UP_WINDOWS=1)
|
||||
|
||||
set(MODULE_DESCRIPTION "OBS MediaFoundation module")
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in win-mf.rc)
|
||||
|
||||
target_sources(win-mf PRIVATE win-mf.rc)
|
||||
|
||||
target_compile_definitions(win-mf PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS OBS_LEGACY)
|
||||
|
||||
target_link_libraries(
|
||||
win-mf
|
||||
PRIVATE OBS::libobs
|
||||
OBS::w32-pthreads
|
||||
setupapi
|
||||
strmiids
|
||||
ksuser
|
||||
winmm
|
||||
wmcodecdspuuid
|
||||
FFmpeg::avcodec
|
||||
FFmpeg::avutil
|
||||
dxcore
|
||||
dxguid
|
||||
libmfcapture)
|
||||
|
||||
source_group(
|
||||
"libmfcapture\\Source Files"
|
||||
FILES libmfcapture/source/DeviceControlChangeListener.cpp libmfcapture/source/mfcapture.cpp
|
||||
libmfcapture/source/mfcapture.rc libmfcapture/source/PhysicalCamera.cpp)
|
||||
source_group(
|
||||
"libmfcapture\\Header Files"
|
||||
FILES libmfcapture/source/DeviceControlChangeListener.hpp libmfcapture/source/framework.hpp
|
||||
libmfcapture/source/mfcapture.hpp libmfcapture/source/PhysicalCamera.hpp libmfcapture/source/resource.hpp)
|
||||
|
||||
set_target_properties(win-mf PROPERTIES FOLDER "plugins/win-mf")
|
||||
|
||||
setup_plugin_target(win-mf)
|
24
plugins/win-mf/cmake/windows/obs-module.rc.in
Normal file
24
plugins/win-mf/cmake/windows/obs-module.rc.in
Normal file
|
@ -0,0 +1,24 @@
|
|||
1 VERSIONINFO
|
||||
FILEVERSION ${OBS_VERSION_MAJOR},${OBS_VERSION_MINOR},${OBS_VERSION_PATCH},0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "${OBS_COMPANY_NAME}"
|
||||
VALUE "FileDescription", "OBS Media Foundation module"
|
||||
VALUE "FileVersion", "${OBS_VERSION_CANONICAL}"
|
||||
VALUE "ProductName", "${OBS_PRODUCT_NAME}"
|
||||
VALUE "ProductVersion", "${OBS_VERSION_CANONICAL}"
|
||||
VALUE "Comments", "${OBS_COMMENTS}"
|
||||
VALUE "LegalCopyright", "${OBS_LEGAL_COPYRIGHT}"
|
||||
VALUE "InternalName", "win-mf"
|
||||
VALUE "OriginalFilename", "win-mf"
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0409, 0x04B0
|
||||
END
|
||||
END
|
65
plugins/win-mf/data/locale/en-US.ini
Normal file
65
plugins/win-mf/data/locale/en-US.ini
Normal file
|
@ -0,0 +1,65 @@
|
|||
# media foundation video capture device text
|
||||
VideoCaptureDevice="Video Capture Device 2"
|
||||
Device="Device"
|
||||
ColorSpace="Color Space"
|
||||
ColorSpace.Default="Default"
|
||||
ColorSpace.709="Rec. 709"
|
||||
ColorSpace.601="Rec. 601"
|
||||
ColorSpace.2100PQ="Rec. 2100 (PQ)"
|
||||
ColorSpace.2100HLG="Rec. 2100 (HLG)"
|
||||
ColorRange="Color Range"
|
||||
ColorRange.Default="Default"
|
||||
ColorRange.Partial="Limited"
|
||||
ColorRange.Full="Full"
|
||||
ConfigureAudio="Configure Audio"
|
||||
ConfigureVideo="Video Effect Control"
|
||||
ConfigureCrossbar="Configure Crossbar"
|
||||
ResFPSType="Resolution/FPS Type"
|
||||
ResFPSType.Custom="Custom"
|
||||
ResFPSType.DevPreferred="Device Default"
|
||||
FPS.Matching="Match Output FPS"
|
||||
FPS.Highest="Highest FPS"
|
||||
Resolution="Resolution"
|
||||
VideoFormat="Video Format"
|
||||
VideoFormat.Any="Any"
|
||||
VideoFormat.Unknown="Unknown (%1)"
|
||||
AudioOutputMode="Audio Output Mode"
|
||||
AudioOutputMode.Capture="Capture audio only"
|
||||
AudioOutputMode.DirectSound="Output desktop audio (DirectSound)"
|
||||
AudioOutputMode.WaveOut="Output desktop audio (WaveOut)"
|
||||
UseCustomAudioDevice="Use custom audio device"
|
||||
AudioDevice="Audio Device"
|
||||
Buffering="Buffering"
|
||||
Buffering.ToolTip="When enabled, buffers video/audio data to ensure the smoothest and most\naccurate playback possible, but at the cost of increased latency. When using\nbuffering with a video capture card, it's recommended to set the card and the\nprogram to the same framerate for best results.\n\nWhen disabled, ensures lowest latency playback, but at the cost of frame\nplayback accuracy. This is ideal for face cameras, or when you want to use the\nprogram's preview window to play a console.\n\nAuto-detect (default) sets it to enabled if the device has delay, and disabled\nif it has no delay."
|
||||
Buffering.AutoDetect="Auto-Detect"
|
||||
Buffering.Enable="Enable"
|
||||
Buffering.Disable="Disable"
|
||||
Activate="Activate"
|
||||
Deactivate="Deactivate"
|
||||
FlipVertically="Flip Vertically"
|
||||
Autorotation="Apply rotation data from camera (if any)"
|
||||
HardwareDecode="Use hardware decoding when available"
|
||||
DeactivateWhenNotShowing="Deactivate when not showing"
|
||||
#if 0
|
||||
MEPFilters.Title="MEP Filters"
|
||||
MEPFilters.Enabled="Enabled"
|
||||
MEPFilters.Disabled="Disabled"
|
||||
MEPFilters.BlurStandard="Blur (Standard)"
|
||||
MEPFilters.BlurPortrait="Blur (Portrait)"
|
||||
MEPFilters.AutoFrame="Auto Framing"
|
||||
MEPFilters.EyeContact="Eye Contact"
|
||||
#endif
|
||||
|
||||
# Intel NPU text
|
||||
IntelNPU.BackgroundBlur="Background Blur"
|
||||
IntelNPU.BlurNone="None"
|
||||
IntelNPU.BlurStandard="Standard Blur (Intel AI Boost)"
|
||||
IntelNPU.Portrait="Portrait Blur (Intel AI Boost)"
|
||||
IntelNPU.BackgroundRemoval="Background Removal (Intel AI Boost)"
|
||||
IntelNPU.AutoFraming="Auto Framing (Intel AI Boost)"
|
||||
IntelNPU.EyeGazeCorrection="Eye Contact Correction (Intel AI Boost)"
|
||||
|
||||
# encoder text
|
||||
Bitrate="Bitrate"
|
||||
Encoder.C985="AVerMedia H.264 Encoder (c985)"
|
||||
Encoder.C353="AVerMedia H.264 Encoder"
|
90
plugins/win-mf/libmfcapture/mfcapture.hpp
Normal file
90
plugins/win-mf/libmfcapture/mfcapture.hpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#ifdef MFCAPTURE_EXPORTS
|
||||
#define MFCAPTURE_EXPORTS __declspec(dllexport)
|
||||
#else
|
||||
#define MFCAPTURE_EXPORTS
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum MF_COLOR_FORMAT {
|
||||
MF_COLOR_FORMAT_UNKNOWN,
|
||||
MF_COLOR_FORMAT_NV12,
|
||||
MF_COLOR_FORMAT_ARGB,
|
||||
MF_COLOR_FORMAT_XRGB
|
||||
};
|
||||
|
||||
typedef HANDLE CAPTURE_DEVICE_HANDLE;
|
||||
typedef void(__stdcall *MF_VideoDataCallback)(void *pData, int Size,
|
||||
long long llTimestamp,
|
||||
void *pUserData);
|
||||
typedef void(__stdcall *MF_EnumerateCameraCallback)(const wchar_t *Name,
|
||||
const wchar_t *DevId,
|
||||
void *pUserData);
|
||||
typedef void(__stdcall *MF_EnumerateStreamCapabilitiesCallback)(
|
||||
UINT32 Width, UINT32 Height, UINT32 FpsN, UINT32 FpsD, void *pUserData);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_EnumerateCameras(MF_EnumerateCameraCallback cb,
|
||||
void *pUserData);
|
||||
|
||||
MFCAPTURE_EXPORTS CAPTURE_DEVICE_HANDLE MF_Create(const wchar_t *DevId);
|
||||
|
||||
MFCAPTURE_EXPORTS void MF_Destroy(CAPTURE_DEVICE_HANDLE h);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_Prepare(CAPTURE_DEVICE_HANDLE h);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_EnumerateStreamCapabilities(
|
||||
CAPTURE_DEVICE_HANDLE h, MF_EnumerateStreamCapabilitiesCallback cb,
|
||||
void *pUserData);
|
||||
|
||||
// if llInterval is 0, set the camera to us the max fps
|
||||
// otherwise, set camera with matching fps.
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetOutputResolution(CAPTURE_DEVICE_HANDLE h,
|
||||
UINT32 uiWidth,
|
||||
UINT32 uiHeight,
|
||||
LONGLONG llInterval,
|
||||
MF_COLOR_FORMAT fmt);
|
||||
|
||||
// LONGLONG llInterval = 10000000ll * uiFpsD / uiFpsN;
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetOutputResolution(CAPTURE_DEVICE_HANDLE h,
|
||||
UINT32 *uiWidth,
|
||||
UINT32 *uiHeight,
|
||||
UINT32 *uiFpsN,
|
||||
UINT32 *uiFpsD);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_Start(CAPTURE_DEVICE_HANDLE h,
|
||||
MF_VideoDataCallback cb, void *pUserData);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_Stop(CAPTURE_DEVICE_HANDLE h);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetBlur(CAPTURE_DEVICE_HANDLE h, bool &blur,
|
||||
bool &shallowFocus, bool &mask);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetBlur(CAPTURE_DEVICE_HANDLE h, BOOL blur,
|
||||
BOOL shallowFocus, BOOL mask);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetTransparent(CAPTURE_DEVICE_HANDLE h,
|
||||
bool &enable);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetAutoFraming(CAPTURE_DEVICE_HANDLE h,
|
||||
bool &enable);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetAutoFraming(CAPTURE_DEVICE_HANDLE h,
|
||||
BOOL enable);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetEyeGazeCorrection(CAPTURE_DEVICE_HANDLE h,
|
||||
bool &enable);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetEyeGazeCorrection(CAPTURE_DEVICE_HANDLE h,
|
||||
BOOL enable);
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_RestoreDefaultSettings(CAPTURE_DEVICE_HANDLE h);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,177 @@
|
|||
#include "DeviceControlChangeListener.hpp"
|
||||
|
||||
DeviceControlChangeListener::DeviceControlChangeListener() {}
|
||||
|
||||
DeviceControlChangeListener::~DeviceControlChangeListener() {}
|
||||
|
||||
// IUnknown methods
|
||||
HRESULT __stdcall DeviceControlChangeListener::QueryInterface(REFIID iid,
|
||||
void **ppv)
|
||||
{
|
||||
|
||||
if (iid == IID_IUnknown) {
|
||||
*ppv = static_cast<IUnknown *>(this);
|
||||
} else if (iid == IID_IMFCameraControlNotify) {
|
||||
*ppv = static_cast<IMFCameraControlNotify *>(this);
|
||||
} else {
|
||||
*ppv = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG __stdcall DeviceControlChangeListener::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
ULONG __stdcall DeviceControlChangeListener::Release()
|
||||
{
|
||||
|
||||
if (InterlockedDecrement(&m_cRef) == 0) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return m_cRef;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
DeviceControlChangeListener::HandleControlSet_ExtendedCameraControl(UINT32 id)
|
||||
{
|
||||
|
||||
if (id != KSPROPERTY_CAMERACONTROL_EXTENDED_EYEGAZECORRECTION &&
|
||||
id != KSPROPERTY_CAMERACONTROL_EXTENDED_BACKGROUNDSEGMENTATION &&
|
||||
id != KSPROPERTY_CAMERACONTROL_EXTENDED_DIGITALWINDOW &&
|
||||
id != KSPROPERTY_CAMERACONTROL_EXTENDED_DIGITALWINDOW_CONFIGCAPS &&
|
||||
id != KSPROPERTY_CAMERACONTROL_EXTENDED_VIDEOHDR) {
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
DWORD dwStreamIndex = KSCAMERA_EXTENDEDPROP_FILTERSCOPE;
|
||||
wil::com_ptr<IMFExtendedCameraControl> spExtControl = nullptr;
|
||||
RETURN_IF_FAILED(m_spExtCamController->GetExtendedCameraControl(
|
||||
dwStreamIndex, id, &spExtControl));
|
||||
|
||||
ULONGLONG Flags = spExtControl->GetFlags();
|
||||
|
||||
WS_CONTROL_TYPE ctrlType = WS_EFFECT_UNKNOWN;
|
||||
WS_CONTROL_VALUE ctrlValue = WS_EFFECT_OFF;
|
||||
|
||||
if (id == KSPROPERTY_CAMERACONTROL_EXTENDED_EYEGAZECORRECTION) {
|
||||
|
||||
bool effect = Flags &
|
||||
KSCAMERA_EXTENDEDPROP_EYEGAZECORRECTION_ON;
|
||||
|
||||
} else if (id ==
|
||||
KSPROPERTY_CAMERACONTROL_EXTENDED_BACKGROUNDSEGMENTATION) {
|
||||
|
||||
bool blur = Flags &
|
||||
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_BLUR;
|
||||
bool focus =
|
||||
Flags &
|
||||
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_SHALLOWFOCUS;
|
||||
bool mask = Flags &
|
||||
KSCAMERA_EXTENDEDPROP_BACKGROUNDSEGMENTATION_MASK;
|
||||
|
||||
if (focus) {
|
||||
blur = false;
|
||||
}
|
||||
|
||||
} else if (id == KSPROPERTY_CAMERACONTROL_EXTENDED_DIGITALWINDOW) {
|
||||
|
||||
bool effect =
|
||||
Flags &
|
||||
KSCAMERA_EXTENDEDPROP_DIGITALWINDOW_AUTOFACEFRAMING;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void PrintGuid(GUID guid)
|
||||
{
|
||||
printf("{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}",
|
||||
guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1],
|
||||
guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5],
|
||||
guid.Data4[6], guid.Data4[7]);
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE
|
||||
DeviceControlChangeListener::OnChange(_In_ REFGUID controlSet, _In_ UINT32 id)
|
||||
{
|
||||
auto lock = m_lock.lock();
|
||||
|
||||
printf("Guid = ");
|
||||
PrintGuid(controlSet);
|
||||
printf(" Id = %d\n", id);
|
||||
|
||||
if (IsEqualCLSID(controlSet, KSPROPERTYSETID_ANYCAMERACONTROL)) {
|
||||
printf("KSPROPERTYSETID_ANYCAMERACONTROL\n");
|
||||
} else if (IsEqualCLSID(controlSet, PROPSETID_VIDCAP_VIDEOPROCAMP)) {
|
||||
printf("PROPSETID_VIDCAP_VIDEOPROCAMP\n");
|
||||
} else if (IsEqualCLSID(controlSet, PROPSETID_VIDCAP_CAMERACONTROL)) {
|
||||
printf("PROPSETID_VIDCAP_CAMERACONTROL\n");
|
||||
|
||||
} else if (IsEqualCLSID(controlSet,
|
||||
KSPROPERTYSETID_ExtendedCameraControl)) {
|
||||
printf("KSPROPERTYSETID_ExtendedCameraControl\n");
|
||||
HandleControlSet_ExtendedCameraControl(id);
|
||||
} else {
|
||||
printf("Unknown control set\n");
|
||||
}
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE
|
||||
DeviceControlChangeListener::OnError(_In_ HRESULT hrStatus)
|
||||
{
|
||||
auto lock = m_lock.lock();
|
||||
printf("%s, hrStatus = 0x%x\n", __FUNCSIG__, hrStatus);
|
||||
}
|
||||
|
||||
HRESULT DeviceControlChangeListener::Start(
|
||||
const wchar_t *devId, IMFExtendedCameraController *pExtCamController)
|
||||
{
|
||||
{
|
||||
auto lock = m_lock.lock();
|
||||
if (m_bStarted) {
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
wil::com_ptr_nothrow<IMFCameraControlMonitor> spMonitor;
|
||||
RETURN_IF_FAILED(MFCreateCameraControlMonitor(devId, this, &spMonitor));
|
||||
RETURN_IF_FAILED(spMonitor->AddControlSubscription(
|
||||
KSPROPERTYSETID_ANYCAMERACONTROL, 0));
|
||||
RETURN_IF_FAILED(spMonitor->Start());
|
||||
|
||||
{
|
||||
auto lock = m_lock.lock();
|
||||
m_spMonitor = spMonitor;
|
||||
}
|
||||
|
||||
m_spExtCamController = pExtCamController;
|
||||
|
||||
m_bStarted = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DeviceControlChangeListener::Stop()
|
||||
{
|
||||
|
||||
auto lock = m_lock.lock();
|
||||
if (!m_bStarted) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (m_spMonitor != nullptr) {
|
||||
m_spMonitor->RemoveControlSubscription(
|
||||
KSPROPERTYSETID_ANYCAMERACONTROL, 0);
|
||||
(void)m_spMonitor->Shutdown();
|
||||
m_spMonitor = nullptr;
|
||||
}
|
||||
|
||||
m_spExtCamController = nullptr;
|
||||
|
||||
m_bStarted = false;
|
||||
return S_OK;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
|
||||
#include "framework.hpp"
|
||||
|
||||
#include <wil\cppwinrt.h> // must be before the first C++ WinRT header, ref:https://github.com/Microsoft/wil/wiki/Error-handling-helpers
|
||||
#include <wil\result.h>
|
||||
#include <wil\com.h>
|
||||
|
||||
#include <mfidl.h>
|
||||
#include <string>
|
||||
|
||||
typedef enum _WS_CONTROL_TYPE {
|
||||
WS_EFFECT_UNKNOWN = -1,
|
||||
WS_BACKGROUND_STANDARD = 0,
|
||||
WS_BACKGROUND_PORTRAIT = 1,
|
||||
WS_BACKGROUND_MASK = 2,
|
||||
WS_BACKGROUND_NONE = 3,
|
||||
WS_AUTO_FRAMING = 4,
|
||||
WS_EYE_CONTACT = 5,
|
||||
} WS_CONTROL_TYPE;
|
||||
|
||||
typedef enum _WS_CONTROL_VALUE {
|
||||
WS_EFFECT_OFF = 0,
|
||||
WS_EFFECT_ON = 1,
|
||||
} WS_CONTROL_VALUE;
|
||||
|
||||
class DeviceControlChangeListener : public IMFCameraControlNotify {
|
||||
long m_cRef = 1;
|
||||
wil::critical_section m_lock;
|
||||
|
||||
std::wstring m_wsDevId;
|
||||
wil::com_ptr_nothrow<IMFCameraControlMonitor> m_spMonitor = nullptr;
|
||||
wil::com_ptr_nothrow<IKsControl> m_spKsControl = nullptr;
|
||||
wil::com_ptr_nothrow<IMFExtendedCameraController> m_spExtCamController =
|
||||
nullptr;
|
||||
void *m_cbdata = nullptr;
|
||||
|
||||
bool m_bStarted = false;
|
||||
|
||||
private:
|
||||
HRESULT HandleControlSet_ExtendedCameraControl(UINT32 id);
|
||||
|
||||
public:
|
||||
DeviceControlChangeListener();
|
||||
~DeviceControlChangeListener();
|
||||
|
||||
// IUnknown methods
|
||||
IFACEMETHODIMP_(ULONG) AddRef(void) override;
|
||||
IFACEMETHODIMP_(ULONG) Release(void) override;
|
||||
IFACEMETHODIMP QueryInterface(_In_ REFIID riid,
|
||||
_Out_ LPVOID *ppvObject) override;
|
||||
|
||||
// IMFCameraControlNotify methods
|
||||
void STDMETHODCALLTYPE OnChange(_In_ REFGUID controlSet,
|
||||
_In_ UINT32 id);
|
||||
void STDMETHODCALLTYPE OnError(_In_ HRESULT hrStatus);
|
||||
|
||||
HRESULT Start(const wchar_t *devId,
|
||||
IMFExtendedCameraController *pExtCamController);
|
||||
|
||||
HRESULT Stop();
|
||||
};
|
1418
plugins/win-mf/libmfcapture/source/PhysicalCamera.cpp
Normal file
1418
plugins/win-mf/libmfcapture/source/PhysicalCamera.cpp
Normal file
File diff suppressed because it is too large
Load diff
148
plugins/win-mf/libmfcapture/source/PhysicalCamera.hpp
Normal file
148
plugins/win-mf/libmfcapture/source/PhysicalCamera.hpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
#pragma once
|
||||
|
||||
#define ARGB_SEG_MASK_WORKAROUND
|
||||
|
||||
struct CameraInformation {
|
||||
std::wstring FriendlyName;
|
||||
std::wstring SymbolicLink;
|
||||
};
|
||||
|
||||
struct StreamInformation {
|
||||
UINT32 uiWidth;
|
||||
UINT32 uiHeight;
|
||||
UINT32 uiFpsN;
|
||||
UINT32 uiFpsD;
|
||||
GUID guidSubtype;
|
||||
};
|
||||
|
||||
struct MepSetting {
|
||||
std::wstring SymbolicLink;
|
||||
bool Blur = false;
|
||||
bool ShallowFocus = false;
|
||||
bool Mask = false;
|
||||
bool AutoFraming = false;
|
||||
bool EyeGazeCorrection = false;
|
||||
};
|
||||
|
||||
class PhysicalCamera : public IMFSourceReaderCallback {
|
||||
static std::vector<MepSetting> s_MepSettings;
|
||||
|
||||
private:
|
||||
long m_cRef = 1;
|
||||
winrt::slim_mutex m_Lock;
|
||||
wil::com_ptr_nothrow<IMFMediaSource> m_spDevSource = nullptr;
|
||||
wil::com_ptr_nothrow<IMFSourceReader> m_spSourceReader = nullptr;
|
||||
wil::com_ptr_nothrow<IMFDXGIDeviceManager> m_spDxgiDevManager = nullptr;
|
||||
wil::com_ptr_nothrow<IMFExtendedCameraController> m_spExtController =
|
||||
nullptr;
|
||||
|
||||
MF_VideoDataCallback m_cbVideoData = nullptr;
|
||||
void *m_pUserData = nullptr;
|
||||
|
||||
MF_COLOR_FORMAT m_fmt = MF_COLOR_FORMAT_UNKNOWN;
|
||||
UINT32 m_uiWidth = 0;
|
||||
UINT32 m_uiHeight = 0;
|
||||
LONG m_lDefaultStride = 0;
|
||||
|
||||
UINT32 m_uiSegMaskBufSize = 0;
|
||||
BYTE *m_pSegMaskBuf = nullptr;
|
||||
|
||||
bool m_transparent = false;
|
||||
|
||||
#ifdef ARGB_SEG_MASK_WORKAROUND
|
||||
BYTE *m_pBufferArgbOut = nullptr;
|
||||
#endif
|
||||
|
||||
std::wstring m_wsSymbolicName;
|
||||
|
||||
DeviceControlChangeListener *m_pDevCtrlNotify = nullptr;
|
||||
|
||||
private:
|
||||
HRESULT CreateSourceReader(IMFMediaSource *pSource,
|
||||
IMFDXGIDeviceManager *pDxgiDevIManager,
|
||||
IMFSourceReader **ppSourceReader);
|
||||
|
||||
HRESULT FindMatchingNativeMediaType(DWORD dwPhyStrmIndex,
|
||||
UINT32 uiWidth, UINT32 uiHeight,
|
||||
UINT32 uiFpsN, UINT32 uiFpsD,
|
||||
IMFMediaType **ppMatchingType);
|
||||
|
||||
HRESULT FindMatchingNativeMediaType(DWORD dwPhyStrmIndex,
|
||||
UINT32 uiWidth, UINT32 uiHeight,
|
||||
LONGLONG llInterval,
|
||||
IMFMediaType **ppMatchingType);
|
||||
|
||||
HRESULT GetMepSetting(MepSetting &setting);
|
||||
HRESULT SetMepSetting(MepSetting &setting);
|
||||
|
||||
HRESULT SaveSettingsToDefault();
|
||||
|
||||
HRESULT FillSegMask(IMFSample *pSample);
|
||||
HRESULT FillAlphaWithSegMask(DWORD *pData);
|
||||
|
||||
public:
|
||||
PhysicalCamera();
|
||||
~PhysicalCamera();
|
||||
|
||||
PhysicalCamera(const PhysicalCamera &) = delete;
|
||||
PhysicalCamera &operator=(PhysicalCamera const &) = delete;
|
||||
|
||||
// IUnknown methods
|
||||
STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
|
||||
STDMETHODIMP_(ULONG) AddRef();
|
||||
STDMETHODIMP_(ULONG) Release();
|
||||
|
||||
// IMFSourceReaderCallback methods
|
||||
STDMETHODIMP OnReadSample(HRESULT hrStatus, DWORD dwPhyStrmIndex,
|
||||
DWORD dwStreamFlags, LONGLONG llTimestamp,
|
||||
IMFSample *pSample);
|
||||
|
||||
STDMETHODIMP OnEvent(DWORD, IMFMediaEvent *) { return S_OK; }
|
||||
|
||||
STDMETHODIMP OnFlush(DWORD) { return S_OK; }
|
||||
|
||||
HRESULT Initialize(LPCWSTR pwszSymLink);
|
||||
|
||||
HRESULT Uninitialize();
|
||||
|
||||
HRESULT SetD3dManager(IMFDXGIDeviceManager *pD3dManager);
|
||||
|
||||
HRESULT Prepare();
|
||||
|
||||
HRESULT Start(DWORD dwPhyStrmIndex, MF_VideoDataCallback cb,
|
||||
void *pUserData);
|
||||
|
||||
HRESULT Stop();
|
||||
|
||||
HRESULT GetStreamCapabilities(DWORD dwPhyStrmIndex,
|
||||
std::vector<StreamInformation> &strmCaps);
|
||||
|
||||
void SetTransparent(bool flag) { m_transparent = flag; }
|
||||
|
||||
bool GetTransparent() { return m_transparent; }
|
||||
|
||||
// if llInterval is 0, set the camera to us the max fps
|
||||
// otherwise, set camera with matching fps.
|
||||
HRESULT SetOutputResolution(DWORD dwPhyStrmIndex, UINT32 uiWidth,
|
||||
UINT32 uiHeight, LONGLONG llInterval,
|
||||
MF_COLOR_FORMAT fmt);
|
||||
|
||||
HRESULT GetCurrentStreamInformation(DWORD dwPhyStrmIndex,
|
||||
StreamInformation &strmInfo);
|
||||
|
||||
HRESULT SetBlur(bool blur, bool shallowFocus, bool mask);
|
||||
HRESULT GetBlur(bool &blur, bool &shallowFocus, bool &mask);
|
||||
|
||||
HRESULT SetAutoFraming(bool enable);
|
||||
HRESULT GetAutoFraming(bool &enable);
|
||||
|
||||
HRESULT SetEyeGazeCorrection(bool enable);
|
||||
HRESULT GetEyeGazeCorrection(bool &enable);
|
||||
|
||||
HRESULT RestoreDefaultSettings();
|
||||
|
||||
static HRESULT CreateInstance(PhysicalCamera **ppPhysicalCamera);
|
||||
|
||||
static HRESULT
|
||||
GetPhysicalCameras(std::vector<CameraInformation> &cameras);
|
||||
};
|
27
plugins/win-mf/libmfcapture/source/framework.hpp
Normal file
27
plugins/win-mf/libmfcapture/source/framework.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
|
||||
#include "winrt\Windows.Foundation.h"
|
||||
#include "winrt\Windows.ApplicationModel.h"
|
||||
|
||||
#include <wil\cppwinrt.h> // must be before the first C++ WinRT header, ref:https://github.com/Microsoft/wil/wiki/Error-handling-helpers
|
||||
#include <wil\result.h>
|
||||
#include <wil\com.h>
|
||||
|
||||
#include <Ks.h>
|
||||
#include <ksproxy.h>
|
||||
#include <ksmedia.h>
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
#include <mfobjects.h>
|
||||
#include <mferror.h>
|
||||
#include <mfreadwrite.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <mfidl.h>
|
||||
|
||||
#include <cfgmgr32.h>
|
||||
#include <initguid.h>
|
224
plugins/win-mf/libmfcapture/source/mfcapture.cpp
Normal file
224
plugins/win-mf/libmfcapture/source/mfcapture.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
#include "mfcapture.hpp"
|
||||
#include "DeviceControlChangeListener.hpp"
|
||||
#include "PhysicalCamera.hpp"
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_EnumerateCameras(MF_EnumerateCameraCallback cb,
|
||||
void *pUserData)
|
||||
{
|
||||
std::vector<CameraInformation> camlist;
|
||||
RETURN_IF_FAILED(PhysicalCamera::GetPhysicalCameras(camlist));
|
||||
|
||||
for (auto &cam : camlist) {
|
||||
if (cb) {
|
||||
cb(cam.FriendlyName.c_str(), cam.SymbolicLink.c_str(),
|
||||
pUserData);
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS CAPTURE_DEVICE_HANDLE MF_Create(const wchar_t *DevId)
|
||||
{
|
||||
wil::com_ptr_nothrow<PhysicalCamera> spCapture = nullptr;
|
||||
HRESULT hr = PhysicalCamera::CreateInstance(&spCapture);
|
||||
if (FAILED(hr)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hr = spCapture->Initialize(DevId);
|
||||
if (FAILED(hr)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return spCapture.detach();
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS void MF_Destroy(CAPTURE_DEVICE_HANDLE h)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (p) {
|
||||
p->Release();
|
||||
}
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_Prepare(CAPTURE_DEVICE_HANDLE h)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->Prepare();
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_EnumerateStreamCapabilities(
|
||||
CAPTURE_DEVICE_HANDLE h, MF_EnumerateStreamCapabilitiesCallback cb,
|
||||
void *pUserData)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
std::vector<StreamInformation> caplist;
|
||||
HRESULT hr = p->GetStreamCapabilities(0, caplist);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
for (auto &cap : caplist) {
|
||||
if (cb) {
|
||||
cb(cap.uiWidth, cap.uiHeight, cap.uiFpsN, cap.uiFpsD,
|
||||
pUserData);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetOutputResolution(CAPTURE_DEVICE_HANDLE h,
|
||||
UINT32 uiWidth,
|
||||
UINT32 uiHeight,
|
||||
LONGLONG llInterval,
|
||||
MF_COLOR_FORMAT fmt)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->SetOutputResolution(0, uiWidth, uiHeight, llInterval, fmt);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetOutputResolution(CAPTURE_DEVICE_HANDLE h,
|
||||
UINT32 *uiWidth,
|
||||
UINT32 *uiHeight,
|
||||
UINT32 *uiFpsN, UINT32 *uiFpsD)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
StreamInformation info;
|
||||
RETURN_IF_FAILED(p->GetCurrentStreamInformation(0, info));
|
||||
|
||||
if (uiWidth && uiHeight && uiFpsN && uiFpsD) {
|
||||
*uiWidth = info.uiWidth;
|
||||
*uiHeight = info.uiHeight;
|
||||
*uiFpsN = info.uiFpsN;
|
||||
*uiFpsD = info.uiFpsD;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_Start(CAPTURE_DEVICE_HANDLE h,
|
||||
MF_VideoDataCallback cb, void *pUserData)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return p->Start(0, cb, pUserData);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_Stop(CAPTURE_DEVICE_HANDLE h)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
return p->Stop();
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetBlur(CAPTURE_DEVICE_HANDLE h, bool &blur,
|
||||
bool &shallowFocus, bool &mask)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->GetBlur(blur, shallowFocus, mask);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetBlur(CAPTURE_DEVICE_HANDLE h, BOOL blur,
|
||||
BOOL shallowFocus, BOOL mask)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
p->SetTransparent(mask);
|
||||
|
||||
return p->SetBlur(blur, shallowFocus, mask);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetTransparent(CAPTURE_DEVICE_HANDLE h,
|
||||
bool &enable)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
enable = p->GetTransparent();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetAutoFraming(CAPTURE_DEVICE_HANDLE h,
|
||||
bool &enable)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->GetAutoFraming(enable);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetAutoFraming(CAPTURE_DEVICE_HANDLE h,
|
||||
BOOL enable)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->SetAutoFraming(enable);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_GetEyeGazeCorrection(CAPTURE_DEVICE_HANDLE h,
|
||||
bool &enable)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->GetEyeGazeCorrection(enable);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_SetEyeGazeCorrection(CAPTURE_DEVICE_HANDLE h,
|
||||
BOOL enable)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->SetEyeGazeCorrection(enable);
|
||||
}
|
||||
|
||||
MFCAPTURE_EXPORTS HRESULT MF_RestoreDefaultSettings(CAPTURE_DEVICE_HANDLE h)
|
||||
{
|
||||
PhysicalCamera *p = (PhysicalCamera *)h;
|
||||
if (!p) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
return p->RestoreDefaultSettings();
|
||||
}
|
141
plugins/win-mf/libmfcapture/source/mfcapture.rc
Normal file
141
plugins/win-mf/libmfcapture/source/mfcapture.rc
Normal file
|
@ -0,0 +1,141 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.hpp"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_DIALOG_EFFECT_CONTROL DIALOGEX 0, 0, 235, 144
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Effect Control"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,92,123,50,14
|
||||
CONTROL "Auto Framing",IDC_CHECK_AUTOFRAMING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,34,65,59,10
|
||||
CONTROL "Eye Gaze Correction",IDC_CHECK_EYEGAZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,34,82,81,10
|
||||
CONTROL "Portrait Blur",IDC_RADIO_BLUR_PORTRAIT,"Button",BS_AUTORADIOBUTTON,34,38,54,10
|
||||
CONTROL "Standard Blur",IDC_RADIO_BLUR_STANDARD,"Button",BS_AUTORADIOBUTTON,99,38,59,10
|
||||
GROUPBOX "Blur",IDC_STATIC,18,20,199,40
|
||||
CONTROL "None",IDC_RADIO_NOBLUR,"Button",BS_AUTORADIOBUTTON,169,38,33,10
|
||||
CONTROL "Background Transparent",IDC_CHECK_BK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,34,99,95,10
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_DIALOG_EFFECT_CONTROL, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 230
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 137
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// AFX_DIALOG_LAYOUT
|
||||
//
|
||||
|
||||
IDD_DIALOG_EFFECT_CONTROL AFX_DIALOG_LAYOUT
|
||||
BEGIN
|
||||
0
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 30,0,1,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Intel Corporation"
|
||||
VALUE "FileDescription", "OBS Video Capture module"
|
||||
VALUE "FileVersion", "30.0.1"
|
||||
VALUE "ProductName", "OBS Studio"
|
||||
VALUE "ProductVersion", "30.0.1"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2023, Intel Corporation"
|
||||
VALUE "InternalName", "win-mf"
|
||||
VALUE "OriginalFilename", "win-mf"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409,1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
23
plugins/win-mf/libmfcapture/source/resource.hpp
Normal file
23
plugins/win-mf/libmfcapture/source/resource.hpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
// {{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by libmfcapture.rc
|
||||
//
|
||||
#define IDD_DIALOG1 101
|
||||
#define IDD_DIALOG_EFFECT_CONTROL 101
|
||||
#define IDC_CHECK_BK 1002
|
||||
#define IDC_CHECK_AUTOFRAMING 1003
|
||||
#define IDC_CHECK_EYEGAZE 1004
|
||||
#define IDC_RADIO_BLUR_PORTRAIT 1005
|
||||
#define IDC_RADIO_BLUR_STANDARD 1006
|
||||
#define IDC_RADIO_NOBLUR 1007
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1008
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
24
plugins/win-mf/mf-plugin.cpp
Normal file
24
plugins/win-mf/mf-plugin.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* mf-plugin.cpp */
|
||||
#include <obs-module.h>
|
||||
#include <strsafe.h>
|
||||
#include <strmif.h>
|
||||
#include "plugin-macros.generated.h"
|
||||
|
||||
OBS_DECLARE_MODULE()
|
||||
OBS_MODULE_USE_DEFAULT_LOCALE(PLUGIN_NAME, "en-US")
|
||||
|
||||
extern void RegisterMediaFoundationSource();
|
||||
|
||||
bool obs_module_load(void)
|
||||
{
|
||||
RegisterMediaFoundationSource();
|
||||
obs_data_t *obs_settings = obs_data_create();
|
||||
obs_apply_private_data(obs_settings);
|
||||
obs_data_release(obs_settings);
|
||||
return true;
|
||||
}
|
||||
|
||||
void obs_module_unload()
|
||||
{
|
||||
blog(LOG_INFO, "plugin unloaded");
|
||||
}
|
28
plugins/win-mf/plugin-macros.generated.h
Normal file
28
plugins/win-mf/plugin-macros.generated.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Plugin Name
|
||||
Copyright (C) <Year> <Developer> <Email Address>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef PLUGINNAME_H
|
||||
#define PLUGINNAME_H
|
||||
|
||||
#define PLUGIN_NAME "obs-mf-source"
|
||||
#define PLUGIN_VERSION "2023.1.0.0"
|
||||
|
||||
#define blog(level, msg, ...) \
|
||||
blog(level, "[" PLUGIN_NAME "] " msg, ##__VA_ARGS__)
|
||||
|
||||
#endif // PLUGINNAME_H
|
27
plugins/win-mf/plugin-macros.h.in
Normal file
27
plugins/win-mf/plugin-macros.h.in
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Plugin Name
|
||||
Copyright (C) <Year> <Developer> <Email Address>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef PLUGINNAME_H
|
||||
#define PLUGINNAME_H
|
||||
|
||||
#define PLUGIN_NAME "@CMAKE_PROJECT_NAME@"
|
||||
#define PLUGIN_VERSION "@CMAKE_PROJECT_VERSION@"
|
||||
|
||||
#define blog(level, msg, ...) blog(level, "[" PLUGIN_NAME "] " msg, ##__VA_ARGS__)
|
||||
|
||||
#endif // PLUGINNAME_H
|
1736
plugins/win-mf/win-mf.cpp
Normal file
1736
plugins/win-mf/win-mf.cpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue