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