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 <string.h>
20
22
24
27
29 {
31 int i;
33 if (hw_devices[i]->type == type) {
34 if (found)
36 found = hw_devices[i];
37 }
38 }
39 return found;
40 }
41
43 {
44 int i;
46 if (!strcmp(hw_devices[i]->name, name))
47 return hw_devices[i];
48 }
50 }
51
53 {
54 int err;
56 sizeof(*hw_devices));
57 if (err) {
60 }
64 return hw_devices[nb_hw_devices++];
65 }
66
68 {
69 // Make an automatic name of the form "type%d". We arbitrarily
70 // limit at 1000 anonymous devices of the same type - there is
71 // probably something else very wrong if you get to this limit.
74 size_t index_pos;
75 int index, index_limit = 1000;
76 index_pos = strlen(type_name);
78 if (!name)
80 for (index = 0; index < index_limit; index++) {
81 snprintf(name, index_pos + 4,
"%s%d", type_name, index);
83 break;
84 }
85 if (index >= index_limit) {
88 }
90 }
91
93 {
94 // "type=name:device,key=value,key2=value2"
95 // "type:device,key=value,key2=value2"
96 // -> av_hwdevice_ctx_create()
97 // "type=name@name"
98 // "type@name"
99 // -> av_hwdevice_ctx_create_derived()
100
106 int err;
107 const char *errmsg, *p, *q;
108 size_t k;
109
110 k = strcspn(arg, ":=@");
111 p = arg + k;
112
114 if (!type_name) {
117 }
120 errmsg = "unknown device type";
121 goto invalid;
122 }
123
124 if (*p == '=') {
125 k = strcspn(p + 1, ":@");
126
128 if (!name) {
131 }
133 errmsg = "named device already exists";
134 goto invalid;
135 }
136
137 p += 1 + k;
138 } else {
140 if (!name) {
143 }
144 }
145
146 if (!*p) {
147 // New device with no parameters.
150 if (err < 0)
152
153 } else if (*p == ':') {
154 // New device with some parameters.
155 ++p;
156 q = strchr(p, ',');
157 if (q) {
159 if (!device) {
162 }
164 if (err < 0) {
165 errmsg = "failed to parse options";
166 goto invalid;
167 }
168 }
169
171 device ? device : p, options, 0);
172 if (err < 0)
174
175 } else if (*p == '@') {
176 // Derive from existing device.
177
179 if (!src) {
180 errmsg = "invalid source device name";
181 goto invalid;
182 }
183
186 if (err < 0)
188 } else {
189 errmsg = "parse error";
190 goto invalid;
191 }
192
194 if (!dev) {
197 }
198
202
203 if (dev_out)
204 *dev_out = dev;
205
207 err = 0;
208 done:
213 return err;
214 invalid:
216 "Invalid device specification \"%s\": %s\n", arg, errmsg);
218 goto done;
221 "Device creation failed: %d.\n", err);
223 goto done;
224 }
225
227 const char *device,
229 {
233 int err;
234
236 if (!name) {
239 }
240
242 if (err < 0) {
244 "Device creation failed: %d.\n", err);
246 }
247
249 if (!dev) {
252 }
253
257
258 if (dev_out)
259 *dev_out = dev;
260
261 return 0;
262
266 return err;
267 }
268
270 {
271 int i;
276 }
278 nb_hw_devices = 0;
279 }
280
282 {
285 int i;
286 for (i = 0;; i++) {
288 if (!config)
291 continue;
293 if (dev)
294 return dev;
295 }
296 }
297
299 {
303 int err, auto_device = 0;
304
307 if (!dev) {
309 auto_device = 1;
313 &dev);
314 } else {
315 // This will be dealt with by API-specific initialisation
316 // (using hwaccel_device), so nothing further needed here.
317 return 0;
318 }
319 } else {
324 "specified for decoder: device %s of type %s is not "
325 "usable with hwaccel %s.\n", dev->
name,
329 }
330 }
331 } else {
333 auto_device = 1;
337 if (!dev)
339 } else {
341 if (!dev) {
342 // No device for this codec, but not using generic hwaccel
343 // and therefore may well not need one - ignore.
344 return 0;
345 }
346 }
347 }
348
349 if (auto_device) {
350 int i;
352 // Decoder does not support any hardware devices.
353 return 0;
354 }
355 for (i = 0; !dev; i++) {
357 if (!config)
358 break;
361 if (dev) {
363 "hwaccel type %s with existing device %s.\n",
365 }
366 }
367 for (i = 0; !dev; i++) {
369 if (!config)
370 break;
372 // Try to make a new device of this type.
374 &dev);
375 if (err < 0) {
376 // Can't make a device of this type.
377 continue;
378 }
381 "hwaccel type %s with new device created "
384 } else {
386 "hwaccel type %s with new default device.\n",
388 }
389 }
390 if (dev) {
392 } else {
394 "disabled: no device found.\n");
396 return 0;
397 }
398 }
399
400 if (!dev) {
402 "for decoder: device type %s needed for codec %s.\n",
404 return err;
405 }
406
410
411 return 0;
412 }
413
415 {
417
419 if (dev) {
423 return 0;
424 } else {
425 // No device required, or no device available.
426 return 0;
427 }
428 }
429
431 {
435 int err;
436
437 if (input->
format == output_format) {
438 // Nothing to do.
439 return 0;
440 }
441
443 if (!output)
445
446 output->
format = output_format;
447
449 if (err < 0) {
451 "output frame: %d.\n", err);
453 }
454
456 if (err < 0) {
459 }
460
464
465 return 0;
466
469 return err;
470 }
471
473 {
475
477
478 return 0;
479 }
static char * hw_device_default_name(enum AVHWDeviceType type)
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
This structure describes decoded (raw) audio or video data.
enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name)
Look up an AVHWDeviceType by name.
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static int hw_device_init_from_type(enum AVHWDeviceType type, const char *device, HWDevice **dev_out)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
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.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static HWDevice * hw_device_add(void)
void hw_device_free_all(void)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int methods
Bit set of AV_CODEC_HW_CONFIG_METHOD_* flags, describing the possible setup methods which can be used...
int hwaccel_decode_init(AVCodecContext *avctx)
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
const char * name
Name of the codec implementation.
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
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.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
#define AV_LOG_INFO
Standard information.
main external API structure.
const AVCodecHWConfig * avcodec_get_hw_config(const AVCodec *codec, int index)
Retrieve supported hardware configurations for a codec.
HWDevice * hw_device_get_by_name(const char *name)
int hw_device_setup_for_decode(InputStream *ist)
const char * av_hwdevice_get_type_name(enum AVHWDeviceType type)
Get the string name of an AVHWDeviceType.
static HWDevice ** hw_devices
static HWDevice * hw_device_get_by_type(enum AVHWDeviceType type)
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input)
A reference to a data buffer.
static HWDevice * hw_device_match_by_codec(const AVCodec *codec)
const OptionDef options[]
int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
enum AVHWDeviceType device_type
The device type associated with the configuration.
int hw_device_setup_for_encode(OutputStream *ost)
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
AVPixelFormat
Pixel format.
The codec supports this format via the hw_device_ctx interface.
char * av_strndup(const char *s, size_t len)
Duplicate a substring of a string.
void * opaque
Private data of the user, can be used to carry app specific stuff.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.