mirror of
https://github.com/k4yt3x/video2x.git
synced 2026-02-15 09:44:46 +08:00
chore(libvideo2x)!: replace the C API with C++ API (#1245)
* chore(libvideo2x)!: replace the C API with C++ API * fix: convert wide string to u8 for av_opt_set * style: removed unnecessary enum and struct specifiers Signed-off-by: k4yt3x <i@k4yt3x.com>
This commit is contained in:
@@ -63,14 +63,13 @@ int64_t get_video_frame_count(AVFormatContext *ifmt_ctx, int in_vstream_idx) {
|
||||
return static_cast<int64_t>(duration_secs * fps);
|
||||
}
|
||||
|
||||
enum AVPixelFormat
|
||||
get_encoder_default_pix_fmt(const AVCodec *encoder, AVPixelFormat target_pix_fmt) {
|
||||
AVPixelFormat get_encoder_default_pix_fmt(const AVCodec *encoder, AVPixelFormat target_pix_fmt) {
|
||||
int ret;
|
||||
char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||
|
||||
// Retrieve the list of supported pixel formats
|
||||
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(61, 13, 100)
|
||||
const enum AVPixelFormat *supported_pix_fmts = nullptr;
|
||||
const AVPixelFormat *supported_pix_fmts = nullptr;
|
||||
ret = avcodec_get_supported_config(
|
||||
nullptr, encoder, AV_CODEC_CONFIG_PIX_FORMAT, 0, (const void **)&supported_pix_fmts, nullptr
|
||||
);
|
||||
@@ -90,7 +89,7 @@ get_encoder_default_pix_fmt(const AVCodec *encoder, AVPixelFormat target_pix_fmt
|
||||
}
|
||||
}
|
||||
#else
|
||||
const enum AVPixelFormat *supported_pix_fmts = encoder->pix_fmts;
|
||||
const AVPixelFormat *supported_pix_fmts = encoder->pix_fmts;
|
||||
#endif
|
||||
|
||||
// Determine if the target pixel format has an alpha channel
|
||||
@@ -102,8 +101,8 @@ get_encoder_default_pix_fmt(const AVCodec *encoder, AVPixelFormat target_pix_fmt
|
||||
}
|
||||
|
||||
// Iterate over supported pixel formats to find the best match
|
||||
enum AVPixelFormat best_pix_fmt = AV_PIX_FMT_NONE;
|
||||
for (const enum AVPixelFormat *p = supported_pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
AVPixelFormat best_pix_fmt = AV_PIX_FMT_NONE;
|
||||
for (const AVPixelFormat *p = supported_pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
if (target_pix_fmt != AV_PIX_FMT_NONE) {
|
||||
best_pix_fmt =
|
||||
av_find_best_pix_fmt_of_2(best_pix_fmt, *p, target_pix_fmt, has_alpha, nullptr);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
enum AVPixelFormat Decoder::hw_pix_fmt_ = AV_PIX_FMT_NONE;
|
||||
AVPixelFormat Decoder::hw_pix_fmt_ = AV_PIX_FMT_NONE;
|
||||
|
||||
Decoder::Decoder() : fmt_ctx_(nullptr), dec_ctx_(nullptr), in_vstream_idx_(-1) {}
|
||||
|
||||
@@ -17,8 +17,8 @@ Decoder::~Decoder() {
|
||||
}
|
||||
}
|
||||
|
||||
enum AVPixelFormat Decoder::get_hw_format(AVCodecContext *_, const enum AVPixelFormat *pix_fmts) {
|
||||
for (const enum AVPixelFormat *p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
AVPixelFormat Decoder::get_hw_format(AVCodecContext *_, const AVPixelFormat *pix_fmts) {
|
||||
for (const AVPixelFormat *p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
if (*p == hw_pix_fmt_) {
|
||||
return *p;
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ int Encoder::init(
|
||||
const std::filesystem::path &out_fpath,
|
||||
AVFormatContext *ifmt_ctx,
|
||||
AVCodecContext *dec_ctx,
|
||||
EncoderConfig *encoder_config,
|
||||
const ProcessorConfig *processor_config,
|
||||
EncoderConfig &enc_cfg,
|
||||
const ProcessorConfig &proc_cfg,
|
||||
int in_vstream_idx
|
||||
) {
|
||||
int ret;
|
||||
@@ -46,10 +46,10 @@ int Encoder::init(
|
||||
}
|
||||
|
||||
// Find the encoder
|
||||
const AVCodec *encoder = avcodec_find_encoder(encoder_config->codec);
|
||||
const AVCodec *encoder = avcodec_find_encoder(enc_cfg.codec);
|
||||
if (!encoder) {
|
||||
spdlog::error(
|
||||
"Required video encoder not found for codec {}", avcodec_get_name(encoder_config->codec)
|
||||
"Required video encoder not found for codec {}", avcodec_get_name(enc_cfg.codec)
|
||||
);
|
||||
return AVERROR_ENCODER_NOT_FOUND;
|
||||
}
|
||||
@@ -85,33 +85,33 @@ int Encoder::init(
|
||||
enc_ctx_->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
|
||||
|
||||
// Set basic video options
|
||||
enc_ctx_->width = encoder_config->width;
|
||||
enc_ctx_->height = encoder_config->height;
|
||||
enc_ctx_->width = enc_cfg.width;
|
||||
enc_ctx_->height = enc_cfg.height;
|
||||
|
||||
// Set rate control and compression options
|
||||
enc_ctx_->bit_rate = encoder_config->bit_rate;
|
||||
enc_ctx_->rc_buffer_size = encoder_config->rc_buffer_size;
|
||||
enc_ctx_->rc_min_rate = encoder_config->rc_min_rate;
|
||||
enc_ctx_->rc_max_rate = encoder_config->rc_max_rate;
|
||||
enc_ctx_->qmin = encoder_config->qmin;
|
||||
enc_ctx_->qmax = encoder_config->qmax;
|
||||
enc_ctx_->bit_rate = enc_cfg.bit_rate;
|
||||
enc_ctx_->rc_buffer_size = enc_cfg.rc_buffer_size;
|
||||
enc_ctx_->rc_min_rate = enc_cfg.rc_min_rate;
|
||||
enc_ctx_->rc_max_rate = enc_cfg.rc_max_rate;
|
||||
enc_ctx_->qmin = enc_cfg.qmin;
|
||||
enc_ctx_->qmax = enc_cfg.qmax;
|
||||
|
||||
// Set GOP and frame structure options
|
||||
enc_ctx_->gop_size = encoder_config->gop_size;
|
||||
enc_ctx_->max_b_frames = encoder_config->max_b_frames;
|
||||
enc_ctx_->keyint_min = encoder_config->keyint_min;
|
||||
enc_ctx_->refs = encoder_config->refs;
|
||||
enc_ctx_->gop_size = enc_cfg.gop_size;
|
||||
enc_ctx_->max_b_frames = enc_cfg.max_b_frames;
|
||||
enc_ctx_->keyint_min = enc_cfg.keyint_min;
|
||||
enc_ctx_->refs = enc_cfg.refs;
|
||||
|
||||
// Set performance and threading options
|
||||
enc_ctx_->thread_count = encoder_config->thread_count;
|
||||
enc_ctx_->thread_count = enc_cfg.thread_count;
|
||||
|
||||
// Set latency and buffering options
|
||||
enc_ctx_->delay = encoder_config->delay;
|
||||
enc_ctx_->delay = enc_cfg.delay;
|
||||
|
||||
// Set the pixel format
|
||||
if (encoder_config->pix_fmt != AV_PIX_FMT_NONE) {
|
||||
if (enc_cfg.pix_fmt != AV_PIX_FMT_NONE) {
|
||||
// Use the specified pixel format
|
||||
enc_ctx_->pix_fmt = encoder_config->pix_fmt;
|
||||
enc_ctx_->pix_fmt = enc_cfg.pix_fmt;
|
||||
} else {
|
||||
// Automatically select the pixel format
|
||||
enc_ctx_->pix_fmt = get_encoder_default_pix_fmt(encoder, dec_ctx->pix_fmt);
|
||||
@@ -122,11 +122,9 @@ int Encoder::init(
|
||||
spdlog::debug("Auto-selected pixel format: {}", av_get_pix_fmt_name(enc_ctx_->pix_fmt));
|
||||
}
|
||||
|
||||
if (processor_config->frm_rate_mul > 0) {
|
||||
if (proc_cfg.frm_rate_mul > 0) {
|
||||
AVRational in_frame_rate = get_video_frame_rate(ifmt_ctx, in_vstream_idx);
|
||||
enc_ctx_->framerate = {
|
||||
in_frame_rate.num * processor_config->frm_rate_mul, in_frame_rate.den
|
||||
};
|
||||
enc_ctx_->framerate = {in_frame_rate.num * proc_cfg.frm_rate_mul, in_frame_rate.den};
|
||||
enc_ctx_->time_base = av_inv_q(enc_ctx_->framerate);
|
||||
} else {
|
||||
// Set the output video's time base
|
||||
@@ -145,13 +143,13 @@ int Encoder::init(
|
||||
}
|
||||
|
||||
// Set extra AVOptions
|
||||
for (size_t i = 0; i < encoder_config->nb_extra_options; i++) {
|
||||
const char *key = encoder_config->extra_options[i].key;
|
||||
const char *value = encoder_config->extra_options[i].value;
|
||||
spdlog::debug("Setting encoder option '{}' to '{}'", key, value);
|
||||
for (const auto &[opt_name, opt_value] : enc_cfg.extra_opts) {
|
||||
std::string opt_name_str = wstring_to_u8string(opt_name);
|
||||
std::string opt_value_str = wstring_to_u8string(opt_value);
|
||||
spdlog::debug("Setting encoder option '{}' to '{}'", opt_name_str, opt_value_str);
|
||||
|
||||
if (av_opt_set(enc_ctx_->priv_data, key, value, 0) < 0) {
|
||||
spdlog::warn("Failed to set encoder option '{}' to '{}'", key, value);
|
||||
if (av_opt_set(enc_ctx_->priv_data, opt_name_str.c_str(), opt_value_str.c_str(), 0) < 0) {
|
||||
spdlog::warn("Failed to set encoder option '{}' to '{}'", opt_name_str, opt_value_str);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +176,7 @@ int Encoder::init(
|
||||
out_vstream->r_frame_rate = enc_ctx_->framerate;
|
||||
|
||||
// Copy other streams if necessary
|
||||
if (encoder_config->copy_streams) {
|
||||
if (enc_cfg.copy_streams) {
|
||||
// Allocate the stream mape frame o
|
||||
stream_map_ =
|
||||
reinterpret_cast<int *>(av_malloc_array(ifmt_ctx->nb_streams, sizeof(*stream_map_)));
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include "char_defs.h"
|
||||
#include "fsutils.h"
|
||||
#include "libplacebo.h"
|
||||
|
||||
@@ -148,12 +147,12 @@ int FilterLibplacebo::flush(std::vector<AVFrame *> &flushed_frames) {
|
||||
}
|
||||
|
||||
void FilterLibplacebo::get_output_dimensions(
|
||||
const ProcessorConfig *processor_config,
|
||||
const ProcessorConfig &proc_cfg,
|
||||
int,
|
||||
int,
|
||||
int &out_width,
|
||||
int &out_height
|
||||
) const {
|
||||
out_width = processor_config->width;
|
||||
out_height = processor_config->height;
|
||||
out_width = proc_cfg.width;
|
||||
out_height = proc_cfg.height;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ int FilterRealesrgan::filter(AVFrame *in_frame, AVFrame **out_frame) {
|
||||
}
|
||||
|
||||
void FilterRealesrgan::get_output_dimensions(
|
||||
const ProcessorConfig *,
|
||||
const ProcessorConfig &,
|
||||
int in_width,
|
||||
int in_height,
|
||||
int &out_width,
|
||||
|
||||
@@ -27,7 +27,7 @@ auto av_packet_deleter = [](AVPacket *packet) {
|
||||
|
||||
// Sets the total number of frames to process in the VideoProcessingContext
|
||||
void set_total_frames(
|
||||
const ProcessorConfig *processor_config,
|
||||
const ProcessorConfig &proc_cfg,
|
||||
VideoProcessingContext *proc_ctx,
|
||||
AVFormatContext *ifmt_ctx,
|
||||
int in_vstream_idx,
|
||||
@@ -44,8 +44,8 @@ void set_total_frames(
|
||||
}
|
||||
|
||||
// Set total frames for interpolation
|
||||
if (processor->get_processing_mode() == PROCESSING_MODE_INTERPOLATE) {
|
||||
proc_ctx->total_frames *= processor_config->frm_rate_mul;
|
||||
if (processor->get_processing_mode() == ProcessingMode::Interpolate) {
|
||||
proc_ctx->total_frames *= proc_cfg.frm_rate_mul;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ int process_filtering(
|
||||
|
||||
int process_interpolation(
|
||||
Processor *processor,
|
||||
const ProcessorConfig *processor_config,
|
||||
const ProcessorConfig &proc_cfg,
|
||||
VideoProcessingContext *proc_ctx,
|
||||
Encoder &encoder,
|
||||
bool benchmark,
|
||||
@@ -141,14 +141,14 @@ int process_interpolation(
|
||||
Interpolator *interpolator = static_cast<Interpolator *>(processor);
|
||||
|
||||
// Calculate the time step for each frame
|
||||
float time_step = 1.0f / static_cast<float>(processor_config->frm_rate_mul);
|
||||
float time_step = 1.0f / static_cast<float>(proc_cfg.frm_rate_mul);
|
||||
float current_time_step = time_step;
|
||||
|
||||
// Check if a scene change is detected
|
||||
bool skip_frame = false;
|
||||
if (prev_frame != nullptr) {
|
||||
float frame_diff = get_frame_diff(prev_frame.get(), frame);
|
||||
if (frame_diff > processor_config->scn_det_thresh) {
|
||||
if (frame_diff > proc_cfg.scn_det_thresh) {
|
||||
spdlog::debug(
|
||||
"Scene change detected ({:.2f}%), skipping frame {}",
|
||||
frame_diff,
|
||||
@@ -159,7 +159,7 @@ int process_interpolation(
|
||||
}
|
||||
|
||||
// Write the interpolated frames
|
||||
for (int i = 0; i < processor_config->frm_rate_mul - 1; i++) {
|
||||
for (int i = 0; i < proc_cfg.frm_rate_mul - 1; i++) {
|
||||
// Skip interpolation if this is the first frame
|
||||
if (prev_frame == nullptr) {
|
||||
break;
|
||||
@@ -206,8 +206,8 @@ int process_interpolation(
|
||||
|
||||
// Process frames using the selected filter.
|
||||
int process_frames(
|
||||
const EncoderConfig *encoder_config,
|
||||
const ProcessorConfig *processor_config,
|
||||
const EncoderConfig &enc_cfg,
|
||||
const ProcessorConfig &proc_cfg,
|
||||
VideoProcessingContext *proc_ctx,
|
||||
Decoder &decoder,
|
||||
Encoder &encoder,
|
||||
@@ -245,7 +245,7 @@ int process_frames(
|
||||
}
|
||||
|
||||
// Set the total number of frames in the VideoProcessingContext
|
||||
set_total_frames(processor_config, proc_ctx, ifmt_ctx, in_vstream_idx, processor);
|
||||
set_total_frames(proc_cfg, proc_ctx, ifmt_ctx, in_vstream_idx, processor);
|
||||
|
||||
// Read frames from the input file
|
||||
while (!proc_ctx->abort) {
|
||||
@@ -292,7 +292,7 @@ int process_frames(
|
||||
|
||||
// Process the frame based on the selected processing mode
|
||||
switch (processor->get_processing_mode()) {
|
||||
case PROCESSING_MODE_FILTER: {
|
||||
case ProcessingMode::Filter: {
|
||||
ret = process_filtering(
|
||||
processor,
|
||||
proc_ctx,
|
||||
@@ -303,10 +303,10 @@ int process_frames(
|
||||
);
|
||||
break;
|
||||
}
|
||||
case PROCESSING_MODE_INTERPOLATE: {
|
||||
case ProcessingMode::Interpolate: {
|
||||
ret = process_interpolation(
|
||||
processor,
|
||||
processor_config,
|
||||
proc_cfg,
|
||||
proc_ctx,
|
||||
encoder,
|
||||
benchmark,
|
||||
@@ -329,7 +329,7 @@ int process_frames(
|
||||
"Processed frame {}/{}", proc_ctx->processed_frames, proc_ctx->total_frames
|
||||
);
|
||||
}
|
||||
} else if (encoder_config->copy_streams && stream_map[packet->stream_index] >= 0) {
|
||||
} else if (enc_cfg.copy_streams && stream_map[packet->stream_index] >= 0) {
|
||||
write_raw_packet(packet.get(), ifmt_ctx, ofmt_ctx, stream_map);
|
||||
}
|
||||
av_packet_unref(packet.get());
|
||||
|
||||
@@ -93,6 +93,33 @@ std::string path_to_u8string(const std::filesystem::path &path) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string wstring_to_u8string(const std::wstring &wstr) {
|
||||
if (wstr.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
int size_needed = WideCharToMultiByte(
|
||||
CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr
|
||||
);
|
||||
std::string converted_str(size_needed, 0);
|
||||
WideCharToMultiByte(
|
||||
CP_UTF8,
|
||||
0,
|
||||
wstr.data(),
|
||||
static_cast<int>(wstr.size()),
|
||||
&converted_str[0],
|
||||
size_needed,
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
return converted_str;
|
||||
}
|
||||
#else
|
||||
std::string wstring_to_u8string(const std::string &str) {
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
StringType path_to_string_type(const std::filesystem::path &path) {
|
||||
#if _WIN32
|
||||
return path.wstring();
|
||||
|
||||
@@ -119,7 +119,7 @@ int InterpolatorRIFE::interpolate(
|
||||
}
|
||||
|
||||
void InterpolatorRIFE::get_output_dimensions(
|
||||
const ProcessorConfig *,
|
||||
const ProcessorConfig &,
|
||||
int in_width,
|
||||
int in_height,
|
||||
int &out_width,
|
||||
|
||||
@@ -16,53 +16,15 @@ extern "C" {
|
||||
#include "processor.h"
|
||||
#include "processor_factory.h"
|
||||
|
||||
static void set_log_level(Libvideo2xLogLevel log_level) {
|
||||
switch (log_level) {
|
||||
case LIBVIDEO2X_LOG_LEVEL_TRACE:
|
||||
av_log_set_level(AV_LOG_TRACE);
|
||||
spdlog::set_level(spdlog::level::trace);
|
||||
break;
|
||||
case LIBVIDEO2X_LOG_LEVEL_DEBUG:
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
spdlog::set_level(spdlog::level::debug);
|
||||
break;
|
||||
case LIBVIDEO2X_LOG_LEVEL_INFO:
|
||||
av_log_set_level(AV_LOG_INFO);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
break;
|
||||
case LIBVIDEO2X_LOG_LEVEL_WARNING:
|
||||
av_log_set_level(AV_LOG_WARNING);
|
||||
spdlog::set_level(spdlog::level::warn);
|
||||
break;
|
||||
case LIBVIDEO2X_LOG_LEVEL_ERROR:
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
spdlog::set_level(spdlog::level::err);
|
||||
break;
|
||||
case LIBVIDEO2X_LOG_LEVEL_CRITICAL:
|
||||
av_log_set_level(AV_LOG_FATAL);
|
||||
spdlog::set_level(spdlog::level::critical);
|
||||
break;
|
||||
case LIBVIDEO2X_LOG_LEVEL_OFF:
|
||||
av_log_set_level(AV_LOG_QUIET);
|
||||
spdlog::set_level(spdlog::level::off);
|
||||
break;
|
||||
default:
|
||||
av_log_set_level(AV_LOG_INFO);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" int process_video(
|
||||
const CharType *in_fname,
|
||||
const CharType *out_fname,
|
||||
int process_video(
|
||||
const std::filesystem::path in_fname,
|
||||
const std::filesystem::path out_fname,
|
||||
const HardwareConfig hw_cfg,
|
||||
const ProcessorConfig proc_cfg,
|
||||
EncoderConfig enc_cfg,
|
||||
VideoProcessingContext *proc_ctx,
|
||||
Libvideo2xLogLevel log_level,
|
||||
bool benchmark,
|
||||
uint32_t vk_device_index,
|
||||
AVHWDeviceType hw_type,
|
||||
const ProcessorConfig *processor_config,
|
||||
EncoderConfig *encoder_config,
|
||||
VideoProcessingContext *proc_ctx
|
||||
bool benchmark
|
||||
) {
|
||||
char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||
int ret = 0;
|
||||
@@ -70,10 +32,6 @@ extern "C" int process_video(
|
||||
// Set the log level for FFmpeg and spdlog
|
||||
set_log_level(log_level);
|
||||
|
||||
// Convert the file names to std::filesystem::path
|
||||
std::filesystem::path in_fpath(in_fname);
|
||||
std::filesystem::path out_fpath(out_fname);
|
||||
|
||||
// Create a smart pointer to manage the hardware device context
|
||||
auto hw_ctx_deleter = [](AVBufferRef *ref) {
|
||||
if (ref != nullptr) {
|
||||
@@ -83,9 +41,9 @@ extern "C" int process_video(
|
||||
std::unique_ptr<AVBufferRef, decltype(hw_ctx_deleter)> hw_ctx(nullptr, hw_ctx_deleter);
|
||||
|
||||
// Initialize hardware device context
|
||||
if (hw_type != AV_HWDEVICE_TYPE_NONE) {
|
||||
if (hw_cfg.hw_device_type != AV_HWDEVICE_TYPE_NONE) {
|
||||
AVBufferRef *tmp_hw_ctx = nullptr;
|
||||
ret = av_hwdevice_ctx_create(&tmp_hw_ctx, hw_type, NULL, NULL, 0);
|
||||
ret = av_hwdevice_ctx_create(&tmp_hw_ctx, hw_cfg.hw_device_type, NULL, NULL, 0);
|
||||
if (ret < 0) {
|
||||
av_strerror(ret, errbuf, sizeof(errbuf));
|
||||
spdlog::critical("Error initializing hardware device context: {}", errbuf);
|
||||
@@ -96,7 +54,7 @@ extern "C" int process_video(
|
||||
|
||||
// Initialize input decoder
|
||||
Decoder decoder;
|
||||
ret = decoder.init(hw_type, hw_ctx.get(), in_fpath);
|
||||
ret = decoder.init(hw_cfg.hw_device_type, hw_ctx.get(), in_fname);
|
||||
if (ret < 0) {
|
||||
av_strerror(ret, errbuf, sizeof(errbuf));
|
||||
spdlog::critical("Failed to initialize decoder: {}", errbuf);
|
||||
@@ -109,7 +67,7 @@ extern "C" int process_video(
|
||||
|
||||
// Create and initialize the appropriate filter
|
||||
std::unique_ptr<Processor> processor(
|
||||
ProcessorFactory::instance().create_processor(processor_config, vk_device_index)
|
||||
ProcessorFactory::instance().create_processor(proc_cfg, hw_cfg.vk_device_index)
|
||||
);
|
||||
if (processor == nullptr) {
|
||||
spdlog::critical("Failed to create filter instance");
|
||||
@@ -119,7 +77,7 @@ extern "C" int process_video(
|
||||
// Initialize output dimensions based on filter configuration
|
||||
int output_width = 0, output_height = 0;
|
||||
processor->get_output_dimensions(
|
||||
processor_config, dec_ctx->width, dec_ctx->height, output_width, output_height
|
||||
proc_cfg, dec_ctx->width, dec_ctx->height, output_width, output_height
|
||||
);
|
||||
if (output_width <= 0 || output_height <= 0) {
|
||||
spdlog::critical("Failed to determine the output dimensions");
|
||||
@@ -127,14 +85,13 @@ extern "C" int process_video(
|
||||
}
|
||||
|
||||
// Update encoder configuration with output dimensions
|
||||
encoder_config->width = output_width;
|
||||
encoder_config->height = output_height;
|
||||
enc_cfg.width = output_width;
|
||||
enc_cfg.height = output_height;
|
||||
|
||||
// Initialize the encoder
|
||||
Encoder encoder;
|
||||
ret = encoder.init(
|
||||
hw_ctx.get(), out_fpath, ifmt_ctx, dec_ctx, encoder_config, processor_config, in_vstream_idx
|
||||
);
|
||||
ret =
|
||||
encoder.init(hw_ctx.get(), out_fname, ifmt_ctx, dec_ctx, enc_cfg, proc_cfg, in_vstream_idx);
|
||||
if (ret < 0) {
|
||||
av_strerror(ret, errbuf, sizeof(errbuf));
|
||||
spdlog::critical("Failed to initialize encoder: {}", errbuf);
|
||||
@@ -149,9 +106,7 @@ extern "C" int process_video(
|
||||
}
|
||||
|
||||
// Process frames using the encoder and decoder
|
||||
ret = process_frames(
|
||||
encoder_config, processor_config, proc_ctx, decoder, encoder, processor.get(), benchmark
|
||||
);
|
||||
ret = process_frames(enc_cfg, proc_cfg, proc_ctx, decoder, encoder, processor.get(), benchmark);
|
||||
if (ret < 0) {
|
||||
av_strerror(ret, errbuf, sizeof(errbuf));
|
||||
spdlog::critical("Error processing frames: {}", errbuf);
|
||||
|
||||
44
src/logging.cpp
Normal file
44
src/logging.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "logging.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/avutil.h>
|
||||
}
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
void set_log_level(Libvideo2xLogLevel log_level) {
|
||||
switch (log_level) {
|
||||
case Libvideo2xLogLevel::Trace:
|
||||
av_log_set_level(AV_LOG_TRACE);
|
||||
spdlog::set_level(spdlog::level::trace);
|
||||
break;
|
||||
case Libvideo2xLogLevel::Debug:
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
spdlog::set_level(spdlog::level::debug);
|
||||
break;
|
||||
case Libvideo2xLogLevel::Info:
|
||||
av_log_set_level(AV_LOG_INFO);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
break;
|
||||
case Libvideo2xLogLevel::Warning:
|
||||
av_log_set_level(AV_LOG_WARNING);
|
||||
spdlog::set_level(spdlog::level::warn);
|
||||
break;
|
||||
case Libvideo2xLogLevel::Error:
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
spdlog::set_level(spdlog::level::err);
|
||||
break;
|
||||
case Libvideo2xLogLevel::Critical:
|
||||
av_log_set_level(AV_LOG_FATAL);
|
||||
spdlog::set_level(spdlog::level::critical);
|
||||
break;
|
||||
case Libvideo2xLogLevel::Off:
|
||||
av_log_set_level(AV_LOG_QUIET);
|
||||
spdlog::set_level(spdlog::level::off);
|
||||
break;
|
||||
default:
|
||||
av_log_set_level(AV_LOG_INFO);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -28,32 +28,33 @@ void ProcessorFactory::register_processor(ProcessorType type, Creator creator) {
|
||||
|
||||
// Create a processor instance
|
||||
std::unique_ptr<Processor> ProcessorFactory::create_processor(
|
||||
const ProcessorConfig *processor_config,
|
||||
const ProcessorConfig &proc_cfg,
|
||||
uint32_t vk_device_index
|
||||
) const {
|
||||
auto it = creators.find(processor_config->processor_type);
|
||||
auto it = creators.find(proc_cfg.processor_type);
|
||||
if (it == creators.end()) {
|
||||
spdlog::critical(
|
||||
"Processor type not registered: {}", static_cast<int>(processor_config->processor_type)
|
||||
"Processor type not registered: {}", static_cast<int>(proc_cfg.processor_type)
|
||||
);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Call the corresponding creator function
|
||||
return it->second(processor_config, vk_device_index);
|
||||
return it->second(proc_cfg, vk_device_index);
|
||||
}
|
||||
|
||||
// Initialize default processors
|
||||
void ProcessorFactory::init_default_processors(ProcessorFactory &factory) {
|
||||
factory.register_processor(
|
||||
PROCESSOR_LIBPLACEBO,
|
||||
[](const ProcessorConfig *config, uint32_t vk_device_index) -> std::unique_ptr<Processor> {
|
||||
const auto &cfg = config->config.libplacebo;
|
||||
if (!cfg.shader_path) {
|
||||
ProcessorType::Libplacebo,
|
||||
[](const ProcessorConfig &proc_cfg,
|
||||
uint32_t vk_device_index) -> std::unique_ptr<Processor> {
|
||||
const auto &config = std::get<LibplaceboConfig>(proc_cfg.config);
|
||||
if (config.shader_path.empty()) {
|
||||
spdlog::critical("Shader path must be provided for the libplacebo filter");
|
||||
return nullptr;
|
||||
}
|
||||
if (config->width <= 0 || config->height <= 0) {
|
||||
if (proc_cfg.width <= 0 || proc_cfg.height <= 0) {
|
||||
spdlog::critical(
|
||||
"Output width and height must be provided for the libplacebo filter"
|
||||
);
|
||||
@@ -61,39 +62,41 @@ void ProcessorFactory::init_default_processors(ProcessorFactory &factory) {
|
||||
}
|
||||
return std::make_unique<FilterLibplacebo>(
|
||||
vk_device_index,
|
||||
std::filesystem::path(cfg.shader_path),
|
||||
config->width,
|
||||
config->height
|
||||
std::filesystem::path(config.shader_path),
|
||||
proc_cfg.width,
|
||||
proc_cfg.height
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
factory.register_processor(
|
||||
PROCESSOR_REALESRGAN,
|
||||
[](const ProcessorConfig *config, uint32_t vk_device_index) -> std::unique_ptr<Processor> {
|
||||
const auto &cfg = config->config.realesrgan;
|
||||
if (config->scaling_factor <= 0) {
|
||||
ProcessorType::RealESRGAN,
|
||||
[](const ProcessorConfig &proc_cfg,
|
||||
uint32_t vk_device_index) -> std::unique_ptr<Processor> {
|
||||
const auto &config = std::get<RealESRGANConfig>(proc_cfg.config);
|
||||
if (proc_cfg.scaling_factor <= 0) {
|
||||
spdlog::critical("Scaling factor must be provided for the RealESRGAN filter");
|
||||
return nullptr;
|
||||
}
|
||||
if (!cfg.model_name) {
|
||||
if (config.model_name.empty()) {
|
||||
spdlog::critical("Model name must be provided for the RealESRGAN filter");
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_unique<FilterRealesrgan>(
|
||||
static_cast<int>(vk_device_index),
|
||||
cfg.tta_mode,
|
||||
config->scaling_factor,
|
||||
cfg.model_name
|
||||
config.tta_mode,
|
||||
proc_cfg.scaling_factor,
|
||||
config.model_name
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
factory.register_processor(
|
||||
PROCESSOR_RIFE,
|
||||
[](const ProcessorConfig *config, uint32_t vk_device_index) -> std::unique_ptr<Processor> {
|
||||
const auto &cfg = config->config.rife;
|
||||
if (!cfg.model_name) {
|
||||
ProcessorType::RIFE,
|
||||
[](const ProcessorConfig &proc_cfg,
|
||||
uint32_t vk_device_index) -> std::unique_ptr<Processor> {
|
||||
const auto &cfg = std::get<RIFEConfig>(proc_cfg.config);
|
||||
if (cfg.model_name.empty()) {
|
||||
spdlog::critical("Model name must be provided for the RIFE filter");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user