Skip to content

Commit

Permalink
refactor(video): move encoder declarations to header
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher committed Mar 4, 2024
1 parent 529f1b8 commit bdda93b
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 150 deletions.
157 changes: 7 additions & 150 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ extern "C" {
#include <libavutil/mastering_display_metadata.h>
#include <libavutil/opt.h>
#include <libavutil/pixdesc.h>
#include <libswscale/swscale.h>
}

#include "cbs.h"
Expand Down Expand Up @@ -51,12 +50,6 @@ namespace video {
av_buffer_unref(&ref);
}

using avcodec_ctx_t = util::safe_ptr<AVCodecContext, free_ctx>;
using avcodec_frame_t = util::safe_ptr<AVFrame, free_frame>;
using avcodec_buffer_t = util::safe_ptr<AVBufferRef, free_buffer>;
using sws_t = util::safe_ptr<SwsContext, sws_freeContext>;
using img_event_t = std::shared_ptr<safe::event_t<std::shared_ptr<platf::img_t>>>;

namespace nv {

enum class profile_h264_e : int {
Expand Down Expand Up @@ -87,11 +80,6 @@ namespace video {
};
} // namespace qsv

platf::mem_type_e
map_base_dev_type(AVHWDeviceType type);
platf::pix_fmt_e
map_pix_fmt(AVPixelFormat fmt);

util::Either<avcodec_buffer_t, int>
dxgi_init_avcodec_hardware_input_buffer(platf::avcodec_encode_device_t *);
util::Either<avcodec_buffer_t, int>
Expand Down Expand Up @@ -288,137 +276,6 @@ namespace video {
ALWAYS_REPROBE = 1 << 9, // This is an encoder of last resort and we want to aggressively probe for a better one
};

struct encoder_platform_formats_t {
virtual ~encoder_platform_formats_t() = default;
platf::mem_type_e dev_type;
platf::pix_fmt_e pix_fmt_8bit, pix_fmt_10bit;
};

struct encoder_platform_formats_avcodec: encoder_platform_formats_t {
using init_buffer_function_t = std::function<util::Either<avcodec_buffer_t, int>(platf::avcodec_encode_device_t *)>;

encoder_platform_formats_avcodec(
const AVHWDeviceType &avcodec_base_dev_type,
const AVHWDeviceType &avcodec_derived_dev_type,
const AVPixelFormat &avcodec_dev_pix_fmt,
const AVPixelFormat &avcodec_pix_fmt_8bit,
const AVPixelFormat &avcodec_pix_fmt_10bit,
const init_buffer_function_t &init_avcodec_hardware_input_buffer_function):
avcodec_base_dev_type { avcodec_base_dev_type },
avcodec_derived_dev_type { avcodec_derived_dev_type },
avcodec_dev_pix_fmt { avcodec_dev_pix_fmt },
avcodec_pix_fmt_8bit { avcodec_pix_fmt_8bit },
avcodec_pix_fmt_10bit { avcodec_pix_fmt_10bit },
init_avcodec_hardware_input_buffer { init_avcodec_hardware_input_buffer_function } {
dev_type = map_base_dev_type(avcodec_base_dev_type);
pix_fmt_8bit = map_pix_fmt(avcodec_pix_fmt_8bit);
pix_fmt_10bit = map_pix_fmt(avcodec_pix_fmt_10bit);
}

AVHWDeviceType avcodec_base_dev_type, avcodec_derived_dev_type;
AVPixelFormat avcodec_dev_pix_fmt;
AVPixelFormat avcodec_pix_fmt_8bit, avcodec_pix_fmt_10bit;

init_buffer_function_t init_avcodec_hardware_input_buffer;
};

struct encoder_platform_formats_nvenc: encoder_platform_formats_t {
encoder_platform_formats_nvenc(
const platf::mem_type_e &dev_type,
const platf::pix_fmt_e &pix_fmt_8bit,
const platf::pix_fmt_e &pix_fmt_10bit) {
encoder_platform_formats_t::dev_type = dev_type;
encoder_platform_formats_t::pix_fmt_8bit = pix_fmt_8bit;
encoder_platform_formats_t::pix_fmt_10bit = pix_fmt_10bit;
}
};

struct encoder_t {
std::string_view name;
enum flag_e {
PASSED, // Is supported
REF_FRAMES_RESTRICT, // Set maximum reference frames
CBR, // Some encoders don't support CBR, if not supported --> attempt constant quantatication parameter instead
DYNAMIC_RANGE, // hdr
VUI_PARAMETERS, // AMD encoder with VAAPI doesn't add VUI parameters to SPS
MAX_FLAGS
};

static std::string_view
from_flag(flag_e flag) {
#define _CONVERT(x) \
case flag_e::x: \
return #x##sv
switch (flag) {
_CONVERT(PASSED);
_CONVERT(REF_FRAMES_RESTRICT);
_CONVERT(CBR);
_CONVERT(DYNAMIC_RANGE);
_CONVERT(VUI_PARAMETERS);
_CONVERT(MAX_FLAGS);
}
#undef _CONVERT

return "unknown"sv;
}

struct option_t {
KITTY_DEFAULT_CONSTR_MOVE(option_t)
option_t(const option_t &) = default;

std::string name;
std::variant<int, int *, std::optional<int> *, std::function<int()>, std::string, std::string *> value;

option_t(std::string &&name, decltype(value) &&value):
name { std::move(name) }, value { std::move(value) } {}
};

const std::unique_ptr<const encoder_platform_formats_t> platform_formats;

struct {
std::vector<option_t> common_options;
std::vector<option_t> sdr_options;
std::vector<option_t> hdr_options;
std::vector<option_t> fallback_options;

// QP option to set in the case that CBR/VBR is not supported
// by the encoder. If CBR/VBR is guaranteed to be supported,
// don't specify this option to avoid wasteful encoder probing.
std::optional<option_t> qp;

std::string name;
std::bitset<MAX_FLAGS> capabilities;

bool
operator[](flag_e flag) const {
return capabilities[(std::size_t) flag];
}

std::bitset<MAX_FLAGS>::reference
operator[](flag_e flag) {
return capabilities[(std::size_t) flag];
}
} av1, hevc, h264;

uint32_t flags;
};

struct encode_session_t {
virtual ~encode_session_t() = default;

virtual int
convert(platf::img_t &img) = 0;

virtual void
request_idr_frame() = 0;

virtual void
request_normal_frame() = 0;

virtual void
invalidate_ref_frames(int64_t first_frame, int64_t last_frame) = 0;
};

class avcodec_encode_session_t: public encode_session_t {
public:
avcodec_encode_session_t() = default;
Expand Down Expand Up @@ -586,7 +443,7 @@ namespace video {
auto capture_thread_sync = safe::make_shared<capture_thread_sync_ctx_t>(start_capture_sync, end_capture_sync);

#ifdef _WIN32
static encoder_t nvenc {
encoder_t nvenc {
"nvenc"sv,
std::make_unique<encoder_platform_formats_nvenc>(
platf::mem_type_e::dxgi,
Expand Down Expand Up @@ -630,7 +487,7 @@ namespace video {
PARALLEL_ENCODING | REF_FRAMES_INVALIDATION // flags
};
#elif !defined(__APPLE__)
static encoder_t nvenc {
encoder_t nvenc {
"nvenc"sv,
std::make_unique<encoder_platform_formats_avcodec>(
#ifdef _WIN32
Expand Down Expand Up @@ -718,7 +575,7 @@ namespace video {
#endif

#ifdef _WIN32
static encoder_t quicksync {
encoder_t quicksync {
"quicksync"sv,
std::make_unique<encoder_platform_formats_avcodec>(
AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_QSV,
Expand Down Expand Up @@ -799,7 +656,7 @@ namespace video {
PARALLEL_ENCODING | CBR_WITH_VBR | RELAXED_COMPLIANCE | NO_RC_BUF_LIMIT
};

static encoder_t amdvce {
encoder_t amdvce {
"amdvce"sv,
std::make_unique<encoder_platform_formats_avcodec>(
AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_NONE,
Expand Down Expand Up @@ -871,7 +728,7 @@ namespace video {
};
#endif

static encoder_t software {
encoder_t software {
"software"sv,
std::make_unique<encoder_platform_formats_avcodec>(
AV_HWDEVICE_TYPE_NONE, AV_HWDEVICE_TYPE_NONE,
Expand Down Expand Up @@ -936,7 +793,7 @@ namespace video {
};

#ifdef __linux__
static encoder_t vaapi {
encoder_t vaapi {
"vaapi"sv,
std::make_unique<encoder_platform_formats_avcodec>(
AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_NONE,
Expand Down Expand Up @@ -1004,7 +861,7 @@ namespace video {
#endif

#ifdef __APPLE__
static encoder_t videotoolbox {
encoder_t videotoolbox {
"videotoolbox"sv,
std::make_unique<encoder_platform_formats_avcodec>(
AV_HWDEVICE_TYPE_VIDEOTOOLBOX, AV_HWDEVICE_TYPE_NONE,
Expand Down
Loading

0 comments on commit bdda93b

Please sign in to comment.