mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-13 07:15:06 +00:00
ffmpeg: Move into its own component
While we're at it, let's also fix the invalid destructor, as well as the NVENC HEVC encoder incorrectly using H264.Level to store H265.Level.
This commit is contained in:
parent
d2a543f118
commit
d5cf2d2ccf
38 changed files with 60 additions and 193 deletions
205
CMakeLists.txt
205
CMakeLists.txt
|
@ -287,14 +287,6 @@ endif()
|
|||
set(${PREFIX}VERSION "" CACHE STRING "Specify an override for the automatically detected version. Accepts a mixture of SemVer 2.0 and CMake Version.")
|
||||
|
||||
# Features
|
||||
## Encoders
|
||||
set(${PREFIX}ENABLE_ENCODER_FFMPEG ${FEATURE_STABLE} CACHE BOOL "Enable FFmpeg Encoder integration.")
|
||||
set(${PREFIX}ENABLE_ENCODER_FFMPEG_AMF ${FEATURE_DEPRECATED} CACHE BOOL "Enable AMF Encoder in FFmpeg.")
|
||||
set(${PREFIX}ENABLE_ENCODER_FFMPEG_NVENC ${FEATURE_STABLE} CACHE BOOL "Enable NVENC Encoder in FFmpeg.")
|
||||
set(${PREFIX}ENABLE_ENCODER_FFMPEG_PRORES ${FEATURE_STABLE} CACHE BOOL "Enable ProRes Encoder in FFmpeg.")
|
||||
set(${PREFIX}ENABLE_ENCODER_FFMPEG_DNXHR ${FEATURE_STABLE} CACHE BOOL "Enable DNXHR Encoder in FFmpeg.")
|
||||
set(${PREFIX}ENABLE_ENCODER_FFMPEG_CFHD ${FEATURE_STABLE} CACHE BOOL "Enable CineForm Encoder in FFmpeg.")
|
||||
|
||||
## Filters
|
||||
set(${PREFIX}ENABLE_FILTER_AUTOFRAMING ${FEATURE_EXPERIMENTAL} CACHE BOOL "Enable Auto-Framing Filter")
|
||||
set(${PREFIX}ENABLE_FILTER_AUTOFRAMING_NVIDIA ${FEATURE_EXPERIMENTAL} CACHE BOOL "Enable NVIDIA provider(s) Auto-Framing Filter")
|
||||
|
@ -449,54 +441,6 @@ macro(set_feature_disabled FEATURE DISABLED)
|
|||
set(${PREFIX}DISABLE_${FEATURE} ${DISABLED} CACHE INTERNAL "" FORCE)
|
||||
endmacro()
|
||||
|
||||
# Features
|
||||
function(feature_encoder_ffmpeg RESOLVE)
|
||||
is_feature_enabled(ENCODER_FFMPEG T_CHECK)
|
||||
if(RESOLVE AND T_CHECK)
|
||||
if(NOT HAVE_FFMPEG)
|
||||
message(WARNING "FFmpeg Encoder requires FFmpeg. Disabling...")
|
||||
set_feature_disabled(ENCODER_FFMPEG ON)
|
||||
else()
|
||||
# AMF
|
||||
is_feature_enabled(ENCODER_FFMPEG_AMF T_CHECK)
|
||||
if(T_CHECK AND D_PLATFORM_MAC)
|
||||
message(WARNING "FFmpeg Encoder 'AMF' requires Windows or Linux. Disabling...")
|
||||
set_feature_disabled(ENCODER_FFMPEG_AMF ON)
|
||||
endif()
|
||||
|
||||
# NVENC
|
||||
is_feature_enabled(ENCODER_FFMPEG_NVENC T_CHECK)
|
||||
if(T_CHECK AND D_PLATFORM_MAC)
|
||||
message(WARNING "FFmpeg Encoder 'NVENC' requires Windows or Linux. Disabling...")
|
||||
set_feature_disabled(ENCODER_FFMPEG_NVENC ON)
|
||||
endif()
|
||||
|
||||
# ProRes
|
||||
is_feature_enabled(ENCODER_FFMPEG_PRORES T_CHECK)
|
||||
|
||||
# DNxHR
|
||||
is_feature_enabled(ENCODER_FFMPEG_DNXHR T_CHECK)
|
||||
|
||||
# CineForm
|
||||
is_feature_enabled(ENCODER_FFMPEG_CFHD T_CHECK)
|
||||
endif()
|
||||
elseif(T_CHECK)
|
||||
set(REQUIRE_FFMPEG ON PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(feature_encoder_aom_av1 RESOLVE)
|
||||
is_feature_enabled(ENCODER_AOM_AV1 T_CHECK)
|
||||
if(RESOLVE AND T_CHECK)
|
||||
if(NOT HAVE_AOM)
|
||||
message(WARNING "AOM AV1 encoder missing AOM library. Disabling...")
|
||||
set_feature_disabled(ENCODER_AOM_AV1 ON)
|
||||
endif()
|
||||
elseif(T_CHECK)
|
||||
set(REQUIRE_AOM ON PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(feature_filter_autoframing RESOLVE)
|
||||
is_feature_enabled(FILTER_AUTOFRAMING T_CHECK)
|
||||
if(RESOLVE AND T_CHECK)
|
||||
|
@ -651,8 +595,6 @@ function(feature_updater RESOLVE)
|
|||
endfunction()
|
||||
|
||||
# Set Requirements
|
||||
feature_encoder_ffmpeg(OFF)
|
||||
feature_encoder_aom_av1(OFF)
|
||||
feature_filter_autoframing(OFF)
|
||||
feature_filter_blur(OFF)
|
||||
feature_filter_color_grade(OFF)
|
||||
|
@ -713,24 +655,6 @@ if(REQUIRE_CURL)
|
|||
find_package("CURL")
|
||||
endif()
|
||||
|
||||
#- FFmpeg
|
||||
set(HAVE_FFMPEG OFF)
|
||||
if(REQUIRE_FFMPEG)
|
||||
find_package("FFmpeg"
|
||||
COMPONENTS "avutil" "avcodec" "swscale"
|
||||
)
|
||||
set(HAVE_FFMPEG ${FFmpeg_FOUND})
|
||||
endif()
|
||||
|
||||
#- AOM
|
||||
set(HAVE_AOM OFF)
|
||||
if(REQUIRE_AOM)
|
||||
if(NOT D_PLATFORM_MAC)
|
||||
find_package("AOM")
|
||||
set(HAVE_AOM ${AOM_FOUND})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#- JSON
|
||||
set(HAVE_JSON OFF)
|
||||
if(REQUIRE_JSON)
|
||||
|
@ -808,8 +732,6 @@ if(REQUIRE_QT)
|
|||
endif()
|
||||
|
||||
# Verify Requirements
|
||||
feature_encoder_ffmpeg(ON)
|
||||
feature_encoder_aom_av1(ON)
|
||||
feature_filter_autoframing(ON)
|
||||
feature_filter_blur(ON)
|
||||
feature_filter_color_grade(ON)
|
||||
|
@ -882,15 +804,6 @@ if(CURL_FOUND)
|
|||
list(APPEND PROJECT_LIBRARIES CURL::libcurl)
|
||||
endif()
|
||||
|
||||
if(HAVE_FFMPEG)
|
||||
list(APPEND PROJECT_LIBRARIES
|
||||
${FFMPEG_LIBRARIES}
|
||||
)
|
||||
list(APPEND PROJECT_INCLUDE_DIRS
|
||||
${FFMPEG_INCLUDE_DIRS}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(HAVE_JSON)
|
||||
list(APPEND PROJECT_INCLUDE_DIRS ${JSON_INCLUDE_DIR})
|
||||
endif()
|
||||
|
@ -1102,107 +1015,6 @@ list(APPEND PROJECT_INCLUDE_DIRS
|
|||
"${PROJECT_SOURCE_DIR}/source"
|
||||
)
|
||||
|
||||
# Encoder/FFmpeg
|
||||
is_feature_enabled(ENCODER_FFMPEG T_CHECK)
|
||||
if(T_CHECK)
|
||||
list(APPEND PROJECT_PRIVATE_SOURCE
|
||||
# FFmpeg
|
||||
"source/ffmpeg/avframe-queue.cpp"
|
||||
"source/ffmpeg/avframe-queue.hpp"
|
||||
"source/ffmpeg/swscale.hpp"
|
||||
"source/ffmpeg/swscale.cpp"
|
||||
"source/ffmpeg/tools.hpp"
|
||||
"source/ffmpeg/tools.cpp"
|
||||
"source/ffmpeg/hwapi/base.hpp"
|
||||
"source/ffmpeg/hwapi/base.cpp"
|
||||
"source/ffmpeg/hwapi/d3d11.hpp"
|
||||
"source/ffmpeg/hwapi/d3d11.cpp"
|
||||
|
||||
# Encoders
|
||||
"source/encoders/encoder-ffmpeg.hpp"
|
||||
"source/encoders/encoder-ffmpeg.cpp"
|
||||
|
||||
# Encoders/Codecs
|
||||
"source/encoders/codecs/hevc.hpp"
|
||||
"source/encoders/codecs/hevc.cpp"
|
||||
"source/encoders/codecs/h264.hpp"
|
||||
"source/encoders/codecs/h264.cpp"
|
||||
"source/encoders/codecs/prores.hpp"
|
||||
"source/encoders/codecs/prores.cpp"
|
||||
"source/encoders/codecs/dnxhr.hpp"
|
||||
"source/encoders/codecs/dnxhr.cpp"
|
||||
|
||||
# Encoders/Handlers
|
||||
"source/encoders/ffmpeg/handler.hpp"
|
||||
"source/encoders/ffmpeg/handler.cpp"
|
||||
"source/encoders/ffmpeg/debug.hpp"
|
||||
"source/encoders/ffmpeg/debug.cpp"
|
||||
)
|
||||
list(APPEND PROJECT_DEFINITIONS
|
||||
ENABLE_ENCODER_FFMPEG
|
||||
)
|
||||
|
||||
# AMF
|
||||
is_feature_enabled(ENCODER_FFMPEG_AMF T_CHECK)
|
||||
if(T_CHECK)
|
||||
list(APPEND PROJECT_PRIVATE_SOURCE
|
||||
"source/encoders/ffmpeg/amf.hpp"
|
||||
"source/encoders/ffmpeg/amf.cpp"
|
||||
)
|
||||
list(APPEND PROJECT_DEFINITIONS
|
||||
ENABLE_ENCODER_FFMPEG_AMF
|
||||
)
|
||||
endif()
|
||||
|
||||
# NVENC
|
||||
is_feature_enabled(ENCODER_FFMPEG_NVENC T_CHECK)
|
||||
if(T_CHECK)
|
||||
list(APPEND PROJECT_PRIVATE_SOURCE
|
||||
"source/encoders/ffmpeg/nvenc.hpp"
|
||||
"source/encoders/ffmpeg/nvenc.cpp"
|
||||
)
|
||||
list(APPEND PROJECT_DEFINITIONS
|
||||
ENABLE_ENCODER_FFMPEG_NVENC
|
||||
)
|
||||
endif()
|
||||
|
||||
# ProRES
|
||||
is_feature_enabled(ENCODER_FFMPEG_PRORES T_CHECK)
|
||||
if(T_CHECK)
|
||||
list(APPEND PROJECT_PRIVATE_SOURCE
|
||||
"source/encoders/ffmpeg/prores_aw.hpp"
|
||||
"source/encoders/ffmpeg/prores_aw.cpp"
|
||||
)
|
||||
list(APPEND PROJECT_DEFINITIONS
|
||||
ENABLE_ENCODER_FFMPEG_PRORES
|
||||
)
|
||||
endif()
|
||||
|
||||
# DNxHR
|
||||
is_feature_enabled(ENCODER_FFMPEG_DNXHR T_CHECK)
|
||||
if(T_CHECK)
|
||||
list(APPEND PROJECT_PRIVATE_SOURCE
|
||||
"source/encoders/ffmpeg/dnxhd.hpp"
|
||||
"source/encoders/ffmpeg/dnxhd.cpp"
|
||||
)
|
||||
list(APPEND PROJECT_DEFINITIONS
|
||||
ENABLE_ENCODER_FFMPEG_DNXHR
|
||||
)
|
||||
endif()
|
||||
|
||||
# CineForm HD
|
||||
is_feature_enabled(ENCODER_FFMPEG_CFHD T_CHECK)
|
||||
if(T_CHECK)
|
||||
list(APPEND PROJECT_PRIVATE_SOURCE
|
||||
"source/encoders/ffmpeg/cfhd.hpp"
|
||||
"source/encoders/ffmpeg/cfhd.cpp"
|
||||
)
|
||||
list(APPEND PROJECT_DEFINITIONS
|
||||
ENABLE_ENCODER_FFMPEG_CFHD
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Filter/Auto-Framing
|
||||
is_feature_enabled(FILTER_AUTOFRAMING T_CHECK)
|
||||
if(T_CHECK)
|
||||
|
@ -1905,6 +1717,7 @@ function(streamfx_add_component COMPONENT_NAME)
|
|||
|
||||
# Allow disabling this component.
|
||||
set(${COMPONENT_OPTION} ON CACHE BOOL "Enable the ${COMPONENT_NAME} component?")
|
||||
set(${COMPONENT_OPTION}_DISABLED OFF CACHE INTERNAL "Disable the ${_NAME} component?" FORCE)
|
||||
|
||||
# Add common include directories
|
||||
target_include_directories(${COMPONENT_TARGET}
|
||||
|
@ -1995,6 +1808,22 @@ function(streamfx_add_component_dependency _NAME)
|
|||
set_target_properties(${COMPONENT_TARGET} PROPERTIES COMPONENT_DEPENDS "${DEPENDS}")
|
||||
endfunction()
|
||||
|
||||
function(streamfx_disable_component _NAME _REASON)
|
||||
# If the component doesn't exist, skip it.
|
||||
if(NOT TARGET ${_NAME})
|
||||
message(WARNING "Not disabling invalid component '${COMPONENT}'.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_target_property(_NAME ${COMPONENT} COMPONENT_LABEL)
|
||||
get_target_property(_OPTION ${COMPONENT} COMPONENT_OPTION)
|
||||
|
||||
CacheSet(${_OPTION}_DISABLED ON)
|
||||
if(_REASON)
|
||||
message(STATUS "[${_NAME}] Disabled due to: ${_REASON}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Register Library
|
||||
################################################################################
|
||||
|
|
26
components/ffmpeg/CMakeLists.txt
Normal file
26
components/ffmpeg/CMakeLists.txt
Normal file
|
@ -0,0 +1,26 @@
|
|||
## AUTOGENERATED COPYRIGHT HEADER START
|
||||
# Copyright (C) NaN-NaN undefined
|
||||
# AUTOGENERATED COPYRIGHT HEADER END
|
||||
cmake_minimum_required(VERSION 3.26)
|
||||
project("FFmpeg")
|
||||
list(APPEND CMAKE_MESSAGE_INDENT "[${PROJECT_NAME}] ")
|
||||
|
||||
streamfx_add_component(${PROJECT_NAME})
|
||||
|
||||
find_package("FFmpeg"
|
||||
COMPONENTS "avutil" "avcodec" "swscale"
|
||||
)
|
||||
if(NOT FFmpeg_FOUND)
|
||||
streamfx_disable_component(${COMPONENT_TARGET} "FFmpeg is not available.")
|
||||
return()
|
||||
else()
|
||||
target_link_libraries(${COMPONENT_TARGET}
|
||||
PUBLIC
|
||||
${FFMPEG_LIBRARIES}
|
||||
)
|
||||
|
||||
target_include_directories(${COMPONENT_TARGET}
|
||||
PUBLIC
|
||||
${FFMPEG_INCLUDE_DIRS}
|
||||
)
|
||||
endif()
|
|
@ -19,6 +19,7 @@ namespace streamfx::encoder::ffmpeg {
|
|||
|
||||
struct handler {
|
||||
handler(std::string codec);
|
||||
virtual ~handler(){};
|
||||
|
||||
virtual bool has_keyframes(ffmpeg_factory* factory);
|
||||
virtual bool has_threading(ffmpeg_factory* factory);
|
|
@ -88,7 +88,7 @@ extern "C" {
|
|||
|
||||
#define ST_KEY_H265_PROFILE "H265.Profile"
|
||||
#define ST_KEY_H265_TIER "H265.Tier"
|
||||
#define ST_KEY_H264_LEVEL "H265.Level"
|
||||
#define ST_KEY_H265_LEVEL "H265.Level"
|
||||
|
||||
using namespace streamfx::encoder::ffmpeg;
|
||||
using namespace streamfx::encoder::codec;
|
||||
|
@ -1045,7 +1045,7 @@ void nvenc_hevc::defaults(ffmpeg_factory* factory, obs_data_t* settings)
|
|||
|
||||
obs_data_set_default_string(settings, ST_KEY_H265_PROFILE, "");
|
||||
obs_data_set_default_string(settings, ST_KEY_H265_TIER, "");
|
||||
obs_data_set_default_string(settings, ST_KEY_H264_LEVEL, "auto");
|
||||
obs_data_set_default_string(settings, ST_KEY_H265_LEVEL, "auto");
|
||||
}
|
||||
|
||||
void nvenc_hevc::properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props)
|
||||
|
@ -1061,6 +1061,17 @@ void nvenc_hevc::migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs
|
|||
{
|
||||
nvenc::migrate(factory, instance, settings, version);
|
||||
|
||||
// Migrate:
|
||||
// - all versions below 0.12.
|
||||
// - all versions that are larger than 0.12, but smaller than 0.12.0.315.
|
||||
// - no other version.
|
||||
if ((version < STREAMFX_MAKE_VERSION(0, 12, 0, 0))
|
||||
|| ((version > STREAMFX_MAKE_VERSION(0, 12, 0, 0)) && (version < STREAMFX_MAKE_VERSION(0, 12, 0, 315)))) {
|
||||
// Accidentally had this stored int he wrong place. Oops.
|
||||
obs_data_set_string(settings, ST_KEY_H265_LEVEL, obs_data_get_string(settings, ST_KEY_H264_LEVEL));
|
||||
obs_data_unset_user_value(settings, ST_KEY_H264_LEVEL);
|
||||
}
|
||||
|
||||
if (version < STREAMFX_MAKE_VERSION(0, 11, 1, 0)) {
|
||||
// Profile
|
||||
if (auto v = obs_data_get_int(settings, ST_KEY_H265_PROFILE); v != -1) {
|
||||
|
@ -1092,7 +1103,7 @@ void nvenc_hevc::migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs
|
|||
}
|
||||
|
||||
// Level
|
||||
obs_data_set_string(settings, ST_KEY_H264_LEVEL, "auto");
|
||||
obs_data_set_string(settings, ST_KEY_H265_LEVEL, "auto");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1110,7 +1121,7 @@ void nvenc_hevc::update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_
|
|||
if (const char* v = obs_data_get_string(settings, ST_KEY_H265_TIER); v && (v[0] != '\0')) {
|
||||
av_opt_set(context->priv_data, "tier", v, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
if (const char* v = obs_data_get_string(settings, ST_KEY_H264_LEVEL); v && (v[0] != '\0')) {
|
||||
if (const char* v = obs_data_get_string(settings, ST_KEY_H265_LEVEL); v && (v[0] != '\0')) {
|
||||
av_opt_set(context->priv_data, "level", v, AV_OPT_SEARCH_CHILDREN);
|
||||
}
|
||||
}
|
||||
|
@ -1172,7 +1183,7 @@ void nvenc_hevc::properties_encoder(ffmpeg_factory* factory, ffmpeg_instance* in
|
|||
});
|
||||
}
|
||||
{
|
||||
auto p = obs_properties_add_list(grp, ST_KEY_H264_LEVEL, D_TRANSLATE(S_CODEC_HEVC_LEVEL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
|
||||
auto p = obs_properties_add_list(grp, ST_KEY_H265_LEVEL, D_TRANSLATE(S_CODEC_HEVC_LEVEL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
|
||||
|
||||
streamfx::ffmpeg::tools::avoption_list_add_entries(context->priv_data, "level", [&p](const AVOption* opt) {
|
||||
if (opt->default_val.i64 == 0) {
|
Loading…
Reference in a new issue