code: Don't use try-catch as function definition
This breaks MSVC and results in leaked exceptions.
This commit is contained in:
parent
678399ce81
commit
0fe5c7e654
|
@ -1278,12 +1278,14 @@ aom_av1_factory::~aom_av1_factory() {}
|
||||||
std::shared_ptr<aom_av1_factory> _aom_av1_factory_instance = nullptr;
|
std::shared_ptr<aom_av1_factory> _aom_av1_factory_instance = nullptr;
|
||||||
|
|
||||||
void aom_av1_factory::initialize()
|
void aom_av1_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_aom_av1_factory_instance) {
|
try {
|
||||||
_aom_av1_factory_instance = std::make_shared<aom_av1_factory>();
|
if (!_aom_av1_factory_instance) {
|
||||||
|
_aom_av1_factory_instance = std::make_shared<aom_av1_factory>();
|
||||||
|
}
|
||||||
|
} catch (std::exception const& ex) {
|
||||||
|
D_LOG_ERROR("Failed to initialize AOM AV1 encoder: %s", ex.what());
|
||||||
}
|
}
|
||||||
} catch (std::exception const& ex) {
|
|
||||||
D_LOG_ERROR("Failed to initialize AOM AV1 encoder: %s", ex.what());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void aom_av1_factory::finalize()
|
void aom_av1_factory::finalize()
|
||||||
|
@ -1349,82 +1351,88 @@ void aom_av1_factory::get_defaults2(obs_data_t* settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_usage(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_usage(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
bool is_all_intra = false;
|
try {
|
||||||
if (obs_data_get_int(settings, ST_KEY_ENCODER_USAGE) == AOM_USAGE_ALL_INTRA) {
|
bool is_all_intra = false;
|
||||||
is_all_intra = true;
|
if (obs_data_get_int(settings, ST_KEY_ENCODER_USAGE) == AOM_USAGE_ALL_INTRA) {
|
||||||
|
is_all_intra = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All-Intra does not support these.
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LOOKAHEAD), !is_all_intra);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_I18N_KEYFRAMES), !is_all_intra);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
|
return false;
|
||||||
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All-Intra does not support these.
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LOOKAHEAD), !is_all_intra);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_I18N_KEYFRAMES), !is_all_intra);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
|
||||||
return false;
|
|
||||||
} catch (...) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_ratecontrol_mode(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_ratecontrol_mode(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
bool is_bitrate_visible = false;
|
try {
|
||||||
bool is_overundershoot_visible = false;
|
bool is_bitrate_visible = false;
|
||||||
bool is_quality_visible = false;
|
bool is_overundershoot_visible = false;
|
||||||
|
bool is_quality_visible = false;
|
||||||
|
|
||||||
// Fix rate control mode selection if ALL_INTRA is selected.
|
// Fix rate control mode selection if ALL_INTRA is selected.
|
||||||
if (obs_data_get_int(settings, ST_KEY_ENCODER_USAGE) == AOM_USAGE_ALL_INTRA) {
|
if (obs_data_get_int(settings, ST_KEY_ENCODER_USAGE) == AOM_USAGE_ALL_INTRA) {
|
||||||
obs_data_set_int(settings, ST_KEY_RATECONTROL_MODE, static_cast<long long>(aom_rc_mode::AOM_Q));
|
obs_data_set_int(settings, ST_KEY_RATECONTROL_MODE, static_cast<long long>(aom_rc_mode::AOM_Q));
|
||||||
}
|
|
||||||
|
|
||||||
{ // Based on the Rate Control Mode, show and hide options.
|
|
||||||
auto mode = static_cast<aom_rc_mode>(obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE));
|
|
||||||
if (mode == AOM_CBR) {
|
|
||||||
is_bitrate_visible = true;
|
|
||||||
is_overundershoot_visible = true;
|
|
||||||
} else if (mode == AOM_VBR) {
|
|
||||||
is_bitrate_visible = true;
|
|
||||||
is_overundershoot_visible = true;
|
|
||||||
} else if (mode == AOM_CQ) {
|
|
||||||
is_bitrate_visible = true;
|
|
||||||
is_overundershoot_visible = true;
|
|
||||||
is_quality_visible = true;
|
|
||||||
} else if (mode == AOM_Q) {
|
|
||||||
is_quality_visible = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_BITRATE), is_bitrate_visible);
|
{ // Based on the Rate Control Mode, show and hide options.
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_BITRATE_UNDERSHOOT),
|
auto mode = static_cast<aom_rc_mode>(obs_data_get_int(settings, ST_KEY_RATECONTROL_MODE));
|
||||||
is_overundershoot_visible);
|
if (mode == AOM_CBR) {
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_BITRATE_OVERSHOOT),
|
is_bitrate_visible = true;
|
||||||
is_overundershoot_visible);
|
is_overundershoot_visible = true;
|
||||||
|
} else if (mode == AOM_VBR) {
|
||||||
|
is_bitrate_visible = true;
|
||||||
|
is_overundershoot_visible = true;
|
||||||
|
} else if (mode == AOM_CQ) {
|
||||||
|
is_bitrate_visible = true;
|
||||||
|
is_overundershoot_visible = true;
|
||||||
|
is_quality_visible = true;
|
||||||
|
} else if (mode == AOM_Q) {
|
||||||
|
is_quality_visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_BITRATE), is_bitrate_visible);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_BITRATE_UNDERSHOOT),
|
||||||
|
is_overundershoot_visible);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_BITRATE_OVERSHOOT),
|
||||||
|
is_overundershoot_visible);
|
||||||
#ifdef AOM_CTRL_AOME_SET_CQ_LEVEL
|
#ifdef AOM_CTRL_AOME_SET_CQ_LEVEL
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_QUALITY), is_quality_visible);
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_RATECONTROL_LIMITS_QUALITY), is_quality_visible);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
|
return false;
|
||||||
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
|
||||||
return false;
|
|
||||||
} catch (...) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
bool is_seconds = obs_data_get_int(settings, ST_KEY_KEYFRAMES_INTERVALTYPE) == 0;
|
try {
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_FRAMES), !is_seconds);
|
bool is_seconds = obs_data_get_int(settings, ST_KEY_KEYFRAMES_INTERVALTYPE) == 0;
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_SECONDS), is_seconds);
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_FRAMES), !is_seconds);
|
||||||
return true;
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_SECONDS), is_seconds);
|
||||||
} catch (const std::exception& ex) {
|
return true;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* aom_av1_factory::get_properties2(instance_t* data)
|
obs_properties_t* aom_av1_factory::get_properties2(instance_t* data)
|
||||||
|
|
|
@ -129,7 +129,7 @@ ffmpeg_instance::ffmpeg_instance(obs_data_t* settings, obs_encoder_t* self, bool
|
||||||
throw std::runtime_error("Failed to create encoder context.");
|
throw std::runtime_error("Failed to create encoder context.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create 8MB of precached Packet data for use later on.
|
// Allocate a small packet for later use.
|
||||||
av_init_packet(&_packet);
|
av_init_packet(&_packet);
|
||||||
av_new_packet(&_packet, 8 * 1024 * 1024); // 8 MB precached Packet size.
|
av_new_packet(&_packet, 8 * 1024 * 1024); // 8 MB precached Packet size.
|
||||||
|
|
||||||
|
@ -1051,17 +1051,19 @@ void ffmpeg_factory::migrate(obs_data_t* data, uint64_t version)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
bool is_seconds = obs_data_get_int(settings, ST_KEY_KEYFRAMES_INTERVALTYPE) == 0;
|
try {
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_FRAMES), !is_seconds);
|
bool is_seconds = obs_data_get_int(settings, ST_KEY_KEYFRAMES_INTERVALTYPE) == 0;
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_SECONDS), is_seconds);
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_FRAMES), !is_seconds);
|
||||||
return true;
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_SECONDS), is_seconds);
|
||||||
} catch (const std::exception& ex) {
|
return true;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
|
obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
|
||||||
|
|
|
@ -1125,14 +1125,16 @@ void autoframing_factory::get_defaults2(obs_data_t* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
return true;
|
try {
|
||||||
} catch (const std::exception& ex) {
|
return true;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* autoframing_factory::get_properties2(autoframing_instance* data)
|
obs_properties_t* autoframing_factory::get_properties2(autoframing_instance* data)
|
||||||
|
@ -1315,13 +1317,15 @@ tracking_provider streamfx::filter::autoframing::autoframing_factory::find_ideal
|
||||||
std::shared_ptr<autoframing_factory> _filter_autoframing_factory_instance = nullptr;
|
std::shared_ptr<autoframing_factory> _filter_autoframing_factory_instance = nullptr;
|
||||||
|
|
||||||
void autoframing_factory::initialize()
|
void autoframing_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_filter_autoframing_factory_instance)
|
try {
|
||||||
_filter_autoframing_factory_instance = std::make_shared<autoframing_factory>();
|
if (!_filter_autoframing_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_filter_autoframing_factory_instance = std::make_shared<autoframing_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void autoframing_factory::finalize()
|
void autoframing_factory::finalize()
|
||||||
|
|
|
@ -649,133 +649,135 @@ void blur_factory::get_defaults2(obs_data_t* settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool modified_properties(void*, obs_properties_t* props, obs_property* prop, obs_data_t* settings) noexcept
|
bool modified_properties(void*, obs_properties_t* props, obs_property* prop, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
obs_property_t* p;
|
try {
|
||||||
const char* propname = obs_property_name(prop);
|
obs_property_t* p;
|
||||||
const char* vtype = obs_data_get_string(settings, ST_KEY_TYPE);
|
const char* propname = obs_property_name(prop);
|
||||||
const char* vsubtype = obs_data_get_string(settings, ST_KEY_SUBTYPE);
|
const char* vtype = obs_data_get_string(settings, ST_KEY_TYPE);
|
||||||
|
const char* vsubtype = obs_data_get_string(settings, ST_KEY_SUBTYPE);
|
||||||
|
|
||||||
// Find new Type
|
// Find new Type
|
||||||
auto type_found = list_of_types.find(vtype);
|
auto type_found = list_of_types.find(vtype);
|
||||||
if (type_found == list_of_types.end()) {
|
if (type_found == list_of_types.end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Find new Subtype
|
|
||||||
auto subtype_found = list_of_subtypes.find(vsubtype);
|
|
||||||
if (subtype_found == list_of_subtypes.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blur Type
|
|
||||||
if (strcmp(propname, ST_KEY_TYPE) == 0) {
|
|
||||||
obs_property_t* prop_subtype = obs_properties_get(props, ST_KEY_SUBTYPE);
|
|
||||||
|
|
||||||
/// Disable unsupported items.
|
|
||||||
std::size_t subvalue_idx = 0;
|
|
||||||
for (std::size_t idx = 0, edx = obs_property_list_item_count(prop_subtype); idx < edx; idx++) {
|
|
||||||
const char* subtype = obs_property_list_item_string(prop_subtype, idx);
|
|
||||||
bool disabled = false;
|
|
||||||
|
|
||||||
auto subtype_found_idx = list_of_subtypes.find(subtype);
|
|
||||||
if (subtype_found_idx != list_of_subtypes.end()) {
|
|
||||||
disabled = !type_found->second.fn().is_type_supported(subtype_found_idx->second.type);
|
|
||||||
} else {
|
|
||||||
disabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
obs_property_list_item_disable(prop_subtype, idx, disabled);
|
|
||||||
if (strcmp(subtype, vsubtype) == 0) {
|
|
||||||
subvalue_idx = idx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure that there is a valid item selected.
|
// Find new Subtype
|
||||||
if (obs_property_list_item_disabled(prop_subtype, subvalue_idx)) {
|
auto subtype_found = list_of_subtypes.find(vsubtype);
|
||||||
|
if (subtype_found == list_of_subtypes.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blur Type
|
||||||
|
if (strcmp(propname, ST_KEY_TYPE) == 0) {
|
||||||
|
obs_property_t* prop_subtype = obs_properties_get(props, ST_KEY_SUBTYPE);
|
||||||
|
|
||||||
|
/// Disable unsupported items.
|
||||||
|
std::size_t subvalue_idx = 0;
|
||||||
for (std::size_t idx = 0, edx = obs_property_list_item_count(prop_subtype); idx < edx; idx++) {
|
for (std::size_t idx = 0, edx = obs_property_list_item_count(prop_subtype); idx < edx; idx++) {
|
||||||
if (!obs_property_list_item_disabled(prop_subtype, idx)) {
|
const char* subtype = obs_property_list_item_string(prop_subtype, idx);
|
||||||
obs_data_set_string(settings, ST_KEY_SUBTYPE, obs_property_list_item_string(prop_subtype, idx));
|
bool disabled = false;
|
||||||
|
|
||||||
// Find new Subtype
|
auto subtype_found_idx = list_of_subtypes.find(subtype);
|
||||||
auto subtype_found2 = list_of_subtypes.find(vsubtype);
|
if (subtype_found_idx != list_of_subtypes.end()) {
|
||||||
if (subtype_found2 == list_of_subtypes.end()) {
|
disabled = !type_found->second.fn().is_type_supported(subtype_found_idx->second.type);
|
||||||
subtype_found = list_of_subtypes.end();
|
} else {
|
||||||
} else {
|
disabled = true;
|
||||||
subtype_found = subtype_found2;
|
}
|
||||||
|
|
||||||
|
obs_property_list_item_disable(prop_subtype, idx, disabled);
|
||||||
|
if (strcmp(subtype, vsubtype) == 0) {
|
||||||
|
subvalue_idx = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensure that there is a valid item selected.
|
||||||
|
if (obs_property_list_item_disabled(prop_subtype, subvalue_idx)) {
|
||||||
|
for (std::size_t idx = 0, edx = obs_property_list_item_count(prop_subtype); idx < edx; idx++) {
|
||||||
|
if (!obs_property_list_item_disabled(prop_subtype, idx)) {
|
||||||
|
obs_data_set_string(settings, ST_KEY_SUBTYPE, obs_property_list_item_string(prop_subtype, idx));
|
||||||
|
|
||||||
|
// Find new Subtype
|
||||||
|
auto subtype_found2 = list_of_subtypes.find(vsubtype);
|
||||||
|
if (subtype_found2 == list_of_subtypes.end()) {
|
||||||
|
subtype_found = list_of_subtypes.end();
|
||||||
|
} else {
|
||||||
|
subtype_found = subtype_found2;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Blur Sub-Type
|
||||||
|
{
|
||||||
|
bool has_angle_support = (subtype_found->second.type == ::streamfx::gfx::blur::type::Directional)
|
||||||
|
|| (subtype_found->second.type == ::streamfx::gfx::blur::type::Rotational);
|
||||||
|
bool has_center_support = (subtype_found->second.type == ::streamfx::gfx::blur::type::Rotational)
|
||||||
|
|| (subtype_found->second.type == ::streamfx::gfx::blur::type::Zoom);
|
||||||
|
bool has_stepscale_support = type_found->second.fn().is_step_scale_supported(subtype_found->second.type);
|
||||||
|
bool show_scaling = obs_data_get_bool(settings, ST_KEY_STEPSCALE) && has_stepscale_support;
|
||||||
|
|
||||||
|
/// Size
|
||||||
|
p = obs_properties_get(props, ST_KEY_SIZE);
|
||||||
|
obs_property_float_set_limits(p, type_found->second.fn().get_min_size(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_max_size(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_step_size(subtype_found->second.type));
|
||||||
|
|
||||||
|
/// Angle
|
||||||
|
p = obs_properties_get(props, ST_KEY_ANGLE);
|
||||||
|
obs_property_set_visible(p, has_angle_support);
|
||||||
|
obs_property_float_set_limits(p, type_found->second.fn().get_min_angle(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_max_angle(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_step_angle(subtype_found->second.type));
|
||||||
|
|
||||||
|
/// Center, Radius
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_CENTER_X), has_center_support);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_CENTER_Y), has_center_support);
|
||||||
|
|
||||||
|
/// Step Scaling
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_STEPSCALE), has_stepscale_support);
|
||||||
|
p = obs_properties_get(props, ST_KEY_STEPSCALE_X);
|
||||||
|
obs_property_set_visible(p, show_scaling);
|
||||||
|
obs_property_float_set_limits(p, type_found->second.fn().get_min_step_scale_x(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_max_step_scale_x(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_step_step_scale_x(subtype_found->second.type));
|
||||||
|
p = obs_properties_get(props, ST_KEY_STEPSCALE_Y);
|
||||||
|
obs_property_set_visible(p, show_scaling);
|
||||||
|
obs_property_float_set_limits(p, type_found->second.fn().get_min_step_scale_x(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_max_step_scale_x(subtype_found->second.type),
|
||||||
|
type_found->second.fn().get_step_step_scale_x(subtype_found->second.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Masking
|
||||||
|
using namespace ::streamfx::gfx::blur;
|
||||||
|
bool show_mask = obs_data_get_bool(settings, ST_KEY_MASK);
|
||||||
|
mask_type mtype = static_cast<mask_type>(obs_data_get_int(settings, ST_KEY_MASK_TYPE));
|
||||||
|
bool show_region = (mtype == mask_type::Region) && show_mask;
|
||||||
|
bool show_image = (mtype == mask_type::Image) && show_mask;
|
||||||
|
bool show_source = (mtype == mask_type::Source) && show_mask;
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_TYPE), show_mask);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_LEFT), show_region);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_TOP), show_region);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_RIGHT), show_region);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_BOTTOM), show_region);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_FEATHER), show_region);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_FEATHER_SHIFT), show_region);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_INVERT), show_region);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_IMAGE), show_image);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_SOURCE), show_source);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_COLOR), show_image || show_source);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_ALPHA), show_image || show_source);
|
||||||
|
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_MULTIPLIER), show_image || show_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in modified_properties callback.");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blur Sub-Type
|
|
||||||
{
|
|
||||||
bool has_angle_support = (subtype_found->second.type == ::streamfx::gfx::blur::type::Directional)
|
|
||||||
|| (subtype_found->second.type == ::streamfx::gfx::blur::type::Rotational);
|
|
||||||
bool has_center_support = (subtype_found->second.type == ::streamfx::gfx::blur::type::Rotational)
|
|
||||||
|| (subtype_found->second.type == ::streamfx::gfx::blur::type::Zoom);
|
|
||||||
bool has_stepscale_support = type_found->second.fn().is_step_scale_supported(subtype_found->second.type);
|
|
||||||
bool show_scaling = obs_data_get_bool(settings, ST_KEY_STEPSCALE) && has_stepscale_support;
|
|
||||||
|
|
||||||
/// Size
|
|
||||||
p = obs_properties_get(props, ST_KEY_SIZE);
|
|
||||||
obs_property_float_set_limits(p, type_found->second.fn().get_min_size(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_max_size(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_step_size(subtype_found->second.type));
|
|
||||||
|
|
||||||
/// Angle
|
|
||||||
p = obs_properties_get(props, ST_KEY_ANGLE);
|
|
||||||
obs_property_set_visible(p, has_angle_support);
|
|
||||||
obs_property_float_set_limits(p, type_found->second.fn().get_min_angle(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_max_angle(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_step_angle(subtype_found->second.type));
|
|
||||||
|
|
||||||
/// Center, Radius
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_CENTER_X), has_center_support);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_CENTER_Y), has_center_support);
|
|
||||||
|
|
||||||
/// Step Scaling
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_STEPSCALE), has_stepscale_support);
|
|
||||||
p = obs_properties_get(props, ST_KEY_STEPSCALE_X);
|
|
||||||
obs_property_set_visible(p, show_scaling);
|
|
||||||
obs_property_float_set_limits(p, type_found->second.fn().get_min_step_scale_x(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_max_step_scale_x(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_step_step_scale_x(subtype_found->second.type));
|
|
||||||
p = obs_properties_get(props, ST_KEY_STEPSCALE_Y);
|
|
||||||
obs_property_set_visible(p, show_scaling);
|
|
||||||
obs_property_float_set_limits(p, type_found->second.fn().get_min_step_scale_x(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_max_step_scale_x(subtype_found->second.type),
|
|
||||||
type_found->second.fn().get_step_step_scale_x(subtype_found->second.type));
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // Masking
|
|
||||||
using namespace ::streamfx::gfx::blur;
|
|
||||||
bool show_mask = obs_data_get_bool(settings, ST_KEY_MASK);
|
|
||||||
mask_type mtype = static_cast<mask_type>(obs_data_get_int(settings, ST_KEY_MASK_TYPE));
|
|
||||||
bool show_region = (mtype == mask_type::Region) && show_mask;
|
|
||||||
bool show_image = (mtype == mask_type::Image) && show_mask;
|
|
||||||
bool show_source = (mtype == mask_type::Source) && show_mask;
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_TYPE), show_mask);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_LEFT), show_region);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_TOP), show_region);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_RIGHT), show_region);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_BOTTOM), show_region);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_FEATHER), show_region);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_FEATHER_SHIFT), show_region);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_REGION_INVERT), show_region);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_IMAGE), show_image);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_SOURCE), show_source);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_COLOR), show_image || show_source);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_ALPHA), show_image || show_source);
|
|
||||||
obs_property_set_visible(obs_properties_get(props, ST_KEY_MASK_MULTIPLIER), show_image || show_source);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (...) {
|
|
||||||
DLOG_ERROR("Unexpected exception in modified_properties callback.");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* blur_factory::get_properties2(blur_instance* data)
|
obs_properties_t* blur_factory::get_properties2(blur_instance* data)
|
||||||
|
@ -896,28 +898,32 @@ std::string blur_factory::translate_string(const char* format, ...)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool blur_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool blur_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<blur_factory> _filter_blur_factory_instance = nullptr;
|
std::shared_ptr<blur_factory> _filter_blur_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::filter::blur::blur_factory::initialize()
|
void streamfx::filter::blur::blur_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_filter_blur_factory_instance)
|
try {
|
||||||
_filter_blur_factory_instance = std::make_shared<blur_factory>();
|
if (!_filter_blur_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_filter_blur_factory_instance = std::make_shared<blur_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::filter::blur::blur_factory::finalize()
|
void streamfx::filter::blur::blur_factory::finalize()
|
||||||
|
|
|
@ -882,28 +882,32 @@ obs_properties_t* color_grade_factory::get_properties2(color_grade_instance* dat
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool color_grade_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool color_grade_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<color_grade_factory> _color_grade_factory_instance = nullptr;
|
std::shared_ptr<color_grade_factory> _color_grade_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::filter::color_grade::color_grade_factory::initialize()
|
void streamfx::filter::color_grade::color_grade_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_color_grade_factory_instance)
|
try {
|
||||||
_color_grade_factory_instance = std::make_shared<color_grade_factory>();
|
if (!_color_grade_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_color_grade_factory_instance = std::make_shared<color_grade_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::filter::color_grade::color_grade_factory::finalize()
|
void streamfx::filter::color_grade::color_grade_factory::finalize()
|
||||||
|
|
|
@ -572,14 +572,16 @@ void denoising_factory::get_defaults2(obs_data_t* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
return true;
|
try {
|
||||||
} catch (const std::exception& ex) {
|
return true;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* denoising_factory::get_properties2(denoising_instance* data)
|
obs_properties_t* denoising_factory::get_properties2(denoising_instance* data)
|
||||||
|
@ -649,13 +651,15 @@ denoising_provider streamfx::filter::denoising::denoising_factory::find_ideal_pr
|
||||||
std::shared_ptr<denoising_factory> _video_denoising_factory_instance = nullptr;
|
std::shared_ptr<denoising_factory> _video_denoising_factory_instance = nullptr;
|
||||||
|
|
||||||
void denoising_factory::initialize()
|
void denoising_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_video_denoising_factory_instance)
|
try {
|
||||||
_video_denoising_factory_instance = std::make_shared<denoising_factory>();
|
if (!_video_denoising_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_video_denoising_factory_instance = std::make_shared<denoising_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void denoising_factory::finalize()
|
void denoising_factory::finalize()
|
||||||
|
|
|
@ -203,13 +203,15 @@ obs_properties_t* displacement_factory::get_properties2(displacement_instance* d
|
||||||
std::shared_ptr<displacement_factory> _filter_displacement_factory_instance = nullptr;
|
std::shared_ptr<displacement_factory> _filter_displacement_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::filter::displacement::displacement_factory::initialize()
|
void streamfx::filter::displacement::displacement_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_filter_displacement_factory_instance)
|
try {
|
||||||
_filter_displacement_factory_instance = std::make_shared<displacement_factory>();
|
if (!_filter_displacement_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_filter_displacement_factory_instance = std::make_shared<displacement_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::filter::displacement::displacement_factory::finalize()
|
void streamfx::filter::displacement::displacement_factory::finalize()
|
||||||
|
|
|
@ -403,33 +403,35 @@ void streamfx::filter::dynamic_mask::dynamic_mask_instance::deactivate()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dynamic_mask_instance::acquire(std::string_view name)
|
bool dynamic_mask_instance::acquire(std::string_view name)
|
||||||
try {
|
{
|
||||||
// Prevent us from creating a circle.
|
try {
|
||||||
if (auto v = obs_source_get_name(obs_filter_get_parent(_self)); (v != nullptr) && (name == v)) {
|
// Prevent us from creating a circle.
|
||||||
|
if (auto v = obs_source_get_name(obs_filter_get_parent(_self)); (v != nullptr) && (name == v)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire a reference to the actual source.
|
||||||
|
::streamfx::obs::source input = name;
|
||||||
|
|
||||||
|
// Acquire a texture renderer for the source, with the parent source as the parent.
|
||||||
|
auto capture = std::make_shared<streamfx::gfx::source_texture>(input, obs_filter_get_parent(_self));
|
||||||
|
|
||||||
|
// Update our local storage.
|
||||||
|
_input = input;
|
||||||
|
_input_capture = capture;
|
||||||
|
|
||||||
|
// Do the necessary things.
|
||||||
|
activate();
|
||||||
|
show();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
release();
|
||||||
|
return false;
|
||||||
|
} catch (...) {
|
||||||
|
release();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acquire a reference to the actual source.
|
|
||||||
::streamfx::obs::source input = name;
|
|
||||||
|
|
||||||
// Acquire a texture renderer for the source, with the parent source as the parent.
|
|
||||||
auto capture = std::make_shared<streamfx::gfx::source_texture>(input, obs_filter_get_parent(_self));
|
|
||||||
|
|
||||||
// Update our local storage.
|
|
||||||
_input = input;
|
|
||||||
_input_capture = capture;
|
|
||||||
|
|
||||||
// Do the necessary things.
|
|
||||||
activate();
|
|
||||||
show();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception&) {
|
|
||||||
release();
|
|
||||||
return false;
|
|
||||||
} catch (...) {
|
|
||||||
release();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dynamic_mask_instance::release()
|
void dynamic_mask_instance::release()
|
||||||
|
@ -565,28 +567,32 @@ std::string dynamic_mask_factory::translate_string(const char* format, ...)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool dynamic_mask_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool dynamic_mask_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<dynamic_mask_factory> _filter_dynamic_mask_factory_instance = nullptr;
|
std::shared_ptr<dynamic_mask_factory> _filter_dynamic_mask_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize()
|
void streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_filter_dynamic_mask_factory_instance)
|
try {
|
||||||
_filter_dynamic_mask_factory_instance = std::make_shared<dynamic_mask_factory>();
|
if (!_filter_dynamic_mask_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_filter_dynamic_mask_factory_instance = std::make_shared<dynamic_mask_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::filter::dynamic_mask::dynamic_mask_factory::finalize()
|
void streamfx::filter::dynamic_mask::dynamic_mask_factory::finalize()
|
||||||
|
|
|
@ -724,28 +724,32 @@ obs_properties_t* sdf_effects_factory::get_properties2(sdf_effects_instance* dat
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool sdf_effects_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool sdf_effects_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<sdf_effects_factory> _filter_sdf_effects_factory_instance = nullptr;
|
std::shared_ptr<sdf_effects_factory> _filter_sdf_effects_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::filter::sdf_effects::sdf_effects_factory::initialize()
|
void streamfx::filter::sdf_effects::sdf_effects_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_filter_sdf_effects_factory_instance)
|
try {
|
||||||
_filter_sdf_effects_factory_instance = std::make_shared<sdf_effects_factory>();
|
if (!_filter_sdf_effects_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_filter_sdf_effects_factory_instance = std::make_shared<sdf_effects_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::filter::sdf_effects::sdf_effects_factory::finalize()
|
void streamfx::filter::sdf_effects::sdf_effects_factory::finalize()
|
||||||
|
|
|
@ -218,28 +218,32 @@ obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<shader_factory> _filter_shader_factory_instance = nullptr;
|
std::shared_ptr<shader_factory> _filter_shader_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::filter::shader::shader_factory::initialize()
|
void streamfx::filter::shader::shader_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_filter_shader_factory_instance)
|
try {
|
||||||
_filter_shader_factory_instance = std::make_shared<shader_factory>();
|
if (!_filter_shader_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_filter_shader_factory_instance = std::make_shared<shader_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::filter::shader::shader_factory::finalize()
|
void streamfx::filter::shader::shader_factory::finalize()
|
||||||
|
|
|
@ -636,28 +636,30 @@ void transform_factory::get_defaults2(obs_data_t* settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_camera_mode(obs_properties_t* pr, obs_property_t*, obs_data_t* d) noexcept
|
static bool modified_camera_mode(obs_properties_t* pr, obs_property_t*, obs_data_t* d) noexcept
|
||||||
try {
|
{
|
||||||
auto mode = static_cast<transform_mode>(obs_data_get_int(d, ST_KEY_CAMERA_MODE));
|
try {
|
||||||
bool is_camera = mode != transform_mode::CORNER_PIN;
|
auto mode = static_cast<transform_mode>(obs_data_get_int(d, ST_KEY_CAMERA_MODE));
|
||||||
bool is_perspective = (mode == transform_mode::PERSPECTIVE) && is_camera;
|
bool is_camera = mode != transform_mode::CORNER_PIN;
|
||||||
bool is_orthographic = (mode == transform_mode::ORTHOGRAPHIC) && is_camera;
|
bool is_perspective = (mode == transform_mode::PERSPECTIVE) && is_camera;
|
||||||
|
bool is_orthographic = (mode == transform_mode::ORTHOGRAPHIC) && is_camera;
|
||||||
|
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_KEY_CAMERA_FIELDOFVIEW), is_perspective);
|
obs_property_set_visible(obs_properties_get(pr, ST_KEY_CAMERA_FIELDOFVIEW), is_perspective);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_I18N_POSITION), is_camera);
|
obs_property_set_visible(obs_properties_get(pr, ST_I18N_POSITION), is_camera);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_KEY_POSITION_Z), is_perspective);
|
obs_property_set_visible(obs_properties_get(pr, ST_KEY_POSITION_Z), is_perspective);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_I18N_ROTATION), is_camera);
|
obs_property_set_visible(obs_properties_get(pr, ST_I18N_ROTATION), is_camera);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_I18N_SCALE), is_camera);
|
obs_property_set_visible(obs_properties_get(pr, ST_I18N_SCALE), is_camera);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_I18N_SHEAR), is_camera);
|
obs_property_set_visible(obs_properties_get(pr, ST_I18N_SHEAR), is_camera);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_KEY_ROTATION_ORDER), is_camera);
|
obs_property_set_visible(obs_properties_get(pr, ST_KEY_ROTATION_ORDER), is_camera);
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_I18N_CORNERS), !is_camera);
|
obs_property_set_visible(obs_properties_get(pr, ST_I18N_CORNERS), !is_camera);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* transform_factory::get_properties2(transform_instance* data)
|
obs_properties_t* transform_factory::get_properties2(transform_instance* data)
|
||||||
|
@ -856,28 +858,32 @@ obs_properties_t* transform_factory::get_properties2(transform_instance* data)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool transform_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool transform_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<transform_factory> _filter_transform_factory_instance = nullptr;
|
std::shared_ptr<transform_factory> _filter_transform_factory_instance = nullptr;
|
||||||
|
|
||||||
void transform_factory::initialize()
|
void transform_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_filter_transform_factory_instance)
|
try {
|
||||||
_filter_transform_factory_instance = std::make_shared<transform_factory>();
|
if (!_filter_transform_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_filter_transform_factory_instance = std::make_shared<transform_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void transform_factory::finalize()
|
void transform_factory::finalize()
|
||||||
|
|
|
@ -573,14 +573,16 @@ void upscaling_factory::get_defaults2(obs_data_t* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
return true;
|
try {
|
||||||
} catch (const std::exception& ex) {
|
return true;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* upscaling_factory::get_properties2(upscaling_instance* data)
|
obs_properties_t* upscaling_factory::get_properties2(upscaling_instance* data)
|
||||||
|
@ -618,15 +620,17 @@ obs_properties_t* upscaling_factory::get_properties2(upscaling_instance* data)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool upscaling_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool upscaling_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -656,13 +660,15 @@ upscaling_provider streamfx::filter::upscaling::upscaling_factory::find_ideal_pr
|
||||||
std::shared_ptr<upscaling_factory> _video_superresolution_factory_instance = nullptr;
|
std::shared_ptr<upscaling_factory> _video_superresolution_factory_instance = nullptr;
|
||||||
|
|
||||||
void upscaling_factory::initialize()
|
void upscaling_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_video_superresolution_factory_instance)
|
try {
|
||||||
_video_superresolution_factory_instance = std::make_shared<upscaling_factory>();
|
if (!_video_superresolution_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_video_superresolution_factory_instance = std::make_shared<upscaling_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void upscaling_factory::finalize()
|
void upscaling_factory::finalize()
|
||||||
|
|
|
@ -574,14 +574,16 @@ void virtual_greenscreen_factory::get_defaults2(obs_data_t* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
static bool modified_provider(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
return true;
|
try {
|
||||||
} catch (const std::exception& ex) {
|
return true;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* virtual_greenscreen_factory::get_properties2(virtual_greenscreen_instance* data)
|
obs_properties_t* virtual_greenscreen_factory::get_properties2(virtual_greenscreen_instance* data)
|
||||||
|
@ -619,15 +621,17 @@ obs_properties_t* virtual_greenscreen_factory::get_properties2(virtual_greenscre
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool virtual_greenscreen_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool virtual_greenscreen_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -658,13 +662,15 @@ virtual_greenscreen_provider streamfx::filter::virtual_greenscreen::virtual_gree
|
||||||
std::shared_ptr<virtual_greenscreen_factory> _video_superresolution_factory_instance = nullptr;
|
std::shared_ptr<virtual_greenscreen_factory> _video_superresolution_factory_instance = nullptr;
|
||||||
|
|
||||||
void virtual_greenscreen_factory::initialize()
|
void virtual_greenscreen_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_video_superresolution_factory_instance)
|
try {
|
||||||
_video_superresolution_factory_instance = std::make_shared<virtual_greenscreen_factory>();
|
if (!_video_superresolution_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_video_superresolution_factory_instance = std::make_shared<virtual_greenscreen_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtual_greenscreen_factory::finalize()
|
void virtual_greenscreen_factory::finalize()
|
||||||
|
|
|
@ -65,27 +65,29 @@ streamfx::gfx::shader::shader::shader(obs_source_t* self, shader_mode mode)
|
||||||
streamfx::gfx::shader::shader::~shader() = default;
|
streamfx::gfx::shader::shader::~shader() = default;
|
||||||
|
|
||||||
bool streamfx::gfx::shader::shader::is_shader_different(const std::filesystem::path& file)
|
bool streamfx::gfx::shader::shader::is_shader_different(const std::filesystem::path& file)
|
||||||
try {
|
{
|
||||||
if (std::filesystem::exists(file)) {
|
try {
|
||||||
// Check if the file name differs.
|
if (std::filesystem::exists(file)) {
|
||||||
if (file != _shader_file)
|
// Check if the file name differs.
|
||||||
return true;
|
if (file != _shader_file)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::filesystem::exists(_shader_file)) {
|
||||||
|
// Is the file write time different?
|
||||||
|
if (std::filesystem::last_write_time(_shader_file) != _shader_file_mt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Is the file size different?
|
||||||
|
if (std::filesystem::file_size(_shader_file) != _shader_file_sz)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
DLOG_ERROR("Loading shader '%s' failed with error: %s", file.c_str(), ex.what());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::filesystem::exists(_shader_file)) {
|
|
||||||
// Is the file write time different?
|
|
||||||
if (std::filesystem::last_write_time(_shader_file) != _shader_file_mt)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Is the file size different?
|
|
||||||
if (std::filesystem::file_size(_shader_file) != _shader_file_sz)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
DLOG_ERROR("Loading shader '%s' failed with error: %s", file.c_str(), ex.what());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool streamfx::gfx::shader::shader::is_technique_different(std::string_view tech)
|
bool streamfx::gfx::shader::shader::is_technique_different(std::string_view tech)
|
||||||
|
@ -99,83 +101,85 @@ bool streamfx::gfx::shader::shader::is_technique_different(std::string_view tech
|
||||||
|
|
||||||
bool streamfx::gfx::shader::shader::load_shader(const std::filesystem::path& file, std::string_view tech,
|
bool streamfx::gfx::shader::shader::load_shader(const std::filesystem::path& file, std::string_view tech,
|
||||||
bool& shader_dirty, bool& param_dirty)
|
bool& shader_dirty, bool& param_dirty)
|
||||||
try {
|
{
|
||||||
if (!std::filesystem::exists(file))
|
try {
|
||||||
return false;
|
if (!std::filesystem::exists(file))
|
||||||
|
return false;
|
||||||
|
|
||||||
shader_dirty = is_shader_different(file);
|
shader_dirty = is_shader_different(file);
|
||||||
param_dirty = is_technique_different(tech) || shader_dirty;
|
param_dirty = is_technique_different(tech) || shader_dirty;
|
||||||
|
|
||||||
// Update Shader
|
// Update Shader
|
||||||
if (shader_dirty) {
|
if (shader_dirty) {
|
||||||
_shader = streamfx::obs::gs::effect(file);
|
_shader = streamfx::obs::gs::effect(file);
|
||||||
_shader_file_mt = std::filesystem::last_write_time(file);
|
_shader_file_mt = std::filesystem::last_write_time(file);
|
||||||
_shader_file_sz = std::filesystem::file_size(file);
|
_shader_file_sz = std::filesystem::file_size(file);
|
||||||
_shader_file = file;
|
_shader_file = file;
|
||||||
_shader_file_tick = 0;
|
_shader_file_tick = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Params
|
// Update Params
|
||||||
if (param_dirty) {
|
if (param_dirty) {
|
||||||
auto settings =
|
auto settings =
|
||||||
std::shared_ptr<obs_data_t>(obs_source_get_settings(_self), [](obs_data_t* p) { obs_data_release(p); });
|
std::shared_ptr<obs_data_t>(obs_source_get_settings(_self), [](obs_data_t* p) { obs_data_release(p); });
|
||||||
|
|
||||||
bool have_valid_tech = false;
|
bool have_valid_tech = false;
|
||||||
for (std::size_t idx = 0; idx < _shader.count_techniques(); idx++) {
|
for (std::size_t idx = 0; idx < _shader.count_techniques(); idx++) {
|
||||||
if (_shader.get_technique(idx).name() == tech) {
|
if (_shader.get_technique(idx).name() == tech) {
|
||||||
have_valid_tech = true;
|
have_valid_tech = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (have_valid_tech) {
|
||||||
|
_shader_tech = tech;
|
||||||
|
} else {
|
||||||
|
_shader_tech = _shader.get_technique(0).name();
|
||||||
|
|
||||||
|
// Update source data.
|
||||||
|
obs_data_set_string(settings.get(), ST_KEY_SHADER_TECHNIQUE, _shader_tech.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the shader parameters map and rebuild.
|
||||||
|
_shader_params.clear();
|
||||||
|
auto etech = _shader.get_technique(_shader_tech);
|
||||||
|
for (std::size_t idx = 0; idx < etech.count_passes(); idx++) {
|
||||||
|
auto pass = etech.get_pass(idx);
|
||||||
|
auto fetch_params = [&](std::size_t count,
|
||||||
|
std::function<streamfx::obs::gs::effect_parameter(std::size_t)> get_func) {
|
||||||
|
for (std::size_t vidx = 0; vidx < count; vidx++) {
|
||||||
|
auto el = get_func(vidx);
|
||||||
|
if (!el)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto el_name = el.get_name();
|
||||||
|
auto fnd = _shader_params.find(el_name);
|
||||||
|
if (fnd != _shader_params.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto param = streamfx::gfx::shader::parameter::make_parameter(this, el, ST_KEY_PARAMETERS);
|
||||||
|
|
||||||
|
if (param) {
|
||||||
|
_shader_params.insert_or_assign(el_name, param);
|
||||||
|
param->defaults(settings.get());
|
||||||
|
param->update(settings.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto gvp = [&](std::size_t idx) { return pass.get_vertex_parameter(idx); };
|
||||||
|
fetch_params(pass.count_vertex_parameters(), gvp);
|
||||||
|
auto gpp = [&](std::size_t idx) { return pass.get_pixel_parameter(idx); };
|
||||||
|
fetch_params(pass.count_pixel_parameters(), gpp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (have_valid_tech) {
|
|
||||||
_shader_tech = tech;
|
|
||||||
} else {
|
|
||||||
_shader_tech = _shader.get_technique(0).name();
|
|
||||||
|
|
||||||
// Update source data.
|
return true;
|
||||||
obs_data_set_string(settings.get(), ST_KEY_SHADER_TECHNIQUE, _shader_tech.c_str());
|
} catch (const std::exception& ex) {
|
||||||
}
|
DLOG_ERROR("Loading shader '%s' failed with error: %s", file.c_str(), ex.what());
|
||||||
|
return false;
|
||||||
// Clear the shader parameters map and rebuild.
|
} catch (...) {
|
||||||
_shader_params.clear();
|
return false;
|
||||||
auto etech = _shader.get_technique(_shader_tech);
|
|
||||||
for (std::size_t idx = 0; idx < etech.count_passes(); idx++) {
|
|
||||||
auto pass = etech.get_pass(idx);
|
|
||||||
auto fetch_params = [&](std::size_t count,
|
|
||||||
std::function<streamfx::obs::gs::effect_parameter(std::size_t)> get_func) {
|
|
||||||
for (std::size_t vidx = 0; vidx < count; vidx++) {
|
|
||||||
auto el = get_func(vidx);
|
|
||||||
if (!el)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto el_name = el.get_name();
|
|
||||||
auto fnd = _shader_params.find(el_name);
|
|
||||||
if (fnd != _shader_params.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto param = streamfx::gfx::shader::parameter::make_parameter(this, el, ST_KEY_PARAMETERS);
|
|
||||||
|
|
||||||
if (param) {
|
|
||||||
_shader_params.insert_or_assign(el_name, param);
|
|
||||||
param->defaults(settings.get());
|
|
||||||
param->update(settings.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto gvp = [&](std::size_t idx) { return pass.get_vertex_parameter(idx); };
|
|
||||||
fetch_params(pass.count_vertex_parameters(), gvp);
|
|
||||||
auto gpp = [&](std::size_t idx) { return pass.get_pixel_parameter(idx); };
|
|
||||||
fetch_params(pass.count_pixel_parameters(), gpp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
DLOG_ERROR("Loading shader '%s' failed with error: %s", file.c_str(), ex.what());
|
|
||||||
return false;
|
|
||||||
} catch (...) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::gfx::shader::shader::defaults(obs_data_t* data)
|
void streamfx::gfx::shader::shader::defaults(obs_data_t* data)
|
||||||
|
|
|
@ -90,7 +90,7 @@ streamfx::nvidia::ar::ar::ar() : _library(), _model_path()
|
||||||
DWORD env_size = GetEnvironmentVariableW(L"NVAR_MODEL_PATH", nullptr, 0);
|
DWORD env_size = GetEnvironmentVariableW(L"NVAR_MODEL_PATH", nullptr, 0);
|
||||||
if (env_size > 0) {
|
if (env_size > 0) {
|
||||||
std::vector<wchar_t> buffer(static_cast<size_t>(env_size) + 1, 0);
|
std::vector<wchar_t> buffer(static_cast<size_t>(env_size) + 1, 0);
|
||||||
env_size = GetEnvironmentVariableW(L"NVAR_MODEL_PATH", buffer.data(), buffer.size());
|
env_size = GetEnvironmentVariableW(L"NVAR_MODEL_PATH", buffer.data(), static_cast<DWORD>(buffer.size()));
|
||||||
_model_path = std::wstring(buffer.data(), buffer.size());
|
_model_path = std::wstring(buffer.data(), buffer.size());
|
||||||
|
|
||||||
// The SDK is location one directory "up" from the model path.
|
// The SDK is location one directory "up" from the model path.
|
||||||
|
|
|
@ -58,7 +58,7 @@ static float find_closest_scale_factor(float factor)
|
||||||
|
|
||||||
static size_t find_closest_scale_factor_index(float factor)
|
static size_t find_closest_scale_factor_index(float factor)
|
||||||
{
|
{
|
||||||
std::pair<size_t, float> minimal = {0.f, std::numeric_limits<float>::max()};
|
std::pair<size_t, float> minimal = {0, std::numeric_limits<float>::max()};
|
||||||
for (size_t idx = 0; idx < supported_scale_factors.size(); idx++) {
|
for (size_t idx = 0; idx < supported_scale_factors.size(); idx++) {
|
||||||
float delta = supported_scale_factors[idx];
|
float delta = supported_scale_factors[idx];
|
||||||
float value = abs(delta - factor);
|
float value = abs(delta - factor);
|
||||||
|
|
|
@ -83,34 +83,38 @@ streamfx::obs::gs::effect_parameter& streamfx::obs::gs::effect_parameter::operat
|
||||||
}
|
}
|
||||||
|
|
||||||
streamfx::obs::gs::effect_parameter::effect_parameter(effect_parameter&& rhs) noexcept
|
streamfx::obs::gs::effect_parameter::effect_parameter(effect_parameter&& rhs) noexcept
|
||||||
try {
|
{
|
||||||
reset(rhs.get(), [](gs_eparam_t*) {});
|
try {
|
||||||
_effect_parent = rhs._effect_parent;
|
reset(rhs.get(), [](gs_eparam_t*) {});
|
||||||
_pass_parent = rhs._pass_parent;
|
_effect_parent = rhs._effect_parent;
|
||||||
_param_parent = rhs._param_parent;
|
_pass_parent = rhs._pass_parent;
|
||||||
|
_param_parent = rhs._param_parent;
|
||||||
|
|
||||||
rhs.reset();
|
rhs.reset();
|
||||||
rhs._effect_parent = nullptr;
|
rhs._effect_parent = nullptr;
|
||||||
rhs._pass_parent = nullptr;
|
rhs._pass_parent = nullptr;
|
||||||
rhs._param_parent = nullptr;
|
rhs._param_parent = nullptr;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
streamfx::obs::gs::effect_parameter& streamfx::obs::gs::effect_parameter::operator=(effect_parameter&& rhs) noexcept
|
streamfx::obs::gs::effect_parameter& streamfx::obs::gs::effect_parameter::operator=(effect_parameter&& rhs) noexcept
|
||||||
try {
|
{
|
||||||
reset(rhs.get(), [](gs_eparam_t*) {});
|
try {
|
||||||
_effect_parent = rhs._effect_parent;
|
reset(rhs.get(), [](gs_eparam_t*) {});
|
||||||
_pass_parent = rhs._pass_parent;
|
_effect_parent = rhs._effect_parent;
|
||||||
_param_parent = rhs._param_parent;
|
_pass_parent = rhs._pass_parent;
|
||||||
|
_param_parent = rhs._param_parent;
|
||||||
|
|
||||||
rhs.reset();
|
rhs.reset();
|
||||||
rhs._effect_parent = nullptr;
|
rhs._effect_parent = nullptr;
|
||||||
rhs._pass_parent = nullptr;
|
rhs._pass_parent = nullptr;
|
||||||
rhs._param_parent = nullptr;
|
rhs._param_parent = nullptr;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return *this;
|
return *this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view streamfx::obs::gs::effect_parameter::get_name()
|
std::string_view streamfx::obs::gs::effect_parameter::get_name()
|
||||||
|
|
|
@ -174,207 +174,237 @@ namespace streamfx::obs {
|
||||||
|
|
||||||
private /* Factory */:
|
private /* Factory */:
|
||||||
static const char* _get_name(void* type_data) noexcept
|
static const char* _get_name(void* type_data) noexcept
|
||||||
try {
|
{
|
||||||
if (type_data)
|
try {
|
||||||
return reinterpret_cast<factory_t*>(type_data)->get_name();
|
if (type_data)
|
||||||
return nullptr;
|
return reinterpret_cast<factory_t*>(type_data)->get_name();
|
||||||
} catch (const std::exception& ex) {
|
return nullptr;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return nullptr;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return nullptr;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return nullptr;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* _create(obs_data_t* settings, obs_encoder_t* encoder) noexcept
|
static void* _create(obs_data_t* settings, obs_encoder_t* encoder) noexcept
|
||||||
try {
|
{
|
||||||
auto* fac = reinterpret_cast<factory_t*>(obs_encoder_get_type_data(encoder));
|
try {
|
||||||
return fac->create(settings, encoder, false);
|
auto* fac = reinterpret_cast<factory_t*>(obs_encoder_get_type_data(encoder));
|
||||||
} catch (const std::exception& ex) {
|
return fac->create(settings, encoder, false);
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return nullptr;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return nullptr;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return nullptr;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* _create_hw(obs_data_t* settings, obs_encoder_t* encoder) noexcept
|
static void* _create_hw(obs_data_t* settings, obs_encoder_t* encoder) noexcept
|
||||||
try {
|
{
|
||||||
auto* fac = reinterpret_cast<factory_t*>(obs_encoder_get_type_data(encoder));
|
|
||||||
try {
|
try {
|
||||||
return fac->create(settings, encoder, true);
|
auto* fac = reinterpret_cast<factory_t*>(obs_encoder_get_type_data(encoder));
|
||||||
|
try {
|
||||||
|
return fac->create(settings, encoder, true);
|
||||||
|
} catch (...) {
|
||||||
|
return obs_encoder_create_rerouted(encoder, fac->_info_fallback.id);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
|
return nullptr;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return obs_encoder_create_rerouted(encoder, fac->_info_fallback.id);
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
|
||||||
return nullptr;
|
|
||||||
} catch (...) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _get_defaults2(obs_data_t* settings, void* type_data) noexcept
|
static void _get_defaults2(obs_data_t* settings, void* type_data) noexcept
|
||||||
try {
|
{
|
||||||
if (type_data)
|
try {
|
||||||
reinterpret_cast<factory_t*>(type_data)->get_defaults2(settings);
|
if (type_data)
|
||||||
} catch (const std::exception& ex) {
|
reinterpret_cast<factory_t*>(type_data)->get_defaults2(settings);
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _properties_migrate_settings(void* priv, obs_properties_t*, obs_property_t* p,
|
static bool _properties_migrate_settings(void* priv, obs_properties_t*, obs_property_t* p,
|
||||||
obs_data_t* settings) noexcept
|
obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
obs_property_set_visible(p, false);
|
try {
|
||||||
reinterpret_cast<factory_t*>(priv)->_migrate(settings, nullptr);
|
obs_property_set_visible(p, false);
|
||||||
return true;
|
reinterpret_cast<factory_t*>(priv)->_migrate(settings, nullptr);
|
||||||
} catch (const std::exception& ex) {
|
return true;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static obs_properties_t* _get_properties2(void* data, void* type_data) noexcept
|
static obs_properties_t* _get_properties2(void* data, void* type_data) noexcept
|
||||||
try {
|
{
|
||||||
if (type_data) {
|
try {
|
||||||
auto props =
|
if (type_data) {
|
||||||
reinterpret_cast<factory_t*>(type_data)->get_properties2(reinterpret_cast<instance_t*>(data));
|
auto props =
|
||||||
|
reinterpret_cast<factory_t*>(type_data)->get_properties2(reinterpret_cast<instance_t*>(data));
|
||||||
|
|
||||||
{ // Support for permanent settings migration.
|
{ // Support for permanent settings migration.
|
||||||
auto p = obs_properties_add_int(
|
auto p = obs_properties_add_int(
|
||||||
props, S_VERSION, "If you can see this, something went horribly wrong.",
|
props, S_VERSION, "If you can see this, something went horribly wrong.",
|
||||||
std::numeric_limits<int32_t>::lowest(), std::numeric_limits<int32_t>::max(), 1);
|
std::numeric_limits<int32_t>::lowest(), std::numeric_limits<int32_t>::max(), 1);
|
||||||
obs_property_set_modified_callback2(p, _properties_migrate_settings, type_data);
|
obs_property_set_modified_callback2(p, _properties_migrate_settings, type_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return props;
|
||||||
}
|
}
|
||||||
|
return nullptr;
|
||||||
return props;
|
} catch (const std::exception& ex) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
|
return nullptr;
|
||||||
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
return nullptr;
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
|
||||||
return nullptr;
|
|
||||||
} catch (...) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private /* Instance */:
|
private /* Instance */:
|
||||||
static void _destroy(void* data) noexcept
|
static void _destroy(void* data) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
delete reinterpret_cast<instance_t*>(data);
|
if (data)
|
||||||
} catch (const std::exception& ex) {
|
delete reinterpret_cast<instance_t*>(data);
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _update(void* data, obs_data_t* settings) noexcept
|
static bool _update(void* data, obs_data_t* settings) noexcept
|
||||||
try {
|
{
|
||||||
auto priv = reinterpret_cast<encoder_instance*>(data);
|
try {
|
||||||
if (priv) {
|
auto priv = reinterpret_cast<encoder_instance*>(data);
|
||||||
reinterpret_cast<factory_t*>(obs_encoder_get_type_data(priv->get()))->_migrate(settings, priv);
|
if (priv) {
|
||||||
return priv->update(settings);
|
reinterpret_cast<factory_t*>(obs_encoder_get_type_data(priv->get()))->_migrate(settings, priv);
|
||||||
|
return priv->update(settings);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
|
return false;
|
||||||
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
|
||||||
return false;
|
|
||||||
} catch (...) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _encode(void* data, struct encoder_frame* frame, struct encoder_packet* packet,
|
static bool _encode(void* data, struct encoder_frame* frame, struct encoder_packet* packet,
|
||||||
bool* received_packet) noexcept
|
bool* received_packet) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
return reinterpret_cast<encoder_instance*>(data)->encode_video(frame, packet, received_packet);
|
if (data)
|
||||||
return false;
|
return reinterpret_cast<encoder_instance*>(data)->encode_video(frame, packet, received_packet);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _encode_texture(void* data, uint32_t handle, int64_t pts, uint64_t lock_key, uint64_t* next_key,
|
static bool _encode_texture(void* data, uint32_t handle, int64_t pts, uint64_t lock_key, uint64_t* next_key,
|
||||||
struct encoder_packet* packet, bool* received_packet) noexcept
|
struct encoder_packet* packet, bool* received_packet) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
return reinterpret_cast<encoder_instance*>(data)->encode_video(handle, pts, lock_key, next_key, packet,
|
if (data)
|
||||||
received_packet);
|
return reinterpret_cast<encoder_instance*>(data)->encode_video(handle, pts, lock_key, next_key,
|
||||||
return false;
|
packet, received_packet);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _get_frame_size(void* data) noexcept
|
static size_t _get_frame_size(void* data) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
return reinterpret_cast<encoder_instance*>(data)->get_frame_size();
|
if (data)
|
||||||
return 0;
|
return reinterpret_cast<encoder_instance*>(data)->get_frame_size();
|
||||||
} catch (const std::exception& ex) {
|
return 0;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return 0;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return 0;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return 0;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _get_extra_data(void* data, uint8_t** extra_data, size_t* size) noexcept
|
static bool _get_extra_data(void* data, uint8_t** extra_data, size_t* size) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
return reinterpret_cast<encoder_instance*>(data)->get_extra_data(extra_data, size);
|
if (data)
|
||||||
return false;
|
return reinterpret_cast<encoder_instance*>(data)->get_extra_data(extra_data, size);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _get_sei_data(void* data, uint8_t** sei_data, size_t* size) noexcept
|
static bool _get_sei_data(void* data, uint8_t** sei_data, size_t* size) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
return reinterpret_cast<encoder_instance*>(data)->get_sei_data(sei_data, size);
|
if (data)
|
||||||
return false;
|
return reinterpret_cast<encoder_instance*>(data)->get_sei_data(sei_data, size);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
return false;
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _get_audio_info(void* data, struct audio_convert_info* info) noexcept
|
static void _get_audio_info(void* data, struct audio_convert_info* info) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
reinterpret_cast<encoder_instance*>(data)->get_audio_info(info);
|
if (data)
|
||||||
} catch (const std::exception& ex) {
|
reinterpret_cast<encoder_instance*>(data)->get_audio_info(info);
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _get_video_info(void* data, struct video_scale_info* info) noexcept
|
static void _get_video_info(void* data, struct video_scale_info* info) noexcept
|
||||||
try {
|
{
|
||||||
if (data)
|
try {
|
||||||
reinterpret_cast<encoder_instance*>(data)->get_video_info(info);
|
if (data)
|
||||||
} catch (const std::exception& ex) {
|
reinterpret_cast<encoder_instance*>(data)->get_video_info(info);
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
DLOG_ERROR("Unexpected exception in function '%s': %s.", __FUNCTION_NAME__, ex.what());
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -44,10 +44,12 @@ namespace streamfx::obs {
|
||||||
std::shared_ptr<obs_source_t> _keepalive;
|
std::shared_ptr<obs_source_t> _keepalive;
|
||||||
|
|
||||||
static void handle_signal(void* ptr, calldata* cd) noexcept
|
static void handle_signal(void* ptr, calldata* cd) noexcept
|
||||||
try {
|
{
|
||||||
auto p = reinterpret_cast<signal_handler<std::shared_ptr<obs_source_t>>*>(ptr);
|
try {
|
||||||
p->event(p->_keepalive, cd);
|
auto p = reinterpret_cast<signal_handler<std::shared_ptr<obs_source_t>>*>(ptr);
|
||||||
} catch (...) {
|
p->event(p->_keepalive, cd);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -72,10 +74,12 @@ namespace streamfx::obs {
|
||||||
::streamfx::obs::source _keepalive;
|
::streamfx::obs::source _keepalive;
|
||||||
|
|
||||||
static void handle_audio(void* ptr, obs_source_t*, const struct audio_data* audio_data, bool muted) noexcept
|
static void handle_audio(void* ptr, obs_source_t*, const struct audio_data* audio_data, bool muted) noexcept
|
||||||
try {
|
{
|
||||||
auto p = reinterpret_cast<audio_signal_handler*>(ptr);
|
try {
|
||||||
p->event(p->_keepalive, audio_data, muted);
|
auto p = reinterpret_cast<audio_signal_handler*>(ptr);
|
||||||
} catch (...) {
|
p->event(p->_keepalive, audio_data, muted);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -97,238 +97,242 @@ static std::shared_ptr<streamfx::gfx::opengl> _streamfx_gfx_opengl;
|
||||||
static std::shared_ptr<streamfx::obs::source_tracker> _source_tracker;
|
static std::shared_ptr<streamfx::obs::source_tracker> _source_tracker;
|
||||||
|
|
||||||
MODULE_EXPORT bool obs_module_load(void)
|
MODULE_EXPORT bool obs_module_load(void)
|
||||||
try {
|
{
|
||||||
DLOG_INFO("Loading Version %s", STREAMFX_VERSION_STRING);
|
try {
|
||||||
|
DLOG_INFO("Loading Version %s", STREAMFX_VERSION_STRING);
|
||||||
|
|
||||||
// Initialize global configuration.
|
// Initialize global configuration.
|
||||||
streamfx::configuration::initialize();
|
streamfx::configuration::initialize();
|
||||||
|
|
||||||
// Initialize global Thread Pool.
|
// Initialize global Thread Pool.
|
||||||
_threadpool = std::make_shared<streamfx::util::threadpool>();
|
_threadpool = std::make_shared<streamfx::util::threadpool>();
|
||||||
|
|
||||||
// Initialize Source Tracker
|
// Initialize Source Tracker
|
||||||
_source_tracker = streamfx::obs::source_tracker::get();
|
_source_tracker = streamfx::obs::source_tracker::get();
|
||||||
|
|
||||||
// Initialize GLAD (OpenGL)
|
// Initialize GLAD (OpenGL)
|
||||||
{
|
{
|
||||||
streamfx::obs::gs::context gctx{};
|
streamfx::obs::gs::context gctx{};
|
||||||
_streamfx_gfx_opengl = streamfx::gfx::opengl::get();
|
_streamfx_gfx_opengl = streamfx::gfx::opengl::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_NVIDIA_CUDA
|
#ifdef ENABLE_NVIDIA_CUDA
|
||||||
// Initialize CUDA if features requested it.
|
// Initialize CUDA if features requested it.
|
||||||
std::shared_ptr<::streamfx::nvidia::cuda::obs> cuda;
|
std::shared_ptr<::streamfx::nvidia::cuda::obs> cuda;
|
||||||
try {
|
try {
|
||||||
cuda = ::streamfx::nvidia::cuda::obs::get();
|
cuda = ::streamfx::nvidia::cuda::obs::get();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// If CUDA failed to load, it is considered safe to ignore.
|
// If CUDA failed to load, it is considered safe to ignore.
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GS Stuff
|
// GS Stuff
|
||||||
{
|
|
||||||
_gs_fstri_vb = std::make_shared<streamfx::obs::gs::vertex_buffer>(uint32_t(3), uint8_t(1));
|
|
||||||
{
|
{
|
||||||
auto vtx = _gs_fstri_vb->at(0);
|
_gs_fstri_vb = std::make_shared<streamfx::obs::gs::vertex_buffer>(uint32_t(3), uint8_t(1));
|
||||||
vec3_set(vtx.position, 0, 0, 0);
|
{
|
||||||
vec4_set(vtx.uv[0], 0, 0, 0, 0);
|
auto vtx = _gs_fstri_vb->at(0);
|
||||||
|
vec3_set(vtx.position, 0, 0, 0);
|
||||||
|
vec4_set(vtx.uv[0], 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto vtx = _gs_fstri_vb->at(1);
|
||||||
|
vec3_set(vtx.position, 2, 0, 0);
|
||||||
|
vec4_set(vtx.uv[0], 2, 0, 0, 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto vtx = _gs_fstri_vb->at(2);
|
||||||
|
vec3_set(vtx.position, 0, 2, 0);
|
||||||
|
vec4_set(vtx.uv[0], 0, 2, 0, 0);
|
||||||
|
}
|
||||||
|
_gs_fstri_vb->update();
|
||||||
}
|
}
|
||||||
{
|
|
||||||
auto vtx = _gs_fstri_vb->at(1);
|
|
||||||
vec3_set(vtx.position, 2, 0, 0);
|
|
||||||
vec4_set(vtx.uv[0], 2, 0, 0, 0);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto vtx = _gs_fstri_vb->at(2);
|
|
||||||
vec3_set(vtx.position, 0, 2, 0);
|
|
||||||
vec4_set(vtx.uv[0], 0, 2, 0, 0);
|
|
||||||
}
|
|
||||||
_gs_fstri_vb->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encoders
|
// Encoders
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_ENCODER_AOM_AV1
|
#ifdef ENABLE_ENCODER_AOM_AV1
|
||||||
streamfx::encoder::aom::av1::aom_av1_factory::initialize();
|
streamfx::encoder::aom::av1::aom_av1_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_ENCODER_FFMPEG
|
#ifdef ENABLE_ENCODER_FFMPEG
|
||||||
using namespace streamfx::encoder::ffmpeg;
|
using namespace streamfx::encoder::ffmpeg;
|
||||||
ffmpeg_manager::initialize();
|
ffmpeg_manager::initialize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filters
|
// Filters
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_FILTER_AUTOFRAMING
|
#ifdef ENABLE_FILTER_AUTOFRAMING
|
||||||
streamfx::filter::autoframing::autoframing_factory::initialize();
|
streamfx::filter::autoframing::autoframing_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_BLUR
|
#ifdef ENABLE_FILTER_BLUR
|
||||||
streamfx::filter::blur::blur_factory::initialize();
|
streamfx::filter::blur::blur_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_COLOR_GRADE
|
#ifdef ENABLE_FILTER_COLOR_GRADE
|
||||||
streamfx::filter::color_grade::color_grade_factory::initialize();
|
streamfx::filter::color_grade::color_grade_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_DENOISING
|
#ifdef ENABLE_FILTER_DENOISING
|
||||||
streamfx::filter::denoising::denoising_factory::initialize();
|
streamfx::filter::denoising::denoising_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_DISPLACEMENT
|
#ifdef ENABLE_FILTER_DISPLACEMENT
|
||||||
streamfx::filter::displacement::displacement_factory::initialize();
|
streamfx::filter::displacement::displacement_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_DYNAMIC_MASK
|
#ifdef ENABLE_FILTER_DYNAMIC_MASK
|
||||||
streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize();
|
streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_SDF_EFFECTS
|
#ifdef ENABLE_FILTER_SDF_EFFECTS
|
||||||
streamfx::filter::sdf_effects::sdf_effects_factory::initialize();
|
streamfx::filter::sdf_effects::sdf_effects_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_SHADER
|
#ifdef ENABLE_FILTER_SHADER
|
||||||
streamfx::filter::shader::shader_factory::initialize();
|
streamfx::filter::shader::shader_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_TRANSFORM
|
#ifdef ENABLE_FILTER_TRANSFORM
|
||||||
streamfx::filter::transform::transform_factory::initialize();
|
streamfx::filter::transform::transform_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_UPSCALING
|
#ifdef ENABLE_FILTER_UPSCALING
|
||||||
streamfx::filter::upscaling::upscaling_factory::initialize();
|
streamfx::filter::upscaling::upscaling_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_VIRTUAL_GREENSCREEN
|
#ifdef ENABLE_FILTER_VIRTUAL_GREENSCREEN
|
||||||
streamfx::filter::virtual_greenscreen::virtual_greenscreen_factory::initialize();
|
streamfx::filter::virtual_greenscreen::virtual_greenscreen_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sources
|
// Sources
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SOURCE_MIRROR
|
#ifdef ENABLE_SOURCE_MIRROR
|
||||||
streamfx::source::mirror::mirror_factory::initialize();
|
streamfx::source::mirror::mirror_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SOURCE_SHADER
|
#ifdef ENABLE_SOURCE_SHADER
|
||||||
streamfx::source::shader::shader_factory::initialize();
|
streamfx::source::shader::shader_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transitions
|
// Transitions
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_TRANSITION_SHADER
|
#ifdef ENABLE_TRANSITION_SHADER
|
||||||
streamfx::transition::shader::shader_factory::initialize();
|
streamfx::transition::shader::shader_factory::initialize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frontend
|
// Frontend
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
streamfx::ui::handler::initialize();
|
streamfx::ui::handler::initialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DLOG_INFO("Loaded Version %s", STREAMFX_VERSION_STRING);
|
DLOG_INFO("Loaded Version %s", STREAMFX_VERSION_STRING);
|
||||||
return true;
|
return true;
|
||||||
} catch (std::exception const& ex) {
|
} catch (std::exception const& ex) {
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s", __FUNCTION_NAME__, ex.what());
|
DLOG_ERROR("Unexpected exception in function '%s': %s", __FUNCTION_NAME__, ex.what());
|
||||||
return false;
|
return false;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_EXPORT void obs_module_unload(void)
|
MODULE_EXPORT void obs_module_unload(void)
|
||||||
try {
|
{
|
||||||
DLOG_INFO("Unloading Version %s", STREAMFX_VERSION_STRING);
|
try {
|
||||||
|
DLOG_INFO("Unloading Version %s", STREAMFX_VERSION_STRING);
|
||||||
|
|
||||||
// Frontend
|
// Frontend
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
streamfx::ui::handler::finalize();
|
streamfx::ui::handler::finalize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Transitions
|
// Transitions
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_TRANSITION_SHADER
|
#ifdef ENABLE_TRANSITION_SHADER
|
||||||
streamfx::transition::shader::shader_factory::finalize();
|
streamfx::transition::shader::shader_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sources
|
// Sources
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SOURCE_MIRROR
|
#ifdef ENABLE_SOURCE_MIRROR
|
||||||
streamfx::source::mirror::mirror_factory::finalize();
|
streamfx::source::mirror::mirror_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_SOURCE_SHADER
|
#ifdef ENABLE_SOURCE_SHADER
|
||||||
streamfx::source::shader::shader_factory::finalize();
|
streamfx::source::shader::shader_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filters
|
// Filters
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_FILTER_AUTOFRAMING
|
#ifdef ENABLE_FILTER_AUTOFRAMING
|
||||||
streamfx::filter::autoframing::autoframing_factory::finalize();
|
streamfx::filter::autoframing::autoframing_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_BLUR
|
#ifdef ENABLE_FILTER_BLUR
|
||||||
streamfx::filter::blur::blur_factory::finalize();
|
streamfx::filter::blur::blur_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_COLOR_GRADE
|
#ifdef ENABLE_FILTER_COLOR_GRADE
|
||||||
streamfx::filter::color_grade::color_grade_factory::finalize();
|
streamfx::filter::color_grade::color_grade_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_DENOISING
|
#ifdef ENABLE_FILTER_DENOISING
|
||||||
streamfx::filter::denoising::denoising_factory::finalize();
|
streamfx::filter::denoising::denoising_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_DISPLACEMENT
|
#ifdef ENABLE_FILTER_DISPLACEMENT
|
||||||
streamfx::filter::displacement::displacement_factory::finalize();
|
streamfx::filter::displacement::displacement_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_DYNAMIC_MASK
|
#ifdef ENABLE_FILTER_DYNAMIC_MASK
|
||||||
streamfx::filter::dynamic_mask::dynamic_mask_factory::finalize();
|
streamfx::filter::dynamic_mask::dynamic_mask_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_SDF_EFFECTS
|
#ifdef ENABLE_FILTER_SDF_EFFECTS
|
||||||
streamfx::filter::sdf_effects::sdf_effects_factory::finalize();
|
streamfx::filter::sdf_effects::sdf_effects_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_SHADER
|
#ifdef ENABLE_FILTER_SHADER
|
||||||
streamfx::filter::shader::shader_factory::finalize();
|
streamfx::filter::shader::shader_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_TRANSFORM
|
#ifdef ENABLE_FILTER_TRANSFORM
|
||||||
streamfx::filter::transform::transform_factory::finalize();
|
streamfx::filter::transform::transform_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_UPSCALING
|
#ifdef ENABLE_FILTER_UPSCALING
|
||||||
streamfx::filter::upscaling::upscaling_factory::finalize();
|
streamfx::filter::upscaling::upscaling_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_FILTER_VIRTUAL_GREENSCREEN
|
#ifdef ENABLE_FILTER_VIRTUAL_GREENSCREEN
|
||||||
streamfx::filter::virtual_greenscreen::virtual_greenscreen_factory::finalize();
|
streamfx::filter::virtual_greenscreen::virtual_greenscreen_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encoders
|
// Encoders
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_ENCODER_FFMPEG
|
#ifdef ENABLE_ENCODER_FFMPEG
|
||||||
streamfx::encoder::ffmpeg::ffmpeg_manager::finalize();
|
streamfx::encoder::ffmpeg::ffmpeg_manager::finalize();
|
||||||
#endif
|
#endif
|
||||||
#ifdef ENABLE_ENCODER_AOM_AV1
|
#ifdef ENABLE_ENCODER_AOM_AV1
|
||||||
streamfx::encoder::aom::av1::aom_av1_factory::finalize();
|
streamfx::encoder::aom::av1::aom_av1_factory::finalize();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// GS Stuff
|
||||||
|
{
|
||||||
|
_gs_fstri_vb.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize GLAD (OpenGL)
|
||||||
|
{
|
||||||
|
streamfx::obs::gs::context gctx{};
|
||||||
|
_streamfx_gfx_opengl.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize Source Tracker
|
||||||
|
_source_tracker.reset();
|
||||||
|
|
||||||
|
// // Auto-Updater
|
||||||
|
//#ifdef ENABLE_UPDATER
|
||||||
|
// _updater.reset();
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
// Finalize Thread Pool
|
||||||
|
_threadpool.reset();
|
||||||
|
|
||||||
|
// Finalize Configuration
|
||||||
|
streamfx::configuration::finalize();
|
||||||
|
|
||||||
|
DLOG_INFO("Unloaded Version %s", STREAMFX_VERSION_STRING);
|
||||||
|
} catch (std::exception const& ex) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s': %s", __FUNCTION_NAME__, ex.what());
|
||||||
|
} catch (...) {
|
||||||
|
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GS Stuff
|
|
||||||
{
|
|
||||||
_gs_fstri_vb.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalize GLAD (OpenGL)
|
|
||||||
{
|
|
||||||
streamfx::obs::gs::context gctx{};
|
|
||||||
_streamfx_gfx_opengl.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalize Source Tracker
|
|
||||||
_source_tracker.reset();
|
|
||||||
|
|
||||||
// // Auto-Updater
|
|
||||||
//#ifdef ENABLE_UPDATER
|
|
||||||
// _updater.reset();
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
// Finalize Thread Pool
|
|
||||||
_threadpool.reset();
|
|
||||||
|
|
||||||
// Finalize Configuration
|
|
||||||
streamfx::configuration::finalize();
|
|
||||||
|
|
||||||
DLOG_INFO("Unloaded Version %s", STREAMFX_VERSION_STRING);
|
|
||||||
} catch (std::exception const& ex) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s': %s", __FUNCTION_NAME__, ex.what());
|
|
||||||
} catch (...) {
|
|
||||||
DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<streamfx::util::threadpool> streamfx::threadpool()
|
std::shared_ptr<streamfx::util::threadpool> streamfx::threadpool()
|
||||||
|
|
|
@ -184,29 +184,31 @@ void mirror_instance::enum_all_sources(obs_source_enum_proc_t cb, void* ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void mirror_instance::acquire(std::string source_name)
|
void mirror_instance::acquire(std::string source_name)
|
||||||
try {
|
{
|
||||||
release();
|
try {
|
||||||
|
release();
|
||||||
|
|
||||||
// Find source by name if possible.
|
// Find source by name if possible.
|
||||||
decltype(_source) source{source_name};
|
decltype(_source) source{source_name};
|
||||||
if ((!source) || (source == _self)) { // If we failed, just exit early.
|
if ((!source) || (source == _self)) { // If we failed, just exit early.
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything went well, store.
|
||||||
|
_source_child = std::make_shared<::streamfx::obs::source_active_child>(_self, source);
|
||||||
|
_source = std::move(source);
|
||||||
|
_source_size.first = obs_source_get_width(_source);
|
||||||
|
_source_size.second = obs_source_get_height(_source);
|
||||||
|
|
||||||
|
// Listen to any audio the source spews out.
|
||||||
|
if (_audio_enabled) {
|
||||||
|
_signal_audio = std::make_shared<obs::audio_signal_handler>(_source);
|
||||||
|
_signal_audio->event.add(std::bind(&mirror_instance::on_audio, this, std::placeholders::_1,
|
||||||
|
std::placeholders::_2, std::placeholders::_3));
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything went well, store.
|
|
||||||
_source_child = std::make_shared<::streamfx::obs::source_active_child>(_self, source);
|
|
||||||
_source = std::move(source);
|
|
||||||
_source_size.first = obs_source_get_width(_source);
|
|
||||||
_source_size.second = obs_source_get_height(_source);
|
|
||||||
|
|
||||||
// Listen to any audio the source spews out.
|
|
||||||
if (_audio_enabled) {
|
|
||||||
_signal_audio = std::make_shared<obs::audio_signal_handler>(_source);
|
|
||||||
_signal_audio->event.add(std::bind(&mirror_instance::on_audio, this, std::placeholders::_1,
|
|
||||||
std::placeholders::_2, std::placeholders::_3));
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mirror_instance::release()
|
void mirror_instance::release()
|
||||||
|
@ -306,15 +308,17 @@ void mirror_factory::get_defaults2(obs_data_t* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool modified_properties(obs_properties_t* pr, obs_property_t* p, obs_data_t* data) noexcept
|
static bool modified_properties(obs_properties_t* pr, obs_property_t* p, obs_data_t* data) noexcept
|
||||||
try {
|
{
|
||||||
if (obs_properties_get(pr, ST_KEY_SOURCE_AUDIO) == p) {
|
try {
|
||||||
bool show = obs_data_get_bool(data, ST_KEY_SOURCE_AUDIO);
|
if (obs_properties_get(pr, ST_KEY_SOURCE_AUDIO) == p) {
|
||||||
obs_property_set_visible(obs_properties_get(pr, ST_KEY_SOURCE_AUDIO_LAYOUT), show);
|
bool show = obs_data_get_bool(data, ST_KEY_SOURCE_AUDIO);
|
||||||
return true;
|
obs_property_set_visible(obs_properties_get(pr, ST_KEY_SOURCE_AUDIO_LAYOUT), show);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (...) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch (...) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_properties_t* mirror_factory::get_properties2(mirror_instance* data)
|
obs_properties_t* mirror_factory::get_properties2(mirror_instance* data)
|
||||||
|
@ -384,28 +388,32 @@ obs_properties_t* mirror_factory::get_properties2(mirror_instance* data)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool mirror_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool mirror_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<mirror_factory> _source_mirror_factory_instance;
|
std::shared_ptr<mirror_factory> _source_mirror_factory_instance;
|
||||||
|
|
||||||
void streamfx::source::mirror::mirror_factory::initialize()
|
void streamfx::source::mirror::mirror_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_source_mirror_factory_instance)
|
try {
|
||||||
_source_mirror_factory_instance = std::make_shared<mirror_factory>();
|
if (!_source_mirror_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_source_mirror_factory_instance = std::make_shared<mirror_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::source::mirror::mirror_factory::finalize()
|
void streamfx::source::mirror::mirror_factory::finalize()
|
||||||
|
|
|
@ -171,28 +171,32 @@ obs_properties_t* shader_factory::get_properties2(shader_instance* data)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<shader_factory> _source_shader_factory_instance = nullptr;
|
std::shared_ptr<shader_factory> _source_shader_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::source::shader::shader_factory::initialize()
|
void streamfx::source::shader::shader_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_source_shader_factory_instance)
|
try {
|
||||||
_source_shader_factory_instance = std::make_shared<shader_factory>();
|
if (!_source_shader_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_source_shader_factory_instance = std::make_shared<shader_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::source::shader::shader_factory::finalize()
|
void streamfx::source::shader::shader_factory::finalize()
|
||||||
|
|
|
@ -183,28 +183,32 @@ obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
|
||||||
|
|
||||||
#ifdef ENABLE_FRONTEND
|
#ifdef ENABLE_FRONTEND
|
||||||
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
bool shader_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||||
try {
|
{
|
||||||
streamfx::open_url(HELP_URL);
|
try {
|
||||||
return false;
|
streamfx::open_url(HELP_URL);
|
||||||
} catch (const std::exception& ex) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to error: %s", ex.what());
|
||||||
} catch (...) {
|
return false;
|
||||||
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
} catch (...) {
|
||||||
return false;
|
D_LOG_ERROR("Failed to open manual due to unknown error.", "");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<shader_factory> _transition_shader_factory_instance = nullptr;
|
std::shared_ptr<shader_factory> _transition_shader_factory_instance = nullptr;
|
||||||
|
|
||||||
void streamfx::transition::shader::shader_factory::initialize()
|
void streamfx::transition::shader::shader_factory::initialize()
|
||||||
try {
|
{
|
||||||
if (!_transition_shader_factory_instance)
|
try {
|
||||||
_transition_shader_factory_instance = std::make_shared<shader_factory>();
|
if (!_transition_shader_factory_instance)
|
||||||
} catch (const std::exception& ex) {
|
_transition_shader_factory_instance = std::make_shared<shader_factory>();
|
||||||
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
} catch (const std::exception& ex) {
|
||||||
} catch (...) {
|
D_LOG_ERROR("Failed to initialize due to error: %s", ex.what());
|
||||||
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
} catch (...) {
|
||||||
|
D_LOG_ERROR("Failed to initialize due to unknown error.", "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::transition::shader::shader_factory::finalize()
|
void streamfx::transition::shader::shader_factory::finalize()
|
||||||
|
|
|
@ -226,137 +226,140 @@ streamfx::version_info::operator std::string()
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamfx::updater::task(streamfx::util::threadpool_data_t)
|
void streamfx::updater::task(streamfx::util::threadpool_data_t)
|
||||||
try {
|
{
|
||||||
auto query_fn = [this](std::vector<char>& buffer) {
|
try {
|
||||||
static constexpr std::string_view ST_API_URL =
|
auto query_fn = [this](std::vector<char>& buffer) {
|
||||||
"https://api.github.com/repos/Xaymar/obs-StreamFX/releases?per_page=25&page=1";
|
static constexpr std::string_view ST_API_URL =
|
||||||
|
"https://api.github.com/repos/Xaymar/obs-StreamFX/releases?per_page=25&page=1";
|
||||||
|
|
||||||
streamfx::util::curl curl;
|
streamfx::util::curl curl;
|
||||||
size_t buffer_offset = 0;
|
size_t buffer_offset = 0;
|
||||||
|
|
||||||
// Set headers (User-Agent is needed so Github can contact us!).
|
// Set headers (User-Agent is needed so Github can contact us!).
|
||||||
curl.set_header("User-Agent", "StreamFX Updater v" STREAMFX_VERSION_STRING);
|
curl.set_header("User-Agent", "StreamFX Updater v" STREAMFX_VERSION_STRING);
|
||||||
curl.set_header("Accept", "application/vnd.github.v3+json");
|
curl.set_header("Accept", "application/vnd.github.v3+json");
|
||||||
|
|
||||||
// Set up request.
|
// Set up request.
|
||||||
curl.set_option(CURLOPT_HTTPGET, true); // GET
|
curl.set_option(CURLOPT_HTTPGET, true); // GET
|
||||||
curl.set_option(CURLOPT_POST, false); // Not POST
|
curl.set_option(CURLOPT_POST, false); // Not POST
|
||||||
curl.set_option(CURLOPT_URL, ST_API_URL);
|
curl.set_option(CURLOPT_URL, ST_API_URL);
|
||||||
curl.set_option(CURLOPT_TIMEOUT, 30); // 10s until we fail.
|
curl.set_option(CURLOPT_TIMEOUT, 30); // 10s until we fail.
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
curl.set_write_callback([this, &buffer, &buffer_offset](void* data, size_t s1, size_t s2) {
|
curl.set_write_callback([this, &buffer, &buffer_offset](void* data, size_t s1, size_t s2) {
|
||||||
size_t size = s1 * s2;
|
size_t size = s1 * s2;
|
||||||
if (buffer.size() < (size + buffer_offset))
|
if (buffer.size() < (size + buffer_offset))
|
||||||
buffer.resize(buffer_offset + size);
|
buffer.resize(buffer_offset + size);
|
||||||
|
|
||||||
memcpy(buffer.data() + buffer_offset, data, size);
|
memcpy(buffer.data() + buffer_offset, data, size);
|
||||||
buffer_offset += size;
|
buffer_offset += size;
|
||||||
|
|
||||||
return s1 * s2;
|
return s1 * s2;
|
||||||
});
|
});
|
||||||
//std::bind(&streamfx::updater::task_write_cb, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)
|
//std::bind(&streamfx::updater::task_write_cb, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)
|
||||||
|
|
||||||
// Clear any unknown data and reserve 64KiB of memory.
|
// Clear any unknown data and reserve 64KiB of memory.
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
buffer.reserve(0xFFFF);
|
buffer.reserve(0xFFFF);
|
||||||
|
|
||||||
// Finally, execute the request.
|
// Finally, execute the request.
|
||||||
D_LOG_DEBUG("Querying for latest releases...", "");
|
D_LOG_DEBUG("Querying for latest releases...", "");
|
||||||
if (CURLcode res = curl.perform(); res != CURLE_OK) {
|
if (CURLcode res = curl.perform(); res != CURLE_OK) {
|
||||||
D_LOG_ERROR("Performing query failed with error: %s", curl_easy_strerror(res));
|
D_LOG_ERROR("Performing query failed with error: %s", curl_easy_strerror(res));
|
||||||
throw std::runtime_error(curl_easy_strerror(res));
|
throw std::runtime_error(curl_easy_strerror(res));
|
||||||
}
|
|
||||||
|
|
||||||
int32_t status_code = 0;
|
|
||||||
if (CURLcode res = curl.get_info(CURLINFO_HTTP_CODE, status_code); res != CURLE_OK) {
|
|
||||||
D_LOG_ERROR("Retrieving status code failed with error: %s", curl_easy_strerror(res));
|
|
||||||
throw std::runtime_error(curl_easy_strerror(res));
|
|
||||||
}
|
|
||||||
D_LOG_DEBUG("API returned status code %d.", status_code);
|
|
||||||
|
|
||||||
if (status_code != 200) {
|
|
||||||
D_LOG_ERROR("API returned unexpected status code %d.", status_code);
|
|
||||||
throw std::runtime_error("Request failed due to one or more reasons.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
auto parse_fn = [this](nlohmann::json json) {
|
|
||||||
// Check if it was parsed as an object.
|
|
||||||
if (json.type() != nlohmann::json::value_t::array) {
|
|
||||||
throw std::runtime_error("Invalid response from API.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decide on the latest version for all update channels.
|
|
||||||
std::lock_guard<decltype(_lock)> lock(_lock);
|
|
||||||
_updates.clear();
|
|
||||||
for (auto obj : json) {
|
|
||||||
try {
|
|
||||||
auto info = obj.get<streamfx::version_info>();
|
|
||||||
|
|
||||||
switch (info.stage) {
|
|
||||||
case version_stage::STABLE:
|
|
||||||
if (get_update_info(version_stage::STABLE).is_older_than(info)) {
|
|
||||||
_updates.emplace(version_stage::STABLE, info);
|
|
||||||
}
|
|
||||||
[[fallthrough]];
|
|
||||||
case version_stage::CANDIDATE:
|
|
||||||
if (get_update_info(version_stage::CANDIDATE).is_older_than(info)) {
|
|
||||||
_updates.emplace(version_stage::CANDIDATE, info);
|
|
||||||
}
|
|
||||||
[[fallthrough]];
|
|
||||||
case version_stage::BETA:
|
|
||||||
if (get_update_info(version_stage::BETA).is_older_than(info)) {
|
|
||||||
_updates.emplace(version_stage::BETA, info);
|
|
||||||
}
|
|
||||||
[[fallthrough]];
|
|
||||||
case version_stage::ALPHA:
|
|
||||||
if (get_update_info(version_stage::ALPHA).is_older_than(info)) {
|
|
||||||
_updates.emplace(version_stage::ALPHA, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
D_LOG_DEBUG("Failed to parse entry, error: %s", ex.what());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
{ // Query and parse the response.
|
int32_t status_code = 0;
|
||||||
nlohmann::json json;
|
if (CURLcode res = curl.get_info(CURLINFO_HTTP_CODE, status_code); res != CURLE_OK) {
|
||||||
|
D_LOG_ERROR("Retrieving status code failed with error: %s", curl_easy_strerror(res));
|
||||||
|
throw std::runtime_error(curl_easy_strerror(res));
|
||||||
|
}
|
||||||
|
D_LOG_DEBUG("API returned status code %d.", status_code);
|
||||||
|
|
||||||
// Query the API or parse a crafted response.
|
if (status_code != 200) {
|
||||||
auto debug_path = streamfx::config_file_path("github_release_query_response.json");
|
D_LOG_ERROR("API returned unexpected status code %d.", status_code);
|
||||||
if (std::filesystem::exists(debug_path)) {
|
throw std::runtime_error("Request failed due to one or more reasons.");
|
||||||
std::ifstream fs{debug_path};
|
}
|
||||||
json = nlohmann::json::parse(fs);
|
};
|
||||||
fs.close();
|
auto parse_fn = [this](nlohmann::json json) {
|
||||||
} else {
|
// Check if it was parsed as an object.
|
||||||
std::vector<char> buffer;
|
if (json.type() != nlohmann::json::value_t::array) {
|
||||||
query_fn(buffer);
|
throw std::runtime_error("Invalid response from API.");
|
||||||
json = nlohmann::json::parse(buffer.begin(), buffer.end());
|
}
|
||||||
|
|
||||||
|
// Decide on the latest version for all update channels.
|
||||||
|
std::lock_guard<decltype(_lock)> lock(_lock);
|
||||||
|
_updates.clear();
|
||||||
|
for (auto obj : json) {
|
||||||
|
try {
|
||||||
|
auto info = obj.get<streamfx::version_info>();
|
||||||
|
|
||||||
|
switch (info.stage) {
|
||||||
|
case version_stage::STABLE:
|
||||||
|
if (get_update_info(version_stage::STABLE).is_older_than(info)) {
|
||||||
|
_updates.emplace(version_stage::STABLE, info);
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
case version_stage::CANDIDATE:
|
||||||
|
if (get_update_info(version_stage::CANDIDATE).is_older_than(info)) {
|
||||||
|
_updates.emplace(version_stage::CANDIDATE, info);
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
case version_stage::BETA:
|
||||||
|
if (get_update_info(version_stage::BETA).is_older_than(info)) {
|
||||||
|
_updates.emplace(version_stage::BETA, info);
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
case version_stage::ALPHA:
|
||||||
|
if (get_update_info(version_stage::ALPHA).is_older_than(info)) {
|
||||||
|
_updates.emplace(version_stage::ALPHA, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
D_LOG_DEBUG("Failed to parse entry, error: %s", ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
{ // Query and parse the response.
|
||||||
|
nlohmann::json json;
|
||||||
|
|
||||||
|
// Query the API or parse a crafted response.
|
||||||
|
auto debug_path = streamfx::config_file_path("github_release_query_response.json");
|
||||||
|
if (std::filesystem::exists(debug_path)) {
|
||||||
|
std::ifstream fs{debug_path};
|
||||||
|
json = nlohmann::json::parse(fs);
|
||||||
|
fs.close();
|
||||||
|
} else {
|
||||||
|
std::vector<char> buffer;
|
||||||
|
query_fn(buffer);
|
||||||
|
json = nlohmann::json::parse(buffer.begin(), buffer.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the JSON response from the API.
|
||||||
|
parse_fn(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the JSON response from the API.
|
// Print all update information to the log file.
|
||||||
parse_fn(json);
|
D_LOG_INFO("Current Version: %s", static_cast<std::string>(_current_info).c_str());
|
||||||
}
|
D_LOG_INFO("Latest Stable Version: %s",
|
||||||
|
static_cast<std::string>(get_update_info(version_stage::STABLE)).c_str());
|
||||||
|
D_LOG_INFO("Latest Candidate Version: %s",
|
||||||
|
static_cast<std::string>(get_update_info(version_stage::CANDIDATE)).c_str());
|
||||||
|
D_LOG_INFO("Latest Beta Version: %s", static_cast<std::string>(get_update_info(version_stage::BETA)).c_str());
|
||||||
|
D_LOG_INFO("Latest Alpha Version: %s", static_cast<std::string>(get_update_info(version_stage::ALPHA)).c_str());
|
||||||
|
if (is_update_available()) {
|
||||||
|
D_LOG_INFO("Update is available.", "");
|
||||||
|
}
|
||||||
|
|
||||||
// Print all update information to the log file.
|
// Notify listeners of the update.
|
||||||
D_LOG_INFO("Current Version: %s", static_cast<std::string>(_current_info).c_str());
|
events.refreshed.call(*this);
|
||||||
D_LOG_INFO("Latest Stable Version: %s", static_cast<std::string>(get_update_info(version_stage::STABLE)).c_str());
|
} catch (const std::exception& ex) {
|
||||||
D_LOG_INFO("Latest Candidate Version: %s",
|
// Notify about the error.
|
||||||
static_cast<std::string>(get_update_info(version_stage::CANDIDATE)).c_str());
|
std::string message = ex.what();
|
||||||
D_LOG_INFO("Latest Beta Version: %s", static_cast<std::string>(get_update_info(version_stage::BETA)).c_str());
|
events.error.call(*this, message);
|
||||||
D_LOG_INFO("Latest Alpha Version: %s", static_cast<std::string>(get_update_info(version_stage::ALPHA)).c_str());
|
|
||||||
if (is_update_available()) {
|
|
||||||
D_LOG_INFO("Update is available.", "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify listeners of the update.
|
|
||||||
events.refreshed.call(*this);
|
|
||||||
} catch (const std::exception& ex) {
|
|
||||||
// Notify about the error.
|
|
||||||
std::string message = ex.what();
|
|
||||||
events.error.call(*this, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool streamfx::updater::can_check()
|
bool streamfx::updater::can_check()
|
||||||
|
|
Loading…
Reference in New Issue