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