2 * This file is part of Libav.
4 * Libav 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.
9 * Libav 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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 static int nb_hw_devices
;
24 static HWDevice
**hw_devices
;
26 static HWDevice
*hw_device_get_by_type(enum AVHWDeviceType type
)
28 HWDevice
*found
= NULL
;
30 for (i
= 0; i
< nb_hw_devices
; i
++) {
31 if (hw_devices
[i
]->type
== type
) {
34 found
= hw_devices
[i
];
40 HWDevice
*hw_device_get_by_name(const char *name
)
43 for (i
= 0; i
< nb_hw_devices
; i
++) {
44 if (!strcmp(hw_devices
[i
]->name
, name
))
50 static HWDevice
*hw_device_add(void)
53 err
= av_reallocp_array(&hw_devices
, nb_hw_devices
+ 1,
59 hw_devices
[nb_hw_devices
] = av_mallocz(sizeof(HWDevice
));
60 if (!hw_devices
[nb_hw_devices
])
62 return hw_devices
[nb_hw_devices
++];
65 static char *hw_device_default_name(enum AVHWDeviceType type
)
67 // Make an automatic name of the form "type%d". We arbitrarily
68 // limit at 1000 anonymous devices of the same type - there is
69 // probably something else very wrong if you get to this limit.
70 const char *type_name
= av_hwdevice_get_type_name(type
);
73 int index
, index_limit
= 1000;
74 index_pos
= strlen(type_name
);
75 name
= av_malloc(index_pos
+ 4);
78 for (index
= 0; index
< index_limit
; index
++) {
79 snprintf(name
, index_pos
+ 4, "%s%d", type_name
, index
);
80 if (!hw_device_get_by_name(name
))
83 if (index
>= index_limit
) {
90 int hw_device_init_from_string(const char *arg
, HWDevice
**dev_out
)
92 // "type=name:device,key=value,key2=value2"
93 // "type:device,key=value,key2=value2"
94 // -> av_hwdevice_ctx_create()
97 // -> av_hwdevice_ctx_create_derived()
99 AVDictionary
*options
= NULL
;
100 char *type_name
= NULL
, *name
= NULL
, *device
= NULL
;
101 enum AVHWDeviceType type
;
103 AVBufferRef
*device_ref
= NULL
;
105 const char *errmsg
, *p
, *q
;
108 k
= strcspn(arg
, ":=@");
111 type_name
= av_strndup(arg
, k
);
113 err
= AVERROR(ENOMEM
);
116 type
= av_hwdevice_find_type_by_name(type_name
);
117 if (type
== AV_HWDEVICE_TYPE_NONE
) {
118 errmsg
= "unknown device type";
123 k
= strcspn(p
+ 1, ":@");
125 name
= av_strndup(p
+ 1, k
);
127 err
= AVERROR(ENOMEM
);
130 if (hw_device_get_by_name(name
)) {
131 errmsg
= "named device already exists";
137 name
= hw_device_default_name(type
);
139 err
= AVERROR(ENOMEM
);
145 // New device with no parameters.
146 err
= av_hwdevice_ctx_create(&device_ref
, type
,
151 } else if (*p
== ':') {
152 // New device with some parameters.
156 device
= av_strndup(p
, q
- p
);
158 err
= AVERROR(ENOMEM
);
161 err
= av_dict_parse_string(&options
, q
+ 1, "=", ",", 0);
163 errmsg
= "failed to parse options";
168 err
= av_hwdevice_ctx_create(&device_ref
, type
,
169 device
? device
: p
, options
, 0);
173 } else if (*p
== '@') {
174 // Derive from existing device.
176 src
= hw_device_get_by_name(p
+ 1);
178 errmsg
= "invalid source device name";
182 err
= av_hwdevice_ctx_create_derived(&device_ref
, type
,
187 errmsg
= "parse error";
191 dev
= hw_device_add();
193 err
= AVERROR(ENOMEM
);
199 dev
->device_ref
= device_ref
;
207 av_freep(&type_name
);
210 av_dict_free(&options
);
213 av_log(NULL
, AV_LOG_ERROR
,
214 "Invalid device specification \"%s\": %s\n", arg
, errmsg
);
215 err
= AVERROR(EINVAL
);
218 av_log(NULL
, AV_LOG_ERROR
,
219 "Device creation failed: %d.\n", err
);
220 av_buffer_unref(&device_ref
);
224 static int hw_device_init_from_type(enum AVHWDeviceType type
,
228 AVBufferRef
*device_ref
= NULL
;
233 name
= hw_device_default_name(type
);
235 err
= AVERROR(ENOMEM
);
239 err
= av_hwdevice_ctx_create(&device_ref
, type
, device
, NULL
, 0);
241 av_log(NULL
, AV_LOG_ERROR
,
242 "Device creation failed: %d.\n", err
);
246 dev
= hw_device_add();
248 err
= AVERROR(ENOMEM
);
254 dev
->device_ref
= device_ref
;
263 av_buffer_unref(&device_ref
);
267 void hw_device_free_all(void)
270 for (i
= 0; i
< nb_hw_devices
; i
++) {
271 av_freep(&hw_devices
[i
]->name
);
272 av_buffer_unref(&hw_devices
[i
]->device_ref
);
273 av_freep(&hw_devices
[i
]);
275 av_freep(&hw_devices
);
279 static HWDevice
*hw_device_match_by_codec(const AVCodec
*codec
)
281 const AVCodecHWConfig
*config
;
285 config
= avcodec_get_hw_config(codec
, i
);
288 if (!(config
->methods
& AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX
))
290 dev
= hw_device_get_by_type(config
->device_type
);
296 int hw_device_setup_for_decode(InputStream
*ist
)
298 const AVCodecHWConfig
*config
;
299 enum AVHWDeviceType type
;
300 HWDevice
*dev
= NULL
;
301 int err
, auto_device
= 0;
303 if (ist
->hwaccel_device
) {
304 dev
= hw_device_get_by_name(ist
->hwaccel_device
);
306 if (ist
->hwaccel_id
== HWACCEL_AUTO
) {
308 } else if (ist
->hwaccel_id
== HWACCEL_GENERIC
) {
309 type
= ist
->hwaccel_device_type
;
310 err
= hw_device_init_from_type(type
, ist
->hwaccel_device
,
313 // This will be dealt with by API-specific initialisation
314 // (using hwaccel_device), so nothing further needed here.
318 if (ist
->hwaccel_id
== HWACCEL_AUTO
) {
319 ist
->hwaccel_device_type
= dev
->type
;
320 } else if (ist
->hwaccel_device_type
!= dev
->type
) {
321 av_log(ist
->dec_ctx
, AV_LOG_ERROR
, "Invalid hwaccel device "
322 "specified for decoder: device %s of type %s is not "
323 "usable with hwaccel %s.\n", dev
->name
,
324 av_hwdevice_get_type_name(dev
->type
),
325 av_hwdevice_get_type_name(ist
->hwaccel_device_type
));
326 return AVERROR(EINVAL
);
330 if (ist
->hwaccel_id
== HWACCEL_AUTO
) {
332 } else if (ist
->hwaccel_id
== HWACCEL_GENERIC
) {
333 type
= ist
->hwaccel_device_type
;
334 dev
= hw_device_get_by_type(type
);
336 err
= hw_device_init_from_type(type
, NULL
, &dev
);
338 dev
= hw_device_match_by_codec(ist
->dec
);
340 // No device for this codec, but not using generic hwaccel
341 // and therefore may well not need one - ignore.
349 if (!avcodec_get_hw_config(ist
->dec
, 0)) {
350 // Decoder does not support any hardware devices.
353 for (i
= 0; !dev
; i
++) {
354 config
= avcodec_get_hw_config(ist
->dec
, i
);
357 type
= config
->device_type
;
358 dev
= hw_device_get_by_type(type
);
360 av_log(ist
->dec_ctx
, AV_LOG_INFO
, "Using auto "
361 "hwaccel type %s with existing device %s.\n",
362 av_hwdevice_get_type_name(type
), dev
->name
);
365 for (i
= 0; !dev
; i
++) {
366 config
= avcodec_get_hw_config(ist
->dec
, i
);
369 type
= config
->device_type
;
370 // Try to make a new device of this type.
371 err
= hw_device_init_from_type(type
, ist
->hwaccel_device
,
374 // Can't make a device of this type.
377 if (ist
->hwaccel_device
) {
378 av_log(ist
->dec_ctx
, AV_LOG_INFO
, "Using auto "
379 "hwaccel type %s with new device created "
380 "from %s.\n", av_hwdevice_get_type_name(type
),
381 ist
->hwaccel_device
);
383 av_log(ist
->dec_ctx
, AV_LOG_INFO
, "Using auto "
384 "hwaccel type %s with new default device.\n",
385 av_hwdevice_get_type_name(type
));
389 ist
->hwaccel_device_type
= type
;
391 av_log(ist
->dec_ctx
, AV_LOG_INFO
, "Auto hwaccel "
392 "disabled: no device found.\n");
393 ist
->hwaccel_id
= HWACCEL_NONE
;
399 av_log(ist
->dec_ctx
, AV_LOG_ERROR
, "No device available "
400 "for decoder: device type %s needed for codec %s.\n",
401 av_hwdevice_get_type_name(type
), ist
->dec
->name
);
405 ist
->dec_ctx
->hw_device_ctx
= av_buffer_ref(dev
->device_ref
);
406 if (!ist
->dec_ctx
->hw_device_ctx
)
407 return AVERROR(ENOMEM
);
412 int hw_device_setup_for_encode(OutputStream
*ost
)
416 dev
= hw_device_match_by_codec(ost
->enc
);
418 ost
->enc_ctx
->hw_device_ctx
= av_buffer_ref(dev
->device_ref
);
419 if (!ost
->enc_ctx
->hw_device_ctx
)
420 return AVERROR(ENOMEM
);
423 // No device required, or no device available.
428 static int hwaccel_retrieve_data(AVCodecContext
*avctx
, AVFrame
*input
)
430 InputStream
*ist
= avctx
->opaque
;
431 AVFrame
*output
= NULL
;
432 enum AVPixelFormat output_format
= ist
->hwaccel_output_format
;
435 if (input
->format
== output_format
) {
440 output
= av_frame_alloc();
442 return AVERROR(ENOMEM
);
444 output
->format
= output_format
;
446 err
= av_hwframe_transfer_data(output
, input
, 0);
448 av_log(avctx
, AV_LOG_ERROR
, "Failed to transfer data to "
449 "output frame: %d.\n", err
);
453 err
= av_frame_copy_props(output
, input
);
455 av_frame_unref(output
);
459 av_frame_unref(input
);
460 av_frame_move_ref(input
, output
);
461 av_frame_free(&output
);
466 av_frame_free(&output
);
470 int hwaccel_decode_init(AVCodecContext
*avctx
)
472 InputStream
*ist
= avctx
->opaque
;
474 ist
->hwaccel_retrieve_data
= &hwaccel_retrieve_data
;