diff --git a/cmake/compile_definitions/windows.cmake b/cmake/compile_definitions/windows.cmake index 60ee905b773..9837896c3cb 100644 --- a/cmake/compile_definitions/windows.cmake +++ b/cmake/compile_definitions/windows.cmake @@ -38,13 +38,16 @@ if(NOT DEFINED SUNSHINE_ICON_PATH) set(SUNSHINE_ICON_PATH "${CMAKE_SOURCE_DIR}/sunshine.ico") endif() +# For cross-compilation with llvm-rc, use relative path from build dir +file(RELATIVE_PATH SUNSHINE_ICON_RELATIVE "${CMAKE_BINARY_DIR}" "${SUNSHINE_ICON_PATH}") + # Create a separate object library for the RC file with minimal includes add_library(sunshine_rc_object OBJECT "${CMAKE_SOURCE_DIR}/src/platform/windows/windows.rc") # Set minimal properties for RC compilation - only what's needed for the resource file # Otherwise compilation can fail due to "line too long" errors set_target_properties(sunshine_rc_object PROPERTIES - COMPILE_DEFINITIONS "PROJECT_ICON_PATH=${SUNSHINE_ICON_PATH};PROJECT_NAME=${PROJECT_NAME};PROJECT_VENDOR=${SUNSHINE_PUBLISHER_NAME};PROJECT_VERSION=${PROJECT_VERSION};PROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR};PROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR};PROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}" # cmake-lint: disable=C0301 + COMPILE_DEFINITIONS "PROJECT_ICON_PATH=\"${SUNSHINE_ICON_RELATIVE}\";PROJECT_NAME=${PROJECT_NAME};PROJECT_VENDOR=\"${SUNSHINE_PUBLISHER_NAME}\";PROJECT_VERSION=${PROJECT_VERSION};PROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR};PROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR};PROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}" # cmake-lint: disable=C0301 INCLUDE_DIRECTORIES "" ) diff --git a/cmake/toolchains/aarch64-w64-mingw32.cmake b/cmake/toolchains/aarch64-w64-mingw32.cmake new file mode 100644 index 00000000000..89f75fe706f --- /dev/null +++ b/cmake/toolchains/aarch64-w64-mingw32.cmake @@ -0,0 +1,39 @@ +# CMake toolchain file for cross-compiling to Windows ARM64 +# using llvm-mingw toolchain + +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +# Toolchain paths - adjust TOOLCHAIN_ROOT as needed +if(NOT DEFINED TOOLCHAIN_ROOT) + set(TOOLCHAIN_ROOT "$ENV{HOME}/toolchains/llvm-mingw") +endif() + +set(TARGET_TRIPLE "aarch64-w64-mingw32") + +# Compilers +set(CMAKE_C_COMPILER "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-clang") +set(CMAKE_CXX_COMPILER "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-clang++") +set(CMAKE_RC_COMPILER "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-windres") +set(CMAKE_AR "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-ar") +set(CMAKE_RANLIB "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-ranlib") + +# Sysroot +set(CMAKE_SYSROOT "${TOOLCHAIN_ROOT}/${TARGET_TRIPLE}") +set(CMAKE_FIND_ROOT_PATH "${TOOLCHAIN_ROOT}/${TARGET_TRIPLE}") + +# Search paths +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +# Compiler flags +set(CMAKE_C_FLAGS_INIT "-D_WIN32_WINNT=0x0A00") +set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++ -D_WIN32_WINNT=0x0A00") +set(CMAKE_EXE_LINKER_FLAGS_INIT "-static -lc++ -lc++abi") +set(CMAKE_SHARED_LINKER_FLAGS_INIT "-static -lc++ -lc++abi") + +# Windows-specific +set(WIN32 TRUE) +set(MINGW TRUE) diff --git a/docs/BUILD-ARM64.md b/docs/BUILD-ARM64.md new file mode 100644 index 00000000000..49b9c555959 --- /dev/null +++ b/docs/BUILD-ARM64.md @@ -0,0 +1,242 @@ +# Building Sunshine for Windows ARM64 + +This guide covers cross-compiling Sunshine for Windows ARM64 (Qualcomm Snapdragon) from a Linux host using the llvm-mingw toolchain. + +## Prerequisites + +- Ubuntu 22.04+ or WSL2 +- ~10GB disk space +- Internet connection for downloading dependencies + +## Quick Start + +```bash +# Install build tools +sudo apt update +sudo apt install -y cmake ninja-build git curl wget pkg-config \ + python3 nodejs npm nasm + +# Download llvm-mingw toolchain +cd ~ +wget https://github.com/mstorsjo/llvm-mingw/releases/download/20241119/llvm-mingw-20241119-ucrt-ubuntu-22.04-x86_64.tar.xz +tar xf llvm-mingw-20241119-ucrt-ubuntu-22.04-x86_64.tar.xz +mv llvm-mingw-20241119-ucrt-ubuntu-22.04-x86_64 toolchains/llvm-mingw + +# Clone Sunshine +git clone --recursive https://github.com/LizardByte/Sunshine.git +cd Sunshine +``` + +## Building Dependencies + +The following dependencies must be built for ARM64. Create a working directory: + +```bash +mkdir -p ~/deps-arm64/install +cd ~/deps-arm64 +export TC=~/toolchains/llvm-mingw +export TARGET=aarch64-w64-mingw32 +export PREFIX=~/deps-arm64/install +``` + +### OpenSSL 3.4.0 + +```bash +wget https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz +tar xf openssl-3.4.0.tar.gz +cd openssl-3.4.0 + +./Configure mingw64 --cross-compile-prefix=$TC/bin/$TARGET- \ + --prefix=$PREFIX --libdir=lib no-shared no-tests +make -j$(nproc) +make install_sw +cd .. +``` + +### libcurl 8.11.1 + +```bash +wget https://curl.se/download/curl-8.11.1.tar.xz +tar xf curl-8.11.1.tar.xz +cd curl-8.11.1 +mkdir build && cd build + +cmake .. -G Ninja \ + -DCMAKE_TOOLCHAIN_FILE=~/Sunshine/cmake/toolchains/aarch64-w64-mingw32.cmake \ + -DCMAKE_PREFIX_PATH=$PREFIX \ + -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DBUILD_SHARED_LIBS=OFF \ + -DCURL_USE_OPENSSL=ON \ + -DCURL_DISABLE_LDAP=ON \ + -DBUILD_CURL_EXE=OFF \ + -DBUILD_TESTING=OFF + +ninja && ninja install +cd ../.. +``` + +### miniupnpc 2.2.8 + +```bash +wget https://github.com/miniupnp/miniupnp/archive/refs/tags/miniupnpc_2_2_8.tar.gz +tar xf miniupnpc_2_2_8.tar.gz +cd miniupnp-miniupnpc_2_2_8/miniupnpc +mkdir build && cd build + +cmake .. -G Ninja \ + -DCMAKE_TOOLCHAIN_FILE=~/Sunshine/cmake/toolchains/aarch64-w64-mingw32.cmake \ + -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DUPNPC_BUILD_STATIC=ON \ + -DUPNPC_BUILD_SHARED=OFF \ + -DUPNPC_BUILD_TESTS=OFF \ + -DUPNPC_BUILD_SAMPLE=OFF + +ninja && ninja install +cd ../../.. +``` + +### Opus 1.5.2 + +```bash +wget https://github.com/xiph/opus/releases/download/v1.5.2/opus-1.5.2.tar.gz +tar xf opus-1.5.2.tar.gz +cd opus-1.5.2 +mkdir build && cd build + +cmake .. -G Ninja \ + -DCMAKE_TOOLCHAIN_FILE=~/Sunshine/cmake/toolchains/aarch64-w64-mingw32.cmake \ + -DCMAKE_INSTALL_PREFIX=$PREFIX \ + -DBUILD_SHARED_LIBS=OFF \ + -DOPUS_BUILD_TESTING=OFF \ + -DOPUS_BUILD_PROGRAMS=OFF + +ninja && ninja install +cd ../.. +``` + +### Stub Libraries + +Some libraries are not available on ARM64 and require stubs: + +#### MinHook (not available on ARM64) + +```bash +mkdir -p $PREFIX/lib +cat > /tmp/minhook_stub.c << 'EOF' +int MH_Initialize(void) { return 0; } +int MH_Uninitialize(void) { return 0; } +int MH_CreateHook(void *a, void *b, void **c) { return 0; } +int MH_EnableHook(void *a) { return 0; } +int MH_DisableHook(void *a) { return 0; } +EOF +$TC/bin/$TARGET-clang -c /tmp/minhook_stub.c -o /tmp/minhook_stub.o +$TC/bin/$TARGET-ar rcs $PREFIX/lib/libMinHook.a /tmp/minhook_stub.o +``` + +#### VPL (Intel QuickSync - not available on ARM64) + +```bash +cat > /tmp/vpl_stub.c << 'EOF' +int MFXInit(int a, void *b, void **c) { return -1; } +int MFXClose(void *a) { return 0; } +int MFXQueryVersion(void *a, void *b) { return -1; } +int MFXInitEx(void *a, void **b) { return -1; } +EOF +$TC/bin/$TARGET-clang -c /tmp/vpl_stub.c -o /tmp/vpl_stub.o +$TC/bin/$TARGET-ar rcs $PREFIX/lib/libvpl.a /tmp/vpl_stub.o + +mkdir -p $PREFIX/include/vpl +cat > $PREFIX/include/vpl/mfxvideo.h << 'EOF' +#pragma once +typedef int mfxStatus; +typedef void* mfxSession; +EOF +``` + +## CMake Toolchain File + +Create `cmake/toolchains/aarch64-w64-mingw32.cmake`: + +```cmake +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +set(TOOLCHAIN_ROOT "$ENV{HOME}/toolchains/llvm-mingw") +set(TARGET_TRIPLE "aarch64-w64-mingw32") + +set(CMAKE_C_COMPILER "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-clang") +set(CMAKE_CXX_COMPILER "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-clang++") +set(CMAKE_RC_COMPILER "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-windres") +set(CMAKE_AR "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-ar") +set(CMAKE_RANLIB "${TOOLCHAIN_ROOT}/bin/${TARGET_TRIPLE}-ranlib") + +set(CMAKE_FIND_ROOT_PATH "${TOOLCHAIN_ROOT}/${TARGET_TRIPLE}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(CMAKE_CXX_FLAGS_INIT "-stdlib=libc++ -D_WIN32_WINNT=0x0A00") +set(CMAKE_EXE_LINKER_FLAGS_INIT "-static -lc++ -lc++abi") +``` + +## Building Sunshine + +```bash +cd ~/Sunshine +mkdir build-arm64 && cd build-arm64 + +cmake .. -G Ninja \ + -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/aarch64-w64-mingw32.cmake \ + -DCMAKE_PREFIX_PATH="$PREFIX;$HOME/Sunshine/third-party/build-deps/dist/Windows-ARM64" \ + -DCMAKE_BUILD_TYPE=Release \ + -DSUNSHINE_ENABLE_TRAY=OFF \ + -DSUNSHINE_ENABLE_DRM=OFF \ + -DSUNSHINE_ENABLE_WAYLAND=OFF \ + -DSUNSHINE_ENABLE_X11=OFF \ + -DSUNSHINE_ENABLE_CUDA=OFF \ + -DSUNSHINE_BUILD_APPIMAGE=OFF \ + -DSUNSHINE_PUBLISHER_NAME="LizardByte" + +ninja sunshine.exe +``` + +## Running on Windows ARM64 + +1. Copy the built files to your Windows ARM64 device: + - `sunshine.exe` + - `assets/` folder (from `src_assets/windows/assets/`) + +2. Install ViGEmBus driver for controller support + +3. Run `sunshine.exe` from an elevated command prompt + +## Hardware Encoding + +Sunshine will automatically detect and use the Qualcomm Adreno GPU for hardware encoding via Windows Media Foundation: + +- **h264_mf**: H.264 hardware encoding +- **hevc_mf**: HEVC hardware encoding +- **av1_mf**: AV1 hardware encoding (if supported) + +### Known Limitations + +- Only SDR 4:2:0 8-bit encoding supported (Qualcomm MF limitation) +- No HDR or YUV444 support +- ~8ms encoder latency overhead compared to direct GPU APIs +- Software encoding (libx264) may perform better in some cases + +To use software encoding, set `encoder = software` in `sunshine.conf`. + +## Troubleshooting + +### "Encoder did not produce IDR frame" +This is normal for the first frame with Media Foundation encoders. The encoder uses a fixed GOP size of 120 frames. + +### Large encoded frames / FEC warnings +The Media Foundation encoder may produce larger keyframes. This is handled automatically but may cause occasional FEC skip warnings. + +### Shader compilation errors +Ensure the `assets/shaders/` directory is present alongside `sunshine.exe`. + +### No GPU detected +Verify the Qualcomm Adreno driver is installed. Check Device Manager for the GPU. diff --git a/src/config.cpp b/src/config.cpp index 8e231a1f826..63d9b07b19f 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -187,7 +187,7 @@ namespace config { }; template - std::optional quality_from_view(const std::string_view &quality_type, const std::optional(&original)) { + ::std::optional quality_from_view(const ::std::string_view &quality_type, const ::std::optional(&original)) { #define _CONVERT_(x) \ if (quality_type == #x##sv) \ return (int) T::x @@ -199,7 +199,7 @@ namespace config { } template - std::optional rc_from_view(const std::string_view &rc, const std::optional(&original)) { + ::std::optional rc_from_view(const ::std::string_view &rc, const ::std::optional(&original)) { #define _CONVERT_(x) \ if (rc == #x##sv) \ return (int) T::x @@ -212,7 +212,7 @@ namespace config { } template - std::optional usage_from_view(const std::string_view &usage, const std::optional(&original)) { + ::std::optional usage_from_view(const ::std::string_view &usage, const ::std::optional(&original)) { #define _CONVERT_(x) \ if (usage == #x##sv) \ return (int) T::x @@ -225,7 +225,7 @@ namespace config { return original; } - int coder_from_view(const std::string_view &coder) { + int coder_from_view(const ::std::string_view &coder) { if (coder == "auto"sv) { return _auto; } @@ -295,7 +295,7 @@ namespace config { cavlc ///< CAVLC }; - int coder_from_view(const std::string_view &coder) { + int coder_from_view(const ::std::string_view &coder) { if (coder == "auto"sv) { return _auto; } diff --git a/src/platform/common.h b/src/platform/common.h index 5ba57027221..71dc4d8999d 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -52,13 +52,16 @@ namespace boost { class path; } - namespace process::inline v1 { - class child; - class group; - template - class basic_environment; - typedef basic_environment environment; - } // namespace process::inline v1 + namespace process { + namespace v1 { + class child; + class group; + template + class basic_environment; + typedef basic_environment environment; + } // namespace v1 + using namespace v1; + } // namespace process } // namespace boost #endif namespace video { diff --git a/src/platform/windows/audio.cpp b/src/platform/windows/audio.cpp index 98af1e75bc8..986000101bf 100644 --- a/src/platform/windows/audio.cpp +++ b/src/platform/windows/audio.cpp @@ -32,8 +32,11 @@ DEFINE_PROPERTYKEY(PKEY_DeviceInterface_FriendlyName, 0x026e516e, 0xb814, 0x414b #if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) #define STEAM_DRIVER_SUBDIR L"x64" +#elif defined(__aarch64__) || defined(_M_ARM64) + #define STEAM_DRIVER_SUBDIR L"arm64" #else #warning No known Steam audio driver for this architecture + #define STEAM_DRIVER_SUBDIR L"unknown" #endif namespace { diff --git a/src/platform/windows/display.h b/src/platform/windows/display.h index a1f2b96fe43..cd828d32c3b 100644 --- a/src/platform/windows/display.h +++ b/src/platform/windows/display.h @@ -12,6 +12,9 @@ #include #include #include +#ifdef __clang__ +#include "include/wgc_interop_guids.h" +#endif #include // local includes diff --git a/src/platform/windows/display_vram.cpp b/src/platform/windows/display_vram.cpp index cf6b4c43d5c..4b989f49637 100644 --- a/src/platform/windows/display_vram.cpp +++ b/src/platform/windows/display_vram.cpp @@ -1906,6 +1906,12 @@ namespace platf::dxgi { if (!boost::algorithm::ends_with(name, "_nvenc")) { return false; } + } else if (adapter_desc.VendorId == 0x4D4F4351 || // Qualcomm (QCOM as MOQC reversed) + adapter_desc.VendorId == 0x5143) { // Qualcomm alternate ID + // If it's not a MediaFoundation encoder, it's not compatible with a Qualcomm GPU + if (!boost::algorithm::ends_with(name, "_mf")) { + return false; + } } else { BOOST_LOG(warning) << "Unknown GPU vendor ID: " << util::hex(adapter_desc.VendorId).to_string_view(); } diff --git a/src/platform/windows/display_wgc.cpp b/src/platform/windows/display_wgc.cpp index 15cab763708..8ce5eb088b3 100644 --- a/src/platform/windows/display_wgc.cpp +++ b/src/platform/windows/display_wgc.cpp @@ -13,6 +13,11 @@ // Gross hack to work around MINGW-packages#22160 #define ____FIReference_1_boolean_INTERFACE_DEFINED__ +// GUID specializations for clang compatibility +#ifdef __clang__ +#include "include/wgc_interop_guids.h" +#endif + #include #include #include diff --git a/src/platform/windows/include/wgc_interop_guids.h b/src/platform/windows/include/wgc_interop_guids.h new file mode 100644 index 00000000000..82791622394 --- /dev/null +++ b/src/platform/windows/include/wgc_interop_guids.h @@ -0,0 +1,25 @@ +/** + * @file wgc_interop_guids.h + * @brief Windows Graphics Capture Interop GUIDs for clang/llvm-mingw compatibility + * + * Provides __mingw_uuidof specialization for IGraphicsCaptureItemInterop + * which is required for constexpr GUID evaluation with clang. + */ +#pragma once + +#ifndef WGC_INTEROP_GUIDS_H +#define WGC_INTEROP_GUIDS_H + +#include + +// Forward declare the interface +struct IGraphicsCaptureItemInterop; + +// MinGW UUID specialization for constexpr evaluation +template<> +constexpr const GUID & __mingw_uuidof() { + static constexpr GUID guid = { 0x3628E81B, 0x3CAC, 0x4C60, { 0xB7, 0xF4, 0x23, 0xCE, 0x0E, 0x0C, 0x33, 0x56 } }; + return guid; +} + +#endif // WGC_INTEROP_GUIDS_H diff --git a/src/video.cpp b/src/video.cpp index 55bd322ad5d..dc6e4cc1987 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -300,6 +300,7 @@ namespace video { ALWAYS_REPROBE = 1 << 9, ///< This is an encoder of last resort and we want to aggressively probe for a better one YUV444_SUPPORT = 1 << 10, ///< Encoder may support 4:4:4 chroma sampling depending on hardware ASYNC_TEARDOWN = 1 << 11, ///< Encoder supports async teardown on a different thread + FIXED_GOP_SIZE = 1 << 12, ///< Use fixed small GOP size (encoder doesn't support on-demand IDR frames) }; class avcodec_encode_session_t: public encode_session_t { @@ -825,6 +826,63 @@ namespace video { }, PARALLEL_ENCODING }; + + encoder_t mediafoundation { + "mediafoundation"sv, + std::make_unique( + AV_HWDEVICE_TYPE_D3D11VA, + AV_HWDEVICE_TYPE_NONE, + AV_PIX_FMT_D3D11, + AV_PIX_FMT_NV12, // SDR 4:2:0 8-bit (only format Qualcomm supports) + AV_PIX_FMT_NONE, // No HDR - Qualcomm MF only supports 8-bit + AV_PIX_FMT_NONE, // No YUV444 SDR + AV_PIX_FMT_NONE, // No YUV444 HDR + dxgi_init_avcodec_hardware_input_buffer + ), + { + // Common options for AV1 - Qualcomm MF encoder + { + {"hw_encoding"s, 1}, + {"rate_control"s, "cbr"s}, + {"scenario"s, "display_remoting"s}, + }, + {}, // SDR-specific options + {}, // HDR-specific options + {}, // YUV444 SDR-specific options + {}, // YUV444 HDR-specific options + {}, // Fallback options + "av1_mf"s, + }, + { + // Common options for HEVC - Qualcomm MF encoder + { + {"hw_encoding"s, 1}, + {"rate_control"s, "cbr"s}, + {"scenario"s, "display_remoting"s}, + }, + {}, // SDR-specific options + {}, // HDR-specific options + {}, // YUV444 SDR-specific options + {}, // YUV444 HDR-specific options + {}, // Fallback options + "hevc_mf"s, + }, + { + // Common options for H.264 - Qualcomm MF encoder + { + {"hw_encoding"s, 1}, + {"rate_control"s, "cbr"s}, + {"scenario"s, "display_remoting"s}, + }, + {}, // SDR-specific options + {}, // HDR-specific options + {}, // YUV444 SDR-specific options + {}, // YUV444 HDR-specific options + {}, // Fallback options + "h264_mf"s, + }, + PARALLEL_ENCODING | FIXED_GOP_SIZE // MF encoder doesn't support on-demand IDR frames + }; #endif encoder_t software { @@ -1031,6 +1089,7 @@ namespace video { #ifdef _WIN32 &quicksync, &amdvce, + &mediafoundation, #endif #if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__) &vaapi, @@ -1565,11 +1624,17 @@ namespace video { ctx->max_b_frames = 0; // Use an infinite GOP length since I-frames are generated on demand - ctx->gop_size = encoder.flags & LIMITED_GOP_SIZE ? - std::numeric_limits::max() : - std::numeric_limits::max(); - - ctx->keyint_min = std::numeric_limits::max(); + // Exception: encoders with FIXED_GOP_SIZE flag don't support on-demand IDR + if (encoder.flags & FIXED_GOP_SIZE) { + // Fixed GOP for encoders that don't support on-demand IDR (e.g. Media Foundation) + ctx->gop_size = 120; // ~2 seconds at 60 FPS - larger to reduce oversized IDR frame frequency + ctx->keyint_min = 120; + } else { + ctx->gop_size = encoder.flags & LIMITED_GOP_SIZE ? + std::numeric_limits::max() : + std::numeric_limits::max(); + ctx->keyint_min = std::numeric_limits::max(); + } // Some client decoders have limits on the number of reference frames if (config.numRefFrames) { diff --git a/src/video.h b/src/video.h index 8dbf76e27bd..eb8bb46f0dd 100644 --- a/src/video.h +++ b/src/video.h @@ -220,6 +220,7 @@ namespace video { #ifdef _WIN32 extern encoder_t amdvce; extern encoder_t quicksync; + extern encoder_t mediafoundation; #endif #if defined(__linux__) || defined(linux) || defined(__linux) || defined(__FreeBSD__)