encoder: Separate get_defaults and get_properties for SW/HW encoders

This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-10-04 19:27:45 +02:00
parent e4e76dae8f
commit 2f8acc58cf
14 changed files with 115 additions and 77 deletions
+71 -27
View File
@@ -147,6 +147,17 @@ static void _get_defaults(obs_data_t* settings, void* type_data) noexcept try {
PLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
};
static void _get_defaults_texture(obs_data_t* settings, void* type_data) noexcept try {
#ifdef DEBUG_CALL_ORDER
PLOG_INFO("%s %llX %llX", __FUNCTION_NAME__, settings, type_data);
#endif
reinterpret_cast<obsffmpeg::encoder_factory*>(type_data)->get_defaults(settings, true);
} catch (const std::exception& ex) {
PLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
} catch (...) {
PLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
};
static obs_properties_t* _get_properties(void* ptr, void* type_data) noexcept try {
#ifdef DEBUG_CALL_ORDER
PLOG_INFO("%s %llX %llX", __FUNCTION_NAME__, ptr, type_data);
@@ -167,6 +178,26 @@ static obs_properties_t* _get_properties(void* ptr, void* type_data) noexcept tr
return reinterpret_cast<obs_properties_t*>(0);
}
static obs_properties_t* _get_properties_texture(void* ptr, void* type_data) noexcept try {
#ifdef DEBUG_CALL_ORDER
PLOG_INFO("%s %llX %llX", __FUNCTION_NAME__, ptr, type_data);
#endif
obs_properties_t* props = obs_properties_create();
if (type_data != nullptr) {
reinterpret_cast<obsffmpeg::encoder_factory*>(type_data)->get_properties(props, true);
}
if (ptr != nullptr) {
reinterpret_cast<obsffmpeg::encoder*>(ptr)->get_properties(props, true);
}
return props;
} catch (const std::exception& ex) {
PLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
return reinterpret_cast<obs_properties_t*>(0);
} catch (...) {
PLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
return reinterpret_cast<obs_properties_t*>(0);
}
static bool _update(void* ptr, obs_data_t* settings) noexcept try {
#ifdef DEBUG_CALL_ORDER
PLOG_INFO("%s %llX %llX", __FUNCTION_NAME__, ptr, settings);
@@ -384,8 +415,10 @@ void obsffmpeg::encoder_factory::register_encoder()
info.oei.type_data = this;
if (ffmpeg::tools::can_hardware_encode(avcodec_ptr)) {
info.oei.create = _create_texture;
info.oei.encode_texture = _encode_texture;
info.oei.create = _create_texture;
info.oei.encode_texture = _encode_texture;
info.oei.get_defaults2 = _get_defaults_texture;
info.oei.get_properties2 = _get_properties_texture;
info_fallback.oei.type = info.oei.type;
info_fallback.oei.create = _create;
@@ -413,10 +446,10 @@ void obsffmpeg::encoder_factory::register_encoder()
avcodec_ptr->name, avcodec_ptr->long_name, avcodec_ptr->capabilities);
}
void obsffmpeg::encoder_factory::get_defaults(obs_data_t* settings)
void obsffmpeg::encoder_factory::get_defaults(obs_data_t* settings, bool hw_encode)
{
if (_handler)
_handler->get_defaults(settings, avcodec_ptr, nullptr);
_handler->get_defaults(settings, avcodec_ptr, nullptr, hw_encode);
if ((avcodec_ptr->capabilities & AV_CODEC_CAP_INTRA_ONLY) == 0) {
obs_data_set_default_int(settings, S_KEYFRAMES_INTERVALTYPE, 0);
@@ -427,8 +460,11 @@ void obsffmpeg::encoder_factory::get_defaults(obs_data_t* settings)
{ // Integrated Options
// FFmpeg
obs_data_set_default_string(settings, ST_FFMPEG_CUSTOMSETTINGS, "");
obs_data_set_default_int(settings, ST_FFMPEG_COLORFORMAT, static_cast<int64_t>(AV_PIX_FMT_NONE));
obs_data_set_default_int(settings, ST_FFMPEG_THREADS, 0);
if (!hw_encode) {
obs_data_set_default_int(settings, ST_FFMPEG_COLORFORMAT,
static_cast<int64_t>(AV_PIX_FMT_NONE));
obs_data_set_default_int(settings, ST_FFMPEG_THREADS, 0);
}
obs_data_set_default_int(settings, ST_FFMPEG_STANDARDCOMPLIANCE, FF_COMPLIANCE_STRICT);
}
}
@@ -446,10 +482,10 @@ static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_dat
return false;
}
void obsffmpeg::encoder_factory::get_properties(obs_properties_t* props)
void obsffmpeg::encoder_factory::get_properties(obs_properties_t* props, bool hw_encode)
{
if (_handler)
_handler->get_properties(props, avcodec_ptr, nullptr);
_handler->get_properties(props, avcodec_ptr, nullptr, hw_encode);
if ((avcodec_ptr->capabilities & AV_CODEC_CAP_INTRA_ONLY) == 0) {
// Key-Frame Options
@@ -498,21 +534,25 @@ void obsffmpeg::encoder_factory::get_properties(obs_properties_t* props)
obs_text_type::OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, TRANSLATE(DESC(ST_FFMPEG_CUSTOMSETTINGS)));
}
if (avcodec_ptr->pix_fmts) {
auto p = obs_properties_add_list(grp, ST_FFMPEG_COLORFORMAT, TRANSLATE(ST_FFMPEG_COLORFORMAT),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, TRANSLATE(DESC(ST_FFMPEG_COLORFORMAT)));
obs_property_list_add_int(p, TRANSLATE(S_STATE_AUTOMATIC),
static_cast<int64_t>(AV_PIX_FMT_NONE));
for (auto ptr = avcodec_ptr->pix_fmts; *ptr != AV_PIX_FMT_NONE; ptr++) {
obs_property_list_add_int(p, ffmpeg::tools::get_pixel_format_name(*ptr),
static_cast<int64_t>(*ptr));
if (!hw_encode) {
if (avcodec_ptr->pix_fmts) {
auto p = obs_properties_add_list(grp, ST_FFMPEG_COLORFORMAT,
TRANSLATE(ST_FFMPEG_COLORFORMAT), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
obs_property_set_long_description(p, TRANSLATE(DESC(ST_FFMPEG_COLORFORMAT)));
obs_property_list_add_int(p, TRANSLATE(S_STATE_AUTOMATIC),
static_cast<int64_t>(AV_PIX_FMT_NONE));
for (auto ptr = avcodec_ptr->pix_fmts; *ptr != AV_PIX_FMT_NONE; ptr++) {
obs_property_list_add_int(p, ffmpeg::tools::get_pixel_format_name(*ptr),
static_cast<int64_t>(*ptr));
}
}
if (avcodec_ptr->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
auto p =
obs_properties_add_int_slider(grp, ST_FFMPEG_THREADS, TRANSLATE(ST_FFMPEG_THREADS),
0, std::thread::hardware_concurrency() * 2, 1);
obs_property_set_long_description(p, TRANSLATE(DESC(ST_FFMPEG_THREADS)));
}
}
if (avcodec_ptr->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
auto p = obs_properties_add_int_slider(grp, ST_FFMPEG_THREADS, TRANSLATE(ST_FFMPEG_THREADS), 0,
std::thread::hardware_concurrency() * 2, 1);
obs_property_set_long_description(p, TRANSLATE(DESC(ST_FFMPEG_THREADS)));
}
{
auto p = obs_properties_add_list(grp, ST_FFMPEG_STANDARDCOMPLIANCE,
@@ -615,7 +655,7 @@ void obsffmpeg::encoder::initialize_sw(obs_data_t* settings)
}
}
void obsffmpeg::encoder::initialize_hw(obs_data_t* settings)
void obsffmpeg::encoder::initialize_hw(obs_data_t*)
{
// Initialize Video Encoding
auto voi = video_output_get_info(obs_encoder_video(_self));
@@ -810,10 +850,10 @@ obsffmpeg::encoder::~encoder()
_swscale.finalize();
}
void obsffmpeg::encoder::get_properties(obs_properties_t* props)
void obsffmpeg::encoder::get_properties(obs_properties_t* props, bool hw_encode)
{
if (_handler)
_handler->get_properties(props, _codec, _context);
_handler->get_properties(props, _codec, _context, hw_encode);
obs_property_set_enabled(obs_properties_get(props, S_KEYFRAMES), false);
obs_property_set_enabled(obs_properties_get(props, S_KEYFRAMES_INTERVALTYPE), false);
@@ -832,8 +872,8 @@ bool obsffmpeg::encoder::update(obs_data_t* settings)
_context->strict_std_compliance = static_cast<int>(obs_data_get_int(settings, ST_FFMPEG_STANDARDCOMPLIANCE));
_context->debug = 0;
/// Threading
if (_codec->capabilities
& (AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)) {
if (_codec->capabilities & (AV_CODEC_CAP_AUTO_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS)
&& !_hwinst) {
if (_codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
_context->thread_type |= FF_THREAD_FRAME;
}
@@ -848,6 +888,10 @@ bool obsffmpeg::encoder::update(obs_data_t* settings)
_context->thread_count = std::thread::hardware_concurrency();
_lag_in_frames = _context->thread_count;
}
} else {
_context->thread_count = 1;
_context->thread_type = 0;
_lag_in_frames = 1;
}
if (_handler)
+4 -4
View File
@@ -52,7 +52,7 @@ namespace obsffmpeg {
std::string uid;
std::string codec;
std::string readable_name;
obs_encoder_info oei;
obs_encoder_info oei = {0};
};
class encoder_factory {
@@ -68,9 +68,9 @@ namespace obsffmpeg {
void register_encoder();
void get_defaults(obs_data_t* settings);
void get_defaults(obs_data_t* settings, bool hw_encoder = false);
void get_properties(obs_properties_t* props);
void get_properties(obs_properties_t* props, bool hw_encoder = false);
const AVCodec* get_avcodec();
@@ -122,7 +122,7 @@ namespace obsffmpeg {
public: // OBS API
// Shared
void get_properties(obs_properties_t* props);
void get_properties(obs_properties_t* props, bool hw_encode = false);
bool update(obs_data_t* settings);
+1 -1
View File
@@ -171,7 +171,7 @@ std::shared_ptr<AVFrame> obsffmpeg::hwapi::d3d11_instance::allocate_frame(AVBuff
return frame;
}
void obsffmpeg::hwapi::d3d11_instance::copy_from_obs(AVBufferRef* frames, uint32_t handle, uint64_t lock_key,
void obsffmpeg::hwapi::d3d11_instance::copy_from_obs(AVBufferRef*, uint32_t handle, uint64_t lock_key,
uint64_t* next_lock_key, std::shared_ptr<AVFrame> frame)
{
ATL::CComPtr<IDXGIKeyedMutex> mutex;
+3 -2
View File
@@ -35,7 +35,7 @@ extern "C" {
#pragma warning(pop)
}
void obsffmpeg::ui::debug_handler::get_defaults(obs_data_t*, const AVCodec*, AVCodecContext*) {}
void obsffmpeg::ui::debug_handler::get_defaults(obs_data_t*, const AVCodec*, AVCodecContext*, bool) {}
template<typename T>
std::string to_string(T value){};
@@ -64,7 +64,8 @@ std::string to_string(double_t value)
return std::string(buf.data(), buf.data() + buf.size());
}
void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t*, const AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t*, const AVCodec* codec, AVCodecContext* context,
bool)
{
if (context)
return;
+3 -3
View File
@@ -26,11 +26,11 @@ namespace obsffmpeg {
namespace ui {
class debug_handler : public handler {
public:
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context,
bool hw_encode) override;
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
AVCodecContext* context, bool hw_encode) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
+12 -19
View File
@@ -23,38 +23,31 @@
void obsffmpeg::ui::handler::override_visible_name(const AVCodec*, std::string&) {}
void obsffmpeg::ui::handler::override_info(obs_encoder_info* main, obs_encoder_info* fallback) {}
void obsffmpeg::ui::handler::override_info(obs_encoder_info*, obs_encoder_info*) {}
void obsffmpeg::ui::handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings,
const AVCodec* codec, AVCodecContext* context)
{}
void obsffmpeg::ui::handler::override_colorformat(AVPixelFormat&, obs_data_t*, const AVCodec*, AVCodecContext*) {}
void obsffmpeg::ui::handler::override_lag_in_frames(size_t& lag, obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context)
{}
void obsffmpeg::ui::handler::override_lag_in_frames(size_t&, obs_data_t*, const AVCodec*, AVCodecContext*) {}
void obsffmpeg::ui::handler::get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) {}
void obsffmpeg::ui::handler::get_defaults(obs_data_t*, const AVCodec*, AVCodecContext*, bool) {}
void obsffmpeg::ui::handler::get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context) {}
void obsffmpeg::ui::handler::get_properties(obs_properties_t*, const AVCodec*, AVCodecContext*, bool) {}
obsffmpeg::hwapi::device obsffmpeg::ui::handler::find_hw_device(std::shared_ptr<obsffmpeg::hwapi::base> api,
const AVCodec* codec, AVCodecContext* context)
obsffmpeg::hwapi::device obsffmpeg::ui::handler::find_hw_device(std::shared_ptr<obsffmpeg::hwapi::base>, const AVCodec*,
AVCodecContext*)
{
return obsffmpeg::hwapi::device();
}
void obsffmpeg::ui::handler::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) {}
void obsffmpeg::ui::handler::update(obs_data_t*, const AVCodec*, AVCodecContext*) {}
void obsffmpeg::ui::handler::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) {}
void obsffmpeg::ui::handler::log_options(obs_data_t*, const AVCodec*, AVCodecContext*) {}
void obsffmpeg::ui::handler::import_from_ffmpeg(const std::string ffmpeg, obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context)
{}
void obsffmpeg::ui::handler::import_from_ffmpeg(const std::string, obs_data_t*, const AVCodec*, AVCodecContext*) {}
std::string obsffmpeg::ui::handler::export_for_ffmpeg(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context)
std::string obsffmpeg::ui::handler::export_for_ffmpeg(obs_data_t*, const AVCodec*, AVCodecContext*)
{
return std::string();
}
void obsffmpeg::ui::handler::process_avpacket(AVPacket& packet, const AVCodec* codec, AVCodecContext* context) {}
void obsffmpeg::ui::handler::process_avpacket(AVPacket&, const AVCodec*, AVCodecContext*) {}
+2 -2
View File
@@ -50,10 +50,10 @@ namespace obsffmpeg {
virtual void override_lag_in_frames(size_t& lag, obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context);
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode);
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context);
AVCodecContext* context, bool hw_encode);
virtual obsffmpeg::hwapi::device find_hw_device(std::shared_ptr<obsffmpeg::hwapi::base> api,
const AVCodec* codec, AVCodecContext* context);
+2 -2
View File
@@ -92,7 +92,7 @@ void obsffmpeg::ui::nvenc_h264_handler::override_lag_in_frames(size_t& lag, obs_
}
void obsffmpeg::ui::nvenc_h264_handler::get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context)
AVCodecContext* context, bool)
{
nvenc::get_defaults(settings, codec, context);
@@ -101,7 +101,7 @@ void obsffmpeg::ui::nvenc_h264_handler::get_defaults(obs_data_t* settings, const
}
void obsffmpeg::ui::nvenc_h264_handler::get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
AVCodecContext* context, bool)
{
if (!context) {
this->get_encoder_properties(props, codec);
+3 -3
View File
@@ -39,11 +39,11 @@ namespace obsffmpeg {
virtual void override_lag_in_frames(size_t& lag, obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context,
bool hw_encode) override;
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
AVCodecContext* context, bool hw_encode) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
+2 -2
View File
@@ -94,7 +94,7 @@ void obsffmpeg::ui::nvenc_hevc_handler::override_lag_in_frames(size_t& lag, obs_
}
void obsffmpeg::ui::nvenc_hevc_handler::get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context)
AVCodecContext* context, bool)
{
nvenc::get_defaults(settings, codec, context);
@@ -104,7 +104,7 @@ void obsffmpeg::ui::nvenc_hevc_handler::get_defaults(obs_data_t* settings, const
}
void obsffmpeg::ui::nvenc_hevc_handler::get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
AVCodecContext* context, bool)
{
if (!context) {
this->get_encoder_properties(props, codec);
+3 -3
View File
@@ -39,11 +39,11 @@ namespace obsffmpeg {
virtual void override_lag_in_frames(size_t& lag, obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context,
bool hw_encode) override;
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
AVCodecContext* context, bool hw_encode) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
+2 -2
View File
@@ -131,7 +131,7 @@ std::map<b_ref_mode, std::string> obsffmpeg::nvenc::b_ref_mode_to_opt{
{b_ref_mode::MIDDLE, "middle"},
};
void obsffmpeg::nvenc::override_lag_in_frames(size_t& lag, obs_data_t* settings, const AVCodec* codec,
void obsffmpeg::nvenc::override_lag_in_frames(size_t& lag, obs_data_t*, const AVCodec*,
AVCodecContext* context)
{
// With NVENC, the number of frames lagged before we get our first
@@ -689,7 +689,7 @@ void obsffmpeg::nvenc::log_options(obs_data_t* settings, const AVCodec* codec, A
bool cfg_rc_quality = obs_data_get_bool(settings, ST_RATECONTROL_QUALITY);
int64_t cfg_rc_quality_min = obs_data_get_int(settings, ST_RATECONTROL_QUALITY_MINIMUM);
int64_t cfg_rc_quality_max = obs_data_get_int(settings, ST_RATECONTROL_QUALITY_MAXIMUM);
double_t cfg_rc_quality_tgt = obs_data_get_int(settings, ST_RATECONTROL_QUALITY_TARGET);
double_t cfg_rc_quality_tgt = obs_data_get_double(settings, ST_RATECONTROL_QUALITY_TARGET) / 100.0 * 51.0;
int64_t cfg_rc_qp_i = obs_data_get_int(settings, ST_RATECONTROL_QP_I);
int64_t cfg_rc_qp_p = obs_data_get_int(settings, ST_RATECONTROL_QP_P);
int64_t cfg_rc_qp_b = obs_data_get_int(settings, ST_RATECONTROL_QP_B);
+5 -5
View File
@@ -36,7 +36,7 @@ INITIALIZER(prores_aw_handler_init)
};
void obsffmpeg::ui::prores_aw_handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings,
const AVCodec* codec, AVCodecContext* context)
const AVCodec* codec, AVCodecContext*)
{
std::string profile = "";
@@ -60,13 +60,13 @@ void obsffmpeg::ui::prores_aw_handler::override_colorformat(AVPixelFormat& targe
}
}
void obsffmpeg::ui::prores_aw_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
void obsffmpeg::ui::prores_aw_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*, bool)
{
obs_data_set_default_int(settings, P_PRORES_PROFILE, 0);
}
void obsffmpeg::ui::prores_aw_handler::get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
AVCodecContext* context, bool)
{
if (!context) {
auto p = obs_properties_add_list(props, P_PRORES_PROFILE, TRANSLATE(P_PRORES_PROFILE),
@@ -105,7 +105,7 @@ void obsffmpeg::ui::prores_aw_handler::update(obs_data_t* settings, const AVCode
context->profile = static_cast<int>(obs_data_get_int(settings, P_PRORES_PROFILE));
}
void obsffmpeg::ui::prores_aw_handler::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::prores_aw_handler::log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext*)
{
for (auto ptr = codec->profiles; ptr->profile != FF_PROFILE_UNKNOWN; ptr++) {
if (ptr->profile == static_cast<int>(obs_data_get_int(settings, P_PRORES_PROFILE)))
@@ -113,7 +113,7 @@ void obsffmpeg::ui::prores_aw_handler::log_options(obs_data_t* settings, const A
}
}
void obsffmpeg::ui::prores_aw_handler::process_avpacket(AVPacket& packet, const AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::prores_aw_handler::process_avpacket(AVPacket& packet, const AVCodec*, AVCodecContext*)
{
//FFmpeg Bug:
// When ProRes content is stored in Matroska, FFmpeg strips the size
+2 -2
View File
@@ -38,10 +38,10 @@ namespace obsffmpeg {
const AVCodec* codec, AVCodecContext* context) override;
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
AVCodecContext* context, bool hw_encode) override;
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
AVCodecContext* context, bool hw_encode) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;