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