diff --git a/CMakeLists.txt b/CMakeLists.txt index 609d50b..cec9a87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1159,12 +1159,8 @@ if(T_CHECK) is_feature_enabled(ENCODER_FFMPEG_AMF T_CHECK) if(T_CHECK) list(APPEND PROJECT_PRIVATE_SOURCE - "source/encoders/ffmpeg/amf_shared.hpp" - "source/encoders/ffmpeg/amf_shared.cpp" - "source/encoders/ffmpeg/amf_h264_handler.hpp" - "source/encoders/ffmpeg/amf_h264_handler.cpp" - "source/encoders/ffmpeg/amf_hevc_handler.hpp" - "source/encoders/ffmpeg/amf_hevc_handler.cpp" + "source/encoders/ffmpeg/amf.hpp" + "source/encoders/ffmpeg/amf.cpp" ) list(APPEND PROJECT_DEFINITIONS ENABLE_ENCODER_FFMPEG_AMF diff --git a/source/encoders/ffmpeg/amf_shared.cpp b/source/encoders/ffmpeg/amf.cpp similarity index 59% rename from source/encoders/ffmpeg/amf_shared.cpp rename to source/encoders/ffmpeg/amf.cpp index 4be507c..8968d90 100644 --- a/source/encoders/ffmpeg/amf_shared.cpp +++ b/source/encoders/ffmpeg/amf.cpp @@ -6,14 +6,20 @@ // THIS FEATURE IS DEPRECATED. SUBMITTED PATCHES WILL BE REJECTED. //--------------------------------------------------------------------------------// -#include "amf_shared.hpp" +#include "amf.hpp" +#include "common.hpp" +#include "strings.hpp" +#include "encoders/codecs/h264.hpp" +#include "encoders/codecs/hevc.hpp" +#include "encoders/encoder-ffmpeg.hpp" #include "ffmpeg/tools.hpp" +#include "plugin.hpp" -extern "C" { #include "warning-disable.hpp" +extern "C" { #include -#include "warning-enable.hpp" } +#include "warning-enable.hpp" // Translation #define ST_I18N "Encoder.FFmpeg.AMF" @@ -60,7 +66,17 @@ extern "C" { #define ST_KEY_OTHER_VBAQ "Other.VBAQ" #define ST_KEY_OTHER_ACCESSUNITDELIMITER "Other.AccessUnitDelimiter" -using namespace streamfx::encoder::ffmpeg::handler; +// Settings +#define ST_KEY_H264_PROFILE "H264.Profile" +#define ST_KEY_H264_LEVEL "H264.Level" + +// Settings +#define ST_KEY_HEVC_PROFILE "H265.Profile" +#define ST_KEY_HEVC_TIER "H265.Tier" +#define ST_KEY_HEVC_LEVEL "H265.Level" + +using namespace streamfx::encoder::ffmpeg; +using namespace streamfx::encoder::codec; std::map amf::presets{ {amf::preset::SPEED, ST_I18N_PRESET_("Speed")}, @@ -88,7 +104,30 @@ std::map amf::ratecontrolmode_to_opt{ {amf::ratecontrolmode::VBR_LATENCY, "vbr_latency"}, }; -bool streamfx::encoder::ffmpeg::handler::amf::is_available() +static std::map h264_profiles{ + {h264::profile::CONSTRAINED_BASELINE, "constrained_baseline"}, + {h264::profile::MAIN, "main"}, + {h264::profile::HIGH, "high"}, +}; + +static std::map h264_levels{ + {h264::level::L1_0, "1.0"}, {h264::level::L1_0b, "1.0b"}, {h264::level::L1_1, "1.1"}, {h264::level::L1_2, "1.2"}, {h264::level::L1_3, "1.3"}, {h264::level::L2_0, "2.0"}, {h264::level::L2_1, "2.1"}, {h264::level::L2_2, "2.2"}, {h264::level::L3_0, "3.0"}, {h264::level::L3_1, "3.1"}, {h264::level::L3_2, "3.2"}, {h264::level::L4_0, "4.0"}, {h264::level::L4_1, "4.1"}, {h264::level::L4_2, "4.2"}, {h264::level::L5_0, "5.0"}, {h264::level::L5_1, "5.1"}, {h264::level::L5_2, "5.2"}, {h264::level::L6_0, "6.0"}, {h264::level::L6_1, "6.1"}, {h264::level::L6_2, "6.2"}, +}; + +static std::map hevc_profiles{ + {hevc::profile::MAIN, "main"}, +}; + +static std::map hevc_tiers{ + {hevc::tier::MAIN, "main"}, + {hevc::tier::HIGH, "high"}, +}; + +static std::map hevc_levels{ + {hevc::level::L1_0, "1.0"}, {hevc::level::L2_0, "2.0"}, {hevc::level::L2_1, "2.1"}, {hevc::level::L3_0, "3.0"}, {hevc::level::L3_1, "3.1"}, {hevc::level::L4_0, "4.0"}, {hevc::level::L4_1, "4.1"}, {hevc::level::L5_0, "5.0"}, {hevc::level::L5_1, "5.1"}, {hevc::level::L5_2, "5.2"}, {hevc::level::L6_0, "6.0"}, {hevc::level::L6_1, "6.1"}, {hevc::level::L6_2, "6.2"}, +}; + +bool streamfx::encoder::ffmpeg::amf::is_available() { #if defined(D_PLATFORM_WINDOWS) #if defined(D_PLATFORM_64BIT) @@ -111,7 +150,7 @@ bool streamfx::encoder::ffmpeg::handler::amf::is_available() } } -void amf::get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) +void amf::defaults(ffmpeg_factory* factory, obs_data_t* settings) { obs_data_set_default_int(settings, ST_KEY_PRESET, static_cast(amf::preset::BALANCED)); @@ -173,7 +212,7 @@ static bool modified_ratecontrol(obs_properties_t* props, obs_property_t*, obs_d return true; } -void amf::get_properties_pre(obs_properties_t* props, const AVCodec* codec) +void amf::properties_before(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) { { auto p = obs_properties_add_text(props, "[[deprecated]]", D_TRANSLATE(ST_I18N_DEPRECATED), OBS_TEXT_INFO); @@ -187,8 +226,10 @@ void amf::get_properties_pre(obs_properties_t* props, const AVCodec* codec) } } -void amf::get_properties_post(obs_properties_t* props, const AVCodec* codec) +void amf::properties_after(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) { + auto codec = factory->get_avcodec(); + { // Rate Control obs_properties_t* grp = obs_properties_create(); obs_properties_add_group(props, ST_I18N_RATECONTROL, D_TRANSLATE(ST_I18N_RATECONTROL), OBS_GROUP_NORMAL, grp); @@ -257,8 +298,15 @@ void amf::get_properties_post(obs_properties_t* props, const AVCodec* codec) } } -void amf::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) +void amf::properties_runtime(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) {} + +void amf::migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) {} + +void amf::update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) { + auto codec = factory->get_avcodec(); + auto context = instance->get_avcodeccontext(); + // Alway enable loop filter. context->flags |= AV_CODEC_FLAG_LOOP_FILTER; @@ -396,10 +444,15 @@ void amf::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* con } } -void amf::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) +void amf::override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) {} + +void amf::log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) { using namespace ::streamfx::ffmpeg; + auto codec = factory->get_avcodec(); + auto context = instance->get_avcodeccontext(); + DLOG_INFO("[%s] AMD AMF:", codec->name); tools::print_av_option_string2(context, "usage", " Usage", [](int64_t v, std::string_view o) { return std::string(o); }); tools::print_av_option_string2(context, "quality", " Preset", [](int64_t v, std::string_view o) { return std::string(o); }); @@ -438,8 +491,278 @@ void amf::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext tools::print_av_option_bool(context, "me_quarter_pel", " Quarter-Pel Motion Estimation"); } -void streamfx::encoder::ffmpeg::handler::amf::get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context) {} +// H264 Handler +//-------------- -void streamfx::encoder::ffmpeg::handler::amf::migrate(obs_data_t* settings, uint64_t version, const AVCodec* codec, AVCodecContext* context) {} +amf_h264::amf_h264() : handler("h264_amf") {} -void streamfx::encoder::ffmpeg::handler::amf::override_update(ffmpeg_instance* instance, obs_data_t* settings) {} +amf_h264::~amf_h264() {} + +bool amf_h264::has_keyframes(ffmpeg_factory* instance) +{ + return true; +} + +bool amf_h264::is_hardware(ffmpeg_factory* instance) +{ + return true; +} + +bool amf_h264::has_threading(ffmpeg_factory* instance) +{ + return false; +} + +void streamfx::encoder::ffmpeg::amf_h264::adjust_info(ffmpeg_factory* factory, std::string& id, std::string& name, std::string& codec) +{ + name = "AMD AMF H.264/AVC (via FFmpeg)"; + if (!amf::is_available()) + factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; + factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; +} + +void amf_h264::defaults(ffmpeg_factory* factory, obs_data_t* settings) +{ + amf::defaults(factory, settings); + + obs_data_set_default_int(settings, ST_KEY_H264_PROFILE, static_cast(h264::profile::HIGH)); + obs_data_set_default_int(settings, ST_KEY_H264_LEVEL, static_cast(h264::level::UNKNOWN)); +} + +void amf_h264::properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) +{ + if (!instance) { + this->get_encoder_properties(factory, instance, props); + } else { + this->get_runtime_properties(factory, instance, props); + } +} + +void amf_h264::migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) +{ + amf::migrate(factory, instance, settings, version); +} + +void amf_h264::update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) +{ + auto codec = factory->get_avcodec(); + auto context = instance->get_avcodeccontext(); + + amf::update(factory, instance, settings); + + { + auto found = h264_profiles.find(static_cast(obs_data_get_int(settings, ST_KEY_H264_PROFILE))); + if (found != h264_profiles.end()) { + av_opt_set(context->priv_data, "profile", found->second.c_str(), 0); + } + } + + { + auto found = h264_levels.find(static_cast(obs_data_get_int(settings, ST_KEY_H264_LEVEL))); + if (found != h264_levels.end()) { + av_opt_set(context->priv_data, "level", found->second.c_str(), 0); + } else { + av_opt_set(context->priv_data, "level", "auto", 0); + } + } +} + +void amf_h264::override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) +{ + amf::override_update(factory, instance, settings); +} + +void amf_h264::log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) +{ + auto codec = factory->get_avcodec(); + auto context = instance->get_avcodeccontext(); + + amf::log(factory, instance, settings); + + DLOG_INFO("[%s] H.264/AVC:", codec->name); + ::streamfx::ffmpeg::tools::print_av_option_string2(context, context->priv_data, "profile", " Profile", [](int64_t v, std::string_view o) { return std::string(o); }); + ::streamfx::ffmpeg::tools::print_av_option_string2(context, context->priv_data, "level", " Level", [](int64_t v, std::string_view o) { return std::string(o); }); +} + +void amf_h264::get_encoder_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) +{ + amf::properties_before(factory, instance, props); + + { + obs_properties_t* grp = obs_properties_create(); + obs_properties_add_group(props, S_CODEC_H264, D_TRANSLATE(S_CODEC_H264), OBS_GROUP_NORMAL, grp); + + { + auto p = obs_properties_add_list(grp, ST_KEY_H264_PROFILE, D_TRANSLATE(S_CODEC_H264_PROFILE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(h264::profile::UNKNOWN)); + for (auto const kv : h264_profiles) { + std::string trans = std::string(S_CODEC_H264_PROFILE) + "." + kv.second; + obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first)); + } + } + { + auto p = obs_properties_add_list(grp, ST_KEY_H264_LEVEL, D_TRANSLATE(S_CODEC_H264_LEVEL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast(h264::level::UNKNOWN)); + for (auto const kv : h264_levels) { + obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); + } + } + } + + amf::properties_after(factory, instance, props); +} + +void amf_h264::get_runtime_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) +{ + amf::properties_runtime(factory, instance, props); +} + +void amf_h264::override_colorformat(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, AVPixelFormat& target_format) +{ + target_format = AV_PIX_FMT_NV12; +} + +static auto inst_h264 = amf_h264(); + +// H265/HEVC Handler +//------------------- + +amf_hevc::amf_hevc() : handler("hevc_amf") {} + +amf_hevc::~amf_hevc(){}; + +bool amf_hevc::has_keyframes(ffmpeg_factory* instance) +{ + return true; +} + +bool amf_hevc::is_hardware(ffmpeg_factory* instance) +{ + return true; +} + +bool amf_hevc::has_threading(ffmpeg_factory* instance) +{ + return false; +} + +void streamfx::encoder::ffmpeg::amf_hevc::adjust_info(ffmpeg_factory* factory, std::string& id, std::string& name, std::string& codec) +{ + name = "AMD AMF H.265/HEVC (via FFmpeg)"; + if (!amf::is_available()) + factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; + factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; +} + +void amf_hevc::defaults(ffmpeg_factory* factory, obs_data_t* settings) +{ + amf::defaults(factory, settings); + + obs_data_set_default_int(settings, ST_KEY_HEVC_PROFILE, static_cast(hevc::profile::MAIN)); + obs_data_set_default_int(settings, ST_KEY_HEVC_TIER, static_cast(hevc::profile::MAIN)); + obs_data_set_default_int(settings, ST_KEY_HEVC_LEVEL, static_cast(hevc::level::UNKNOWN)); +} + +void amf_hevc::properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) +{ + if (!instance) { + this->get_encoder_properties(factory, instance, props); + } else { + this->get_runtime_properties(factory, instance, props); + } +} + +void amf_hevc::migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) +{ + amf::migrate(factory, instance, settings, version); +} + +void amf_hevc::update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) +{ + auto codec = factory->get_avcodec(); + auto context = instance->get_avcodeccontext(); + + amf::update(factory, instance, settings); + + { // HEVC Options + auto found = hevc_profiles.find(static_cast(obs_data_get_int(settings, ST_KEY_HEVC_PROFILE))); + if (found != hevc_profiles.end()) { + av_opt_set(context->priv_data, "profile", found->second.c_str(), 0); + } + } + { + auto found = hevc_tiers.find(static_cast(obs_data_get_int(settings, ST_KEY_HEVC_TIER))); + if (found != hevc_tiers.end()) { + av_opt_set(context->priv_data, "tier", found->second.c_str(), 0); + } + } + { + auto found = hevc_levels.find(static_cast(obs_data_get_int(settings, ST_KEY_HEVC_LEVEL))); + if (found != hevc_levels.end()) { + av_opt_set(context->priv_data, "level", found->second.c_str(), 0); + } else { + av_opt_set(context->priv_data, "level", "auto", 0); + } + } +} + +void amf_hevc::override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) +{ + amf::override_update(factory, instance, settings); +} + +void amf_hevc::log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) +{ + auto codec = factory->get_avcodec(); + auto context = instance->get_avcodeccontext(); + + amf::log(factory, instance, settings); + + DLOG_INFO("[%s] H.265/HEVC:", codec->name); + ::streamfx::ffmpeg::tools::print_av_option_string2(context, "profile", " Profile", [](int64_t v, std::string_view o) { return std::string(o); }); + ::streamfx::ffmpeg::tools::print_av_option_string2(context, "level", " Level", [](int64_t v, std::string_view o) { return std::string(o); }); + ::streamfx::ffmpeg::tools::print_av_option_string2(context, "tier", " Tier", [](int64_t v, std::string_view o) { return std::string(o); }); +} + +void amf_hevc::get_encoder_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) +{ + amf::properties_before(factory, instance, props); + + { + obs_properties_t* grp = obs_properties_create(); + obs_properties_add_group(props, S_CODEC_HEVC, D_TRANSLATE(S_CODEC_HEVC), OBS_GROUP_NORMAL, grp); + + { + auto p = obs_properties_add_list(grp, ST_KEY_HEVC_PROFILE, D_TRANSLATE(S_CODEC_HEVC_PROFILE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(hevc::profile::UNKNOWN)); + for (auto const kv : hevc_profiles) { + std::string trans = std::string(S_CODEC_HEVC_PROFILE) + "." + kv.second; + obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first)); + } + } + { + auto p = obs_properties_add_list(grp, ST_KEY_HEVC_TIER, D_TRANSLATE(S_CODEC_HEVC_TIER), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(hevc::tier::UNKNOWN)); + for (auto const kv : hevc_tiers) { + std::string trans = std::string(S_CODEC_HEVC_TIER) + "." + kv.second; + obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first)); + } + } + { + auto p = obs_properties_add_list(grp, ST_KEY_HEVC_LEVEL, D_TRANSLATE(S_CODEC_HEVC_LEVEL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast(hevc::level::UNKNOWN)); + for (auto const kv : hevc_levels) { + obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); + } + } + } + + amf::properties_after(factory, instance, props); +} + +void amf_hevc::get_runtime_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) +{ + amf::properties_runtime(factory, instance, props); +} + +static auto inst_hevc = amf_hevc(); diff --git a/source/encoders/ffmpeg/amf.hpp b/source/encoders/ffmpeg/amf.hpp new file mode 100644 index 0000000..d5a420f --- /dev/null +++ b/source/encoders/ffmpeg/amf.hpp @@ -0,0 +1,163 @@ +// AUTOGENERATED COPYRIGHT HEADER START +// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks +// AUTOGENERATED COPYRIGHT HEADER END + +// THIS FEATURE IS DEPRECATED. SUBMITTED PATCHES WILL BE REJECTED. + +#pragma once +#include "encoders/encoder-ffmpeg.hpp" +#include "encoders/ffmpeg/handler.hpp" + +#include "warning-disable.hpp" +#include +extern "C" { +#include +} +#include "warning-enable.hpp" + +/* Parameters by their codec specific name. + * '#' denotes a parameter specified via the context itself. + +H.264 H.265 Options Done? +usage usage transcoding -- +preset preset speed,balanced,quality Defines +profile profile Defines +level level Defines + tier main,high +rc rc cqp,cbr,vbr_peak,vbr_latency Defines +preanalysis preanalysis false,true Defines +vbaq vbaq false,true Defines +enforce_hrd enforce_hrd false,true Defines +filler_data filler_data false,true -- +frame_skipping skip_frame false,true Defines +qp_i qp_i range(-1 - 51) Defines +qp_p qp_p range(-1 - 51) Defines +qp_b range(-1 - 51) Defines +#max_b_frames Defines +bf_delta_qp range(-10 - 10) -- +bf_ref false,true Defines +bf_ref_delta_qp range(-10 - 10) -- +me_half_pel me_half_pel false,true -- +me_quarter_pel me_quarter_pel false,true -- +aud aud false,true Defines +max_au_size max_au_size range(0 - Inf) -- +#refs range(0 - 16?) Defines +#color_range AVCOL_RANGE_JPEG FFmpeg +#bit_rate Defines +#rc_max_rate Defines +#rc_buffer_size Defines +#rc_initial_buffer_occupancy -- +#flags AV_CODEC_FLAG_LOOP_FILTER -- +#gop_size FFmpeg +*/ + +// AMF H.264 +// intra_refresh_mb: 0 - Inf +// header_spacing: -1 - 1000 +// coder: auto, cavlc, cabac +// qmin, qmax (HEVC uses its own settings) + +// AMF H.265 +// header_insertion_mode: none, gop, idr +// gops_per_idr: 0 - Inf +// min_qp_i: -1 - 51 +// max_qp_i: -1 - 51 +// min_qp_p: -1 - 51 +// max_qp_p: -1 - 51 + +namespace streamfx::encoder::ffmpeg { + namespace amf { + enum class preset : int32_t { + SPEED, + BALANCED, + QUALITY, + INVALID = -1, + }; + + enum class ratecontrolmode : int64_t { + CQP, + CBR, + VBR_PEAK, + VBR_LATENCY, + INVALID = -1, + }; + + extern std::map presets; + + extern std::map preset_to_opt; + + extern std::map ratecontrolmodes; + + extern std::map ratecontrolmode_to_opt; + + bool is_available(); + + void defaults(ffmpeg_factory* factory, obs_data_t* settings); + void properties_before(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props); + void properties_after(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props); + void properties_runtime(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props); + void migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version); + void update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings); + void override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings); + void log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings); + + } // namespace amf + + class amf_h264 : public handler { + public: + amf_h264(); + virtual ~amf_h264(); + + bool has_keyframes(ffmpeg_factory* instance) override; + bool is_hardware(ffmpeg_factory* instance) override; + bool has_threading(ffmpeg_factory* instance) override; + + void adjust_info(ffmpeg_factory* factory, std::string& id, std::string& name, std::string& codec) override; + + virtual std::string help(ffmpeg_factory* factory) override + { + return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-AMF"; + }; + + void defaults(ffmpeg_factory* factory, obs_data_t* settings) override; + void properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) override; + void migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) override; + void update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) override; + void override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) override; + void log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) override; + + void override_colorformat(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, AVPixelFormat& target_format) override; + + private: + void get_encoder_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props); + void get_runtime_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props); + }; + + class amf_hevc : public handler { + public: + amf_hevc(); + virtual ~amf_hevc(); + + bool has_keyframes(ffmpeg_factory* instance) override; + bool is_hardware(ffmpeg_factory* instance) override; + bool has_threading(ffmpeg_factory* instance) override; + + void adjust_info(ffmpeg_factory* factory, std::string& id, std::string& name, std::string& codec) override; + + std::string help(ffmpeg_factory* factory) override + { + return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-AMF"; + }; + + void defaults(ffmpeg_factory* factory, obs_data_t* settings) override; + void properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) override; + void migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) override; + void update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) override; + void override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) override; + void log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) override; + + private: + void get_encoder_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props); + void get_runtime_properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props); + }; +} // namespace streamfx::encoder::ffmpeg diff --git a/source/encoders/ffmpeg/amf_h264_handler.cpp b/source/encoders/ffmpeg/amf_h264_handler.cpp deleted file mode 100644 index 18c4265..0000000 --- a/source/encoders/ffmpeg/amf_h264_handler.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// AUTOGENERATED COPYRIGHT HEADER START -// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks -// AUTOGENERATED COPYRIGHT HEADER END - -//--------------------------------------------------------------------------------// -// THIS FEATURE IS DEPRECATED. SUBMITTED PATCHES WILL BE REJECTED. -//--------------------------------------------------------------------------------// - -#include "amf_h264_handler.hpp" -#include "../codecs/h264.hpp" -#include "../encoder-ffmpeg.hpp" -#include "amf_shared.hpp" -#include "ffmpeg/tools.hpp" - -extern "C" { -#include "warning-disable.hpp" -#include -#include "warning-enable.hpp" -} - -// Settings -#define ST_KEY_PROFILE "H264.Profile" -#define ST_KEY_LEVEL "H264.Level" - -using namespace streamfx::encoder::ffmpeg::handler; -using namespace streamfx::encoder::codec::h264; - -static std::map profiles{ - {profile::CONSTRAINED_BASELINE, "constrained_baseline"}, - {profile::MAIN, "main"}, - {profile::HIGH, "high"}, -}; - -static std::map levels{ - {level::L1_0, "1.0"}, {level::L1_0b, "1.0b"}, {level::L1_1, "1.1"}, {level::L1_2, "1.2"}, {level::L1_3, "1.3"}, {level::L2_0, "2.0"}, {level::L2_1, "2.1"}, {level::L2_2, "2.2"}, {level::L3_0, "3.0"}, {level::L3_1, "3.1"}, {level::L3_2, "3.2"}, {level::L4_0, "4.0"}, {level::L4_1, "4.1"}, {level::L4_2, "4.2"}, {level::L5_0, "5.0"}, {level::L5_1, "5.1"}, {level::L5_2, "5.2"}, {level::L6_0, "6.0"}, {level::L6_1, "6.1"}, {level::L6_2, "6.2"}, -}; - -void amf_h264_handler::adjust_info(ffmpeg_factory* factory, const AVCodec* codec, std::string& id, std::string& name, std::string& codec_id) -{ - name = "AMD AMF H.264/AVC (via FFmpeg)"; - if (!amf::is_available()) - factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; - factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; -} - -void amf_h264_handler::get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode) -{ - amf::get_defaults(settings, codec, context); - - obs_data_set_default_int(settings, ST_KEY_PROFILE, static_cast(profile::HIGH)); - obs_data_set_default_int(settings, ST_KEY_LEVEL, static_cast(level::UNKNOWN)); -} - -bool amf_h264_handler::has_keyframe_support(ffmpeg_factory* instance) -{ - return true; -} - -bool amf_h264_handler::is_hardware_encoder(ffmpeg_factory* instance) -{ - return true; -} - -bool amf_h264_handler::has_threading_support(ffmpeg_factory* instance) -{ - return false; -} - -bool amf_h264_handler::has_pixel_format_support(ffmpeg_factory* instance) -{ - return false; -} - -void amf_h264_handler::get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, bool hw_encode) -{ - if (!context) { - this->get_encoder_properties(props, codec); - } else { - this->get_runtime_properties(props, codec, context); - } -} - -void amf_h264_handler::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) -{ - amf::update(settings, codec, context); - - { - auto found = profiles.find(static_cast(obs_data_get_int(settings, ST_KEY_PROFILE))); - if (found != profiles.end()) { - av_opt_set(context->priv_data, "profile", found->second.c_str(), 0); - } - } - - { - auto found = levels.find(static_cast(obs_data_get_int(settings, ST_KEY_LEVEL))); - if (found != levels.end()) { - av_opt_set(context->priv_data, "level", found->second.c_str(), 0); - } else { - av_opt_set(context->priv_data, "level", "auto", 0); - } - } -} - -void amf_h264_handler::override_update(ffmpeg_instance* instance, obs_data_t* settings) -{ - amf::override_update(instance, settings); -} - -void amf_h264_handler::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) -{ - amf::log_options(settings, codec, context); - - DLOG_INFO("[%s] H.264/AVC:", codec->name); - ::streamfx::ffmpeg::tools::print_av_option_string2(context, context->priv_data, "profile", " Profile", [](int64_t v, std::string_view o) { return std::string(o); }); - ::streamfx::ffmpeg::tools::print_av_option_string2(context, context->priv_data, "level", " Level", [](int64_t v, std::string_view o) { return std::string(o); }); -} - -void amf_h264_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec) -{ - amf::get_properties_pre(props, codec); - - { - obs_properties_t* grp = obs_properties_create(); - obs_properties_add_group(props, S_CODEC_H264, D_TRANSLATE(S_CODEC_H264), OBS_GROUP_NORMAL, grp); - - { - auto p = obs_properties_add_list(grp, ST_KEY_PROFILE, D_TRANSLATE(S_CODEC_H264_PROFILE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(profile::UNKNOWN)); - for (auto const kv : profiles) { - std::string trans = std::string(S_CODEC_H264_PROFILE) + "." + kv.second; - obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first)); - } - } - { - auto p = obs_properties_add_list(grp, ST_KEY_LEVEL, D_TRANSLATE(S_CODEC_H264_LEVEL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast(level::UNKNOWN)); - for (auto const kv : levels) { - obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); - } - } - } - - amf::get_properties_post(props, codec); -} - -void amf_h264_handler::get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context) -{ - amf::get_runtime_properties(props, codec, context); -} - -void amf_h264_handler::migrate(obs_data_t* settings, std::uint64_t version, const AVCodec* codec, AVCodecContext* context) -{ - amf::migrate(settings, version, codec, context); -} - -void amf_h264_handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) -{ - target_format = AV_PIX_FMT_NV12; -} diff --git a/source/encoders/ffmpeg/amf_h264_handler.hpp b/source/encoders/ffmpeg/amf_h264_handler.hpp deleted file mode 100644 index 7747bb7..0000000 --- a/source/encoders/ffmpeg/amf_h264_handler.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// AUTOGENERATED COPYRIGHT HEADER START -// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks -// AUTOGENERATED COPYRIGHT HEADER END - -//--------------------------------------------------------------------------------// -// THIS FEATURE IS DEPRECATED. SUBMITTED PATCHES WILL BE REJECTED. -//--------------------------------------------------------------------------------// - -#pragma once -#include "common.hpp" -#include "handler.hpp" - -extern "C" { -#include "warning-disable.hpp" -#include -#include "warning-enable.hpp" -} - -namespace streamfx::encoder::ffmpeg::handler { - class amf_h264_handler : public handler { - public: - virtual ~amf_h264_handler(){}; - - public /*factory*/: - void adjust_info(ffmpeg_factory* factory, const AVCodec* codec, std::string& id, std::string& name, std::string& codec_id) override; - - void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode) override; - - virtual std::string_view get_help_url(const AVCodec* codec) override - { - return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-AMF"; - }; - - public /*support tests*/: - bool has_keyframe_support(ffmpeg_factory* instance) override; - - bool is_hardware_encoder(ffmpeg_factory* instance) override; - - bool has_threading_support(ffmpeg_factory* instance) override; - - bool has_pixel_format_support(ffmpeg_factory* instance) override; - - public /*settings*/: - void get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, bool hw_encode) override; - - void migrate(obs_data_t* settings, std::uint64_t version, const AVCodec* codec, AVCodecContext* context) override; - - void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override; - - void override_update(ffmpeg_instance* instance, obs_data_t* settings) override; - - void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override; - - public /*instance*/: - void override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override; - - private: - void get_encoder_properties(obs_properties_t* props, const AVCodec* codec); - - void get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context); - }; -} // namespace streamfx::encoder::ffmpeg::handler diff --git a/source/encoders/ffmpeg/amf_hevc_handler.cpp b/source/encoders/ffmpeg/amf_hevc_handler.cpp deleted file mode 100644 index 2646e7f..0000000 --- a/source/encoders/ffmpeg/amf_hevc_handler.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// AUTOGENERATED COPYRIGHT HEADER START -// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks -// AUTOGENERATED COPYRIGHT HEADER END - -//--------------------------------------------------------------------------------// -// THIS FEATURE IS DEPRECATED. SUBMITTED PATCHES WILL BE REJECTED. -//--------------------------------------------------------------------------------// - -#include "amf_hevc_handler.hpp" -#include "common.hpp" -#include "strings.hpp" -#include "../codecs/hevc.hpp" -#include "../encoder-ffmpeg.hpp" -#include "amf_shared.hpp" -#include "ffmpeg/tools.hpp" -#include "plugin.hpp" - -extern "C" { -#include "warning-disable.hpp" -#include -#include "warning-enable.hpp" -} - -// Settings -#define ST_KEY_PROFILE "H265.Profile" -#define ST_KEY_TIER "H265.Tier" -#define ST_KEY_LEVEL "H265.Level" - -using namespace streamfx::encoder::ffmpeg::handler; -using namespace streamfx::encoder::codec::hevc; - -static std::map profiles{ - {profile::MAIN, "main"}, -}; - -static std::map tiers{ - {tier::MAIN, "main"}, - {tier::HIGH, "high"}, -}; - -static std::map levels{ - {level::L1_0, "1.0"}, {level::L2_0, "2.0"}, {level::L2_1, "2.1"}, {level::L3_0, "3.0"}, {level::L3_1, "3.1"}, {level::L4_0, "4.0"}, {level::L4_1, "4.1"}, {level::L5_0, "5.0"}, {level::L5_1, "5.1"}, {level::L5_2, "5.2"}, {level::L6_0, "6.0"}, {level::L6_1, "6.1"}, {level::L6_2, "6.2"}, -}; - -void amf_hevc_handler::adjust_info(ffmpeg_factory* factory, const AVCodec* codec, std::string& id, std::string& name, std::string& codec_id) -{ - name = "AMD AMF H.265/HEVC (via FFmpeg)"; - if (!amf::is_available()) - factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; - factory->get_info()->caps |= OBS_ENCODER_CAP_DEPRECATED; -} - -void amf_hevc_handler::get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool) -{ - amf::get_defaults(settings, codec, context); - - obs_data_set_default_int(settings, ST_KEY_PROFILE, static_cast(profile::MAIN)); - obs_data_set_default_int(settings, ST_KEY_TIER, static_cast(profile::MAIN)); - obs_data_set_default_int(settings, ST_KEY_LEVEL, static_cast(level::UNKNOWN)); -} - -bool amf_hevc_handler::has_keyframe_support(ffmpeg_factory*) -{ - return true; -} - -bool amf_hevc_handler::is_hardware_encoder(ffmpeg_factory* instance) -{ - return true; -} - -bool amf_hevc_handler::has_threading_support(ffmpeg_factory* instance) -{ - return false; -} - -bool amf_hevc_handler::has_pixel_format_support(ffmpeg_factory* instance) -{ - return false; -} - -void amf_hevc_handler::get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, bool) -{ - if (!context) { - this->get_encoder_properties(props, codec); - } else { - this->get_runtime_properties(props, codec, context); - } -} - -void amf_hevc_handler::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) -{ - amf::update(settings, codec, context); - - { // HEVC Options - auto found = profiles.find(static_cast(obs_data_get_int(settings, ST_KEY_PROFILE))); - if (found != profiles.end()) { - av_opt_set(context->priv_data, "profile", found->second.c_str(), 0); - } - } - { - auto found = tiers.find(static_cast(obs_data_get_int(settings, ST_KEY_TIER))); - if (found != tiers.end()) { - av_opt_set(context->priv_data, "tier", found->second.c_str(), 0); - } - } - { - auto found = levels.find(static_cast(obs_data_get_int(settings, ST_KEY_LEVEL))); - if (found != levels.end()) { - av_opt_set(context->priv_data, "level", found->second.c_str(), 0); - } else { - av_opt_set(context->priv_data, "level", "auto", 0); - } - } -} - -void amf_hevc_handler::override_update(ffmpeg_instance* instance, obs_data_t* settings) -{ - amf::override_update(instance, settings); -} - -void amf_hevc_handler::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) -{ - amf::log_options(settings, codec, context); - - DLOG_INFO("[%s] H.265/HEVC:", codec->name); - ::streamfx::ffmpeg::tools::print_av_option_string2(context, "profile", " Profile", [](int64_t v, std::string_view o) { return std::string(o); }); - ::streamfx::ffmpeg::tools::print_av_option_string2(context, "level", " Level", [](int64_t v, std::string_view o) { return std::string(o); }); - ::streamfx::ffmpeg::tools::print_av_option_string2(context, "tier", " Tier", [](int64_t v, std::string_view o) { return std::string(o); }); -} - -void amf_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec) -{ - amf::get_properties_pre(props, codec); - - { - obs_properties_t* grp = obs_properties_create(); - obs_properties_add_group(props, S_CODEC_HEVC, D_TRANSLATE(S_CODEC_HEVC), OBS_GROUP_NORMAL, grp); - - { - auto p = obs_properties_add_list(grp, ST_KEY_PROFILE, D_TRANSLATE(S_CODEC_HEVC_PROFILE), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(profile::UNKNOWN)); - for (auto const kv : profiles) { - std::string trans = std::string(S_CODEC_HEVC_PROFILE) + "." + kv.second; - obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first)); - } - } - { - auto p = obs_properties_add_list(grp, ST_KEY_TIER, D_TRANSLATE(S_CODEC_HEVC_TIER), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(p, D_TRANSLATE(S_STATE_DEFAULT), static_cast(tier::UNKNOWN)); - for (auto const kv : tiers) { - std::string trans = std::string(S_CODEC_HEVC_TIER) + "." + kv.second; - obs_property_list_add_int(p, D_TRANSLATE(trans.c_str()), static_cast(kv.first)); - } - } - { - auto p = obs_properties_add_list(grp, ST_KEY_LEVEL, D_TRANSLATE(S_CODEC_HEVC_LEVEL), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(p, D_TRANSLATE(S_STATE_AUTOMATIC), static_cast(level::UNKNOWN)); - for (auto const kv : levels) { - obs_property_list_add_int(p, kv.second.c_str(), static_cast(kv.first)); - } - } - } - - amf::get_properties_post(props, codec); -} - -void amf_hevc_handler::get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context) -{ - amf::get_runtime_properties(props, codec, context); -} - -void streamfx::encoder::ffmpeg::handler::amf_hevc_handler::migrate(obs_data_t* settings, std::uint64_t version, const AVCodec* codec, AVCodecContext* context) -{ - amf::migrate(settings, version, codec, context); -} diff --git a/source/encoders/ffmpeg/amf_hevc_handler.hpp b/source/encoders/ffmpeg/amf_hevc_handler.hpp deleted file mode 100644 index a404b4c..0000000 --- a/source/encoders/ffmpeg/amf_hevc_handler.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// AUTOGENERATED COPYRIGHT HEADER START -// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks -// AUTOGENERATED COPYRIGHT HEADER END - -//--------------------------------------------------------------------------------// -// THIS FEATURE IS DEPRECATED. SUBMITTED PATCHES WILL BE REJECTED. -//--------------------------------------------------------------------------------// - -#pragma once -#include "handler.hpp" - -extern "C" { -#include "warning-disable.hpp" -#include -#include "warning-enable.hpp" -} - -namespace streamfx::encoder::ffmpeg::handler { - class amf_hevc_handler : public handler { - public: - virtual ~amf_hevc_handler(){}; - - public /*factory*/: - virtual void adjust_info(ffmpeg_factory* factory, const AVCodec* codec, std::string& id, std::string& name, std::string& codec_id); - - virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode); - - virtual std::string_view get_help_url(const AVCodec* codec) override - { - return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg-AMF"; - }; - - public /*support tests*/: - virtual bool has_keyframe_support(ffmpeg_factory* instance); - - virtual bool is_hardware_encoder(ffmpeg_factory* instance); - - virtual bool has_threading_support(ffmpeg_factory* instance); - - virtual bool has_pixel_format_support(ffmpeg_factory* instance); - - public /*settings*/: - virtual void get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, bool hw_encode); - - virtual void migrate(obs_data_t* settings, std::uint64_t version, const AVCodec* codec, AVCodecContext* context); - - virtual void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context); - - virtual void override_update(ffmpeg_instance* instance, obs_data_t* settings); - - virtual void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context); - - private: - void get_encoder_properties(obs_properties_t* props, const AVCodec* codec); - - void get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context); - }; -} // namespace streamfx::encoder::ffmpeg::handler diff --git a/source/encoders/ffmpeg/amf_shared.hpp b/source/encoders/ffmpeg/amf_shared.hpp deleted file mode 100644 index 35e8031..0000000 --- a/source/encoders/ffmpeg/amf_shared.hpp +++ /dev/null @@ -1,109 +0,0 @@ -// AUTOGENERATED COPYRIGHT HEADER START -// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks -// AUTOGENERATED COPYRIGHT HEADER END - -// THIS FEATURE IS DEPRECATED. SUBMITTED PATCHES WILL BE REJECTED. - -#pragma once -#include "common.hpp" -#include "handler.hpp" - -extern "C" { -#include "warning-disable.hpp" -#include -#include "warning-enable.hpp" -} - -namespace streamfx::encoder::ffmpeg::handler::amf { - enum class preset : int32_t { - SPEED, - BALANCED, - QUALITY, - INVALID = -1, - }; - - enum class ratecontrolmode : int64_t { - CQP, - CBR, - VBR_PEAK, - VBR_LATENCY, - INVALID = -1, - }; - - extern std::map presets; - - extern std::map preset_to_opt; - - extern std::map ratecontrolmodes; - - extern std::map ratecontrolmode_to_opt; - - bool is_available(); - - void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context); - - void get_properties_pre(obs_properties_t* props, const AVCodec* codec); - - void get_properties_post(obs_properties_t* props, const AVCodec* codec); - - void get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context); - - void migrate(obs_data_t* settings, uint64_t version, const AVCodec* codec, AVCodecContext* context); - - void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context); - - void override_update(ffmpeg_instance* instance, obs_data_t* settings); - - void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context); - -} // namespace streamfx::encoder::ffmpeg::handler::amf - -/* Parameters by their codec specific name. - * '#' denotes a parameter specified via the context itself. - -H.264 H.265 Options Done? -usage usage transcoding -- -preset preset speed,balanced,quality Defines -profile profile Defines -level level Defines - tier main,high -rc rc cqp,cbr,vbr_peak,vbr_latency Defines -preanalysis preanalysis false,true Defines -vbaq vbaq false,true Defines -enforce_hrd enforce_hrd false,true Defines -filler_data filler_data false,true -- -frame_skipping skip_frame false,true Defines -qp_i qp_i range(-1 - 51) Defines -qp_p qp_p range(-1 - 51) Defines -qp_b range(-1 - 51) Defines -#max_b_frames Defines -bf_delta_qp range(-10 - 10) -- -bf_ref false,true Defines -bf_ref_delta_qp range(-10 - 10) -- -me_half_pel me_half_pel false,true -- -me_quarter_pel me_quarter_pel false,true -- -aud aud false,true Defines -max_au_size max_au_size range(0 - Inf) -- -#refs range(0 - 16?) Defines -#color_range AVCOL_RANGE_JPEG FFmpeg -#bit_rate Defines -#rc_max_rate Defines -#rc_buffer_size Defines -#rc_initial_buffer_occupancy -- -#flags AV_CODEC_FLAG_LOOP_FILTER -- -#gop_size FFmpeg -*/ - -// AMF H.264 -// intra_refresh_mb: 0 - Inf -// header_spacing: -1 - 1000 -// coder: auto, cavlc, cabac -// qmin, qmax (HEVC uses its own settings) - -// AMF H.265 -// header_insertion_mode: none, gop, idr -// gops_per_idr: 0 - Inf -// min_qp_i: -1 - 51 -// max_qp_i: -1 - 51 -// min_qp_p: -1 - 51 -// max_qp_p: -1 - 51