mirror of
https://github.com/k4yt3x/video2x.git
synced 2025-01-15 04:08:52 +00:00
fix(fsutils): fix resource finding in AppImage
Signed-off-by: k4yt3x <i@k4yt3x.com>
This commit is contained in:
parent
55556e60a1
commit
774fd4f8c2
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace video2x {
|
namespace video2x {
|
||||||
@ -20,9 +21,9 @@ typedef std::wstring StringType;
|
|||||||
typedef std::string StringType;
|
typedef std::string StringType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool filepath_is_readable(const std::filesystem::path& path);
|
bool file_is_readable(const std::filesystem::path& path);
|
||||||
|
|
||||||
std::filesystem::path find_resource_file(const std::filesystem::path& path);
|
std::optional<std::filesystem::path> find_resource(const std::filesystem::path& resource);
|
||||||
|
|
||||||
std::string path_to_u8string(const std::filesystem::path& path);
|
std::string path_to_u8string(const std::filesystem::path& path);
|
||||||
|
|
||||||
|
@ -42,20 +42,20 @@ FilterLibplacebo::~FilterLibplacebo() {
|
|||||||
|
|
||||||
int FilterLibplacebo::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVBufferRef*) {
|
int FilterLibplacebo::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVBufferRef*) {
|
||||||
// Construct the shader path
|
// Construct the shader path
|
||||||
std::filesystem::path shader_full_path;
|
std::optional<std::filesystem::path> shader_full_path = std::nullopt;
|
||||||
if (fsutils::filepath_is_readable(shader_path_)) {
|
if (fsutils::file_is_readable(shader_path_)) {
|
||||||
// If the shader path is directly readable, use it
|
// If the shader path is directly readable, use it
|
||||||
shader_full_path = shader_path_;
|
shader_full_path = shader_path_;
|
||||||
} else {
|
} else {
|
||||||
// Construct the fallback path using std::filesystem
|
// Construct the fallback path using std::filesystem
|
||||||
shader_full_path = fsutils::find_resource_file(
|
shader_full_path = fsutils::find_resource(
|
||||||
std::filesystem::path(STR("models")) / STR("libplacebo") /
|
std::filesystem::path(STR("models")) / STR("libplacebo") /
|
||||||
(fsutils::path_to_string_type(shader_path_) + STR(".glsl"))
|
(fsutils::path_to_string_type(shader_path_) + STR(".glsl"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the shader file exists
|
// Check if the shader file exists
|
||||||
if (!std::filesystem::exists(shader_full_path)) {
|
if (!shader_full_path.has_value()) {
|
||||||
logger()->error("libplacebo shader file not found: '{}'", shader_path_.u8string());
|
logger()->error("libplacebo shader file not found: '{}'", shader_path_.u8string());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ int FilterLibplacebo::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVB
|
|||||||
width_,
|
width_,
|
||||||
height_,
|
height_,
|
||||||
vk_device_index_,
|
vk_device_index_,
|
||||||
shader_full_path
|
shader_full_path.value()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set these resources to nullptr since they are already freed by `avfilter_graph_free`
|
// Set these resources to nullptr since they are already freed by `avfilter_graph_free`
|
||||||
|
@ -66,20 +66,22 @@ int FilterRealcugan::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVBu
|
|||||||
std::filesystem::path(STR("models")) / STR("realcugan") / model_name_ / bin_file_name;
|
std::filesystem::path(STR("models")) / STR("realcugan") / model_name_ / bin_file_name;
|
||||||
|
|
||||||
// Get the full paths using a function that possibly modifies or validates the path
|
// Get the full paths using a function that possibly modifies or validates the path
|
||||||
std::filesystem::path model_param_full_path = fsutils::find_resource_file(model_param_path);
|
std::optional<std::filesystem::path> model_param_full_path =
|
||||||
std::filesystem::path model_bin_full_path = fsutils::find_resource_file(model_bin_path);
|
fsutils::find_resource(model_param_path);
|
||||||
|
std::optional<std::filesystem::path> model_bin_full_path =
|
||||||
|
fsutils::find_resource(model_bin_path);
|
||||||
|
|
||||||
// Check if the model files exist
|
// Check if the model files exist
|
||||||
if (!std::filesystem::exists(model_param_full_path)) {
|
if (!model_param_full_path.has_value()) {
|
||||||
logger()->error("RealCUGAN model param file not found: {}", model_param_path.u8string());
|
logger()->error("Real-CUGAN model param file not found: {}", model_param_path.u8string());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!std::filesystem::exists(model_bin_full_path)) {
|
if (!model_bin_full_path.has_value()) {
|
||||||
logger()->error("RealCUGAN model bin file not found: {}", model_bin_path.u8string());
|
logger()->error("Real-CUGAN model bin file not found: {}", model_bin_path.u8string());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RealCUGAN instance
|
// Create a new Real-CUGAN instance
|
||||||
realcugan_ = new RealCUGAN(gpuid_, tta_mode_, num_threads_);
|
realcugan_ = new RealCUGAN(gpuid_, tta_mode_, num_threads_);
|
||||||
|
|
||||||
// Store the time bases
|
// Store the time bases
|
||||||
@ -88,8 +90,8 @@ int FilterRealcugan::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVBu
|
|||||||
out_pix_fmt_ = enc_ctx->pix_fmt;
|
out_pix_fmt_ = enc_ctx->pix_fmt;
|
||||||
|
|
||||||
// Load the model
|
// Load the model
|
||||||
if (realcugan_->load(model_param_full_path, model_bin_full_path) != 0) {
|
if (realcugan_->load(model_param_full_path.value(), model_bin_full_path.value()) != 0) {
|
||||||
logger()->error("Failed to load RealCUGAN model");
|
logger()->error("Failed to load Real-CUGAN model");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +178,7 @@ int FilterRealcugan::filter(AVFrame* in_frame, AVFrame** out_frame) {
|
|||||||
|
|
||||||
ret = realcugan_->process(in_mat, out_mat);
|
ret = realcugan_->process(in_mat, out_mat);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
logger()->error("RealCUGAN processing failed");
|
logger()->error("Real-CUGAN processing failed");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,20 +45,22 @@ int FilterRealesrgan::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVB
|
|||||||
model_bin_path = std::filesystem::path(STR("models")) / STR("realesrgan") / bin_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
|
// Get the full paths using a function that possibly modifies or validates the path
|
||||||
std::filesystem::path model_param_full_path = fsutils::find_resource_file(model_param_path);
|
std::optional<std::filesystem::path> model_param_full_path =
|
||||||
std::filesystem::path model_bin_full_path = fsutils::find_resource_file(model_bin_path);
|
fsutils::find_resource(model_param_path);
|
||||||
|
std::optional<std::filesystem::path> model_bin_full_path =
|
||||||
|
fsutils::find_resource(model_bin_path);
|
||||||
|
|
||||||
// Check if the model files exist
|
// Check if the model files exist
|
||||||
if (!std::filesystem::exists(model_param_full_path)) {
|
if (!model_param_full_path.has_value()) {
|
||||||
logger()->error("RealESRGAN model param file not found: {}", model_param_path.u8string());
|
logger()->error("Real-ESRGAN model param file not found: {}", model_param_path.u8string());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!std::filesystem::exists(model_bin_full_path)) {
|
if (!model_bin_full_path.has_value()) {
|
||||||
logger()->error("RealESRGAN model bin file not found: {}", model_bin_path.u8string());
|
logger()->error("Real-ESRGAN model bin file not found: {}", model_bin_path.u8string());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new RealESRGAN instance
|
// Create a new Real-ESRGAN instance
|
||||||
realesrgan_ = new RealESRGAN(gpuid_, tta_mode_);
|
realesrgan_ = new RealESRGAN(gpuid_, tta_mode_);
|
||||||
|
|
||||||
// Store the time bases
|
// Store the time bases
|
||||||
@ -67,12 +69,12 @@ int FilterRealesrgan::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVB
|
|||||||
out_pix_fmt_ = enc_ctx->pix_fmt;
|
out_pix_fmt_ = enc_ctx->pix_fmt;
|
||||||
|
|
||||||
// Load the model
|
// Load the model
|
||||||
if (realesrgan_->load(model_param_full_path, model_bin_full_path) != 0) {
|
if (realesrgan_->load(model_param_full_path.value(), model_bin_full_path.value()) != 0) {
|
||||||
logger()->error("Failed to load RealESRGAN model");
|
logger()->error("Failed to load Real-ESRGAN model");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set RealESRGAN parameters
|
// Set Real-ESRGAN parameters
|
||||||
realesrgan_->scale = scaling_factor_;
|
realesrgan_->scale = scaling_factor_;
|
||||||
realesrgan_->prepadding = 10;
|
realesrgan_->prepadding = 10;
|
||||||
|
|
||||||
@ -108,7 +110,7 @@ int FilterRealesrgan::filter(AVFrame* in_frame, AVFrame** out_frame) {
|
|||||||
|
|
||||||
ret = realesrgan_->process(in_mat, out_mat);
|
ret = realesrgan_->process(in_mat, out_mat);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
logger()->error("RealESRGAN processing failed");
|
logger()->error("Real-ESRGAN processing failed");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,13 +54,13 @@ static std::filesystem::path get_executable_directory() {
|
|||||||
}
|
}
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
bool filepath_is_readable(const std::filesystem::path& path) {
|
bool file_is_readable(const std::filesystem::path& path) {
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
FILE* fp = _wfopen(path.c_str(), L"rb");
|
FILE* fp = _wfopen(path.c_str(), L"rb");
|
||||||
#else // _WIN32
|
#else
|
||||||
FILE* fp = fopen(path.c_str(), "rb");
|
FILE* fp = fopen(path.c_str(), "rb");
|
||||||
#endif // _WIN32
|
#endif
|
||||||
if (!fp) {
|
if (fp == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,16 +68,40 @@ bool filepath_is_readable(const std::filesystem::path& path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path find_resource_file(const std::filesystem::path& path) {
|
std::optional<std::filesystem::path> find_resource(const std::filesystem::path& resource) {
|
||||||
if (filepath_is_readable(path)) {
|
// Build a list of candidate directories
|
||||||
return path;
|
std::vector<std::filesystem::path> candidates;
|
||||||
|
|
||||||
|
// 1. The resource's path as provided
|
||||||
|
candidates.push_back(resource);
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// 2. AppImage's mounted directory
|
||||||
|
if (const char* appdir = std::getenv("APPDIR")) {
|
||||||
|
candidates.push_back(
|
||||||
|
std::filesystem::path(appdir) / "usr" / "share" / "video2x" / resource
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filepath_is_readable(std::filesystem::path("/usr/share/video2x/") / path)) {
|
// 3. The Linux standard local data directory
|
||||||
return std::filesystem::path("/usr/share/video2x/") / path;
|
candidates.push_back(std::filesystem::path("/usr/local/share/video2x") / resource);
|
||||||
|
|
||||||
|
// 4. The Linux standard data directory
|
||||||
|
candidates.push_back(std::filesystem::path("/usr/share/video2x") / resource);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 5. The executable's parent directory
|
||||||
|
candidates.push_back(get_executable_directory() / resource);
|
||||||
|
|
||||||
|
// Iterate over the candidate directories and return the first readable file
|
||||||
|
for (const auto& candidate : candidates) {
|
||||||
|
if (file_is_readable(candidate) || std::filesystem::is_directory(candidate)) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_executable_directory() / path;
|
// Return nullopt if the resource was not found
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path_to_u8string(const std::filesystem::path& path) {
|
std::string path_to_u8string(const std::filesystem::path& path) {
|
||||||
@ -119,11 +143,11 @@ std::string wstring_to_u8string(const std::wstring& wstr) {
|
|||||||
);
|
);
|
||||||
return converted_str;
|
return converted_str;
|
||||||
}
|
}
|
||||||
#else
|
#else // _WIN32
|
||||||
std::string wstring_to_u8string(const std::string& str) {
|
std::string wstring_to_u8string(const std::string& str) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // _WIN32
|
||||||
|
|
||||||
fsutils::StringType path_to_string_type(const std::filesystem::path& path) {
|
fsutils::StringType path_to_string_type(const std::filesystem::path& path) {
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
@ -35,17 +35,15 @@ InterpolatorRIFE::~InterpolatorRIFE() {
|
|||||||
|
|
||||||
int InterpolatorRIFE::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVBufferRef*) {
|
int InterpolatorRIFE::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVBufferRef*) {
|
||||||
// Construct the model directory path using std::filesystem
|
// Construct the model directory path using std::filesystem
|
||||||
std::filesystem::path model_param_dir;
|
std::filesystem::path model_dir =
|
||||||
|
std::filesystem::path(STR("models")) / STR("rife") / model_name_;
|
||||||
// Find the model paths by model name if provided
|
|
||||||
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
|
// Get the full paths using a function that possibly modifies or validates the path
|
||||||
std::filesystem::path model_param_full_path = fsutils::find_resource_file(model_param_dir);
|
std::optional<std::filesystem::path> model_dir_full_path = fsutils::find_resource(model_dir);
|
||||||
|
|
||||||
// Check if the model files exist
|
// Check if the model files exist
|
||||||
if (!std::filesystem::exists(model_param_full_path)) {
|
if (!model_dir_full_path.has_value()) {
|
||||||
logger()->error("RIFE model param directory not found: {}", model_param_dir.u8string());
|
logger()->error("RIFE model param directory not found: {}", model_dir.u8string());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +71,7 @@ int InterpolatorRIFE::init(AVCodecContext* dec_ctx, AVCodecContext* enc_ctx, AVB
|
|||||||
out_pix_fmt_ = enc_ctx->pix_fmt;
|
out_pix_fmt_ = enc_ctx->pix_fmt;
|
||||||
|
|
||||||
// Load the model
|
// Load the model
|
||||||
if (rife_->load(model_param_full_path) != 0) {
|
if (rife_->load(model_dir_full_path.value()) != 0) {
|
||||||
logger()->error("Failed to load RIFE model");
|
logger()->error("Failed to load RIFE model");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user