mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-23 20:05:11 +00:00
code: Migrate encoder::ffmpeg to modern handler loader
A different version of the dynamic loader allows us to simply register handlers at load time, instead of requiring custom code. Could also make it so that it loads them when needed, but since they're mostly static code, this won't matter much.
This commit is contained in:
parent
a1968b970b
commit
c4461e70b9
4 changed files with 125 additions and 156 deletions
|
@ -10,7 +10,6 @@
|
|||
#include "strings.hpp"
|
||||
#include "codecs/hevc.hpp"
|
||||
#include "ffmpeg/tools.hpp"
|
||||
#include "handlers/debug_handler.hpp"
|
||||
#include "obs/gs/gs-helper.hpp"
|
||||
#include "plugin.hpp"
|
||||
|
||||
|
@ -32,24 +31,6 @@ extern "C" {
|
|||
#include "warning-enable.hpp"
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_AMF
|
||||
#include "handlers/amf_h264_handler.hpp"
|
||||
#include "handlers/amf_hevc_handler.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_NVENC
|
||||
#include "handlers/nvenc_h264_handler.hpp"
|
||||
#include "handlers/nvenc_hevc_handler.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_PRORES
|
||||
#include "handlers/prores_aw_handler.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_DNXHR
|
||||
#include "handlers/dnxhd_handler.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "ffmpeg/hwapi/d3d11.hpp"
|
||||
#endif
|
||||
|
@ -176,7 +157,7 @@ ffmpeg_instance::~ffmpeg_instance()
|
|||
void ffmpeg_instance::get_properties(obs_properties_t* props)
|
||||
{
|
||||
if (_handler)
|
||||
_handler->get_properties(props, _codec, _context, _handler->is_hardware_encoder(_factory));
|
||||
_handler->properties(this->_factory, this, props);
|
||||
|
||||
obs_property_set_enabled(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVALTYPE), false);
|
||||
obs_property_set_enabled(obs_properties_get(props, ST_KEY_KEYFRAMES_INTERVAL_SECONDS), false);
|
||||
|
@ -189,7 +170,7 @@ void ffmpeg_instance::get_properties(obs_properties_t* props)
|
|||
void ffmpeg_instance::migrate(obs_data_t* settings, uint64_t version)
|
||||
{
|
||||
if (_handler)
|
||||
_handler->migrate(settings, version, _codec, _context);
|
||||
_handler->migrate(this->_factory, this, settings, version);
|
||||
}
|
||||
|
||||
bool ffmpeg_instance::update(obs_data_t* settings)
|
||||
|
@ -199,7 +180,7 @@ bool ffmpeg_instance::update(obs_data_t* settings)
|
|||
bool support_reconfig_gpu = false;
|
||||
bool support_reconfig_keyframes = false;
|
||||
if (_handler) {
|
||||
support_reconfig = _handler->supports_reconfigure(_factory, support_reconfig_threads, support_reconfig_gpu, support_reconfig_keyframes);
|
||||
support_reconfig = _handler->is_reconfigurable(_factory, support_reconfig_threads, support_reconfig_gpu, support_reconfig_keyframes);
|
||||
}
|
||||
|
||||
if (!_context->internal) {
|
||||
|
@ -245,7 +226,7 @@ bool ffmpeg_instance::update(obs_data_t* settings)
|
|||
|
||||
if (!_context->internal || (support_reconfig && support_reconfig_keyframes)) {
|
||||
// Keyframes
|
||||
if (_handler && _handler->has_keyframe_support(_factory)) {
|
||||
if (_handler && _handler->has_keyframes(_factory)) {
|
||||
// Key-Frame Options
|
||||
obs_video_info ovi;
|
||||
if (!obs_get_video_info(&ovi)) {
|
||||
|
@ -268,7 +249,7 @@ bool ffmpeg_instance::update(obs_data_t* settings)
|
|||
if (!_context->internal || support_reconfig) {
|
||||
// Handler Options
|
||||
if (_handler)
|
||||
_handler->update(settings, _codec, _context);
|
||||
_handler->update(this->_factory, this, settings);
|
||||
|
||||
{ // FFmpeg Custom Options
|
||||
const char* opts = obs_data_get_string(settings, ST_KEY_FFMPEG_CUSTOMSETTINGS);
|
||||
|
@ -279,7 +260,7 @@ bool ffmpeg_instance::update(obs_data_t* settings)
|
|||
|
||||
// Handler Overrides
|
||||
if (_handler)
|
||||
_handler->override_update(this, settings);
|
||||
_handler->override_update(this->_factory, this, settings);
|
||||
}
|
||||
|
||||
// Handler Logging
|
||||
|
@ -310,7 +291,7 @@ bool ffmpeg_instance::update(obs_data_t* settings)
|
|||
}
|
||||
|
||||
if (_handler) {
|
||||
_handler->log_options(settings, _codec, _context);
|
||||
_handler->log(this->_factory, this, settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -438,7 +419,7 @@ void ffmpeg_instance::initialize_sw(obs_data_t* settings)
|
|||
}
|
||||
|
||||
if (_handler) // Allow Handler to override the automatic color format for sanity reasons.
|
||||
_handler->override_colorformat(pix_fmt_target, settings, _codec, _context);
|
||||
_handler->override_colorformat(this->_factory, this, settings, pix_fmt_target);
|
||||
}
|
||||
|
||||
// Setup from OBS information.
|
||||
|
@ -634,8 +615,9 @@ int ffmpeg_instance::receive_packet(bool* received_packet, struct encoder_packet
|
|||
}
|
||||
|
||||
// Allow Handler Post-Processing
|
||||
if (_handler)
|
||||
_handler->process_avpacket(_packet, _codec, _context);
|
||||
//FIXME! Is this still necessary?
|
||||
//if (_handler)
|
||||
// _handler->process_avpacket(_packet, _codec, _context);
|
||||
|
||||
// Build packet for use in OBS.
|
||||
packet->type = OBS_ENCODER_VIDEO;
|
||||
|
@ -960,10 +942,10 @@ ffmpeg_factory::ffmpeg_factory(ffmpeg_manager* manager, const AVCodec* codec) :
|
|||
// Find any available handlers for this codec.
|
||||
if (_handler = manager->get_handler(_avcodec->name); _handler) {
|
||||
// Override any found info with the one specified by the handler.
|
||||
_handler->adjust_info(this, _avcodec, _id, _name, _codec);
|
||||
_handler->adjust_info(this, _id, _name, _codec);
|
||||
|
||||
// Add texture capability for hardware encoders.
|
||||
if (_handler->is_hardware_encoder(this)) {
|
||||
if (_handler->is_hardware(this)) {
|
||||
_info.caps |= OBS_ENCODER_CAP_PASS_TEXTURE;
|
||||
}
|
||||
} else {
|
||||
|
@ -1007,9 +989,9 @@ const char* ffmpeg_factory::get_name()
|
|||
void ffmpeg_factory::get_defaults2(obs_data_t* settings)
|
||||
{
|
||||
if (_handler) {
|
||||
_handler->get_defaults(settings, _avcodec, nullptr, _handler->is_hardware_encoder(this));
|
||||
_handler->defaults(this, settings);
|
||||
|
||||
if (_handler->has_keyframe_support(this)) {
|
||||
if (_handler->has_keyframes(this)) {
|
||||
obs_data_set_default_int(settings, ST_KEY_KEYFRAMES_INTERVALTYPE, 0);
|
||||
obs_data_set_default_double(settings, ST_KEY_KEYFRAMES_INTERVAL_SECONDS, 2.0);
|
||||
obs_data_set_default_int(settings, ST_KEY_KEYFRAMES_INTERVAL_FRAMES, 300);
|
||||
|
@ -1027,7 +1009,7 @@ void ffmpeg_factory::get_defaults2(obs_data_t* settings)
|
|||
void ffmpeg_factory::migrate(obs_data_t* data, uint64_t version)
|
||||
{
|
||||
if (_handler)
|
||||
_handler->migrate(data, version, _avcodec, nullptr);
|
||||
_handler->migrate(this, nullptr, data, version);
|
||||
}
|
||||
|
||||
static bool modified_keyframes(obs_properties_t* props, obs_property_t*, obs_data_t* settings) noexcept
|
||||
|
@ -1061,9 +1043,9 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
|
|||
}
|
||||
|
||||
if (_handler)
|
||||
_handler->get_properties(props, _avcodec, nullptr, _handler->is_hardware_encoder(this));
|
||||
_handler->properties(this, data, props);
|
||||
|
||||
if (_handler && _handler->has_keyframe_support(this)) {
|
||||
if (_handler && _handler->has_keyframes(this)) {
|
||||
// Key-Frame Options
|
||||
obs_properties_t* grp = props;
|
||||
if (!streamfx::util::are_property_groups_broken()) {
|
||||
|
@ -1099,11 +1081,11 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
|
|||
auto p = obs_properties_add_text(grp, ST_KEY_FFMPEG_CUSTOMSETTINGS, D_TRANSLATE(ST_I18N_FFMPEG_CUSTOMSETTINGS), obs_text_type::OBS_TEXT_DEFAULT);
|
||||
}
|
||||
|
||||
if (_handler && _handler->is_hardware_encoder(this)) {
|
||||
if (_handler && _handler->is_hardware(this)) {
|
||||
auto p = obs_properties_add_int(grp, ST_KEY_FFMPEG_GPU, D_TRANSLATE(ST_I18N_FFMPEG_GPU), -1, std::numeric_limits<uint8_t>::max(), 1);
|
||||
}
|
||||
|
||||
if (_handler && _handler->has_threading_support(this)) {
|
||||
if (_handler && _handler->has_threading(this)) {
|
||||
auto p = obs_properties_add_int_slider(grp, ST_KEY_FFMPEG_THREADS, D_TRANSLATE(ST_I18N_FFMPEG_THREADS), 0, static_cast<int64_t>(std::thread::hardware_concurrency()) * 2, 1);
|
||||
}
|
||||
|
||||
|
@ -1132,7 +1114,7 @@ obs_properties_t* ffmpeg_factory::get_properties2(instance_t* data)
|
|||
bool ffmpeg_factory::on_manual_open(obs_properties_t* props, obs_property_t* property, void* data)
|
||||
{
|
||||
ffmpeg_factory* ptr = static_cast<ffmpeg_factory*>(data);
|
||||
streamfx::open_url(ptr->_handler->get_help_url(ptr->_avcodec));
|
||||
streamfx::open_url(ptr->_handler->help(ptr));
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -1147,25 +1129,8 @@ obs_encoder_info* streamfx::encoder::ffmpeg::ffmpeg_factory::get_info()
|
|||
return &_info;
|
||||
}
|
||||
|
||||
ffmpeg_manager::ffmpeg_manager() : _factories(), _handlers(), _debug_handler()
|
||||
ffmpeg_manager::ffmpeg_manager() : _factories()
|
||||
{
|
||||
// Handlers
|
||||
_debug_handler = ::std::make_shared<handler::debug_handler>();
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_AMF
|
||||
register_handler("h264_amf", ::std::make_shared<handler::amf_h264_handler>());
|
||||
register_handler("hevc_amf", ::std::make_shared<handler::amf_hevc_handler>());
|
||||
#endif
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_NVENC
|
||||
register_handler("h264_nvenc", ::std::make_shared<handler::nvenc_h264_handler>());
|
||||
register_handler("hevc_nvenc", ::std::make_shared<handler::nvenc_hevc_handler>());
|
||||
#endif
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_PRORES
|
||||
register_handler("prores_aw", ::std::make_shared<handler::prores_aw_handler>());
|
||||
#endif
|
||||
#ifdef ENABLE_ENCODER_FFMPEG_DNXHR
|
||||
register_handler("dnxhd", ::std::make_shared<handler::dnxhd_handler>());
|
||||
#endif
|
||||
|
||||
// Encoders
|
||||
void* iterator = nullptr;
|
||||
for (const AVCodec* codec = av_codec_iterate(&iterator); codec != nullptr; codec = av_codec_iterate(&iterator)) {
|
||||
|
@ -1188,28 +1153,6 @@ 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_view codec)
|
||||
{
|
||||
return (_handlers.find(codec.data()) != _handlers.end());
|
||||
}
|
||||
|
||||
std::shared_ptr<ffmpeg_manager> ffmpeg_manager::instance()
|
||||
{
|
||||
static std::weak_ptr<ffmpeg_manager> winst;
|
||||
|
@ -1224,6 +1167,30 @@ std::shared_ptr<ffmpeg_manager> ffmpeg_manager::instance()
|
|||
return instance;
|
||||
}
|
||||
|
||||
streamfx::encoder::ffmpeg::handler* ffmpeg_manager::find_handler(std::string_view codec)
|
||||
{
|
||||
auto handlers = streamfx::encoder::ffmpeg::handler::handlers();
|
||||
if (auto kv = handlers.find(std::string{codec}); kv != handlers.end()) {
|
||||
return kv->second;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
if (auto kv = handlers.find(""); kv != handlers.end()) {
|
||||
return kv->second;
|
||||
}
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
streamfx::encoder::ffmpeg::handler* ffmpeg_manager::get_handler(std::string_view codec)
|
||||
{
|
||||
return find_handler(codec);
|
||||
}
|
||||
|
||||
bool ffmpeg_manager::has_handler(std::string_view codec)
|
||||
{
|
||||
return find_handler(codec) != nullptr;
|
||||
}
|
||||
|
||||
static std::shared_ptr<ffmpeg_manager> loader_instance;
|
||||
|
||||
static auto loader = streamfx::loader(
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
#pragma once
|
||||
#include "common.hpp"
|
||||
#include "encoders/ffmpeg/handler.hpp"
|
||||
#include "ffmpeg/avframe-queue.hpp"
|
||||
#include "ffmpeg/hwapi/base.hpp"
|
||||
#include "ffmpeg/swscale.hpp"
|
||||
#include "handlers/handler.hpp"
|
||||
#include "obs/obs-encoder-factory.hpp"
|
||||
|
||||
#include "warning-disable.hpp"
|
||||
|
@ -17,16 +17,15 @@
|
|||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "warning-enable.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "warning-disable.hpp"
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/frame.h>
|
||||
#include "warning-enable.hpp"
|
||||
}
|
||||
#include "warning-enable.hpp"
|
||||
|
||||
namespace streamfx::encoder::ffmpeg {
|
||||
class ffmpeg_instance;
|
||||
|
@ -38,7 +37,7 @@ namespace streamfx::encoder::ffmpeg {
|
|||
const AVCodec* _codec;
|
||||
AVCodecContext* _context;
|
||||
|
||||
std::shared_ptr<handler::handler> _handler;
|
||||
streamfx::encoder::ffmpeg::handler* _handler;
|
||||
|
||||
::streamfx::ffmpeg::swscale _scaler;
|
||||
std::shared_ptr<AVPacket> _packet;
|
||||
|
@ -116,7 +115,7 @@ namespace streamfx::encoder::ffmpeg {
|
|||
|
||||
const AVCodec* _avcodec;
|
||||
|
||||
std::shared_ptr<handler::handler> _handler;
|
||||
streamfx::encoder::ffmpeg::handler* _handler;
|
||||
|
||||
public:
|
||||
ffmpeg_factory(ffmpeg_manager* manager, const AVCodec* codec);
|
||||
|
@ -142,16 +141,14 @@ namespace streamfx::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);
|
||||
streamfx::encoder::ffmpeg::handler* find_handler(std::string_view codec);
|
||||
|
||||
std::shared_ptr<handler::handler> get_handler(std::string codec);
|
||||
streamfx::encoder::ffmpeg::handler* get_handler(std::string_view codec);
|
||||
|
||||
bool has_handler(std::string_view codec);
|
||||
|
||||
|
|
|
@ -1,41 +1,67 @@
|
|||
// AUTOGENERATED COPYRIGHT HEADER START
|
||||
// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
|
||||
// AUTOGENERATED COPYRIGHT HEADER END
|
||||
|
||||
#include "handler.hpp"
|
||||
#include "../encoder-ffmpeg.hpp"
|
||||
|
||||
using namespace streamfx::encoder::ffmpeg;
|
||||
streamfx::encoder::ffmpeg::handler::handler_map_t& streamfx::encoder::ffmpeg::handler::handlers()
|
||||
{
|
||||
static handler_map_t handlers;
|
||||
return handlers;
|
||||
}
|
||||
|
||||
bool handler::handler::has_keyframe_support(ffmpeg_factory* instance)
|
||||
streamfx::encoder::ffmpeg::handler::handler(std::string codec)
|
||||
{
|
||||
handlers().emplace(codec, this);
|
||||
}
|
||||
|
||||
bool streamfx::encoder::ffmpeg::handler::has_keyframes(ffmpeg_factory* factory)
|
||||
{
|
||||
#if LIBAVCODEC_VERSION_MAJOR > 58
|
||||
if (auto* desc = avcodec_descriptor_get(instance->get_avcodec()->id); desc) {
|
||||
if (auto* desc = avcodec_descriptor_get(factory->get_avcodec()->id); desc) {
|
||||
return (desc->props & AV_CODEC_PROP_INTRA_ONLY) == 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return (instance->get_avcodec()->capabilities & AV_CODEC_CAP_INTRA_ONLY) == 0;
|
||||
return (factory->get_avcodec()->capabilities & AV_CODEC_CAP_INTRA_ONLY) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool handler::handler::is_hardware_encoder(ffmpeg_factory* instance)
|
||||
bool streamfx::encoder::ffmpeg::handler::has_threading(ffmpeg_factory* factory)
|
||||
{
|
||||
return (factory->get_avcodec()->capabilities & (AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_OTHER_THREADS));
|
||||
}
|
||||
|
||||
bool streamfx::encoder::ffmpeg::handler::is_hardware(ffmpeg_factory* factory)
|
||||
{
|
||||
if (factory->get_avcodec()->capabilities & AV_CODEC_CAP_HARDWARE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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 handler::handler::has_pixel_format_support(ffmpeg_factory* instance)
|
||||
{
|
||||
return (instance->get_avcodec()->pix_fmts != nullptr);
|
||||
}
|
||||
|
||||
bool handler::handler::supports_reconfigure(ffmpeg_factory* instance, bool& threads, bool& gpu, bool& keyframes)
|
||||
bool streamfx::encoder::ffmpeg::handler::is_reconfigurable(ffmpeg_factory* factory, bool& threads, bool& gpu, bool& keyframes)
|
||||
{
|
||||
if (factory->get_avcodec()->capabilities & AV_CODEC_CAP_PARAM_CHANGE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::adjust_info(ffmpeg_factory* factory, std::string& id, std::string& name, std::string& codec) {}
|
||||
|
||||
std::string streamfx::encoder::ffmpeg::handler::help(ffmpeg_factory* factory) {
|
||||
return "about:blank";
|
||||
}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::defaults(ffmpeg_factory* factory, obs_data_t* settings) {}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props) {}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version) {}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) {}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) {}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings) {}
|
||||
|
||||
void streamfx::encoder::ffmpeg::handler::override_colorformat(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, AVPixelFormat target_format) {}
|
||||
|
|
|
@ -1,63 +1,42 @@
|
|||
// AUTOGENERATED COPYRIGHT HEADER START
|
||||
// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
|
||||
// AUTOGENERATED COPYRIGHT HEADER END
|
||||
|
||||
#pragma once
|
||||
#include "common.hpp"
|
||||
#include "ffmpeg/hwapi/base.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "warning-disable.hpp"
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
extern "C" {
|
||||
#include <obs.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include "warning-enable.hpp"
|
||||
}
|
||||
#include "warning-enable.hpp"
|
||||
|
||||
namespace streamfx::encoder::ffmpeg {
|
||||
struct ffmpeg_info;
|
||||
class ffmpeg_factory;
|
||||
class ffmpeg_instance;
|
||||
|
||||
namespace handler {
|
||||
class handler {
|
||||
public:
|
||||
virtual ~handler(){};
|
||||
struct handler {
|
||||
handler(std::string codec);
|
||||
|
||||
public /*factory*/:
|
||||
virtual void adjust_info(ffmpeg_factory* factory, const AVCodec* codec, std::string& id, std::string& name, std::string& codec_id){};
|
||||
virtual bool has_keyframes(ffmpeg_factory* factory);
|
||||
virtual bool has_threading(ffmpeg_factory* factory);
|
||||
virtual bool is_hardware(ffmpeg_factory* factory);
|
||||
virtual bool is_reconfigurable(ffmpeg_factory* factory, bool& threads, bool& gpu, bool& keyframes);
|
||||
|
||||
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context, bool hw_encode){};
|
||||
virtual void adjust_info(ffmpeg_factory* factory, std::string& id, std::string& name, std::string& codec);
|
||||
|
||||
virtual std::string_view get_help_url(const AVCodec* codec)
|
||||
{
|
||||
return "https://github.com/Xaymar/obs-StreamFX/wiki/Encoder-FFmpeg";
|
||||
};
|
||||
virtual std::string help(ffmpeg_factory* factory);
|
||||
|
||||
public /*support tests*/:
|
||||
virtual bool has_keyframe_support(ffmpeg_factory* instance);
|
||||
virtual void defaults(ffmpeg_factory* factory, obs_data_t* settings);
|
||||
virtual void properties(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_properties_t* props);
|
||||
virtual void migrate(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, uint64_t version);
|
||||
virtual void update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings);
|
||||
virtual void override_update(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings);
|
||||
virtual void log(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings);
|
||||
|
||||
virtual bool is_hardware_encoder(ffmpeg_factory* instance);
|
||||
virtual void override_colorformat(ffmpeg_factory* factory, ffmpeg_instance* instance, obs_data_t* settings, AVPixelFormat target_format);
|
||||
|
||||
virtual bool has_threading_support(ffmpeg_factory* instance);
|
||||
public:
|
||||
typedef std::map<std::string, handler*> handler_map_t;
|
||||
|
||||
virtual bool has_pixel_format_support(ffmpeg_factory* instance);
|
||||
|
||||
virtual bool supports_reconfigure(ffmpeg_factory* instance, bool& threads, bool& gpu, bool& keyframes);
|
||||
|
||||
public /*settings*/:
|
||||
virtual void get_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context, bool hw_encode){};
|
||||
|
||||
virtual void migrate(obs_data_t* settings, uint64_t version, const AVCodec* codec, AVCodecContext* context){};
|
||||
|
||||
virtual void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context){};
|
||||
|
||||
virtual void override_update(ffmpeg_instance* instance, obs_data_t* settings){};
|
||||
|
||||
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){};
|
||||
|
||||
virtual void process_avpacket(std::shared_ptr<AVPacket> packet, const AVCodec* codec, AVCodecContext* context){};
|
||||
};
|
||||
} // namespace handler
|
||||
static handler_map_t& handlers();
|
||||
};
|
||||
} // namespace streamfx::encoder::ffmpeg
|
||||
|
|
Loading…
Reference in a new issue