feat(libplacebo): added Vulkan device selection for libplacebo

Signed-off-by: k4yt3x <i@k4yt3x.com>
This commit is contained in:
k4yt3x 2024-11-04 00:00:00 +00:00
parent 77a06e7d92
commit ec4b51064a
No known key found for this signature in database
6 changed files with 37 additions and 15 deletions

View File

@ -9,13 +9,13 @@ extern "C" {
} }
int init_libplacebo( int init_libplacebo(
AVBufferRef *hw_ctx,
AVFilterGraph **filter_graph, AVFilterGraph **filter_graph,
AVFilterContext **buffersrc_ctx, AVFilterContext **buffersrc_ctx,
AVFilterContext **buffersink_ctx, AVFilterContext **buffersink_ctx,
AVCodecContext *dec_ctx, AVCodecContext *dec_ctx,
int out_width, int out_width,
int out_height, int out_height,
uint32_t vk_device_index,
const std::filesystem::path &shader_path const std::filesystem::path &shader_path
); );

View File

@ -17,15 +17,21 @@ class LibplaceboFilter : public Filter {
AVFilterGraph *filter_graph; AVFilterGraph *filter_graph;
AVFilterContext *buffersrc_ctx; AVFilterContext *buffersrc_ctx;
AVFilterContext *buffersink_ctx; AVFilterContext *buffersink_ctx;
uint32_t vk_device_index;
const std::filesystem::path shader_path;
int out_width; int out_width;
int out_height; int out_height;
const std::filesystem::path shader_path;
AVRational in_time_base; AVRational in_time_base;
AVRational out_time_base; AVRational out_time_base;
public: public:
// Constructor // Constructor
LibplaceboFilter(int width, int height, const std::filesystem::path &shader_path); LibplaceboFilter(
uint32_t vk_device_index,
const std::filesystem::path &shader_path,
int width,
int height
);
// Destructor // Destructor
virtual ~LibplaceboFilter() override; virtual ~LibplaceboFilter() override;

View File

@ -2,25 +2,37 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string>
extern "C" { extern "C" {
#include <libavutil/dict.h>
#include <libavutil/opt.h> #include <libavutil/opt.h>
} }
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
int init_libplacebo( int init_libplacebo(
AVBufferRef *hw_ctx,
AVFilterGraph **filter_graph, AVFilterGraph **filter_graph,
AVFilterContext **buffersrc_ctx, AVFilterContext **buffersrc_ctx,
AVFilterContext **buffersink_ctx, AVFilterContext **buffersink_ctx,
AVCodecContext *dec_ctx, AVCodecContext *dec_ctx,
int out_width, int out_width,
int out_height, int out_height,
uint32_t vk_device_index,
const std::filesystem::path &shader_path const std::filesystem::path &shader_path
) { ) {
int ret; int ret;
// Create the Vulkan hardware device context
AVBufferRef *vk_hw_device_ctx = nullptr;
ret = av_hwdevice_ctx_create(
&vk_hw_device_ctx, AV_HWDEVICE_TYPE_VULKAN, std::to_string(vk_device_index).c_str(), NULL, 0
);
if (ret < 0) {
spdlog::error("Failed to create Vulkan hardware device context.");
return ret;
}
AVFilterGraph *graph = avfilter_graph_alloc(); AVFilterGraph *graph = avfilter_graph_alloc();
if (!graph) { if (!graph) {
spdlog::error("Unable to create filter graph."); spdlog::error("Unable to create filter graph.");
@ -106,9 +118,8 @@ int init_libplacebo(
} }
// Set the hardware device context to Vulkan // Set the hardware device context to Vulkan
if (hw_ctx != nullptr) { libplacebo_ctx->hw_device_ctx = av_buffer_ref(vk_hw_device_ctx);
libplacebo_ctx->hw_device_ctx = av_buffer_ref(hw_ctx); av_buffer_unref(&vk_hw_device_ctx);
}
// Link buffersrc to libplacebo // Link buffersrc to libplacebo
ret = avfilter_link(last_filter, 0, libplacebo_ctx, 0); ret = avfilter_link(last_filter, 0, libplacebo_ctx, 0);

View File

@ -9,16 +9,18 @@
#include "libplacebo.h" #include "libplacebo.h"
LibplaceboFilter::LibplaceboFilter( LibplaceboFilter::LibplaceboFilter(
uint32_t vk_device_index,
const std::filesystem::path &shader_path,
int out_width, int out_width,
int out_height, int out_height
const std::filesystem::path &shader_path
) )
: filter_graph(nullptr), : filter_graph(nullptr),
buffersrc_ctx(nullptr), buffersrc_ctx(nullptr),
buffersink_ctx(nullptr), buffersink_ctx(nullptr),
vk_device_index(vk_device_index),
shader_path(std::move(shader_path)),
out_width(out_width), out_width(out_width),
out_height(out_height), out_height(out_height) {}
shader_path(std::move(shader_path)) {}
LibplaceboFilter::~LibplaceboFilter() { LibplaceboFilter::~LibplaceboFilter() {
if (buffersrc_ctx) { if (buffersrc_ctx) {
@ -35,7 +37,7 @@ LibplaceboFilter::~LibplaceboFilter() {
} }
} }
int LibplaceboFilter::init(AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVBufferRef *hw_ctx) { int LibplaceboFilter::init(AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVBufferRef *_) {
// Construct the shader path // Construct the shader path
std::filesystem::path shader_full_path; std::filesystem::path shader_full_path;
if (filepath_is_readable(shader_path)) { if (filepath_is_readable(shader_path)) {
@ -61,13 +63,13 @@ int LibplaceboFilter::init(AVCodecContext *dec_ctx, AVCodecContext *enc_ctx, AVB
// Initialize the libplacebo filter // Initialize the libplacebo filter
int ret = init_libplacebo( int ret = init_libplacebo(
hw_ctx,
&filter_graph, &filter_graph,
&buffersrc_ctx, &buffersrc_ctx,
&buffersink_ctx, &buffersink_ctx,
dec_ctx, dec_ctx,
out_width, out_width,
out_height, out_height,
vk_device_index,
shader_full_path shader_full_path
); );

View File

@ -413,7 +413,10 @@ extern "C" int process_video(
return -1; return -1;
} }
filter = new LibplaceboFilter{ filter = new LibplaceboFilter{
config.out_width, config.out_height, std::filesystem::path(config.shader_path) vk_device_index,
std::filesystem::path(config.shader_path),
config.out_width,
config.out_height
}; };
} else if (filter_config->filter_type == FILTER_REALESRGAN) { } else if (filter_config->filter_type == FILTER_REALESRGAN) {
const auto &config = filter_config->config.realesrgan; const auto &config = filter_config->config.realesrgan;

View File

@ -702,7 +702,7 @@ int main(int argc, char **argv) {
spdlog::warn("Video processing aborted"); spdlog::warn("Video processing aborted");
return 2; return 2;
} else if (proc_ret != 0) { } else if (proc_ret != 0) {
spdlog::error("Video processing failed with error code {}", proc_ret); spdlog::critical("Video processing failed with error code {}", proc_ret);
return 1; return 1;
} else { } else {
spdlog::info("Video processed successfully"); spdlog::info("Video processed successfully");