Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NVENC Refactor #10536

Merged
merged 4 commits into from
Aug 9, 2024
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
3 changes: 2 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@
"CMAKE_INSTALL_LIBDIR": "lib/CMAKE_SYSTEM_PROCESSOR-linux-gnu",
"OBS_CMAKE_VERSION": {"type": "STRING", "value": "3.0.0"},
"ENABLE_AJA": false,
"ENABLE_NATIVE_NVENC": false,
"ENABLE_NVENC": false,
"ENABLE_FFMPEG_NVENC": true,
"ENABLE_VLC": true,
"ENABLE_WAYLAND": true,
"ENABLE_WEBRTC": false
Expand Down
14 changes: 8 additions & 6 deletions UI/window-basic-main-outputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -609,15 +609,17 @@ const char *get_simple_output_encoder(const char *encoder)
} else if (strcmp(encoder, SIMPLE_ENCODER_AMD_AV1) == 0) {
return "av1_texture_amf";
} else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) {
return EncoderAvailable("jim_nvenc") ? "jim_nvenc"
: "ffmpeg_nvenc";
return EncoderAvailable("obs_nvenc_h264_tex")
? "obs_nvenc_h264_tex"
: "ffmpeg_nvenc";
#ifdef ENABLE_HEVC
} else if (strcmp(encoder, SIMPLE_ENCODER_NVENC_HEVC) == 0) {
return EncoderAvailable("jim_hevc_nvenc") ? "jim_hevc_nvenc"
: "ffmpeg_hevc_nvenc";
return EncoderAvailable("obs_nvenc_hevc_tex")
? "obs_nvenc_hevc_tex"
: "ffmpeg_hevc_nvenc";
#endif
} else if (strcmp(encoder, SIMPLE_ENCODER_NVENC_AV1) == 0) {
return "jim_av1_nvenc";
return "obs_nvenc_av1_tex";
} else if (strcmp(encoder, SIMPLE_ENCODER_APPLE_H264) == 0) {
return "com.apple.videotoolbox.videoencoder.ave.avc";
#ifdef ENABLE_HEVC
Expand Down Expand Up @@ -1848,7 +1850,7 @@ void AdvancedOutput::UpdateStreamSettings()
blog(LOG_WARNING, "User is ignoring service settings.");
}

if (dynBitrate && astrcmpi(streamEncoder, "jim_nvenc") == 0)
if (dynBitrate && strstr(streamEncoder, "nvenc") != nullptr)
obs_data_set_bool(settings, "lookahead", false);

video_t *video = obs_get_video();
Expand Down
7 changes: 4 additions & 3 deletions UI/window-basic-settings-stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1606,8 +1606,9 @@ bool OBSBasicSettings::ServiceAndACodecCompatible()
/* we really need a way to find fallbacks in a less hardcoded way. maybe. */
static QString get_adv_fallback(const QString &enc)
{
if (enc == "jim_hevc_nvenc" || enc == "jim_av1_nvenc")
return "jim_nvenc";
if (enc == "obs_nvenc_hevc_tex" || enc == "obs_nvenc_av1_tex" ||
enc == "jim_hevc_nvenc" || enc == "jim_av1_nvenc")
return "obs_nvenc_h264_tex";
if (enc == "h265_texture_amf" || enc == "av1_texture_amf")
return "h264_texture_amf";
if (enc == "com.apple.videotoolbox.videoencoder.ave.hevc")
Expand Down Expand Up @@ -1863,7 +1864,7 @@ void OBSBasicSettings::ResetEncoders(bool streamOnly)
ui->simpleOutStrEncoder->addItem(
ENCODER_STR("Hardware.NVENC.H264"),
QString(SIMPLE_ENCODER_NVENC));
if (service_supports_encoder(vcodecs, "jim_av1_nvenc"))
if (service_supports_encoder(vcodecs, "obs_nvenc_av1_tex"))
ui->simpleOutStrEncoder->addItem(
ENCODER_STR("Hardware.NVENC.AV1"),
QString(SIMPLE_ENCODER_NVENC_AV1));
Expand Down
2 changes: 1 addition & 1 deletion UI/window-basic-settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5354,7 +5354,7 @@ void OBSBasicSettings::FillSimpleRecordingValues()
ui->simpleOutRecEncoder->addItem(
ENCODER_STR("Hardware.NVENC.H264"),
QString(SIMPLE_ENCODER_NVENC));
if (EncoderAvailable("jim_av1_nvenc"))
if (EncoderAvailable("obs_nvenc_av1_tex"))
ui->simpleOutRecEncoder->addItem(
ENCODER_STR("Hardware.NVENC.AV1"),
QString(SIMPLE_ENCODER_NVENC_AV1));
Expand Down
1 change: 1 addition & 0 deletions plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ if(OBS_CMAKE_VERSION VERSION_GREATER_EQUAL 3.0.0)
add_obs_plugin(obs-ffmpeg)
add_obs_plugin(obs-filters)
add_obs_plugin(obs-libfdk)
add_obs_plugin(obs-nvenc PLATFORMS WINDOWS LINUX)
add_obs_plugin(obs-outputs)
add_obs_plugin(
obs-qsv11
Expand Down
14 changes: 8 additions & 6 deletions plugins/obs-ffmpeg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ legacy_check()
option(ENABLE_FFMPEG_LOGGING "Enables obs-ffmpeg logging" OFF)
option(ENABLE_NEW_MPEGTS_OUTPUT "Use native SRT/RIST mpegts output" ON)

if(OS_LINUX)
option(ENABLE_NATIVE_NVENC "Use native NVENC implementation" ON)
if(OS_LINUX OR OS_WINDOWS)
option(ENABLE_FFMPEG_NVENC "Enable legacy FFmpeg NVENC encoder" OFF)
endif()

include(cmake/dependencies.cmake)
Expand All @@ -20,6 +20,7 @@ target_sources(
obs-ffmpeg
PRIVATE # cmake-format: sortable
$<$<BOOL:${ENABLE_FFMPEG_LOGGING}>:obs-ffmpeg-logging.c>
$<$<BOOL:${ENABLE_FFMPEG_NVENC}>:obs-ffmpeg-nvenc.c>
$<$<BOOL:${ENABLE_NEW_MPEGTS_OUTPUT}>:obs-ffmpeg-mpegts.c>
$<$<BOOL:${ENABLE_NEW_MPEGTS_OUTPUT}>:obs-ffmpeg-rist.h>
$<$<BOOL:${ENABLE_NEW_MPEGTS_OUTPUT}>:obs-ffmpeg-srt.h>
Expand All @@ -36,16 +37,18 @@ target_sources(
obs-ffmpeg-hls-mux.c
obs-ffmpeg-mux.c
obs-ffmpeg-mux.h
obs-ffmpeg-nvenc.c
obs-ffmpeg-output.c
obs-ffmpeg-output.h
obs-ffmpeg-source.c
obs-ffmpeg-video-encoders.c
obs-ffmpeg.c)

target_compile_options(obs-ffmpeg PRIVATE $<$<COMPILE_LANG_AND_ID:C,AppleClang,Clang>:-Wno-shorten-64-to-32>)
target_compile_definitions(obs-ffmpeg PRIVATE $<$<BOOL:${ENABLE_FFMPEG_LOGGING}>:ENABLE_FFMPEG_LOGGING>
$<$<BOOL:${ENABLE_NEW_MPEGTS_OUTPUT}>:NEW_MPEGTS_OUTPUT>)
target_compile_definitions(
obs-ffmpeg
PRIVATE $<$<BOOL:${ENABLE_FFMPEG_LOGGING}>:ENABLE_FFMPEG_LOGGING>
$<$<BOOL:${ENABLE_FFMPEG_NVENC}>:ENABLE_FFMPEG_NVENC>
$<$<BOOL:${ENABLE_NEW_MPEGTS_OUTPUT}>:NEW_MPEGTS_OUTPUT>)

target_link_libraries(
obs-ffmpeg
Expand All @@ -59,7 +62,6 @@ target_link_libraries(
FFmpeg::avutil
FFmpeg::swscale
FFmpeg::swresample
$<TARGET_NAME_IF_EXISTS:OBS::obs-nvenc-native>
$<$<PLATFORM_ID:Windows>:OBS::w32-pthreads>
$<$<PLATFORM_ID:Windows>:AMF::AMF>
$<$<PLATFORM_ID:Windows>:ws2_32>
Expand Down
26 changes: 0 additions & 26 deletions plugins/obs-ffmpeg/cmake/dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,6 @@ elseif(
find_package(Libdrm REQUIRED)
endif()

if(OS_WINDOWS OR (OS_LINUX AND ENABLE_NATIVE_NVENC))
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}")

find_package(FFnvcodec 12.0.0.0...<12.2.0.0 REQUIRED)

if(OS_LINUX AND NOT TARGET OBS::glad)
add_subdirectory("${CMAKE_SOURCE_DIR}/deps/glad" "${CMAKE_BINARY_DIR}/deps/glad")
endif()

add_library(obs-nvenc-native INTERFACE)
add_library(OBS::obs-nvenc-native ALIAS obs-nvenc-native)
target_sources(obs-nvenc-native INTERFACE obs-nvenc-helpers.c obs-nvenc.c obs-nvenc.h)
target_compile_definitions(obs-nvenc-native INTERFACE $<$<PLATFORM_ID:Linux>:NVCODEC_AVAILABLE>)
target_include_directories(obs-nvenc-native INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")

target_link_libraries(obs-nvenc-native INTERFACE FFnvcodec::FFnvcodec OBS::obs-nvenc-version
$<$<PLATFORM_ID:Linux>:OBS::glad>)

if(OS_WINDOWS)
add_subdirectory(obs-nvenc-test)
endif()
endif()

if(ENABLE_NEW_MPEGTS_OUTPUT)
find_package(Librist QUIET)
find_package(Libsrt QUIET)
Expand Down
29 changes: 10 additions & 19 deletions plugins/obs-ffmpeg/cmake/legacy.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ project(obs-ffmpeg)

option(ENABLE_FFMPEG_LOGGING "Enables obs-ffmpeg logging" OFF)
option(ENABLE_NEW_MPEGTS_OUTPUT "Use native SRT/RIST mpegts output" ON)
option(ENABLE_NATIVE_NVENC "Use native NVENC implementation" ON)

if(OS_LINUX OR OS_WINDOWS)
option(ENABLE_FFMPEG_NVENC "Enables legacy FFmpeg NVENC encoder" OFF)
endif()

find_package(
FFmpeg REQUIRED
Expand Down Expand Up @@ -49,7 +52,6 @@ target_sources(
obs-ffmpeg-video-encoders.c
obs-ffmpeg-audio-encoders.c
obs-ffmpeg-av1.c
obs-ffmpeg-nvenc.c
obs-ffmpeg-output.c
obs-ffmpeg-output.h
obs-ffmpeg-mux.c
Expand Down Expand Up @@ -85,6 +87,11 @@ if(ENABLE_NEW_MPEGTS_OUTPUT)
target_compile_definitions(obs-ffmpeg PRIVATE NEW_MPEGTS_OUTPUT)
endif()

if(ENABLE_FFMPEG_NVENC)
target_sources(obs-ffmpeg PRIVATE obs-ffmpeg-nvenc.c)
target_compile_definitions(obs-ffmpeg PRIVATE ENABLE_FFMPEG_NVENC)
endif()

if(ENABLE_FFMPEG_LOGGING)
target_sources(obs-ffmpeg PRIVATE obs-ffmpeg-logging.c)
endif()
Expand All @@ -96,7 +103,6 @@ if(OS_WINDOWS)
find_package(FFnvcodec 12 REQUIRED)

add_subdirectory(obs-amf-test)
add_subdirectory(obs-nvenc-test)

if(MSVC)
target_link_libraries(obs-ffmpeg PRIVATE OBS::w32-pthreads)
Expand All @@ -106,29 +112,14 @@ if(OS_WINDOWS)
set(MODULE_DESCRIPTION "OBS FFmpeg module")
configure_file(${CMAKE_SOURCE_DIR}/cmake/bundle/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 texture-amf.cpp texture-amf-opts.hpp obs-ffmpeg.rc)

elseif(OS_POSIX AND NOT OS_MACOS)
find_package(Libva REQUIRED)
find_package(Libpci REQUIRED)
find_package(Libdrm REQUIRED)
target_sources(obs-ffmpeg PRIVATE obs-ffmpeg-vaapi.c vaapi-utils.c vaapi-utils.h)
target_link_libraries(obs-ffmpeg PRIVATE Libva::va Libva::drm LIBPCI::LIBPCI Libdrm::Libdrm)

if(ENABLE_NATIVE_NVENC)
find_package(FFnvcodec 12.0.0.0...<12.2.0.0 REQUIRED)
target_sources(obs-ffmpeg PRIVATE obs-nvenc.c obs-nvenc.h obs-nvenc-helpers.c obs-nvenc-ver.h)
target_link_libraries(obs-ffmpeg PRIVATE FFnvcodec::FFnvcodec OBS::obsglad)
target_compile_definitions(obs-ffmpeg PRIVATE NVCODEC_AVAILABLE)
endif()
endif()

setup_plugin_target(obs-ffmpeg)
43 changes: 3 additions & 40 deletions plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
return true;
}

obs_properties_t *nvenc_properties_internal(enum codec_type codec, bool ffmpeg)
obs_properties_t *nvenc_properties_internal(enum codec_type codec)
{
obs_properties_t *props = obs_properties_create();
obs_property_t *p;
Expand Down Expand Up @@ -587,15 +587,6 @@ obs_properties_t *nvenc_properties_internal(enum codec_type codec, bool ffmpeg)
}
#undef add_profile

if (!ffmpeg) {
p = obs_properties_add_bool(props, "lookahead",
obs_module_text("NVENC.LookAhead"));
obs_property_set_long_description(
p, obs_module_text("NVENC.LookAhead.ToolTip"));
p = obs_properties_add_bool(props, "repeat_headers",
"repeat_headers");
obs_property_set_visible(p, false);
}
p = obs_properties_add_bool(
props, "psycho_aq",
obs_module_text("NVENC.PsychoVisualTuning"));
Expand All @@ -610,37 +601,17 @@ obs_properties_t *nvenc_properties_internal(enum codec_type codec, bool ffmpeg)
return props;
}

obs_properties_t *h264_nvenc_properties(void *unused)
{
UNUSED_PARAMETER(unused);
return nvenc_properties_internal(CODEC_H264, false);
}

#ifdef ENABLE_HEVC
obs_properties_t *hevc_nvenc_properties(void *unused)
{
UNUSED_PARAMETER(unused);
return nvenc_properties_internal(CODEC_HEVC, false);
}
#endif

obs_properties_t *av1_nvenc_properties(void *unused)
{
UNUSED_PARAMETER(unused);
return nvenc_properties_internal(CODEC_AV1, false);
}

obs_properties_t *h264_nvenc_properties_ffmpeg(void *unused)
{
UNUSED_PARAMETER(unused);
return nvenc_properties_internal(CODEC_H264, true);
return nvenc_properties_internal(CODEC_H264);
}

#ifdef ENABLE_HEVC
obs_properties_t *hevc_nvenc_properties_ffmpeg(void *unused)
{
UNUSED_PARAMETER(unused);
return nvenc_properties_internal(CODEC_HEVC, true);
return nvenc_properties_internal(CODEC_HEVC);
}
#endif

Expand Down Expand Up @@ -676,11 +647,7 @@ struct obs_encoder_info h264_nvenc_encoder_info = {
.get_extra_data = nvenc_extra_data,
.get_sei_data = nvenc_sei_data,
.get_video_info = nvenc_video_info,
#if defined(_WIN32) || defined(NVCODEC_AVAILABLE)
.caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
#else
.caps = OBS_ENCODER_CAP_DYN_BITRATE,
#endif
};

#ifdef ENABLE_HEVC
Expand All @@ -698,10 +665,6 @@ struct obs_encoder_info hevc_nvenc_encoder_info = {
.get_extra_data = nvenc_extra_data,
.get_sei_data = nvenc_sei_data,
.get_video_info = nvenc_video_info,
#if defined(_WIN32) || defined(NVCODEC_AVAILABLE)
.caps = OBS_ENCODER_CAP_DYN_BITRATE | OBS_ENCODER_CAP_INTERNAL,
#else
.caps = OBS_ENCODER_CAP_DYN_BITRATE,
#endif
};
#endif
Loading