mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-24 23:01:10 +00:00
lavd: advertise accelerated codesc if probed
Advertise conversion to HW-accelerated codecs (eg. HW_VDPAU, RPI4_8) only if probe (which now works in the same way as regular init since HEAD^) would initialize to an accelerated codec. This would prevent situations, when eg. `--param use-hw-accel=vaapi -d gl` is used, in which case HW_VDPAU was selected as a display codec, although not intended.
This commit is contained in:
@@ -49,19 +49,22 @@
|
||||
|
||||
#include "hwaccel_libav_common.h"
|
||||
#include "libavcodec/lavc_common.h"
|
||||
#include "types.h"
|
||||
#include "utils/color_out.h"
|
||||
#include "utils/macros.h"
|
||||
|
||||
struct {
|
||||
static const struct {
|
||||
const char *name;
|
||||
enum hw_accel_type type;
|
||||
enum AVPixelFormat av_pixfmt;
|
||||
codec_t ug_pixfmt;
|
||||
} accel_str_map[] = {
|
||||
{"vdpau", HWACCEL_VDPAU},
|
||||
{"vaapi", HWACCEL_VAAPI},
|
||||
{"videotoolbox", HWACCEL_VIDEOTOOLBOX},
|
||||
{"rpi4", HWACCEL_RPI4},
|
||||
{"cuda", HWACCEL_CUDA},
|
||||
{"vulkan", HWACCEL_VULKAN},
|
||||
{"vdpau", HWACCEL_VDPAU, AV_PIX_FMT_VDPAU, HW_VDPAU},
|
||||
{ "vaapi", HWACCEL_VAAPI, AV_PIX_FMT_VAAPI, 0 },
|
||||
{ "videotoolbox", HWACCEL_VIDEOTOOLBOX, AV_PIX_FMT_VIDEOTOOLBOX, 0 },
|
||||
{ "rpi4", HWACCEL_RPI4, AV_PIX_FMT_RPI4_8, RPI4_8 },
|
||||
{ "cuda", HWACCEL_CUDA, AV_PIX_FMT_CUDA, 0 },
|
||||
{ "vulkan", HWACCEL_VULKAN, AV_PIX_FMT_VULKAN, 0 },
|
||||
};
|
||||
|
||||
enum hw_accel_type hw_accel_from_str(const char *str){
|
||||
@@ -84,6 +87,20 @@ enum hw_accel_type hw_accel_from_str(const char *str){
|
||||
|
||||
return HWACCEL_NONE;
|
||||
}
|
||||
|
||||
enum hw_accel_type
|
||||
hw_accel_from_pixfmt(enum AVPixelFormat pixfmt)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof accel_str_map / sizeof accel_str_map[0];
|
||||
i++) {
|
||||
if (accel_str_map[i].av_pixfmt == pixfmt) {
|
||||
return accel_str_map[i].type;
|
||||
}
|
||||
}
|
||||
|
||||
return HWACCEL_NONE;
|
||||
}
|
||||
|
||||
const char *hw_accel_to_str(enum hw_accel_type type){
|
||||
for(unsigned i = 0; i < sizeof(accel_str_map) / sizeof(accel_str_map[0]); i++){
|
||||
if(type == accel_str_map[i].type){
|
||||
@@ -94,6 +111,18 @@ const char *hw_accel_to_str(enum hw_accel_type type){
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
codec_t
|
||||
hw_accel_to_ug_pixfmt(enum hw_accel_type type)
|
||||
{
|
||||
for (unsigned i = 0;
|
||||
i < sizeof(accel_str_map) / sizeof(accel_str_map[0]); i++) {
|
||||
if (type == accel_str_map[i].type) {
|
||||
return accel_str_map[i].ug_pixfmt;
|
||||
}
|
||||
}
|
||||
return VIDEO_CODEC_NONE;
|
||||
}
|
||||
|
||||
void hwaccel_state_init(struct hw_accel_state *hwaccel){
|
||||
hwaccel->type = HWACCEL_NONE;
|
||||
hwaccel->copy = false;
|
||||
|
||||
@@ -56,18 +56,9 @@ extern "C" {
|
||||
#include <libavutil/hwcontext.h>
|
||||
#endif
|
||||
|
||||
enum hw_accel_type {
|
||||
HWACCEL_NONE,
|
||||
HWACCEL_VDPAU,
|
||||
HWACCEL_VAAPI,
|
||||
HWACCEL_VIDEOTOOLBOX,
|
||||
HWACCEL_RPI4,
|
||||
HWACCEL_CUDA,
|
||||
HWACCEL_VULKAN,
|
||||
HWACCEL_COUNT
|
||||
};
|
||||
|
||||
enum hw_accel_type hw_accel_from_pixfmt(enum AVPixelFormat);
|
||||
enum hw_accel_type hw_accel_from_str(const char *str);
|
||||
codec_t hw_accel_to_ug_pixfmt(enum hw_accel_type type);
|
||||
const char *hw_accel_to_str(enum hw_accel_type type);
|
||||
|
||||
/**
|
||||
|
||||
@@ -92,6 +92,14 @@ enum {
|
||||
#define AV_CODEC_CAP_OTHER_THREADS AV_CODEC_CAP_AUTO_THREADS
|
||||
#endif
|
||||
|
||||
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 39, 100)
|
||||
#define AV_PIX_FMT_VULKAN AV_PIX_FMT_NONE
|
||||
#endif
|
||||
#ifndef HWACC_RPI4
|
||||
#define AV_PIX_FMT_RPI4_8 AV_PIX_FMT_NONE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
13
src/types.h
13
src/types.h
@@ -108,13 +108,24 @@ typedef enum {
|
||||
VIDEO_CODEC_END = VIDEO_CODEC_COUNT
|
||||
} codec_t;
|
||||
|
||||
enum hw_accel_type {
|
||||
HWACCEL_NONE,
|
||||
HWACCEL_VDPAU,
|
||||
HWACCEL_VAAPI,
|
||||
HWACCEL_VIDEOTOOLBOX,
|
||||
HWACCEL_RPI4,
|
||||
HWACCEL_CUDA,
|
||||
HWACCEL_VULKAN,
|
||||
HWACCEL_COUNT
|
||||
};
|
||||
|
||||
struct pixfmt_desc {
|
||||
int depth; ///< bit depth; 0 means that whole struct is undefined
|
||||
int subsampling; ///< in 'JabA' format, eg. '4444'
|
||||
bool rgb;
|
||||
enum hw_accel_type accel_type;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum interlacing_t
|
||||
* Specifies interlacing mode of the frame
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "utils/misc.h" // get_cpu_core_count()
|
||||
#include "utils/worker.h"
|
||||
#include "video.h"
|
||||
#include "video_codec.h"
|
||||
#include "video_decompress.h"
|
||||
|
||||
#ifdef HAVE_SWSCALE
|
||||
@@ -573,26 +574,25 @@ static enum AVPixelFormat get_format_callback(struct AVCodecContext *s, const en
|
||||
|
||||
static const struct{
|
||||
enum AVPixelFormat pix_fmt;
|
||||
enum hw_accel_type accel_type;
|
||||
int (*init_func)(AVCodecContext *, struct hw_accel_state *, codec_t);
|
||||
} accels[] = {
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 39, 100)
|
||||
{AV_PIX_FMT_VULKAN, HWACCEL_VULKAN, vulkan_init},
|
||||
{AV_PIX_FMT_VULKAN, vulkan_init},
|
||||
#endif
|
||||
#ifdef HWACC_VDPAU
|
||||
{AV_PIX_FMT_VDPAU, HWACCEL_VDPAU, vdpau_init},
|
||||
{AV_PIX_FMT_VDPAU, vdpau_init},
|
||||
#endif
|
||||
{AV_PIX_FMT_CUDA, HWACCEL_CUDA, hwacc_cuda_init},
|
||||
{AV_PIX_FMT_CUDA, hwacc_cuda_init},
|
||||
#ifdef HWACC_VAAPI
|
||||
{AV_PIX_FMT_VAAPI, HWACCEL_VAAPI, vaapi_init},
|
||||
{AV_PIX_FMT_VAAPI, vaapi_init},
|
||||
#endif
|
||||
#ifdef HAVE_MACOSX
|
||||
{AV_PIX_FMT_VIDEOTOOLBOX, HWACCEL_VIDEOTOOLBOX, videotoolbox_init},
|
||||
{AV_PIX_FMT_VIDEOTOOLBOX, videotoolbox_init},
|
||||
#endif
|
||||
#ifdef HWACC_RPI4
|
||||
{AV_PIX_FMT_RPI4_8, HWACCEL_RPI4, rpi4_hwacc_init},
|
||||
{AV_PIX_FMT_RPI4_8, rpi4_hwacc_init},
|
||||
#endif
|
||||
{AV_PIX_FMT_NONE, HWACCEL_NONE, NULL}
|
||||
{AV_PIX_FMT_NONE, NULL}
|
||||
};
|
||||
|
||||
if (hwaccel != NULL) {
|
||||
@@ -607,18 +607,21 @@ static enum AVPixelFormat get_format_callback(struct AVCodecContext *s, const en
|
||||
: HWACCEL_NONE;
|
||||
for(const enum AVPixelFormat *it = fmt; *it != AV_PIX_FMT_NONE; it++){
|
||||
for(unsigned i = 0; i < sizeof(accels) / sizeof(accels[0]); i++){
|
||||
if(*it == accels[i].pix_fmt && !state->block_accel[accels[i].accel_type])
|
||||
{
|
||||
if(forced_hwaccel != HWACCEL_NONE && accels[i].accel_type != forced_hwaccel){
|
||||
break;
|
||||
}
|
||||
int ret = accels[i].init_func(s, &state->hwaccel, state->out_codec);
|
||||
if(ret < 0){
|
||||
hwaccel_state_reset(&state->hwaccel);
|
||||
break;
|
||||
}
|
||||
SELECT_PIXFMT(accels[i].pix_fmt);
|
||||
if (*it != accels[i].pix_fmt ||
|
||||
state->block_accel[hw_accel_from_pixfmt(accels[i].pix_fmt)]) {
|
||||
continue;
|
||||
}
|
||||
if (forced_hwaccel != HWACCEL_NONE &&
|
||||
hw_accel_from_pixfmt(accels[i].pix_fmt) !=
|
||||
forced_hwaccel) {
|
||||
break;
|
||||
}
|
||||
int ret = accels[i].init_func(s, &state->hwaccel, state->out_codec);
|
||||
if(ret < 0){
|
||||
hwaccel_state_reset(&state->hwaccel);
|
||||
break;
|
||||
}
|
||||
SELECT_PIXFMT(accels[i].pix_fmt);
|
||||
}
|
||||
}
|
||||
if(forced_hwaccel != HWACCEL_NONE){
|
||||
@@ -1074,6 +1077,8 @@ static decompress_status libavcodec_decompress(void *state, unsigned char *dst,
|
||||
av_get_pix_fmt_name(s->codec_ctx->pix_fmt),
|
||||
av_get_pix_fmt_name(s->codec_ctx->sw_pix_fmt));
|
||||
*internal_props = av_pixfmt_get_desc(s->codec_ctx->sw_pix_fmt);
|
||||
internal_props->accel_type =
|
||||
hw_accel_from_pixfmt(s->codec_ctx->pix_fmt);
|
||||
return DECODER_GOT_CODEC;
|
||||
}
|
||||
|
||||
@@ -1130,9 +1135,7 @@ static void libavcodec_decompress_done(void *state)
|
||||
* This should be take into account existing conversions.
|
||||
*/
|
||||
static int libavcodec_decompress_get_priority(codec_t compression, struct pixfmt_desc internal, codec_t ugc) {
|
||||
if (get_commandline_param("use-hw-accel") &&
|
||||
(((compression == H264 || compression == H265) && ugc == HW_VDPAU) ||
|
||||
(compression == H265 && ugc == RPI4_8))) {
|
||||
if (hw_accel_to_ug_pixfmt(internal.accel_type) == ugc) {
|
||||
return 200;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user