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