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