From 4f609a5bbbb6cdd2f2dec3a063bc54228391e0a9 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Sat, 18 Nov 2023 13:39:44 +0100 Subject: [PATCH] Make hwdevice configurable for decoding. --- video/ffmpeg_decode.cpp | 2 +- video/ffmpeg_decode.hpp | 1 + video/ffmpeg_encode.cpp | 2 +- video/ffmpeg_hw_device.cpp | 21 ++++++++++++++------- video/ffmpeg_hw_device.hpp | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/video/ffmpeg_decode.cpp b/video/ffmpeg_decode.cpp index 186df966..3b55d725 100644 --- a/video/ffmpeg_decode.cpp +++ b/video/ffmpeg_decode.cpp @@ -1044,7 +1044,7 @@ void VideoDecoder::Impl::begin_audio_stream() bool VideoDecoder::Impl::init_video_decoder_post_device() { - if (!hw.init_codec_context(video.av_codec, device, video.av_ctx)) + if (!hw.init_codec_context(video.av_codec, device, video.av_ctx, opts.hwdevice)) LOGW("Failed to init hardware decode context. Falling back to software.\n"); if (avcodec_open2(video.av_ctx, video.av_codec, nullptr) < 0) diff --git a/video/ffmpeg_decode.hpp b/video/ffmpeg_decode.hpp index 53f9cb4b..7d5e6549 100644 --- a/video/ffmpeg_decode.hpp +++ b/video/ffmpeg_decode.hpp @@ -47,6 +47,7 @@ class VideoDecoder bool blocking = false; float target_video_buffer_time = 0.2f; float target_realtime_audio_buffer_time = 0.5f; + const char *hwdevice = nullptr; }; void set_io_interface(DemuxerIOInterface *iface); diff --git a/video/ffmpeg_encode.cpp b/video/ffmpeg_encode.cpp index ca2c6ae4..91b531f1 100644 --- a/video/ffmpeg_encode.cpp +++ b/video/ffmpeg_encode.cpp @@ -849,7 +849,7 @@ bool VideoEncoder::Impl::init_video_codec() if (avcodec_get_hw_config(codec, 0) != nullptr) { - if (!hw.init_codec_context(codec, device, nullptr)) + if (!hw.init_codec_context(codec, device, nullptr, nullptr)) { LOGW("Failed to init HW encoder context, falling back to software.\n"); return false; diff --git a/video/ffmpeg_hw_device.cpp b/video/ffmpeg_hw_device.cpp index ed43a2d9..2f948b93 100644 --- a/video/ffmpeg_hw_device.cpp +++ b/video/ffmpeg_hw_device.cpp @@ -132,7 +132,7 @@ struct FFmpegHWDevice::Impl } } - bool init_hw_device(const AVCodec *av_codec) + bool init_hw_device(const AVCodec *av_codec, const char *type) { #ifdef HAVE_FFMPEG_VULKAN bool use_vulkan = false; @@ -159,10 +159,15 @@ struct FFmpegHWDevice::Impl #ifdef HAVE_FFMPEG_VULKAN if (config->device_type == AV_HWDEVICE_TYPE_VULKAN && !use_vulkan) continue; - if (config->device_type != AV_HWDEVICE_TYPE_VULKAN && use_vulkan) - continue; #endif + if (type) + { + const char *hwdevice_name = av_hwdevice_get_type_name(config->device_type); + if (strcmp(type, hwdevice_name) != 0) + continue; + } + if ((config->methods & (AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX | AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX)) != 0) init_hw_device_ctx(config); } @@ -221,7 +226,8 @@ struct FFmpegHWDevice::Impl return true; } - bool init_codec_context(const AVCodec *av_codec, Vulkan::Device *device_, AVCodecContext *av_ctx) + bool init_codec_context(const AVCodec *av_codec, Vulkan::Device *device_, + AVCodecContext *av_ctx, const char *type) { if (device && (device != device_ || av_codec != cached_av_codec)) { @@ -235,7 +241,7 @@ struct FFmpegHWDevice::Impl device = device_; cached_av_codec = av_codec; - if (!init_hw_device(av_codec)) + if (!init_hw_device(av_codec, type)) return false; if (av_ctx && (hw_config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0) @@ -294,11 +300,12 @@ FFmpegHWDevice::~FFmpegHWDevice() { } -bool FFmpegHWDevice::init_codec_context(const AVCodec *codec, Vulkan::Device *device, AVCodecContext *ctx) +bool FFmpegHWDevice::init_codec_context(const AVCodec *codec, Vulkan::Device *device, + AVCodecContext *ctx, const char *type) { if (!impl) impl.reset(new Impl); - return impl->init_codec_context(codec, device, ctx); + return impl->init_codec_context(codec, device, ctx, type); } bool FFmpegHWDevice::init_frame_context(AVCodecContext *ctx, diff --git a/video/ffmpeg_hw_device.hpp b/video/ffmpeg_hw_device.hpp index 541571c3..2a6b6898 100644 --- a/video/ffmpeg_hw_device.hpp +++ b/video/ffmpeg_hw_device.hpp @@ -40,7 +40,7 @@ struct FFmpegHWDevice FFmpegHWDevice(); ~FFmpegHWDevice(); - bool init_codec_context(const AVCodec *codec, Vulkan::Device *device, AVCodecContext *ctx); + bool init_codec_context(const AVCodec *codec, Vulkan::Device *device, AVCodecContext *ctx, const char *type); bool init_frame_context(AVCodecContext *ctx, unsigned width, unsigned height, int sw_pixel_format); int get_hw_device_type() const; int get_pix_fmt() const;