FFmpeg
Loading...
Searching...
No Matches
hwdevice.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include <stdio.h>
20
21#include "libavutil/hwcontext.h"
22
23static int test_derivation(AVBufferRef *src_ref, const char *src_name)
24{
25 enum AVHWDeviceType derived_type;
26 const char *derived_name;
27 AVBufferRef *derived_ref = NULL, *back_ref = NULL;
28 AVHWDeviceContext *src_dev, *derived_dev;
29 int err;
30
31 src_dev = (AVHWDeviceContext*)src_ref->data;
32
33 derived_type = AV_HWDEVICE_TYPE_NONE;
34 while (1) {
35 derived_type = av_hwdevice_iterate_types(derived_type);
36 if (derived_type == AV_HWDEVICE_TYPE_NONE)
37 break;
38
39 derived_name = av_hwdevice_get_type_name(derived_type);
40
41 err = av_hwdevice_ctx_create_derived(&derived_ref, derived_type,
42 src_ref, 0);
43 if (err < 0) {
44 fprintf(stderr, "Unable to derive %s -> %s: %d.\n",
45 src_name, derived_name, err);
46 continue;
47 }
48
49 derived_dev = (AVHWDeviceContext*)derived_ref->data;
50 if (derived_dev->type != derived_type) {
51 fprintf(stderr, "Device derived as type %d has type %d.\n",
52 derived_type, derived_dev->type);
53 goto fail;
54 }
55
56 if (derived_type == src_dev->type) {
57 if (derived_dev != src_dev) {
58 fprintf(stderr, "Derivation of %s from itself succeeded "
59 "but did not return the same device.\n", src_name);
60 goto fail;
61 }
62 av_buffer_unref(&derived_ref);
63 continue;
64 }
65
66 err = av_hwdevice_ctx_create_derived(&back_ref, src_dev->type,
67 derived_ref, 0);
68 if (err < 0) {
69 fprintf(stderr, "Derivation %s to %s succeeded, but derivation "
70 "back again failed: %d.\n",
71 src_name, derived_name, err);
72 goto fail;
73 }
74
75 if (back_ref->data != src_ref->data) {
76 fprintf(stderr, "Derivation %s to %s succeeded, but derivation "
77 "back again did not return the original device.\n",
78 src_name, derived_name);
79 goto fail;
80 }
81
82 fprintf(stderr, "Successfully tested derivation %s -> %s.\n",
83 src_name, derived_name);
84
85 av_buffer_unref(&derived_ref);
86 av_buffer_unref(&back_ref);
87 }
88
89 return 0;
90
91fail:
92 av_buffer_unref(&derived_ref);
93 av_buffer_unref(&back_ref);
94 return -1;
95}
96
97static int test_device(enum AVHWDeviceType type, const char *name,
98 const char *device, AVDictionary *opts, int flags)
99{
102 int err;
103
104 err = av_hwdevice_ctx_create(&ref, type, device, opts, flags);
105 if (err < 0) {
106 fprintf(stderr, "Failed to create %s device: %d.\n", name, err);
107 return 1;
108 }
109
110 dev = (AVHWDeviceContext*)ref->data;
111 if (dev->type != type) {
112 fprintf(stderr, "Device created as type %d has type %d.\n",
113 type, dev->type);
115 return -1;
116 }
117
118 fprintf(stderr, "Device type %s successfully created.\n", name);
119
120 err = test_derivation(ref, name);
121
123
124 return err;
125}
126
127static const struct {
129 const char *possible_devices[5];
130} test_devices[] = {
132 { "0", "1", "2" } },
134 { "/dev/dri/card0", "/dev/dri/card1",
135 "/dev/dri/renderD128", "/dev/dri/renderD129" } },
137 { "0", "1", "2" } },
139 { "0", "1", "2" } },
141 { "0", "1", "2" } },
143 { "0.0", "0.1", "1.0", "1.1" } },
145 { "/dev/dri/renderD128", "/dev/dri/renderD129", ":0", "0", "1" } },
147
149{
151 const char *name;
152 int i, j, found, err;
153
155 if (!name) {
156 fprintf(stderr, "No name available for device type %d.\n", type);
157 return -1;
158 }
159
161 if (check != type) {
162 fprintf(stderr, "Type %d maps to name %s maps to type %d.\n",
163 type, name, check);
164 return -1;
165 }
166
167 found = 0;
168
169 err = test_device(type, name, NULL, NULL, 0);
170 if (err < 0) {
171 fprintf(stderr, "Test failed for %s with default options.\n", name);
172 return -1;
173 }
174 if (err == 0) {
175 fprintf(stderr, "Test passed for %s with default options.\n", name);
176 ++found;
177 }
178
179 for (i = 0; i < FF_ARRAY_ELEMS(test_devices); i++) {
180 if (test_devices[i].type != type)
181 continue;
182
183 for (j = 0; test_devices[i].possible_devices[j]; j++) {
184 err = test_device(type, name,
186 NULL, 0);
187 if (err < 0) {
188 fprintf(stderr, "Test failed for %s with device %s.\n",
190 return -1;
191 }
192 if (err == 0) {
193 fprintf(stderr, "Test passed for %s with device %s.\n",
195 ++found;
196 }
197 }
198 }
199
200 return !found;
201}
202
203int main(void)
204{
206 int pass, fail, skip, err;
207
208 pass = fail = skip = 0;
209 while (1) {
212 break;
213
214 err = test_device_type(type);
215 if (err == 0)
216 ++pass;
217 else if (err < 0)
218 ++fail;
219 else
220 ++skip;
221 }
222
223 fprintf(stderr, "Attempted to test %d device types: "
224 "%d passed, %d failed, %d skipped.\n",
225 pass + fail + skip, pass, fail, skip);
226
227 return fail > 0;
228}
static AVDictionary * opts
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define NULL
Definition coverity.c:32
#define fail
Definition test.h:479
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev)
Iterate over supported device types.
Definition hwcontext.c:129
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
Definition hwcontext.c:615
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
Definition hwcontext.c:120
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, enum AVHWDeviceType type, AVBufferRef *src_ref, int flags)
Create a new device of the specified type from an existing device.
Definition hwcontext.c:718
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
Look up an AVHWDeviceType by name.
Definition hwcontext.c:110
AVHWDeviceType
Definition hwcontext.h:27
@ AV_HWDEVICE_TYPE_D3D11VA
Definition hwcontext.h:35
@ AV_HWDEVICE_TYPE_NONE
Definition hwcontext.h:28
@ AV_HWDEVICE_TYPE_OPENCL
Definition hwcontext.h:37
@ AV_HWDEVICE_TYPE_CUDA
Definition hwcontext.h:30
@ AV_HWDEVICE_TYPE_DRM
Definition hwcontext.h:36
@ AV_HWDEVICE_TYPE_D3D12VA
Definition hwcontext.h:40
@ AV_HWDEVICE_TYPE_DXVA2
Definition hwcontext.h:32
@ AV_HWDEVICE_TYPE_VAAPI
Definition hwcontext.h:31
cl_device_type type
const char * possible_devices[5]
Definition hwdevice.c:129
static int test_device(enum AVHWDeviceType type, const char *name, const char *device, AVDictionary *opts, int flags)
Definition hwdevice.c:97
static int test_derivation(AVBufferRef *src_ref, const char *src_name)
Definition hwdevice.c:23
int main(void)
Definition hwdevice.c:203
static const struct @214073112317026074153203046112364171340227055373 test_devices[]
static int test_device_type(enum AVHWDeviceType type)
Definition hwdevice.c:148
#define check(x, y, S, v)
const char * name
Definition qsvenc.c:142
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition hwcontext.h:75
static int ref[MAX_W *MAX_W]