From db895092ed60a96c64bdf06823ee144867c4e267 Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Tue, 28 Mar 2023 19:50:59 +0200 Subject: [PATCH] cmake: Add changes for CMake build framework 3.0 New code path only taken if OBS_CMAKE_VERSION is set to 3.0.0 or greater, old functionality remains unchanged. --- CMakeLists.txt | 3 +- UI/CMakeLists.txt | 11 +- UI/cmake/feature-importers.cmake | 2 +- UI/cmake/feature-whatsnew.cmake | 2 +- UI/cmake/feature-youtube.cmake | 4 +- UI/cmake/os-windows.cmake | 10 +- UI/cmake/ui-qt.cmake | 3 +- UI/cmake/windows/obs-studio.ico | Bin 0 -> 93455 bytes UI/cmake/windows/obs.manifest | 20 ++ UI/cmake/windows/obs.rc.in | 26 ++ UI/win-update/updater/CMakeLists.txt | 9 +- deps/CMakeLists.txt | 4 - deps/ipc-util/CMakeLists.txt | 22 +- libobs-d3d11/CMakeLists.txt | 47 ++-- libobs-d3d11/cmake/legacy.cmake | 50 ++++ libobs-d3d11/cmake/windows/obs-module.rc.in | 24 ++ libobs-d3d11/d3d11-config.h.in | 20 -- libobs-d3d11/d3d11-subsystem.cpp | 4 +- libobs-winrt/CMakeLists.txt | 28 ++- libobs-winrt/cmake/legacy.cmake | 31 +++ libobs/CMakeLists.txt | 12 +- libobs/cmake/os-freebsd.cmake | 42 ++-- libobs/cmake/os-linux.cmake | 39 ++- libobs/cmake/os-windows.cmake | 2 +- libobs/obs-windows.c | 10 +- plugins/coreaudio-encoder/CMakeLists.txt | 3 - plugins/obs-ffmpeg/CMakeLists.txt | 41 ++-- .../obs-ffmpeg/obs-amf-test/CMakeLists.txt | 15 +- .../obs-amf-test/cmake/legacy.cmake | 14 ++ .../obs-ffmpeg/obs-nvenc-test/CMakeLists.txt | 14 +- .../obs-nvenc-test/cmake/legacy.cmake | 12 + .../obs-nvenc-test/obs-nvenc-test.c | 4 + plugins/obs-outputs/cmake/ftl.cmake | 49 ++-- plugins/obs-qsv11/CMakeLists.txt | 137 +++++------ plugins/obs-qsv11/cmake/legacy.cmake | 125 ++++++++++ .../obs-qsv11/cmake/windows/obs-module.rc.in | 24 ++ plugins/obs-qsv11/obs-qsv-test/CMakeLists.txt | 13 +- .../obs-qsv11/obs-qsv-test/cmake/legacy.cmake | 11 + plugins/obs-text/CMakeLists.txt | 19 +- plugins/obs-text/cmake/legacy.cmake | 19 ++ .../obs-text/cmake/windows/obs-module.rc.in | 24 ++ plugins/win-capture/CMakeLists.txt | 91 ++++--- plugins/win-capture/cmake/32bit-build.cmake | 3 + plugins/win-capture/cmake/legacy.cmake | 63 +++++ .../win-capture/duplicator-monitor-capture.c | 5 + .../get-graphics-offsets/CMakeLists.txt | 40 ++-- .../cmake/32bit-build.cmake | 5 + .../get-graphics-offsets/cmake/32bit.cmake | 5 + .../get-graphics-offsets/cmake/legacy.cmake | 33 +++ .../get-graphics-offsets/d3d8-offsets.cpp | 4 + .../get-graphics-offsets.h | 4 + .../win-capture/graphics-hook/CMakeLists.txt | 92 ++++---- .../graphics-hook/cmake/32bit-build.cmake | 9 + .../graphics-hook/cmake/32bit.cmake | 5 + .../graphics-hook/cmake/legacy.cmake | 58 +++++ .../graphics-hook/d3d8-capture.cpp | 4 + .../win-capture/graphics-hook/graphics-hook.c | 5 + .../win-capture/graphics-hook/graphics-hook.h | 4 + .../win-capture/inject-helper/CMakeLists.txt | 31 +-- .../inject-helper/cmake/32bit-build.cmake | 5 + .../inject-helper/cmake/32bit.cmake | 5 + .../inject-helper/cmake/legacy.cmake | 21 ++ .../win-capture/inject-helper/inject-helper.c | 5 + plugins/win-capture/inject-library.c | 4 + plugins/win-capture/plugin-main.c | 2 + plugins/win-capture/window-capture.c | 5 + plugins/win-dshow/CMakeLists.txt | 223 +++--------------- plugins/win-dshow/cmake/legacy.cmake | 216 +++++++++++++++++ plugins/win-dshow/cmake/libdshowcapture.cmake | 56 +++++ .../win-dshow/cmake/windows/obs-module.rc.in | 24 ++ .../virtualcam-module/CMakeLists.txt | 138 +++++++---- .../virtualcam-module/cmake/32bit-build.cmake | 49 ++++ .../virtualcam-module/cmake/32bit.cmake | 5 + .../virtualcam-module/cmake/legacy.cmake | 60 +++++ .../cmake/windows/obs-module.rc.in | 24 ++ .../cmake/windows/virtualcam-module32.def | 8 + .../cmake/windows/virtualcam-module64.def | 8 + .../virtualcam-module/virtualcam-filter.hpp | 10 + .../virtualcam-guid.h.in | 0 .../virtualcam-install.bat.in | 0 .../virtualcam-uninstall.bat.in | 0 plugins/win-wasapi/CMakeLists.txt | 17 +- plugins/win-wasapi/cmake/legacy.cmake | 18 ++ .../win-wasapi/cmake/windows/obs-module.rc.in | 24 ++ 84 files changed, 1642 insertions(+), 695 deletions(-) create mode 100644 UI/cmake/windows/obs-studio.ico create mode 100644 UI/cmake/windows/obs.manifest create mode 100644 UI/cmake/windows/obs.rc.in create mode 100644 libobs-d3d11/cmake/legacy.cmake create mode 100644 libobs-d3d11/cmake/windows/obs-module.rc.in delete mode 100644 libobs-d3d11/d3d11-config.h.in create mode 100644 libobs-winrt/cmake/legacy.cmake create mode 100644 plugins/obs-ffmpeg/obs-amf-test/cmake/legacy.cmake create mode 100644 plugins/obs-ffmpeg/obs-nvenc-test/cmake/legacy.cmake create mode 100644 plugins/obs-qsv11/cmake/legacy.cmake create mode 100644 plugins/obs-qsv11/cmake/windows/obs-module.rc.in create mode 100644 plugins/obs-qsv11/obs-qsv-test/cmake/legacy.cmake create mode 100644 plugins/obs-text/cmake/legacy.cmake create mode 100644 plugins/obs-text/cmake/windows/obs-module.rc.in create mode 100644 plugins/win-capture/cmake/32bit-build.cmake create mode 100644 plugins/win-capture/cmake/legacy.cmake create mode 100644 plugins/win-capture/get-graphics-offsets/cmake/32bit-build.cmake create mode 100644 plugins/win-capture/get-graphics-offsets/cmake/32bit.cmake create mode 100644 plugins/win-capture/get-graphics-offsets/cmake/legacy.cmake create mode 100644 plugins/win-capture/graphics-hook/cmake/32bit-build.cmake create mode 100644 plugins/win-capture/graphics-hook/cmake/32bit.cmake create mode 100644 plugins/win-capture/graphics-hook/cmake/legacy.cmake create mode 100644 plugins/win-capture/inject-helper/cmake/32bit-build.cmake create mode 100644 plugins/win-capture/inject-helper/cmake/32bit.cmake create mode 100644 plugins/win-capture/inject-helper/cmake/legacy.cmake create mode 100644 plugins/win-dshow/cmake/legacy.cmake create mode 100644 plugins/win-dshow/cmake/libdshowcapture.cmake create mode 100644 plugins/win-dshow/cmake/windows/obs-module.rc.in create mode 100644 plugins/win-dshow/virtualcam-module/cmake/32bit-build.cmake create mode 100644 plugins/win-dshow/virtualcam-module/cmake/32bit.cmake create mode 100644 plugins/win-dshow/virtualcam-module/cmake/legacy.cmake create mode 100644 plugins/win-dshow/virtualcam-module/cmake/windows/obs-module.rc.in create mode 100644 plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module32.def create mode 100644 plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module64.def rename plugins/win-dshow/{ => virtualcam-module}/virtualcam-guid.h.in (100%) rename plugins/win-dshow/{ => virtualcam-module}/virtualcam-install.bat.in (100%) rename plugins/win-dshow/{ => virtualcam-module}/virtualcam-uninstall.bat.in (100%) create mode 100644 plugins/win-wasapi/cmake/legacy.cmake create mode 100644 plugins/win-wasapi/cmake/windows/obs-module.rc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 39dc6eaa7..d034f9e31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16...3.25) -if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0) +if(CMAKE_HOST_SYSTEM_NAME MATCHES "(Darwin)" OR OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0) include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake" NO_POLICY_SCOPE) project(obs-studio VERSION ${OBS_VERSION_CANONICAL}) @@ -14,7 +14,6 @@ if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0) include(defaults) include(helpers) - option(ENABLE_RELEASE_BUILD "Enable all options for a release build" OFF) option(ENABLE_UI "Enable building with UI (requires Qt)" ON) option(ENABLE_SCRIPTING "Enable scripting support" ON) option(ENABLE_HEVC "Enable HEVC encoders" ON) diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt index 9a671a4bb..10de47680 100644 --- a/UI/CMakeLists.txt +++ b/UI/CMakeLists.txt @@ -45,11 +45,10 @@ include(cmake/feature-importers.cmake) include(cmake/feature-browserpanels.cmake) if(NOT OAUTH_BASE_URL) - set(OAUTH_BASE_URL - "https://auth.obsproject.com/" - CACHE STRING "Default OAuth base URL") - + # cmake-format: off + set(OAUTH_BASE_URL "https://auth.obsproject.com/" CACHE STRING "Default OAuth base URL") mark_as_advanced(OAUTH_BASE_URL) + # cmake-format: on endif() include(cmake/feature-twitch.cmake) include(cmake/feature-restream.cmake) @@ -109,4 +108,6 @@ foreach(graphics_library IN ITEMS opengl metal d3d11) endif() endforeach() -set_target_properties_obs(obs-studio PROPERTIES FOLDER frontend OUTPUT_NAME obs) +# cmake-format: off +set_target_properties_obs(obs-studio PROPERTIES FOLDER frontend OUTPUT_NAME "$,obs64,obs>") +# cmake-format: on diff --git a/UI/cmake/feature-importers.cmake b/UI/cmake/feature-importers.cmake index 455306c7a..e55620c4a 100644 --- a/UI/cmake/feature-importers.cmake +++ b/UI/cmake/feature-importers.cmake @@ -1,2 +1,2 @@ -target_sources(obs-studio PRIVATE importers/importers.cpp importers/importers.hpp importers/classic.cpp +target_sources(obs-studio PRIVATE importers/classic.cpp importers/importers.cpp importers/importers.hpp importers/sl.cpp importers/studio.cpp importers/xsplit.cpp) diff --git a/UI/cmake/feature-whatsnew.cmake b/UI/cmake/feature-whatsnew.cmake index d87822917..a4d9be6d4 100644 --- a/UI/cmake/feature-whatsnew.cmake +++ b/UI/cmake/feature-whatsnew.cmake @@ -8,7 +8,7 @@ if(ENABLE_WHATSNEW AND TARGET OBS::browser-panels) target_link_libraries(obs-studio PRIVATE MbedTLS::MbedTLS OBS::blake2) target_sources( - obs-studio PRIVATE update/crypto-helpers.hpp update/crypto-helpers-mbedtls.cpp update/shared-update.cpp + obs-studio PRIVATE update/crypto-helpers-mbedtls.cpp update/crypto-helpers.hpp update/shared-update.cpp update/shared-update.hpp update/update-helpers.cpp update/update-helpers.hpp) endif() diff --git a/UI/cmake/feature-youtube.cmake b/UI/cmake/feature-youtube.cmake index 1fbdd0f74..28a0c2c1e 100644 --- a/UI/cmake/feature-youtube.cmake +++ b/UI/cmake/feature-youtube.cmake @@ -2,8 +2,8 @@ if(YOUTUBE_CLIENTID AND YOUTUBE_SECRET AND YOUTUBE_CLIENTID_HASH AND YOUTUBE_SECRET_HASH) - target_sources(obs-studio PRIVATE auth-youtube.cpp auth-youtube.hpp youtube-api-wrappers.cpp youtube-api-wrappers.hpp - window-youtube-actions.cpp window-youtube-actions.hpp) + target_sources(obs-studio PRIVATE auth-youtube.cpp auth-youtube.hpp window-youtube-actions.cpp + window-youtube-actions.hpp youtube-api-wrappers.cpp youtube-api-wrappers.hpp) target_enable_feature(obs-studio "YouTube API connection" YOUTUBE_ENABLED) else() diff --git a/UI/cmake/os-windows.cmake b/UI/cmake/os-windows.cmake index 67cb6c817..13b194f2e 100644 --- a/UI/cmake/os-windows.cmake +++ b/UI/cmake/os-windows.cmake @@ -29,7 +29,7 @@ target_sources( update/win-update.hpp) target_link_libraries(obs-studio PRIVATE crypt32 OBS::blake2 OBS::w32-pthreads MbedTLS::MbedTLS Detours::Detours) -target_compile_options(obs-studio PRIVATE PSAPI_VERSION=2) +target_compile_definitions(obs-studio PRIVATE PSAPI_VERSION=2) target_link_options(obs-studio PRIVATE /IGNORE:4098 /IGNORE:4099) add_library(obs-update-helpers INTERFACE) @@ -49,8 +49,6 @@ set_property( set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT obs-studio) set_target_properties( obs-studio - PROPERTIES - WIN32_EXECUTABLE TRUE - VS_DEBUGGER_COMMAND - "${CMAKE_BINARY_DIR}/rundir/$/$<$:bin/>$" - VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/rundir/$$<$:/bin>") + PROPERTIES WIN32_EXECUTABLE TRUE + VS_DEBUGGER_COMMAND "${CMAKE_BINARY_DIR}/rundir/$/bin/64bit/$" + VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/rundir/$/bin/64bit") diff --git a/UI/cmake/ui-qt.cmake b/UI/cmake/ui-qt.cmake index 62ae3dbd5..3107f2aae 100644 --- a/UI/cmake/ui-qt.cmake +++ b/UI/cmake/ui-qt.cmake @@ -14,7 +14,7 @@ set_property( PROPERTY AUTOUIC_SEARCH_PATHS forms forms/source-toolbar) set(_qt_sources - forms/obs.qrc + # cmake-format: sortable forms/AutoConfigFinishPage.ui forms/AutoConfigStartPage.ui forms/AutoConfigStartPage.ui @@ -22,6 +22,7 @@ set(_qt_sources forms/AutoConfigTestPage.ui forms/AutoConfigVideoPage.ui forms/ColorSelect.ui + forms/obs.qrc forms/OBSAbout.ui forms/OBSAdvAudio.ui forms/OBSBasic.ui diff --git a/UI/cmake/windows/obs-studio.ico b/UI/cmake/windows/obs-studio.ico new file mode 100644 index 0000000000000000000000000000000000000000..7127372917d0ae308412302998833d60e420fd4f GIT binary patch literal 93455 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

C#Vyy0Xt+}qRZF9tgd$_hM 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 + + OBS Studio + + + + + + + + + + + + + + diff --git a/UI/cmake/windows/obs.rc.in b/UI/cmake/windows/obs.rc.in new file mode 100644 index 000000000..6115c4e52 --- /dev/null +++ b/UI/cmake/windows/obs.rc.in @@ -0,0 +1,26 @@ +IDI_ICON1 ICON DISCARDABLE "cmake/windows/obs-studio.ico" + +1 VERSIONINFO +FILEVERSION ${OBS_VERSION_MAJOR},${OBS_VERSION_MINOR},${OBS_VERSION_PATCH},0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "OBS" + VALUE "FileDescription", "OBS Studio" + VALUE "FileVersion", "${OBS_VERSION_CANONICAL}" + VALUE "InternalName", "obs" + VALUE "OriginalFilename", "obs" + VALUE "ProductName", "OBS Studio" + VALUE "ProductVersion", "${OBS_VERSION_CANONICAL}" + VALUE "Comments", "Free and open source software for video recording and live streaming" + VALUE "LegalCopyright", "${OBS_LEGAL_COPYRIGHT}" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/UI/win-update/updater/CMakeLists.txt b/UI/win-update/updater/CMakeLists.txt index ddff7d15b..6add11d3f 100644 --- a/UI/win-update/updater/CMakeLists.txt +++ b/UI/win-update/updater/CMakeLists.txt @@ -2,13 +2,6 @@ cmake_minimum_required(VERSION 3.24...3.25) legacy_check() -option(ENABLE_UPDATER "Build with Windows updater" ON) - -if(NOT ENABLE_UPDATER) - target_disable_feature(obs "Windows updater") - return() -endif() - find_package(zstd) if(NOT TARGET OBS::json11) @@ -39,4 +32,4 @@ target_include_directories(updater PRIVATE "${CMAKE_SOURCE_DIR}/libobs" "${CMAKE target_link_libraries(updater PRIVATE OBS::blake2 OBS::json11 zstd::libzstd_static comctl32 shell32 winhttp) target_link_options(updater PRIVATE /IGNORE:4098) -set_target_properties_obs(updater PROPERTIES FOLDER frontend OUTPUT_NAME updater) +set_target_properties(updater PROPERTIES FOLDER frontend OUTPUT_NAME updater) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 9e92bb114..90ceeb6be 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -1,7 +1,3 @@ -if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0) - return() -endif() - if(OS_WINDOWS) if(NOT MINGW) add_subdirectory(w32-pthreads) diff --git a/deps/ipc-util/CMakeLists.txt b/deps/ipc-util/CMakeLists.txt index 1742d0f6e..d750129ea 100644 --- a/deps/ipc-util/CMakeLists.txt +++ b/deps/ipc-util/CMakeLists.txt @@ -1,20 +1,14 @@ -project(ipc-util) +cmake_minimum_required(VERSION 3.24...3.25) -add_library(ipc-util STATIC) +# cmake-format: off +add_library(ipc-util STATIC EXCLUDE_FROM_ALL) +# cmake-format: on add_library(OBS::ipc-util ALIAS ipc-util) target_sources(ipc-util PRIVATE ipc-util/pipe.h) +target_include_directories(ipc-util PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") -set_target_properties(ipc-util PROPERTIES FOLDER "deps" POSITION_INDEPENDENT_CODE ON) +target_sources(ipc-util PRIVATE ipc-util/pipe-windows.c ipc-util/pipe-windows.h) +target_compile_options(ipc-util PRIVATE $,/MTd,/MT> /Zl) -target_include_directories(ipc-util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - -if(OS_WINDOWS) - if(MSVC) - target_compile_options(ipc-util PRIVATE "$,/MTd,/MT>" /Zl) - endif() - - target_sources(ipc-util PRIVATE ipc-util/pipe-windows.c ipc-util/pipe-windows.h) -else() - target_sources(ipc-util PRIVATE ipc-util/pipe-posix.c ipc-util/pipe-posic.h) -endif() +set_target_properties(ipc-util PROPERTIES FOLDER deps POSITION_INDEPENDENT_CODE ON) diff --git a/libobs-d3d11/CMakeLists.txt b/libobs-d3d11/CMakeLists.txt index e881ee784..800868e6c 100644 --- a/libobs-d3d11/CMakeLists.txt +++ b/libobs-d3d11/CMakeLists.txt @@ -1,11 +1,16 @@ -project(libobs-d3d11) +cmake_minimum_required(VERSION 3.24...3.25) + +legacy_check() add_library(libobs-d3d11 MODULE) add_library(OBS::libobs-d3d11 ALIAS libobs-d3d11) target_sources( libobs-d3d11 - PRIVATE d3d11-indexbuffer.cpp + PRIVATE # cmake-format: sortable + d3d11-duplicator.cpp + d3d11-indexbuffer.cpp + d3d11-rebuild.cpp d3d11-samplerstate.cpp d3d11-shader.cpp d3d11-shaderprocessor.cpp @@ -16,35 +21,23 @@ target_sources( d3d11-texture2d.cpp d3d11-texture3d.cpp d3d11-vertexbuffer.cpp - d3d11-duplicator.cpp - d3d11-rebuild.cpp d3d11-zstencilbuffer.cpp) -set(MODULE_DESCRIPTION "OBS Library D3D11 wrapper") -configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in libobs-d3d11.rc) - -target_include_directories(libobs-d3d11 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) - +configure_file(cmake/windows/obs-module.rc.in libobs-d3d11.rc) target_sources(libobs-d3d11 PRIVATE libobs-d3d11.rc) - -target_compile_features(libobs-d3d11 PRIVATE cxx_std_17) - -target_compile_definitions(libobs-d3d11 PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) - -if(NOT DEFINED GPU_PRIORITY_VAL - OR "x${GPU_PRIORITY_VAL}x" STREQUAL "xx" - OR "${GPU_PRIORITY_VAL}" STREQUAL "0") - target_compile_definitions(libobs-d3d11 PRIVATE USE_GPU_PRIORITY=FALSE GPU_PRIORITY_VAL=0) -else() - target_compile_definitions(libobs-d3d11 PRIVATE USE_GPU_PRIORITY=TRUE GPU_PRIORITY_VAL=${GPU_PRIORITY_VAL}) -endif() +target_compile_options(libobs-d3d11 PRIVATE /wd4595) +target_compile_definitions( + libobs-d3d11 PRIVATE "$<$:USE_GPU_PRIORITY>" + "$,GPU_PRIORITY_VAL=${GPU_PRIORITY_VAL},GPU_PRIORITY_VAL=0>") target_link_libraries(libobs-d3d11 PRIVATE OBS::libobs d3d9 d3d11 dxgi shcore) -set_target_properties( - libobs-d3d11 - PROPERTIES OUTPUT_NAME libobs-d3d11 - FOLDER "core" - PREFIX "") +target_enable_feature(libobs "Direct3D 11 renderer") -setup_binary_target(libobs-d3d11) +# cmake-format: off +set_target_properties_obs( + libobs-d3d11 + PROPERTIES FOLDER core + VERSION 0 + SOVERSION ${OBS_VERSION_MAJOR}) +# cmake-format: on diff --git a/libobs-d3d11/cmake/legacy.cmake b/libobs-d3d11/cmake/legacy.cmake new file mode 100644 index 000000000..3d5d6cbeb --- /dev/null +++ b/libobs-d3d11/cmake/legacy.cmake @@ -0,0 +1,50 @@ +project(libobs-d3d11) + +add_library(libobs-d3d11 MODULE) +add_library(OBS::libobs-d3d11 ALIAS libobs-d3d11) + +target_sources( + libobs-d3d11 + PRIVATE d3d11-indexbuffer.cpp + d3d11-samplerstate.cpp + d3d11-shader.cpp + d3d11-shaderprocessor.cpp + d3d11-shaderprocessor.hpp + d3d11-stagesurf.cpp + d3d11-subsystem.cpp + d3d11-subsystem.hpp + d3d11-texture2d.cpp + d3d11-texture3d.cpp + d3d11-vertexbuffer.cpp + d3d11-duplicator.cpp + d3d11-rebuild.cpp + d3d11-zstencilbuffer.cpp) + +set(MODULE_DESCRIPTION "OBS Library D3D11 wrapper") +configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in libobs-d3d11.rc) + +target_include_directories(libobs-d3d11 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +target_sources(libobs-d3d11 PRIVATE libobs-d3d11.rc) + +target_compile_features(libobs-d3d11 PRIVATE cxx_std_17) + +target_compile_definitions(libobs-d3d11 PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) + +if(NOT DEFINED GPU_PRIORITY_VAL + OR "x${GPU_PRIORITY_VAL}x" STREQUAL "xx" + OR "${GPU_PRIORITY_VAL}" STREQUAL "0") + target_compile_definitions(libobs-d3d11 PRIVATE GPU_PRIORITY_VAL=0) +else() + target_compile_definitions(libobs-d3d11 PRIVATE USE_GPU_PRIORITY=TRUE GPU_PRIORITY_VAL=${GPU_PRIORITY_VAL}) +endif() + +target_link_libraries(libobs-d3d11 PRIVATE OBS::libobs d3d9 d3d11 dxgi shcore) + +set_target_properties( + libobs-d3d11 + PROPERTIES OUTPUT_NAME libobs-d3d11 + FOLDER "core" + PREFIX "") + +setup_binary_target(libobs-d3d11) diff --git a/libobs-d3d11/cmake/windows/obs-module.rc.in b/libobs-d3d11/cmake/windows/obs-module.rc.in new file mode 100644 index 000000000..ee4ef74b0 --- /dev/null +++ b/libobs-d3d11/cmake/windows/obs-module.rc.in @@ -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 Library D3D11 wrapper" + 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", "libobs-d3d11" + VALUE "OriginalFilename", "libobs-d3d11" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/libobs-d3d11/d3d11-config.h.in b/libobs-d3d11/d3d11-config.h.in deleted file mode 100644 index 26064daad..000000000 --- a/libobs-d3d11/d3d11-config.h.in +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef ON -#define ON 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef OFF -#define OFF 0 -#endif - -#define USE_GPU_PRIORITY @USE_GPU_PRIORITY@ -#define GPU_PRIORITY_VAL @GPU_PRIORITY_VAL@ diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index a60edef30..59b6bb92b 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -473,7 +473,7 @@ static bool increase_maximum_frame_latency(ID3D11Device *device) return true; } -#if USE_GPU_PRIORITY +#ifdef USE_GPU_PRIORITY static bool set_priority(ID3D11Device *device, bool hags_enabled) { ComQIPtr dxgiDevice(device); @@ -688,7 +688,7 @@ void gs_device::InitDevice(uint32_t adapterIdx) } /* adjust gpu thread priority on non-intel GPUs */ -#if USE_GPU_PRIORITY +#ifdef USE_GPU_PRIORITY if (desc.VendorId != 0x8086 && !set_priority(device, hags_enabled)) { blog(LOG_INFO, "D3D11 GPU priority setup " "failed (not admin?)"); diff --git a/libobs-winrt/CMakeLists.txt b/libobs-winrt/CMakeLists.txt index 86f439ec7..2940840c3 100644 --- a/libobs-winrt/CMakeLists.txt +++ b/libobs-winrt/CMakeLists.txt @@ -1,4 +1,12 @@ -project(libobs-winrt) +cmake_minimum_required(VERSION 3.24...3.25) + +legacy_check() + +add_library(libobs-winrt-headers INTERFACE) +add_library(OBS::winrt-headers ALIAS libobs-winrt-headers) + +target_sources(libobs-winrt-headers INTERFACE winrt-capture.h) +target_include_directories(libobs-winrt-headers INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") add_library(libobs-winrt MODULE) add_library(OBS::libobs-winrt ALIAS libobs-winrt) @@ -8,24 +16,18 @@ target_sources(libobs-winrt PRIVATE winrt-capture.cpp winrt-capture.h winrt-disp target_precompile_headers( libobs-winrt PRIVATE - [["../libobs/util/windows/ComPtr.hpp"]] - + + ) -target_link_libraries(libobs-winrt PRIVATE OBS::libobs Dwmapi windowsapp) +target_link_libraries(libobs-winrt PRIVATE OBS::libobs OBS::COMutils Dwmapi windowsapp) -target_compile_features(libobs-winrt PRIVATE cxx_std_17) - -set_target_properties( - libobs-winrt - PROPERTIES OUTPUT_NAME libobs-winrt - FOLDER "core" - PREFIX "") - -setup_binary_target(libobs-winrt) +# cmake-format: off +set_target_properties_obs(libobs-winrt PROPERTIES FOLDER core) +# cmake-format: on diff --git a/libobs-winrt/cmake/legacy.cmake b/libobs-winrt/cmake/legacy.cmake new file mode 100644 index 000000000..86f439ec7 --- /dev/null +++ b/libobs-winrt/cmake/legacy.cmake @@ -0,0 +1,31 @@ +project(libobs-winrt) + +add_library(libobs-winrt MODULE) +add_library(OBS::libobs-winrt ALIAS libobs-winrt) + +target_sources(libobs-winrt PRIVATE winrt-capture.cpp winrt-capture.h winrt-dispatch.cpp winrt-dispatch.h) + +target_precompile_headers( + libobs-winrt + PRIVATE + [["../libobs/util/windows/ComPtr.hpp"]] + + + + + + + + ) + +target_link_libraries(libobs-winrt PRIVATE OBS::libobs Dwmapi windowsapp) + +target_compile_features(libobs-winrt PRIVATE cxx_std_17) + +set_target_properties( + libobs-winrt + PROPERTIES OUTPUT_NAME libobs-winrt + FOLDER "core" + PREFIX "") + +setup_binary_target(libobs-winrt) diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index d7bb1839c..1c092e1b8 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -222,12 +222,11 @@ target_sources( graphics/vec4.c graphics/vec4.h) -target_compile_features(libobs PUBLIC $) -target_compile_options(libobs PUBLIC ${ARCH_SIMD_FLAGS}) +target_compile_features(libobs PUBLIC cxx_std_17) target_compile_definitions( libobs PRIVATE IS_LIBOBS - PUBLIC ${ARCH_SIMD_DEFINES} $:ENABLE_HEVC>> + PUBLIC $:ENABLE_HEVC>> $:SHOW_SUBPROCESSES>>) target_link_libraries( @@ -326,15 +325,14 @@ if(ARCH_SIMD_FLAGS) util/simde/x86/sse2.h) endif() -set_property( - TARGET libobs - APPEND - PROPERTY OBS_PUBLIC_HEADERS ${public_headers}) +# cmake-format: off +set_property(TARGET libobs APPEND PROPERTY OBS_PUBLIC_HEADERS ${public_headers}) set_target_properties_obs( libobs PROPERTIES FOLDER core VERSION 0 SOVERSION "${OBS_VERSION_MAJOR}") +# cmake-format: on target_export(libobs) diff --git a/libobs/cmake/os-freebsd.cmake b/libobs/cmake/os-freebsd.cmake index 76c1d1155..b5c6cd259 100644 --- a/libobs/cmake/os-freebsd.cmake +++ b/libobs/cmake/os-freebsd.cmake @@ -1,20 +1,11 @@ find_package(X11 REQUIRED) find_package(x11-xcb REQUIRED) -find_package( - xcb - OPTIONAL_COMPONENTS xcb-xinput - QUIET) +# cmake-format: off +find_package(xcb OPTIONAL_COMPONENTS xcb-xinput QUIET) +# cmake-format: on find_package(gio) find_package(Sysinfo REQUIRED) -target_link_libraries(libobs PRIVATE X11::x11-xcb xcb::xcb Sysinfo::Sysinfo) - -if(TARGET xcb::xcb-xinput) - target_link_libraries(libobs PRIVATE xcb::xcb-xinput) -endif() - -target_compile_definitions(libobs PRIVATE $<$,$>:ENABLE_DARRAY_TYPE_TEST>) - target_sources( libobs PRIVATE obs-nix.c @@ -25,6 +16,12 @@ target_sources( util/platform-nix.c util/threading-posix.c util/threading-posix.h) +target_compile_definitions(libobs PRIVATE $<$,$>:ENABLE_DARRAY_TYPE_TEST>) + +target_link_libraries(libobs PRIVATE X11::x11-xcb xcb::xcb Sysinfo::Sysinfo) +if(TARGET xcb::xcb-xinput) + target_link_libraries(libobs PRIVATE xcb::xcb-xinput) +endif() if(ENABLE_PULSEAUDIO) find_package(PulseAudio REQUIRED) @@ -36,31 +33,28 @@ if(ENABLE_PULSEAUDIO) audio-monitoring/pulse/pulseaudio-wrapper.h) target_link_libraries(libobs PRIVATE PulseAudio::PulseAudio) - - set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_ENABLED "PulseAudio audio monitoring (Linux)") + target_enable_feature(libobs "PulseAudio audio monitoring (Linux)") else() target_sources(libobs PRIVATE audio-monitoring/null/null-audio-monitoring.c) - set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_DISABLED "PulseAudio audio monitoring (Linux)") + target_disable_feature(libobs "PulseAudio audio monitoring (Linux)") endif() if(TARGET gio::gio) - target_link_libraries(libobs PRIVATE gio::gio) - target_sources(libobs PRIVATE util/platform-nix-dbus.c util/platform-nix-portal.c) + target_link_libraries(libobs PRIVATE gio::gio) endif() if(ENABLE_WAYLAND) - find_package( - Wayland - COMPONENTS Client - REQUIRED) + # cmake-format: off + find_package(Wayland COMPONENTS Client REQUIRED) + # cmake-format: on find_package(xkbcommon REQUIRED) - target_link_libraries(libobs PRIVATE Wayland::Client xkbcommon::xkbcommon) target_sources(libobs PRIVATE obs-nix-wayland.c) - set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_ENABLED "Wayland compositor support (Linux)") + target_link_libraries(libobs PRIVATE Wayland::Client xkbcommon::xkbcommon) + target_enable_feature(libobs "Wayland compositor support (Linux)") else() - set_property(GLOBAL APPEND PROPERTY OBS_FEATURES_DISABLED "Wayland compositor support (Linux)") + target_disable_feature(libobs "Wayland compositor support (Linux)") endif() set_target_properties(libobs PROPERTIES OUTPUT_NAME obs) diff --git a/libobs/cmake/os-linux.cmake b/libobs/cmake/os-linux.cmake index 4e1f7ea4a..9aa825f4c 100644 --- a/libobs/cmake/os-linux.cmake +++ b/libobs/cmake/os-linux.cmake @@ -1,24 +1,11 @@ -cmake_minimum_required(VERSION 3.22...3.25) - find_package(LibUUID REQUIRED) find_package(X11 REQUIRED) find_package(x11-xcb REQUIRED) -find_package( - xcb - COMPONENTS xcb - OPTIONAL_COMPONENTS xcb-xinput - QUIET) +# cmake-format: off +find_package(xcb COMPONENTS xcb OPTIONAL_COMPONENTS xcb-xinput QUIET) +# cmake-format: on find_package(gio) -target_link_libraries(libobs PRIVATE X11::x11-xcb xcb::xcb LibUUID::LibUUID ${CMAKE_DL_LIBS}) - -if(TARGET xcb::xcb-xinput) - target_link_libraries(libobs PRIVATE xcb::xcb-xinput) -endif() - -target_compile_definitions(libobs PRIVATE USE_XDG - $<$,$>:ENABLE_DARRAY_TYPE_TEST>) - target_sources( libobs PRIVATE obs-nix.c @@ -30,6 +17,13 @@ target_sources( util/threading-posix.c util/threading-posix.h) +target_compile_definitions(libobs PRIVATE USE_XDG $<$:ENABLE_DARRAY_TYPE_TEST>) + +target_link_libraries(libobs PRIVATE X11::x11-xcb xcb::xcb LibUUID::LibUUID ${CMAKE_DL_LIBS}) +if(TARGET xcb::xcb-xinput) + target_link_libraries(libobs PRIVATE xcb::xcb-xinput) +endif() + if(ENABLE_PULSEAUDIO) find_package(PulseAudio REQUIRED) @@ -40,7 +34,6 @@ if(ENABLE_PULSEAUDIO) audio-monitoring/pulse/pulseaudio-wrapper.h) target_link_libraries(libobs PRIVATE PulseAudio::PulseAudio) - target_enable_feature(libobs "PulseAudio audio monitoring (Linux)") else() target_sources(libobs PRIVATE audio-monitoring/null/null-audio-monitoring.c) @@ -48,20 +41,18 @@ else() endif() if(TARGET gio::gio) - target_link_libraries(libobs PRIVATE gio::gio) - target_sources(libobs PRIVATE util/platform-nix-dbus.c util/platform-nix-portal.c) + target_link_libraries(libobs PRIVATE gio::gio) endif() if(ENABLE_WAYLAND) - find_package( - Wayland - COMPONENTS Client - REQUIRED) + # cmake-format: off + find_package(Wayland COMPONENTS Client REQUIRED) + # cmake-format: on find_package(xkbcommon REQUIRED) - target_link_libraries(libobs PRIVATE Wayland::Client xkbcommon::xkbcommon) target_sources(libobs PRIVATE obs-nix-wayland.c) + target_link_libraries(libobs PRIVATE Wayland::Client xkbcommon::xkbcommon) target_enable_feature(libobs "Wayland compositor support (Linux)") else() target_disable_feature(libobs "Wayland compositor support (Linux)") diff --git a/libobs/cmake/os-windows.cmake b/libobs/cmake/os-windows.cmake index dd3b77da3..04500d1b0 100644 --- a/libobs/cmake/os-windows.cmake +++ b/libobs/cmake/os-windows.cmake @@ -57,4 +57,4 @@ target_link_libraries( target_link_options(libobs PRIVATE /IGNORE:4098 /SAFESEH:NO) -set_target_properties(libobs PROPERTIES PREFIX "") +set_target_properties(libobs PROPERTIES PREFIX "" OUTPUT_NAME "obs") diff --git a/libobs/obs-windows.c b/libobs/obs-windows.c index 4c0da5483..3f08795b6 100644 --- a/libobs/obs-windows.c +++ b/libobs/obs-windows.c @@ -34,15 +34,7 @@ const char *get_module_extension(void) return ".dll"; } -#ifdef _WIN64 -#define BIT_STRING "64bit" -#else -#define BIT_STRING "32bit" -#endif - -static const char *module_bin[] = { - "../../obs-plugins/" BIT_STRING, -}; +static const char *module_bin[] = {"../../obs-plugins/64bit"}; static const char *module_data[] = {"../../data/obs-plugins/%module%"}; diff --git a/plugins/coreaudio-encoder/CMakeLists.txt b/plugins/coreaudio-encoder/CMakeLists.txt index 6f744a4ea..554b9d37b 100644 --- a/plugins/coreaudio-encoder/CMakeLists.txt +++ b/plugins/coreaudio-encoder/CMakeLists.txt @@ -17,10 +17,7 @@ target_sources(coreaudio-encoder PRIVATE encoder.cpp) target_link_libraries(coreaudio-encoder PRIVATE OBS::libobs) if(OS_WINDOWS) - target_compile_definitions(coreaudio-encoder PRIVATE UNICODE _UNICODE) - configure_file(cmake/windows/obs-module.rc.in coreaudio-encoder.rc) - target_sources(coreaudio-encoder PRIVATE coreaudio-encoder.rc windows-imports.h) elseif(OS_MACOS) # cmake-format: off diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt index 92420436b..00485dda7 100644 --- a/plugins/obs-ffmpeg/CMakeLists.txt +++ b/plugins/obs-ffmpeg/CMakeLists.txt @@ -30,19 +30,21 @@ add_subdirectory(ffmpeg-mux) target_sources( obs-ffmpeg - PRIVATE obs-ffmpeg.c - obs-ffmpeg-video-encoders.c + PRIVATE # cmake-format: sortable + $<$:obs-ffmpeg-logging.c> obs-ffmpeg-audio-encoders.c obs-ffmpeg-av1.c - obs-ffmpeg-nvenc.c - obs-ffmpeg-output.c - obs-ffmpeg-mux.c - obs-ffmpeg-mux.h - obs-ffmpeg-hls-mux.c - obs-ffmpeg-source.c obs-ffmpeg-compat.h obs-ffmpeg-formats.h - $<$:obs-ffmpeg-logging.c>) + obs-ffmpeg-hls-mux.c + obs-ffmpeg-mux.c + obs-ffmpeg-mux.h + obs-ffmpeg-nvenc.c + obs-ffmpeg-output.c + obs-ffmpeg-source.c + obs-ffmpeg-video-encoders.c + obs-ffmpeg.c) + target_compile_definitions(obs-ffmpeg PRIVATE $<$:ENABLE_FFMPEG_LOGGING>) target_link_libraries( @@ -85,21 +87,20 @@ if(OS_WINDOWS) find_package(AMF 1.4.29 REQUIRED) find_package(FFnvcodec 12 REQUIRED) + add_library(obs-nvenc-version INTERFACE) + add_library(OBS::obs-nvenc-version ALIAS obs-nvenc-version) + target_sources(obs-nvenc-version INTERFACE obs-nvenc-ver.h) + target_include_directories(obs-nvenc-version INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") + add_subdirectory(obs-amf-test) add_subdirectory(obs-nvenc-test) - target_link_libraries(obs-ffmpeg PRIVATE OBS::w32-pthreads AMF::AMF FFnvcodec::FFnvcodec ws2_32) + target_link_libraries(obs-ffmpeg PRIVATE OBS::obs-nvenc-version OBS::w32-pthreads AMF::AMF FFnvcodec::FFnvcodec + ws2_32) configure_file(cmake/windows/obs-module.rc.in obs-ffmpeg.rc) - target_sources( - obs-ffmpeg - PRIVATE texture-amf.cpp - texture-amf-opts.hpp - obs-nvenc.c - obs-nvenc.h - obs-nvenc-helpers.c - obs-nvenc-ver.h - obs-ffmpeg.rc) + target_sources(obs-ffmpeg PRIVATE obs-nvenc-helpers.c obs-nvenc.c obs-nvenc.h obs-ffmpeg.rc texture-amf-opts.hpp + texture-amf.cpp) elseif(OS_LINUX OR OS_FREEBSD) find_package(Libva REQUIRED) find_package(Libpci REQUIRED) @@ -108,4 +109,6 @@ elseif(OS_LINUX OR OS_FREEBSD) target_link_libraries(obs-ffmpeg PRIVATE Libva::va Libva::drm Libpci::pci) endif() +# cmake-format: off set_target_properties_obs(obs-ffmpeg PROPERTIES FOLDER plugins/obs-ffmpeg PREFIX "") +# cmake-format: on diff --git a/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt b/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt index e00cef1cf..6221c69df 100644 --- a/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt +++ b/plugins/obs-ffmpeg/obs-amf-test/CMakeLists.txt @@ -1,14 +1,15 @@ -project(obs-amf-test) +cmake_minimum_required(VERSION 3.24...3.25) -add_executable(obs-amf-test) +legacy_check() find_package(AMF 1.4.29 REQUIRED) -target_include_directories(obs-amf-test PRIVATE ${CMAKE_SOURCE_DIR}/libobs) +add_executable(obs-amf-test) +add_executable(OBS::amf-test ALIAS obs-amf-test) target_sources(obs-amf-test PRIVATE obs-amf-test.cpp) -target_link_libraries(obs-amf-test d3d11 dxgi dxguid AMF::AMF) +target_link_libraries(obs-amf-test PRIVATE OBS::COMutils AMF::AMF d3d11 dxgi dxguid) -set_target_properties(obs-amf-test PROPERTIES FOLDER "plugins/obs-ffmpeg") - -setup_binary_target(obs-amf-test) +# cmake-format: off +set_target_properties_obs(obs-amf-test PROPERTIES FOLDER plugins/obs-ffmpeg) +# cmake-format: on diff --git a/plugins/obs-ffmpeg/obs-amf-test/cmake/legacy.cmake b/plugins/obs-ffmpeg/obs-amf-test/cmake/legacy.cmake new file mode 100644 index 000000000..e00cef1cf --- /dev/null +++ b/plugins/obs-ffmpeg/obs-amf-test/cmake/legacy.cmake @@ -0,0 +1,14 @@ +project(obs-amf-test) + +add_executable(obs-amf-test) + +find_package(AMF 1.4.29 REQUIRED) + +target_include_directories(obs-amf-test PRIVATE ${CMAKE_SOURCE_DIR}/libobs) + +target_sources(obs-amf-test PRIVATE obs-amf-test.cpp) +target_link_libraries(obs-amf-test d3d11 dxgi dxguid AMF::AMF) + +set_target_properties(obs-amf-test PROPERTIES FOLDER "plugins/obs-ffmpeg") + +setup_binary_target(obs-amf-test) diff --git a/plugins/obs-ffmpeg/obs-nvenc-test/CMakeLists.txt b/plugins/obs-ffmpeg/obs-nvenc-test/CMakeLists.txt index 9bffa73e7..351a2e055 100644 --- a/plugins/obs-ffmpeg/obs-nvenc-test/CMakeLists.txt +++ b/plugins/obs-ffmpeg/obs-nvenc-test/CMakeLists.txt @@ -1,12 +1,14 @@ -project(obs-nvenc-test) +cmake_minimum_required(VERSION 3.24...3.25) -add_executable(obs-nvenc-test) +legacy_check() find_package(FFnvcodec 12 REQUIRED) -target_sources(obs-nvenc-test PRIVATE obs-nvenc-test.c ../obs-nvenc-ver.h) -target_link_libraries(obs-nvenc-test d3d11 dxgi dxguid FFnvcodec::FFnvcodec) +add_executable(obs-nvenc-test) -set_target_properties(obs-nvenc-test PROPERTIES FOLDER "plugins/obs-ffmpeg") +target_sources(obs-nvenc-test PRIVATE obs-nvenc-test.c) +target_link_libraries(obs-nvenc-test OBS::obs-nvenc-version FFnvcodec::FFnvcodec d3d11 dxgi dxguid) -setup_binary_target(obs-nvenc-test) +# cmake-format: off +set_target_properties_obs(obs-nvenc-test PROPERTIES FOLDER plugins/obs-ffmpeg) +# cmake-format: on diff --git a/plugins/obs-ffmpeg/obs-nvenc-test/cmake/legacy.cmake b/plugins/obs-ffmpeg/obs-nvenc-test/cmake/legacy.cmake new file mode 100644 index 000000000..9bffa73e7 --- /dev/null +++ b/plugins/obs-ffmpeg/obs-nvenc-test/cmake/legacy.cmake @@ -0,0 +1,12 @@ +project(obs-nvenc-test) + +add_executable(obs-nvenc-test) + +find_package(FFnvcodec 12 REQUIRED) + +target_sources(obs-nvenc-test PRIVATE obs-nvenc-test.c ../obs-nvenc-ver.h) +target_link_libraries(obs-nvenc-test d3d11 dxgi dxguid FFnvcodec::FFnvcodec) + +set_target_properties(obs-nvenc-test PROPERTIES FOLDER "plugins/obs-ffmpeg") + +setup_binary_target(obs-nvenc-test) diff --git a/plugins/obs-ffmpeg/obs-nvenc-test/obs-nvenc-test.c b/plugins/obs-ffmpeg/obs-nvenc-test/obs-nvenc-test.c index ccc5ecd99..7d8e75183 100644 --- a/plugins/obs-ffmpeg/obs-nvenc-test/obs-nvenc-test.c +++ b/plugins/obs-ffmpeg/obs-nvenc-test/obs-nvenc-test.c @@ -3,7 +3,11 @@ #include #include +#ifdef OBS_LEGACY #include "../obs-nvenc-ver.h" +#else +#include +#endif #include #include diff --git a/plugins/obs-outputs/cmake/ftl.cmake b/plugins/obs-outputs/cmake/ftl.cmake index 19777368a..65b8da5f7 100644 --- a/plugins/obs-outputs/cmake/ftl.cmake +++ b/plugins/obs-outputs/cmake/ftl.cmake @@ -10,20 +10,21 @@ target_link_libraries(ftl-sdk INTERFACE jansson::jansson CURL::libcurl) target_sources( ftl-sdk - INTERFACE ftl-stream.c + INTERFACE # cmake-format: sortable + ftl-sdk/libftl/ftl-sdk.c ftl-sdk/libftl/ftl.h + ftl-sdk/libftl/ftl_helpers.c ftl-sdk/libftl/ftl_private.h + ftl-sdk/libftl/gettimeofday/gettimeofday.c + ftl-sdk/libftl/handshake.c ftl-sdk/libftl/hmac/hmac.c ftl-sdk/libftl/hmac/hmac.h ftl-sdk/libftl/hmac/sha2.c ftl-sdk/libftl/hmac/sha2.h - ftl-sdk/libftl/ftl-sdk.c - ftl-sdk/libftl/handshake.c ftl-sdk/libftl/ingest.c - ftl-sdk/libftl/ftl_helpers.c + ftl-sdk/libftl/logging.c ftl-sdk/libftl/media.c - ftl-sdk/libftl/gettimeofday/gettimeofday.c - ftl-sdk/libftl/logging.c) + ftl-stream.c) target_include_directories(ftl-sdk INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/ftl-sdk/libftl") @@ -45,29 +46,25 @@ target_link_libraries(obs-outputs PRIVATE ftl-sdk) target_enable_feature(obs-outputs "FTL protocol support") get_target_property(target_sources ftl-sdk INTERFACE_SOURCES) -list( - APPEND - silence_ftl - -Wno-unused-parameter - -Wno-unused-variable - -Wno-sign-compare - -Wno-pointer-sign - -Wno-int-conversion) -if(CMAKE_C_COMPILER_ID STREQUAL AppleClang OR CMAKE_C_COMPILER_ID STREQUAL Clang) - list(APPEND silence_ftl -Wno-incompatible-function-pointer-types -Wno-implicit-int-conversion -Wno-shorten-64-to-32 - -Wno-macro-redefined) -elseif(CMAKE_C_COMPILER_ID STREQUAL GNU) - list(APPEND silence_ftl -Wno-error=extra -Wno-error=incompatible-pointer-types -Wno-error=int-conversion - -Wno-error=builtin-macro-redefined) +if(NOT CMAKE_C_COMPILER_ID STREQUAL "MSVC") + set(silence_ftl -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=sign-compare + -Wno-error=pointer-sign -Wno-error=int-conversion) + + if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?Clang") + list(APPEND silence_ftl -Wno-error=incompatible-function-pointer-types -Wno-error=implicit-int-conversion + -Wno-shorten-64-to-32 -Wno-macro-redefined) + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") + list(APPEND silence_ftl -Wno-error=extra -Wno-error=incompatible-pointer-types -Wno-error=int-conversion + -Wno-error=builtin-macro-redefined) + endif() + + if((NOT CMAKE_C_COMPILER_ID STREQUAL "GNU") OR CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10) + list(APPEND silence_ftl -Wno-error=enum-conversion) + endif() + set_source_files_properties(${target_sources} PROPERTIES COMPILE_OPTIONS "${silence_ftl}") endif() -if((NOT CMAKE_C_COMPILER_ID STREQUAL GNU) OR CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 10) - list(APPEND silence_ftl -Wno-error=enum-conversion) -endif() - -set_source_files_properties(${target_sources} PROPERTIES COMPILE_OPTIONS "${silence_ftl}") - set(target_headers ${target_sources}) list(FILTER target_sources INCLUDE REGEX ".+ftl-sdk/.+\\.(m|c[cp]?p?|swift)") list(FILTER target_headers INCLUDE REGEX ".+ftl-sdk/.+\\.h(pp)?") diff --git a/plugins/obs-qsv11/CMakeLists.txt b/plugins/obs-qsv11/CMakeLists.txt index 3d3777961..87aeaa33b 100644 --- a/plugins/obs-qsv11/CMakeLists.txt +++ b/plugins/obs-qsv11/CMakeLists.txt @@ -1,47 +1,20 @@ -option(ENABLE_QSV11 "Build Intel QSV11 Hardware Encoder." TRUE) +cmake_minimum_required(VERSION 3.24...3.25) +legacy_check() + +option(ENABLE_QSV11 "Build Intel QSV11 Hardware Encoder." TRUE) if(NOT ENABLE_QSV11) - obs_status(DISABLED "obs-qsv11") + target_disable_feature(obs-qsv11 "Intel QSV11 Hardware Encoder") + target_disable(obs-qsv11) return() endif() -project(obs-qsv11) - -add_library(obs-qsv11 MODULE) -add_library(OBS::qsv11 ALIAS obs-qsv11) - add_library(libmfx INTERFACE) add_library(OBS::libmfx ALIAS libmfx) target_sources( libmfx - INTERFACE libmfx/src/main.cpp - libmfx/src/mfx_critical_section.cpp - libmfx/src/mfx_dispatcher.cpp - libmfx/src/mfx_dispatcher_log.cpp - libmfx/src/mfx_driver_store_loader.cpp - libmfx/src/mfx_dxva2_device.cpp - libmfx/src/mfx_function_table.cpp - libmfx/src/mfx_library_iterator.cpp - libmfx/src/mfx_load_dll.cpp - libmfx/src/mfx_load_plugin.cpp - libmfx/src/mfx_plugin_hive.cpp - libmfx/src/mfx_win_reg_key.cpp - libmfx/include/msdk/include/mfxadapter.h - libmfx/include/msdk/include/mfxastructures.h - libmfx/include/msdk/include/mfxaudio.h - libmfx/include/msdk/include/mfxaudio++.h - libmfx/include/msdk/include/mfxcommon.h - libmfx/include/msdk/include/mfxdefs.h - libmfx/include/msdk/include/mfxjpeg.h - libmfx/include/msdk/include/mfxmvc.h - libmfx/include/msdk/include/mfxplugin.h - libmfx/include/msdk/include/mfxplugin++.h - libmfx/include/msdk/include/mfxsession.h - libmfx/include/msdk/include/mfxstructures.h - libmfx/include/msdk/include/mfxvideo.h - libmfx/include/msdk/include/mfxvideo++.h - libmfx/include/msdk/include/mfxvstructures.h + INTERFACE # cmake-format: sortable libmfx/include/mfx_critical_section.h libmfx/include/mfx_dispatcher.h libmfx/include/mfx_dispatcher_defs.h @@ -55,30 +28,66 @@ target_sources( libmfx/include/mfx_plugin_hive.h libmfx/include/mfx_vector.h libmfx/include/mfx_win_reg_key.h - libmfx/include/mfxaudio_exposed_functions_list.h) + libmfx/include/mfxaudio_exposed_functions_list.h + libmfx/include/msdk/include/mfxadapter.h + libmfx/include/msdk/include/mfxastructures.h + libmfx/include/msdk/include/mfxaudio++.h + libmfx/include/msdk/include/mfxaudio.h + libmfx/include/msdk/include/mfxcommon.h + libmfx/include/msdk/include/mfxdefs.h + libmfx/include/msdk/include/mfxjpeg.h + libmfx/include/msdk/include/mfxmvc.h + libmfx/include/msdk/include/mfxplugin++.h + libmfx/include/msdk/include/mfxplugin.h + libmfx/include/msdk/include/mfxsession.h + libmfx/include/msdk/include/mfxstructures.h + libmfx/include/msdk/include/mfxvideo++.h + libmfx/include/msdk/include/mfxvideo.h + libmfx/include/msdk/include/mfxvstructures.h + libmfx/src/main.cpp + libmfx/src/mfx_critical_section.cpp + libmfx/src/mfx_dispatcher.cpp + libmfx/src/mfx_dispatcher_log.cpp + libmfx/src/mfx_driver_store_loader.cpp + libmfx/src/mfx_dxva2_device.cpp + libmfx/src/mfx_function_table.cpp + libmfx/src/mfx_library_iterator.cpp + libmfx/src/mfx_load_dll.cpp + libmfx/src/mfx_load_plugin.cpp + libmfx/src/mfx_plugin_hive.cpp + libmfx/src/mfx_win_reg_key.cpp) -target_include_directories(libmfx INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include/msdk/include - ${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include) +target_include_directories(libmfx INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include/msdk/include" + "${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include") + +add_library(obs-qsv11 MODULE) +add_library(OBS::qsv11 ALIAS obs-qsv11) target_sources( obs-qsv11 - PRIVATE obs-qsv11.c - obs-qsv11-plugin-main.c - common_directx9.cpp - common_directx9.h + PRIVATE # cmake-format: sortable + bits/linux_defs.h + bits/windows_defs.h common_directx11.cpp common_directx11.h + common_directx9.cpp + common_directx9.h common_utils.cpp common_utils.h common_utils_windows.cpp device_directx9.cpp device_directx9.h + obs-qsv11-plugin-main.c + obs-qsv11.c QSV_Encoder.cpp QSV_Encoder.h QSV_Encoder_Internal.cpp - QSV_Encoder_Internal.h - bits/linux_defs.h - bits/windows_defs.h) + QSV_Encoder_Internal.h) + +configure_file(cmake/windows/obs-module.rc.in obs-qsv11.rc) +target_sources(obs-qsv11 PRIVATE obs-qsv11.rc) + +target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D) target_link_libraries( obs-qsv11 @@ -90,36 +99,14 @@ target_link_libraries( dxgi dxguid) -target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D) +add_subdirectory(obs-qsv-test) -if(OS_WINDOWS) - add_subdirectory(obs-qsv-test) +# cmake-format: off +set_target_properties_obs(obs-qsv11 PROPERTIES FOLDER plugins/obs-qsv11 PREFIX "") +# cmake-format: on - set(MODULE_DESCRIPTION "OBS QSV encoder") - configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in obs-qsv11.rc) - - target_sources(obs-qsv11 PRIVATE obs-qsv11.rc) - - target_compile_definitions(obs-qsv11 PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) -endif() - -set_target_properties(obs-qsv11 PROPERTIES FOLDER "plugins/obs-qsv11") - -file(GLOB _OBS_QSV11_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) -file(GLOB _OBS_QSV11_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) - -source_group("obs-qsv11\\Source Files" FILES ${_OBS_QSV11_SOURCE_FILES}) -source_group("obs-qsv11\\Header Files" FILES ${_OBS_QSV11_HEADER_FILES}) - -get_target_property(_LIBMFX_SOURCES OBS::libmfx INTERFACE_SOURCES) - -foreach(_LIBMFX_SOURCE ${_LIBMFX_SOURCES}) - get_filename_component(_EXT ${_LIBMFX_SOURCE} EXT) - if(${_EXT} STREQUAL "hpp" OR ${_EXT} STREQUAL "h") - source_group("libmfx\\Header Files" FILES ${_LIBMFX_SOURCE}) - elseif(${_EXT} STREQUAL "cpp" OR ${_EXT} STREQUAL "c") - source_group("libmfx\\Source Files" FILES ${_LIBMFX_SOURCE}) - endif() -endforeach() - -setup_plugin_target(obs-qsv11) +get_target_property(target_sources libmfx SOURCES) +list(FILTER target_sources INCLUDE REGEX ".*\\.(m|c[cp]?p?|swift)") +list(FILTER target_headers INCLUDE REGEX ".*\\.h(pp)?") +source_group("libmfx\\Source Files" FILES ${target_sources}) +source_group("libmfx\\Header Files" FILES ${target_headers}) diff --git a/plugins/obs-qsv11/cmake/legacy.cmake b/plugins/obs-qsv11/cmake/legacy.cmake new file mode 100644 index 000000000..3d3777961 --- /dev/null +++ b/plugins/obs-qsv11/cmake/legacy.cmake @@ -0,0 +1,125 @@ +option(ENABLE_QSV11 "Build Intel QSV11 Hardware Encoder." TRUE) + +if(NOT ENABLE_QSV11) + obs_status(DISABLED "obs-qsv11") + return() +endif() + +project(obs-qsv11) + +add_library(obs-qsv11 MODULE) +add_library(OBS::qsv11 ALIAS obs-qsv11) + +add_library(libmfx INTERFACE) +add_library(OBS::libmfx ALIAS libmfx) + +target_sources( + libmfx + INTERFACE libmfx/src/main.cpp + libmfx/src/mfx_critical_section.cpp + libmfx/src/mfx_dispatcher.cpp + libmfx/src/mfx_dispatcher_log.cpp + libmfx/src/mfx_driver_store_loader.cpp + libmfx/src/mfx_dxva2_device.cpp + libmfx/src/mfx_function_table.cpp + libmfx/src/mfx_library_iterator.cpp + libmfx/src/mfx_load_dll.cpp + libmfx/src/mfx_load_plugin.cpp + libmfx/src/mfx_plugin_hive.cpp + libmfx/src/mfx_win_reg_key.cpp + libmfx/include/msdk/include/mfxadapter.h + libmfx/include/msdk/include/mfxastructures.h + libmfx/include/msdk/include/mfxaudio.h + libmfx/include/msdk/include/mfxaudio++.h + libmfx/include/msdk/include/mfxcommon.h + libmfx/include/msdk/include/mfxdefs.h + libmfx/include/msdk/include/mfxjpeg.h + libmfx/include/msdk/include/mfxmvc.h + libmfx/include/msdk/include/mfxplugin.h + libmfx/include/msdk/include/mfxplugin++.h + libmfx/include/msdk/include/mfxsession.h + libmfx/include/msdk/include/mfxstructures.h + libmfx/include/msdk/include/mfxvideo.h + libmfx/include/msdk/include/mfxvideo++.h + libmfx/include/msdk/include/mfxvstructures.h + libmfx/include/mfx_critical_section.h + libmfx/include/mfx_dispatcher.h + libmfx/include/mfx_dispatcher_defs.h + libmfx/include/mfx_dispatcher_log.h + libmfx/include/mfx_driver_store_loader.h + libmfx/include/mfx_dxva2_device.h + libmfx/include/mfx_exposed_functions_list.h + libmfx/include/mfx_library_iterator.h + libmfx/include/mfx_load_dll.h + libmfx/include/mfx_load_plugin.h + libmfx/include/mfx_plugin_hive.h + libmfx/include/mfx_vector.h + libmfx/include/mfx_win_reg_key.h + libmfx/include/mfxaudio_exposed_functions_list.h) + +target_include_directories(libmfx INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include/msdk/include + ${CMAKE_CURRENT_SOURCE_DIR}/libmfx/include) + +target_sources( + obs-qsv11 + PRIVATE obs-qsv11.c + obs-qsv11-plugin-main.c + common_directx9.cpp + common_directx9.h + common_directx11.cpp + common_directx11.h + common_utils.cpp + common_utils.h + common_utils_windows.cpp + device_directx9.cpp + device_directx9.h + QSV_Encoder.cpp + QSV_Encoder.h + QSV_Encoder_Internal.cpp + QSV_Encoder_Internal.h + bits/linux_defs.h + bits/windows_defs.h) + +target_link_libraries( + obs-qsv11 + PRIVATE OBS::libobs + OBS::libmfx + d3d9 + d3d11 + dxva2 + dxgi + dxguid) + +target_compile_definitions(obs-qsv11 PRIVATE DX11_D3D) + +if(OS_WINDOWS) + add_subdirectory(obs-qsv-test) + + set(MODULE_DESCRIPTION "OBS QSV encoder") + configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in obs-qsv11.rc) + + target_sources(obs-qsv11 PRIVATE obs-qsv11.rc) + + target_compile_definitions(obs-qsv11 PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) +endif() + +set_target_properties(obs-qsv11 PROPERTIES FOLDER "plugins/obs-qsv11") + +file(GLOB _OBS_QSV11_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.c ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) +file(GLOB _OBS_QSV11_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp) + +source_group("obs-qsv11\\Source Files" FILES ${_OBS_QSV11_SOURCE_FILES}) +source_group("obs-qsv11\\Header Files" FILES ${_OBS_QSV11_HEADER_FILES}) + +get_target_property(_LIBMFX_SOURCES OBS::libmfx INTERFACE_SOURCES) + +foreach(_LIBMFX_SOURCE ${_LIBMFX_SOURCES}) + get_filename_component(_EXT ${_LIBMFX_SOURCE} EXT) + if(${_EXT} STREQUAL "hpp" OR ${_EXT} STREQUAL "h") + source_group("libmfx\\Header Files" FILES ${_LIBMFX_SOURCE}) + elseif(${_EXT} STREQUAL "cpp" OR ${_EXT} STREQUAL "c") + source_group("libmfx\\Source Files" FILES ${_LIBMFX_SOURCE}) + endif() +endforeach() + +setup_plugin_target(obs-qsv11) diff --git a/plugins/obs-qsv11/cmake/windows/obs-module.rc.in b/plugins/obs-qsv11/cmake/windows/obs-module.rc.in new file mode 100644 index 000000000..d3d129c16 --- /dev/null +++ b/plugins/obs-qsv11/cmake/windows/obs-module.rc.in @@ -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 QSV encoder" + 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", "obs-qsv11" + VALUE "OriginalFilename", "obs-qsv11" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/plugins/obs-qsv11/obs-qsv-test/CMakeLists.txt b/plugins/obs-qsv11/obs-qsv-test/CMakeLists.txt index 467f23c81..8659465ed 100644 --- a/plugins/obs-qsv11/obs-qsv-test/CMakeLists.txt +++ b/plugins/obs-qsv11/obs-qsv-test/CMakeLists.txt @@ -1,11 +1,12 @@ -project(obs-qsv-test) +cmake_minimum_required(VERSION 3.24...3.25) -include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/libobs) +legacy_check() add_executable(obs-qsv-test) + target_sources(obs-qsv-test PRIVATE obs-qsv-test.cpp) -target_link_libraries(obs-qsv-test d3d11 dxgi dxguid OBS::libmfx) +target_link_libraries(obs-qsv-test d3d11 dxgi dxguid OBS::libmfx OBS::COMutils) -set_target_properties(obs-qsv-test PROPERTIES FOLDER "plugins/obs-qsv11") - -setup_binary_target(obs-qsv-test) +# cmake-format: off +set_target_properties_obs(obs-qsv-test PROPERTIES FOLDER plugins/obs-qsv11 PREFIX "") +# cmake-format: on diff --git a/plugins/obs-qsv11/obs-qsv-test/cmake/legacy.cmake b/plugins/obs-qsv11/obs-qsv-test/cmake/legacy.cmake new file mode 100644 index 000000000..467f23c81 --- /dev/null +++ b/plugins/obs-qsv11/obs-qsv-test/cmake/legacy.cmake @@ -0,0 +1,11 @@ +project(obs-qsv-test) + +include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/libobs) + +add_executable(obs-qsv-test) +target_sources(obs-qsv-test PRIVATE obs-qsv-test.cpp) +target_link_libraries(obs-qsv-test d3d11 dxgi dxguid OBS::libmfx) + +set_target_properties(obs-qsv-test PROPERTIES FOLDER "plugins/obs-qsv11") + +setup_binary_target(obs-qsv-test) diff --git a/plugins/obs-text/CMakeLists.txt b/plugins/obs-text/CMakeLists.txt index 0bca288ba..cd0f1fdaa 100644 --- a/plugins/obs-text/CMakeLists.txt +++ b/plugins/obs-text/CMakeLists.txt @@ -1,19 +1,16 @@ -project(obs-text) +cmake_minimum_required(VERSION 3.24...3.25) + +legacy_check() add_library(obs-text MODULE) add_library(OBS::text ALIAS obs-text) -target_link_libraries(obs-text PRIVATE OBS::libobs) - -set_target_properties(obs-text PROPERTIES FOLDER "plugins") - -set(MODULE_DESCRIPTION "OBS GDI+ text module") -configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in obs-text.rc) +configure_file(cmake/windows/obs-module.rc.in obs-text.rc) target_sources(obs-text PRIVATE gdiplus/obs-text.cpp obs-text.rc) -target_link_libraries(obs-text PRIVATE gdiplus) +target_link_libraries(obs-text PRIVATE OBS::libobs gdiplus) -target_compile_definitions(obs-text PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) - -setup_plugin_target(obs-text) +# cmake-format: off +set_target_properties_obs(obs-text PROPERTIES FOLDER plugins PREFIX "") +# cmake-format: on diff --git a/plugins/obs-text/cmake/legacy.cmake b/plugins/obs-text/cmake/legacy.cmake new file mode 100644 index 000000000..0bca288ba --- /dev/null +++ b/plugins/obs-text/cmake/legacy.cmake @@ -0,0 +1,19 @@ +project(obs-text) + +add_library(obs-text MODULE) +add_library(OBS::text ALIAS obs-text) + +target_link_libraries(obs-text PRIVATE OBS::libobs) + +set_target_properties(obs-text PROPERTIES FOLDER "plugins") + +set(MODULE_DESCRIPTION "OBS GDI+ text module") +configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in obs-text.rc) + +target_sources(obs-text PRIVATE gdiplus/obs-text.cpp obs-text.rc) + +target_link_libraries(obs-text PRIVATE gdiplus) + +target_compile_definitions(obs-text PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) + +setup_plugin_target(obs-text) diff --git a/plugins/obs-text/cmake/windows/obs-module.rc.in b/plugins/obs-text/cmake/windows/obs-module.rc.in new file mode 100644 index 000000000..c0efe5fe6 --- /dev/null +++ b/plugins/obs-text/cmake/windows/obs-module.rc.in @@ -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 GDI+ text 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", "obs-text" + VALUE "OriginalFilename", "obs-text" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/plugins/win-capture/CMakeLists.txt b/plugins/win-capture/CMakeLists.txt index 21ef2ff53..794951e3c 100644 --- a/plugins/win-capture/CMakeLists.txt +++ b/plugins/win-capture/CMakeLists.txt @@ -1,62 +1,87 @@ -project(win-capture) +cmake_minimum_required(VERSION 3.24...3.25) + +if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0) + add_library(hook-config INTERFACE) + add_library(OBS::hook-config ALIAS hook-config) + target_sources(hook-config INTERFACE graphics-hook-ver.h graphics-hook-info.h hook-helpers.h) + target_include_directories(hook-config INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") + + add_library(inject-library INTERFACE) + add_library(OBS::inject-library ALIAS inject-library) + target_sources(inject-library INTERFACE inject-library.c inject-library.h) + target_include_directories(inject-library INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") + + add_library(d3d8-api INTERFACE) + add_library(OBS::d3d8-api ALIAS d3d8-api) + target_sources(d3d8-api INTERFACE d3d8-api/d3d8.h d3d8-api/d3d8caps.h d3d8-api/d3d8types.h) + target_include_directories(d3d8-api INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/d3d8-api") +endif() + +legacy_check() option(ENABLE_COMPAT_UPDATES "Checks for service updates" OFF) -set(COMPAT_URL - "https://obsproject.com/obs2_update/win-capture" - CACHE STRING "Default services package URL") - +# cmake-format: off +set(COMPAT_URL "https://obsproject.com/obs2_update/win-capture" CACHE STRING "Default services package URL") mark_as_advanced(COMPAT_URL) +# cmake-format: on + +if(NOT TARGET OBS::ipc-util) + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/ipc-util" "${CMAKE_BINARY_DIR}/deps/ipc-util") +endif() + +if(NOT TARGET OBS::file-updater) + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/file-updater" "${CMAKE_BINARY_DIR}/deps/file-updater") +endif() + +find_package(jansson REQUIRED) add_library(win-capture MODULE) add_library(OBS::capture ALIAS win-capture) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/compat-config.h.in ${CMAKE_BINARY_DIR}/config/compat-config.h) - target_sources( win-capture - PRIVATE plugin-main.c + PRIVATE # cmake-format: sortable app-helpers.c app-helpers.h + compat-format-ver.h + compat-helpers.c + compat-helpers.h cursor-capture.c cursor-capture.h dc-capture.c dc-capture.h duplicator-monitor-capture.c - game-capture.c game-capture-file-init.c - graphics-hook-info.h - graphics-hook-ver.h - hook-helpers.h - inject-library.c - inject-library.h + game-capture.c load-graphics-offsets.c monitor-capture.c nt-stuff.c nt-stuff.h - window-capture.c - compat-helpers.c - compat-helpers.h - compat-format-ver.h - ../../libobs/util/windows/obfuscate.c - ../../libobs/util/windows/obfuscate.h - ${CMAKE_BINARY_DIR}/config/compat-config.h) + plugin-main.c + window-capture.c) -target_link_libraries(win-capture PRIVATE OBS::libobs OBS::ipc-util OBS::file-updater Jansson::Jansson) +target_compile_definitions( + win-capture PRIVATE COMPAT_URL="${COMPAT_URL}" "$<$:ENABLE_COMPAT_UPDATES>" + OBS_VERSION="${OBS_VERSION_CANONICAL}") -set_target_properties(win-capture PROPERTIES FOLDER "plugins/win-capture") +target_link_libraries( + win-capture + PRIVATE OBS::file-updater + OBS::hook-config + OBS::inject-library + OBS::ipc-util + OBS::libobs + OBS::obfuscate + OBS::w32-pthreads + OBS::winrt-headers + jansson::jansson) -if(MSVC) - target_link_libraries(win-capture PRIVATE OBS::w32-pthreads) - target_link_options(win-capture PRIVATE "LINKER:/IGNORE:4098") -endif() +target_link_options(win-capture PRIVATE /NODEFAULTLIB:msvcrtd.lib) -target_compile_definitions(win-capture PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS - OBS_VERSION="${OBS_VERSION_CANONICAL}") - -set_property(GLOBAL APPEND PROPERTY OBS_MODULE_LIST "win-capture") - -setup_plugin_target(win-capture) +# cmake-format: off +set_target_properties_obs(win-capture PROPERTIES FOLDER plugins/win-capture PREFIX "") +# cmake-format: on add_subdirectory(graphics-hook) add_subdirectory(get-graphics-offsets) diff --git a/plugins/win-capture/cmake/32bit-build.cmake b/plugins/win-capture/cmake/32bit-build.cmake new file mode 100644 index 000000000..6fa9c74da --- /dev/null +++ b/plugins/win-capture/cmake/32bit-build.cmake @@ -0,0 +1,3 @@ +add_subdirectory(graphics-hook) +add_subdirectory(get-graphics-offsets) +add_subdirectory(inject-helper) diff --git a/plugins/win-capture/cmake/legacy.cmake b/plugins/win-capture/cmake/legacy.cmake new file mode 100644 index 000000000..21ef2ff53 --- /dev/null +++ b/plugins/win-capture/cmake/legacy.cmake @@ -0,0 +1,63 @@ +project(win-capture) + +option(ENABLE_COMPAT_UPDATES "Checks for service updates" OFF) + +set(COMPAT_URL + "https://obsproject.com/obs2_update/win-capture" + CACHE STRING "Default services package URL") + +mark_as_advanced(COMPAT_URL) + +add_library(win-capture MODULE) +add_library(OBS::capture ALIAS win-capture) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/compat-config.h.in ${CMAKE_BINARY_DIR}/config/compat-config.h) + +target_sources( + win-capture + PRIVATE plugin-main.c + app-helpers.c + app-helpers.h + cursor-capture.c + cursor-capture.h + dc-capture.c + dc-capture.h + duplicator-monitor-capture.c + game-capture.c + game-capture-file-init.c + graphics-hook-info.h + graphics-hook-ver.h + hook-helpers.h + inject-library.c + inject-library.h + load-graphics-offsets.c + monitor-capture.c + nt-stuff.c + nt-stuff.h + window-capture.c + compat-helpers.c + compat-helpers.h + compat-format-ver.h + ../../libobs/util/windows/obfuscate.c + ../../libobs/util/windows/obfuscate.h + ${CMAKE_BINARY_DIR}/config/compat-config.h) + +target_link_libraries(win-capture PRIVATE OBS::libobs OBS::ipc-util OBS::file-updater Jansson::Jansson) + +set_target_properties(win-capture PROPERTIES FOLDER "plugins/win-capture") + +if(MSVC) + target_link_libraries(win-capture PRIVATE OBS::w32-pthreads) + target_link_options(win-capture PRIVATE "LINKER:/IGNORE:4098") +endif() + +target_compile_definitions(win-capture PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS + OBS_VERSION="${OBS_VERSION_CANONICAL}") + +set_property(GLOBAL APPEND PROPERTY OBS_MODULE_LIST "win-capture") + +setup_plugin_target(win-capture) + +add_subdirectory(graphics-hook) +add_subdirectory(get-graphics-offsets) +add_subdirectory(inject-helper) diff --git a/plugins/win-capture/duplicator-monitor-capture.c b/plugins/win-capture/duplicator-monitor-capture.c index 69d206235..c9abb0014 100644 --- a/plugins/win-capture/duplicator-monitor-capture.c +++ b/plugins/win-capture/duplicator-monitor-capture.c @@ -5,8 +5,13 @@ #include #include "cursor-capture.h" +#ifdef OBS_LEGACY #include "../../libobs/util/platform.h" #include "../../libobs-winrt/winrt-capture.h" +#else +#include +#include +#endif #define do_log(level, format, ...) \ blog(level, "[duplicator-monitor-capture: '%s'] " format, \ diff --git a/plugins/win-capture/get-graphics-offsets/CMakeLists.txt b/plugins/win-capture/get-graphics-offsets/CMakeLists.txt index 18afdc3e5..3218e3446 100644 --- a/plugins/win-capture/get-graphics-offsets/CMakeLists.txt +++ b/plugins/win-capture/get-graphics-offsets/CMakeLists.txt @@ -1,30 +1,22 @@ -project(get-graphics-offsets) +cmake_minimum_required(VERSION 3.24...3.25) + +add_library(_get-graphics-offsets INTERFACE) +target_sources(_get-graphics-offsets INTERFACE d3d8-offsets.cpp d3d9-offsets.cpp dxgi-offsets.cpp + get-graphics-offsets.c get-graphics-offsets.h) + +target_compile_options(_get-graphics-offsets INTERFACE $,/MTd,/MT>) + +target_link_libraries(_get-graphics-offsets INTERFACE OBS::hook-config OBS::d3d8-api d3d9.lib dxgi.lib d3d11.lib) + +legacy_check() add_executable(get-graphics-offsets) +target_link_libraries(get-graphics-offsets PRIVATE _get-graphics-offsets) -target_sources( - get-graphics-offsets - PRIVATE get-graphics-offsets.c - get-graphics-offsets.h - dxgi-offsets.cpp - d3d8-offsets.cpp - d3d9-offsets.cpp - ../graphics-hook-info.h - ../hook-helpers.h) +include(cmake/32bit.cmake) -target_include_directories(get-graphics-offsets PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..) - -target_link_libraries(get-graphics-offsets d3d9.lib dxgi.lib d3d11.lib) - -if(MSVC) - target_compile_options(get-graphics-offsets PRIVATE "$,/MTd,/MT>") -endif() - -set_target_properties(get-graphics-offsets PROPERTIES FOLDER "plugins/win-capture") -set_target_properties(get-graphics-offsets - PROPERTIES OUTPUT_NAME "get-graphics-offsets$,64,32>") - -set(OBS_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture/") -setup_plugin_target(get-graphics-offsets) +# cmake-format: off +set_target_properties_obs(get-graphics-offsets PROPERTIES FOLDER plugins/win-capture OUTPUT_NAME get-graphics-offsets64) +# cmake-format: on add_dependencies(win-capture get-graphics-offsets) diff --git a/plugins/win-capture/get-graphics-offsets/cmake/32bit-build.cmake b/plugins/win-capture/get-graphics-offsets/cmake/32bit-build.cmake new file mode 100644 index 000000000..4affae68f --- /dev/null +++ b/plugins/win-capture/get-graphics-offsets/cmake/32bit-build.cmake @@ -0,0 +1,5 @@ +project(get-graphics-offsets) + +add_executable(get-graphics-offsets) +target_link_libraries(get-graphics-offsets PRIVATE _get-graphics-offsets) +set_property(TARGET get-graphics-offsets PROPERTY OUTPUT_NAME get-graphics-offsets32) diff --git a/plugins/win-capture/get-graphics-offsets/cmake/32bit.cmake b/plugins/win-capture/get-graphics-offsets/cmake/32bit.cmake new file mode 100644 index 000000000..a411604b9 --- /dev/null +++ b/plugins/win-capture/get-graphics-offsets/cmake/32bit.cmake @@ -0,0 +1,5 @@ +add_custom_command( + TARGET get-graphics-offsets + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $ -t get-graphics-offsets + COMMENT "Build 32-bit get-graphics-offsets") diff --git a/plugins/win-capture/get-graphics-offsets/cmake/legacy.cmake b/plugins/win-capture/get-graphics-offsets/cmake/legacy.cmake new file mode 100644 index 000000000..e5b97e674 --- /dev/null +++ b/plugins/win-capture/get-graphics-offsets/cmake/legacy.cmake @@ -0,0 +1,33 @@ +project(get-graphics-offsets) + +add_executable(get-graphics-offsets) + +target_sources( + get-graphics-offsets + PRIVATE get-graphics-offsets.c + get-graphics-offsets.h + dxgi-offsets.cpp + d3d8-offsets.cpp + d3d9-offsets.cpp + ../graphics-hook-info.h + ../hook-helpers.h) + +target_include_directories(get-graphics-offsets PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../d3d8-api) + +target_link_libraries(get-graphics-offsets d3d9.lib dxgi.lib d3d11.lib) + +target_compile_definitions(get-graphics-offsets PRIVATE OBS_LEGACY) + +if(MSVC) + target_compile_options(get-graphics-offsets PRIVATE "$,/MTd,/MT>") +endif() + +set_target_properties(get-graphics-offsets PROPERTIES FOLDER "plugins/win-capture") +set_target_properties(get-graphics-offsets + PROPERTIES OUTPUT_NAME "get-graphics-offsets$,64,32>") + +set(OBS_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture/") +setup_plugin_target(get-graphics-offsets) + +add_dependencies(win-capture get-graphics-offsets) diff --git a/plugins/win-capture/get-graphics-offsets/d3d8-offsets.cpp b/plugins/win-capture/get-graphics-offsets/d3d8-offsets.cpp index 9b72ee89f..7f488b058 100644 --- a/plugins/win-capture/get-graphics-offsets/d3d8-offsets.cpp +++ b/plugins/win-capture/get-graphics-offsets/d3d8-offsets.cpp @@ -1,6 +1,10 @@ #include #include +#ifdef OBS_LEGACY #include "../d3d8-api/d3d8.h" +#else +#include +#endif #include "get-graphics-offsets.h" typedef IDirect3D8 *(WINAPI *d3d8create_t)(UINT); diff --git a/plugins/win-capture/get-graphics-offsets/get-graphics-offsets.h b/plugins/win-capture/get-graphics-offsets/get-graphics-offsets.h index 53a6ee407..3a4173e30 100644 --- a/plugins/win-capture/get-graphics-offsets/get-graphics-offsets.h +++ b/plugins/win-capture/get-graphics-offsets/get-graphics-offsets.h @@ -2,7 +2,11 @@ #include #include +#ifdef OBS_LEGACY #include "../graphics-hook-info.h" +#else +#include +#endif #define DUMMY_WNDCLASS "get_addrs_wndclass" diff --git a/plugins/win-capture/graphics-hook/CMakeLists.txt b/plugins/win-capture/graphics-hook/CMakeLists.txt index fcc833aac..3070c3307 100644 --- a/plugins/win-capture/graphics-hook/CMakeLists.txt +++ b/plugins/win-capture/graphics-hook/CMakeLists.txt @@ -1,57 +1,57 @@ -project(graphics-hook) +cmake_minimum_required(VERSION 3.24...3.25) find_package(Detours REQUIRED) find_package(Vulkan REQUIRED) +if(NOT TARGET OBS::ipc-util) + add_subdirectory("${CMAKE_SOURCE_DIR}/deps/ipc-util" "${CMAKE_BINARY_DIR}/deps/ipc-util") +endif() + +if(NOT TARGET OBS::obfuscate) + add_subdirectory("${CMAKE_SOURCE_DIR}/libobs" "${CMAKE_BINARY_DIR}/libobs") +endif() + +add_library(_graphics-hook INTERFACE) + +target_sources( + _graphics-hook + INTERFACE d3d8-capture.cpp + d3d9-capture.cpp + d3d9-patches.hpp + d3d10-capture.cpp + d3d11-capture.cpp + d3d12-capture.cpp + dxgi-capture.cpp + gl-capture.c + gl-decs.h + graphics-hook.c + graphics-hook.h + graphics-hook.rc) + +target_compile_definitions(_graphics-hook INTERFACE COMPILE_D3D12_HOOK) +target_compile_options(_graphics-hook INTERFACE $,/MTd,/MT>) + +target_link_libraries(_graphics-hook INTERFACE OBS::d3d8-api OBS::hook-config OBS::ipc-util OBS::obfuscate + Detours::Detours dxguid) +target_link_options(_graphics-hook INTERFACE /IGNORE:4099) + +if(TARGET Vulkan::Vulkan) + target_sources(_graphics-hook INTERFACE vulkan-capture.c vulkan-capture.h) + target_link_libraries(_graphics-hook INTERFACE Vulkan::Vulkan) + target_compile_definitions(_graphics-hook INTERFACE COMPILE_VULKAN_HOOK) +endif() + +legacy_check() + add_library(graphics-hook MODULE) add_library(OBS::graphics-hook ALIAS graphics-hook) -target_sources( - graphics-hook - PRIVATE graphics-hook.c - graphics-hook.h - gl-capture.c - gl-decs.h - d3d8-capture.cpp - d3d9-capture.cpp - d3d9-patches.hpp - dxgi-capture.cpp - d3d10-capture.cpp - d3d11-capture.cpp - d3d12-capture.cpp - ../../../libobs/util/windows/obfuscate.c - ../../../libobs/util/windows/obfuscate.h - ../graphics-hook-ver.h - ../graphics-hook-info.h - ../hook-helpers.h - graphics-hook.rc) +target_link_libraries(graphics-hook PRIVATE _graphics-hook) -target_include_directories(graphics-hook PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..) +include(cmake/32bit.cmake) -target_link_libraries(graphics-hook PRIVATE OBS::ipc-util Detours::Detours dxguid) -target_link_options(graphics-hook PRIVATE "LINKER:/IGNORE:4099") - -if(MSVC) - target_compile_options(graphics-hook PRIVATE "$,/MTd,/MT>") -endif() - -set_target_properties(graphics-hook PROPERTIES FOLDER "plugins/win-capture" - OUTPUT_NAME "graphics-hook$,64,32>") - -target_compile_definitions(graphics-hook PRIVATE COMPILE_D3D12_HOOK) - -if(TARGET Vulkan::Vulkan) - target_sources(graphics-hook PRIVATE vulkan-capture.c vulkan-capture.h) - - target_link_libraries(graphics-hook PRIVATE Vulkan::Vulkan) - - target_compile_definitions(graphics-hook PRIVATE COMPILE_VULKAN_HOOK) - - add_target_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan64.json" "obs-plugins/win-capture/") - add_target_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan32.json" "obs-plugins/win-capture/") -endif() - -set(OBS_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture/") -setup_plugin_target(graphics-hook) +# cmake-format: off +set_target_properties_obs(graphics-hook PROPERTIES FOLDER "plugins/win-capture" OUTPUT_NAME graphics-hook64) +# cmake-format: on add_dependencies(win-capture graphics-hook) diff --git a/plugins/win-capture/graphics-hook/cmake/32bit-build.cmake b/plugins/win-capture/graphics-hook/cmake/32bit-build.cmake new file mode 100644 index 000000000..365c9e735 --- /dev/null +++ b/plugins/win-capture/graphics-hook/cmake/32bit-build.cmake @@ -0,0 +1,9 @@ +project(graphics-hook) + +if(NOT TARGET OBS::obfuscate) + add_subdirectory("${CMAKE_SOURCE_DIR}/libobs" "${CMAKE_BINARY_DIR}/libobs") +endif() + +add_library(graphics-hook MODULE) +target_link_libraries(graphics-hook PRIVATE _graphics-hook) +set_property(TARGET graphics-hook PROPERTY OUTPUT_NAME graphics-hook32) diff --git a/plugins/win-capture/graphics-hook/cmake/32bit.cmake b/plugins/win-capture/graphics-hook/cmake/32bit.cmake new file mode 100644 index 000000000..af87a228f --- /dev/null +++ b/plugins/win-capture/graphics-hook/cmake/32bit.cmake @@ -0,0 +1,5 @@ +add_custom_command( + TARGET graphics-hook + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $ -t graphics-hook + COMMENT "Build 32-bit graphics-hook") diff --git a/plugins/win-capture/graphics-hook/cmake/legacy.cmake b/plugins/win-capture/graphics-hook/cmake/legacy.cmake new file mode 100644 index 000000000..bcf2623b0 --- /dev/null +++ b/plugins/win-capture/graphics-hook/cmake/legacy.cmake @@ -0,0 +1,58 @@ +project(graphics-hook) + +find_package(Detours REQUIRED) +find_package(Vulkan REQUIRED) + +add_library(graphics-hook MODULE) +add_library(OBS::graphics-hook ALIAS graphics-hook) + +target_sources( + graphics-hook + PRIVATE graphics-hook.c + graphics-hook.h + gl-capture.c + gl-decs.h + d3d8-capture.cpp + d3d9-capture.cpp + d3d9-patches.hpp + dxgi-capture.cpp + d3d10-capture.cpp + d3d11-capture.cpp + d3d12-capture.cpp + ../../../libobs/util/windows/obfuscate.c + ../../../libobs/util/windows/obfuscate.h + ../graphics-hook-ver.h + ../graphics-hook-info.h + ../hook-helpers.h + graphics-hook.rc) + +target_include_directories(graphics-hook PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_SOURCE_DIR}/libobs + ${CMAKE_CURRENT_SOURCE_DIR}/../d3d8-api) + +target_link_libraries(graphics-hook PRIVATE OBS::ipc-util Detours::Detours dxguid) +target_link_options(graphics-hook PRIVATE "LINKER:/IGNORE:4099") + +if(MSVC) + target_compile_options(graphics-hook PRIVATE "$,/MTd,/MT>") +endif() + +set_target_properties(graphics-hook PROPERTIES FOLDER "plugins/win-capture" + OUTPUT_NAME "graphics-hook$,64,32>") + +target_compile_definitions(graphics-hook PRIVATE COMPILE_D3D12_HOOK OBS_LEGACY) + +if(TARGET Vulkan::Vulkan) + target_sources(graphics-hook PRIVATE vulkan-capture.c vulkan-capture.h) + + target_link_libraries(graphics-hook PRIVATE Vulkan::Vulkan) + + target_compile_definitions(graphics-hook PRIVATE COMPILE_VULKAN_HOOK) + + add_target_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan64.json" "obs-plugins/win-capture/") + add_target_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan32.json" "obs-plugins/win-capture/") +endif() + +set(OBS_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture/") +setup_plugin_target(graphics-hook) + +add_dependencies(win-capture graphics-hook) diff --git a/plugins/win-capture/graphics-hook/d3d8-capture.cpp b/plugins/win-capture/graphics-hook/d3d8-capture.cpp index eb81794e8..36d363bbd 100644 --- a/plugins/win-capture/graphics-hook/d3d8-capture.cpp +++ b/plugins/win-capture/graphics-hook/d3d8-capture.cpp @@ -1,6 +1,10 @@ #include +#ifdef OBS_LEGACY #include "../d3d8-api/d3d8.h" +#else +#include +#endif #include "graphics-hook.h" #include diff --git a/plugins/win-capture/graphics-hook/graphics-hook.c b/plugins/win-capture/graphics-hook/graphics-hook.c index 294604ea3..d7c5dfa3a 100644 --- a/plugins/win-capture/graphics-hook/graphics-hook.c +++ b/plugins/win-capture/graphics-hook/graphics-hook.c @@ -2,8 +2,13 @@ #include #include #include "graphics-hook.h" +#ifdef OBS_LEGACY #include "../graphics-hook-ver.h" #include "../../libobs/util/windows/obfuscate.h" +#else +#include +#include +#endif #define DEBUG_OUTPUT diff --git a/plugins/win-capture/graphics-hook/graphics-hook.h b/plugins/win-capture/graphics-hook/graphics-hook.h index e6f9b04ba..4ebf25ae1 100644 --- a/plugins/win-capture/graphics-hook/graphics-hook.h +++ b/plugins/win-capture/graphics-hook/graphics-hook.h @@ -5,7 +5,11 @@ #pragma warning(disable : 4152) #endif +#ifdef OBS_LEGACY #include "../graphics-hook-info.h" +#else +#include +#endif #include #include diff --git a/plugins/win-capture/inject-helper/CMakeLists.txt b/plugins/win-capture/inject-helper/CMakeLists.txt index b212bc237..1b50dcdf8 100644 --- a/plugins/win-capture/inject-helper/CMakeLists.txt +++ b/plugins/win-capture/inject-helper/CMakeLists.txt @@ -1,20 +1,23 @@ -project(inject-helper) +cmake_minimum_required(VERSION 3.24...3.25) -add_executable(inject-helper) - -target_sources(inject-helper PRIVATE inject-helper.c ../inject-library.c ../inject-library.h - ../../../libobs/util/windows/obfuscate.c ../../../libobs/util/windows/obfuscate.h) - -target_include_directories(inject-helper PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..) - -if(MSVC) - target_compile_options(inject-helper PRIVATE "$,/MTd,/MT>") +if(NOT TARGET OBS::obfuscate) + add_subdirectory("${CMAKE_SOURCE_DIR}/libobs" "${CMAKE_BINARY_DIR}/libobs") endif() -set_target_properties(inject-helper PROPERTIES FOLDER "plugins/win-capture" - OUTPUT_NAME "inject-helper$,64,32>") +add_library(_inject-helper INTERFACE) +target_sources(_inject-helper INTERFACE inject-helper.c) +target_compile_options(_inject-helper INTERFACE $,/MTd,/MT>) +target_link_libraries(_inject-helper INTERFACE OBS::inject-library OBS::obfuscate) -set(OBS_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture/") -setup_plugin_target(inject-helper) +legacy_check() + +add_executable(inject-helper) +target_link_libraries(inject-helper PRIVATE _inject-helper) + +include(cmake/32bit.cmake) + +# cmake-format: off +set_target_properties_obs(inject-helper PROPERTIES FOLDER plugins/win-capture OUTPUT_NAME inject-helper64) +# cmake-format: on add_dependencies(win-capture inject-helper) diff --git a/plugins/win-capture/inject-helper/cmake/32bit-build.cmake b/plugins/win-capture/inject-helper/cmake/32bit-build.cmake new file mode 100644 index 000000000..fce6eea49 --- /dev/null +++ b/plugins/win-capture/inject-helper/cmake/32bit-build.cmake @@ -0,0 +1,5 @@ +project(inject-helper) + +add_executable(inject-helper) +target_link_libraries(inject-helper PRIVATE _inject-helper) +set_property(TARGET inject-helper PROPERTY OUTPUT_NAME inject-helper32) diff --git a/plugins/win-capture/inject-helper/cmake/32bit.cmake b/plugins/win-capture/inject-helper/cmake/32bit.cmake new file mode 100644 index 000000000..7a02e99c6 --- /dev/null +++ b/plugins/win-capture/inject-helper/cmake/32bit.cmake @@ -0,0 +1,5 @@ +add_custom_command( + TARGET inject-helper + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $ -t inject-helper + COMMENT "Build 32-bit inject-helper") diff --git a/plugins/win-capture/inject-helper/cmake/legacy.cmake b/plugins/win-capture/inject-helper/cmake/legacy.cmake new file mode 100644 index 000000000..a4a45971a --- /dev/null +++ b/plugins/win-capture/inject-helper/cmake/legacy.cmake @@ -0,0 +1,21 @@ +project(inject-helper) + +add_executable(inject-helper) + +target_sources(inject-helper PRIVATE inject-helper.c ../inject-library.c ../inject-library.h + ../../../libobs/util/windows/obfuscate.c ../../../libobs/util/windows/obfuscate.h) + +target_include_directories(inject-helper PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_SOURCE_DIR}/libobs) + +target_compile_definitions(inject-helper PRIVATE OBS_LEGACY) +if(MSVC) + target_compile_options(inject-helper PRIVATE "$,/MTd,/MT>") +endif() + +set_target_properties(inject-helper PROPERTIES FOLDER "plugins/win-capture" + OUTPUT_NAME "inject-helper$,64,32>") + +set(OBS_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture/") +setup_plugin_target(inject-helper) + +add_dependencies(win-capture inject-helper) diff --git a/plugins/win-capture/inject-helper/inject-helper.c b/plugins/win-capture/inject-helper/inject-helper.c index 4026536e7..ee161288d 100644 --- a/plugins/win-capture/inject-helper/inject-helper.c +++ b/plugins/win-capture/inject-helper/inject-helper.c @@ -4,8 +4,13 @@ #include #include #include +#ifdef OBS_LEGACY #include "../../../libobs/util/windows/obfuscate.h" #include "../inject-library.h" +#else +#include +#include +#endif #if defined(_MSC_VER) && !defined(inline) #define inline __inline diff --git a/plugins/win-capture/inject-library.c b/plugins/win-capture/inject-library.c index f1226c9f7..44d6e0f4a 100644 --- a/plugins/win-capture/inject-library.c +++ b/plugins/win-capture/inject-library.c @@ -1,6 +1,10 @@ #include #include +#ifdef OBS_LEGACY #include "../../libobs/util/windows/obfuscate.h" +#else +#include +#endif #include "inject-library.h" typedef HANDLE(WINAPI *create_remote_thread_t)(HANDLE, LPSECURITY_ATTRIBUTES, diff --git a/plugins/win-capture/plugin-main.c b/plugins/win-capture/plugin-main.c index 49972bd53..dbb15a240 100644 --- a/plugins/win-capture/plugin-main.c +++ b/plugins/win-capture/plugin-main.c @@ -8,7 +8,9 @@ #include "compat-helpers.h" #include "compat-format-ver.h" +#ifdef OBS_LEGACY #include "compat-config.h" +#endif #define WIN_CAPTURE_LOG_STRING "[win-capture plugin] " #define WIN_CAPTURE_VER_STRING "win-capture plugin (libobs " OBS_VERSION ")" diff --git a/plugins/win-capture/window-capture.c b/plugins/win-capture/window-capture.c index 1ee0f90d3..df0acf977 100644 --- a/plugins/win-capture/window-capture.c +++ b/plugins/win-capture/window-capture.c @@ -4,8 +4,13 @@ #include #include "dc-capture.h" #include "compat-helpers.h" +#ifdef OBS_LEGACY #include "../../libobs/util/platform.h" #include "../../libobs-winrt/winrt-capture.h" +#else +#include +#include +#endif /* clang-format off */ diff --git a/plugins/win-dshow/CMakeLists.txt b/plugins/win-dshow/CMakeLists.txt index d39b273f5..eef67846f 100644 --- a/plugins/win-dshow/CMakeLists.txt +++ b/plugins/win-dshow/CMakeLists.txt @@ -1,215 +1,48 @@ -if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture/dshowcapture.hpp") - obs_status(FATAL_ERROR "libdshowcapture submodule not found! Please fetch submodules. win-dshow plugin disabled.") - return() +cmake_minimum_required(VERSION 3.24...3.25) + +if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0) + add_library(obs-virtualcam-interface INTERFACE) + add_library(OBS::virtualcam-interface ALIAS obs-virtualcam-interface) + + target_sources(obs-virtualcam-interface INTERFACE shared-memory-queue.c shared-memory-queue.h tiny-nv12-scale.c + tiny-nv12-scale.h) + target_include_directories(obs-virtualcam-interface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") + + include(cmake/libdshowcapture.cmake) + add_subdirectory(virtualcam-module) endif() -option(ENABLE_VIRTUALCAM "Enable building with Virtual Camera (Windows)" ON) +legacy_check() -if(NOT ENABLE_VIRTUALCAM) - obs_status(DISABLED "Windows Virtual Camera") -endif() - -if(ENABLE_VIRTUALCAM AND NOT VIRTUALCAM_GUID) - set(VIRTUALCAM_GUID - "" - CACHE STRING "Virtual Camera GUID" FORCE) - mark_as_advanced(VIRTUALCAM_GUID) -endif() - -project(win-dshow) - -find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil) +find_package(FFmpeg REQUIRED avcodec avutil) add_library(win-dshow MODULE) add_library(OBS::dshow ALIAS win-dshow) -target_sources(win-dshow PRIVATE encode-dstr.hpp win-dshow.cpp win-dshow-encoder.cpp dshow-plugin.cpp ffmpeg-decode.c - ffmpeg-decode.h) - -add_library(libdshowcapture-external INTERFACE) -add_library(libdshowcapture INTERFACE) -add_library(OBS::libdshowcapture-external ALIAS libdshowcapture-external) -add_library(OBS::libdshowcapture ALIAS libdshowcapture) - -target_sources( - libdshowcapture-external - INTERFACE libdshowcapture/external/capture-device-support/Library/EGAVResult.cpp - libdshowcapture/external/capture-device-support/Library/ElgatoUVCDevice.cpp - libdshowcapture/external/capture-device-support/Library/win/EGAVHIDImplementation.cpp - libdshowcapture/external/capture-device-support/SampleCode/DriverInterface.cpp) - -target_sources( - libdshowcapture - INTERFACE libdshowcapture/dshowcapture.hpp - libdshowcapture/source/capture-filter.cpp - libdshowcapture/source/capture-filter.hpp - libdshowcapture/source/output-filter.cpp - libdshowcapture/source/output-filter.hpp - libdshowcapture/source/dshowcapture.cpp - libdshowcapture/source/dshowencode.cpp - libdshowcapture/source/device.cpp - libdshowcapture/source/device.hpp - libdshowcapture/source/device-vendor.cpp - libdshowcapture/source/encoder.cpp - libdshowcapture/source/encoder.hpp - libdshowcapture/source/dshow-base.cpp - libdshowcapture/source/dshow-base.hpp - libdshowcapture/source/dshow-demux.cpp - libdshowcapture/source/dshow-demux.hpp - libdshowcapture/source/dshow-device-defs.hpp - libdshowcapture/source/dshow-enum.cpp - libdshowcapture/source/dshow-enum.hpp - libdshowcapture/source/dshow-formats.cpp - libdshowcapture/source/dshow-formats.hpp - libdshowcapture/source/dshow-media-type.cpp - libdshowcapture/source/dshow-encoded-device.cpp - libdshowcapture/source/dshow-media-type.hpp - libdshowcapture/source/log.cpp - libdshowcapture/source/log.hpp - libdshowcapture/source/external/IVideoCaptureFilter.h) - -target_include_directories( - libdshowcapture INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture - ${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture/external/capture-device-support/Library) - -target_compile_definitions(libdshowcapture-external INTERFACE _UP_WINDOWS=1) -target_compile_definitions(libdshowcapture INTERFACE _UP_WINDOWS=1) -target_compile_options(libdshowcapture-external INTERFACE /wd4018) - -set(MODULE_DESCRIPTION "OBS DirectShow module") - -configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in win-dshow.rc) +target_sources(win-dshow PRIVATE dshow-plugin.cpp encode-dstr.hpp ffmpeg-decode.c ffmpeg-decode.h win-dshow-encoder.cpp + win-dshow.cpp) +configure_file(cmake/windows/obs-module.rc.in win-dshow.rc) target_sources(win-dshow PRIVATE win-dshow.rc) -target_compile_definitions(win-dshow PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) - -set(VIRTUALCAM_AVAILABLE OFF) -if(ENABLE_VIRTUALCAM) - if(VIRTUALCAM_GUID STREQUAL "") - obs_status(WARNING "Windows Virtual Camera - GUID not set. Specify as 'VIRTUALCAM_GUID' to enable.") - else() - set(INVALID_GUID ON) - - string(REPLACE "-" ";" GUID_VALS ${VIRTUALCAM_GUID}) - - list(LENGTH GUID_VALS GUID_VAL_COUNT) - if(GUID_VAL_COUNT EQUAL 5) - string(REPLACE ";" "0" GUID_HEX ${GUID_VALS}) - string(REGEX MATCH "[0-9a-fA-F]+" GUID_ACTUAL_HEX ${GUID_HEX}) - if(GUID_ACTUAL_HEX STREQUAL GUID_HEX) - list(GET GUID_VALS 0 GUID_VALS_DATA1) - list(GET GUID_VALS 1 GUID_VALS_DATA2) - list(GET GUID_VALS 2 GUID_VALS_DATA3) - list(GET GUID_VALS 3 GUID_VALS_DATA4) - list(GET GUID_VALS 4 GUID_VALS_DATA5) - string(LENGTH ${GUID_VALS_DATA1} GUID_VALS_DATA1_LENGTH) - string(LENGTH ${GUID_VALS_DATA2} GUID_VALS_DATA2_LENGTH) - string(LENGTH ${GUID_VALS_DATA3} GUID_VALS_DATA3_LENGTH) - string(LENGTH ${GUID_VALS_DATA4} GUID_VALS_DATA4_LENGTH) - string(LENGTH ${GUID_VALS_DATA5} GUID_VALS_DATA5_LENGTH) - if(GUID_VALS_DATA1_LENGTH EQUAL 8 - AND GUID_VALS_DATA2_LENGTH EQUAL 4 - AND GUID_VALS_DATA3_LENGTH EQUAL 4 - AND GUID_VALS_DATA4_LENGTH EQUAL 4 - AND GUID_VALS_DATA5_LENGTH EQUAL 12) - set(GUID_VAL01 ${GUID_VALS_DATA1}) - set(GUID_VAL02 ${GUID_VALS_DATA2}) - set(GUID_VAL03 ${GUID_VALS_DATA3}) - string(SUBSTRING ${GUID_VALS_DATA4} 0 2 GUID_VAL04) - string(SUBSTRING ${GUID_VALS_DATA4} 2 2 GUID_VAL05) - string(SUBSTRING ${GUID_VALS_DATA5} 0 2 GUID_VAL06) - string(SUBSTRING ${GUID_VALS_DATA5} 2 2 GUID_VAL07) - string(SUBSTRING ${GUID_VALS_DATA5} 4 2 GUID_VAL08) - string(SUBSTRING ${GUID_VALS_DATA5} 6 2 GUID_VAL09) - string(SUBSTRING ${GUID_VALS_DATA5} 8 2 GUID_VAL10) - string(SUBSTRING ${GUID_VALS_DATA5} 10 2 GUID_VAL11) - set(VIRTUALCAM_AVAILABLE ON) - set(INVALID_GUID OFF) - endif() - endif() - endif() - endif() - - if(INVALID_GUID) - obs_status(WARNING "Windows Virtual Camera - invalid GUID supplied") - endif() -endif() - target_link_libraries( win-dshow PRIVATE OBS::libobs OBS::w32-pthreads - OBS::libdshowcapture-external OBS::libdshowcapture - setupapi - strmiids - ksuser - winmm - wmcodecdspuuid FFmpeg::avcodec - FFmpeg::avutil) - -source_group( - "libdshowcapture-external\\Source Files" - FILES libdshowcapture/external/capture-device-support/Library/EGAVResult.cpp - libdshowcapture/external/capture-device-support/Library/ElgatoUVCDevice.cpp - libdshowcapture/external/capture-device-support/Library/win/EGAVHIDImplementation.cpp - libdshowcapture/external/capture-device-support/SampleCode/DriverInterface.cpp) -source_group( - "libdshowcapture\\Source Files" - FILES libdshowcapture/source/capture-filter.cpp - libdshowcapture/source/output-filter.cpp - libdshowcapture/source/dshowcapture.cpp - libdshowcapture/source/dshowencode.cpp - libdshowcapture/source/device.cpp - libdshowcapture/source/device-vendor.cpp - libdshowcapture/source/encoder.cpp - libdshowcapture/source/dshow-base.cpp - libdshowcapture/source/dshow-demux.cpp - libdshowcapture/source/dshow-enum.cpp - libdshowcapture/source/dshow-formats.cpp - libdshowcapture/source/dshow-media-type.cpp - libdshowcapture/source/dshow-encoded-device.cpp - libdshowcapture/source/log.cpp) -source_group( - "libdshowcapture\\Header Files" - FILES libdshowcapture/dshowcapture.hpp - libdshowcapture/source/capture-filter.hpp - libdshowcapture/source/output-filter.hpp - libdshowcapture/source/device.hpp - libdshowcapture/source/encoder.hpp - libdshowcapture/source/dshow-base.hpp - libdshowcapture/source/dshow-demux.hpp - libdshowcapture/source/dshow-device-defs.hpp - libdshowcapture/source/dshow-enum.hpp - libdshowcapture/source/dshow-formats.hpp - libdshowcapture/source/dshow-media-type.hpp - libdshowcapture/source/log.hpp - libdshowcapture/source/external/IVideoCaptureFilter.h) - -set_target_properties(win-dshow PROPERTIES FOLDER "plugins/win-dshow") - -setup_plugin_target(win-dshow) - -if(ENABLE_VIRTUALCAM AND VIRTUALCAM_AVAILABLE) - target_sources(win-dshow PRIVATE tiny-nv12-scale.c tiny-nv12-scale.h shared-memory-queue.c shared-memory-queue.h - virtualcam.c) + FFmpeg::avutil + strmiids + winmm) +if(TARGET OBS::virtualcam AND TARGET OBS::virtualcam-guid) + target_sources(win-dshow PRIVATE virtualcam.c) + target_link_libraries(win-dshow PRIVATE OBS::virtualcam-interface OBS::virtualcam-guid) target_compile_definitions(win-dshow PRIVATE VIRTUALCAM_AVAILABLE) - target_include_directories(win-dshow PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/config) - - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/virtualcam-guid.h.in ${CMAKE_CURRENT_BINARY_DIR}/config/virtualcam-guid.h) - - target_sources(win-dshow PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/config/virtualcam-guid.h) - - configure_file(virtualcam-install.bat.in "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-install.bat") - - configure_file(virtualcam-uninstall.bat.in "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-uninstall.bat") - - add_target_resource(win-dshow "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-install.bat" "obs-plugins/win-dshow/") - add_target_resource(win-dshow "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-uninstall.bat" "obs-plugins/win-dshow/") - - add_subdirectory(virtualcam-module) + add_dependencies(win-dshow obs-virtualcam-module) endif() + +# cmake-format: off +set_target_properties_obs(win-dshow PROPERTIES FOLDER plugins/win-dshow PREFIX "") +# cmake-format: on diff --git a/plugins/win-dshow/cmake/legacy.cmake b/plugins/win-dshow/cmake/legacy.cmake new file mode 100644 index 000000000..3b87bfb34 --- /dev/null +++ b/plugins/win-dshow/cmake/legacy.cmake @@ -0,0 +1,216 @@ +if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture/dshowcapture.hpp") + obs_status(FATAL_ERROR "libdshowcapture submodule not found! Please fetch submodules. win-dshow plugin disabled.") + return() +endif() + +option(ENABLE_VIRTUALCAM "Enable building with Virtual Camera (Windows)" ON) + +if(NOT ENABLE_VIRTUALCAM) + obs_status(DISABLED "Windows Virtual Camera") +endif() + +if(ENABLE_VIRTUALCAM AND NOT VIRTUALCAM_GUID) + set(VIRTUALCAM_GUID + "" + CACHE STRING "Virtual Camera GUID" FORCE) + mark_as_advanced(VIRTUALCAM_GUID) +endif() + +project(win-dshow) + +find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil) + +add_library(win-dshow MODULE) +add_library(OBS::dshow ALIAS win-dshow) + +target_sources(win-dshow PRIVATE encode-dstr.hpp win-dshow.cpp win-dshow-encoder.cpp dshow-plugin.cpp ffmpeg-decode.c + ffmpeg-decode.h) + +add_library(libdshowcapture-external INTERFACE) +add_library(libdshowcapture INTERFACE) +add_library(OBS::libdshowcapture-external ALIAS libdshowcapture-external) +add_library(OBS::libdshowcapture ALIAS libdshowcapture) + +target_sources( + libdshowcapture-external + INTERFACE libdshowcapture/external/capture-device-support/Library/EGAVResult.cpp + libdshowcapture/external/capture-device-support/Library/ElgatoUVCDevice.cpp + libdshowcapture/external/capture-device-support/Library/win/EGAVHIDImplementation.cpp + libdshowcapture/external/capture-device-support/SampleCode/DriverInterface.cpp) + +target_sources( + libdshowcapture + INTERFACE libdshowcapture/dshowcapture.hpp + libdshowcapture/source/capture-filter.cpp + libdshowcapture/source/capture-filter.hpp + libdshowcapture/source/output-filter.cpp + libdshowcapture/source/output-filter.hpp + libdshowcapture/source/dshowcapture.cpp + libdshowcapture/source/dshowencode.cpp + libdshowcapture/source/device.cpp + libdshowcapture/source/device.hpp + libdshowcapture/source/device-vendor.cpp + libdshowcapture/source/encoder.cpp + libdshowcapture/source/encoder.hpp + libdshowcapture/source/dshow-base.cpp + libdshowcapture/source/dshow-base.hpp + libdshowcapture/source/dshow-demux.cpp + libdshowcapture/source/dshow-demux.hpp + libdshowcapture/source/dshow-device-defs.hpp + libdshowcapture/source/dshow-enum.cpp + libdshowcapture/source/dshow-enum.hpp + libdshowcapture/source/dshow-formats.cpp + libdshowcapture/source/dshow-formats.hpp + libdshowcapture/source/dshow-media-type.cpp + libdshowcapture/source/dshow-encoded-device.cpp + libdshowcapture/source/dshow-media-type.hpp + libdshowcapture/source/log.cpp + libdshowcapture/source/log.hpp + libdshowcapture/source/external/IVideoCaptureFilter.h) + +target_include_directories( + libdshowcapture INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture + ${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture/external/capture-device-support/Library) + +target_compile_definitions(libdshowcapture-external INTERFACE _UP_WINDOWS=1) +target_compile_definitions(libdshowcapture INTERFACE _UP_WINDOWS=1) +target_compile_options(libdshowcapture-external INTERFACE /wd4018) + +set(MODULE_DESCRIPTION "OBS DirectShow module") + +configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in win-dshow.rc) + +target_sources(win-dshow PRIVATE win-dshow.rc) + +target_compile_definitions(win-dshow PRIVATE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS + OBS_LEGACY) + +set(VIRTUALCAM_AVAILABLE OFF) +if(ENABLE_VIRTUALCAM) + if(VIRTUALCAM_GUID STREQUAL "") + obs_status(WARNING "Windows Virtual Camera - GUID not set. Specify as 'VIRTUALCAM_GUID' to enable.") + else() + set(INVALID_GUID ON) + + string(REPLACE "-" ";" GUID_VALS ${VIRTUALCAM_GUID}) + + list(LENGTH GUID_VALS GUID_VAL_COUNT) + if(GUID_VAL_COUNT EQUAL 5) + string(REPLACE ";" "0" GUID_HEX ${GUID_VALS}) + string(REGEX MATCH "[0-9a-fA-F]+" GUID_ACTUAL_HEX ${GUID_HEX}) + if(GUID_ACTUAL_HEX STREQUAL GUID_HEX) + list(GET GUID_VALS 0 GUID_VALS_DATA1) + list(GET GUID_VALS 1 GUID_VALS_DATA2) + list(GET GUID_VALS 2 GUID_VALS_DATA3) + list(GET GUID_VALS 3 GUID_VALS_DATA4) + list(GET GUID_VALS 4 GUID_VALS_DATA5) + string(LENGTH ${GUID_VALS_DATA1} GUID_VALS_DATA1_LENGTH) + string(LENGTH ${GUID_VALS_DATA2} GUID_VALS_DATA2_LENGTH) + string(LENGTH ${GUID_VALS_DATA3} GUID_VALS_DATA3_LENGTH) + string(LENGTH ${GUID_VALS_DATA4} GUID_VALS_DATA4_LENGTH) + string(LENGTH ${GUID_VALS_DATA5} GUID_VALS_DATA5_LENGTH) + if(GUID_VALS_DATA1_LENGTH EQUAL 8 + AND GUID_VALS_DATA2_LENGTH EQUAL 4 + AND GUID_VALS_DATA3_LENGTH EQUAL 4 + AND GUID_VALS_DATA4_LENGTH EQUAL 4 + AND GUID_VALS_DATA5_LENGTH EQUAL 12) + set(GUID_VAL01 ${GUID_VALS_DATA1}) + set(GUID_VAL02 ${GUID_VALS_DATA2}) + set(GUID_VAL03 ${GUID_VALS_DATA3}) + string(SUBSTRING ${GUID_VALS_DATA4} 0 2 GUID_VAL04) + string(SUBSTRING ${GUID_VALS_DATA4} 2 2 GUID_VAL05) + string(SUBSTRING ${GUID_VALS_DATA5} 0 2 GUID_VAL06) + string(SUBSTRING ${GUID_VALS_DATA5} 2 2 GUID_VAL07) + string(SUBSTRING ${GUID_VALS_DATA5} 4 2 GUID_VAL08) + string(SUBSTRING ${GUID_VALS_DATA5} 6 2 GUID_VAL09) + string(SUBSTRING ${GUID_VALS_DATA5} 8 2 GUID_VAL10) + string(SUBSTRING ${GUID_VALS_DATA5} 10 2 GUID_VAL11) + set(VIRTUALCAM_AVAILABLE ON) + set(INVALID_GUID OFF) + endif() + endif() + endif() + endif() + + if(INVALID_GUID) + obs_status(WARNING "Windows Virtual Camera - invalid GUID supplied") + endif() +endif() + +target_link_libraries( + win-dshow + PRIVATE OBS::libobs + OBS::w32-pthreads + OBS::libdshowcapture-external + OBS::libdshowcapture + setupapi + strmiids + ksuser + winmm + wmcodecdspuuid + FFmpeg::avcodec + FFmpeg::avutil) + +source_group( + "libdshowcapture-external\\Source Files" + FILES libdshowcapture/external/capture-device-support/Library/EGAVResult.cpp + libdshowcapture/external/capture-device-support/Library/ElgatoUVCDevice.cpp + libdshowcapture/external/capture-device-support/Library/win/EGAVHIDImplementation.cpp + libdshowcapture/external/capture-device-support/SampleCode/DriverInterface.cpp) +source_group( + "libdshowcapture\\Source Files" + FILES libdshowcapture/source/capture-filter.cpp + libdshowcapture/source/output-filter.cpp + libdshowcapture/source/dshowcapture.cpp + libdshowcapture/source/dshowencode.cpp + libdshowcapture/source/device.cpp + libdshowcapture/source/device-vendor.cpp + libdshowcapture/source/encoder.cpp + libdshowcapture/source/dshow-base.cpp + libdshowcapture/source/dshow-demux.cpp + libdshowcapture/source/dshow-enum.cpp + libdshowcapture/source/dshow-formats.cpp + libdshowcapture/source/dshow-media-type.cpp + libdshowcapture/source/dshow-encoded-device.cpp + libdshowcapture/source/log.cpp) +source_group( + "libdshowcapture\\Header Files" + FILES libdshowcapture/dshowcapture.hpp + libdshowcapture/source/capture-filter.hpp + libdshowcapture/source/output-filter.hpp + libdshowcapture/source/device.hpp + libdshowcapture/source/encoder.hpp + libdshowcapture/source/dshow-base.hpp + libdshowcapture/source/dshow-demux.hpp + libdshowcapture/source/dshow-device-defs.hpp + libdshowcapture/source/dshow-enum.hpp + libdshowcapture/source/dshow-formats.hpp + libdshowcapture/source/dshow-media-type.hpp + libdshowcapture/source/log.hpp + libdshowcapture/source/external/IVideoCaptureFilter.h) + +set_target_properties(win-dshow PROPERTIES FOLDER "plugins/win-dshow") + +setup_plugin_target(win-dshow) + +if(ENABLE_VIRTUALCAM AND VIRTUALCAM_AVAILABLE) + target_sources(win-dshow PRIVATE tiny-nv12-scale.c tiny-nv12-scale.h shared-memory-queue.c shared-memory-queue.h + virtualcam.c) + + target_compile_definitions(win-dshow PRIVATE VIRTUALCAM_AVAILABLE) + + target_include_directories(win-dshow PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/config) + + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/virtualcam-guid.h.in ${CMAKE_CURRENT_BINARY_DIR}/config/virtualcam-guid.h) + + target_sources(win-dshow PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/config/virtualcam-guid.h) + + configure_file(virtualcam-module/virtualcam-install.bat.in "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-install.bat") + + configure_file(virtualcam-module/virtualcam-uninstall.bat.in "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-uninstall.bat") + + add_target_resource(win-dshow "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-install.bat" "obs-plugins/win-dshow/") + add_target_resource(win-dshow "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-uninstall.bat" "obs-plugins/win-dshow/") + + add_subdirectory(virtualcam-module) +endif() diff --git a/plugins/win-dshow/cmake/libdshowcapture.cmake b/plugins/win-dshow/cmake/libdshowcapture.cmake new file mode 100644 index 000000000..2cc78e640 --- /dev/null +++ b/plugins/win-dshow/cmake/libdshowcapture.cmake @@ -0,0 +1,56 @@ +add_library(libdshowcapture INTERFACE) +add_library(OBS::libdshowcapture ALIAS libdshowcapture) + +target_sources( + libdshowcapture + INTERFACE libdshowcapture/dshowcapture.hpp + libdshowcapture/source/capture-filter.cpp + libdshowcapture/source/capture-filter.hpp + libdshowcapture/source/device-vendor.cpp + libdshowcapture/source/device.cpp + libdshowcapture/source/device.hpp + libdshowcapture/source/dshow-base.cpp + libdshowcapture/source/dshow-base.hpp + libdshowcapture/source/dshow-demux.cpp + libdshowcapture/source/dshow-demux.hpp + libdshowcapture/source/dshow-device-defs.hpp + libdshowcapture/source/dshow-encoded-device.cpp + libdshowcapture/source/dshow-enum.cpp + libdshowcapture/source/dshow-enum.hpp + libdshowcapture/source/dshow-formats.cpp + libdshowcapture/source/dshow-formats.hpp + libdshowcapture/source/dshow-media-type.cpp + libdshowcapture/source/dshow-media-type.hpp + libdshowcapture/source/dshowcapture.cpp + libdshowcapture/source/dshowencode.cpp + libdshowcapture/source/encoder.cpp + libdshowcapture/source/encoder.hpp + libdshowcapture/source/external/IVideoCaptureFilter.h + libdshowcapture/source/log.cpp + libdshowcapture/source/log.hpp + libdshowcapture/source/output-filter.cpp + libdshowcapture/source/output-filter.hpp + libdshowcapture/external/capture-device-support/Library/EGAVResult.cpp + libdshowcapture/external/capture-device-support/Library/ElgatoUVCDevice.cpp + libdshowcapture/external/capture-device-support/Library/win/EGAVHIDImplementation.cpp + libdshowcapture/external/capture-device-support/SampleCode/DriverInterface.cpp) + +target_include_directories( + libdshowcapture INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture" + "${CMAKE_CURRENT_SOURCE_DIR}/libdshowcapture/external/capture-device-support/Library") + +target_compile_definitions(libdshowcapture INTERFACE _UP_WINDOWS=1) +target_compile_options(libdshowcapture INTERFACE /wd4018) + +get_target_property(target_sources libdshowcapture INTERFACE_SOURCES) +set(target_headers ${target_sources}) +set(target_external_sources ${target_sources}) + +list(FILTER target_external_sources INCLUDE REGEX ".+external/.+/.+\\.cpp") +list(FILTER target_sources EXCLUDE REGEX ".+external/.+/.+\\.cpp") +list(FILTER target_sources INCLUDE REGEX ".*\\.(m|c[cp]?p?|swift)") +list(FILTER target_headers INCLUDE REGEX ".*\\.h(pp)?") + +source_group("libdshowcapture-external\\Source Files" FILES ${target_external_sources}) +source_group("libdshowcapture\\Source Files" FILES ${target_sources}) +source_group("libdshowcapture\\Header Files" FILES ${target_headers}) diff --git a/plugins/win-dshow/cmake/windows/obs-module.rc.in b/plugins/win-dshow/cmake/windows/obs-module.rc.in new file mode 100644 index 000000000..fd2b76804 --- /dev/null +++ b/plugins/win-dshow/cmake/windows/obs-module.rc.in @@ -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 DirectShow 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-dshow" + VALUE "OriginalFilename", "win-dshow" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/plugins/win-dshow/virtualcam-module/CMakeLists.txt b/plugins/win-dshow/virtualcam-module/CMakeLists.txt index 6898c74c7..613c23778 100644 --- a/plugins/win-dshow/virtualcam-module/CMakeLists.txt +++ b/plugins/win-dshow/virtualcam-module/CMakeLists.txt @@ -1,59 +1,97 @@ -cmake_minimum_required(VERSION 3.5) -project(obs-virtualcam-module) +cmake_minimum_required(VERSION 3.24...3.25) -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_output_suffix "64") -else() - set(_output_suffix "32") +if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0) + option(ENABLE_VIRTUALCAM "Enable Windows Virtual Camera" ON) + if(NOT ENABLE_VIRTUALCAM) + target_disable_feature(obs-virtualcam-module "Virtual Camera Support") + target_disable(obs-virtualcam-module) + return() + endif() + + if(NOT VIRTUALCAM_GUID) + # cmake-format: off + set(VIRTUALCAM_GUID "" CACHE STRING "Virtual Camera GUID" FORCE) + mark_as_advanced(VIRTUALCAM_GUID) + # cmake-format: on + + message(WARNING "Empty Virtual Camera GUID set.") + target_disable_feature(obs-virtualcam-module "Virtual Camera Support (empty GUID)") + return() + else() + set(VALID_GUID FALSE) + check_uuid(${VIRTUALCAM_GUID} VALID_GUID) + + if(NOT VALID_GUID) + message(WARNING "Invalid Virtual Camera GUID set.") + target_disable_feature(obs-virtualcam-module "Virtual Camera Support (invalid GUID)") + return() + endif() + + # DirectShow API requires separate GUID tokens + string(REPLACE "-" ";" GUID_VALS ${VIRTUALCAM_GUID}) + list(GET GUID_VALS 0 GUID_VALS_DATA1) + list(GET GUID_VALS 1 GUID_VALS_DATA2) + list(GET GUID_VALS 2 GUID_VALS_DATA3) + list(GET GUID_VALS 3 GUID_VALS_DATA4) + list(GET GUID_VALS 4 GUID_VALS_DATA5) + set(GUID_VAL01 ${GUID_VALS_DATA1}) + set(GUID_VAL02 ${GUID_VALS_DATA2}) + set(GUID_VAL03 ${GUID_VALS_DATA3}) + string(SUBSTRING ${GUID_VALS_DATA4} 0 2 GUID_VAL04) + string(SUBSTRING ${GUID_VALS_DATA4} 2 2 GUID_VAL05) + string(SUBSTRING ${GUID_VALS_DATA5} 0 2 GUID_VAL06) + string(SUBSTRING ${GUID_VALS_DATA5} 2 2 GUID_VAL07) + string(SUBSTRING ${GUID_VALS_DATA5} 4 2 GUID_VAL08) + string(SUBSTRING ${GUID_VALS_DATA5} 6 2 GUID_VAL09) + string(SUBSTRING ${GUID_VALS_DATA5} 8 2 GUID_VAL10) + string(SUBSTRING ${GUID_VALS_DATA5} 10 2 GUID_VAL11) + endif() + + add_library(obs-virtualcam-guid INTERFACE) + add_library(OBS::virtualcam-guid ALIAS obs-virtualcam-guid) + + configure_file(virtualcam-guid.h.in virtualcam-guid.h) + target_sources(obs-virtualcam-guid INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-guid.h") + target_include_directories(obs-virtualcam-guid INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") + + add_library(_virtualcam INTERFACE) + + configure_file(cmake/windows/obs-module.rc.in virtualcam-module.rc) + target_sources(_virtualcam INTERFACE placeholder.cpp sleepto.c sleepto.h virtualcam-filter.cpp virtualcam-filter.hpp + virtualcam-module.cpp) + target_include_directories(_virtualcam INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") + target_compile_definitions(_virtualcam INTERFACE VIRTUALCAM_AVAILABLE) + target_compile_options(_virtualcam INTERFACE $,/MTd,/MT>) + + target_link_libraries( + _virtualcam + INTERFACE OBS::virtualcam-interface + OBS::virtualcam-guid + OBS::libdshowcapture + OBS::winhandle + gdiplus + strmiids + winmm) endif() +legacy_check() + add_library(obs-virtualcam-module MODULE) -add_library(OBS::virtualcam-module ALIAS obs-virtualcam-module) +add_library(OBS::virtualcam ALIAS obs-virtualcam-module) -target_sources( - obs-virtualcam-module - PRIVATE sleepto.c - sleepto.h - placeholder.cpp - virtualcam-module.cpp - virtualcam-filter.cpp - virtualcam-filter.hpp - virtualcam-module.rc - ../shared-memory-queue.c - ../shared-memory-queue.h - ../tiny-nv12-scale.c - ../tiny-nv12-scale.h) +target_sources(obs-virtualcam-module PRIVATE cmake/windows/virtualcam-module64.def) +target_link_libraries(obs-virtualcam-module PRIVATE _virtualcam) -target_include_directories(obs-virtualcam-module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..) +configure_file(virtualcam-install.bat.in virtualcam-install.bat) +target_add_resource(obs-virtualcam-module "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-install.bat" + "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow") -set(MODULE_DESCRIPTION "OBS Virtual Camera output module") +configure_file(virtualcam-uninstall.bat.in virtualcam-uninstall.bat) +target_add_resource(obs-virtualcam-module "${CMAKE_CURRENT_BINARY_DIR}/virtualcam-uninstall.bat" + "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow") -configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in virtualcam-module.rc) +include(cmake/32bit.cmake) -target_sources(obs-virtualcam-module PRIVATE virtualcam-module.rc) - -target_link_libraries(obs-virtualcam-module PRIVATE OBS::libdshowcapture OBS::libdshowcapture-external setupapi winmm - strmiids gdiplus) - -target_link_options(obs-virtualcam-module PRIVATE "LINKER:/ignore:4104") - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/virtualcam-module.def.in ${CMAKE_CURRENT_BINARY_DIR}/virtualcam-module.def) - -target_sources(obs-virtualcam-module PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/virtualcam-module.def) - -target_include_directories(obs-virtualcam-module PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../config) - -target_compile_definitions(obs-virtualcam-module PRIVATE VIRTUALCAM_AVAILABLE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS - _CRT_NONSTDC_NO_WARNINGS) - -if(MSVC) - target_compile_options(obs-virtualcam-module PRIVATE "$,/MTd,/MT>") - add_target_resource(win-dshow "$" "obs-plugins/win-dshow/" OPTIONAL) - -endif() - -set_target_properties(obs-virtualcam-module PROPERTIES FOLDER "plugins/win-dshow") - -set_target_properties(obs-virtualcam-module PROPERTIES OUTPUT_NAME "obs-virtualcam-module${_output_suffix}") - -add_target_resource(win-dshow "$" "obs-plugins/win-dshow/") +# cmake-format: off +set_target_properties_obs(obs-virtualcam-module PROPERTIES FOLDER plugins/win-dshow OUTPUT_NAME obs-virtualcam-module64) +# cmake-format: on diff --git a/plugins/win-dshow/virtualcam-module/cmake/32bit-build.cmake b/plugins/win-dshow/virtualcam-module/cmake/32bit-build.cmake new file mode 100644 index 000000000..553658c7e --- /dev/null +++ b/plugins/win-dshow/virtualcam-module/cmake/32bit-build.cmake @@ -0,0 +1,49 @@ +option(ENABLE_VIRTUALCAM "Enable Windows Virtual Camera" ON) +if(NOT ENABLE_VIRTUALCAM) + return() +endif() + +if(NOT VIRTUALCAM_GUID) + set(VIRTUALCAM_GUID + "" + CACHE STRING "Virtual Camera GUID" FORCE) + mark_as_advanced(VIRTUALCAM_GUID) + + message(WARNING "Empty Virtual Camera GUID set.") + return() +else() + set(VALID_GUID FALSE) + check_uuid(${VIRTUALCAM_GUID} VALID_GUID) + + if(NOT VALID_GUID) + message(WARNING "Invalid Virtual Camera GUID set.") + return() + endif() + + # DirectShow API requires separate GUID tokens + string(REPLACE "-" ";" GUID_VALS ${VIRTUALCAM_GUID}) + list(GET GUID_VALS 0 GUID_VALS_DATA1) + list(GET GUID_VALS 1 GUID_VALS_DATA2) + list(GET GUID_VALS 2 GUID_VALS_DATA3) + list(GET GUID_VALS 3 GUID_VALS_DATA4) + list(GET GUID_VALS 4 GUID_VALS_DATA5) + set(GUID_VAL01 ${GUID_VALS_DATA1}) + set(GUID_VAL02 ${GUID_VALS_DATA2}) + set(GUID_VAL03 ${GUID_VALS_DATA3}) + string(SUBSTRING ${GUID_VALS_DATA4} 0 2 GUID_VAL04) + string(SUBSTRING ${GUID_VALS_DATA4} 2 2 GUID_VAL05) + string(SUBSTRING ${GUID_VALS_DATA5} 0 2 GUID_VAL06) + string(SUBSTRING ${GUID_VALS_DATA5} 2 2 GUID_VAL07) + string(SUBSTRING ${GUID_VALS_DATA5} 4 2 GUID_VAL08) + string(SUBSTRING ${GUID_VALS_DATA5} 6 2 GUID_VAL09) + string(SUBSTRING ${GUID_VALS_DATA5} 8 2 GUID_VAL10) + string(SUBSTRING ${GUID_VALS_DATA5} 10 2 GUID_VAL11) +endif() + +add_library(obs-virtualcam-module MODULE) +add_library(OBS::virtualcam ALIAS obs-virtualcam-module) + +target_sources(obs-virtualcam-module PRIVATE cmake/windows/virtualcam-module32.def) +target_link_libraries(obs-virtualcam-module PRIVATE _virtualcam) + +set_property(TARGET obs-virtualcam-module PROPERTY OUTPUT_NAME obs-virtualcam-module32) diff --git a/plugins/win-dshow/virtualcam-module/cmake/32bit.cmake b/plugins/win-dshow/virtualcam-module/cmake/32bit.cmake new file mode 100644 index 000000000..daf4fca56 --- /dev/null +++ b/plugins/win-dshow/virtualcam-module/cmake/32bit.cmake @@ -0,0 +1,5 @@ +add_custom_command( + TARGET obs-virtualcam-module + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $ -t obs-virtualcam-module + COMMENT "Build 32-bit obs-virtualcam") diff --git a/plugins/win-dshow/virtualcam-module/cmake/legacy.cmake b/plugins/win-dshow/virtualcam-module/cmake/legacy.cmake new file mode 100644 index 000000000..1afd54a36 --- /dev/null +++ b/plugins/win-dshow/virtualcam-module/cmake/legacy.cmake @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.5) +project(obs-virtualcam-module) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_output_suffix "64") +else() + set(_output_suffix "32") +endif() + +add_library(obs-virtualcam-module MODULE) +add_library(OBS::virtualcam-module ALIAS obs-virtualcam-module) + +target_sources( + obs-virtualcam-module + PRIVATE sleepto.c + sleepto.h + placeholder.cpp + virtualcam-module.cpp + virtualcam-filter.cpp + virtualcam-filter.hpp + virtualcam-module.rc + ../shared-memory-queue.c + ../shared-memory-queue.h + ../tiny-nv12-scale.c + ../tiny-nv12-scale.h) + +target_include_directories(obs-virtualcam-module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..) + +set(MODULE_DESCRIPTION "OBS Virtual Camera output module") + +configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in virtualcam-module.rc) + +target_sources(obs-virtualcam-module PRIVATE virtualcam-module.rc) + +target_link_libraries(obs-virtualcam-module PRIVATE OBS::libdshowcapture OBS::libdshowcapture-external setupapi winmm + strmiids gdiplus) + +target_link_options(obs-virtualcam-module PRIVATE "LINKER:/ignore:4104") + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/virtualcam-module.def.in ${CMAKE_CURRENT_BINARY_DIR}/virtualcam-module.def) + +target_sources(obs-virtualcam-module PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/virtualcam-module.def) + +target_include_directories(obs-virtualcam-module PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../config + ${CMAKE_SOURCE_DIR}/libobs) + +target_compile_definitions(obs-virtualcam-module PRIVATE VIRTUALCAM_AVAILABLE UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS + _CRT_NONSTDC_NO_WARNINGS OBS_LEGACY) + +if(MSVC) + target_compile_options(obs-virtualcam-module PRIVATE "$,/MTd,/MT>") + add_target_resource(win-dshow "$" "obs-plugins/win-dshow/" OPTIONAL) + +endif() + +set_target_properties(obs-virtualcam-module PROPERTIES FOLDER "plugins/win-dshow") + +set_target_properties(obs-virtualcam-module PROPERTIES OUTPUT_NAME "obs-virtualcam-module${_output_suffix}") + +add_target_resource(win-dshow "$" "obs-plugins/win-dshow/") diff --git a/plugins/win-dshow/virtualcam-module/cmake/windows/obs-module.rc.in b/plugins/win-dshow/virtualcam-module/cmake/windows/obs-module.rc.in new file mode 100644 index 000000000..c5788b291 --- /dev/null +++ b/plugins/win-dshow/virtualcam-module/cmake/windows/obs-module.rc.in @@ -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 Virtual Camera output 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", "${PROJECT_NAME}" + VALUE "OriginalFilename", "${PROJECT_NAME}" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module32.def b/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module32.def new file mode 100644 index 000000000..d6b2256ab --- /dev/null +++ b/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module32.def @@ -0,0 +1,8 @@ +LIBRARY obs-virtualcam-module32.dll +EXPORTS + DllMain PRIVATE + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DllInstall PRIVATE diff --git a/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module64.def b/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module64.def new file mode 100644 index 000000000..034c9fa66 --- /dev/null +++ b/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module64.def @@ -0,0 +1,8 @@ +LIBRARY obs-virtualcam-module64.dll +EXPORTS + DllMain PRIVATE + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DllInstall PRIVATE diff --git a/plugins/win-dshow/virtualcam-module/virtualcam-filter.hpp b/plugins/win-dshow/virtualcam-module/virtualcam-filter.hpp index 14824cac6..66e43318a 100644 --- a/plugins/win-dshow/virtualcam-module/virtualcam-filter.hpp +++ b/plugins/win-dshow/virtualcam-module/virtualcam-filter.hpp @@ -3,12 +3,22 @@ #include #include #include + +#ifdef OBS_LEGACY #include "../shared-memory-queue.h" #include "../tiny-nv12-scale.h" #include "../libdshowcapture/source/output-filter.hpp" #include "../libdshowcapture/source/dshow-formats.hpp" #include "../../../libobs/util/windows/WinHandle.hpp" #include "../../../libobs/util/threading-windows.h" +#else +#include +#include +#include +#include +#include +#include +#endif typedef struct { int cx; diff --git a/plugins/win-dshow/virtualcam-guid.h.in b/plugins/win-dshow/virtualcam-module/virtualcam-guid.h.in similarity index 100% rename from plugins/win-dshow/virtualcam-guid.h.in rename to plugins/win-dshow/virtualcam-module/virtualcam-guid.h.in diff --git a/plugins/win-dshow/virtualcam-install.bat.in b/plugins/win-dshow/virtualcam-module/virtualcam-install.bat.in similarity index 100% rename from plugins/win-dshow/virtualcam-install.bat.in rename to plugins/win-dshow/virtualcam-module/virtualcam-install.bat.in diff --git a/plugins/win-dshow/virtualcam-uninstall.bat.in b/plugins/win-dshow/virtualcam-module/virtualcam-uninstall.bat.in similarity index 100% rename from plugins/win-dshow/virtualcam-uninstall.bat.in rename to plugins/win-dshow/virtualcam-module/virtualcam-uninstall.bat.in diff --git a/plugins/win-wasapi/CMakeLists.txt b/plugins/win-wasapi/CMakeLists.txt index bed4677cc..fa801ddde 100644 --- a/plugins/win-wasapi/CMakeLists.txt +++ b/plugins/win-wasapi/CMakeLists.txt @@ -1,18 +1,17 @@ -project(win-wasapi) +cmake_minimum_required(VERSION 3.24...3.25) + +legacy_check() add_library(win-wasapi MODULE) add_library(OBS::wasapi ALIAS win-wasapi) -target_sources(win-wasapi PRIVATE win-wasapi.cpp enum-wasapi.cpp enum-wasapi.hpp plugin-main.cpp) - -set(MODULE_DESCRIPTION "OBS WASAPI module") - -configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in win-wasapi.rc) +target_sources(win-wasapi PRIVATE enum-wasapi.cpp enum-wasapi.hpp plugin-main.cpp win-wasapi.cpp) +configure_file(cmake/windows/obs-module.rc.in win-wasapi.rc) target_sources(win-wasapi PRIVATE win-wasapi.rc) target_link_libraries(win-wasapi PRIVATE OBS::libobs Avrt) -set_target_properties(win-wasapi PROPERTIES FOLDER "plugins") - -setup_plugin_target(win-wasapi) +# cmake-format: off +set_target_properties_obs(win-wasapi PROPERTIES FOLDER plugins PREFIX "") +# cmake-format: on diff --git a/plugins/win-wasapi/cmake/legacy.cmake b/plugins/win-wasapi/cmake/legacy.cmake new file mode 100644 index 000000000..bed4677cc --- /dev/null +++ b/plugins/win-wasapi/cmake/legacy.cmake @@ -0,0 +1,18 @@ +project(win-wasapi) + +add_library(win-wasapi MODULE) +add_library(OBS::wasapi ALIAS win-wasapi) + +target_sources(win-wasapi PRIVATE win-wasapi.cpp enum-wasapi.cpp enum-wasapi.hpp plugin-main.cpp) + +set(MODULE_DESCRIPTION "OBS WASAPI module") + +configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/windows/obs-module.rc.in win-wasapi.rc) + +target_sources(win-wasapi PRIVATE win-wasapi.rc) + +target_link_libraries(win-wasapi PRIVATE OBS::libobs Avrt) + +set_target_properties(win-wasapi PROPERTIES FOLDER "plugins") + +setup_plugin_target(win-wasapi) diff --git a/plugins/win-wasapi/cmake/windows/obs-module.rc.in b/plugins/win-wasapi/cmake/windows/obs-module.rc.in new file mode 100644 index 000000000..07f7b276e --- /dev/null +++ b/plugins/win-wasapi/cmake/windows/obs-module.rc.in @@ -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 WASAPI 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-wasapi" + VALUE "OriginalFilename", "win-wasapi" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END