project: Fix support for avcodec version 58 and newer

This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-08-03 09:45:56 +02:00
parent f9e56d33f3
commit f5052f45c6
16 changed files with 113 additions and 79 deletions
+2 -2
View File
@@ -54,7 +54,7 @@ extern "C" {
enum class keyframe_type { Seconds, Frames };
obsffmpeg::encoder_factory::encoder_factory(AVCodec* codec) : avcodec_ptr(codec), info()
obsffmpeg::encoder_factory::encoder_factory(const AVCodec * codec) : avcodec_ptr(codec), info()
{
// Unique Id is FFmpeg name.
this->info.uid = avcodec_ptr->name;
@@ -419,7 +419,7 @@ void obsffmpeg::encoder_factory::get_properties(obs_properties_t* props)
};
}
AVCodec* obsffmpeg::encoder_factory::get_avcodec()
const AVCodec* obsffmpeg::encoder_factory::get_avcodec()
{
return this->avcodec_ptr;
}
+4 -4
View File
@@ -45,10 +45,10 @@ namespace obsffmpeg {
std::string readable_name;
obs_encoder_info oei;
} info;
AVCodec* avcodec_ptr;
const AVCodec* avcodec_ptr;
public:
encoder_factory(AVCodec* codec);
encoder_factory(const AVCodec * codec);
virtual ~encoder_factory();
void register_encoder();
@@ -59,14 +59,14 @@ namespace obsffmpeg {
void get_properties(obs_properties_t* props);
AVCodec* get_avcodec();
const AVCodec* get_avcodec();
};
class encoder {
obs_encoder_t* self;
encoder_factory* factory;
AVCodec* codec;
const AVCodec* codec;
AVCodecContext* context;
ffmpeg::avframe_queue frame_queue;
-9
View File
@@ -40,26 +40,17 @@ std::string ffmpeg::tools::translate_encoder_capabilities(int capabilities)
// Quality
{AV_CODEC_CAP_LOSSLESS, "Lossless"},
//{AV_CODEC_CAP_INTRA_ONLY, "I-Frames only"},
// Threading
//{AV_CODEC_CAP_FRAME_THREADS, "Frame-Threading"},
//{AV_CODEC_CAP_SLICE_THREADS, "Slice-Threading"},
//{AV_CODEC_CAP_AUTO_THREADS, "Automatic-Threading"},
// Features
{AV_CODEC_CAP_PARAM_CHANGE, "Dynamic Parameter Change"},
{AV_CODEC_CAP_SUBFRAMES, "Sub-Frames"},
{AV_CODEC_CAP_VARIABLE_FRAME_SIZE, "Variable Frame Size"},
{AV_CODEC_CAP_SMALL_LAST_FRAME, "Small Final Frame"},
//{AV_CODEC_CAP_DR1, "Uses get_buffer"},
//{AV_CODEC_CAP_DELAY, "Requires Flush"},
// Other
{AV_CODEC_CAP_TRUNCATED, "Truncated"},
{AV_CODEC_CAP_CHANNEL_CONF, "AV_CODEC_CAP_CHANNEL_CONF"},
{AV_CODEC_CAP_DRAW_HORIZ_BAND, "AV_CODEC_CAP_DRAW_HORIZ_BAND"},
{AV_CODEC_CAP_HWACCEL_VDPAU, "AV_CODEC_CAP_HWACCEL_VDPAU"},
{AV_CODEC_CAP_AVOID_PROBING, "AV_CODEC_CAP_AVOID_PROBING"},
};
+33 -4
View File
@@ -20,12 +20,12 @@
// SOFTWARE.
#include "plugin.hpp"
#include <map>
#include <memory>
#include "encoder.hpp"
#include "ui/debug_handler.hpp"
#include "ui/handler.hpp"
#include "utility.hpp"
#include <map>
extern "C" {
#include <obs-module.h>
@@ -64,12 +64,18 @@ bool obsffmpeg::has_codec_handler(std::string const codec)
return (found != codec_to_handler_map.end());
}
static std::map<AVCodec*, std::shared_ptr<obsffmpeg::encoder_factory>> generic_factories;
static std::map<const AVCodec*, std::shared_ptr<obsffmpeg::encoder_factory>> generic_factories;
#pragma warning(push)
#pragma warning(disable : 4996) // Handled by software and precompiler branch
MODULE_EXPORT bool obs_module_load(void)
try {
#if FF_API_NEXT
if (avcodec_version() < AV_VERSION_INT(58, 0, 0)) {
// Initialize avcodec.
avcodec_register_all();
}
#endif
// Run all initializers.
for (auto const func : obsffmpeg::initializers) {
@@ -77,17 +83,40 @@ try {
}
// Register all codecs.
#if FF_API_NEXT
if (avcodec_version() < AV_VERSION_INT(58, 0, 0)) {
AVCodec* cdc = nullptr;
while ((cdc = av_codec_next(cdc)) != nullptr) {
if (!av_codec_is_encoder(cdc))
continue;
if ((cdc->type == AVMediaType::AVMEDIA_TYPE_AUDIO) || (cdc->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) {
if ((cdc->type == AVMediaType::AVMEDIA_TYPE_AUDIO)
|| (cdc->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) {
auto ptr = std::make_shared<obsffmpeg::encoder_factory>(cdc);
ptr->register_encoder();
generic_factories.emplace(cdc, ptr);
}
}
} else {
#endif
#if LIBAVCODEC_VERSION_MAJOR >= 58
void* storage = nullptr;
const AVCodec* cdc = nullptr;
for (cdc = av_codec_iterate(&storage); cdc != nullptr; cdc = av_codec_iterate(&storage)) {
if (!av_codec_is_encoder(cdc))
continue;
if ((cdc->type == AVMediaType::AVMEDIA_TYPE_AUDIO)
|| (cdc->type == AVMediaType::AVMEDIA_TYPE_VIDEO)) {
auto ptr = std::make_shared<obsffmpeg::encoder_factory>(cdc);
ptr->register_encoder();
generic_factories.emplace(cdc, ptr);
}
}
#endif
#if FF_API_NEXT
}
#endif
return true;
} catch (std::exception& ex) {
@@ -97,10 +126,10 @@ try {
PLOG_ERROR("Unrecognized exception during initalization.");
return false;
}
#pragma warning(pop)
MODULE_EXPORT void obs_module_unload(void)
try {
// Run all finalizers.
for (auto const func : obsffmpeg::finalizers) {
func();
+3 -3
View File
@@ -35,7 +35,7 @@ extern "C" {
#pragma warning(pop)
}
void obsffmpeg::ui::debug_handler::get_defaults(obs_data_t*, AVCodec*, AVCodecContext*) {}
void obsffmpeg::ui::debug_handler::get_defaults(obs_data_t*, const AVCodec*, AVCodecContext*) {}
template<typename T>
std::string to_string(T value){};
@@ -64,7 +64,7 @@ std::string to_string(double_t value)
return std::string(buf.data(), buf.data() + buf.size());
}
void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t*, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t*, const AVCodec* codec, AVCodecContext* context)
{
if (context)
return;
@@ -206,4 +206,4 @@ void obsffmpeg::ui::debug_handler::get_properties(obs_properties_t*, AVCodec* co
}
}
void obsffmpeg::ui::debug_handler::update(obs_data_t*, AVCodec*, AVCodecContext*) {}
void obsffmpeg::ui::debug_handler::update(obs_data_t*, const AVCodec*, AVCodecContext*) {}
+4 -3
View File
@@ -26,13 +26,14 @@ namespace obsffmpeg {
namespace ui {
class debug_handler : public handler {
public:
virtual void get_defaults(obs_data_t* settings, AVCodec* codec,
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_properties(obs_properties_t* props, AVCodec* codec,
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
virtual void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
};
} // namespace ui
} // namespace obsffmpeg
+1 -1
View File
@@ -21,4 +21,4 @@
#include "handler.hpp"
void obsffmpeg::ui::handler::override_visible_name(AVCodec* codec, std::string& name) {}
void obsffmpeg::ui::handler::override_visible_name(const AVCodec*, std::string&) {}
+6 -5
View File
@@ -36,14 +36,15 @@ namespace obsffmpeg {
namespace ui {
class handler {
public:
virtual void override_visible_name(AVCodec* codec, std::string& name);
virtual void override_visible_name(const AVCodec* codec, std::string& name);
virtual void get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) = 0;
virtual void get_properties(obs_properties_t* props, AVCodec* codec,
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) = 0;
virtual void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) = 0;
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) = 0;
virtual void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context) = 0;
};
} // namespace ui
} // namespace obsffmpeg
+9 -6
View File
@@ -79,11 +79,13 @@ INITIALIZER(nvenc_h264_handler_init)
});
};
void obsffmpeg::ui::nvenc_h264_handler::override_visible_name(AVCodec* codec, std::string& name) {
void obsffmpeg::ui::nvenc_h264_handler::override_visible_name(const AVCodec*, std::string& name)
{
name = "H.264/AVC Encoder (NVidia NVENC)";
}
void obsffmpeg::ui::nvenc_h264_handler::get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::nvenc_h264_handler::get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context)
{
nvenc::get_defaults(settings, codec, context);
@@ -91,7 +93,8 @@ void obsffmpeg::ui::nvenc_h264_handler::get_defaults(obs_data_t* settings, AVCod
obs_data_set_default_int(settings, P_H264_LEVEL, static_cast<int64_t>(codecs::h264::level::UNKNOWN));
}
void obsffmpeg::ui::nvenc_h264_handler::get_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::nvenc_h264_handler::get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
{
if (!context) {
this->get_encoder_properties(props, codec);
@@ -100,7 +103,7 @@ void obsffmpeg::ui::nvenc_h264_handler::get_properties(obs_properties_t* props,
}
}
void obsffmpeg::ui::nvenc_h264_handler::update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::nvenc_h264_handler::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
{
nvenc::update(settings, codec, context);
@@ -122,7 +125,7 @@ void obsffmpeg::ui::nvenc_h264_handler::update(obs_data_t* settings, AVCodec* co
}
}
void obsffmpeg::ui::nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, AVCodec* codec)
void obsffmpeg::ui::nvenc_h264_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
{
nvenc::get_properties_pre(props, codec);
@@ -159,7 +162,7 @@ void obsffmpeg::ui::nvenc_h264_handler::get_encoder_properties(obs_properties_t*
nvenc::get_properties_post(props, codec);
}
void obsffmpeg::ui::nvenc_h264_handler::get_runtime_properties(obs_properties_t* props, AVCodec* codec,
void obsffmpeg::ui::nvenc_h264_handler::get_runtime_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
{
nvenc::get_runtime_properties(props, codec, context);
+8 -6
View File
@@ -34,20 +34,22 @@ namespace obsffmpeg {
namespace ui {
class nvenc_h264_handler : public handler {
public:
virtual void override_visible_name(AVCodec* codec, std::string& name) override;
virtual void override_visible_name(const AVCodec* codec, std::string& name) override;
virtual void get_defaults(obs_data_t* settings, AVCodec* codec,
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_properties(obs_properties_t* props, AVCodec* codec,
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
virtual void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
private:
void get_encoder_properties(obs_properties_t* props, AVCodec* codec);
void get_encoder_properties(obs_properties_t* props, const AVCodec* codec);
void get_runtime_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context);
void get_runtime_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context);
};
} // namespace ui
} // namespace obsffmpeg
+9 -6
View File
@@ -82,11 +82,13 @@ INITIALIZER(nvenc_hevc_handler_init)
});
};
void obsffmpeg::ui::nvenc_hevc_handler::override_visible_name(AVCodec* codec, std::string& name) {
void obsffmpeg::ui::nvenc_hevc_handler::override_visible_name(const AVCodec*, std::string& name)
{
name = "H.265/HEVC Encoder (NVidia NVENC)";
}
void obsffmpeg::ui::nvenc_hevc_handler::get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::nvenc_hevc_handler::get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context)
{
nvenc::get_defaults(settings, codec, context);
@@ -95,7 +97,8 @@ void obsffmpeg::ui::nvenc_hevc_handler::get_defaults(obs_data_t* settings, AVCod
obs_data_set_default_int(settings, P_HEVC_LEVEL, static_cast<int64_t>(codecs::hevc::level::UNKNOWN));
}
void obsffmpeg::ui::nvenc_hevc_handler::get_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::nvenc_hevc_handler::get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
{
if (!context) {
this->get_encoder_properties(props, codec);
@@ -104,7 +107,7 @@ void obsffmpeg::ui::nvenc_hevc_handler::get_properties(obs_properties_t* props,
}
}
void obsffmpeg::ui::nvenc_hevc_handler::update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::nvenc_hevc_handler::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
{
nvenc::update(settings, codec, context);
@@ -130,7 +133,7 @@ void obsffmpeg::ui::nvenc_hevc_handler::update(obs_data_t* settings, AVCodec* co
}
}
void obsffmpeg::ui::nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, AVCodec* codec)
void obsffmpeg::ui::nvenc_hevc_handler::get_encoder_properties(obs_properties_t* props, const AVCodec* codec)
{
nvenc::get_properties_pre(props, codec);
@@ -178,7 +181,7 @@ void obsffmpeg::ui::nvenc_hevc_handler::get_encoder_properties(obs_properties_t*
nvenc::get_properties_post(props, codec);
}
void obsffmpeg::ui::nvenc_hevc_handler::get_runtime_properties(obs_properties_t* props, AVCodec* codec,
void obsffmpeg::ui::nvenc_hevc_handler::get_runtime_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
{
nvenc::get_runtime_properties(props, codec, context);
+8 -6
View File
@@ -34,20 +34,22 @@ namespace obsffmpeg {
namespace ui {
class nvenc_hevc_handler : public handler {
public:
virtual void override_visible_name(AVCodec* codec, std::string& name) override;
virtual void override_visible_name(const AVCodec* codec, std::string& name) override;
virtual void get_defaults(obs_data_t* settings, AVCodec* codec,
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_properties(obs_properties_t* props, AVCodec* codec,
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
virtual void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
private:
void get_encoder_properties(obs_properties_t* props, AVCodec* codec);
void get_encoder_properties(obs_properties_t* props, const AVCodec* codec);
void get_runtime_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context);
void get_runtime_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context);
};
} // namespace ui
} // namespace obsffmpeg
+5 -5
View File
@@ -130,7 +130,7 @@ std::map<b_ref_mode, std::string> obsffmpeg::nvenc::b_ref_mode_to_opt{
{b_ref_mode::MIDDLE, "middle"},
};
void obsffmpeg::nvenc::get_defaults(obs_data_t* settings, AVCodec*, AVCodecContext*)
void obsffmpeg::nvenc::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
{
obs_data_set_default_int(settings, P_PRESET, static_cast<int64_t>(preset::DEFAULT));
@@ -228,7 +228,7 @@ static bool modified_aq(obs_properties_t* props, obs_property_t*, obs_data_t* se
return true;
}
void obsffmpeg::nvenc::get_properties_pre(obs_properties_t* props, AVCodec*)
void obsffmpeg::nvenc::get_properties_pre(obs_properties_t* props, const AVCodec*)
{
{
auto p = obs_properties_add_list(props, P_PRESET, TRANSLATE(P_PRESET), OBS_COMBO_TYPE_LIST,
@@ -240,7 +240,7 @@ void obsffmpeg::nvenc::get_properties_pre(obs_properties_t* props, AVCodec*)
}
}
void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, AVCodec* codec)
void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, const AVCodec* codec)
{
{ // Rate Control
obs_properties_t* grp = props;
@@ -449,7 +449,7 @@ void obsffmpeg::nvenc::get_properties_post(obs_properties_t* props, AVCodec* cod
}
}
void obsffmpeg::nvenc::get_runtime_properties(obs_properties_t* props, AVCodec*, AVCodecContext*)
void obsffmpeg::nvenc::get_runtime_properties(obs_properties_t* props, const AVCodec*, AVCodecContext*)
{
obs_property_set_enabled(obs_properties_get(props, P_PRESET), false);
obs_property_set_enabled(obs_properties_get(props, P_RATECONTROL), false);
@@ -484,7 +484,7 @@ void obsffmpeg::nvenc::get_runtime_properties(obs_properties_t* props, AVCodec*,
obs_property_set_enabled(obs_properties_get(props, P_OTHER_NONREFERENCE_PFRAMES), false);
}
void obsffmpeg::nvenc::update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::nvenc::update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context)
{
{
preset c_preset = static_cast<preset>(obs_data_get_int(settings, P_PRESET));
+5 -5
View File
@@ -75,14 +75,14 @@ namespace obsffmpeg {
extern std::map<b_ref_mode, std::string> b_ref_mode_to_opt;
void get_defaults(obs_data_t* settings, AVCodec* codec, AVCodecContext* context);
void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
void get_properties_pre(obs_properties_t* props, AVCodec* codec);
void get_properties_pre(obs_properties_t* props, const AVCodec* codec);
void get_properties_post(obs_properties_t* props, AVCodec* codec);
void get_properties_post(obs_properties_t* props, const AVCodec* codec);
void get_runtime_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context);
void get_runtime_properties(obs_properties_t* props, const AVCodec* codec, AVCodecContext* context);
void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context);
void update(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context);
} // namespace nvenc
} // namespace obsffmpeg
+4 -3
View File
@@ -41,12 +41,13 @@ INITIALIZER(prores_aw_handler_init)
});
};
void obsffmpeg::ui::prores_aw_handler::get_defaults(obs_data_t* settings, AVCodec*, AVCodecContext*)
void obsffmpeg::ui::prores_aw_handler::get_defaults(obs_data_t* settings, const AVCodec*, AVCodecContext*)
{
obs_data_set_default_int(settings, P_PROFILE, 0);
}
void obsffmpeg::ui::prores_aw_handler::get_properties(obs_properties_t* props, AVCodec* codec, AVCodecContext* context)
void obsffmpeg::ui::prores_aw_handler::get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context)
{
if (!context) {
auto p = obs_properties_add_list(props, P_PROFILE, TRANSLATE(P_PROFILE), OBS_COMBO_TYPE_LIST,
@@ -77,7 +78,7 @@ void obsffmpeg::ui::prores_aw_handler::get_properties(obs_properties_t* props, A
}
}
void obsffmpeg::ui::prores_aw_handler::update(obs_data_t* settings, AVCodec*, AVCodecContext* context)
void obsffmpeg::ui::prores_aw_handler::update(obs_data_t* settings, const AVCodec*, AVCodecContext* context)
{
context->profile = static_cast<int>(obs_data_get_int(settings, P_PROFILE));
}
+4 -3
View File
@@ -34,13 +34,14 @@ namespace obsffmpeg {
namespace ui {
class prores_aw_handler : public handler {
public:
virtual void get_defaults(obs_data_t* settings, AVCodec* codec,
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
virtual void get_properties(obs_properties_t* props, AVCodec* codec,
virtual void get_properties(obs_properties_t* props, const AVCodec* codec,
AVCodecContext* context) override;
virtual void update(obs_data_t* settings, AVCodec* codec, AVCodecContext* context) override;
virtual void update(obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;
};
} // namespace ui
} // namespace obsffmpeg