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