FFmpeg
Loading...
Searching...
No Matches
vaapi_decode.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 "config_components.h"
20
21#include "libavutil/avassert.h"
22#include "libavutil/common.h"
23#include "libavutil/mem.h"
24#include "libavutil/pixdesc.h"
25
26#include "avcodec.h"
27#include "codec_desc.h"
28#include "decode.h"
29#include "internal.h"
30#include "vaapi_decode.h"
31#include "vaapi_hevc.h"
32
33
36 int type,
37 const void *data,
38 size_t size)
39{
41 VAStatus vas;
42
45 VABufferID *tmp =
48 sizeof(*pic->param_buffers));
49 if (!tmp)
50 return AVERROR(ENOMEM);
51
52 pic->param_buffers = tmp;
54 }
56
57 vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
58 type, size, 1, (void*)data,
60 if (vas != VA_STATUS_SUCCESS) {
61 av_log(avctx, AV_LOG_ERROR, "Failed to create parameter "
62 "buffer (type %d): %d (%s).\n",
63 type, vas, vaErrorStr(vas));
64 return AVERROR(EIO);
65 }
66
67 av_log(avctx, AV_LOG_DEBUG, "Param buffer (type %d, %zu bytes) "
68 "is %#x.\n", type, size, pic->param_buffers[pic->nb_param_buffers]);
69
70 ++pic->nb_param_buffers;
71
72 return 0;
73}
74
77 const void *params_data,
78 int nb_params,
79 size_t params_size,
80 const void *slice_data,
81 size_t slice_size)
82{
84 VAStatus vas;
85 int index;
86
88 if (pic->nb_slices == pic->nb_slice_buffers_allocated) {
89 VABufferID *tmp =
92 2 * sizeof(*pic->slice_buffers));
93 if (!tmp)
94 return AVERROR(ENOMEM);
95
96 pic->slice_buffers = tmp;
98 }
100
101 index = 2 * pic->nb_slices;
102
103 vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
104 VASliceParameterBufferType,
105 params_size, nb_params, (void*)params_data,
106 &pic->slice_buffers[index]);
107 if (vas != VA_STATUS_SUCCESS) {
108 av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
109 "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas));
110 return AVERROR(EIO);
111 }
112
113 av_log(avctx, AV_LOG_DEBUG, "Slice %d param buffer (%zu bytes) "
114 "is %#x.\n", pic->nb_slices, params_size,
115 pic->slice_buffers[index]);
116
117 vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
118 VASliceDataBufferType,
119 slice_size, 1, (void*)slice_data,
120 &pic->slice_buffers[index + 1]);
121 if (vas != VA_STATUS_SUCCESS) {
122 av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
123 "data buffer (size %zu): %d (%s).\n",
124 slice_size, vas, vaErrorStr(vas));
125 vaDestroyBuffer(ctx->hwctx->display,
126 pic->slice_buffers[index]);
127 return AVERROR(EIO);
128 }
129
130 av_log(avctx, AV_LOG_DEBUG, "Slice %d data buffer (%zu bytes) "
131 "is %#x.\n", pic->nb_slices, slice_size,
132 pic->slice_buffers[index + 1]);
133
134 ++pic->nb_slices;
135 return 0;
136}
137
140{
142 VAStatus vas;
143 int i;
144
145 for (i = 0; i < pic->nb_param_buffers; i++) {
146 vas = vaDestroyBuffer(ctx->hwctx->display,
147 pic->param_buffers[i]);
148 if (vas != VA_STATUS_SUCCESS) {
149 av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
150 "parameter buffer %#x: %d (%s).\n",
151 pic->param_buffers[i], vas, vaErrorStr(vas));
152 }
153 }
154
155 for (i = 0; i < 2 * pic->nb_slices; i++) {
156 vas = vaDestroyBuffer(ctx->hwctx->display,
157 pic->slice_buffers[i]);
158 if (vas != VA_STATUS_SUCCESS) {
159 av_log(avctx, AV_LOG_ERROR, "Failed to destroy slice "
160 "slice buffer %#x: %d (%s).\n",
161 pic->slice_buffers[i], vas, vaErrorStr(vas));
162 }
163 }
164}
165
168{
170 VAStatus vas;
171 int err;
172
173 if (pic->nb_slices <= 0) {
174 err = AVERROR(EINVAL);
175 goto fail;
176 }
177
178 av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n",
179 pic->output_surface);
180
181 vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
182 pic->output_surface);
183 if (vas != VA_STATUS_SUCCESS) {
184 av_log(avctx, AV_LOG_ERROR, "Failed to begin picture decode "
185 "issue: %d (%s).\n", vas, vaErrorStr(vas));
186 err = AVERROR(EIO);
187 goto fail_with_picture;
188 }
189
190 vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
192 if (vas != VA_STATUS_SUCCESS) {
193 av_log(avctx, AV_LOG_ERROR, "Failed to upload decode "
194 "parameters: %d (%s).\n", vas, vaErrorStr(vas));
195 err = AVERROR(EIO);
196 goto fail_with_picture;
197 }
198
199 vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
200 pic->slice_buffers, 2 * pic->nb_slices);
201 if (vas != VA_STATUS_SUCCESS) {
202 av_log(avctx, AV_LOG_ERROR, "Failed to upload slices: "
203 "%d (%s).\n", vas, vaErrorStr(vas));
204 err = AVERROR(EIO);
205 goto fail_with_picture;
206 }
207
208 vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
209 if (vas != VA_STATUS_SUCCESS) {
210 av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode "
211 "issue: %d (%s).\n", vas, vaErrorStr(vas));
212 err = AVERROR(EIO);
213 if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
215 goto fail;
216 else
217 goto fail_at_end;
218 }
219
220 if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
223
224 err = 0;
225 goto exit;
226
227fail_with_picture:
228 vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
229 if (vas != VA_STATUS_SUCCESS) {
230 av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode "
231 "after error: %d (%s).\n", vas, vaErrorStr(vas));
232 }
233fail:
235fail_at_end:
236exit:
237 pic->nb_param_buffers = 0;
239 av_freep(&pic->param_buffers);
240 pic->nb_slices = 0;
242 av_freep(&pic->slice_buffers);
243
244 return err;
245}
246
249{
251
252 pic->nb_param_buffers = 0;
254 av_freep(&pic->param_buffers);
255 pic->nb_slices = 0;
257 av_freep(&pic->slice_buffers);
258
259 return 0;
260}
261
262static const struct {
263 uint32_t fourcc;
265} vaapi_format_map[] = {
266#define MAP(va, av) { VA_FOURCC_ ## va, AV_PIX_FMT_ ## av }
267 // 4:0:0
268 MAP(Y800, GRAY8),
269 // 4:2:0
270 MAP(NV12, NV12),
271 MAP(YV12, YUV420P),
272 MAP(IYUV, YUV420P),
273#ifdef VA_FOURCC_I420
274 MAP(I420, YUV420P),
275#endif
276 MAP(IMC3, YUV420P),
277 // 4:1:1
278 MAP(411P, YUV411P),
279 // 4:2:2
280 MAP(422H, YUV422P),
281#ifdef VA_FOURCC_YV16
282 MAP(YV16, YUV422P),
283#endif
284 MAP(YUY2, YUYV422),
285#ifdef VA_FOURCC_Y210
286 MAP(Y210, Y210),
287#endif
288#ifdef VA_FOURCC_Y212
289 MAP(Y212, Y212),
290#endif
291 // 4:4:0
292 MAP(422V, YUV440P),
293 // 4:4:4
294 MAP(444P, YUV444P),
295#ifdef VA_FOURCC_XYUV
296 MAP(XYUV, VUYX),
297#endif
298#ifdef VA_FOURCC_Y410
299 MAP(Y410, XV30),
300#endif
301#ifdef VA_FOURCC_Y412
302 MAP(Y412, XV36),
303#endif
304 // 4:2:0 10-bit
305#ifdef VA_FOURCC_P010
306 MAP(P010, P010),
307#endif
308#ifdef VA_FOURCC_P012
309 MAP(P012, P012),
310#endif
311#ifdef VA_FOURCC_I010
312 MAP(I010, YUV420P10),
313#endif
314#undef MAP
316
318 AVHWDeviceContext *device,
319 VAConfigID config_id,
321{
322 AVVAAPIDeviceContext *hwctx = device->hwctx;
323 VAStatus vas;
324 VASurfaceAttrib *attr;
325 enum AVPixelFormat source_format, best_format, format;
326 uint32_t best_fourcc, fourcc;
327 int i, j, nb_attr;
328
329 source_format = avctx->sw_pix_fmt;
330 av_assert0(source_format != AV_PIX_FMT_NONE);
331
332 vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
333 NULL, &nb_attr);
334 if (vas != VA_STATUS_SUCCESS) {
335 av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
336 "%d (%s).\n", vas, vaErrorStr(vas));
337 return AVERROR(ENOSYS);
338 }
339
340 attr = av_malloc_array(nb_attr, sizeof(*attr));
341 if (!attr)
342 return AVERROR(ENOMEM);
343
344 vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
345 attr, &nb_attr);
346 if (vas != VA_STATUS_SUCCESS) {
347 av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
348 "%d (%s).\n", vas, vaErrorStr(vas));
349 av_freep(&attr);
350 return AVERROR(ENOSYS);
351 }
352
353 best_format = AV_PIX_FMT_NONE;
354
355 for (i = 0; i < nb_attr; i++) {
356 if (attr[i].type != VASurfaceAttribPixelFormat)
357 continue;
358
359 fourcc = attr[i].value.value.i;
360 for (j = 0; j < FF_ARRAY_ELEMS(vaapi_format_map); j++) {
362 break;
363 }
365 av_log(avctx, AV_LOG_DEBUG, "Ignoring unknown format %#x.\n",
366 fourcc);
367 continue;
368 }
369 format = vaapi_format_map[j].pix_fmt;
370 av_log(avctx, AV_LOG_DEBUG, "Considering format %#x -> %s.\n",
372
373 best_format = av_find_best_pix_fmt_of_2(format, best_format,
374 source_format, 0, NULL);
375 if (format == best_format)
376 best_fourcc = fourcc;
377 }
378
379 av_freep(&attr);
380
381 if (best_format == AV_PIX_FMT_NONE) {
382 av_log(avctx, AV_LOG_ERROR, "No usable formats for decoding!\n");
383 return AVERROR(EINVAL);
384 }
385
386 av_log(avctx, AV_LOG_DEBUG, "Picked %s (%#x) as best match for %s.\n",
387 av_get_pix_fmt_name(best_format), best_fourcc,
388 av_get_pix_fmt_name(source_format));
389
390 frames->sw_format = best_format;
391 if (avctx->internal->hwaccel_priv_data) {
393 AVVAAPIFramesContext *avfc = frames->hwctx;
394
395 ctx->pixel_format_attribute = (VASurfaceAttrib) {
396 .type = VASurfaceAttribPixelFormat,
397 .flags = VA_SURFACE_ATTRIB_SETTABLE,
398 .value.type = VAGenericValueTypeInteger,
399 .value.value.i = best_fourcc,
400 };
401
402 avfc->attributes = &ctx->pixel_format_attribute;
403 avfc->nb_attributes = 1;
404 }
405
406 return 0;
407}
408
409static const struct {
412 VAProfile va_profile;
413 VAProfile (*profile_parser)(AVCodecContext *avctx);
414} vaapi_profile_map[] = {
415#define MAP(c, p, v, ...) { AV_CODEC_ID_ ## c, AV_PROFILE_ ## p, VAProfile ## v, __VA_ARGS__ }
416 MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ),
417 MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ),
418 MAP(H263, UNKNOWN, H263Baseline),
419 MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ),
420 MAP(MPEG4, MPEG4_ADVANCED_SIMPLE,
421 MPEG4AdvancedSimple),
422 MAP(MPEG4, MPEG4_MAIN, MPEG4Main ),
423#if VA_CHECK_VERSION(1, 18, 0)
424 MAP(H264, H264_HIGH_10_INTRA,
425 H264High10 ),
426 MAP(H264, H264_HIGH_10, H264High10 ),
427#endif
428 MAP(H264, H264_CONSTRAINED_BASELINE,
429 H264ConstrainedBaseline),
430 MAP(H264, H264_MAIN, H264Main ),
431 MAP(H264, H264_HIGH, H264High ),
432#if VA_CHECK_VERSION(0, 37, 0)
433 MAP(HEVC, HEVC_MAIN, HEVCMain ),
434 MAP(HEVC, HEVC_MAIN_10, HEVCMain10 ),
435 MAP(HEVC, HEVC_MAIN_STILL_PICTURE,
436 HEVCMain ),
437#endif
438#if VA_CHECK_VERSION(1, 2, 0) && CONFIG_HEVC_VAAPI_HWACCEL
439 MAP(HEVC, HEVC_REXT, None,
441 MAP(HEVC, HEVC_SCC, None,
443#endif
444 MAP(MJPEG, MJPEG_HUFFMAN_BASELINE_DCT,
445 JPEGBaseline),
446 MAP(WMV3, VC1_SIMPLE, VC1Simple ),
447 MAP(WMV3, VC1_MAIN, VC1Main ),
448 MAP(WMV3, VC1_COMPLEX, VC1Advanced ),
449 MAP(WMV3, VC1_ADVANCED, VC1Advanced ),
450 MAP(VC1, VC1_SIMPLE, VC1Simple ),
451 MAP(VC1, VC1_MAIN, VC1Main ),
452 MAP(VC1, VC1_COMPLEX, VC1Advanced ),
453 MAP(VC1, VC1_ADVANCED, VC1Advanced ),
454 MAP(VP8, UNKNOWN, VP8Version0_3 ),
455#if VA_CHECK_VERSION(0, 38, 0)
456 MAP(VP9, VP9_0, VP9Profile0 ),
457#endif
458#if VA_CHECK_VERSION(0, 39, 0)
459 MAP(VP9, VP9_1, VP9Profile1 ),
460 MAP(VP9, VP9_2, VP9Profile2 ),
461 MAP(VP9, VP9_3, VP9Profile3 ),
462#endif
463#if VA_CHECK_VERSION(1, 8, 0)
464 MAP(AV1, AV1_MAIN, AV1Profile0),
465 MAP(AV1, AV1_HIGH, AV1Profile1),
466#endif
467#if VA_CHECK_VERSION(1, 22, 0)
468 MAP(H266, VVC_MAIN_10, VVCMain10),
469#endif
470
471#undef MAP
473
474/*
475 * Set *va_config and the frames_ref fields from the current codec parameters
476 * in avctx.
477 */
479 AVBufferRef *device_ref,
480 VAConfigID *va_config,
481 AVBufferRef *frames_ref)
482{
483 AVVAAPIHWConfig *hwconfig = NULL;
484 AVHWFramesConstraints *constraints = NULL;
485 VAStatus vas;
486 int err, i, j;
487 const AVCodecDescriptor *codec_desc;
488 VAProfile *profile_list = NULL, matched_va_profile, va_profile;
489 int profile_count, exact_match, matched_ff_profile, codec_profile;
490
491 AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data;
492 AVVAAPIDeviceContext *hwctx = device->hwctx;
493
494 codec_desc = avcodec_descriptor_get(avctx->codec_id);
495 if (!codec_desc) {
496 err = AVERROR(EINVAL);
497 goto fail;
498 }
499
500 profile_count = vaMaxNumProfiles(hwctx->display);
501 profile_list = av_malloc_array(profile_count,
502 sizeof(VAProfile));
503 if (!profile_list) {
504 err = AVERROR(ENOMEM);
505 goto fail;
506 }
507
508 vas = vaQueryConfigProfiles(hwctx->display,
509 profile_list, &profile_count);
510 if (vas != VA_STATUS_SUCCESS) {
511 av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "
512 "%d (%s).\n", vas, vaErrorStr(vas));
513 err = AVERROR(ENOSYS);
514 goto fail;
515 }
516
517 matched_va_profile = VAProfileNone;
518 exact_match = 0;
519
520 for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
521 int profile_match = 0;
522 if (avctx->codec_id != vaapi_profile_map[i].codec_id)
523 continue;
524 if (avctx->profile == vaapi_profile_map[i].codec_profile ||
525 vaapi_profile_map[i].codec_profile == AV_PROFILE_UNKNOWN)
526 profile_match = 1;
527
528 va_profile = vaapi_profile_map[i].profile_parser ?
529 vaapi_profile_map[i].profile_parser(avctx) :
530 vaapi_profile_map[i].va_profile;
531 codec_profile = vaapi_profile_map[i].codec_profile;
532
533 for (j = 0; j < profile_count; j++) {
534 if (va_profile == profile_list[j]) {
535 exact_match = profile_match;
536 break;
537 }
538 }
539 if (j < profile_count) {
540 matched_va_profile = va_profile;
541 matched_ff_profile = codec_profile;
542 if (exact_match)
543 break;
544 }
545 }
546 av_freep(&profile_list);
547
548 if (matched_va_profile == VAProfileNone) {
549 av_log(avctx, AV_LOG_ERROR, "No support for codec %s "
550 "profile %d.\n", codec_desc->name, avctx->profile);
551 err = AVERROR(ENOSYS);
552 goto fail;
553 }
554 if (!exact_match) {
555 if (avctx->hwaccel_flags &
557 av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
558 "supported for hardware decode.\n",
559 codec_desc->name, avctx->profile);
560 av_log(avctx, AV_LOG_WARNING, "Using possibly-"
561 "incompatible profile %d instead.\n",
562 matched_ff_profile);
563 } else {
564 av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
565 "supported for hardware decode.\n",
566 codec_desc->name, avctx->profile);
567 err = AVERROR(EINVAL);
568 goto fail;
569 }
570 }
571
572 vas = vaCreateConfig(hwctx->display, matched_va_profile,
573 VAEntrypointVLD, NULL, 0,
574 va_config);
575 if (vas != VA_STATUS_SUCCESS) {
576 av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
577 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
578 err = AVERROR(EIO);
579 goto fail;
580 }
581
582 hwconfig = av_hwdevice_hwconfig_alloc(device_ref);
583 if (!hwconfig) {
584 err = AVERROR(ENOMEM);
585 goto fail;
586 }
587 hwconfig->config_id = *va_config;
588
589 constraints =
590 av_hwdevice_get_hwframe_constraints(device_ref, hwconfig);
591 if (!constraints) {
592 err = AVERROR(ENOMEM);
593 goto fail;
594 }
595
596 if (avctx->coded_width < constraints->min_width ||
597 avctx->coded_height < constraints->min_height ||
598 avctx->coded_width > constraints->max_width ||
599 avctx->coded_height > constraints->max_height) {
600 av_log(avctx, AV_LOG_ERROR, "Hardware does not support image "
601 "size %dx%d (constraints: width %d-%d height %d-%d).\n",
602 avctx->coded_width, avctx->coded_height,
603 constraints->min_width, constraints->max_width,
604 constraints->min_height, constraints->max_height);
605 err = AVERROR(EINVAL);
606 goto fail;
607 }
608 if (!constraints->valid_sw_formats ||
609 constraints->valid_sw_formats[0] == AV_PIX_FMT_NONE) {
610 av_log(avctx, AV_LOG_ERROR, "Hardware does not offer any "
611 "usable surface formats.\n");
612 err = AVERROR(EINVAL);
613 goto fail;
614 }
615
616 if (frames_ref) {
618
619 frames->format = AV_PIX_FMT_VAAPI;
620 frames->width = avctx->coded_width;
621 frames->height = avctx->coded_height;
622
623 err = vaapi_decode_find_best_format(avctx, device,
624 *va_config, frames);
625 if (err < 0)
626 goto fail;
627
628 if (CONFIG_VAAPI_1)
629 frames->initial_pool_size = 0;
630 else {
631 frames->initial_pool_size = 1;
632 // Add per-codec number of surfaces used for storing reference frames.
633 switch (avctx->codec_id) {
634 case AV_CODEC_ID_H264:
635 case AV_CODEC_ID_H266:
636 case AV_CODEC_ID_HEVC:
637 case AV_CODEC_ID_AV1:
638 frames->initial_pool_size += 16;
639 break;
640 case AV_CODEC_ID_VP9:
641 frames->initial_pool_size += 8;
642 break;
643 case AV_CODEC_ID_VP8:
644 frames->initial_pool_size += 3;
645 break;
646 default:
647 frames->initial_pool_size += 2;
648 }
649 }
650 }
651
652 av_hwframe_constraints_free(&constraints);
653 av_freep(&hwconfig);
654
655 return 0;
656
657fail:
658 av_hwframe_constraints_free(&constraints);
659 av_freep(&hwconfig);
660 if (*va_config != VA_INVALID_ID) {
661 vaDestroyConfig(hwctx->display, *va_config);
662 *va_config = VA_INVALID_ID;
663 }
664 av_freep(&profile_list);
665 return err;
666}
667
669 AVBufferRef *hw_frames_ctx)
670{
671 AVHWFramesContext *hw_frames = (AVHWFramesContext *)hw_frames_ctx->data;
672 AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
674 VAConfigID va_config = VA_INVALID_ID;
675 int err;
676
677 if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI)
678 return AVERROR(EINVAL);
679 hwctx = device_ctx->hwctx;
680
681 err = vaapi_decode_make_config(avctx, hw_frames->device_ref, &va_config,
682 hw_frames_ctx);
683 if (err)
684 return err;
685
686 if (va_config != VA_INVALID_ID)
687 vaDestroyConfig(hwctx->display, va_config);
688
689 return 0;
690}
691
693{
695 VAStatus vas;
696 int err;
697
698 ctx->va_config = VA_INVALID_ID;
699 ctx->va_context = VA_INVALID_ID;
700
702 if (err < 0)
703 goto fail;
704
705 ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
706 ctx->hwfc = ctx->frames->hwctx;
707 ctx->device = ctx->frames->device_ctx;
708 ctx->hwctx = ctx->device->hwctx;
709
710 err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
711 &ctx->va_config, NULL);
712 if (err)
713 goto fail;
714
715 vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
716 avctx->coded_width, avctx->coded_height,
717 VA_PROGRESSIVE,
718 ctx->hwfc->surface_ids,
719 ctx->hwfc->nb_surfaces,
720 &ctx->va_context);
721 if (vas != VA_STATUS_SUCCESS) {
722 av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
723 "context: %d (%s).\n", vas, vaErrorStr(vas));
724 err = AVERROR(EIO);
725 goto fail;
726 }
727
728 av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: "
729 "%#x/%#x.\n", ctx->va_config, ctx->va_context);
730
731 return 0;
732
733fail:
735 return err;
736}
737
739{
741 VAStatus vas;
742
743 if (ctx->va_context != VA_INVALID_ID) {
744 vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context);
745 if (vas != VA_STATUS_SUCCESS) {
746 av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
747 "context %#x: %d (%s).\n",
748 ctx->va_context, vas, vaErrorStr(vas));
749 }
750 }
751 if (ctx->va_config != VA_INVALID_ID) {
752 vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
753 if (vas != VA_STATUS_SUCCESS) {
754 av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
755 "configuration %#x: %d (%s).\n",
756 ctx->va_config, vas, vaErrorStr(vas));
757 }
758 }
759
760 return 0;
761}
static const char *const format[]
Definition af_aiir.c:444
static int frames
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
#define V
Definition avdct.c:32
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define AV_CODEC_ID_H266
Definition codec_id.h:248
common internal and external API header
#define NULL
Definition coverity.c:32
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
Definition decode.c:1069
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
static enum AVPixelFormat pix_fmt
@ UNKNOWN
Definition ftp.c:39
#define fail
Definition test.h:479
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_VP8
Definition codec_id.h:190
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_VP9
Definition codec_id.h:217
#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH
Hardware acceleration should still be attempted for decoding when the codec profile does not match th...
Definition avcodec.h:2018
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:217
int index
Definition gxfenc.c:90
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition hwcontext.c:606
AVHWFramesConstraints * av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, const void *hwconfig)
Get the constraints on HW frames given a device and the HW-specific configuration to be used with tha...
Definition hwcontext.c:581
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition hwcontext.c:570
@ AV_HWDEVICE_TYPE_VAAPI
Definition hwcontext.h:31
cl_device_type type
@ AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
common internal api header.
Memory handling functions.
#define P
const char data[16]
Definition mxf.c:149
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3380
enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
Compute what kind of losses will occur when converting from one specific pixel format to another.
Definition pixdesc.c:3739
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition pixfmt.h:126
#define H
Definition pixlet.c:39
#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
main external API structure.
Definition avcodec.h:443
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition avcodec.h:1502
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1471
int profile
profile
Definition avcodec.h:1636
enum AVCodecID codec_id
Definition avcodec.h:453
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition avcodec.h:619
struct AVCodecInternal * internal
Private context used for internal data.
Definition avcodec.h:478
This struct describes the properties of a single codec described by an AVCodecID.
Definition codec_desc.h:38
const char * name
Name of the codec described by this descriptor.
Definition codec_desc.h:46
void * hwaccel_priv_data
hwaccel-specific private data
Definition internal.h:130
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition hwcontext.h:88
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition hwcontext.h:75
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition hwcontext.h:444
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition hwcontext.h:469
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition hwcontext.h:456
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition hwcontext.h:462
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition hwcontext.h:129
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition hwcontext.h:137
VAAPI connection details.
VADisplay display
The VADisplay handle, to be filled by the user.
VAAPI-specific data associated with a frame pool.
VASurfaceAttrib * attributes
Set by the user to apply surface attributes to all surfaces in the frame pool.
VAAPI hardware pipeline configuration details.
VAConfigID config_id
ID of a VAAPI pipeline configuration.
VABufferID * param_buffers
VABufferID * slice_buffers
VASurfaceID output_surface
#define av_malloc_array(a, b)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
int size
enum AVCodecID codec_id
static int vaapi_decode_make_config(AVCodecContext *avctx, AVBufferRef *device_ref, VAConfigID *va_config, AVBufferRef *frames_ref)
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
static const struct @255370265033273361374341050074042335024152335074 vaapi_profile_map[]
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
static const struct @375310172260344333305017135226063207373101217274 vaapi_format_map[]
VAProfile va_profile
#define MAP(va, av)
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
VAProfile(* profile_parser)(AVCodecContext *avctx)
uint32_t fourcc
int ff_vaapi_decode_init(AVCodecContext *avctx)
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
static int vaapi_decode_find_best_format(AVCodecContext *avctx, AVHWDeviceContext *device, VAConfigID config_id, AVHWFramesContext *frames)
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
static void ff_vaapi_decode_destroy_buffers(AVCodecContext *avctx, VAAPIDecodePicture *pic)
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, int nb_params, size_t params_size, const void *slice_data, size_t slice_size)
int codec_profile
VAProfile ff_vaapi_parse_hevc_rext_scc_profile(AVCodecContext *avctx)
Definition vaapi_hevc.c:597