project: Fix Linux support by fixing errors and warnings

With this, GCC 8 and above should now be able to compile the project both in obs-studio and as a standalone install. Some features are currently still not fully supported and require extra work, but the majority of things are supported and work out of the box. Exact feature parity can be looked up here on the wiki: https://github.com/Xaymar/obs-StreamFX/wiki/Platform-Feature-Parity

Related: #119 #98 #30
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2020-04-02 20:29:00 +02:00 committed by Michael Fabian Dirks
parent 8b7e1a2826
commit cc9d3486b2
26 changed files with 91 additions and 233 deletions

View file

@ -8,9 +8,9 @@
#pragma warning(pop)
#endif
OBS_DECLARE_MODULE();
OBS_MODULE_AUTHOR("@PROJECT_AUTHORS@");
OBS_MODULE_USE_DEFAULT_LOCALE("@PROJECT_NAME@", "en-US");
OBS_DECLARE_MODULE()
OBS_MODULE_AUTHOR("@PROJECT_AUTHORS@")
OBS_MODULE_USE_DEFAULT_LOCALE("@PROJECT_NAME@", "en-US")
MODULE_EXPORT const char* obs_module_name()
{

View file

@ -41,10 +41,10 @@
// Common Plugin includes
#include "strings.hpp"
#include "version.hpp"
#include "util-profiler.hpp"
#include "util-threadpool.hpp"
#include "utility.hpp"
#include "version.hpp"
// Common OBS includes
extern "C" {
@ -53,15 +53,23 @@ extern "C" {
#pragma warning(disable : 4201)
#endif
#include <obs.h>
#include <obs-config.h>
#include <obs-data.h>
#include <obs-encoder.h>
#include <obs-module.h>
#include <obs-properties.h>
#include <obs-source.h>
#include <util/platform.h>
#include <graphics/graphics.h>
#include <graphics/vec3.h>
#include <graphics/effect.h>
#include <graphics/matrix4.h>
#include <graphics/vec2.h>
#include <graphics/vec3.h>
#include <graphics/vec4.h>
#include <util/platform.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View file

@ -20,6 +20,7 @@
// SOFTWARE.
#include "ffmpeg-encoder.hpp"
#include "strings.hpp"
#include <sstream>
#include "codecs/hevc.hpp"
#include "ffmpeg/tools.hpp"
@ -27,13 +28,11 @@
#include "handlers/nvenc_h264_handler.hpp"
#include "handlers/nvenc_hevc_handler.hpp"
#include "handlers/prores_aw_handler.hpp"
#include "obs/gs/gs-helper.hpp"
#include "plugin.hpp"
#include "strings.hpp"
#include "utility.hpp"
extern "C" {
#include <obs-avc.h>
#include <obs-module.h>
#pragma warning(push)
#pragma warning(disable : 4244)
#include <libavcodec/avcodec.h>
@ -41,6 +40,7 @@ extern "C" {
#include <libavutil/frame.h>
#include <libavutil/opt.h>
#include <libavutil/pixdesc.h>
#include <obs-avc.h>
#pragma warning(pop)
}
@ -782,7 +782,7 @@ ffmpeg_instance::ffmpeg_instance(obs_data_t* settings, obs_encoder_t* encoder, b
}
#ifdef WIN32
auto gctx = util::obs_graphics();
auto gctx = gs::context();
if (gs_get_device_type() == GS_DEVICE_DIRECT3D_11) {
_hwapi = std::make_shared<::ffmpeg::hwapi::d3d11>();
}
@ -815,7 +815,7 @@ ffmpeg_instance::ffmpeg_instance(obs_data_t* settings, obs_encoder_t* encoder, b
update(settings);
// Initialize Encoder
auto gctx = util::obs_graphics();
auto gctx = gs::context();
int res = avcodec_open2(_context, _codec, NULL);
if (res < 0) {
std::stringstream sstr;
@ -827,7 +827,7 @@ ffmpeg_instance::ffmpeg_instance(obs_data_t* settings, obs_encoder_t* encoder, b
ffmpeg_instance::~ffmpeg_instance()
{
auto gctx = util::obs_graphics();
auto gctx = gs::context();
if (_context) {
// Flush encoders that require it.
if ((_codec->capabilities & AV_CODEC_CAP_DELAY) != 0) {
@ -938,7 +938,8 @@ bool ffmpeg_instance::update(obs_data_t* settings)
if (_handler) {
LOG_INFO("[%s] Initializing...", _codec->name);
LOG_INFO("[%s] FFmpeg:", _codec->name);
LOG_INFO("[%s] Custom Settings: %s", _codec->name, obs_data_get_string(settings, KEY_FFMPEG_CUSTOMSETTINGS));
LOG_INFO("[%s] Custom Settings: %s", _codec->name,
obs_data_get_string(settings, KEY_FFMPEG_CUSTOMSETTINGS));
LOG_INFO("[%s] Standard Compliance: %s", _codec->name,
::ffmpeg::tools::get_std_compliance_name(_context->strict_std_compliance));
LOG_INFO("[%s] Threading: %s (with %i threads)", _codec->name,
@ -1115,7 +1116,7 @@ int ffmpeg_instance::receive_packet(bool* received_packet, struct encoder_packet
av_packet_unref(&_current_packet);
{
auto gctx = util::obs_graphics();
auto gctx = gs::context();
res = avcodec_receive_packet(_context, &_current_packet);
}
if (res != 0) {
@ -1181,7 +1182,7 @@ int ffmpeg_instance::send_frame(std::shared_ptr<AVFrame> const frame)
{
int res = 0;
{
auto gctx = util::obs_graphics();
auto gctx = gs::context();
res = avcodec_send_frame(_context, frame.get());
}
if (res == 0) {

View file

@ -25,6 +25,8 @@
namespace encoder::ffmpeg::handler {
class debug_handler : public handler {
public:
virtual ~debug_handler(){};
virtual void get_defaults(obs_data_t* settings, const AVCodec* codec, AVCodecContext* context,
bool hw_encode) override;

View file

@ -37,6 +37,9 @@ namespace encoder::ffmpeg {
namespace handler {
class handler {
public:
virtual ~handler(){};
public /*factory*/:
virtual void adjust_encoder_info(ffmpeg_factory* factory, ffmpeg_info* main, ffmpeg_info* fallback);

View file

@ -31,6 +31,9 @@ extern "C" {
namespace encoder::ffmpeg::handler {
class nvenc_h264_handler : public handler {
public:
virtual ~nvenc_h264_handler(){};
public /*factory*/:
virtual void adjust_encoder_info(ffmpeg_factory* factory, ffmpeg_info* main, ffmpeg_info* fallback);

View file

@ -31,6 +31,9 @@ extern "C" {
namespace encoder::ffmpeg::handler {
class nvenc_hevc_handler : public handler {
public:
virtual ~nvenc_hevc_handler(){};
public /*factory*/:
virtual void adjust_encoder_info(ffmpeg_factory* factory, ffmpeg_info* main, ffmpeg_info* fallback);

View file

@ -31,6 +31,9 @@ extern "C" {
namespace encoder::ffmpeg::handler {
class prores_aw_handler : public handler {
public:
virtual ~prores_aw_handler(){};
public:
virtual void override_colorformat(AVPixelFormat& target_format, obs_data_t* settings, const AVCodec* codec,
AVCodecContext* context) override;

View file

@ -44,6 +44,8 @@ namespace ffmpeg::hwapi {
class instance {
public:
virtual ~instance(){};
virtual AVBufferRef* create_device_context() = 0;
virtual std::shared_ptr<AVFrame> allocate_frame(AVBufferRef* frames) = 0;
@ -57,6 +59,8 @@ namespace ffmpeg::hwapi {
class base {
public:
virtual ~base(){};
virtual std::list<hwapi::device> enumerate_adapters() = 0;
virtual std::shared_ptr<hwapi::instance> create(hwapi::device target) = 0;

View file

@ -24,6 +24,7 @@
#include "d3d11.hpp"
#include <sstream>
#include <vector>
#include "obs/gs/gs-helper.hpp"
#include "utility.hpp"
extern "C" {
@ -33,9 +34,7 @@ extern "C" {
#pragma warning(disable : 4244)
#pragma warning(disable : 4365)
#pragma warning(disable : 4986)
#include <graphics/graphics.h>
#include <libavutil/hwcontext_d3d11va.h>
#include <obs.h>
#pragma warning(pop)
}
@ -138,7 +137,7 @@ std::shared_ptr<instance> d3d11::create(device target)
std::shared_ptr<instance> d3d11::create_from_obs()
{
auto gctx = util::obs_graphics();
auto gctx = gs::context();
if (GS_DEVICE_DIRECT3D_11 != gs_get_device_type()) {
throw std::runtime_error("OBS Device is not a D3D11 Device.");
@ -190,7 +189,7 @@ AVBufferRef* d3d11_instance::create_device_context()
std::shared_ptr<AVFrame> d3d11_instance::allocate_frame(AVBufferRef* frames)
{
auto gctx = util::obs_graphics();
auto gctx = gs::context();
auto frame = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame* frame) {
av_frame_unref(frame);
@ -207,7 +206,7 @@ std::shared_ptr<AVFrame> d3d11_instance::allocate_frame(AVBufferRef* frames)
void d3d11_instance::copy_from_obs(AVBufferRef*, uint32_t handle, uint64_t lock_key, uint64_t* next_lock_key,
std::shared_ptr<AVFrame> frame)
{
auto gctx = util::obs_graphics();
auto gctx = gs::context();
ATL::CComPtr<IDXGIKeyedMutex> mutex;
ATL::CComPtr<ID3D11Texture2D> input;
@ -246,7 +245,7 @@ void d3d11_instance::copy_from_obs(AVBufferRef*, uint32_t handle, uint64_t lock_
std::shared_ptr<AVFrame> d3d11_instance::avframe_from_obs(AVBufferRef* frames, uint32_t handle, uint64_t lock_key,
uint64_t* next_lock_key)
{
auto gctx = util::obs_graphics();
auto gctx = gs::context();
auto frame = this->allocate_frame(frames);
this->copy_from_obs(frames, handle, lock_key, next_lock_key, frame);

View file

@ -31,6 +31,7 @@ extern "C++" {
#pragma warning(disable : 4777)
#pragma warning(disable : 4986)
#pragma warning(disable : 5039)
#pragma warning(disable : 5204)
#include <atlutil.h>
#include <d3d11.h>
#include <d3d11_1.h>

View file

@ -164,7 +164,7 @@ gfx::shader::parameter::parameter(gs::effect_parameter param, std::string key_pr
if (ov > 0)
_size = ov;
}
_size = std::clamp(_size, 1ull, 32ull);
_size = std::clamp<size_t>(_size, size_t{1}, size_t{32});
}
void gfx::shader::parameter::defaults(obs_data_t* settings) {}

View file

@ -23,7 +23,7 @@
#ifdef WIN32
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4191 4365 4777 5039)
#pragma warning(disable: 4191 4365 4777 5039 5204)
#endif
#include <atlutil.h>
#ifdef _MSC_VER

View file

@ -25,6 +25,7 @@
#ifdef WIN32
#pragma warning(push)
#pragma warning(disable : 4365)
#pragma warning(disable : 5204)
#include <d3d11.h>
#include <dxgi.h>
#pragma warning(pop)

View file

@ -22,8 +22,16 @@
#include <stdexcept>
#include "gs-effect-pass.hpp"
extern "C" {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <graphics/effect.h>
#include <graphics/vec2.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
}
gs::effect_parameter::effect_parameter() : _effect_parent(nullptr), _pass_parent(nullptr), _param_parent(nullptr)
{

View file

@ -20,7 +20,16 @@
#include "gs-effect-pass.hpp"
#include <cstring>
extern "C" {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <graphics/effect.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
}
gs::effect_pass::effect_pass(gs_epass_t* pass, std::shared_ptr<gs_technique_t>* parent) : _parent(parent)
{

View file

@ -21,7 +21,16 @@
#include <cstring>
#include <stdexcept>
extern "C" {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <graphics/effect.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
}
gs::effect_technique::effect_technique(gs_technique_t* technique, std::shared_ptr<gs_effect_t>* parent)
: _parent(parent)

View file

@ -23,17 +23,6 @@
#include <vector>
#include "obs/gs/gs-helper.hpp"
// OBS
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <graphics/effect.h>
#include <obs.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#define MAX_EFFECT_SIZE 32 * 1024 * 1024
static std::string load_file_as_code(std::filesystem::path file)

View file

@ -22,16 +22,6 @@
#include "gs-limits.hpp"
#include "obs/gs/gs-helper.hpp"
// OBS
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <obs.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
gs::index_buffer::index_buffer(uint32_t maximumVertices)
{
this->reserve(maximumVertices);

View file

@ -22,18 +22,6 @@
#include "obs/gs/gs-helper.hpp"
#include "plugin.hpp"
// OBS
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <graphics/graphics.h>
#include <obs-module.h>
#include <obs.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#if defined(WIN32) || defined(WIN64)
#ifdef _MSC_VER
#pragma warning(push)

View file

@ -21,17 +21,6 @@
#include <stdexcept>
#include "obs/gs/gs-helper.hpp"
// OBS
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <graphics/graphics.h>
#include <obs.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
gs::rendertarget::~rendertarget()
{
auto gctx = gs::context();

View file

@ -24,17 +24,6 @@
#include "obs/gs/gs-helper.hpp"
#include "util-math.hpp"
// OBS
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <obs.h>
#include <util/platform.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
static uint32_t decode_flags(gs::texture::flags texture_flags)
{
uint32_t flags = 0;

View file

@ -22,16 +22,6 @@
#include "obs/gs/gs-helper.hpp"
#include "utility.hpp"
// OBS
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <obs.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
void gs::vertex_buffer::initialize(size_t capacity, size_t layers)
{
if (capacity > MAXIMUM_VERTICES) {

View file

@ -22,16 +22,6 @@
#include <stdexcept>
#include "plugin.hpp"
// OBS
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <obs-properties.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
struct scs_searchdata {
obs_source_t* source;
bool found = false;

View file

@ -35,9 +35,7 @@
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <graphics/matrix4.h>
#include <media-io/audio-io.h>
#include <obs-config.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View file

@ -18,18 +18,20 @@
*/
#pragma once
#include "common.hpp"
#include <cinttypes>
#include <cstddef>
#include <string>
#include <type_traits>
extern "C" {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201)
#endif
#include <obs.h>
#include <graphics/vec2.h>
#include <graphics/vec3.h>
#include <graphics/vec4.h>
#include <obs-config.h>
#include <obs.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
@ -94,17 +96,6 @@ namespace util {
return obs_get_version() < MAKE_SEMANTIC_VERSION(24, 0, 0);
}
struct obs_graphics {
obs_graphics()
{
obs_enter_graphics();
}
~obs_graphics()
{
obs_leave_graphics();
}
};
obs_property_t* obs_properties_add_tristate(obs_properties_t* props, const char* name, const char* desc);
inline bool is_tristate_enabled(int64_t tristate)
@ -122,25 +113,6 @@ namespace util {
return tristate == -1;
}
typedef union {
uint32_t color;
struct {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
};
} rgba32;
typedef union {
uint32_t color;
struct {
uint8_t a;
uint8_t r;
uint8_t g;
uint8_t b;
};
} argb32;
struct vec2a : public vec2 {
// 16-byte Aligned version of vec2
static void* operator new(size_t count);
@ -171,16 +143,6 @@ namespace util {
static void operator delete[](void* p);
};
inline size_t GetNearestPowerOfTwoAbove(size_t v)
{
return 1ull << size_t(ceil(log10(double(v)) / log10(2.0)));
}
inline size_t GetNearestPowerOfTwoBelow(size_t v)
{
return 1ull << size_t(floor(log10(double(v)) / log10(2.0)));
}
std::pair<int64_t, int64_t> size_from_string(std::string text, bool allowSquare = true);
namespace math {
@ -216,14 +178,14 @@ namespace util {
{ \
return is_power_of_two_loop(v); \
}
P_IS_POWER_OF_TWO_AS_LOOP(int8_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint8_t);
P_IS_POWER_OF_TWO_AS_LOOP(int16_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint16_t);
P_IS_POWER_OF_TWO_AS_LOOP(int32_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint32_t);
P_IS_POWER_OF_TWO_AS_LOOP(int64_t);
P_IS_POWER_OF_TWO_AS_LOOP(uint64_t);
P_IS_POWER_OF_TWO_AS_LOOP(int8_t)
P_IS_POWER_OF_TWO_AS_LOOP(uint8_t)
P_IS_POWER_OF_TWO_AS_LOOP(int16_t)
P_IS_POWER_OF_TWO_AS_LOOP(uint16_t)
P_IS_POWER_OF_TWO_AS_LOOP(int32_t)
P_IS_POWER_OF_TWO_AS_LOOP(uint32_t)
P_IS_POWER_OF_TWO_AS_LOOP(int64_t)
P_IS_POWER_OF_TWO_AS_LOOP(uint64_t)
#undef P_IS_POWER_OF_TWO_AS_LOOP
#pragma pop_macro("P_IS_POWER_OF_TWO_AS_LOOP")
@ -315,85 +277,4 @@ namespace util {
}
void* malloc_aligned(size_t align, size_t size);
void free_aligned(void* mem);
template<typename T, size_t N = 16>
class AlignmentAllocator {
public:
typedef T value_type;
typedef size_t size_type;
#ifdef __clang__
typedef ptrdiff_t difference_type;
#else
typedef std::ptrdiff_t difference_type;
#endif
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
public:
inline AlignmentAllocator() {}
template<typename T2>
inline AlignmentAllocator(const AlignmentAllocator<T2, N>&)
{}
inline ~AlignmentAllocator() {}
inline pointer adress(reference r)
{
return &r;
}
inline const_pointer adress(const_reference r) const
{
return &r;
}
inline pointer allocate(size_type n)
{
return (pointer)malloc_aligned(n * sizeof(value_type), N);
}
inline void deallocate(pointer p, size_type)
{
free_aligned(p);
}
inline void construct(pointer p, const value_type& wert)
{
new (p) value_type(wert);
}
inline void destroy(pointer p)
{
p->~value_type();
p;
}
inline size_type max_size() const
{
return size_type(-1) / sizeof(value_type);
}
template<typename T2>
struct rebind {
typedef AlignmentAllocator<T2, N> other;
};
bool operator!=(const AlignmentAllocator<T, N>& other) const
{
return !(*this == other);
}
// Returns true if and only if storage allocated from *this
// can be deallocated from other, and vice versa.
// Always returns true for stateless allocators.
bool operator==(const AlignmentAllocator<T, N>&) const
{
return true;
}
};
} // namespace util