obs-StreamFX/source/encoders/encoder-ffmpeg.hpp
Michael Fabian 'Xaymar' Dirks 5a3954ae0e project: Fix License, License headers and Copyright information
Fixes several files incorrectly stated a different license from the actual project, as well as the copyright headers included in all files. This change has no effect on the licensing terms, it should clear up a bit of confusion by contributors. Plus the files get a bit smaller, and we have less duplicated information across the entire project.

Overall the project is GPLv2 if not built with Qt, and GPLv3 if it is built with Qt. There are no parts licensed under a different license, all have been adapted from other compatible licenses into GPLv2 or GPLv3.
2023-04-05 18:59:08 +02:00

166 lines
4.6 KiB
C++

// AUTOGENERATED COPYRIGHT HEADER START
// Copyright (C) 2020-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
// Copyright (C) 2022 lainon <GermanAizek@yandex.ru>
// AUTOGENERATED COPYRIGHT HEADER END
#pragma once
#include "common.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"
#include <condition_variable>
#include <map>
#include <mutex>
#include <queue>
#include <stack>
#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"
}
namespace streamfx::encoder::ffmpeg {
class ffmpeg_factory;
class ffmpeg_instance : public obs::encoder_instance {
ffmpeg_factory* _factory;
const AVCodec* _codec;
AVCodecContext* _context;
std::shared_ptr<handler::handler> _handler;
::streamfx::ffmpeg::swscale _scaler;
std::shared_ptr<AVPacket> _packet;
std::shared_ptr<::streamfx::ffmpeg::hwapi::base> _hwapi;
std::shared_ptr<::streamfx::ffmpeg::hwapi::instance> _hwinst;
std::size_t _lag_in_frames;
std::size_t _sent_frames;
std::size_t _framerate_divisor;
// Extra Data
bool _have_first_frame;
std::vector<uint8_t> _extra_data;
std::vector<uint8_t> _sei_data;
// Frame Stack and Queue
std::stack<std::shared_ptr<AVFrame>> _free_frames;
std::queue<std::shared_ptr<AVFrame>> _used_frames;
std::chrono::high_resolution_clock::time_point _free_frames_last_used;
public:
ffmpeg_instance(obs_data_t* settings, obs_encoder_t* self, bool is_hw);
virtual ~ffmpeg_instance();
public:
void get_properties(obs_properties_t* props);
void migrate(obs_data_t* settings, uint64_t version) override;
bool update(obs_data_t* settings) override;
bool encode_audio(struct encoder_frame* frame, struct encoder_packet* packet, bool* received_packet) override;
bool encode_video(struct encoder_frame* frame, struct encoder_packet* packet, bool* received_packet) override;
bool encode_video(uint32_t handle, int64_t pts, uint64_t lock_key, uint64_t* next_key,
struct encoder_packet* packet, bool* received_packet) override;
bool get_extra_data(uint8_t** extra_data, size_t* size) override;
bool get_sei_data(uint8_t** sei_data, size_t* size) override;
void get_video_info(struct video_scale_info* info) override;
public:
void initialize_sw(obs_data_t* settings);
void initialize_hw(obs_data_t* settings);
void push_free_frame(std::shared_ptr<AVFrame> frame);
std::shared_ptr<AVFrame> pop_free_frame();
void push_used_frame(std::shared_ptr<AVFrame> frame);
std::shared_ptr<AVFrame> pop_used_frame();
int receive_packet(bool* received_packet, struct encoder_packet* packet);
int send_frame(std::shared_ptr<AVFrame> frame);
bool encode_avframe(std::shared_ptr<AVFrame> frame, struct encoder_packet* packet, bool* received_packet);
public: // Handler API
bool is_hardware_encode();
const AVCodec* get_avcodec();
const AVCodecContext* get_avcodeccontext();
void parse_ffmpeg_commandline(std::string_view text);
};
class ffmpeg_factory : public obs::encoder_factory<ffmpeg_factory, ffmpeg_instance> {
std::string _id;
std::string _codec;
std::string _name;
const AVCodec* _avcodec;
std::shared_ptr<handler::handler> _handler;
public:
ffmpeg_factory(const AVCodec* codec);
virtual ~ffmpeg_factory();
const char* get_name() override;
void get_defaults2(obs_data_t* data) override;
void migrate(obs_data_t* data, uint64_t version) override;
obs_properties_t* get_properties2(instance_t* data) override;
#ifdef ENABLE_FRONTEND
static bool on_manual_open(obs_properties_t* props, obs_property_t* property, void* data);
#endif
public:
const AVCodec* get_avcodec();
obs_encoder_info* get_info();
};
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_encoders();
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_view codec);
public: // Singleton
static void initialize();
static void finalize();
static std::shared_ptr<ffmpeg_manager> get();
};
} // namespace streamfx::encoder::ffmpeg