mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-14 15:55:07 +00:00
667 lines
17 KiB
C++
667 lines
17 KiB
C++
/*
|
|
* Modern effects for a modern Streamer
|
|
* Copyright (C) 2018 Michael Fabian Dirks
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#pragma once
|
|
#include "common.hpp"
|
|
|
|
namespace streamfx::obs {
|
|
class source {
|
|
obs_source_t* _ref;
|
|
bool _is_owner;
|
|
|
|
public:
|
|
FORCE_INLINE ~source()
|
|
{
|
|
release();
|
|
};
|
|
|
|
/** Empty/Invalid hard reference.
|
|
*
|
|
*/
|
|
FORCE_INLINE source() : _ref(nullptr), _is_owner(false){};
|
|
|
|
/** Create a new hard reference from an existing pointer.
|
|
*
|
|
* @param source The source object to reference.
|
|
* @param add_reference Should we increment the reference counter (duplicate ownership) or leave as it is (transfer ownership)?
|
|
*/
|
|
FORCE_INLINE source(obs_source_t* source, bool duplicate_reference = false, bool take_ownership = true)
|
|
: _is_owner(take_ownership)
|
|
{
|
|
if (duplicate_reference) {
|
|
_ref = obs_source_get_ref(source);
|
|
} else {
|
|
_ref = source;
|
|
}
|
|
};
|
|
|
|
/** Create a new hard reference for a given source by name.
|
|
*
|
|
* Attention: May fail if the name does not exactly match.
|
|
*/
|
|
FORCE_INLINE source(std::string_view name) : _is_owner(true)
|
|
{
|
|
_ref = obs_get_source_by_name(name.data());
|
|
};
|
|
|
|
/** Create a new hard reference for a new source.
|
|
*
|
|
* Attention: May fail.
|
|
*/
|
|
FORCE_INLINE source(std::string_view id, std::string_view name, obs_data_t* settings, obs_data_t* hotkeys)
|
|
: _is_owner(true)
|
|
{
|
|
_ref = obs_source_create(id.data(), name.data(), settings, hotkeys);
|
|
if (!_ref) {
|
|
throw std::runtime_error("Failed to create source with given parameters.");
|
|
}
|
|
};
|
|
|
|
/** Create a new hard reference for a new private source.
|
|
*
|
|
* Attention: May fail.
|
|
*/
|
|
FORCE_INLINE source(std::string_view id, std::string_view name, obs_data_t* settings) : _is_owner(true)
|
|
{
|
|
_ref = obs_source_create_private(id.data(), name.data(), settings);
|
|
if (!_ref) {
|
|
throw std::runtime_error("Failed to create source with given parameters.");
|
|
}
|
|
};
|
|
|
|
FORCE_INLINE source(source&& move) noexcept
|
|
{
|
|
_ref = move._ref;
|
|
_is_owner = move._is_owner;
|
|
move._ref = nullptr;
|
|
};
|
|
|
|
FORCE_INLINE ::streamfx::obs::source& operator=(source&& move) noexcept
|
|
{
|
|
release();
|
|
_ref = move._ref;
|
|
_is_owner = move._is_owner;
|
|
move._ref = nullptr;
|
|
return *this;
|
|
};
|
|
|
|
FORCE_INLINE source(const source& copy)
|
|
{
|
|
if (copy._is_owner) {
|
|
_ref = obs_source_get_ref(copy._ref);
|
|
} else {
|
|
_ref = copy._ref;
|
|
}
|
|
_is_owner = copy._is_owner;
|
|
};
|
|
|
|
FORCE_INLINE ::streamfx::obs::source& operator=(const source& copy)
|
|
{
|
|
release();
|
|
if (copy._is_owner) {
|
|
_ref = obs_source_get_ref(copy._ref);
|
|
} else {
|
|
_ref = copy._ref;
|
|
}
|
|
_is_owner = copy._is_owner;
|
|
return *this;
|
|
};
|
|
|
|
public:
|
|
/** Retrieve the underlying pointer for manual manipulation.
|
|
*
|
|
* Attention: Ownership remains with the class instance.
|
|
*/
|
|
FORCE_INLINE obs_source_t* get() const
|
|
{
|
|
return _ref;
|
|
};
|
|
|
|
/** Release the underlying pointer.
|
|
*
|
|
* Useful if you need to respond to the "source_remove" or "remove" signals.
|
|
*
|
|
* EXPORT void obs_source_release(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void release()
|
|
{
|
|
if (_ref && _is_owner) {
|
|
obs_source_release(_ref);
|
|
_ref = nullptr;
|
|
_is_owner = false;
|
|
}
|
|
};
|
|
|
|
/** Duplicate the source if possible.
|
|
*
|
|
* Will create a duplicate the source entirely unless forbidden. If forbidden, will instead just return a reference.
|
|
*
|
|
* EXPORT obs_source_t *obs_source_duplicate(obs_source_t *source, const char *desired_name, bool create_private);
|
|
*/
|
|
FORCE_INLINE ::streamfx::obs::source duplicate(std::string_view name, bool is_private)
|
|
{
|
|
return obs_source_duplicate(_ref, name.data(), is_private);
|
|
};
|
|
|
|
public:
|
|
/** Get the source info identifier for this reference.
|
|
*
|
|
* May have a version appended to the end.
|
|
*
|
|
* EXPORT const char *obs_source_get_id(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE std::string_view id() const
|
|
{
|
|
return obs_source_get_id(_ref);
|
|
};
|
|
|
|
/** Get the source info identifier for this reference.
|
|
*
|
|
* EXPORT const char *obs_source_get_unversioned_id(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE std::string_view unversioned_id() const
|
|
{
|
|
return obs_source_get_unversioned_id(_ref);
|
|
};
|
|
|
|
/** What type is this source?
|
|
*
|
|
*/
|
|
FORCE_INLINE obs_source_type type() const
|
|
{
|
|
return obs_source_get_type(_ref);
|
|
};
|
|
|
|
/** Get the output flags.
|
|
*
|
|
* EXPORT uint32_t obs_source_get_output_flags(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE uint32_t output_flags() const
|
|
{
|
|
return obs_source_get_output_flags(_ref);
|
|
};
|
|
|
|
/** Get the flags
|
|
*
|
|
* EXPORT uint32_t obs_source_get_flags(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE uint32_t flags() const
|
|
{
|
|
return obs_source_get_flags(_ref);
|
|
};
|
|
|
|
/** Set the flags
|
|
*
|
|
* EXPORT void obs_source_set_default_flags(obs_source_t* source, uint32_t flags);
|
|
*/
|
|
FORCE_INLINE void default_flags(uint32_t flags)
|
|
{
|
|
obs_source_set_default_flags(_ref, flags);
|
|
};
|
|
|
|
/** Set the flags
|
|
*
|
|
* EXPORT void obs_source_set_flags(obs_source_t *source, uint32_t flags);
|
|
*/
|
|
FORCE_INLINE void flags(uint32_t flags)
|
|
{
|
|
obs_source_set_flags(_ref, flags);
|
|
};
|
|
|
|
/** What is the source type called?
|
|
*
|
|
* EXPORT const char *obs_source_get_display_name(const char *id);
|
|
*/
|
|
FORCE_INLINE std::string_view display_name() const
|
|
{
|
|
return obs_source_get_display_name(id().data());
|
|
};
|
|
|
|
/** What is this source called?
|
|
*
|
|
* EXPORT const char *obs_source_get_name(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE std::string_view name() const
|
|
{
|
|
return obs_source_get_name(_ref);
|
|
};
|
|
|
|
/** Change the name of the source.
|
|
*
|
|
* Triggers 'rename' on the source itself, as well as 'source_rename' globally if not private.
|
|
*
|
|
* EXPORT void obs_source_set_name(obs_source_t *source, const char *name);
|
|
*/
|
|
FORCE_INLINE void name(std::string_view new_name)
|
|
{
|
|
obs_source_set_name(_ref, new_name.data());
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT bool obs_source_enabled(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE bool enabled() const
|
|
{
|
|
return obs_source_enabled(_ref);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_set_enabled(obs_source_t *source, bool enabled);
|
|
*/
|
|
FORCE_INLINE void enabled(bool enabled)
|
|
{
|
|
obs_source_set_enabled(_ref, enabled);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT bool obs_source_is_hidden(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE bool hidden() const
|
|
{
|
|
return obs_source_is_hidden(_ref);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_set_hidden(obs_source_t *source, bool hidden);
|
|
*/
|
|
FORCE_INLINE void hidden(bool v)
|
|
{
|
|
obs_source_set_hidden(_ref, v);
|
|
};
|
|
|
|
public /* Size */:
|
|
/** Get the base width of the source, if supported.
|
|
*
|
|
* This will be the size without any other scaling factors applied.
|
|
*
|
|
* EXPORT uint32_t obs_source_get_base_width(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE uint32_t base_width() const
|
|
{
|
|
return obs_source_get_base_width(_ref);
|
|
};
|
|
|
|
/** Get the base height of the source, if supported.
|
|
*
|
|
* This will be the size without any other scaling factors applied.
|
|
*
|
|
* EXPORT uint32_t obs_source_get_base_height(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE uint32_t base_height() const
|
|
{
|
|
return obs_source_get_base_height(_ref);
|
|
};
|
|
|
|
/** Get the reported width of the source, if supported.
|
|
*
|
|
* EXPORT uint32_t obs_source_get_width(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE uint32_t width() const
|
|
{
|
|
return obs_source_get_width(_ref);
|
|
};
|
|
|
|
/** Get the reported height of the source, if supported.
|
|
*
|
|
* EXPORT uint32_t obs_source_get_height(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE uint32_t height() const
|
|
{
|
|
return obs_source_get_height(_ref);
|
|
};
|
|
|
|
/** Get the reported size of the source, if supported.
|
|
*
|
|
* EXPORT uint32_t obs_source_get_width(obs_source_t *source);
|
|
* EXPORT uint32_t obs_source_get_height(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE std::pair<uint32_t, uint32_t> size() const
|
|
{
|
|
return {width(), height()};
|
|
};
|
|
|
|
public /* Configuration */:
|
|
/** Is the source configurable?
|
|
*
|
|
* EXPORT bool obs_source_configurable(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE bool configurable()
|
|
{
|
|
return obs_source_configurable(_ref);
|
|
};
|
|
|
|
/** Retrieve the properties for the source.
|
|
*
|
|
* EXPORT obs_properties_t *obs_get_source_properties(const char *id);
|
|
*/
|
|
FORCE_INLINE obs_properties_t* properties()
|
|
{
|
|
return obs_source_properties(_ref);
|
|
};
|
|
|
|
/** Signal for properties to be updated.
|
|
*
|
|
* EXPORT void obs_source_update_properties(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void update_properties()
|
|
{
|
|
obs_source_update_properties(_ref);
|
|
};
|
|
|
|
/** Retrieve the default values for the settings.
|
|
*
|
|
* EXPORT obs_data_t *obs_get_source_defaults(const char *id);
|
|
*/
|
|
FORCE_INLINE obs_data_t* defaults()
|
|
{
|
|
return obs_get_source_defaults(id().data());
|
|
};
|
|
|
|
/** Retrieve the private settings.
|
|
*
|
|
* EXPORT obs_data_t *obs_source_get_private_settings(obs_source_t *item);
|
|
*/
|
|
FORCE_INLINE obs_data_t* private_settings()
|
|
{
|
|
return obs_source_get_private_settings(_ref);
|
|
};
|
|
|
|
/** Retrieve the current settings.
|
|
*
|
|
* EXPORT obs_data_t *obs_source_get_settings(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE obs_data_t* settings()
|
|
{
|
|
return obs_source_get_settings(_ref);
|
|
};
|
|
|
|
/** Update the settings with new ones.
|
|
*
|
|
* Does not remove previously existing entries.
|
|
*
|
|
* EXPORT void obs_source_update(obs_source_t *source, obs_data_t *settings);
|
|
*/
|
|
FORCE_INLINE void update(obs_data_t* settings)
|
|
{
|
|
obs_source_update(_ref, settings);
|
|
};
|
|
|
|
/** Reset the settings, then update with new settings.
|
|
*
|
|
* EXPORT void obs_source_reset_settings(obs_source_t *source, obs_data_t *settings);
|
|
*/
|
|
FORCE_INLINE void reset_settings(obs_data_t* settings = nullptr)
|
|
{
|
|
obs_source_reset_settings(_ref, settings);
|
|
};
|
|
|
|
/** Signal the source to load.
|
|
*
|
|
* EXPORT void obs_source_load(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void load()
|
|
{
|
|
obs_source_load(_ref);
|
|
};
|
|
|
|
/** Signal the source and all its filters to load.
|
|
*
|
|
* EXPORT void obs_source_load2(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void load2()
|
|
{
|
|
obs_source_load2(_ref);
|
|
};
|
|
|
|
/** Signal the source to save.
|
|
*
|
|
* EXPORT void obs_source_save(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void save()
|
|
{
|
|
obs_source_save(_ref);
|
|
};
|
|
|
|
public /* Interaction */:
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_send_mouse_click(obs_source_t *source, const struct obs_mouse_event *event, int32_t type, bool mouse_up, uint32_t click_count);
|
|
*/
|
|
FORCE_INLINE void send_mouse_press(const obs_mouse_event* event, int32_t type, bool released, uint32_t count)
|
|
{
|
|
return obs_source_send_mouse_click(_ref, event, type, released, count);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_send_mouse_move(obs_source_t *source, const struct obs_mouse_event *event, bool mouse_leave);
|
|
*/
|
|
FORCE_INLINE void send_mouse_move(const obs_mouse_event* event, bool leave)
|
|
{
|
|
return obs_source_send_mouse_move(_ref, event, leave);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_send_mouse_wheel(obs_source_t *source, const struct obs_mouse_event *event, int x_delta, int y_delta);
|
|
*/
|
|
FORCE_INLINE void send_mouse_wheel(const obs_mouse_event* event, int32_t x_delta, int32_t y_delta)
|
|
{
|
|
return obs_source_send_mouse_wheel(_ref, event, x_delta, y_delta);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_send_key_click(obs_source_t *source, const struct obs_key_event *event, bool key_up);
|
|
*/
|
|
FORCE_INLINE void send_key_press(const obs_key_event* event, bool released)
|
|
{
|
|
return obs_source_send_key_click(_ref, event, released);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_send_focus(obs_source_t *source, bool focus);
|
|
*/
|
|
FORCE_INLINE void send_focus(bool in_focus)
|
|
{
|
|
return obs_source_send_focus(_ref, in_focus);
|
|
};
|
|
|
|
public /* Filters */:
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_filter_add(obs_source_t *source, obs_source_t *filter);
|
|
*/
|
|
FORCE_INLINE void add_filter(::streamfx::obs::source& filter)
|
|
{
|
|
return obs_source_filter_add(_ref, filter.get());
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_filter_remove(obs_source_t *source, obs_source_t *filter);
|
|
*/
|
|
FORCE_INLINE void remove_filter(::streamfx::obs::source& filter)
|
|
{
|
|
return obs_source_filter_remove(_ref, filter.get());
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT obs_source_t *obs_filter_get_parent(const obs_source_t *filter);
|
|
*/
|
|
FORCE_INLINE ::streamfx::obs::source get_filter_parent()
|
|
{
|
|
return obs_filter_get_parent(_ref);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT obs_source_t *obs_filter_get_target(const obs_source_t *filter);
|
|
*/
|
|
FORCE_INLINE ::streamfx::obs::source get_filter_target()
|
|
{
|
|
return obs_filter_get_target(_ref);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_skip_video_filter(obs_source_t *filter);
|
|
*/
|
|
FORCE_INLINE void skip_video_filter()
|
|
{
|
|
return obs_source_skip_video_filter(_ref);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT bool obs_source_process_filter_begin(obs_source_t *filter, enum gs_color_format format, enum obs_allow_direct_render allow_direct);
|
|
*/
|
|
FORCE_INLINE bool process_filter_begin(gs_color_format format, obs_allow_direct_render allow_direct)
|
|
{
|
|
return obs_source_process_filter_begin(_ref, format, allow_direct);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_process_filter_end(obs_source_t *filter, gs_effect_t *effect, uint32_t width, uint32_t height);
|
|
*/
|
|
FORCE_INLINE void process_filter_end(gs_effect_t* effect, uint32_t width, uint32_t height)
|
|
{
|
|
obs_source_process_filter_end(_ref, effect, width, height);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_process_filter_tech_end(obs_source_t *filter, gs_effect_t *effect, uint32_t width, uint32_t height, const char *tech_name);
|
|
*/
|
|
FORCE_INLINE void process_filter_tech_end(gs_effect_t* effect, uint32_t width, uint32_t height,
|
|
std::string_view tech_name)
|
|
{
|
|
obs_source_process_filter_tech_end(_ref, effect, width, height, tech_name.data());
|
|
};
|
|
|
|
public /* Active/Showing References */:
|
|
/** Is the source visible in main view?
|
|
*
|
|
* EXPORT bool obs_source_active(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE bool active() const
|
|
{
|
|
return obs_source_active(_ref);
|
|
}
|
|
|
|
/** Add a active reference (visible in main view).
|
|
*
|
|
* EXPORT void obs_source_inc_active(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void increment_active()
|
|
{
|
|
obs_source_inc_active(_ref);
|
|
}
|
|
|
|
/** Remove a active reference (visible in main view).
|
|
*
|
|
* EXPORT void obs_source_dec_active(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void decrement_active()
|
|
{
|
|
obs_source_dec_active(_ref);
|
|
}
|
|
|
|
/** Is the source visible in auxiliary views?
|
|
*
|
|
* EXPORT bool obs_source_showing(const obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE bool showing() const
|
|
{
|
|
return obs_source_showing(_ref);
|
|
}
|
|
|
|
/** Add a showing reference (visible in auxiliary view).
|
|
*
|
|
* EXPORT void obs_source_inc_showing(obs_source_t *source);
|
|
* EXPORT void obs_source_dec_showing(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void increment_showing()
|
|
{
|
|
obs_source_inc_showing(_ref);
|
|
}
|
|
|
|
/** Add a showing reference (visible in auxiliary view).
|
|
*
|
|
* EXPORT void obs_source_inc_showing(obs_source_t *source);
|
|
* EXPORT void obs_source_dec_showing(obs_source_t *source);
|
|
*/
|
|
FORCE_INLINE void decrement_showing()
|
|
{
|
|
obs_source_dec_showing(_ref);
|
|
}
|
|
|
|
public /* ToDo */:
|
|
|
|
/**
|
|
*
|
|
* EXPORT obs_missing_files_t* obs_source_get_missing_files(const obs_source_t *source);
|
|
*/
|
|
obs_missing_files_t* get_missing_files();
|
|
|
|
/**
|
|
*
|
|
* EXPORT void obs_source_replace_missing_file(obs_missing_file_cb cb, obs_source_t *source, const char *new_path, void *data);
|
|
*/
|
|
void replace_missing_file(obs_missing_file_cb cb, std::string_view path, void* data);
|
|
|
|
public:
|
|
FORCE_INLINE operator obs_source_t*() const
|
|
{
|
|
return _ref;
|
|
}
|
|
|
|
FORCE_INLINE obs_source_t* operator*() const
|
|
{
|
|
return _ref;
|
|
}
|
|
|
|
FORCE_INLINE operator bool() const
|
|
{
|
|
return _ref != nullptr;
|
|
};
|
|
|
|
FORCE_INLINE bool operator==(source const& rhs) const
|
|
{
|
|
return _ref == rhs._ref;
|
|
};
|
|
|
|
FORCE_INLINE bool operator<(source const& rhs) const
|
|
{
|
|
return _ref < rhs._ref;
|
|
};
|
|
|
|
FORCE_INLINE bool operator==(obs_source_t* const& rhs) const
|
|
{
|
|
return _ref == rhs;
|
|
};
|
|
};
|
|
} // namespace streamfx::obs
|