project: Refactor into namespace streamfx

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2020-04-05 18:52:06 +02:00 committed by Michael Fabian Dirks
parent 0feaeb1afc
commit d0941895ad
44 changed files with 810 additions and 694 deletions

View file

@ -25,6 +25,25 @@ State.Manual="Manual"
State.Automatic="Automatic"
State.Default="Default"
# Front-end
UI.Menu="StreamFX"
UI.Menu.Website="Visit the Website"
UI.Menu.Discord="Join the Discord"
UI.Menu.Github="Source Code on Github"
UI.Menu.ReportIssue="Report a Bug or Crash"
UI.Menu.RequestHelp="Request Help && Support"
UI.Menu.About="About StreamFX"
UI.About.Title="About StreamFX"
UI.About.Text="<html><head/><body><p>StreamFX is made possible by all the supporters on <a href='https://patreon.com/Xaymar'><span style='text-decoration: underline;'>Patreon</span></a>, on <a href='https://github.com/sponsors/xaymar'><span style='text-decoration: underline;'>Github Sponsors</span></a>, and anyone donating through <a href='https://paypal.me/Xaymar'><span style='text-decoration: underline;'>PayPal</span></a>. Additional thanks go out to all the translators helping out with the localization on <a href='https://crowdin.com/project/obs-stream-effects'><span style='text-decoration: underline;'>Crowdin</span></a>. You all are amazing!</p></body></html>"
UI.About.Role.Contributor="Contributor"
UI.About.Role.Translator="Translator"
UI.About.Role.Family="%s's Family"
UI.About.Role.Friend="%s's Friend"
UI.About.Role.Supporter.Github="Github Sponsor"
UI.About.Role.Supporter.Patreon="Patreon Supporter"
UI.About.Role.Supporter.Twitch="Twitch Subscriber"
UI.About.Role.Creator="Content Creator"
# Blur
Blur.Type.Box="Box"
Blur.Type.Box.Description="Box blur (named for its distinct shape) is a simple average over a number of pixels, resulting in a box like look."
@ -209,7 +228,7 @@ Filter.Nvidia.FaceTracking.ROI.Stability="Stability"
Filter.NVidia.FaceTracking.ROI.Stability.Description="Controls the responsiveness of the tracking filter to filter out noisy and/or bad results.\nValues closer to 0% will be quicker but more noisy, while values closer to 100% will be slower but noise free.\nDue to unique noise patterns of modern Webcams, there is no universal setting for this."
# Filter - SDF Effects
Filter.SDFEffects="Signed Distance Field Effects"
Filter.SDFEffects="SDF Effects"
Filter.SDFEffects.Shadow.Inner="Inner Shadow"
Filter.SDFEffects.Shadow.Inner.Description="Draw a shadow on the inside of the source?"
Filter.SDFEffects.Shadow.Inner.Range.Minimum="Inner Shadow Minimum Distance"

View file

@ -27,7 +27,7 @@
#define P_H264_PROFILE "Codec.H264.Profile"
#define P_H264_LEVEL "Codec.H264.Level"
namespace encoder::codec::h264 {
namespace streamfx::encoder::codec::h264 {
enum class profile {
CONSTRAINED_BASELINE,
BASELINE,
@ -60,4 +60,4 @@ namespace encoder::codec::h264 {
L6_2,
UNKNOWN = -1,
};
} // namespace encoder::codec::h264
} // namespace streamfx::encoder::codec::h264

View file

@ -22,7 +22,7 @@
#include "hevc.hpp"
#include "utility.hpp"
using namespace encoder::codec;
using namespace streamfx::encoder::codec;
enum class nal_unit_type : std::uint8_t { // 6 bits
TRAIL_N = 0,

View file

@ -28,7 +28,7 @@
#define P_HEVC_TIER "Codec.HEVC.Tier"
#define P_HEVC_LEVEL "Codec.HEVC.Level"
namespace encoder::codec::hevc {
namespace streamfx::encoder::codec::hevc {
enum class profile {
MAIN,
MAIN10,
@ -61,4 +61,4 @@ namespace encoder::codec::hevc {
void extract_header_sei(std::uint8_t* data, std::size_t sz_data, std::vector<std::uint8_t>& header,
std::vector<std::uint8_t>& sei);
} // namespace encoder::codec::hevc
} // namespace streamfx::encoder::codec::hevc

View file

@ -32,7 +32,7 @@
#define P_PRORES_PROFILE_AP4H "Codec.ProRes.Profile.AP4H"
#define P_PRORES_PROFILE_AP4X "Codec.ProRes.Profile.AP4X"
namespace encoder::codec::prores {
namespace streamfx::encoder::codec::prores {
enum class profile : std::int32_t {
APCO = 0,
Y422_PROXY = APCO,

View file

@ -72,67 +72,11 @@ extern "C" {
#define ST_KEYFRAMES_INTERVAL_FRAMES "FFmpegEncoder.KeyFrames.Interval.Frames"
#define KEY_KEYFRAMES_INTERVAL_FRAMES "KeyFrames.Interval.Frames"
using namespace encoder::ffmpeg;
using namespace streamfx::encoder::ffmpeg;
using namespace streamfx::encoder::codec;
enum class keyframe_type { SECONDS, FRAMES };
std::shared_ptr<ffmpeg_manager> encoder::ffmpeg::ffmpeg_manager::_instance;
ffmpeg_manager::ffmpeg_manager() : _factories(), _handlers(), _debug_handler()
{
// Handlers
_debug_handler = ::std::make_shared<handler::debug_handler>();
register_handler("prores_aw", ::std::make_shared<handler::prores_aw_handler>());
register_handler("h264_nvenc", ::std::make_shared<handler::nvenc_h264_handler>());
register_handler("hevc_nvenc", ::std::make_shared<handler::nvenc_hevc_handler>());
}
ffmpeg_manager::~ffmpeg_manager()
{
_factories.clear();
}
void ffmpeg_manager::register_handler(std::string codec, std::shared_ptr<handler::handler> handler)
{
_handlers.emplace(codec, handler);
}
std::shared_ptr<handler::handler> ffmpeg_manager::get_handler(std::string codec)
{
auto fnd = _handlers.find(codec);
if (fnd != _handlers.end())
return fnd->second;
#ifdef _DEBUG
return _debug_handler;
#else
return nullptr;
#endif
}
bool ffmpeg_manager::has_handler(std::string codec)
{
return (_handlers.find(codec) != _handlers.end());
}
void encoder::ffmpeg::ffmpeg_manager::register_encoders()
{
// Encoders
void* iterator = nullptr;
const AVCodec* codec = nullptr;
for (codec = av_codec_iterate(&iterator); codec != nullptr; codec = av_codec_iterate(&iterator)) {
if (!av_codec_is_encoder(codec))
continue;
if ((codec->type == AVMediaType::AVMEDIA_TYPE_AUDIO) || (codec->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) {
try {
auto factory = std::make_shared<ffmpeg_factory>(codec);
factory->register_encoder();
_factories.emplace(codec, factory);
} catch (...) {
}
}
}
}
static void* _create(obs_data_t* settings, obs_encoder_t* encoder) noexcept
try {
return reinterpret_cast<void*>(new ffmpeg_instance(settings, encoder));
@ -1152,8 +1096,8 @@ int ffmpeg_instance::receive_packet(bool* received_packet, struct encoder_packet
bfree(tmp_header);
bfree(tmp_sei);
} else if (_codec->id == AV_CODEC_ID_HEVC) {
::encoder::codec::hevc::extract_header_sei(_current_packet.data, static_cast<size_t>(_current_packet.size),
_extra_data, _sei_data);
hevc::extract_header_sei(_current_packet.data, static_cast<size_t>(_current_packet.size), _extra_data,
_sei_data);
} else if (_context->extradata != nullptr) {
_extra_data.resize(static_cast<size_t>(_context->extradata_size));
std::memcpy(_extra_data.data(), _context->extradata, static_cast<size_t>(_context->extradata_size));
@ -1406,3 +1350,78 @@ void ffmpeg_instance::parse_ffmpeg_commandline(std::string text)
}
}
}
ffmpeg_manager::ffmpeg_manager() : _factories(), _handlers(), _debug_handler()
{
// Handlers
_debug_handler = ::std::make_shared<handler::debug_handler>();
register_handler("prores_aw", ::std::make_shared<handler::prores_aw_handler>());
register_handler("h264_nvenc", ::std::make_shared<handler::nvenc_h264_handler>());
register_handler("hevc_nvenc", ::std::make_shared<handler::nvenc_hevc_handler>());
}
ffmpeg_manager::~ffmpeg_manager()
{
_factories.clear();
}
void ffmpeg_manager::register_handler(std::string codec, std::shared_ptr<handler::handler> handler)
{
_handlers.emplace(codec, handler);
}
std::shared_ptr<handler::handler> ffmpeg_manager::get_handler(std::string codec)
{
auto fnd = _handlers.find(codec);
if (fnd != _handlers.end())
return fnd->second;
#ifdef _DEBUG
return _debug_handler;
#else
return nullptr;
#endif
}
bool ffmpeg_manager::has_handler(std::string codec)
{
return (_handlers.find(codec) != _handlers.end());
}
void ffmpeg_manager::register_encoders()
{
// Encoders
void* iterator = nullptr;
const AVCodec* codec = nullptr;
for (codec = av_codec_iterate(&iterator); codec != nullptr; codec = av_codec_iterate(&iterator)) {
if (!av_codec_is_encoder(codec))
continue;
if ((codec->type == AVMediaType::AVMEDIA_TYPE_AUDIO) || (codec->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) {
try {
auto factory = std::make_shared<ffmpeg_factory>(codec);
factory->register_encoder();
_factories.emplace(codec, factory);
} catch (...) {
}
}
}
}
std::shared_ptr<ffmpeg_manager> _ffmepg_encoder_factory_instance = nullptr;
void streamfx::encoder::ffmpeg::ffmpeg_manager::initialize()
{
if (!_ffmepg_encoder_factory_instance) {
_ffmepg_encoder_factory_instance = std::make_shared<ffmpeg_manager>();
_ffmepg_encoder_factory_instance->register_encoders();
}
}
void streamfx::encoder::ffmpeg::ffmpeg_manager::finalize()
{
_ffmepg_encoder_factory_instance.reset();
}
std::shared_ptr<ffmpeg_manager> streamfx::encoder::ffmpeg::ffmpeg_manager::get()
{
return _ffmepg_encoder_factory_instance;
}

View file

@ -46,47 +46,9 @@ extern "C" {
#endif
}
namespace encoder::ffmpeg {
namespace streamfx::encoder::ffmpeg {
class ffmpeg_factory;
class ffmpeg_manager {
static ::std::shared_ptr<ffmpeg_manager> _instance;
public: // Singleton
static void initialize()
{
_instance = ::std::make_shared<ffmpeg_manager>();
_instance->register_encoders();
}
static void finalize()
{
_instance.reset();
}
static std::shared_ptr<ffmpeg_manager> get()
{
return _instance;
}
private:
std::map<const AVCodec*, std::shared_ptr<ffmpeg_factory>> _factories;
std::map<std::string, std::shared_ptr<handler::handler>> _handlers;
std::shared_ptr<handler::handler> _debug_handler;
public:
ffmpeg_manager();
~ffmpeg_manager();
void register_handler(std::string codec, std::shared_ptr<handler::handler> handler);
std::shared_ptr<handler::handler> get_handler(std::string codec);
bool has_handler(std::string codec);
void register_encoders();
};
struct ffmpeg_info {
std::string uid;
std::string codec;
@ -199,4 +161,29 @@ namespace encoder::ffmpeg {
void parse_ffmpeg_commandline(std::string text);
};
} // namespace encoder::ffmpeg
class ffmpeg_manager {
std::map<const AVCodec*, std::shared_ptr<ffmpeg_factory>> _factories;
std::map<std::string, std::shared_ptr<handler::handler>> _handlers;
std::shared_ptr<handler::handler> _debug_handler;
public:
ffmpeg_manager();
~ffmpeg_manager();
void register_handler(std::string codec, std::shared_ptr<handler::handler> handler);
std::shared_ptr<handler::handler> get_handler(std::string codec);
bool has_handler(std::string codec);
void register_encoders();
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<ffmpeg_manager> get();
};
} // namespace streamfx::encoder::ffmpeg

View file

@ -36,7 +36,7 @@ extern "C" {
#pragma warning(pop)
}
using namespace encoder::ffmpeg::handler;
using namespace streamfx::encoder::ffmpeg::handler;
void debug_handler::get_defaults(obs_data_t*, const AVCodec*, AVCodecContext*, bool) {}

View file

@ -22,7 +22,7 @@
#pragma once
#include "handler.hpp"
namespace encoder::ffmpeg::handler {
namespace streamfx::encoder::ffmpeg::handler {
class debug_handler : public handler {
public:
virtual ~debug_handler(){};
@ -35,4 +35,4 @@ namespace encoder::ffmpeg::handler {
virtual void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) override;
};
} // namespace encoder::ffmpeg::handler
} // namespace streamfx::encoder::ffmpeg::handler

View file

@ -22,42 +22,40 @@
#include "handler.hpp"
#include "../ffmpeg-encoder.hpp"
void encoder::ffmpeg::handler::handler::adjust_encoder_info(encoder::ffmpeg::ffmpeg_factory*, ffmpeg_info*,
ffmpeg_info*)
{}
using namespace streamfx::encoder::ffmpeg;
void encoder::ffmpeg::handler::handler::get_defaults(obs_data_t*, const AVCodec*, AVCodecContext*, bool) {}
void handler::handler::adjust_encoder_info(ffmpeg_factory*, ffmpeg_info*, ffmpeg_info*) {}
bool encoder::ffmpeg::handler::handler::has_keyframe_support(ffmpeg_factory* instance)
void handler::handler::get_defaults(obs_data_t*, const AVCodec*, AVCodecContext*, bool) {}
bool handler::handler::has_keyframe_support(ffmpeg_factory* instance)
{
return (instance->get_avcodec()->capabilities & AV_CODEC_CAP_INTRA_ONLY) == 0;
}
bool encoder::ffmpeg::handler::handler::is_hardware_encoder(ffmpeg_factory* instance)
bool handler::handler::is_hardware_encoder(ffmpeg_factory* instance)
{
return false;
}
bool encoder::ffmpeg::handler::handler::has_threading_support(ffmpeg_factory* instance)
bool handler::handler::has_threading_support(ffmpeg_factory* instance)
{
return (instance->get_avcodec()->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS));
}
bool encoder::ffmpeg::handler::handler::has_pixel_format_support(ffmpeg_factory* instance)
bool handler::handler::has_pixel_format_support(ffmpeg_factory* instance)
{
return (instance->get_avcodec()->pix_fmts != nullptr);
}
void encoder::ffmpeg::handler::handler::get_properties(obs_properties_t*, const AVCodec*, AVCodecContext*, bool) {}
void handler::handler::get_properties(obs_properties_t*, const AVCodec*, AVCodecContext*, bool) {}
void encoder::ffmpeg::handler::handler::update(obs_data_t*, const AVCodec*, AVCodecContext*) {}
void handler::handler::update(obs_data_t*, const AVCodec*, AVCodecContext*) {}
void encoder::ffmpeg::handler::handler::override_update(ffmpeg_instance*, obs_data_t*) {}
void handler::handler::override_update(ffmpeg_instance*, obs_data_t*) {}
void encoder::ffmpeg::handler::handler::log_options(obs_data_t*, const AVCodec*, AVCodecContext*) {}
void handler::handler::log_options(obs_data_t*, const AVCodec*, AVCodecContext*) {}
void encoder::ffmpeg::handler::handler::override_colorformat(AVPixelFormat&, obs_data_t*, const AVCodec*,
AVCodecContext*)
{}
void handler::handler::override_colorformat(AVPixelFormat&, obs_data_t*, const AVCodec*, AVCodecContext*) {}
void encoder::ffmpeg::handler::handler::process_avpacket(AVPacket&, const AVCodec*, AVCodecContext*) {}
void handler::handler::process_avpacket(AVPacket&, const AVCodec*, AVCodecContext*) {}

View file

@ -30,7 +30,7 @@ extern "C" {
#pragma warning(pop)
}
namespace encoder::ffmpeg {
namespace streamfx::encoder::ffmpeg {
struct ffmpeg_info;
class ffmpeg_factory;
class ffmpeg_instance;
@ -73,4 +73,4 @@ namespace encoder::ffmpeg {
virtual void process_avpacket(AVPacket& packet, const AVCodec* codec, AVCodecContext* context);
};
} // namespace handler
} // namespace encoder::ffmpeg
} // namespace streamfx::encoder::ffmpeg

View file

@ -43,8 +43,8 @@ extern "C" {
#define KEY_PROFILE "H264.Profile"
#define KEY_LEVEL "H264.Level"
using namespace encoder::ffmpeg::handler;
using namespace encoder::codec::h264;
using namespace streamfx::encoder::ffmpeg::handler;
using namespace streamfx::encoder::codec::h264;
std::map<profile, std::string> profiles{
{profile::BASELINE, "baseline"},
@ -75,22 +75,22 @@ void nvenc_h264_handler::get_defaults(obs_data_t* settings, const AVCodec* codec
obs_data_set_default_int(settings, KEY_LEVEL, static_cast<int64_t>(level::UNKNOWN));
}
bool encoder::ffmpeg::handler::nvenc_h264_handler::is_hardware_encoder(ffmpeg_factory* instance)
bool nvenc_h264_handler::has_keyframe_support(ffmpeg_factory*)
{
return true;
}
bool encoder::ffmpeg::handler::nvenc_h264_handler::has_threading_support(ffmpeg_factory* instance)
bool nvenc_h264_handler::is_hardware_encoder(ffmpeg_factory*)
{
return true;
}
bool nvenc_h264_handler::has_threading_support(ffmpeg_factory*)
{
return false;
}
bool encoder::ffmpeg::handler::nvenc_h264_handler::has_pixel_format_support(ffmpeg_factory* instance)
{
return true;
}
bool nvenc_h264_handler::has_keyframe_support(ffmpeg_instance*)
bool nvenc_h264_handler::has_pixel_format_support(ffmpeg_factory*)
{
return true;
}

View file

@ -29,7 +29,7 @@ extern "C" {
#pragma warning(pop)
}
namespace encoder::ffmpeg::handler {
namespace streamfx::encoder::ffmpeg::handler {
class nvenc_h264_handler : public handler {
public:
virtual ~nvenc_h264_handler(){};
@ -40,7 +40,7 @@ namespace encoder::ffmpeg::handler {
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode);
public /*support tests*/:
virtual bool has_keyframe_support(ffmpeg_instance* instance);
virtual bool has_keyframe_support(ffmpeg_factory* instance);
virtual bool is_hardware_encoder(ffmpeg_factory* instance);
@ -58,12 +58,9 @@ namespace encoder::ffmpeg::handler {
virtual void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
public /*instance*/:
//virtual void override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
private:
void get_encoder_properties(obs_properties_t* props, const AVCodec* codec);
void get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context);
};
} // namespace encoder::ffmpeg::handler
} // namespace streamfx::encoder::ffmpeg::handler

View file

@ -40,8 +40,8 @@ extern "C" {
#define KEY_TIER "H265.Tier"
#define KEY_LEVEL "H265.Level"
using namespace encoder::ffmpeg::handler;
using namespace encoder::codec::hevc;
using namespace streamfx::encoder::ffmpeg::handler;
using namespace streamfx::encoder::codec::hevc;
std::map<profile, std::string> profiles{
{profile::MAIN, "main"},
@ -76,7 +76,22 @@ void nvenc_hevc_handler::get_defaults(obs_data_t* settings, const AVCodec* codec
obs_data_set_default_int(settings, KEY_LEVEL, static_cast<int64_t>(level::UNKNOWN));
}
bool nvenc_hevc_handler::has_keyframe_support(ffmpeg_instance*)
bool nvenc_hevc_handler::has_keyframe_support(ffmpeg_factory*)
{
return true;
}
bool nvenc_hevc_handler::is_hardware_encoder(ffmpeg_factory* instance)
{
return true;
}
bool nvenc_hevc_handler::has_threading_support(ffmpeg_factory* instance)
{
return false;
}
bool nvenc_hevc_handler::has_pixel_format_support(ffmpeg_factory* instance)
{
return true;
}

View file

@ -29,7 +29,7 @@ extern "C" {
#pragma warning(pop)
}
namespace encoder::ffmpeg::handler {
namespace streamfx::encoder::ffmpeg::handler {
class nvenc_hevc_handler : public handler {
public:
virtual ~nvenc_hevc_handler(){};
@ -39,9 +39,16 @@ namespace encoder::ffmpeg::handler {
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode);
public /*settings*/:
virtual bool has_keyframe_support(ffmpeg_instance* instance);
public /*support tests*/:
virtual bool has_keyframe_support(ffmpeg_factory* instance);
virtual bool is_hardware_encoder(ffmpeg_factory* instance);
virtual bool has_threading_support(ffmpeg_factory* instance);
virtual bool has_pixel_format_support(ffmpeg_factory* instance);
public /*settings*/:
virtual void get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context,
bool hw_encode);
@ -51,12 +58,9 @@ namespace encoder::ffmpeg::handler {
virtual void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
public /*instance*/:
//virtual void override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
private:
void get_encoder_properties(obs_properties_t* props, const AVCodec* codec);
void get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context);
};
} // namespace encoder::ffmpeg::handler
} // namespace streamfx::encoder::ffmpeg::handler

View file

@ -97,8 +97,7 @@ extern "C" {
#define KEY_OTHER_ACCESSUNITDELIMITER "Other.AccessUnitDelimiter"
#define KEY_OTHER_DECODEDPICTUREBUFFERSIZE "Other.DecodedPictureBufferSize"
using namespace encoder::ffmpeg::handler;
using namespace ffmpeg;
using namespace streamfx::encoder::ffmpeg::handler;
std::map<nvenc::preset, std::string> nvenc::presets{
{nvenc::preset::DEFAULT, ST_PRESET_(Default)},
@ -713,6 +712,8 @@ void nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* c
void nvenc::log_options(obs_data_t*, const AVCodec* codec, AVCodecContext* context)
{
using namespace ::ffmpeg;
LOG_INFO("[%s] Nvidia NVENC:", codec->name);
tools::print_av_option_string(context, "preset", " Preset", [](int64_t v) {
preset val = static_cast<preset>(v);

View file

@ -42,9 +42,7 @@ extern "C" {
- CQ: Constant Quality (rc=vbr b=0 maxrate=0 qmin=0 qmax=51 cq=qp), this is basically CRF in X264.
*/
using namespace encoder::ffmpeg;
namespace encoder::ffmpeg::handler::nvenc {
namespace streamfx::encoder::ffmpeg::handler::nvenc {
enum class preset : int64_t {
DEFAULT,
SLOW,
@ -106,4 +104,4 @@ namespace encoder::ffmpeg::handler::nvenc {
void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
void log_options(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
} // namespace encoder::ffmpeg::handler::nvenc
} // namespace streamfx::encoder::ffmpeg::handler::nvenc

View file

@ -30,25 +30,22 @@ extern "C" {
#include <obs-module.h>
}
using namespace encoder::ffmpeg::handler;
using namespace streamfx::encoder::ffmpeg::handler;
using namespace streamfx::encoder::codec::prores;
void prores_aw_handler::override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec,
AVCodecContext*)
{
static const std::array<std::pair<encoder::codec::prores::profile, AVPixelFormat>,
static_cast<size_t>(encoder::codec::prores::profile::_COUNT)>
static const std::array<std::pair<profile, AVPixelFormat>, static_cast<size_t>(profile::_COUNT)>
profile_to_format_map{
std::pair{encoder::codec::prores::profile::APCO, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::APCS, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::APCN, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::APCH, AV_PIX_FMT_YUV422P10},
std::pair{encoder::codec::prores::profile::AP4H, AV_PIX_FMT_YUV444P10},
std::pair{encoder::codec::prores::profile::AP4X, AV_PIX_FMT_YUV444P10},
std::pair{profile::APCO, AV_PIX_FMT_YUV422P10}, std::pair{profile::APCS, AV_PIX_FMT_YUV422P10},
std::pair{profile::APCN, AV_PIX_FMT_YUV422P10}, std::pair{profile::APCH, AV_PIX_FMT_YUV422P10},
std::pair{profile::AP4H, AV_PIX_FMT_YUV444P10}, std::pair{profile::AP4X, AV_PIX_FMT_YUV444P10},
};
const std::int64_t profile_id = obs_data_get_int(settings, P_PRORES_PROFILE);
for (auto kv : profile_to_format_map) {
if (kv.first == static_cast<encoder::codec::prores::profile>(profile_id)) {
if (kv.first == static_cast<profile>(profile_id)) {
target_format = kv.second;
break;
}
@ -60,25 +57,25 @@ void prores_aw_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCod
obs_data_set_default_int(settings, P_PRORES_PROFILE, 0);
}
bool encoder::ffmpeg::handler::prores_aw_handler::has_pixel_format_support(ffmpeg_factory* instance)
bool prores_aw_handler::has_pixel_format_support(ffmpeg_factory* instance)
{
return false;
}
inline const char* profile_to_name(const AVProfile* ptr)
{
switch (static_cast<encoder::codec::prores::profile>(ptr->profile)) {
case encoder::codec::prores::profile::APCO:
switch (static_cast<profile>(ptr->profile)) {
case profile::APCO:
return D_TRANSLATE(P_PRORES_PROFILE_APCO);
case encoder::codec::prores::profile::APCS:
case profile::APCS:
return D_TRANSLATE(P_PRORES_PROFILE_APCS);
case encoder::codec::prores::profile::APCN:
case profile::APCN:
return D_TRANSLATE(P_PRORES_PROFILE_APCN);
case encoder::codec::prores::profile::APCH:
case profile::APCH:
return D_TRANSLATE(P_PRORES_PROFILE_APCH);
case encoder::codec::prores::profile::AP4H:
case profile::AP4H:
return D_TRANSLATE(P_PRORES_PROFILE_AP4H);
case encoder::codec::prores::profile::AP4X:
case profile::AP4X:
return D_TRANSLATE(P_PRORES_PROFILE_AP4X);
default:
return ptr->name;

View file

@ -29,7 +29,7 @@ extern "C" {
#pragma warning(pop)
}
namespace encoder::ffmpeg::handler {
namespace streamfx::encoder::ffmpeg::handler {
class prores_aw_handler : public handler {
public:
virtual ~prores_aw_handler(){};
@ -55,4 +55,4 @@ namespace encoder::ffmpeg::handler {
virtual void process_avpacket(AVPacket& packet, const AVCodec* codec, AVCodecContext* context) override;
};
} // namespace encoder::ffmpeg::handler
} // namespace streamfx::encoder::ffmpeg::handler

View file

@ -77,7 +77,7 @@
#define ST_MASK_ALPHA "Filter.Blur.Mask.Alpha"
#define ST_MASK_MULTIPLIER "Filter.Blur.Mask.Multiplier"
using namespace filter;
using namespace streamfx::filter::blur;
struct local_blur_type_t {
std::function<::gfx::blur::ifactory&()> fn;
@ -102,9 +102,7 @@ static std::map<std::string, local_blur_subtype_t> list_of_subtypes = {
{"zoom", {::gfx::blur::type::Zoom, S_BLUR_SUBTYPE_ZOOM}},
};
std::shared_ptr<blur::blur_factory> blur::blur_factory::factory_instance = nullptr;
blur::blur_instance::blur_instance(obs_data_t* settings, obs_source_t* self)
blur_instance::blur_instance(obs_data_t* settings, obs_source_t* self)
: obs::source_instance(settings, self), _source_rendered(false), _output_rendered(false)
{
{
@ -130,10 +128,10 @@ blur::blur_instance::blur_instance(obs_data_t* settings, obs_source_t* self)
update(settings);
}
blur::blur_instance::~blur_instance() {}
blur_instance::~blur_instance() {}
bool blur::blur_instance::apply_mask_parameters(gs::effect effect, gs_texture_t* original_texture,
gs_texture_t* blurred_texture)
bool blur_instance::apply_mask_parameters(gs::effect effect, gs_texture_t* original_texture,
gs_texture_t* blurred_texture)
{
if (effect.has_parameter("image_orig")) {
effect.get_parameter("image_orig").set_texture(original_texture);
@ -197,12 +195,12 @@ bool blur::blur_instance::apply_mask_parameters(gs::effect effect, gs_texture_t*
return true;
}
void blur::blur_instance::load(obs_data_t* settings)
void blur_instance::load(obs_data_t* settings)
{
update(settings);
}
void filter::blur::blur_instance::migrate(obs_data_t* settings, std::uint64_t version)
void blur_instance::migrate(obs_data_t* settings, std::uint64_t version)
{
// Now we use a fall-through switch to gradually upgrade each known version change.
switch (version) {
@ -240,7 +238,7 @@ void filter::blur::blur_instance::migrate(obs_data_t* settings, std::uint64_t ve
}
}
void blur::blur_instance::update(obs_data_t* settings)
void blur_instance::update(obs_data_t* settings)
{
{ // Blur Type
const char* blur_type = obs_data_get_string(settings, ST_TYPE);
@ -275,7 +273,7 @@ void blur::blur_instance::update(obs_data_t* settings)
{ // Masking
_mask.enabled = obs_data_get_bool(settings, ST_MASK);
if (_mask.enabled) {
_mask.type = static_cast<blur::mask_type>(obs_data_get_int(settings, ST_MASK_TYPE));
_mask.type = static_cast<mask_type>(obs_data_get_int(settings, ST_MASK_TYPE));
switch (_mask.type) {
case mask_type::Region:
_mask.region.left = float_t(obs_data_get_double(settings, ST_MASK_REGION_LEFT) / 100.0);
@ -306,7 +304,7 @@ void blur::blur_instance::update(obs_data_t* settings)
}
}
void blur::blur_instance::video_tick(float)
void blur_instance::video_tick(float)
{
// Blur
if (_blur) {
@ -355,7 +353,7 @@ void blur::blur_instance::video_tick(float)
_output_rendered = false;
}
void blur::blur_instance::video_render(gs_effect_t* effect)
void blur_instance::video_render(gs_effect_t* effect)
{
obs_source_t* parent = obs_filter_get_parent(this->_self);
obs_source_t* target = obs_filter_get_target(this->_self);
@ -534,7 +532,7 @@ void blur::blur_instance::video_render(gs_effect_t* effect)
}
}
blur::blur_factory::blur_factory()
blur_factory::blur_factory()
{
_info.id = "obs-stream-effects-filter-blur";
_info.type = OBS_SOURCE_TYPE_FILTER;
@ -544,14 +542,14 @@ blur::blur_factory::blur_factory()
finish_setup();
}
blur::blur_factory::~blur_factory() {}
blur_factory::~blur_factory() {}
const char* blur::blur_factory::get_name()
const char* blur_factory::get_name()
{
return D_TRANSLATE(ST);
}
void blur::blur_factory::get_defaults2(obs_data_t* settings)
void blur_factory::get_defaults2(obs_data_t* settings)
{
// Type, Subtype
obs_data_set_default_string(settings, ST_TYPE, "box");
@ -724,7 +722,7 @@ try {
}
{ // Masking
using namespace blur;
using namespace ::gfx::blur;
bool show_mask = obs_data_get_bool(settings, ST_MASK);
mask_type mtype = static_cast<mask_type>(obs_data_get_int(settings, ST_MASK_TYPE));
bool show_region = (mtype == mask_type::Region) && show_mask;
@ -751,7 +749,7 @@ try {
return false;
}
obs_properties_t* blur::blur_factory::get_properties2(blur::blur_instance* data)
obs_properties_t* blur_factory::get_properties2(blur_instance* data)
{
obs_properties_t* pr = obs_properties_create();
obs_property_t* p = NULL;
@ -870,7 +868,7 @@ obs_properties_t* blur::blur_factory::get_properties2(blur::blur_instance* data)
return pr;
}
std::string blur::blur_factory::translate_string(const char* format, ...)
std::string blur_factory::translate_string(const char* format, ...)
{
va_list vargs;
va_start(vargs, format);
@ -879,3 +877,21 @@ std::string blur::blur_factory::translate_string(const char* format, ...)
va_end(vargs);
return std::string(buffer.data(), buffer.data() + len);
}
std::shared_ptr<blur_factory> _filter_blur_factory_instance = nullptr;
void streamfx::filter::blur::blur_factory::initialize()
{
if (!_filter_blur_factory_instance)
_filter_blur_factory_instance = std::make_shared<blur_factory>();
}
void streamfx::filter::blur::blur_factory::finalize()
{
_filter_blur_factory_instance.reset();
}
std::shared_ptr<blur_factory> streamfx::filter::blur::blur_factory::get()
{
return _filter_blur_factory_instance;
}

View file

@ -31,7 +31,7 @@
#include "obs/gs/gs-texture.hpp"
#include "obs/obs-source-factory.hpp"
namespace filter::blur {
namespace streamfx::filter::blur {
enum class mask_type : int64_t {
Region,
Image,
@ -111,25 +111,6 @@ namespace filter::blur {
};
class blur_factory : public obs::source_factory<filter::blur::blur_factory, filter::blur::blur_instance> {
static std::shared_ptr<filter::blur::blur_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::blur::blur_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<blur_factory> get()
{
return factory_instance;
}
private:
std::vector<std::string> _translation_cache;
public:
@ -143,5 +124,12 @@ namespace filter::blur {
virtual obs_properties_t* get_properties2(filter::blur::blur_instance* data) override;
std::string translate_string(const char* format, ...);
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<blur_factory> get();
};
} // namespace filter::blur
} // namespace streamfx::filter::blur

View file

@ -74,12 +74,11 @@
#define MODE_LOG Log
#define MODE_LOG10 Log10
using namespace filter;
using namespace streamfx::filter::color_grade;
color_grade::color_grade_instance::~color_grade_instance() {}
color_grade_instance::~color_grade_instance() {}
color_grade::color_grade_instance::color_grade_instance(obs_data_t* data, obs_source_t* self)
: obs::source_instance(data, self)
color_grade_instance::color_grade_instance(obs_data_t* data, obs_source_t* self) : obs::source_instance(data, self)
{
{
char* file = obs_module_file("effects/color-grade.effect");
@ -123,14 +122,14 @@ float_t fix_gamma_value(double_t v)
}
}
void color_grade::color_grade_instance::load(obs_data_t* data)
void color_grade_instance::load(obs_data_t* data)
{
update(data);
}
void filter::color_grade::color_grade_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void color_grade_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void color_grade::color_grade_instance::update(obs_data_t* data)
void color_grade_instance::update(obs_data_t* data)
{
_lift.x = static_cast<float_t>(obs_data_get_double(data, ST_LIFT_(RED)) / 100.0);
_lift.y = static_cast<float_t>(obs_data_get_double(data, ST_LIFT_(GREEN)) / 100.0);
@ -166,13 +165,13 @@ void color_grade::color_grade_instance::update(obs_data_t* data)
_correction.w = static_cast<float_t>(obs_data_get_double(data, ST_CORRECTION_(CONTRAST)) / 100.0);
}
void color_grade::color_grade_instance::video_tick(float)
void color_grade_instance::video_tick(float)
{
_source_updated = false;
_grade_updated = false;
}
void color_grade::color_grade_instance::video_render(gs_effect_t* effect)
void color_grade_instance::video_render(gs_effect_t* effect)
{
// Grab initial values.
obs_source_t* parent = obs_filter_get_parent(_self);
@ -256,9 +255,7 @@ void color_grade::color_grade_instance::video_render(gs_effect_t* effect)
}
}
std::shared_ptr<color_grade::color_grade_factory> color_grade::color_grade_factory::factory_instance = nullptr;
color_grade::color_grade_factory::color_grade_factory()
color_grade_factory::color_grade_factory()
{
_info.id = "obs-stream-effects-filter-color-grade";
_info.type = OBS_SOURCE_TYPE_FILTER;
@ -268,14 +265,14 @@ color_grade::color_grade_factory::color_grade_factory()
finish_setup();
}
color_grade::color_grade_factory::~color_grade_factory() {}
color_grade_factory::~color_grade_factory() {}
const char* color_grade::color_grade_factory::get_name()
const char* color_grade_factory::get_name()
{
return D_TRANSLATE(ST);
}
void color_grade::color_grade_factory::get_defaults2(obs_data_t* data)
void color_grade_factory::get_defaults2(obs_data_t* data)
{
obs_data_set_default_string(data, ST_TOOL, ST_CORRECTION);
obs_data_set_default_double(data, ST_LIFT_(RED), 0);
@ -294,8 +291,8 @@ void color_grade::color_grade_factory::get_defaults2(obs_data_t* data)
obs_data_set_default_double(data, ST_OFFSET_(GREEN), 0.0);
obs_data_set_default_double(data, ST_OFFSET_(BLUE), 0.0);
obs_data_set_default_double(data, ST_OFFSET_(ALL), 0.0);
obs_data_set_default_int(data, ST_TINT_MODE, static_cast<int64_t>(color_grade::luma_mode::Linear));
obs_data_set_default_int(data, ST_TINT_DETECTION, static_cast<int64_t>(color_grade::detection_mode::YUV_SDR));
obs_data_set_default_int(data, ST_TINT_MODE, static_cast<int64_t>(luma_mode::Linear));
obs_data_set_default_int(data, ST_TINT_DETECTION, static_cast<int64_t>(detection_mode::YUV_SDR));
obs_data_set_default_double(data, ST_TINT_EXPONENT, 1.5);
obs_data_set_default_double(data, ST_TINT_(TONE_LOW, RED), 100.0);
obs_data_set_default_double(data, ST_TINT_(TONE_LOW, GREEN), 100.0);
@ -312,7 +309,7 @@ void color_grade::color_grade_factory::get_defaults2(obs_data_t* data)
obs_data_set_default_double(data, ST_CORRECTION_(CONTRAST), 100.0);
}
obs_properties_t* color_grade::color_grade_factory::get_properties2(color_grade_instance* data)
obs_properties_t* color_grade_factory::get_properties2(color_grade_instance* data)
{
obs_properties_t* pr = obs_properties_create();
@ -402,12 +399,11 @@ obs_properties_t* color_grade::color_grade_factory::get_properties2(color_grade_
{
auto p = obs_properties_add_list(grp, ST_TINT_MODE, D_TRANSLATE(ST_TINT_MODE), OBS_COMBO_TYPE_LIST,
OBS_COMBO_FORMAT_INT);
std::pair<const char*, color_grade::luma_mode> els[] = {
{ST_TINT_MODE_(MODE_LINEAR), color_grade::luma_mode::Linear},
{ST_TINT_MODE_(MODE_EXP), color_grade::luma_mode::Exp},
{ST_TINT_MODE_(MODE_EXP2), color_grade::luma_mode::Exp2},
{ST_TINT_MODE_(MODE_LOG), color_grade::luma_mode::Log},
{ST_TINT_MODE_(MODE_LOG10), color_grade::luma_mode::Log10}};
std::pair<const char*, luma_mode> els[] = {{ST_TINT_MODE_(MODE_LINEAR), luma_mode::Linear},
{ST_TINT_MODE_(MODE_EXP), luma_mode::Exp},
{ST_TINT_MODE_(MODE_EXP2), luma_mode::Exp2},
{ST_TINT_MODE_(MODE_LOG), luma_mode::Log},
{ST_TINT_MODE_(MODE_LOG10), luma_mode::Log10}};
for (auto kv : els) {
obs_property_list_add_int(p, D_TRANSLATE(kv.first), static_cast<int64_t>(kv.second));
}
@ -416,10 +412,10 @@ obs_properties_t* color_grade::color_grade_factory::get_properties2(color_grade_
{
auto p = obs_properties_add_list(grp, ST_TINT_DETECTION, D_TRANSLATE(ST_TINT_DETECTION),
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT);
std::pair<const char*, color_grade::detection_mode> els[] = {
{ST_TINT_DETECTION_(DETECTION_HSV), color_grade::detection_mode::HSV},
{ST_TINT_DETECTION_(DETECTION_HSL), color_grade::detection_mode::HSL},
{ST_TINT_DETECTION_(DETECTION_YUV_SDR), color_grade::detection_mode::YUV_SDR}};
std::pair<const char*, detection_mode> els[] = {
{ST_TINT_DETECTION_(DETECTION_HSV), detection_mode::HSV},
{ST_TINT_DETECTION_(DETECTION_HSL), detection_mode::HSL},
{ST_TINT_DETECTION_(DETECTION_YUV_SDR), detection_mode::YUV_SDR}};
for (auto kv : els) {
obs_property_list_add_int(p, D_TRANSLATE(kv.first), static_cast<int64_t>(kv.second));
}
@ -430,3 +426,21 @@ obs_properties_t* color_grade::color_grade_factory::get_properties2(color_grade_
return pr;
}
std::shared_ptr<color_grade_factory> _color_grade_factory_instance = nullptr;
void streamfx::filter::color_grade::color_grade_factory::initialize()
{
if (!_color_grade_factory_instance)
_color_grade_factory_instance = std::make_shared<color_grade_factory>();
}
void streamfx::filter::color_grade::color_grade_factory::finalize()
{
_color_grade_factory_instance.reset();
}
std::shared_ptr<color_grade_factory> streamfx::filter::color_grade::color_grade_factory::get()
{
return _color_grade_factory_instance;
}

View file

@ -26,7 +26,7 @@
#include "obs/obs-source-factory.hpp"
#include "plugin.hpp"
namespace filter::color_grade {
namespace streamfx::filter::color_grade {
enum class detection_mode {
HSV,
HSL,
@ -81,24 +81,6 @@ namespace filter::color_grade {
class color_grade_factory : public obs::source_factory<filter::color_grade::color_grade_factory,
filter::color_grade::color_grade_instance> {
static std::shared_ptr<filter::color_grade::color_grade_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::color_grade::color_grade_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<color_grade_factory> get()
{
return factory_instance;
}
public:
color_grade_factory();
virtual ~color_grade_factory();
@ -108,5 +90,12 @@ namespace filter::color_grade {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(color_grade_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<color_grade_factory> get();
};
} // namespace filter::color_grade
} // namespace streamfx::filter::color_grade

View file

@ -27,9 +27,9 @@
#define ST_SCALE "Filter.Displacement.Scale"
#define ST_SCALE_TYPE "Filter.Displacement.Scale.Type"
using namespace filter;
using namespace streamfx::filter::displacement;
displacement::displacement_instance::displacement_instance(obs_data_t* data, obs_source_t* context)
displacement_instance::displacement_instance(obs_data_t* data, obs_source_t* context)
: obs::source_instance(data, context)
{
std::string effect = "";
@ -44,17 +44,17 @@ displacement::displacement_instance::displacement_instance(obs_data_t* data, obs
update(data);
}
displacement::displacement_instance::~displacement_instance()
displacement_instance::~displacement_instance()
{
_texture.reset();
}
void displacement::displacement_instance::load(obs_data_t* settings)
void displacement_instance::load(obs_data_t* settings)
{
update(settings);
}
void filter::displacement::displacement_instance::migrate(obs_data_t* data, std::uint64_t version)
void displacement_instance::migrate(obs_data_t* data, std::uint64_t version)
{
switch (version & STREAMFX_MASK_COMPAT) {
case 0:
@ -66,7 +66,7 @@ void filter::displacement::displacement_instance::migrate(obs_data_t* data, std:
}
}
void displacement::displacement_instance::update(obs_data_t* settings)
void displacement_instance::update(obs_data_t* settings)
{
_scale[0] = _scale[1] = static_cast<float_t>(obs_data_get_double(settings, ST_SCALE));
_scale_type = static_cast<float_t>(obs_data_get_double(settings, ST_SCALE_TYPE) / 100.0);
@ -82,13 +82,13 @@ void displacement::displacement_instance::update(obs_data_t* settings)
}
}
void displacement::displacement_instance::video_tick(float_t)
void displacement_instance::video_tick(float_t)
{
_width = obs_source_get_base_width(_self);
_height = obs_source_get_base_height(_self);
}
void displacement::displacement_instance::video_render(gs_effect_t*)
void displacement_instance::video_render(gs_effect_t*)
{
if (!_texture) { // No displacement map, so just skip us for now.
obs_source_skip_video_filter(_self);
@ -110,14 +110,12 @@ void displacement::displacement_instance::video_render(gs_effect_t*)
obs_source_process_filter_end(_self, _effect.get_object(), _width, _height);
}
std::string displacement::displacement_instance::get_file()
std::string displacement_instance::get_file()
{
return _texture_file;
}
std::shared_ptr<displacement::displacement_factory> displacement::displacement_factory::factory_instance = nullptr;
displacement::displacement_factory::displacement_factory()
displacement_factory::displacement_factory()
{
_info.id = "obs-stream-effects-filter-displacement";
_info.type = OBS_SOURCE_TYPE_FILTER;
@ -127,14 +125,14 @@ displacement::displacement_factory::displacement_factory()
finish_setup();
}
displacement::displacement_factory::~displacement_factory() {}
displacement_factory::~displacement_factory() {}
const char* displacement::displacement_factory::get_name()
const char* displacement_factory::get_name()
{
return D_TRANSLATE(ST);
}
void displacement::displacement_factory::get_defaults2(obs_data_t* data)
void displacement_factory::get_defaults2(obs_data_t* data)
{
{
char* disp = obs_module_file("examples/normal-maps/neutral.png");
@ -146,7 +144,7 @@ void displacement::displacement_factory::get_defaults2(obs_data_t* data)
obs_data_set_default_double(data, ST_SCALE_TYPE, 0.0);
}
obs_properties_t* displacement::displacement_factory::get_properties2(displacement::displacement_instance* data)
obs_properties_t* displacement_factory::get_properties2(displacement_instance* data)
{
obs_properties_t* pr = obs_properties_create();
@ -175,3 +173,21 @@ obs_properties_t* displacement::displacement_factory::get_properties2(displaceme
return pr;
}
std::shared_ptr<displacement_factory> _filter_displacement_factory_instance = nullptr;
void streamfx::filter::displacement::displacement_factory::initialize()
{
if (!_filter_displacement_factory_instance)
_filter_displacement_factory_instance = std::make_shared<displacement_factory>();
}
void streamfx::filter::displacement::displacement_factory::finalize()
{
_filter_displacement_factory_instance.reset();
}
std::shared_ptr<displacement_factory> streamfx::filter::displacement::displacement_factory::get()
{
return _filter_displacement_factory_instance;
}

View file

@ -22,7 +22,7 @@
#include "obs/gs/gs-effect.hpp"
#include "obs/obs-source-factory.hpp"
namespace filter::displacement {
namespace streamfx::filter::displacement {
class displacement_instance : public obs::source_instance {
gs::effect _effect;
@ -52,24 +52,6 @@ namespace filter::displacement {
class displacement_factory : public obs::source_factory<filter::displacement::displacement_factory,
filter::displacement::displacement_instance> {
static std::shared_ptr<filter::displacement::displacement_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::displacement::displacement_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<displacement_factory> get()
{
return factory_instance;
}
public:
displacement_factory();
virtual ~displacement_factory();
@ -79,5 +61,12 @@ namespace filter::displacement {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(filter::displacement::displacement_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<displacement_factory> get();
};
} // namespace filter::displacement
} // namespace streamfx::filter::displacement

View file

@ -40,18 +40,16 @@
#define ST_CHANNEL_MULTIPLIER "Filter.DynamicMask.Channel.Multiplier"
#define ST_CHANNEL_INPUT "Filter.DynamicMask.Channel.Input"
using namespace filter;
using namespace streamfx::filter::dynamic_mask;
std::shared_ptr<dynamic_mask::dynamic_mask_factory> dynamic_mask::dynamic_mask_factory::factory_instance = nullptr;
static std::pair<dynamic_mask::channel, const char*> channel_translations[] = {
{dynamic_mask::channel::Red, S_CHANNEL_RED},
{dynamic_mask::channel::Green, S_CHANNEL_GREEN},
{dynamic_mask::channel::Blue, S_CHANNEL_BLUE},
{dynamic_mask::channel::Alpha, S_CHANNEL_ALPHA},
static std::pair<channel, const char*> channel_translations[] = {
{channel::Red, S_CHANNEL_RED},
{channel::Green, S_CHANNEL_GREEN},
{channel::Blue, S_CHANNEL_BLUE},
{channel::Alpha, S_CHANNEL_ALPHA},
};
dynamic_mask::dynamic_mask_instance::dynamic_mask_instance(obs_data_t* settings, obs_source_t* self)
dynamic_mask_instance::dynamic_mask_instance(obs_data_t* settings, obs_source_t* self)
: obs::source_instance(settings, self), _translation_map(), _effect(), _have_filter_texture(false), _filter_rt(),
_filter_texture(), _have_input_texture(false), _input(), _input_capture(), _input_texture(),
_have_final_texture(false), _final_rt(), _final_texture(), _channels(), _precalc()
@ -73,23 +71,23 @@ dynamic_mask::dynamic_mask_instance::dynamic_mask_instance(obs_data_t* settings,
update(settings);
}
dynamic_mask::dynamic_mask_instance::~dynamic_mask_instance() {}
dynamic_mask_instance::~dynamic_mask_instance() {}
void dynamic_mask::dynamic_mask_instance::load(obs_data_t* settings)
void dynamic_mask_instance::load(obs_data_t* settings)
{
update(settings);
}
void filter::dynamic_mask::dynamic_mask_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void dynamic_mask_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void dynamic_mask::dynamic_mask_instance::update(obs_data_t* settings)
void dynamic_mask_instance::update(obs_data_t* settings)
{
// Update source.
try {
_input = std::make_shared<obs::deprecated_source>(obs_data_get_string(settings, ST_INPUT));
_input_capture = std::make_shared<gfx::source_texture>(_input, _self);
_input->events.rename += std::bind(&dynamic_mask::dynamic_mask_instance::input_renamed, this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
_input->events.rename += std::bind(&dynamic_mask_instance::input_renamed, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
} catch (...) {
_input.reset();
_input_capture.reset();
@ -143,7 +141,7 @@ void dynamic_mask::dynamic_mask_instance::update(obs_data_t* settings)
}
}
void dynamic_mask::dynamic_mask_instance::save(obs_data_t* settings)
void dynamic_mask_instance::save(obs_data_t* settings)
{
if (_input) {
obs_data_set_string(settings, ST_INPUT, obs_source_get_name(_input->get()));
@ -174,16 +172,15 @@ void dynamic_mask::dynamic_mask_instance::save(obs_data_t* settings)
}
}
void dynamic_mask::dynamic_mask_instance::input_renamed(obs::deprecated_source*, std::string old_name,
std::string new_name)
void dynamic_mask_instance::input_renamed(obs::deprecated_source*, std::string old_name, std::string new_name)
{
obs_data_t* settings = obs_source_get_settings(_self);
obs_data_set_string(settings, ST_INPUT, new_name.c_str());
obs_source_update(_self, settings);
}
bool dynamic_mask::dynamic_mask_instance::modified(void*, obs_properties_t* properties, obs_property_t*,
obs_data_t* settings) noexcept
bool dynamic_mask_instance::modified(void*, obs_properties_t* properties, obs_property_t*,
obs_data_t* settings) noexcept
try {
channel mask = static_cast<channel>(obs_data_get_int(settings, ST_CHANNEL));
@ -208,14 +205,14 @@ try {
return false;
}
void dynamic_mask::dynamic_mask_instance::video_tick(float)
void dynamic_mask_instance::video_tick(float)
{
_have_input_texture = false;
_have_filter_texture = false;
_have_final_texture = false;
}
void dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_effect)
void dynamic_mask_instance::video_render(gs_effect_t* in_effect)
{
obs_source_t* parent = obs_filter_get_parent(_self);
obs_source_t* target = obs_filter_get_target(_self);
@ -350,7 +347,7 @@ void dynamic_mask::dynamic_mask_instance::video_render(gs_effect_t* in_effect)
}
}
dynamic_mask::dynamic_mask_factory::dynamic_mask_factory()
dynamic_mask_factory::dynamic_mask_factory()
{
_info.id = "obs-stream-effects-filter-dynamic-mask";
_info.type = OBS_SOURCE_TYPE_FILTER;
@ -360,16 +357,16 @@ dynamic_mask::dynamic_mask_factory::dynamic_mask_factory()
finish_setup();
}
dynamic_mask::dynamic_mask_factory::~dynamic_mask_factory() {}
dynamic_mask_factory::~dynamic_mask_factory() {}
const char* dynamic_mask::dynamic_mask_factory::get_name()
const char* dynamic_mask_factory::get_name()
{
return D_TRANSLATE(ST);
}
void dynamic_mask::dynamic_mask_factory::get_defaults2(obs_data_t* data)
void dynamic_mask_factory::get_defaults2(obs_data_t* data)
{
obs_data_set_default_int(data, ST_CHANNEL, static_cast<int64_t>(dynamic_mask::channel::Red));
obs_data_set_default_int(data, ST_CHANNEL, static_cast<int64_t>(channel::Red));
for (auto kv : channel_translations) {
obs_data_set_default_double(data, (std::string(ST_CHANNEL_VALUE) + "." + kv.second).c_str(), 1.0);
obs_data_set_default_double(data, (std::string(ST_CHANNEL_MULTIPLIER) + "." + kv.second).c_str(), 1.0);
@ -380,7 +377,7 @@ void dynamic_mask::dynamic_mask_factory::get_defaults2(obs_data_t* data)
}
}
obs_properties_t* dynamic_mask::dynamic_mask_factory::get_properties2(dynamic_mask::dynamic_mask_instance* data)
obs_properties_t* dynamic_mask_factory::get_properties2(dynamic_mask_instance* data)
{
obs_properties_t* props = obs_properties_create();
obs_property_t* p;
@ -450,7 +447,7 @@ obs_properties_t* dynamic_mask::dynamic_mask_factory::get_properties2(dynamic_ma
return props;
}
std::string dynamic_mask::dynamic_mask_factory::translate_string(const char* format, ...)
std::string dynamic_mask_factory::translate_string(const char* format, ...)
{
va_list vargs;
va_start(vargs, format);
@ -459,3 +456,21 @@ std::string dynamic_mask::dynamic_mask_factory::translate_string(const char* for
va_end(vargs);
return std::string(buffer.data(), buffer.data() + len);
}
std::shared_ptr<dynamic_mask_factory> _filter_dynamic_mask_factory_instance = nullptr;
void streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize()
{
if (!_filter_dynamic_mask_factory_instance)
_filter_dynamic_mask_factory_instance = std::make_shared<dynamic_mask_factory>();
}
void streamfx::filter::dynamic_mask::dynamic_mask_factory::finalize()
{
_filter_dynamic_mask_factory_instance.reset();
}
std::shared_ptr<dynamic_mask_factory> streamfx::filter::dynamic_mask::dynamic_mask_factory::get()
{
return _filter_dynamic_mask_factory_instance;
}

View file

@ -27,7 +27,7 @@
#include "obs/obs-source-tracker.hpp"
#include "obs/obs-source.hpp"
namespace filter::dynamic_mask {
namespace streamfx::filter::dynamic_mask {
enum class channel : std::int8_t { Invalid = -1, Red, Green, Blue, Alpha };
class dynamic_mask_instance : public obs::source_instance {
@ -75,31 +75,12 @@ namespace filter::dynamic_mask {
static bool modified(void* self, obs_properties_t* properties, obs_property_t* property,
obs_data_t* settings) noexcept;
void video_tick(float_t _time);
void video_render(gs_effect_t* effect);
virtual void video_tick(float_t _time) override;
virtual void video_render(gs_effect_t* effect) override;
};
class dynamic_mask_factory : public obs::source_factory<filter::dynamic_mask::dynamic_mask_factory,
filter::dynamic_mask::dynamic_mask_instance> {
static std::shared_ptr<filter::dynamic_mask::dynamic_mask_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::dynamic_mask::dynamic_mask_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<dynamic_mask_factory> get()
{
return factory_instance;
}
private:
std::list<std::string> _translation_cache;
public:
@ -113,5 +94,12 @@ namespace filter::dynamic_mask {
virtual obs_properties_t* get_properties2(filter::dynamic_mask::dynamic_mask_instance* data) override;
std::string translate_string(const char* format, ...);
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<dynamic_mask_factory> get();
};
} // namespace filter::dynamic_mask
} // namespace streamfx::filter::dynamic_mask

View file

@ -38,12 +38,14 @@
#define ST_ROI_STABILITY "Filter.Nvidia.FaceTracking.ROI.Stability"
#define SK_ROI_STABILITY "ROI.Stability"
using namespace streamfx::filter::nvidia;
void ar_feature_deleter(NvAR_FeatureHandle v)
{
filter::nvidia::face_tracking_factory::get()->get_ar()->destroy(v);
face_tracking_factory::get()->get_ar()->destroy(v);
}
filter::nvidia::face_tracking_instance::face_tracking_instance(obs_data_t* settings, obs_source_t* self)
face_tracking_instance::face_tracking_instance(obs_data_t* settings, obs_source_t* self)
: obs::source_instance(settings, self),
_rt_is_fresh(false), _rt(),
@ -93,13 +95,13 @@ filter::nvidia::face_tracking_instance::face_tracking_instance(obs_data_t* setti
async_initialize(nullptr);
}
filter::nvidia::face_tracking_instance::~face_tracking_instance()
face_tracking_instance::~face_tracking_instance()
{
_ar_library->image_dealloc(&_ar_image_temp);
_ar_library->image_dealloc(&_ar_image_bgr);
}
void filter::nvidia::face_tracking_instance::async_initialize(std::shared_ptr<void> ptr)
void face_tracking_instance::async_initialize(std::shared_ptr<void> ptr)
{
struct async_data {
std::shared_ptr<obs_weak_source_t> source;
@ -118,8 +120,8 @@ void filter::nvidia::face_tracking_instance::async_initialize(std::shared_ptr<vo
models_path.concat("\\");
data->models_path = models_path.string();
get_global_threadpool()->push(
std::bind(&filter::nvidia::face_tracking_instance::async_initialize, this, std::placeholders::_1), data);
streamfx::threadpool()->push(std::bind(&face_tracking_instance::async_initialize, this, std::placeholders::_1),
data);
} else {
std::shared_ptr<async_data> data = std::static_pointer_cast<async_data>(ptr);
@ -192,7 +194,7 @@ void filter::nvidia::face_tracking_instance::async_initialize(std::shared_ptr<vo
}
}
void filter::nvidia::face_tracking_instance::refresh_geometry()
void face_tracking_instance::refresh_geometry()
{ // Update Region of Interest Geometry.
std::unique_lock<std::mutex> lock(_roi_lock);
@ -231,7 +233,7 @@ void filter::nvidia::face_tracking_instance::refresh_geometry()
_roi_geom->update();
}
void filter::nvidia::face_tracking_instance::async_track(std::shared_ptr<void> ptr)
void face_tracking_instance::async_track(std::shared_ptr<void> ptr)
{
struct async_data {
std::shared_ptr<obs_weak_source_t> source;
@ -265,8 +267,8 @@ void filter::nvidia::face_tracking_instance::async_track(std::shared_ptr<void> p
}
// Push work
get_global_threadpool()->push(
std::bind(&filter::nvidia::face_tracking_instance::async_track, this, std::placeholders::_1), data);
streamfx::threadpool()->push(std::bind(&face_tracking_instance::async_track, this, std::placeholders::_1),
data);
} else {
std::shared_ptr<async_data> data = std::static_pointer_cast<async_data>(ptr);
@ -423,7 +425,7 @@ void filter::nvidia::face_tracking_instance::async_track(std::shared_ptr<void> p
}
}
void filter::nvidia::face_tracking_instance::roi_refresh()
void face_tracking_instance::roi_refresh()
{
double_t kalman_q = util::math::lerp<double_t>(1.0, 1e-6, _cfg_roi_stability);
double_t kalman_r = util::math::lerp<double_t>(std::numeric_limits<double_t>::epsilon(), 1e+2, _cfg_roi_stability);
@ -434,7 +436,7 @@ void filter::nvidia::face_tracking_instance::roi_refresh()
_roi_filters[3] = util::math::kalman1D<double_t>{kalman_q, kalman_r, 1.0, _roi_size.second};
}
void filter::nvidia::face_tracking_instance::roi_reset()
void face_tracking_instance::roi_reset()
{
_roi_center.first = static_cast<double_t>(_size.first / 2);
_roi_center.second = static_cast<double_t>(_size.second / 2);
@ -444,14 +446,14 @@ void filter::nvidia::face_tracking_instance::roi_reset()
roi_refresh();
}
void filter::nvidia::face_tracking_instance::load(obs_data_t* data)
void face_tracking_instance::load(obs_data_t* data)
{
update(data);
}
void filter::nvidia::face_tracking_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void face_tracking_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void filter::nvidia::face_tracking_instance::update(obs_data_t* data)
void face_tracking_instance::update(obs_data_t* data)
{
_cfg_roi_zoom = obs_data_get_double(data, SK_ROI_ZOOM) / 100.0;
_cfg_roi_offset.first = obs_data_get_double(data, SK_ROI_OFFSET_X) / 100.0;
@ -463,7 +465,7 @@ void filter::nvidia::face_tracking_instance::update(obs_data_t* data)
roi_refresh();
}
void filter::nvidia::face_tracking_instance::video_tick(float_t seconds)
void face_tracking_instance::video_tick(float_t seconds)
{
// If we aren't yet ready to do work, abort for now.
if (!_ar_loaded) {
@ -478,7 +480,7 @@ void filter::nvidia::face_tracking_instance::video_tick(float_t seconds)
_rt_is_fresh = false;
}
void filter::nvidia::face_tracking_instance::video_render(gs_effect_t* effect)
void face_tracking_instance::video_render(gs_effect_t* effect)
{
gs::debug_marker gdm_main{gs::debug_color_source, "%s", obs_source_get_name(_self)};
obs_source_t* filter_parent = obs_filter_get_parent(_self);
@ -528,7 +530,7 @@ void filter::nvidia::face_tracking_instance::video_render(gs_effect_t* effect)
}
#ifdef _DEBUG
bool filter::nvidia::face_tracking_instance::button_profile(obs_properties_t* props, obs_property_t* property)
bool face_tracking_instance::button_profile(obs_properties_t* props, obs_property_t* property)
{
LOG_INFO("%-22s: %-10s %-10s %-10s %-10s %-10s", "Task", "Total", "Count", "Average", "99.9%ile", "95.0%ile");
@ -550,10 +552,7 @@ bool filter::nvidia::face_tracking_instance::button_profile(obs_properties_t* pr
}
#endif
std::shared_ptr<filter::nvidia::face_tracking_factory> filter::nvidia::face_tracking_factory::factory_instance =
nullptr;
filter::nvidia::face_tracking_factory::face_tracking_factory()
face_tracking_factory::face_tracking_factory()
{
// Try and load CUDA.
_cuda = std::make_shared<::nvidia::cuda::cuda>();
@ -584,14 +583,14 @@ filter::nvidia::face_tracking_factory::face_tracking_factory()
finish_setup();
}
filter::nvidia::face_tracking_factory::~face_tracking_factory() {}
face_tracking_factory::~face_tracking_factory() {}
const char* filter::nvidia::face_tracking_factory::get_name()
const char* face_tracking_factory::get_name()
{
return D_TRANSLATE(ST);
}
void filter::nvidia::face_tracking_factory::get_defaults2(obs_data_t* data)
void face_tracking_factory::get_defaults2(obs_data_t* data)
{
obs_data_set_default_double(data, SK_ROI_ZOOM, 50.0);
obs_data_set_default_double(data, SK_ROI_OFFSET_X, 0.0);
@ -599,7 +598,7 @@ void filter::nvidia::face_tracking_factory::get_defaults2(obs_data_t* data)
obs_data_set_default_double(data, SK_ROI_STABILITY, 50.0);
}
obs_properties_t* filter::nvidia::face_tracking_factory::get_properties2(filter::nvidia::face_tracking_instance* data)
obs_properties_t* face_tracking_factory::get_properties2(face_tracking_instance* data)
{
obs_properties_t* pr = obs_properties_create();
@ -640,7 +639,7 @@ obs_properties_t* filter::nvidia::face_tracking_factory::get_properties2(filter:
obs_properties_add_button2(
pr, "Profile", "Profile",
[](obs_properties_t* props, obs_property_t* property, void* data) {
return reinterpret_cast<filter::nvidia::face_tracking_instance*>(data)->button_profile(props, property);
return reinterpret_cast<face_tracking_instance*>(data)->button_profile(props, property);
},
data);
}
@ -649,17 +648,38 @@ obs_properties_t* filter::nvidia::face_tracking_factory::get_properties2(filter:
return pr;
}
std::shared_ptr<::nvidia::cuda::cuda> filter::nvidia::face_tracking_factory::get_cuda()
std::shared_ptr<::nvidia::cuda::cuda> face_tracking_factory::get_cuda()
{
return _cuda;
}
std::shared_ptr<::nvidia::cuda::context> filter::nvidia::face_tracking_factory::get_cuda_context()
std::shared_ptr<::nvidia::cuda::context> face_tracking_factory::get_cuda_context()
{
return _cuda_ctx;
}
std::shared_ptr<::nvidia::ar::ar> filter::nvidia::face_tracking_factory::get_ar()
std::shared_ptr<::nvidia::ar::ar> face_tracking_factory::get_ar()
{
return _ar;
}
std::shared_ptr<face_tracking_factory> _filter_nvidia_face_tracking_factory_instance = nullptr;
void streamfx::filter::nvidia::face_tracking_factory::initialize()
{
try {
_filter_nvidia_face_tracking_factory_instance = std::make_shared<filter::nvidia::face_tracking_factory>();
} catch (const std::exception& ex) {
LOG_ERROR("<Nvidia Face Tracking Filter> %s", ex.what());
}
}
void streamfx::filter::nvidia::face_tracking_factory::finalize()
{
_filter_nvidia_face_tracking_factory_instance.reset();
}
std::shared_ptr<face_tracking_factory> streamfx::filter::nvidia::face_tracking_factory::get()
{
return _filter_nvidia_face_tracking_factory_instance;
}

View file

@ -34,7 +34,7 @@
#include "nvidia/cuda/nvidia-cuda-stream.hpp"
#include "nvidia/cuda/nvidia-cuda.hpp"
namespace filter::nvidia {
namespace streamfx::filter::nvidia {
class face_tracking_instance : public obs::source_instance {
// Filter Cache
bool _rt_is_fresh;
@ -121,30 +121,10 @@ namespace filter::nvidia {
class face_tracking_factory
: public obs::source_factory<filter::nvidia::face_tracking_factory, filter::nvidia::face_tracking_instance> {
static std::shared_ptr<filter::nvidia::face_tracking_factory> factory_instance;
std::shared_ptr<::nvidia::cuda::cuda> _cuda;
std::shared_ptr<::nvidia::cuda::context> _cuda_ctx;
std::shared_ptr<::nvidia::ar::ar> _ar;
public: // Singleton
static void initialize()
try {
factory_instance = std::make_shared<filter::nvidia::face_tracking_factory>();
} catch (const std::exception& ex) {
LOG_ERROR("<Nvidia Face Tracking Filter> %s", ex.what());
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<face_tracking_factory> get()
{
return factory_instance;
}
public:
face_tracking_factory();
virtual ~face_tracking_factory() override;
@ -160,5 +140,12 @@ namespace filter::nvidia {
std::shared_ptr<::nvidia::cuda::context> get_cuda_context();
std::shared_ptr<::nvidia::ar::ar> get_ar();
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<face_tracking_factory> get();
};
} // namespace filter::nvidia
} // namespace streamfx::filter::nvidia

View file

@ -65,11 +65,9 @@
#define ST_SDF_SCALE "Filter.SDFEffects.SDF.Scale"
#define ST_SDF_THRESHOLD "Filter.SDFEffects.SDF.Threshold"
using namespace filter;
using namespace streamfx::filter::sdf_effects;
std::shared_ptr<sdf_effects::sdf_effects_factory> sdf_effects::sdf_effects_factory::factory_instance = nullptr;
sdf_effects::sdf_effects_instance::sdf_effects_instance(obs_data_t* settings, obs_source_t* self)
sdf_effects_instance::sdf_effects_instance(obs_data_t* settings, obs_source_t* self)
: obs::source_instance(settings, self), _source_rendered(false), _sdf_scale(1.0), _sdf_threshold(),
_output_rendered(false), _inner_shadow(false), _inner_shadow_color(), _inner_shadow_range_min(),
_inner_shadow_range_max(), _inner_shadow_offset_x(), _inner_shadow_offset_y(), _outer_shadow(false),
@ -117,16 +115,16 @@ sdf_effects::sdf_effects_instance::sdf_effects_instance(obs_data_t* settings, ob
update(settings);
}
sdf_effects::sdf_effects_instance::~sdf_effects_instance() {}
sdf_effects_instance::~sdf_effects_instance() {}
void sdf_effects::sdf_effects_instance::load(obs_data_t* settings)
void sdf_effects_instance::load(obs_data_t* settings)
{
update(settings);
}
void filter::sdf_effects::sdf_effects_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void sdf_effects_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void sdf_effects::sdf_effects_instance::update(obs_data_t* data)
void sdf_effects_instance::update(obs_data_t* data)
{
{
_outer_shadow =
@ -261,7 +259,7 @@ void sdf_effects::sdf_effects_instance::update(obs_data_t* data)
_sdf_threshold = float_t(obs_data_get_double(data, ST_SDF_THRESHOLD) / 100.0);
}
void sdf_effects::sdf_effects_instance::video_tick(float)
void sdf_effects_instance::video_tick(float)
{
if (obs_source_t* target = obs_filter_get_target(_self); target != nullptr) {
_source_rendered = false;
@ -269,7 +267,7 @@ void sdf_effects::sdf_effects_instance::video_tick(float)
}
}
void sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect)
void sdf_effects_instance::video_render(gs_effect_t* effect)
{
obs_source_t* parent = obs_filter_get_parent(_self);
obs_source_t* target = obs_filter_get_target(_self);
@ -497,7 +495,7 @@ void sdf_effects::sdf_effects_instance::video_render(gs_effect_t* effect)
}
}
sdf_effects::sdf_effects_factory::sdf_effects_factory()
sdf_effects_factory::sdf_effects_factory()
{
_info.id = "obs-stream-effects-filter-sdf-effects";
_info.type = OBS_SOURCE_TYPE_FILTER;
@ -507,14 +505,14 @@ sdf_effects::sdf_effects_factory::sdf_effects_factory()
finish_setup();
}
sdf_effects::sdf_effects_factory::~sdf_effects_factory() {}
sdf_effects_factory::~sdf_effects_factory() {}
const char* sdf_effects::sdf_effects_factory::get_name()
const char* sdf_effects_factory::get_name()
{
return D_TRANSLATE(ST);
}
void sdf_effects::sdf_effects_factory::get_defaults2(obs_data_t* data)
void sdf_effects_factory::get_defaults2(obs_data_t* data)
{
obs_data_set_default_bool(data, ST_SHADOW_OUTER, false);
obs_data_set_default_int(data, ST_SHADOW_OUTER_COLOR, 0x00000000);
@ -655,7 +653,7 @@ try {
return true;
}
obs_properties_t* sdf_effects::sdf_effects_factory::get_properties2(sdf_effects::sdf_effects_instance* data)
obs_properties_t* sdf_effects_factory::get_properties2(sdf_effects_instance* data)
{
obs_properties_t* props = obs_properties_create();
obs_property_t* p = nullptr;
@ -781,3 +779,21 @@ obs_properties_t* sdf_effects::sdf_effects_factory::get_properties2(sdf_effects:
return props;
}
std::shared_ptr<sdf_effects_factory> _filter_sdf_effects_factory_instance = nullptr;
void streamfx::filter::sdf_effects::sdf_effects_factory::initialize()
{
if (!_filter_sdf_effects_factory_instance)
_filter_sdf_effects_factory_instance = std::make_shared<sdf_effects_factory>();
}
void streamfx::filter::sdf_effects::sdf_effects_factory::finalize()
{
_filter_sdf_effects_factory_instance.reset();
}
std::shared_ptr<sdf_effects_factory> streamfx::filter::sdf_effects::sdf_effects_factory::get()
{
return _filter_sdf_effects_factory_instance;
}

View file

@ -26,7 +26,7 @@
#include "obs/gs/gs-vertexbuffer.hpp"
#include "obs/obs-source-factory.hpp"
namespace filter::sdf_effects {
namespace streamfx::filter::sdf_effects {
class sdf_effects_instance : public obs::source_instance {
gs::effect _sdf_producer_effect;
gs::effect _sdf_consumer_effect;
@ -95,24 +95,6 @@ namespace filter::sdf_effects {
class sdf_effects_factory : public obs::source_factory<filter::sdf_effects::sdf_effects_factory,
filter::sdf_effects::sdf_effects_instance> {
static std::shared_ptr<filter::sdf_effects::sdf_effects_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::sdf_effects::sdf_effects_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<sdf_effects_factory> get()
{
return factory_instance;
}
public:
sdf_effects_factory();
virtual ~sdf_effects_factory();
@ -122,6 +104,13 @@ namespace filter::sdf_effects {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(filter::sdf_effects::sdf_effects_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<sdf_effects_factory> get();
};
} // namespace filter::sdf_effects
} // namespace streamfx::filter::sdf_effects

View file

@ -25,44 +25,45 @@
#define ST "Filter.Shader"
filter::shader::shader_instance::shader_instance(obs_data_t* data, obs_source_t* self)
: obs::source_instance(data, self)
using namespace streamfx::filter::shader;
shader_instance::shader_instance(obs_data_t* data, obs_source_t* self) : obs::source_instance(data, self)
{
_fx = std::make_shared<gfx::shader::shader>(self, gfx::shader::shader_mode::Filter);
_rt = std::make_shared<gs::rendertarget>(GS_RGBA, GS_ZS_NONE);
update(data);
}
filter::shader::shader_instance::~shader_instance() {}
shader_instance::~shader_instance() {}
std::uint32_t filter::shader::shader_instance::get_width()
std::uint32_t shader_instance::get_width()
{
return _fx->width();
}
std::uint32_t filter::shader::shader_instance::get_height()
std::uint32_t shader_instance::get_height()
{
return _fx->height();
}
void filter::shader::shader_instance::properties(obs_properties_t* props)
void shader_instance::properties(obs_properties_t* props)
{
_fx->properties(props);
}
void filter::shader::shader_instance::load(obs_data_t* data)
void shader_instance::load(obs_data_t* data)
{
update(data);
}
void filter::shader::shader_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void shader_instance::migrate(obs_data_t* data, std::uint64_t version) {}
void filter::shader::shader_instance::update(obs_data_t* data)
void shader_instance::update(obs_data_t* data)
{
_fx->update(data);
}
void filter::shader::shader_instance::video_tick(float_t sec_since_last)
void shader_instance::video_tick(float_t sec_since_last)
{
if (_fx->tick(sec_since_last)) {
obs_data_t* data = obs_source_get_settings(_self);
@ -77,7 +78,7 @@ void filter::shader::shader_instance::video_tick(float_t sec_since_last)
}
}
void filter::shader::shader_instance::video_render(gs_effect_t* effect)
void shader_instance::video_render(gs_effect_t* effect)
{
if (!_fx || !_fx->width() || !_fx->height()) {
obs_source_skip_video_filter(_self);
@ -123,9 +124,7 @@ void filter::shader::shader_instance::video_render(gs_effect_t* effect)
}
}
std::shared_ptr<filter::shader::shader_factory> filter::shader::shader_factory::factory_instance = nullptr;
filter::shader::shader_factory::shader_factory()
shader_factory::shader_factory()
{
_info.id = "obs-stream-effects-filter-shader";
_info.type = OBS_SOURCE_TYPE_FILTER;
@ -134,19 +133,19 @@ filter::shader::shader_factory::shader_factory()
finish_setup();
}
filter::shader::shader_factory::~shader_factory() {}
shader_factory::~shader_factory() {}
const char* filter::shader::shader_factory::get_name()
const char* shader_factory::get_name()
{
return D_TRANSLATE(ST);
}
void filter::shader::shader_factory::get_defaults2(obs_data_t* data)
void shader_factory::get_defaults2(obs_data_t* data)
{
gfx::shader::shader::defaults(data);
}
obs_properties_t* filter::shader::shader_factory::get_properties2(shader::shader_instance* data)
obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
{
auto pr = obs_properties_create();
obs_properties_set_param(pr, data, nullptr);
@ -157,3 +156,21 @@ obs_properties_t* filter::shader::shader_factory::get_properties2(shader::shader
return pr;
}
std::shared_ptr<shader_factory> _filter_shader_factory_instance = nullptr;
void streamfx::filter::shader::shader_factory::initialize()
{
if (!_filter_shader_factory_instance)
_filter_shader_factory_instance = std::make_shared<shader_factory>();
}
void streamfx::filter::shader::shader_factory::finalize()
{
_filter_shader_factory_instance.reset();
}
std::shared_ptr<shader_factory> streamfx::filter::shader::shader_factory::get()
{
return _filter_shader_factory_instance;
}

View file

@ -23,7 +23,7 @@
#include "obs/gs/gs-rendertarget.hpp"
#include "obs/obs-source-factory.hpp"
namespace filter::shader {
namespace streamfx::filter::shader {
class shader_instance : public obs::source_instance {
std::shared_ptr<gfx::shader::shader> _fx;
std::shared_ptr<gs::rendertarget> _rt;
@ -46,24 +46,6 @@ namespace filter::shader {
};
class shader_factory : public obs::source_factory<filter::shader::shader_factory, filter::shader::shader_instance> {
static std::shared_ptr<filter::shader::shader_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::shader::shader_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<shader_factory> get()
{
return factory_instance;
}
public:
shader_factory();
virtual ~shader_factory();
@ -73,5 +55,12 @@ namespace filter::shader {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(filter::shader::shader_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<shader_factory> get();
};
} // namespace filter::shader
} // namespace streamfx::filter::shader

View file

@ -64,7 +64,7 @@
#define ST_ROTATION_ORDER_ZYX "Filter.Transform.Rotation.Order.ZYX"
#define ST_MIPMAPPING "Filter.Transform.Mipmapping"
using namespace filter;
using namespace streamfx::filter::transform;
static const float_t farZ = 2097152.0f; // 2 pow 21
static const float_t nearZ = 1.0f / farZ;
@ -80,7 +80,7 @@ enum RotationOrder : int64_t {
ZYX,
};
transform::transform_instance::transform_instance(obs_data_t* data, obs_source_t* context)
transform_instance::transform_instance(obs_data_t* data, obs_source_t* context)
: obs::source_instance(data, context), _cache_rendered(), _mipmap_enabled(), _mipmap_strength(),
_mipmap_generator(), _source_rendered(), _source_size(), _update_mesh(), _rotation_order(),
_camera_orthographic(), _camera_fov()
@ -101,7 +101,7 @@ transform::transform_instance::transform_instance(obs_data_t* data, obs_source_t
update(data);
}
transform::transform_instance::~transform_instance()
transform_instance::~transform_instance()
{
_shear.reset();
_scale.reset();
@ -113,12 +113,12 @@ transform::transform_instance::~transform_instance()
_mipmap_texture.reset();
}
void transform::transform_instance::load(obs_data_t* settings)
void transform_instance::load(obs_data_t* settings)
{
update(settings);
}
void filter::transform::transform_instance::migrate(obs_data_t* data, std::uint64_t version)
void transform_instance::migrate(obs_data_t* data, std::uint64_t version)
{
switch (version & STREAMFX_MASK_COMPAT) {
case 0:
@ -127,7 +127,7 @@ void filter::transform::transform_instance::migrate(obs_data_t* data, std::uint6
}
}
void transform::transform_instance::update(obs_data_t* settings)
void transform_instance::update(obs_data_t* settings)
{
// Camera
_camera_orthographic = obs_data_get_int(settings, ST_CAMERA) == 0;
@ -156,7 +156,7 @@ void transform::transform_instance::update(obs_data_t* settings)
_update_mesh = true;
}
void transform::transform_instance::video_tick(float)
void transform_instance::video_tick(float)
{
std::uint32_t width = 0;
std::uint32_t height = 0;
@ -274,7 +274,7 @@ void transform::transform_instance::video_tick(float)
_source_rendered = false;
}
void transform::transform_instance::video_render(gs_effect_t* effect)
void transform_instance::video_render(gs_effect_t* effect)
{
obs_source_t* parent = obs_filter_get_parent(_self);
obs_source_t* target = obs_filter_get_target(_self);
@ -423,9 +423,7 @@ void transform::transform_instance::video_render(gs_effect_t* effect)
}
}
std::shared_ptr<transform::transform_factory> transform::transform_factory::factory_instance = nullptr;
transform::transform_factory::transform_factory()
transform_factory::transform_factory()
{
_info.id = "obs-stream-effects-filter-transform";
_info.type = OBS_SOURCE_TYPE_FILTER;
@ -435,14 +433,14 @@ transform::transform_factory::transform_factory()
finish_setup();
}
transform::transform_factory::~transform_factory() {}
transform_factory::~transform_factory() {}
const char* transform::transform_factory::get_name()
const char* transform_factory::get_name()
{
return D_TRANSLATE(ST);
}
void transform::transform_factory::get_defaults2(obs_data_t* settings)
void transform_factory::get_defaults2(obs_data_t* settings)
{
obs_data_set_default_int(settings, ST_CAMERA, (int64_t)CameraMode::Orthographic);
obs_data_set_default_double(settings, ST_CAMERA_FIELDOFVIEW, 90.0);
@ -489,7 +487,7 @@ try {
return true;
}
obs_properties_t* transform::transform_factory::get_properties2(transform::transform_instance* data)
obs_properties_t* transform_factory::get_properties2(transform_instance* data)
{
obs_properties_t* pr = obs_properties_create();
@ -617,3 +615,21 @@ obs_properties_t* transform::transform_factory::get_properties2(transform::trans
return pr;
}
std::shared_ptr<transform_factory> _filter_transform_factory_instance = nullptr;
void transform_factory::initialize()
{
if (!_filter_transform_factory_instance)
_filter_transform_factory_instance = std::make_shared<transform_factory>();
}
void transform_factory::finalize()
{
_filter_transform_factory_instance.reset();
}
std::shared_ptr<transform_factory> transform_factory::get()
{
return _filter_transform_factory_instance;
}

View file

@ -26,7 +26,7 @@
#include "obs/gs/gs-vertexbuffer.hpp"
#include "obs/obs-source-factory.hpp"
namespace filter::transform {
namespace streamfx::filter::transform {
class transform_instance : public obs::source_instance {
// Cache
bool _cache_rendered;
@ -74,24 +74,6 @@ namespace filter::transform {
class transform_factory
: public obs::source_factory<filter::transform::transform_factory, filter::transform::transform_instance> {
static std::shared_ptr<filter::transform::transform_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<filter::transform::transform_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<transform_factory> get()
{
return factory_instance;
}
public:
transform_factory();
virtual ~transform_factory() override;
@ -101,5 +83,12 @@ namespace filter::transform {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(filter::transform::transform_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<transform_factory> get();
};
} // namespace filter::transform
} // namespace streamfx::filter::transform

View file

@ -62,64 +62,78 @@
#include "transitions/transition-shader.hpp"
#endif
static std::shared_ptr<util::threadpool> global_threadpool;
static std::shared_ptr<util::threadpool> _threadpool;
MODULE_EXPORT bool obs_module_load(void)
try {
LOG_INFO("Loading Version %s", STREAMFX_VERSION_STRING);
global_threadpool = std::make_shared<util::threadpool>();
// Initialize Configuration
// Initialize global configuration.
streamfx::configuration::initialize();
// Initialize global Thread Pool.
_threadpool = std::make_shared<util::threadpool>();
// Initialize Source Tracker
obs::source_tracker::initialize();
// Encoders
// Encoders
{
#ifdef ENABLE_ENCODER_FFMPEG
encoder::ffmpeg::ffmpeg_manager::initialize();
using namespace streamfx::encoder::ffmpeg;
ffmpeg_manager::initialize();
#endif
}
// Filters
// Filters
{
using namespace streamfx::filter;
#ifdef ENABLE_FILTER_BLUR
filter::blur::blur_factory::initialize();
blur::blur_factory::initialize();
#endif
#ifdef ENABLE_FILTER_COLOR_GRADE
filter::color_grade::color_grade_factory::initialize();
color_grade::color_grade_factory::initialize();
#endif
#ifdef ENABLE_FILTER_DISPLACEMENT
filter::displacement::displacement_factory::initialize();
displacement::displacement_factory::initialize();
#endif
#ifdef ENABLE_FILTER_DYNAMIC_MASK
filter::dynamic_mask::dynamic_mask_factory::initialize();
dynamic_mask::dynamic_mask_factory::initialize();
#endif
#ifdef ENABLE_FILTER_NVIDIA_FACE_TRACKING
filter::nvidia::face_tracking_factory::initialize();
streamfx::filter::nvidia::face_tracking_factory::initialize();
#endif
#ifdef ENABLE_FILTER_SDF_EFFECTS
filter::sdf_effects::sdf_effects_factory::initialize();
sdf_effects::sdf_effects_factory::initialize();
#endif
#ifdef ENABLE_FILTER_SHADER
filter::shader::shader_factory::initialize();
shader::shader_factory::initialize();
#endif
#ifdef ENABLE_FILTER_TRANSFORM
filter::transform::transform_factory::initialize();
transform::transform_factory::initialize();
#endif
}
// Sources
// Sources
{
using namespace streamfx::source;
#ifdef ENABLE_SOURCE_MIRROR
source::mirror::mirror_factory::initialize();
mirror::mirror_factory::initialize();
#endif
#ifdef ENABLE_SOURCE_SHADER
source::shader::shader_factory::initialize();
shader::shader_factory::initialize();
#endif
}
// Transitions
// Transitions
{
using namespace streamfx::transition;
#ifdef ENABLE_TRANSITION_SHADER
transition::shader::shader_factory::initialize();
shader::shader_factory::initialize();
#endif
}
LOG_INFO("Loaded Version %s", STREAMFX_VERSION_STRING);
return true;
} catch (...) {
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
@ -131,61 +145,76 @@ try {
LOG_INFO("Unloading Version %s", STREAMFX_VERSION_STRING);
// Transitions
{
using namespace streamfx::transition;
#ifdef ENABLE_TRANSITION_SHADER
transition::shader::shader_factory::finalize();
shader::shader_factory::finalize();
#endif
}
// Sources
// Sources
{
using namespace streamfx::source;
#ifdef ENABLE_SOURCE_MIRROR
source::mirror::mirror_factory::finalize();
mirror::mirror_factory::finalize();
#endif
#ifdef ENABLE_SOURCE_SHADER
source::shader::shader_factory::finalize();
shader::shader_factory::finalize();
#endif
}
// Filters
// Filters
{
using namespace streamfx::filter;
#ifdef ENABLE_FILTER_BLUR
filter::blur::blur_factory::finalize();
blur::blur_factory::finalize();
#endif
#ifdef ENABLE_FILTER_COLOR_GRADE
filter::color_grade::color_grade_factory::finalize();
color_grade::color_grade_factory::finalize();
#endif
#ifdef ENABLE_FILTER_DISPLACEMENT
filter::displacement::displacement_factory::finalize();
displacement::displacement_factory::finalize();
#endif
#ifdef ENABLE_FILTER_DYNAMIC_MASK
filter::dynamic_mask::dynamic_mask_factory::finalize();
dynamic_mask::dynamic_mask_factory::finalize();
#endif
#ifdef ENABLE_FILTER_NVIDIA_FACE_TRACKING
filter::nvidia::face_tracking_factory::finalize();
streamfx::filter::nvidia::face_tracking_factory::finalize();
#endif
#ifdef ENABLE_FILTER_SDF_EFFECTS
filter::sdf_effects::sdf_effects_factory::finalize();
sdf_effects::sdf_effects_factory::finalize();
#endif
#ifdef ENABLE_FILTER_SHADER
filter::shader::shader_factory::finalize();
shader::shader_factory::finalize();
#endif
#ifdef ENABLE_FILTER_TRANSFORM
filter::transform::transform_factory::finalize();
transform::transform_factory::finalize();
#endif
}
// Encoders
// Encoders
{
#ifdef ENABLE_ENCODER_FFMPEG
encoder::ffmpeg::ffmpeg_manager::finalize();
using namespace streamfx::encoder::ffmpeg;
ffmpeg_manager::finalize();
#endif
}
// Finalize Source Tracker
obs::source_tracker::finalize();
// Finalize Thread Pool
_threadpool.reset();
// Finalize Configuration
streamfx::configuration::finalize();
global_threadpool.reset();
LOG_INFO("Unloaded Version %s", STREAMFX_VERSION_STRING);
} catch (...) {
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
}
std::shared_ptr<util::threadpool> get_global_threadpool()
std::shared_ptr<util::threadpool> streamfx::threadpool()
{
return global_threadpool;
return _threadpool;
}

View file

@ -20,5 +20,7 @@
#pragma once
#include "common.hpp"
// Threadpool
std::shared_ptr<util::threadpool> get_global_threadpool();
namespace streamfx {
// Threadpool
std::shared_ptr<util::threadpool> threadpool();
} // namespace streamfx

View file

@ -46,9 +46,9 @@
#define ST_SOURCE_AUDIO_LAYOUT ST_SOURCE_AUDIO ".Layout"
#define ST_SOURCE_AUDIO_LAYOUT_(x) ST_SOURCE_AUDIO_LAYOUT "." D_VSTR(x)
using namespace source;
using namespace streamfx::source::mirror;
source::mirror::mirror_audio_data::mirror_audio_data(const audio_data* audio, speaker_layout layout)
mirror_audio_data::mirror_audio_data(const audio_data* audio, speaker_layout layout)
{
// Build a clone of a packet.
audio_t* oad = obs_get_audio();
@ -71,32 +71,32 @@ source::mirror::mirror_audio_data::mirror_audio_data(const audio_data* audio, sp
}
}
mirror::mirror_instance::mirror_instance(obs_data_t* settings, obs_source_t* self)
mirror_instance::mirror_instance(obs_data_t* settings, obs_source_t* self)
: obs::source_instance(settings, self), _source(), _source_child(), _signal_rename(), _audio_enabled(false),
_audio_layout(SPEAKERS_UNKNOWN)
{}
mirror::mirror_instance::~mirror_instance()
mirror_instance::~mirror_instance()
{
release();
}
std::uint32_t mirror::mirror_instance::get_width()
std::uint32_t mirror_instance::get_width()
{
return _source_size.first;
}
std::uint32_t mirror::mirror_instance::get_height()
std::uint32_t mirror_instance::get_height()
{
return _source_size.second;
}
void mirror::mirror_instance::load(obs_data_t* data)
void mirror_instance::load(obs_data_t* data)
{
update(data);
}
void source::mirror::mirror_instance::migrate(obs_data_t* data, std::uint64_t version)
void mirror_instance::migrate(obs_data_t* data, std::uint64_t version)
{
switch (version) {
case 0:
@ -107,7 +107,7 @@ void source::mirror::mirror_instance::migrate(obs_data_t* data, std::uint64_t ve
}
}
void mirror::mirror_instance::update(obs_data_t* data)
void mirror_instance::update(obs_data_t* data)
{
// Audio
_audio_enabled = obs_data_get_bool(data, ST_SOURCE_AUDIO);
@ -117,7 +117,7 @@ void mirror::mirror_instance::update(obs_data_t* data)
acquire(obs_data_get_string(data, ST_SOURCE));
}
void mirror::mirror_instance::save(obs_data_t* data)
void mirror_instance::save(obs_data_t* data)
{
if (_source) {
obs_data_set_string(data, ST_SOURCE, obs_source_get_name(_source.get()));
@ -126,7 +126,7 @@ void mirror::mirror_instance::save(obs_data_t* data)
}
}
void mirror::mirror_instance::video_tick(float_t time)
void mirror_instance::video_tick(float_t time)
{
if (_source) {
_source_size.first = obs_source_get_width(_source.get());
@ -134,7 +134,7 @@ void mirror::mirror_instance::video_tick(float_t time)
}
}
void mirror::mirror_instance::video_render(gs_effect_t* effect)
void mirror_instance::video_render(gs_effect_t* effect)
{
if (!_source)
return;
@ -144,14 +144,14 @@ void mirror::mirror_instance::video_render(gs_effect_t* effect)
obs_source_video_render(_source.get());
}
void mirror::mirror_instance::enum_active_sources(obs_source_enum_proc_t cb, void* ptr)
void mirror_instance::enum_active_sources(obs_source_enum_proc_t cb, void* ptr)
{
if (!_source)
return;
cb(_self, _source.get(), ptr);
}
void source::mirror::mirror_instance::enum_all_sources(obs_source_enum_proc_t cb, void* ptr)
void mirror_instance::enum_all_sources(obs_source_enum_proc_t cb, void* ptr)
{
if (!_source)
return;
@ -159,7 +159,7 @@ void source::mirror::mirror_instance::enum_all_sources(obs_source_enum_proc_t cb
cb(_self, _source.get(), ptr);
}
void mirror::mirror_instance::acquire(std::string source_name)
void mirror_instance::acquire(std::string source_name)
try {
release();
@ -177,19 +177,19 @@ try {
// Listen to the rename event to update our own settings.
_signal_rename = std::make_shared<obs::source_signal_handler>("rename", _source);
_signal_rename->event.add(
std::bind(&source::mirror::mirror_instance::on_rename, this, std::placeholders::_1, std::placeholders::_2));
std::bind(&mirror_instance::on_rename, this, std::placeholders::_1, std::placeholders::_2));
// 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(&source::mirror::mirror_instance::on_audio, this, std::placeholders::_1,
_signal_audio->event.add(std::bind(&mirror_instance::on_audio, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3));
}
} catch (...) {
release();
}
void mirror::mirror_instance::release()
void mirror_instance::release()
{
_signal_audio.reset();
_signal_rename.reset();
@ -197,12 +197,12 @@ void mirror::mirror_instance::release()
_source.reset();
}
void source::mirror::mirror_instance::on_rename(std::shared_ptr<obs_source_t>, calldata*)
void mirror_instance::on_rename(std::shared_ptr<obs_source_t>, calldata*)
{
obs_source_save(_self);
}
void source::mirror::mirror_instance::on_audio(std::shared_ptr<obs_source_t>, const audio_data* audio, bool)
void mirror_instance::on_audio(std::shared_ptr<obs_source_t>, const audio_data* audio, bool)
{
// Immediately quit if there isn't any actual audio to send out.
if (!_audio_enabled) {
@ -252,11 +252,10 @@ void source::mirror::mirror_instance::on_audio(std::shared_ptr<obs_source_t>, co
}
// Create a clone of the audio data and push it to the thread pool.
get_global_threadpool()->push(
std::bind(&source::mirror::mirror_instance::audio_output, this, std::placeholders::_1), nullptr);
streamfx::threadpool()->push(std::bind(&mirror_instance::audio_output, this, std::placeholders::_1), nullptr);
}
void source::mirror::mirror_instance::audio_output(std::shared_ptr<void> data)
void mirror_instance::audio_output(std::shared_ptr<void> data)
{
std::unique_lock<std::mutex> ul(_audio_queue_lock);
while (_audio_queue.size() > 0) {
@ -265,9 +264,7 @@ void source::mirror::mirror_instance::audio_output(std::shared_ptr<void> data)
}
}
std::shared_ptr<mirror::mirror_factory> mirror::mirror_factory::factory_instance;
mirror::mirror_factory::mirror_factory()
mirror_factory::mirror_factory()
{
_info.id = "obs-stream-effects-source-mirror";
_info.type = OBS_SOURCE_TYPE_INPUT;
@ -278,14 +275,14 @@ mirror::mirror_factory::mirror_factory()
finish_setup();
}
mirror::mirror_factory::~mirror_factory() {}
mirror_factory::~mirror_factory() {}
const char* mirror::mirror_factory::get_name()
const char* mirror_factory::get_name()
{
return D_TRANSLATE(ST);
}
void mirror::mirror_factory::get_defaults2(obs_data_t* data)
void mirror_factory::get_defaults2(obs_data_t* data)
{
obs_data_set_default_string(data, ST_SOURCE, "");
obs_data_set_default_bool(data, ST_SOURCE_AUDIO, false);
@ -304,7 +301,7 @@ try {
return false;
}
obs_properties_t* mirror::mirror_factory::get_properties2(mirror::mirror_instance* data)
obs_properties_t* mirror_factory::get_properties2(mirror_instance* data)
{
obs_properties_t* pr = obs_properties_create();
obs_property_t* p = nullptr;
@ -363,3 +360,18 @@ obs_properties_t* mirror::mirror_factory::get_properties2(mirror::mirror_instanc
return pr;
}
std::shared_ptr<mirror_factory> _source_mirror_factory_instance;
void streamfx::source::mirror::mirror_factory::initialize()
{
if (!_source_mirror_factory_instance)
_source_mirror_factory_instance = std::make_shared<mirror_factory>();
}
void streamfx::source::mirror::mirror_factory::finalize() {}
std::shared_ptr<mirror_factory> streamfx::source::mirror::mirror_factory::get()
{
return std::shared_ptr<mirror_factory>();
}

View file

@ -32,7 +32,7 @@
#include "obs/obs-source.hpp"
#include "obs/obs-tools.hpp"
namespace source::mirror {
namespace streamfx::source::mirror {
struct mirror_audio_data {
mirror_audio_data(const audio_data*, speaker_layout);
@ -83,24 +83,6 @@ namespace source::mirror {
};
class mirror_factory : public obs::source_factory<source::mirror::mirror_factory, source::mirror::mirror_instance> {
static std::shared_ptr<source::mirror::mirror_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<source::mirror::mirror_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<mirror_factory> get()
{
return factory_instance;
}
public:
mirror_factory();
virtual ~mirror_factory() override;
@ -110,5 +92,12 @@ namespace source::mirror {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(source::mirror::mirror_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<mirror_factory> get();
};
} // namespace source::mirror
} // namespace streamfx::source::mirror

View file

@ -24,43 +24,43 @@
#define ST "Source.Shader"
using namespace source;
using namespace streamfx::source::shader;
shader::shader_instance::shader_instance(obs_data_t* data, obs_source_t* self) : obs::source_instance(data, self), _fx()
shader_instance::shader_instance(obs_data_t* data, obs_source_t* self) : obs::source_instance(data, self), _fx()
{
_fx = std::make_shared<gfx::shader::shader>(self, gfx::shader::shader_mode::Source);
_fx = std::make_shared<::gfx::shader::shader>(self, ::gfx::shader::shader_mode::Source);
update(data);
}
shader::shader_instance::~shader_instance() {}
shader_instance::~shader_instance() {}
std::uint32_t shader::shader_instance::get_width()
std::uint32_t shader_instance::get_width()
{
return _fx->width();
}
std::uint32_t shader::shader_instance::get_height()
std::uint32_t shader_instance::get_height()
{
return _fx->height();
}
void shader::shader_instance::properties(obs_properties_t* props)
void shader_instance::properties(obs_properties_t* props)
{
_fx->properties(props);
}
void shader::shader_instance::load(obs_data_t* data)
void shader_instance::load(obs_data_t* data)
{
_fx->update(data);
}
void shader::shader_instance::update(obs_data_t* data)
void shader_instance::update(obs_data_t* data)
{
_fx->update(data);
}
void shader::shader_instance::video_tick(float_t sec_since_last)
void shader_instance::video_tick(float_t sec_since_last)
{
if (_fx->tick(sec_since_last)) {
obs_data_t* data = obs_source_get_settings(_self);
@ -73,7 +73,7 @@ void shader::shader_instance::video_tick(float_t sec_since_last)
_fx->set_size(ovi.base_width, ovi.base_height);
}
void shader::shader_instance::video_render(gs_effect_t* effect)
void shader_instance::video_render(gs_effect_t* effect)
{
if (!_fx) {
return;
@ -83,9 +83,7 @@ void shader::shader_instance::video_render(gs_effect_t* effect)
_fx->render();
}
std::shared_ptr<shader::shader_factory> shader::shader_factory::factory_instance = nullptr;
shader::shader_factory::shader_factory()
shader_factory::shader_factory()
{
_info.id = "obs-stream-effects-source-shader";
_info.type = OBS_SOURCE_TYPE_INPUT;
@ -94,19 +92,19 @@ shader::shader_factory::shader_factory()
finish_setup();
}
shader::shader_factory::~shader_factory() {}
shader_factory::~shader_factory() {}
const char* shader::shader_factory::get_name()
const char* shader_factory::get_name()
{
return D_TRANSLATE(ST);
}
void shader::shader_factory::get_defaults2(obs_data_t* data)
void shader_factory::get_defaults2(obs_data_t* data)
{
gfx::shader::shader::defaults(data);
::gfx::shader::shader::defaults(data);
}
obs_properties_t* shader::shader_factory::get_properties2(shader::shader_instance* data)
obs_properties_t* shader_factory::get_properties2(shader_instance* data)
{
auto pr = obs_properties_create();
obs_properties_set_param(pr, data, nullptr);
@ -117,3 +115,21 @@ obs_properties_t* shader::shader_factory::get_properties2(shader::shader_instanc
return pr;
}
std::shared_ptr<shader_factory> _source_shader_factory_instance = nullptr;
void streamfx::source::shader::shader_factory::initialize()
{
if (!_source_shader_factory_instance)
_source_shader_factory_instance = std::make_shared<shader_factory>();
}
void streamfx::source::shader::shader_factory::finalize()
{
_source_shader_factory_instance.reset();
}
std::shared_ptr<shader_factory> streamfx::source::shader::shader_factory::get()
{
return _source_shader_factory_instance;
}

View file

@ -24,7 +24,7 @@
#include "obs/obs-source-factory.hpp"
#include "plugin.hpp"
namespace source::shader {
namespace streamfx::source::shader {
class shader_instance : public obs::source_instance {
std::shared_ptr<gfx::shader::shader> _fx;
@ -45,24 +45,6 @@ namespace source::shader {
};
class shader_factory : public obs::source_factory<source::shader::shader_factory, source::shader::shader_instance> {
static std::shared_ptr<source::shader::shader_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<source::shader::shader_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<shader_factory> get()
{
return factory_instance;
}
public:
shader_factory();
virtual ~shader_factory();
@ -72,5 +54,12 @@ namespace source::shader {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(source::shader::shader_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<shader_factory> get();
};
} // namespace source::shader
} // namespace streamfx::source::shader

View file

@ -24,7 +24,9 @@
#define ST "Transition.Shader"
transition::shader::shader_instance::shader_instance(obs_data_t* data, obs_source_t* self)
using namespace streamfx::transition::shader;
shader_instance::shader_instance(obs_data_t* data, obs_source_t* self)
: obs::source_instance(data, self), _is_main(false)
{
_fx = std::make_shared<gfx::shader::shader>(self, gfx::shader::shader_mode::Transition);
@ -32,34 +34,34 @@ transition::shader::shader_instance::shader_instance(obs_data_t* data, obs_sourc
update(data);
}
transition::shader::shader_instance::~shader_instance() {}
shader_instance::~shader_instance() {}
std::uint32_t transition::shader::shader_instance::get_width()
std::uint32_t shader_instance::get_width()
{
return _fx->width();
}
std::uint32_t transition::shader::shader_instance::get_height()
std::uint32_t shader_instance::get_height()
{
return _fx->height();
}
void transition::shader::shader_instance::properties(obs_properties_t* props)
void shader_instance::properties(obs_properties_t* props)
{
_fx->properties(props);
}
void transition::shader::shader_instance::load(obs_data_t* data)
void shader_instance::load(obs_data_t* data)
{
update(data);
}
void transition::shader::shader_instance::update(obs_data_t* data)
void shader_instance::update(obs_data_t* data)
{
_fx->update(data);
}
void transition::shader::shader_instance::video_tick(float_t sec_since_last)
void shader_instance::video_tick(float_t sec_since_last)
{
if (_fx->tick(sec_since_last)) {
obs_data_t* data = obs_source_get_settings(_self);
@ -73,7 +75,7 @@ void transition::shader::shader_instance::video_tick(float_t sec_since_last)
_fx->set_size(ovi.base_width, ovi.base_height);
}
void transition::shader::shader_instance::video_render(gs_effect_t* effect)
void shader_instance::video_render(gs_effect_t* effect)
{
if (!_fx) {
return;
@ -86,8 +88,7 @@ void transition::shader::shader_instance::video_render(gs_effect_t* effect)
});
}
void transition::shader::shader_instance::transition_render(gs_texture_t* a, gs_texture_t* b, float_t t,
std::uint32_t cx, std::uint32_t cy)
void shader_instance::transition_render(gs_texture_t* a, gs_texture_t* b, float_t t, std::uint32_t cx, std::uint32_t cy)
{
_fx->set_input_a(std::make_shared<::gs::texture>(a, false));
_fx->set_input_b(std::make_shared<::gs::texture>(b, false));
@ -96,22 +97,19 @@ void transition::shader::shader_instance::transition_render(gs_texture_t* a, gs_
_fx->render();
}
bool transition::shader::shader_instance::audio_render(uint64_t* ts_out, obs_source_audio_mix* audio_output,
std::uint32_t mixers, std::size_t channels,
std::size_t sample_rate)
bool shader_instance::audio_render(uint64_t* ts_out, obs_source_audio_mix* audio_output, std::uint32_t mixers,
std::size_t channels, std::size_t sample_rate)
{
return obs_transition_audio_render(
_self, ts_out, audio_output, mixers, channels, sample_rate, [](void*, float_t t) { return 1.0f - t; },
[](void*, float_t t) { return t; });
}
void transition::shader::shader_instance::transition_start() {}
void shader_instance::transition_start() {}
void transition::shader::shader_instance::transition_stop() {}
void shader_instance::transition_stop() {}
std::shared_ptr<transition::shader::shader_factory> transition::shader::shader_factory::factory_instance = nullptr;
transition::shader::shader_factory::shader_factory()
shader_factory::shader_factory()
{
_info.id = "obs-stream-effects-transition-shader";
_info.type = OBS_SOURCE_TYPE_TRANSITION;
@ -120,19 +118,19 @@ transition::shader::shader_factory::shader_factory()
finish_setup();
}
transition::shader::shader_factory::~shader_factory() {}
shader_factory::~shader_factory() {}
const char* transition::shader::shader_factory::get_name()
const char* shader_factory::get_name()
{
return D_TRANSLATE(ST);
}
void transition::shader::shader_factory::get_defaults2(obs_data_t* data)
void shader_factory::get_defaults2(obs_data_t* data)
{
gfx::shader::shader::defaults(data);
}
obs_properties_t* transition::shader::shader_factory::get_properties2(shader::shader_instance* data)
obs_properties_t* shader_factory::get_properties2(shader::shader_instance* data)
{
auto pr = obs_properties_create();
obs_properties_set_param(pr, data, nullptr);
@ -143,3 +141,21 @@ obs_properties_t* transition::shader::shader_factory::get_properties2(shader::sh
return pr;
}
std::shared_ptr<shader_factory> _transition_shader_factory_instance = nullptr;
void streamfx::transition::shader::shader_factory::initialize()
{
if (!_transition_shader_factory_instance)
_transition_shader_factory_instance = std::make_shared<shader_factory>();
}
void streamfx::transition::shader::shader_factory::finalize()
{
_transition_shader_factory_instance.reset();
}
std::shared_ptr<shader_factory> streamfx::transition::shader::shader_factory::get()
{
return _transition_shader_factory_instance;
}

View file

@ -24,7 +24,7 @@
#include "obs/obs-source-factory.hpp"
#include "plugin.hpp"
namespace transition::shader {
namespace streamfx::transition::shader {
class shader_instance : public obs::source_instance {
std::shared_ptr<gfx::shader::shader> _fx;
@ -54,26 +54,8 @@ namespace transition::shader {
virtual void transition_stop() override;
};
class shader_factory
: public obs::source_factory<transition::shader::shader_factory, transition::shader::shader_instance> {
static std::shared_ptr<transition::shader::shader_factory> factory_instance;
public: // Singleton
static void initialize()
{
factory_instance = std::make_shared<transition::shader::shader_factory>();
}
static void finalize()
{
factory_instance.reset();
}
static std::shared_ptr<shader_factory> get()
{
return factory_instance;
}
class shader_factory : public obs::source_factory<streamfx::transition::shader::shader_factory,
transition::shader::shader_instance> {
public:
shader_factory();
virtual ~shader_factory();
@ -83,5 +65,12 @@ namespace transition::shader {
virtual void get_defaults2(obs_data_t* data) override;
virtual obs_properties_t* get_properties2(transition::shader::shader_instance* data) override;
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<shader_factory> get();
};
} // namespace transition::shader
} // namespace streamfx::transition::shader

View file

@ -101,7 +101,8 @@ inline bool is_equal(T a, T b, T c)
std::chrono::nanoseconds util::profiler::percentile(double_t percentile, bool by_time)
{
uint64_t calls = count();
constexpr double_t edge = 0.00005;
uint64_t calls = count();
std::map<std::chrono::nanoseconds, size_t> copy_timings;
{
@ -119,7 +120,7 @@ std::chrono::nanoseconds util::profiler::percentile(double_t percentile, bool by
for (auto kv : copy_timings) {
double_t kv_pct = double_t((kv.first - smallest).count()) / double_t(variance.count());
if (is_equal(kv_pct, percentile, 0.00005) || (kv_pct > percentile)) {
if (is_equal(kv_pct, percentile, edge) || (kv_pct > percentile)) {
return std::chrono::nanoseconds(kv.first);
}
}
@ -136,7 +137,7 @@ std::chrono::nanoseconds util::profiler::percentile(double_t percentile, bool by
double_t percentile_last = double_t(accu_calls_last) / double_t(calls);
double_t percentile_now = double_t(accu_calls_now) / double_t(calls);
if (is_equal(percentile, percentile_now, 0.0005)
if (is_equal(percentile, percentile_now, edge)
|| ((percentile_last < percentile) && (percentile_now > percentile))) {
return std::chrono::nanoseconds(kv.first);
}