Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ if(${END_BUILD})
return()
endif()

# Build-deps owns the dependency versions shared with its FFmpeg builds.
# Include its lock only for full builds so manifest-only configurations do not
# require the build-deps submodule.
include(${CMAKE_CURRENT_SOURCE_DIR}/third-party/build-deps/package-lock.cmake)

# project constants
include(${CMAKE_MODULE_PATH}/prep/constants.cmake)

Expand Down
11 changes: 4 additions & 7 deletions cmake/compile_definitions/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ if(WIN32)
add_nvenc_sdk_implementation(nvenc_sdk_1100 1100 "${NV_CODEC_HEADERS_11_INCLUDE_DIR}")
add_nvenc_sdk_implementation(nvenc_sdk_1200 1200 "${NV_CODEC_HEADERS_12_INCLUDE_DIR}")
add_nvenc_sdk_implementation(nvenc_sdk_1300 1300 "${NV_CODEC_HEADERS_13_INCLUDE_DIR}")
add_nvenc_sdk_implementation(nvenc_sdk_1301 1301 "${NV_CODEC_HEADERS_13_1_INCLUDE_DIR}")

list(APPEND NVENC_SOURCES
$<TARGET_OBJECTS:nvenc_sdk_1100>
$<TARGET_OBJECTS:nvenc_sdk_1200>
$<TARGET_OBJECTS:nvenc_sdk_1300>
$<TARGET_OBJECTS:nvenc_sdk_1301>
)
endif()

Expand Down Expand Up @@ -209,13 +211,8 @@ include_directories(
${Boost_INCLUDE_DIRS} # has to be the last, or we get runtime error on macOS ffmpeg encoder
)

if(WIN32)
include_directories(BEFORE SYSTEM "${NV_CODEC_HEADERS_13_INCLUDE_DIR}")
else()
include_directories(
BEFORE SYSTEM
"${CMAKE_SOURCE_DIR}/third-party/build-deps/third-party/FFmpeg/nv-codec-headers/include"
)
if(NOT APPLE)
include_directories(BEFORE SYSTEM "${NV_CODEC_HEADERS_13_1_INCLUDE_DIR}")
endif()

list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
Expand Down
23 changes: 23 additions & 0 deletions cmake/dependencies/nv_codec_headers.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# Keep build-deps-owned declarations out of Sunshine's generated package lock.
set(SUNSHINE_CPM_PACKAGE_LOCK_ENABLED "${CPM_PACKAGE_LOCK_ENABLED}")
set(CPM_PACKAGE_LOCK_ENABLED OFF)

if(NOT APPLE)
set(SUNSHINE_PREPARED_NV_CODEC_HEADERS
"${FFMPEG_PREPARED_BINARIES}/include/ffnvcodec/nvEncodeAPI.h")

if(DEFINED FFMPEG_PREPARED_BINARIES AND EXISTS "${SUNSHINE_PREPARED_NV_CODEC_HEADERS}")
# Prepared FFmpeg bundles include the NV codec headers used to build them.
set(NV_CODEC_HEADERS_13_1_INCLUDE_DIR "${FFMPEG_PREPARED_BINARIES}/include")
message(STATUS "Using NV codec headers from prepared FFmpeg binaries")
else()
CPMGetPackage(nv_codec_headers_13_1)
set(NV_CODEC_HEADERS_13_1_INCLUDE_DIR "${nv_codec_headers_13_1_SOURCE_DIR}/include")
endif()

unset(SUNSHINE_PREPARED_NV_CODEC_HEADERS)
endif()

if(WIN32)
CPMGetPackage(nv_codec_headers_13)
CPMGetPackage(nv_codec_headers_11)
Expand All @@ -7,3 +27,6 @@ if(WIN32)
set(NV_CODEC_HEADERS_12_INCLUDE_DIR "${nv_codec_headers_12_SOURCE_DIR}/include")
set(NV_CODEC_HEADERS_13_INCLUDE_DIR "${nv_codec_headers_13_SOURCE_DIR}/include")
endif()

set(CPM_PACKAGE_LOCK_ENABLED "${SUNSHINE_CPM_PACKAGE_LOCK_ENABLED}")
unset(SUNSHINE_CPM_PACKAGE_LOCK_ENABLED)
35 changes: 1 addition & 34 deletions package-lock.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,4 @@
# - `set(EXAMPLE_SHA256 <sha256>)`
# - `CPMDeclarePackage(...)`

set(PATCH_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/patches")

# NVENC SDK 11.0 headers
# renovate: datasource=github-tags depName=FFmpeg/nv-codec-headers
# versioning=regex:^n(?<major>11)\.(?<minor>0)\.(?<patch>\d+)\.(?<build>\d+)$
set(NV_CODEC_HEADERS_11_TAG n11.0.10.3)
CPMDeclarePackage(nv_codec_headers_11
NAME nv_codec_headers_11
GIT_REPOSITORY https://github.com/FFmpeg/nv-codec-headers.git
GIT_TAG ${NV_CODEC_HEADERS_11_TAG}
DOWNLOAD_ONLY YES
)

# NVENC SDK 12.0 headers
# renovate: datasource=github-tags depName=FFmpeg/nv-codec-headers
# versioning=regex:^n(?<major>12)\.(?<minor>0)\.(?<patch>\d+)\.(?<build>\d+)$
set(NV_CODEC_HEADERS_12_TAG n12.0.16.2)
CPMDeclarePackage(nv_codec_headers_12
NAME nv_codec_headers_12
GIT_REPOSITORY https://github.com/FFmpeg/nv-codec-headers.git
GIT_TAG ${NV_CODEC_HEADERS_12_TAG}
DOWNLOAD_ONLY YES
)

# NVENC SDK 13.0 headers
# renovate: datasource=github-tags depName=FFmpeg/nv-codec-headers
# versioning=regex:^n(?<major>13)\.(?<minor>0)\.(?<patch>\d+)\.(?<build>\d+)$
set(NV_CODEC_HEADERS_13_TAG n13.0.19.1)
CPMDeclarePackage(nv_codec_headers_13
NAME nv_codec_headers_13
GIT_REPOSITORY https://github.com/FFmpeg/nv-codec-headers.git
GIT_TAG ${NV_CODEC_HEADERS_13_TAG}
DOWNLOAD_ONLY YES
)
set(PATCH_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/patches")
8 changes: 4 additions & 4 deletions packaging/linux/flatpak/modules/ffmpeg.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"sources": [
{
"type": "file",
"url": "https://github.com/LizardByte/build-deps/releases/download/v2026.905.170812/Linux-x86_64-ffmpeg.tar.gz",
"sha256": "880f0b9983ea9b55a6cceb2e5afa6388e256751f3cac2baf4ef0cf6eedc57aea",
"url": "https://github.com/LizardByte/build-deps/releases/download/v2026.910.121303/Linux-x86_64-ffmpeg.tar.gz",
"sha256": "496d2bbb674d01e6033e31b9dfc15cbc9dc1494e882a4505f6ab1e03f75b385c",
"dest-filename": "ffmpeg.tar.gz",
"only-arches": [
"x86_64"
Expand All @@ -23,8 +23,8 @@
},
{
"type": "file",
"url": "https://github.com/LizardByte/build-deps/releases/download/v2026.905.170812/Linux-aarch64-ffmpeg.tar.gz",
"sha256": "096069f2737a93ff44ba6445b700213708ab1fec01fd015e528a47845b5fde46",
"url": "https://github.com/LizardByte/build-deps/releases/download/v2026.910.121303/Linux-aarch64-ffmpeg.tar.gz",
"sha256": "21f99409e1aba09191f9df28688fb7f9d44f98e65378a651324c632c19823aa0",
"dest-filename": "ffmpeg.tar.gz",
"only-arches": [
"aarch64"
Expand Down
8 changes: 6 additions & 2 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@

namespace nv {

std::string ffmpeg_preset_from_quality(const int quality_preset) {
return std::format("p{}", quality_preset);
}

/**
* @brief Parse the `nvenc_twopass` configuration value.
*
Expand Down Expand Up @@ -267,7 +271,7 @@
_CONVERT_(balanced);
_CONVERT_(quality);
_CONVERT_(speed);
#undef _CONVERT_

Check failure on line 274 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i2&open=AaCIsislic2y3LVY46i2&pullRequest=5668
return original;
}

Expand All @@ -289,7 +293,7 @@
_CONVERT_(cqp);
_CONVERT_(vbr_latency);
_CONVERT_(vbr_peak);
#undef _CONVERT_

Check failure on line 296 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i3&open=AaCIsislic2y3LVY46i3&pullRequest=5668
return original;
}

Expand All @@ -312,7 +316,7 @@
_CONVERT_(transcoding);
_CONVERT_(ultralowlatency);
_CONVERT_(webcam);
#undef _CONVERT_

Check failure on line 319 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i4&open=AaCIsislic2y3LVY46i4&pullRequest=5668
return original;
}

Expand Down Expand Up @@ -379,7 +383,7 @@
_CONVERT_(fast);
_CONVERT_(faster);
_CONVERT_(veryfast);
#undef _CONVERT_

Check failure on line 386 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i5&open=AaCIsislic2y3LVY46i5&pullRequest=5668
return std::nullopt;
}

Expand Down Expand Up @@ -584,7 +588,7 @@
_CONVERT_(veryfast, 10);
_CONVERT_(superfast, 11);
_CONVERT_(ultrafast, 12);
#undef _CONVERT_

Check failure on line 591 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i6&open=AaCIsislic2y3LVY46i6&pullRequest=5668
return 11; // Default to superfast
}
} // namespace sw
Expand All @@ -607,7 +611,7 @@
_CONVERT_(ensure_active);
_CONVERT_(ensure_primary);
_CONVERT_(ensure_only_display);
#undef _CONVERT_

Check failure on line 614 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i7&open=AaCIsislic2y3LVY46i7&pullRequest=5668
return video_t::dd_t::config_option_e::disabled; // Default to this if value is invalid
}

Expand All @@ -627,8 +631,8 @@
_CONVERT_(disabled);
_CONVERT_2_ARG_(auto, automatic);
_CONVERT_(manual);
#undef _CONVERT_

Check failure on line 634 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i8&open=AaCIsislic2y3LVY46i8&pullRequest=5668
#undef _CONVERT_2_ARG_

Check failure on line 635 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i9&open=AaCIsislic2y3LVY46i9&pullRequest=5668
return video_t::dd_t::resolution_option_e::disabled; // Default to this if value is invalid
}

Expand All @@ -648,8 +652,8 @@
_CONVERT_(disabled);
_CONVERT_2_ARG_(auto, automatic);
_CONVERT_(manual);
#undef _CONVERT_

Check failure on line 655 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i-&open=AaCIsislic2y3LVY46i-&pullRequest=5668
#undef _CONVERT_2_ARG_

Check failure on line 656 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46i_&open=AaCIsislic2y3LVY46i_&pullRequest=5668
return video_t::dd_t::refresh_rate_option_e::disabled; // Default to this if value is invalid
}

Expand All @@ -668,8 +672,8 @@
#endif
_CONVERT_(disabled);
_CONVERT_2_ARG_(auto, automatic);
#undef _CONVERT_

Check failure on line 675 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46jA&open=AaCIsislic2y3LVY46jA&pullRequest=5668
#undef _CONVERT_2_ARG_

Check failure on line 676 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this #undef directive that undefines a non-existing macro.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46jB&open=AaCIsislic2y3LVY46jB&pullRequest=5668
return video_t::dd_t::hdr_option_e::disabled; // Default to this if value is invalid
}

Expand Down Expand Up @@ -710,89 +714,89 @@
/**
* @brief Default video configuration values used before file and CLI overrides.
*/
video_t video {
28, // qp

0, // hevc_mode
0, // av1_mode

2, // min_threads
{
"superfast"s, // preset
"zerolatency"s, // tune
11, // superfast
}, // software

{}, // nv
true, // nv_realtime_hags
true, // nv_opengl_vulkan_on_dxgi
true, // nv_sunshine_high_power_mode
{}, // nv_legacy

{
qsv::medium, // preset
qsv::_auto, // cavlc
false, // slow_hevc
}, // qsv

{
(int) amd::usage_h264_e::ultralowlatency, // usage (h264)
(int) amd::usage_hevc_e::ultralowlatency, // usage (hevc)
(int) amd::usage_av1_e::ultralowlatency, // usage (av1)
(int) amd::rc_h264_e::vbr_latency, // rate control (h264)
(int) amd::rc_hevc_e::vbr_latency, // rate control (hevc)
(int) amd::rc_av1_e::vbr_latency, // rate control (av1)
0, // enforce_hrd
(int) amd::quality_h264_e::balanced, // quality (h264)
(int) amd::quality_hevc_e::balanced, // quality (hevc)
(int) amd::quality_av1_e::balanced, // quality (av1)
0, // preanalysis
1, // vbaq
{}, // max_au_size (disabled by default)
(int) amd::coder_e::_auto, // coder
}, // amd

{
0,
0,
1,
-1,
}, // vt

{
0, // blbrc
std::to_underlying(vaapi::quality_e::_auto), // quality
std::to_underlying(vaapi::rc_e::_auto), // rate control
{}, // rate control string
false, // strict_rc_buffer
}, // vaapi

{
2, // vk.tune (default: ll - low latency)
2, // vk.rc_mode (default: cbr)
},

{}, // capture
{}, // encoder
{}, // adapter_name
{}, // output_name

{
video_t::dd_t::config_option_e::disabled, // configuration_option
video_t::dd_t::resolution_option_e::automatic, // resolution_option
{}, // manual_resolution
video_t::dd_t::refresh_rate_option_e::automatic, // refresh_rate_option
{}, // manual_refresh_rate
video_t::dd_t::hdr_option_e::automatic, // hdr_option
3s, // config_revert_delay
{}, // config_revert_on_disconnect
{}, // mode_remapping
{} // wa
}, // display_device

0, // max_bitrate
0 // minimum_fps_target (0 = framerate)
};

Check failure on line 799 in src/config.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Global variables should be const.

See more on https://sonarcloud.io/project/issues?id=LizardByte_Sunshine&issues=AaCIsislic2y3LVY46jD&open=AaCIsislic2y3LVY46jD&pullRequest=5668

/**
* @brief Default audio configuration values used before file and CLI overrides.
Expand Down Expand Up @@ -1619,12 +1623,12 @@
bool_f(vars, "nvenc_latency_over_power", video.nv_sunshine_high_power_mode);

#if !defined(__ANDROID__) && !defined(__APPLE__)
video.nv_legacy.preset = video.nv.quality_preset + 11;
video.nv_legacy.preset = nv::ffmpeg_preset_from_quality(video.nv.quality_preset);
video.nv_legacy.multipass = video.nv.two_pass == nvenc::nvenc_two_pass::quarter_resolution ? NV_ENC_TWO_PASS_QUARTER_RESOLUTION :
video.nv.two_pass == nvenc::nvenc_two_pass::full_resolution ? NV_ENC_TWO_PASS_FULL_RESOLUTION :
NV_ENC_MULTI_PASS_DISABLED;
video.nv_legacy.h264_coder = video.nv.h264_cavlc ? NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC : NV_ENC_H264_ENTROPY_CODING_MODE_CABAC;
video.nv_legacy.aq = video.nv.adaptive_quantization;
video.nv_legacy.spatial_aq = video.nv.adaptive_quantization;
video.nv_legacy.vbv_percentage_increase = video.nv.vbv_percentage_increase;
#endif

Expand Down
14 changes: 12 additions & 2 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@
#include "nvenc/nvenc_config.h"

namespace config {
namespace nv {
/**
* @brief Convert Sunshine's NVENC quality preset number to FFmpeg's stable symbolic name.
*
* @param quality_preset Validated Sunshine quality preset in the range 1 through 7.
* @return FFmpeg preset name from `p1` through `p7`.
*/
std::string ffmpeg_preset_from_quality(int quality_preset);
} // namespace nv

// Valid range for the packetsize limit
constexpr int PACKETSIZE_MIN = 200; ///< Lowest accepted configured packet size in bytes.
constexpr int PACKETSIZE_MAX = 65535; ///< Highest accepted configured packet size in bytes.
Expand Down Expand Up @@ -73,10 +83,10 @@ namespace config {
bool nv_sunshine_high_power_mode; ///< Request NVIDIA high-power mode for Sunshine.

struct {
int preset; ///< Legacy NVENC preset selection.
std::string preset; ///< FFmpeg NVENC preset name shared by supported FFmpeg versions.
int multipass; ///< Legacy NVENC multipass mode.
int h264_coder; ///< Legacy NVENC H.264 entropy-coding mode.
int aq; ///< Legacy NVENC adaptive-quantization mode.
int spatial_aq; ///< FFmpeg NVENC spatial adaptive-quantization mode.
int vbv_percentage_increase; ///< Legacy NVENC VBV buffer-size percentage increase.
} nv_legacy; ///< Legacy NVIDIA encoder options kept for config compatibility.

Expand Down
8 changes: 8 additions & 0 deletions src/nvenc/nvenc_dynamic_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ namespace nvenc {
const auto max_version = decode_nvenc_driver_version(packed_max_version);
const auto sdk_version = select_nvenc_sdk_version(max_version);
switch (sdk_version) {
case nvenc_sdk_version::sdk_13_1:
return std::make_shared<nvenc_dynamic_factory>(
std::move(dll),
sdk_version,
detail::create_nvenc_d3d11_native_1301,
detail::create_nvenc_d3d11_on_cuda_1301
);

case nvenc_sdk_version::sdk_13_0:
return std::make_shared<nvenc_dynamic_factory>(
std::move(dll),
Expand Down
16 changes: 16 additions & 0 deletions src/nvenc/nvenc_dynamic_factory_versions.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ namespace nvenc::detail {
* @return SDK-neutral encoder instance.
*/
std::unique_ptr<nvenc_d3d11_interface> create_nvenc_d3d11_on_cuda_1300(ID3D11Device *device, shared_dll dll);
/**
* @brief Create an SDK 13.1 native Direct3D11 encoder.
*
* @param device Direct3D11 device used for encoding.
* @param dll Shared NVENC driver module.
* @return SDK-neutral encoder instance.
*/
std::unique_ptr<nvenc_d3d11_interface> create_nvenc_d3d11_native_1301(ID3D11Device *device, shared_dll dll);
/**
* @brief Create an SDK 13.1 CUDA-interoperability encoder.
*
* @param device Direct3D11 device used for input surfaces.
* @param dll Shared NVENC driver module.
* @return SDK-neutral encoder instance.
*/
std::unique_ptr<nvenc_d3d11_interface> create_nvenc_d3d11_on_cuda_1301(ID3D11Device *device, shared_dll dll);

} // namespace nvenc::detail
#endif
2 changes: 1 addition & 1 deletion src/nvenc/nvenc_sdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* @brief NVENC SDK version used while generating documentation.
*/
// Doxygen must select the same preprocessor interface used by versioned build targets.
#define NVENC_SDK_VERSION 1300 // NOSONAR(cpp:S5028)
#define NVENC_SDK_VERSION 1301 // NOSONAR(cpp:S5028)
#endif

#ifndef NVENC_NAMESPACE
Expand Down
4 changes: 4 additions & 0 deletions src/nvenc/nvenc_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace nvenc {
sdk_11_0 = 1100U, ///< Video Codec SDK 11.0.
sdk_12_0 = 1200U, ///< Video Codec SDK 12.0.
sdk_13_0 = 1300U, ///< Video Codec SDK 13.0.
sdk_13_1 = 1301U, ///< Video Codec SDK 13.1.
};

/**
Expand All @@ -38,6 +39,9 @@ namespace nvenc {
*/
constexpr nvenc_sdk_version select_nvenc_sdk_version(std::uint32_t max_version) {
using enum nvenc_sdk_version;
if (max_version >= std::to_underlying(sdk_13_1)) {
return sdk_13_1;
}
if (max_version >= std::to_underlying(sdk_13_0)) {
return sdk_13_0;
}
Expand Down
6 changes: 3 additions & 3 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ namespace video {
{"tune"s, NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY},
{"rc"s, NV_ENC_PARAMS_RC_CBR},
{"multipass"s, &config::video.nv_legacy.multipass},
{"aq"s, &config::video.nv_legacy.aq},
{"spatial-aq"s, &config::video.nv_legacy.spatial_aq},
},
{}, // SDR-specific options
{}, // HDR-specific options
Expand All @@ -807,7 +807,7 @@ namespace video {
{"tune"s, NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY},
{"rc"s, NV_ENC_PARAMS_RC_CBR},
{"multipass"s, &config::video.nv_legacy.multipass},
{"aq"s, &config::video.nv_legacy.aq},
{"spatial-aq"s, &config::video.nv_legacy.spatial_aq},
},
{
// SDR-specific options
Expand All @@ -834,7 +834,7 @@ namespace video {
{"rc"s, NV_ENC_PARAMS_RC_CBR},
{"coder"s, &config::video.nv_legacy.h264_coder},
{"multipass"s, &config::video.nv_legacy.multipass},
{"aq"s, &config::video.nv_legacy.aq},
{"spatial-aq"s, &config::video.nv_legacy.spatial_aq},
},
{
// SDR-specific options
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/test_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,35 @@
#include <src/config.h>
#include <src/file_handler.h>

using namespace std::literals;

using NvencPresetNameParam = std::pair<int, std::string_view>;

/**
* @brief Parameterized coverage for FFmpeg's symbolic NVENC preset names.
*/
struct NvencPresetNameTest: testing::TestWithParam<NvencPresetNameParam> {};

TEST_P(NvencPresetNameTest, UsesStableSymbolicName) {
const auto &[quality_preset, expected] = GetParam();

EXPECT_EQ(expected, config::nv::ffmpeg_preset_from_quality(quality_preset));
}

INSTANTIATE_TEST_SUITE_P(
NvencQualityPresets,
NvencPresetNameTest,
testing::Values(
NvencPresetNameParam {1, "p1"sv},
NvencPresetNameParam {2, "p2"sv},
NvencPresetNameParam {3, "p3"sv},
NvencPresetNameParam {4, "p4"sv},
NvencPresetNameParam {5, "p5"sv},
NvencPresetNameParam {6, "p6"sv},
NvencPresetNameParam {7, "p7"sv}
)
);

namespace {

/**
Expand Down
7 changes: 4 additions & 3 deletions tests/unit/test_nvenc_dynamic_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ namespace {
std::pair {11U << 4U, sdk_11_0},
std::pair {12U << 4U, sdk_12_0},
std::pair {13U << 4U, sdk_13_0},
std::pair {14U << 4U, sdk_13_0},
std::pair {(13U << 4U) | 1U, sdk_13_1},
std::pair {14U << 4U, sdk_13_1},
};
reported_status = 0U;

Expand All @@ -163,7 +164,7 @@ namespace {
const auto dll = make_fake_dll();
nvenc::nvenc_dynamic_factory factory {
dll,
nvenc::nvenc_sdk_version::sdk_13_0,
nvenc::nvenc_sdk_version::sdk_13_1,
[&created_native, &dll](ID3D11Device *, nvenc::shared_dll callback_dll) {
created_native = true;
EXPECT_EQ(callback_dll, dll);
Expand All @@ -176,7 +177,7 @@ namespace {
},
};

EXPECT_EQ(factory.sdk_version(), nvenc::nvenc_sdk_version::sdk_13_0);
EXPECT_EQ(factory.sdk_version(), nvenc::nvenc_sdk_version::sdk_13_1);
EXPECT_TRUE(factory.create_nvenc_d3d11_native(nullptr));
EXPECT_TRUE(factory.create_nvenc_d3d11_on_cuda(nullptr));
EXPECT_TRUE(created_native);
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_nvenc_version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ namespace {
nvenc_version_test_case {1201U, sdk_12_0},
nvenc_version_test_case {1299U, sdk_12_0},
nvenc_version_test_case {1300U, sdk_13_0},
nvenc_version_test_case {1301U, sdk_13_0},
nvenc_version_test_case {1400U, sdk_13_0},
nvenc_version_test_case {1301U, sdk_13_1},
nvenc_version_test_case {1400U, sdk_13_1},
};

for (const auto &[max_version, expected] : test_cases) {
Expand Down
28 changes: 28 additions & 0 deletions tests/unit/test_video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// standard includes
#include <algorithm>
#include <array>
#include <limits>
#include <optional>
#include <tuple>
Expand Down Expand Up @@ -65,6 +66,33 @@ INSTANTIATE_TEST_SUITE_P(
}
);

#if !defined(_WIN32) && !defined(__APPLE__)
TEST(NvencAvcodecOptionsTest, UsesVersionStablePresetAndSpatialAqNames) {
const std::array codecs {
&video::nvenc.av1,
&video::nvenc.hevc,
&video::nvenc.h264,
};

for (const auto *codec : codecs) {
const auto preset = std::ranges::find(codec->common_options, "preset"sv, &video::encoder_t::option_t::name);
ASSERT_NE(codec->common_options.end(), preset);
ASSERT_TRUE(std::holds_alternative<std::string *>(preset->value));
EXPECT_EQ(&config::video.nv_legacy.preset, std::get<std::string *>(preset->value));

const auto spatial_aq = std::ranges::find(codec->common_options, "spatial-aq"sv, &video::encoder_t::option_t::name);
ASSERT_NE(codec->common_options.end(), spatial_aq);
ASSERT_TRUE(std::holds_alternative<int *>(spatial_aq->value));
EXPECT_EQ(&config::video.nv_legacy.spatial_aq, std::get<int *>(spatial_aq->value));

EXPECT_EQ(
codec->common_options.end(),
std::ranges::find(codec->common_options, "aq"sv, &video::encoder_t::option_t::name)
);
}
}
#endif

TEST_P(EncoderTest, ValidateEncoder) {
// todo:: test something besides fixture setup
}
Expand Down
Loading
Loading