mirror of
https://github.com/k4yt3x/video2x.git
synced 2026-02-14 00:54:47 +08:00
feat(ns): improve optimization flags and add namespaces (#1261)
Signed-off-by: k4yt3x <i@k4yt3x.com>
This commit is contained in:
@@ -11,6 +11,9 @@ extern "C" {
|
||||
|
||||
#include "conversions.h"
|
||||
|
||||
namespace video2x {
|
||||
namespace avutils {
|
||||
|
||||
AVRational get_video_frame_rate(AVFormatContext *ifmt_ctx, int in_vstream_idx) {
|
||||
AVRational frame_rate = ifmt_ctx->streams[in_vstream_idx]->avg_frame_rate;
|
||||
if (frame_rate.num == 0 && frame_rate.den == 0) {
|
||||
@@ -147,8 +150,8 @@ float get_frame_diff(AVFrame *frame1, AVFrame *frame2) {
|
||||
|
||||
// Convert both frames to the target pixel format using the provided function
|
||||
AVPixelFormat target_pix_fmt = AV_PIX_FMT_RGB24;
|
||||
AVFrame *rgb_frame1 = convert_avframe_pix_fmt(frame1, target_pix_fmt);
|
||||
AVFrame *rgb_frame2 = convert_avframe_pix_fmt(frame2, target_pix_fmt);
|
||||
AVFrame *rgb_frame1 = conversions::convert_avframe_pix_fmt(frame1, target_pix_fmt);
|
||||
AVFrame *rgb_frame2 = conversions::convert_avframe_pix_fmt(frame2, target_pix_fmt);
|
||||
|
||||
if (!rgb_frame1 || !rgb_frame2) {
|
||||
spdlog::error("Failed to convert frames to target pixel format");
|
||||
@@ -208,3 +211,6 @@ void av_packet_deleter(AVPacket *packet) {
|
||||
packet = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace avutils
|
||||
} // namespace video2x
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace video2x {
|
||||
namespace conversions {
|
||||
|
||||
// Convert AVFrame format
|
||||
AVFrame *convert_avframe_pix_fmt(AVFrame *src_frame, AVPixelFormat pix_fmt) {
|
||||
AVFrame *dst_frame = av_frame_alloc();
|
||||
@@ -195,3 +198,6 @@ AVFrame *ncnn_mat_to_avframe(const ncnn::Mat &mat, AVPixelFormat pix_fmt) {
|
||||
|
||||
return dst_frame;
|
||||
}
|
||||
|
||||
} // namespace conversions
|
||||
} // namespace video2x
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace video2x {
|
||||
namespace decoder {
|
||||
|
||||
AVPixelFormat Decoder::hw_pix_fmt_ = AV_PIX_FMT_NONE;
|
||||
|
||||
Decoder::Decoder() : fmt_ctx_(nullptr), dec_ctx_(nullptr), in_vstream_idx_(-1) {}
|
||||
@@ -130,3 +133,6 @@ AVCodecContext *Decoder::get_codec_context() const {
|
||||
int Decoder::get_video_stream_index() const {
|
||||
return in_vstream_idx_;
|
||||
}
|
||||
|
||||
} // namespace decoder
|
||||
} // namespace video2x
|
||||
|
||||
@@ -9,6 +9,9 @@ extern "C" {
|
||||
#include "avutils.h"
|
||||
#include "conversions.h"
|
||||
|
||||
namespace video2x {
|
||||
namespace encoder {
|
||||
|
||||
Encoder::Encoder()
|
||||
: ofmt_ctx_(nullptr), enc_ctx_(nullptr), out_vstream_idx_(-1), stream_map_(nullptr) {}
|
||||
|
||||
@@ -116,7 +119,7 @@ int Encoder::init(
|
||||
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);
|
||||
enc_ctx_->pix_fmt = avutils::get_encoder_default_pix_fmt(encoder, dec_ctx->pix_fmt);
|
||||
if (enc_ctx_->pix_fmt == AV_PIX_FMT_NONE) {
|
||||
spdlog::error("Could not get the default pixel format for the encoder");
|
||||
return AVERROR(EINVAL);
|
||||
@@ -125,7 +128,7 @@ int Encoder::init(
|
||||
}
|
||||
|
||||
if (frm_rate_mul > 0) {
|
||||
AVRational in_frame_rate = get_video_frame_rate(ifmt_ctx, in_vstream_idx);
|
||||
AVRational in_frame_rate = avutils::get_video_frame_rate(ifmt_ctx, in_vstream_idx);
|
||||
enc_ctx_->framerate = {in_frame_rate.num * frm_rate_mul, in_frame_rate.den};
|
||||
enc_ctx_->time_base = av_inv_q(enc_ctx_->framerate);
|
||||
} else {
|
||||
@@ -146,8 +149,8 @@ int Encoder::init(
|
||||
|
||||
// Set extra AVOptions
|
||||
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);
|
||||
std::string opt_name_str = fsutils::wstring_to_u8string(opt_name);
|
||||
std::string opt_value_str = fsutils::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, opt_name_str.c_str(), opt_value_str.c_str(), 0) < 0) {
|
||||
@@ -262,7 +265,7 @@ int Encoder::write_frame(AVFrame *frame, int64_t frame_idx) {
|
||||
|
||||
// Convert the frame to the encoder's pixel format if needed
|
||||
if (frame->format != enc_ctx_->pix_fmt) {
|
||||
converted_frame = convert_avframe_pix_fmt(frame, enc_ctx_->pix_fmt);
|
||||
converted_frame = conversions::convert_avframe_pix_fmt(frame, enc_ctx_->pix_fmt);
|
||||
if (!converted_frame) {
|
||||
spdlog::error("Error converting frame to encoder's pixel format");
|
||||
return AVERROR_EXTERNAL;
|
||||
@@ -384,3 +387,6 @@ int Encoder::get_output_video_stream_index() const {
|
||||
int *Encoder::get_stream_map() const {
|
||||
return stream_map_;
|
||||
}
|
||||
|
||||
} // namespace encoder
|
||||
} // namespace video2x
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "fsutils.h"
|
||||
#include "libplacebo.h"
|
||||
|
||||
namespace video2x {
|
||||
namespace processors {
|
||||
|
||||
FilterLibplacebo::FilterLibplacebo(
|
||||
uint32_t vk_device_index,
|
||||
const std::filesystem::path &shader_path,
|
||||
@@ -39,14 +42,14 @@ FilterLibplacebo::~FilterLibplacebo() {
|
||||
int FilterLibplacebo::init(AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVBufferRef *) {
|
||||
// Construct the shader path
|
||||
std::filesystem::path shader_full_path;
|
||||
if (filepath_is_readable(shader_path_)) {
|
||||
if (fsutils::filepath_is_readable(shader_path_)) {
|
||||
// If the shader path is directly readable, use it
|
||||
shader_full_path = shader_path_;
|
||||
} else {
|
||||
// Construct the fallback path using std::filesystem
|
||||
shader_full_path = find_resource_file(
|
||||
shader_full_path = fsutils::find_resource_file(
|
||||
std::filesystem::path(STR("models")) / STR("libplacebo") /
|
||||
(path_to_string_type(shader_path_) + STR(".glsl"))
|
||||
(fsutils::path_to_string_type(shader_path_) + STR(".glsl"))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -156,3 +159,6 @@ void FilterLibplacebo::get_output_dimensions(
|
||||
out_width = proc_cfg.width;
|
||||
out_height = proc_cfg.height;
|
||||
}
|
||||
|
||||
} // namespace processors
|
||||
} // namespace video2x
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
#include "conversions.h"
|
||||
#include "fsutils.h"
|
||||
|
||||
namespace video2x {
|
||||
namespace processors {
|
||||
|
||||
FilterRealesrgan::FilterRealesrgan(
|
||||
int gpuid,
|
||||
bool tta_mode,
|
||||
int scaling_factor,
|
||||
const StringType model_name
|
||||
const fsutils::StringType model_name
|
||||
)
|
||||
: realesrgan_(nullptr),
|
||||
gpuid_(gpuid),
|
||||
@@ -33,18 +36,20 @@ int FilterRealesrgan::init(AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVB
|
||||
std::filesystem::path model_param_path;
|
||||
std::filesystem::path model_bin_path;
|
||||
|
||||
StringType param_file_name =
|
||||
model_name_ + STR("-x") + to_string_type(scaling_factor_) + STR(".param");
|
||||
StringType bin_file_name =
|
||||
model_name_ + STR("-x") + to_string_type(scaling_factor_) + STR(".bin");
|
||||
fsutils::StringType param_file_name =
|
||||
model_name_ + STR("-x") + fsutils::to_string_type(scaling_factor_) + STR(".param");
|
||||
fsutils::StringType bin_file_name =
|
||||
model_name_ + STR("-x") + fsutils::to_string_type(scaling_factor_) + STR(".bin");
|
||||
|
||||
// Find the model paths by model name if provided
|
||||
model_param_path = std::filesystem::path(STR("models")) / STR("realesrgan") / param_file_name;
|
||||
model_bin_path = std::filesystem::path(STR("models")) / STR("realesrgan") / bin_file_name;
|
||||
|
||||
// Get the full paths using a function that possibly modifies or validates the path
|
||||
std::filesystem::path model_param_full_path = find_resource_file(model_param_path);
|
||||
std::filesystem::path model_bin_full_path = find_resource_file(model_bin_path);
|
||||
std::filesystem::path model_param_full_path =
|
||||
fsutils::find_resource_file(model_param_path);
|
||||
std::filesystem::path model_bin_full_path =
|
||||
fsutils::find_resource_file(model_bin_path);
|
||||
|
||||
// Check if the model files exist
|
||||
if (!std::filesystem::exists(model_param_full_path)) {
|
||||
@@ -93,7 +98,7 @@ int FilterRealesrgan::filter(AVFrame *in_frame, AVFrame **out_frame) {
|
||||
int ret;
|
||||
|
||||
// Convert the input frame to RGB24
|
||||
ncnn::Mat in_mat = avframe_to_ncnn_mat(in_frame);
|
||||
ncnn::Mat in_mat = conversions::avframe_to_ncnn_mat(in_frame);
|
||||
if (in_mat.empty()) {
|
||||
spdlog::error("Failed to convert AVFrame to ncnn::Mat");
|
||||
return -1;
|
||||
@@ -111,7 +116,7 @@ int FilterRealesrgan::filter(AVFrame *in_frame, AVFrame **out_frame) {
|
||||
}
|
||||
|
||||
// Convert ncnn::Mat to AVFrame
|
||||
*out_frame = ncnn_mat_to_avframe(out_mat, out_pix_fmt_);
|
||||
*out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_);
|
||||
|
||||
// Rescale PTS to encoder's time base
|
||||
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
||||
@@ -130,3 +135,6 @@ void FilterRealesrgan::get_output_dimensions(
|
||||
out_width = in_width * scaling_factor_;
|
||||
out_height = in_height * scaling_factor_;
|
||||
}
|
||||
|
||||
} // namespace processors
|
||||
} // namespace video2x
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace video2x {
|
||||
namespace fsutils {
|
||||
|
||||
#if _WIN32
|
||||
static std::filesystem::path get_executable_directory() {
|
||||
std::vector<wchar_t> filepath(MAX_PATH);
|
||||
@@ -120,7 +123,7 @@ std::string wstring_to_u8string(const std::string &str) {
|
||||
}
|
||||
#endif
|
||||
|
||||
StringType path_to_string_type(const std::filesystem::path &path) {
|
||||
fsutils::StringType path_to_string_type(const std::filesystem::path &path) {
|
||||
#if _WIN32
|
||||
return path.wstring();
|
||||
#else
|
||||
@@ -128,10 +131,13 @@ StringType path_to_string_type(const std::filesystem::path &path) {
|
||||
#endif
|
||||
}
|
||||
|
||||
StringType to_string_type(int value) {
|
||||
fsutils::StringType to_string_type(int value) {
|
||||
#if _WIN32
|
||||
return std::to_wstring(value);
|
||||
#else
|
||||
return std::to_string(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace fsutils
|
||||
} // namespace video2x
|
||||
|
||||
@@ -8,13 +8,16 @@
|
||||
#include "conversions.h"
|
||||
#include "fsutils.h"
|
||||
|
||||
namespace video2x {
|
||||
namespace processors {
|
||||
|
||||
InterpolatorRIFE::InterpolatorRIFE(
|
||||
int gpuid,
|
||||
bool tta_mode,
|
||||
bool tta_temporal_mode,
|
||||
bool uhd_mode,
|
||||
int num_threads,
|
||||
const StringType model_name
|
||||
const fsutils::StringType model_name
|
||||
)
|
||||
: rife_(nullptr),
|
||||
gpuid_(gpuid),
|
||||
@@ -39,7 +42,8 @@ int InterpolatorRIFE::init(AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVB
|
||||
model_param_dir = std::filesystem::path(STR("models")) / STR("rife") / model_name_;
|
||||
|
||||
// Get the full paths using a function that possibly modifies or validates the path
|
||||
std::filesystem::path model_param_full_path = find_resource_file(model_param_dir);
|
||||
std::filesystem::path model_param_full_path =
|
||||
fsutils::find_resource_file(model_param_dir);
|
||||
|
||||
// Check if the model files exist
|
||||
if (!std::filesystem::exists(model_param_full_path)) {
|
||||
@@ -50,13 +54,13 @@ int InterpolatorRIFE::init(AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVB
|
||||
// Automatically infer the RIFE model generation based on the model name
|
||||
bool rife_v2 = false;
|
||||
bool rife_v4 = false;
|
||||
if (model_name_.find(STR("rife-v2")) != StringType::npos) {
|
||||
if (model_name_.find(STR("rife-v2")) != fsutils::StringType::npos) {
|
||||
rife_v2 = true;
|
||||
} else if (model_name_.find(STR("rife-v3")) != StringType::npos) {
|
||||
} else if (model_name_.find(STR("rife-v3")) != fsutils::StringType::npos) {
|
||||
rife_v2 = true;
|
||||
} else if (model_name_.find(STR("rife-v4")) != StringType::npos) {
|
||||
} else if (model_name_.find(STR("rife-v4")) != fsutils::StringType::npos) {
|
||||
rife_v4 = true;
|
||||
} else if (model_name_.find(STR("rife")) == StringType::npos) {
|
||||
} else if (model_name_.find(STR("rife")) == fsutils::StringType::npos) {
|
||||
spdlog::critical("Failed to infer RIFE model generation from model name");
|
||||
return -1;
|
||||
}
|
||||
@@ -87,13 +91,13 @@ int InterpolatorRIFE::interpolate(
|
||||
) {
|
||||
int ret;
|
||||
|
||||
ncnn::Mat in_mat1 = avframe_to_ncnn_mat(prev_frame);
|
||||
ncnn::Mat in_mat1 = conversions::avframe_to_ncnn_mat(prev_frame);
|
||||
if (in_mat1.empty()) {
|
||||
spdlog::error("Failed to convert AVFrame to ncnn::Mat");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ncnn::Mat in_mat2 = avframe_to_ncnn_mat(in_frame);
|
||||
ncnn::Mat in_mat2 = conversions::avframe_to_ncnn_mat(in_frame);
|
||||
if (in_mat2.empty()) {
|
||||
spdlog::error("Failed to convert AVFrame to ncnn::Mat");
|
||||
return -1;
|
||||
@@ -109,7 +113,7 @@ int InterpolatorRIFE::interpolate(
|
||||
}
|
||||
|
||||
// Convert ncnn::Mat to AVFrame
|
||||
*out_frame = ncnn_mat_to_avframe(out_mat, out_pix_fmt_);
|
||||
*out_frame = conversions::ncnn_mat_to_avframe(out_mat, out_pix_fmt_);
|
||||
|
||||
// Rescale PTS to encoder's time base
|
||||
(*out_frame)->pts = av_rescale_q(in_frame->pts, in_time_base_, out_time_base_);
|
||||
@@ -128,3 +132,6 @@ void InterpolatorRIFE::get_output_dimensions(
|
||||
out_width = in_width;
|
||||
out_height = in_height;
|
||||
}
|
||||
|
||||
} // namespace processors
|
||||
} // namespace video2x
|
||||
|
||||
@@ -11,6 +11,9 @@ extern "C" {
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace video2x {
|
||||
namespace processors {
|
||||
|
||||
int init_libplacebo(
|
||||
AVFilterGraph **filter_graph,
|
||||
AVFilterContext **buffersrc_ctx,
|
||||
@@ -161,3 +164,6 @@ int init_libplacebo(
|
||||
*filter_graph = graph;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace processors
|
||||
} // namespace video2x
|
||||
|
||||
@@ -9,16 +9,18 @@ extern "C" {
|
||||
#include "avutils.h"
|
||||
#include "decoder.h"
|
||||
#include "encoder.h"
|
||||
#include "logging.h"
|
||||
#include "logutils.h"
|
||||
#include "processor.h"
|
||||
#include "processor_factory.h"
|
||||
|
||||
namespace video2x {
|
||||
|
||||
VideoProcessor::VideoProcessor(
|
||||
const ProcessorConfig proc_cfg,
|
||||
const EncoderConfig enc_cfg,
|
||||
const processors::ProcessorConfig proc_cfg,
|
||||
const encoder::EncoderConfig enc_cfg,
|
||||
const uint32_t vk_device_idx,
|
||||
const AVHWDeviceType hw_device_type,
|
||||
const Video2xLogLevel log_level,
|
||||
const logutils::Video2xLogLevel log_level,
|
||||
const bool benchmark
|
||||
)
|
||||
: proc_cfg_(proc_cfg),
|
||||
@@ -51,8 +53,8 @@ int VideoProcessor::process(
|
||||
state_.store(VideoProcessorState::Running);
|
||||
|
||||
// Create a smart pointer to manage the hardware device context
|
||||
std::unique_ptr<AVBufferRef, decltype(&av_bufferref_deleter)> hw_ctx(
|
||||
nullptr, &av_bufferref_deleter
|
||||
std::unique_ptr<AVBufferRef, decltype(&avutils::av_bufferref_deleter)> hw_ctx(
|
||||
nullptr, &avutils::av_bufferref_deleter
|
||||
);
|
||||
|
||||
// Initialize hardware device context
|
||||
@@ -66,7 +68,7 @@ int VideoProcessor::process(
|
||||
}
|
||||
|
||||
// Initialize input decoder
|
||||
Decoder decoder;
|
||||
decoder::Decoder decoder;
|
||||
ret = decoder.init(hw_device_type_, hw_ctx.get(), in_fname);
|
||||
if (ret < 0) {
|
||||
return handle_error(ret, "Failed to initialize decoder");
|
||||
@@ -77,8 +79,8 @@ int VideoProcessor::process(
|
||||
int in_vstream_idx = decoder.get_video_stream_index();
|
||||
|
||||
// Create and initialize the appropriate filter
|
||||
std::unique_ptr<Processor> processor(
|
||||
ProcessorFactory::instance().create_processor(proc_cfg_, vk_device_idx_)
|
||||
std::unique_ptr<processors::Processor> processor(
|
||||
processors::ProcessorFactory::instance().create_processor(proc_cfg_, vk_device_idx_)
|
||||
);
|
||||
if (processor == nullptr) {
|
||||
return handle_error(-1, "Failed to create filter instance");
|
||||
@@ -94,7 +96,7 @@ int VideoProcessor::process(
|
||||
}
|
||||
|
||||
// Initialize the encoder
|
||||
Encoder encoder;
|
||||
encoder::Encoder encoder;
|
||||
ret = encoder.init(
|
||||
hw_ctx.get(),
|
||||
out_fname,
|
||||
@@ -140,9 +142,9 @@ int VideoProcessor::process(
|
||||
|
||||
// Process frames using the selected filter.
|
||||
int VideoProcessor::process_frames(
|
||||
Decoder &decoder,
|
||||
Encoder &encoder,
|
||||
std::unique_ptr<Processor> &processor
|
||||
decoder::Decoder &decoder,
|
||||
encoder::Encoder &encoder,
|
||||
std::unique_ptr<processors::Processor> &processor
|
||||
) {
|
||||
char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||
int ret = 0;
|
||||
@@ -156,11 +158,13 @@ int VideoProcessor::process_frames(
|
||||
|
||||
// Reference to the previous frame does not require allocation
|
||||
// It will be cloned from the current frame
|
||||
std::unique_ptr<AVFrame, decltype(&av_frame_deleter)> prev_frame(nullptr, &av_frame_deleter);
|
||||
std::unique_ptr<AVFrame, decltype(&avutils::av_frame_deleter)> prev_frame(
|
||||
nullptr, &avutils::av_frame_deleter
|
||||
);
|
||||
|
||||
// Allocate space for the decoded frames
|
||||
std::unique_ptr<AVFrame, decltype(&av_frame_deleter)> frame(
|
||||
av_frame_alloc(), &av_frame_deleter
|
||||
std::unique_ptr<AVFrame, decltype(&avutils::av_frame_deleter)> frame(
|
||||
av_frame_alloc(), &avutils::av_frame_deleter
|
||||
);
|
||||
if (frame == nullptr) {
|
||||
spdlog::critical("Error allocating frame");
|
||||
@@ -168,8 +172,8 @@ int VideoProcessor::process_frames(
|
||||
}
|
||||
|
||||
// Allocate space for the decoded packets
|
||||
std::unique_ptr<AVPacket, decltype(&av_packet_deleter)> packet(
|
||||
av_packet_alloc(), &av_packet_deleter
|
||||
std::unique_ptr<AVPacket, decltype(&avutils::av_packet_deleter)> packet(
|
||||
av_packet_alloc(), &avutils::av_packet_deleter
|
||||
);
|
||||
if (packet == nullptr) {
|
||||
spdlog::critical("Error allocating packet");
|
||||
@@ -178,7 +182,7 @@ int VideoProcessor::process_frames(
|
||||
|
||||
// Set the total number of frames in the VideoProcessingContext
|
||||
spdlog::debug("Estimating the total number of frames to process");
|
||||
total_frames_ = get_video_frame_count(ifmt_ctx, in_vstream_idx);
|
||||
total_frames_ = avutils::get_video_frame_count(ifmt_ctx, in_vstream_idx);
|
||||
|
||||
if (total_frames_ <= 0) {
|
||||
spdlog::warn("Unable to determine the total number of frames");
|
||||
@@ -188,7 +192,7 @@ int VideoProcessor::process_frames(
|
||||
}
|
||||
|
||||
// Set total frames for interpolation
|
||||
if (processor->get_processing_mode() == ProcessingMode::Interpolate) {
|
||||
if (processor->get_processing_mode() == processors::ProcessingMode::Interpolate) {
|
||||
total_frames_.store(total_frames_.load() * proc_cfg_.frm_rate_mul);
|
||||
}
|
||||
|
||||
@@ -236,11 +240,11 @@ int VideoProcessor::process_frames(
|
||||
// Process the frame based on the selected processing mode
|
||||
AVFrame *proc_frame = nullptr;
|
||||
switch (processor->get_processing_mode()) {
|
||||
case ProcessingMode::Filter: {
|
||||
case processors::ProcessingMode::Filter: {
|
||||
ret = process_filtering(processor, encoder, frame.get(), proc_frame);
|
||||
break;
|
||||
}
|
||||
case ProcessingMode::Interpolate: {
|
||||
case processors::ProcessingMode::Interpolate: {
|
||||
ret = process_interpolation(
|
||||
processor, encoder, prev_frame, frame.get(), proc_frame
|
||||
);
|
||||
@@ -276,9 +280,9 @@ int VideoProcessor::process_frames(
|
||||
}
|
||||
|
||||
// Wrap flushed frames in unique_ptrs
|
||||
std::vector<std::unique_ptr<AVFrame, decltype(&av_frame_deleter)>> flushed_frames;
|
||||
std::vector<std::unique_ptr<AVFrame, decltype(&avutils::av_frame_deleter)>> flushed_frames;
|
||||
for (AVFrame *raw_frame : raw_flushed_frames) {
|
||||
flushed_frames.emplace_back(raw_frame, &av_frame_deleter);
|
||||
flushed_frames.emplace_back(raw_frame, &avutils::av_frame_deleter);
|
||||
}
|
||||
|
||||
// Encode and write all flushed frames
|
||||
@@ -301,7 +305,7 @@ int VideoProcessor::process_frames(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int VideoProcessor::write_frame(AVFrame *frame, Encoder &encoder) {
|
||||
int VideoProcessor::write_frame(AVFrame *frame, encoder::Encoder &encoder) {
|
||||
char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||
int ret = 0;
|
||||
|
||||
@@ -340,8 +344,8 @@ int VideoProcessor::write_raw_packet(
|
||||
}
|
||||
|
||||
int VideoProcessor::process_filtering(
|
||||
std::unique_ptr<Processor> &processor,
|
||||
Encoder &encoder,
|
||||
std::unique_ptr<processors::Processor> &processor,
|
||||
encoder::Encoder &encoder,
|
||||
AVFrame *frame,
|
||||
AVFrame *proc_frame
|
||||
) {
|
||||
@@ -349,7 +353,7 @@ int VideoProcessor::process_filtering(
|
||||
int ret = 0;
|
||||
|
||||
// Cast the processor to a Filter
|
||||
Filter *filter = static_cast<Filter *>(processor.get());
|
||||
processors::Filter *filter = static_cast<processors::Filter *>(processor.get());
|
||||
|
||||
// Process the frame using the filter
|
||||
ret = filter->filter(frame, &proc_frame);
|
||||
@@ -359,17 +363,18 @@ int VideoProcessor::process_filtering(
|
||||
av_strerror(ret, errbuf, sizeof(errbuf));
|
||||
spdlog::critical("Error filtering frame: {}", errbuf);
|
||||
} else if (ret == 0 && proc_frame != nullptr) {
|
||||
auto processed_frame =
|
||||
std::unique_ptr<AVFrame, decltype(&av_frame_deleter)>(proc_frame, &av_frame_deleter);
|
||||
auto processed_frame = std::unique_ptr<AVFrame, decltype(&avutils::av_frame_deleter)>(
|
||||
proc_frame, &avutils::av_frame_deleter
|
||||
);
|
||||
ret = write_frame(processed_frame.get(), encoder);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int VideoProcessor::process_interpolation(
|
||||
std::unique_ptr<Processor> &processor,
|
||||
Encoder &encoder,
|
||||
std::unique_ptr<AVFrame, decltype(&av_frame_deleter)> &prev_frame,
|
||||
std::unique_ptr<processors::Processor> &processor,
|
||||
encoder::Encoder &encoder,
|
||||
std::unique_ptr<AVFrame, decltype(&avutils::av_frame_deleter)> &prev_frame,
|
||||
AVFrame *frame,
|
||||
AVFrame *proc_frame
|
||||
) {
|
||||
@@ -377,7 +382,8 @@ int VideoProcessor::process_interpolation(
|
||||
int ret = 0;
|
||||
|
||||
// Cast the processor to an Interpolator
|
||||
Interpolator *interpolator = static_cast<Interpolator *>(processor.get());
|
||||
processors::Interpolator *interpolator =
|
||||
static_cast<processors::Interpolator *>(processor.get());
|
||||
|
||||
// Calculate the time step for each frame
|
||||
float time_step = 1.0f / static_cast<float>(proc_cfg_.frm_rate_mul);
|
||||
@@ -386,7 +392,7 @@ int VideoProcessor::process_interpolation(
|
||||
// Check if a scene change is detected
|
||||
bool skip_frame = false;
|
||||
if (proc_cfg_.scn_det_thresh < 100.0 && prev_frame.get() != nullptr) {
|
||||
float frame_diff = get_frame_diff(prev_frame.get(), frame);
|
||||
float frame_diff = avutils::get_frame_diff(prev_frame.get(), frame);
|
||||
if (frame_diff > proc_cfg_.scn_det_thresh) {
|
||||
spdlog::debug(
|
||||
"Scene change detected ({:.2f}%), skipping frame {}", frame_diff, frame_idx_.load()
|
||||
@@ -417,8 +423,8 @@ int VideoProcessor::process_interpolation(
|
||||
spdlog::critical("Error interpolating frame: {}", errbuf);
|
||||
return ret;
|
||||
} else if (ret == 0 && proc_frame != nullptr) {
|
||||
auto processed_frame = std::unique_ptr<AVFrame, decltype(&av_frame_deleter)>(
|
||||
proc_frame, &av_frame_deleter
|
||||
auto processed_frame = std::unique_ptr<AVFrame, decltype(&avutils::av_frame_deleter)>(
|
||||
proc_frame, &avutils::av_frame_deleter
|
||||
);
|
||||
|
||||
ret = write_frame(processed_frame.get(), encoder);
|
||||
@@ -438,3 +444,5 @@ int VideoProcessor::process_interpolation(
|
||||
prev_frame.reset(av_frame_clone(frame));
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace video2x
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "logging.h"
|
||||
#include "logutils.h"
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/avutil.h>
|
||||
@@ -6,6 +6,9 @@ extern "C" {
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace video2x {
|
||||
namespace logutils {
|
||||
|
||||
void set_log_level(Video2xLogLevel log_level) {
|
||||
switch (log_level) {
|
||||
case Video2xLogLevel::Trace:
|
||||
@@ -42,3 +45,6 @@ void set_log_level(Video2xLogLevel log_level) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace logutils
|
||||
} // namespace video2x
|
||||
@@ -7,6 +7,9 @@
|
||||
#include "filter_realesrgan.h"
|
||||
#include "interpolator_rife.h"
|
||||
|
||||
namespace video2x {
|
||||
namespace processors {
|
||||
|
||||
// Access the singleton instance
|
||||
ProcessorFactory &ProcessorFactory::instance() {
|
||||
static ProcessorFactory factory;
|
||||
@@ -111,3 +114,6 @@ void ProcessorFactory::init_default_processors(ProcessorFactory &factory) {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace processors
|
||||
} // namespace video2x
|
||||
|
||||
Reference in New Issue
Block a user