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