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