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