UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
hwaccel_libav_common.c
Go to the documentation of this file.
1
7/*
8 * Copyright (c) 2018-2021 CESNET z.s.p.o.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, is permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 *
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 *
24 * This product includes software developed by CESNET z.s.p.o.
25 *
26 * 4. Neither the name of the CESNET nor the names of its contributors may be
27 * used to endorse or promote products derived from this software without
28 * specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
32 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
33 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
34 * EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
40 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
41 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 *
43 */
44#ifdef HAVE_CONFIG_H
45#include "config.h"
46#include "config_unix.h"
47#include "config_win32.h"
48#endif
49
50#include "debug.h"
53#include "types.h"
54#include "utils/color_out.h"
55#include "utils/macros.h"
56
57static const struct {
58 const char *name;
60 enum AVPixelFormat av_pixfmt;
62} accel_str_map[] = {
63 {"vdpau", HWACCEL_VDPAU, AV_PIX_FMT_VDPAU, HW_VDPAU},
64 { "vdpau-copy", HWACCEL_VDPAU, AV_PIX_FMT_VDPAU, HW_VDPAU},
65 { "vaapi", HWACCEL_VAAPI, AV_PIX_FMT_VAAPI, 0 },
66 { "videotoolbox", HWACCEL_VIDEOTOOLBOX, AV_PIX_FMT_VIDEOTOOLBOX, 0 },
67 { "cuda", HWACCEL_CUDA, AV_PIX_FMT_CUDA, 0 },
68#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 75, 100)
69 { "drm-prime", HWACCEL_DRM_PRIME, AV_PIX_FMT_DRM_PRIME, DRM_PRIME },
70#endif
71#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 39, 100)
72 { "vulkan", HWACCEL_VULKAN, AV_PIX_FMT_VULKAN, 0 },
73#endif
74};
75
76enum hw_accel_type hw_accel_from_str(const char *str){
77 if (strcmp(str, "help") == 0) {
78 char msg[STR_LEN] = "Available decode accelerations:";
79 for (unsigned i = 0;
80 i < sizeof(accel_str_map) / sizeof(accel_str_map[0]);
81 i++) {
82 snprintf(msg + strlen(msg), sizeof msg - strlen(msg),
83 " " TBOLD("%s"), accel_str_map[i].name);
84 }
85 color_printf("%s\n", msg);
86 return HWACCEL_NONE;
87 }
88 for(unsigned i = 0; i < sizeof(accel_str_map) / sizeof(accel_str_map[0]); i++){
89 if(strcmp(str, accel_str_map[i].name) == 0){
90 return accel_str_map[i].type;
91 }
92 }
93
94 return HWACCEL_NONE;
95}
96
98hw_accel_from_pixfmt(enum AVPixelFormat pixfmt)
99{
100 for (unsigned i = 0; i < sizeof accel_str_map / sizeof accel_str_map[0];
101 i++) {
102 if (accel_str_map[i].av_pixfmt == pixfmt) {
103 return accel_str_map[i].type;
104 }
105 }
106
107 return HWACCEL_NONE;
108}
109
111 for(unsigned i = 0; i < sizeof(accel_str_map) / sizeof(accel_str_map[0]); i++){
112 if(type == accel_str_map[i].type){
113 return accel_str_map[i].name;
114 }
115 }
116
117 return "unknown";
118}
119
122{
123 for (unsigned i = 0;
124 i < sizeof(accel_str_map) / sizeof(accel_str_map[0]); i++) {
125 if (type == accel_str_map[i].type) {
126 return accel_str_map[i].ug_pixfmt;
127 }
128 }
129 return VIDEO_CODEC_NONE;
130}
131
132void hwaccel_state_init(struct hw_accel_state *hwaccel){
133 hwaccel->type = HWACCEL_NONE;
134 hwaccel->copy = false;
135 hwaccel->uninit = NULL;
136 hwaccel->tmp_frame = NULL;
137 hwaccel->uninit = NULL;
138 hwaccel->ctx = NULL;
139}
140
142 if(hwaccel->ctx){
143 hwaccel->uninit(hwaccel);
144 }
145
146 if(hwaccel->tmp_frame){
147 av_frame_free(&hwaccel->tmp_frame);
148 }
149
150 hwaccel_state_init(hwaccel);
151}
152
153#ifdef HWACC_COMMON_IMPL
154
155int create_hw_device_ctx(enum AVHWDeviceType type, AVBufferRef **device_ref){
156 const char *device_paths[] = { NULL, "/dev/dri/renderD128" };
157
158 int ret;
159 for(size_t i = 0; i < sizeof(device_paths) / sizeof(*device_paths); i++){
160 ret = av_hwdevice_ctx_create(device_ref, type, device_paths[i], NULL, 0);
161 if(ret == 0)
162 return 0;
163 }
164
165 log_msg(LOG_LEVEL_ERROR, "[hw accel] Unable to create hwdevice!!\n");
166 return ret;
167}
168
169int create_hw_frame_ctx(AVBufferRef *device_ref,
170 int width,
171 int height,
172 enum AVPixelFormat format,
173 enum AVPixelFormat sw_format,
174 int decode_surfaces,
175 AVBufferRef **ctx)
176{
177 *ctx = av_hwframe_ctx_alloc(device_ref);
178 if(!*ctx){
179 log_msg(LOG_LEVEL_ERROR, "[hw accel] Failed to allocate hwframe_ctx!!\n");
180 return -1;
181 }
182
183 AVHWFramesContext *frames_ctx = (AVHWFramesContext *)(void *) (*ctx)->data;
184 frames_ctx->format = format;
185 frames_ctx->width = width;
186 frames_ctx->height = height;
187 frames_ctx->sw_format = sw_format;
188 frames_ctx->initial_pool_size = decode_surfaces;
189
190 int ret = av_hwframe_ctx_init(*ctx);
191 if (ret < 0) {
192 av_buffer_unref(ctx);
193 *ctx = NULL;
194 log_msg(LOG_LEVEL_ERROR, "[hw accel] Unable to init hwframe_ctx: %s\n\n",
195 av_err2str(ret));
196 return ret;
197 }
198
199 return 0;
200}
201
202void transfer_frame(struct hw_accel_state *s, AVFrame *frame){
203 log_msg(LOG_LEVEL_DEBUG, "[hw accel] HW frame to CPU transfer\n");
204 av_hwframe_transfer_data(s->tmp_frame, frame, 0);
205
206 av_frame_copy_props(s->tmp_frame, frame);
207
208 av_frame_unref(frame);
209 av_frame_move_ref(frame, s->tmp_frame);
210}
211#endif
struct video_frame * frame
int color_printf(const char *format,...)
#define TBOLD(x)
Definition color_out.h:70
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
enum AVPixelFormat av_pixfmt
const char * hw_accel_to_str(enum hw_accel_type type)
enum hw_accel_type hw_accel_from_pixfmt(enum AVPixelFormat pixfmt)
const char * name
void hwaccel_state_init(struct hw_accel_state *hwaccel)
Initializes hw_accel_state structure.
enum hw_accel_type hw_accel_from_str(const char *str)
codec_t ug_pixfmt
static const struct @20 accel_str_map[]
enum hw_accel_type type
void hwaccel_state_reset(struct hw_accel_state *hwaccel)
Uninitializes existing acceleration and resets hw_accel_state to initial state.
codec_t hw_accel_to_ug_pixfmt(enum hw_accel_type type)
This file contains functions related to hw acceleration.
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
#define AV_PIX_FMT_VULKAN
@ STR_LEN
"standard" string length placeholder
Definition macros.h:134
void(* uninit)(struct hw_accel_state *)
Optional uninit function ptr.
AVFrame * tmp_frame
Temporary frame used when copying.
void * ctx
Type depends on hwaccel type.
enum hw_accel_type type
bool copy
Specifies whether to use the copy mode.
This file contains some common data types.
hw_accel_type
Definition types.h:114
@ HWACCEL_NONE
Definition types.h:115
@ HWACCEL_VULKAN
Definition types.h:120
@ HWACCEL_VDPAU
Definition types.h:116
@ HWACCEL_CUDA
Definition types.h:119
@ HWACCEL_VAAPI
Definition types.h:117
@ HWACCEL_DRM_PRIME
Definition types.h:121
@ HWACCEL_VIDEOTOOLBOX
Definition types.h:118
codec_t
Definition types.h:65
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ HW_VDPAU
VDPAU hardware surface.
Definition types.h:91
@ DRM_PRIME
DRM Prime buffer, data contains struct drm_prime_frame.
Definition types.h:107