Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
encoder: Separate get_defaults and get_properties for SW/HW encoders
Browse files Browse the repository at this point in the history
  • Loading branch information
Xaymar committed Oct 4, 2019
1 parent e4e76da commit 2f8acc5
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 77 deletions.
98 changes: 71 additions & 27 deletions source/encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand All @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions source/encoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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();

Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion source/hwapi/d3d11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions source/ui/debug_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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){};
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions source/ui/debug_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
31 changes: 12 additions & 19 deletions source/ui/handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*) {}
4 changes: 2 additions & 2 deletions source/ui/handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions source/ui/nvenc_h264_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions source/ui/nvenc_h264_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions source/ui/nvenc_hevc_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions source/ui/nvenc_hevc_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 2f8acc5

Please sign in to comment.