qsv: align surface width/height to 16.
[ffmpeg.git] / avtools / avconv_hw.c
1 /*
2  * This file is part of Libav.
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include <string.h>
20
21 #include "avconv.h"
22
23 static int nb_hw_devices;
24 static HWDevice **hw_devices;
25
26 static HWDevice *hw_device_get_by_type(enum AVHWDeviceType type)
27 {
28     HWDevice *found = NULL;
29     int i;
30     for (i = 0; i < nb_hw_devices; i++) {
31         if (hw_devices[i]->type == type) {
32             if (found)
33                 return NULL;
34             found = hw_devices[i];
35         }
36     }
37     return found;
38 }
39
40 HWDevice *hw_device_get_by_name(const char *name)
41 {
42     int i;
43     for (i = 0; i < nb_hw_devices; i++) {
44         if (!strcmp(hw_devices[i]->name, name))
45             return hw_devices[i];
46     }
47     return NULL;
48 }
49
50 static HWDevice *hw_device_add(void)
51 {
52     int err;
53     err = av_reallocp_array(&hw_devices, nb_hw_devices + 1,
54                             sizeof(*hw_devices));
55     if (err) {
56         nb_hw_devices = 0;
57         return NULL;
58     }
59     hw_devices[nb_hw_devices] = av_mallocz(sizeof(HWDevice));
60     if (!hw_devices[nb_hw_devices])
61         return NULL;
62     return hw_devices[nb_hw_devices++];
63 }
64
65 static char *hw_device_default_name(enum AVHWDeviceType type)
66 {
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);
71     char *name;
72     size_t index_pos;
73     int index, index_limit = 1000;
74     index_pos = strlen(type_name);
75     name = av_malloc(index_pos + 4);
76     if (!name)
77         return NULL;
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))
81             break;
82     }
83     if (index >= index_limit) {
84         av_freep(&name);
85         return NULL;
86     }
87     return name;
88 }
89
90 int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
91 {
92     // "type=name:device,key=value,key2=value2"
93     // "type:device,key=value,key2=value2"
94     // -> av_hwdevice_ctx_create()
95     // "type=name@name"
96     // "type@name"
97     // -> av_hwdevice_ctx_create_derived()
98
99     AVDictionary *options = NULL;
100     char *type_name = NULL, *name = NULL, *device = NULL;
101     enum AVHWDeviceType type;
102     HWDevice *dev, *src;
103     AVBufferRef *device_ref = NULL;
104     int err;
105     const char *errmsg, *p, *q;
106     size_t k;
107
108     k = strcspn(arg, ":=@");
109     p = arg + k;
110
111     type_name = av_strndup(arg, k);
112     if (!type_name) {
113         err = AVERROR(ENOMEM);
114         goto fail;
115     }
116     type = av_hwdevice_find_type_by_name(type_name);
117     if (type == AV_HWDEVICE_TYPE_NONE) {
118         errmsg = "unknown device type";
119         goto invalid;
120     }
121
122     if (*p == '=') {
123         k = strcspn(p + 1, ":@");
124
125         name = av_strndup(p + 1, k);
126         if (!name) {
127             err = AVERROR(ENOMEM);
128             goto fail;
129         }
130         if (hw_device_get_by_name(name)) {
131             errmsg = "named device already exists";
132             goto invalid;
133         }
134
135         p += 1 + k;
136     } else {
137         name = hw_device_default_name(type);
138         if (!name) {
139             err = AVERROR(ENOMEM);
140             goto fail;
141         }
142     }
143
144     if (!*p) {
145         // New device with no parameters.
146         err = av_hwdevice_ctx_create(&device_ref, type,
147                                      NULL, NULL, 0);
148         if (err < 0)
149             goto fail;
150
151     } else if (*p == ':') {
152         // New device with some parameters.
153         ++p;
154         q = strchr(p, ',');
155         if (q) {
156             device = av_strndup(p, q - p);
157             if (!device) {
158                 err = AVERROR(ENOMEM);
159                 goto fail;
160             }
161             err = av_dict_parse_string(&options, q + 1, "=", ",", 0);
162             if (err < 0) {
163                 errmsg = "failed to parse options";
164                 goto invalid;
165             }
166         }
167
168         err = av_hwdevice_ctx_create(&device_ref, type,
169                                      device ? device : p, options, 0);
170         if (err < 0)
171             goto fail;
172
173     } else if (*p == '@') {
174         // Derive from existing device.
175
176         src = hw_device_get_by_name(p + 1);
177         if (!src) {
178             errmsg = "invalid source device name";
179             goto invalid;
180         }
181
182         err = av_hwdevice_ctx_create_derived(&device_ref, type,
183                                              src->device_ref, 0);
184         if (err < 0)
185             goto fail;
186     } else {
187         errmsg = "parse error";
188         goto invalid;
189     }
190
191     dev = hw_device_add();
192     if (!dev) {
193         err = AVERROR(ENOMEM);
194         goto fail;
195     }
196
197     dev->name = name;
198     dev->type = type;
199     dev->device_ref = device_ref;
200
201     if (dev_out)
202         *dev_out = dev;
203
204     name = NULL;
205     err = 0;
206 done:
207     av_freep(&type_name);
208     av_freep(&name);
209     av_freep(&device);
210     av_dict_free(&options);
211     return err;
212 invalid:
213     av_log(NULL, AV_LOG_ERROR,
214            "Invalid device specification \"%s\": %s\n", arg, errmsg);
215     err = AVERROR(EINVAL);
216     goto done;
217 fail:
218     av_log(NULL, AV_LOG_ERROR,
219            "Device creation failed: %d.\n", err);
220     av_buffer_unref(&device_ref);
221     goto done;
222 }
223
224 static int hw_device_init_from_type(enum AVHWDeviceType type,
225                                     const char *device,
226                                     HWDevice **dev_out)
227 {
228     AVBufferRef *device_ref = NULL;
229     HWDevice *dev;
230     char *name;
231     int err;
232
233     name = hw_device_default_name(type);
234     if (!name) {
235         err = AVERROR(ENOMEM);
236         goto fail;
237     }
238
239     err = av_hwdevice_ctx_create(&device_ref, type, device, NULL, 0);
240     if (err < 0) {
241         av_log(NULL, AV_LOG_ERROR,
242                "Device creation failed: %d.\n", err);
243         goto fail;
244     }
245
246     dev = hw_device_add();
247     if (!dev) {
248         err = AVERROR(ENOMEM);
249         goto fail;
250     }
251
252     dev->name = name;
253     dev->type = type;
254     dev->device_ref = device_ref;
255
256     if (dev_out)
257         *dev_out = dev;
258
259     return 0;
260
261 fail:
262     av_freep(&name);
263     av_buffer_unref(&device_ref);
264     return err;
265 }
266
267 void hw_device_free_all(void)
268 {
269     int i;
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]);
274     }
275     av_freep(&hw_devices);
276     nb_hw_devices = 0;
277 }
278
279 static HWDevice *hw_device_match_by_codec(const AVCodec *codec)
280 {
281     const AVCodecHWConfig *config;
282     HWDevice *dev;
283     int i;
284     for (i = 0;; i++) {
285         config = avcodec_get_hw_config(codec, i);
286         if (!config)
287             return NULL;
288         if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
289             continue;
290         dev = hw_device_get_by_type(config->device_type);
291         if (dev)
292             return dev;
293     }
294 }
295
296 int hw_device_setup_for_decode(InputStream *ist)
297 {
298     const AVCodecHWConfig *config;
299     enum AVHWDeviceType type;
300     HWDevice *dev = NULL;
301     int err, auto_device = 0;
302
303     if (ist->hwaccel_device) {
304         dev = hw_device_get_by_name(ist->hwaccel_device);
305         if (!dev) {
306             if (ist->hwaccel_id == HWACCEL_AUTO) {
307                 auto_device = 1;
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,
311                                                &dev);
312             } else {
313                 // This will be dealt with by API-specific initialisation
314                 // (using hwaccel_device), so nothing further needed here.
315                 return 0;
316             }
317         } else {
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);
327             }
328         }
329     } else {
330         if (ist->hwaccel_id == HWACCEL_AUTO) {
331             auto_device = 1;
332         } else if (ist->hwaccel_id == HWACCEL_GENERIC) {
333             type = ist->hwaccel_device_type;
334             dev = hw_device_get_by_type(type);
335             if (!dev)
336                 err = hw_device_init_from_type(type, NULL, &dev);
337         } else {
338             dev = hw_device_match_by_codec(ist->dec);
339             if (!dev) {
340                 // No device for this codec, but not using generic hwaccel
341                 // and therefore may well not need one - ignore.
342                 return 0;
343             }
344         }
345     }
346
347     if (auto_device) {
348         int i;
349         if (!avcodec_get_hw_config(ist->dec, 0)) {
350             // Decoder does not support any hardware devices.
351             return 0;
352         }
353         for (i = 0; !dev; i++) {
354             config = avcodec_get_hw_config(ist->dec, i);
355             if (!config)
356                 break;
357             type = config->device_type;
358             dev = hw_device_get_by_type(type);
359             if (dev) {
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);
363             }
364         }
365         for (i = 0; !dev; i++) {
366             config = avcodec_get_hw_config(ist->dec, i);
367             if (!config)
368                 break;
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,
372                                            &dev);
373             if (err < 0) {
374                 // Can't make a device of this type.
375                 continue;
376             }
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);
382             } else {
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));
386             }
387         }
388         if (dev) {
389             ist->hwaccel_device_type = type;
390         } else {
391             av_log(ist->dec_ctx, AV_LOG_INFO, "Auto hwaccel "
392                    "disabled: no device found.\n");
393             ist->hwaccel_id = HWACCEL_NONE;
394             return 0;
395         }
396     }
397
398     if (!dev) {
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);
402         return err;
403     }
404
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);
408
409     return 0;
410 }
411
412 int hw_device_setup_for_encode(OutputStream *ost)
413 {
414     HWDevice *dev;
415
416     dev = hw_device_match_by_codec(ost->enc);
417     if (dev) {
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);
421         return 0;
422     } else {
423         // No device required, or no device available.
424         return 0;
425     }
426 }
427
428 static int hwaccel_retrieve_data(AVCodecContext *avctx, AVFrame *input)
429 {
430     InputStream *ist = avctx->opaque;
431     AVFrame *output = NULL;
432     enum AVPixelFormat output_format = ist->hwaccel_output_format;
433     int err;
434
435     if (input->format == output_format) {
436         // Nothing to do.
437         return 0;
438     }
439
440     output = av_frame_alloc();
441     if (!output)
442         return AVERROR(ENOMEM);
443
444     output->format = output_format;
445
446     err = av_hwframe_transfer_data(output, input, 0);
447     if (err < 0) {
448         av_log(avctx, AV_LOG_ERROR, "Failed to transfer data to "
449                "output frame: %d.\n", err);
450         goto fail;
451     }
452
453     err = av_frame_copy_props(output, input);
454     if (err < 0) {
455         av_frame_unref(output);
456         goto fail;
457     }
458
459     av_frame_unref(input);
460     av_frame_move_ref(input, output);
461     av_frame_free(&output);
462
463     return 0;
464
465 fail:
466     av_frame_free(&output);
467     return err;
468 }
469
470 int hwaccel_decode_init(AVCodecContext *avctx)
471 {
472     InputStream *ist = avctx->opaque;
473
474     ist->hwaccel_retrieve_data = &hwaccel_retrieve_data;
475
476     return 0;
477 }