gfx-source-texture, source-mirror: Prevent recursion caused by Source Mirror

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2018-04-24 13:48:42 +02:00
parent 31342239bc
commit 49964e15be
4 changed files with 43 additions and 14 deletions

View File

@ -18,6 +18,7 @@
#include "gfx-source-texture.h"
gfx::source_texture::~source_texture() {
obs_source_remove_active_child(m_parent, m_source);
if (m_source) {
obs_source_release(m_source);
m_source = nullptr;
@ -25,28 +26,39 @@ gfx::source_texture::~source_texture() {
m_rt = nullptr;
}
gfx::source_texture::source_texture() {
gfx::source_texture::source_texture(obs_source_t* parent) {
m_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
m_parent = parent;
}
obs_source_t* gfx::source_texture::get_object() {
return m_source;
}
gfx::source_texture::source_texture(const char* name) : source_texture() {
obs_source_t* gfx::source_texture::get_parent() {
return m_parent;
}
gfx::source_texture::source_texture(const char* name, obs_source_t* parent) : source_texture(parent) {
m_source = obs_get_source_by_name(name);
if (!m_source) {
throw std::invalid_argument("No such source.");
}
if (!obs_source_add_active_child(m_parent, m_source)) {
throw std::runtime_error("Recursion is not allowed.");
}
}
gfx::source_texture::source_texture(std::string name) : source_texture(name.c_str()) {}
gfx::source_texture::source_texture(std::string name, obs_source_t* parent) : source_texture(name.c_str(), parent) {}
gfx::source_texture::source_texture(obs_source_t* src) : source_texture() {
gfx::source_texture::source_texture(obs_source_t* src, obs_source_t* parent) : source_texture(parent) {
m_source = src;
if (!m_source) {
throw std::invalid_argument("No such source.");
}
if (!obs_source_add_active_child(m_parent, m_source)) {
throw std::runtime_error("Recursion is not allowed.");
}
}
std::shared_ptr<gs::texture> gfx::source_texture::render(size_t width, size_t height) {

View File

@ -25,16 +25,18 @@
namespace gfx {
class source_texture {
obs_source_t* m_source;
obs_source_t* m_parent;
std::shared_ptr<gs::rendertarget> m_rt;
source_texture();
source_texture(obs_source_t* parent);
public:
~source_texture();
source_texture(const char* name);
source_texture(std::string name);
source_texture(obs_source_t* src);
source_texture(const char* name, obs_source_t* parent);
source_texture(std::string name, obs_source_t* parent);
source_texture(obs_source_t* src, obs_source_t* parent);
obs_source_t* get_object();
obs_source_t* get_parent();
std::shared_ptr<gs::texture> render(size_t width, size_t height);
};

View File

@ -73,6 +73,7 @@ Source::MirrorAddon::MirrorAddon() {
osi.deactivate = deactivate;
osi.video_tick = video_tick;
osi.video_render = video_render;
osi.enum_active_sources = enum_active_sources;
obs_register_source(&osi);
}
@ -197,6 +198,10 @@ void Source::MirrorAddon::video_render(void *p, gs_effect_t *ef) {
static_cast<Source::Mirror*>(p)->video_render(ef);
}
void Source::MirrorAddon::enum_active_sources(void *p, obs_source_enum_proc_t enum_callback, void *param) {
static_cast<Source::Mirror*>(p)->enum_active_sources(enum_callback, param);
}
Source::Mirror::Mirror(obs_data_t* data, obs_source_t* src) {
m_active = true;
m_source = src;
@ -213,17 +218,19 @@ Source::Mirror::Mirror(obs_data_t* data, obs_source_t* src) {
Source::Mirror::~Mirror() {}
uint32_t Source::Mirror::get_width() {
if (m_rescale && m_width > 0 && !m_keepOriginalSize)
if (m_rescale && m_width > 0 && !m_keepOriginalSize) {
return m_width;
if (m_mirrorSource)
}
if (m_mirrorSource && (m_mirrorSource->get_object() != m_source)) {
return obs_source_get_width(m_mirrorSource->get_object());
}
return 1;
}
uint32_t Source::Mirror::get_height() {
if (m_rescale && m_height > 0 && !m_keepOriginalSize)
return m_height;
if (m_mirrorSource)
if (m_mirrorSource && (m_mirrorSource->get_object() != m_source))
return obs_source_get_height(m_mirrorSource->get_object());
return 1;
}
@ -233,7 +240,7 @@ void Source::Mirror::update(obs_data_t* data) {
const char* sourceName = obs_data_get_string(data, P_SOURCE);
if (sourceName != m_mirrorName) {
try {
m_mirrorSource = std::make_unique<gfx::source_texture>(sourceName);
m_mirrorSource = std::make_unique<gfx::source_texture>(sourceName, m_source);
m_mirrorName = sourceName;
} catch (...) {
}
@ -312,8 +319,8 @@ void Source::Mirror::video_tick(float) {
m_mirrorName = obs_source_get_name(m_mirrorSource->get_object());
}
void Source::Mirror::video_render(gs_effect_t* ) {
if ((m_width == 0) || (m_height == 0) || !m_mirrorSource) {
void Source::Mirror::video_render(gs_effect_t*) {
if ((m_width == 0) || (m_height == 0) || !m_mirrorSource || (m_mirrorSource->get_object() == m_source)) {
return;
}
@ -367,3 +374,9 @@ void Source::Mirror::video_render(gs_effect_t* ) {
obs_source_video_render(m_mirrorSource->get_object());
}
}
void Source::Mirror::enum_active_sources(obs_source_enum_proc_t enum_callback, void *param) {
if (m_mirrorSource) {
enum_callback(m_source, m_mirrorSource->get_object(), param);
}
}

View File

@ -48,6 +48,7 @@ namespace Source {
static void deactivate(void *);
static void video_tick(void *, float);
static void video_render(void *, gs_effect_t *);
static void enum_active_sources(void *data, obs_source_enum_proc_t enum_callback, void *param);
};
class Mirror {
@ -77,5 +78,6 @@ namespace Source {
void deactivate();
void video_tick(float);
void video_render(gs_effect_t*);
void enum_active_sources(obs_source_enum_proc_t enum_callback, void *param);
};
};