FFmpeg
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 
23 static 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 
91 fail:
92  av_buffer_unref(&derived_ref);
93  av_buffer_unref(&back_ref);
94  return -1;
95 }
96 
97 static int test_device(enum AVHWDeviceType type, const char *name,
98  const char *device, AVDictionary *opts, int flags)
99 {
100  AVBufferRef *ref;
101  AVHWDeviceContext *dev;
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 
127 static 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" } },
146 };
147 
149 {
150  enum AVHWDeviceType check;
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 
203 int 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 }
test_derivation
static int test_derivation(AVBufferRef *src_ref, const char *src_name)
Definition: hwdevice.c:23
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_HWDEVICE_TYPE_NONE
@ AV_HWDEVICE_TYPE_NONE
Definition: hwcontext.h:28
av_hwdevice_find_type_by_name
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
Look up an AVHWDeviceType by name.
Definition: hwcontext.c:102
av_hwdevice_iterate_types
enum AVHWDeviceType av_hwdevice_iterate_types(enum AVHWDeviceType prev)
Iterate over supported device types.
Definition: hwcontext.c:121
AVDictionary
Definition: dict.c:34
AV_HWDEVICE_TYPE_CUDA
@ AV_HWDEVICE_TYPE_CUDA
Definition: hwcontext.h:30
fail
#define fail()
Definition: checkasm.h:188
AV_HWDEVICE_TYPE_D3D11VA
@ AV_HWDEVICE_TYPE_D3D11VA
Definition: hwcontext.h:35
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
check
#define check(x, y, S, v)
Definition: motion_est_template.c:405
AVHWDeviceType
AVHWDeviceType
Definition: hwcontext.h:27
av_hwdevice_get_type_name
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
Definition: hwcontext.c:112
if
if(ret)
Definition: filter_design.txt:179
opts
AVDictionary * opts
Definition: movenc.c:51
NULL
#define NULL
Definition: coverity.c:32
av_buffer_unref
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
AV_HWDEVICE_TYPE_DXVA2
@ AV_HWDEVICE_TYPE_DXVA2
Definition: hwcontext.h:32
AV_HWDEVICE_TYPE_D3D12VA
@ AV_HWDEVICE_TYPE_D3D12VA
Definition: hwcontext.h:40
AV_HWDEVICE_TYPE_OPENCL
@ AV_HWDEVICE_TYPE_OPENCL
Definition: hwcontext.h:37
main
int main(void)
Definition: hwdevice.c:203
type
enum AVHWDeviceType type
Definition: hwdevice.c:128
test_device_type
static int test_device_type(enum AVHWDeviceType type)
Definition: hwdevice.c:148
AV_HWDEVICE_TYPE_VAAPI
@ AV_HWDEVICE_TYPE_VAAPI
Definition: hwcontext.h:31
av_hwdevice_ctx_create_derived
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:703
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
test_device
static int test_device(enum AVHWDeviceType type, const char *name, const char *device, AVDictionary *opts, int flags)
Definition: hwdevice.c:97
AVHWDeviceContext::type
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition: hwcontext.h:72
av_hwdevice_ctx_create
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:600
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
test_devices
static const struct @456 test_devices[]
possible_devices
const char * possible_devices[5]
Definition: hwdevice.c:129
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
hwcontext.h
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
AV_HWDEVICE_TYPE_DRM
@ AV_HWDEVICE_TYPE_DRM
Definition: hwcontext.h:36