FFmpeg  4.4.4
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 "libavutil/avassert.h"
20 #include "libavutil/common.h"
21 #include "libavutil/pixdesc.h"
22 
23 #include "avcodec.h"
24 #include "decode.h"
25 #include "internal.h"
26 #include "vaapi_decode.h"
27 #include "vaapi_hevc.h"
28 
29 
31  VAAPIDecodePicture *pic,
32  int type,
33  const void *data,
34  size_t size)
35 {
37  VAStatus vas;
38  VABufferID buffer;
39 
41 
42  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
43  type, size, 1, (void*)data, &buffer);
44  if (vas != VA_STATUS_SUCCESS) {
45  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter "
46  "buffer (type %d): %d (%s).\n",
47  type, vas, vaErrorStr(vas));
48  return AVERROR(EIO);
49  }
50 
51  pic->param_buffers[pic->nb_param_buffers++] = buffer;
52 
53  av_log(avctx, AV_LOG_DEBUG, "Param buffer (type %d, %zu bytes) "
54  "is %#x.\n", type, size, buffer);
55  return 0;
56 }
57 
58 
60  VAAPIDecodePicture *pic,
61  const void *params_data,
62  size_t params_size,
63  const void *slice_data,
64  size_t slice_size)
65 {
67  VAStatus vas;
68  int index;
69 
71  if (pic->nb_slices == pic->slices_allocated) {
72  if (pic->slices_allocated > 0)
73  pic->slices_allocated *= 2;
74  else
75  pic->slices_allocated = 64;
76 
77  pic->slice_buffers =
79  pic->slices_allocated,
80  2 * sizeof(*pic->slice_buffers));
81  if (!pic->slice_buffers)
82  return AVERROR(ENOMEM);
83  }
84  av_assert0(pic->nb_slices + 1 <= pic->slices_allocated);
85 
86  index = 2 * pic->nb_slices;
87 
88  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
89  VASliceParameterBufferType,
90  params_size, 1, (void*)params_data,
91  &pic->slice_buffers[index]);
92  if (vas != VA_STATUS_SUCCESS) {
93  av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
94  "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas));
95  return AVERROR(EIO);
96  }
97 
98  av_log(avctx, AV_LOG_DEBUG, "Slice %d param buffer (%zu bytes) "
99  "is %#x.\n", pic->nb_slices, params_size,
100  pic->slice_buffers[index]);
101 
102  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
103  VASliceDataBufferType,
104  slice_size, 1, (void*)slice_data,
105  &pic->slice_buffers[index + 1]);
106  if (vas != VA_STATUS_SUCCESS) {
107  av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
108  "data buffer (size %zu): %d (%s).\n",
109  slice_size, vas, vaErrorStr(vas));
110  vaDestroyBuffer(ctx->hwctx->display,
111  pic->slice_buffers[index]);
112  return AVERROR(EIO);
113  }
114 
115  av_log(avctx, AV_LOG_DEBUG, "Slice %d data buffer (%zu bytes) "
116  "is %#x.\n", pic->nb_slices, slice_size,
117  pic->slice_buffers[index + 1]);
118 
119  ++pic->nb_slices;
120  return 0;
121 }
122 
124  VAAPIDecodePicture *pic)
125 {
127  VAStatus vas;
128  int i;
129 
130  for (i = 0; i < pic->nb_param_buffers; i++) {
131  vas = vaDestroyBuffer(ctx->hwctx->display,
132  pic->param_buffers[i]);
133  if (vas != VA_STATUS_SUCCESS) {
134  av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
135  "parameter buffer %#x: %d (%s).\n",
136  pic->param_buffers[i], vas, vaErrorStr(vas));
137  }
138  }
139 
140  for (i = 0; i < 2 * pic->nb_slices; i++) {
141  vas = vaDestroyBuffer(ctx->hwctx->display,
142  pic->slice_buffers[i]);
143  if (vas != VA_STATUS_SUCCESS) {
144  av_log(avctx, AV_LOG_ERROR, "Failed to destroy slice "
145  "slice buffer %#x: %d (%s).\n",
146  pic->slice_buffers[i], vas, vaErrorStr(vas));
147  }
148  }
149 }
150 
152  VAAPIDecodePicture *pic)
153 {
155  VAStatus vas;
156  int err;
157 
158  av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n",
159  pic->output_surface);
160 
161  vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
162  pic->output_surface);
163  if (vas != VA_STATUS_SUCCESS) {
164  av_log(avctx, AV_LOG_ERROR, "Failed to begin picture decode "
165  "issue: %d (%s).\n", vas, vaErrorStr(vas));
166  err = AVERROR(EIO);
167  goto fail_with_picture;
168  }
169 
170  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
171  pic->param_buffers, pic->nb_param_buffers);
172  if (vas != VA_STATUS_SUCCESS) {
173  av_log(avctx, AV_LOG_ERROR, "Failed to upload decode "
174  "parameters: %d (%s).\n", vas, vaErrorStr(vas));
175  err = AVERROR(EIO);
176  goto fail_with_picture;
177  }
178 
179  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
180  pic->slice_buffers, 2 * pic->nb_slices);
181  if (vas != VA_STATUS_SUCCESS) {
182  av_log(avctx, AV_LOG_ERROR, "Failed to upload slices: "
183  "%d (%s).\n", vas, vaErrorStr(vas));
184  err = AVERROR(EIO);
185  goto fail_with_picture;
186  }
187 
188  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
189  if (vas != VA_STATUS_SUCCESS) {
190  av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode "
191  "issue: %d (%s).\n", vas, vaErrorStr(vas));
192  err = AVERROR(EIO);
193  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
195  goto fail;
196  else
197  goto fail_at_end;
198  }
199 
200  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
203 
204  err = 0;
205  goto exit;
206 
207 fail_with_picture:
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  "after error: %d (%s).\n", vas, vaErrorStr(vas));
212  }
213 fail:
215 fail_at_end:
216 exit:
217  pic->nb_param_buffers = 0;
218  pic->nb_slices = 0;
219  pic->slices_allocated = 0;
220  av_freep(&pic->slice_buffers);
221 
222  return err;
223 }
224 
226  VAAPIDecodePicture *pic)
227 {
229 
230  pic->nb_param_buffers = 0;
231  pic->nb_slices = 0;
232  pic->slices_allocated = 0;
233  av_freep(&pic->slice_buffers);
234 
235  return 0;
236 }
237 
238 static const struct {
239  uint32_t fourcc;
240  enum AVPixelFormat pix_fmt;
241 } vaapi_format_map[] = {
242 #define MAP(va, av) { VA_FOURCC_ ## va, AV_PIX_FMT_ ## av }
243  // 4:0:0
244  MAP(Y800, GRAY8),
245  // 4:2:0
246  MAP(NV12, NV12),
247  MAP(YV12, YUV420P),
248  MAP(IYUV, YUV420P),
249 #ifdef VA_FOURCC_I420
250  MAP(I420, YUV420P),
251 #endif
252  MAP(IMC3, YUV420P),
253  // 4:1:1
254  MAP(411P, YUV411P),
255  // 4:2:2
256  MAP(422H, YUV422P),
257 #ifdef VA_FOURCC_YV16
258  MAP(YV16, YUV422P),
259 #endif
260  MAP(YUY2, YUYV422),
261 #ifdef VA_FOURCC_Y210
262  MAP(Y210, Y210),
263 #endif
264  // 4:4:0
265  MAP(422V, YUV440P),
266  // 4:4:4
267  MAP(444P, YUV444P),
268  // 4:2:0 10-bit
269 #ifdef VA_FOURCC_P010
270  MAP(P010, P010),
271 #endif
272 #ifdef VA_FOURCC_I010
273  MAP(I010, YUV420P10),
274 #endif
275 #undef MAP
276 };
277 
279  AVHWDeviceContext *device,
280  VAConfigID config_id,
282 {
283  AVVAAPIDeviceContext *hwctx = device->hwctx;
284  VAStatus vas;
285  VASurfaceAttrib *attr;
286  enum AVPixelFormat source_format, best_format, format;
287  uint32_t best_fourcc, fourcc;
288  int i, j, nb_attr;
289 
290  source_format = avctx->sw_pix_fmt;
291  av_assert0(source_format != AV_PIX_FMT_NONE);
292 
293  vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
294  NULL, &nb_attr);
295  if (vas != VA_STATUS_SUCCESS) {
296  av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
297  "%d (%s).\n", vas, vaErrorStr(vas));
298  return AVERROR(ENOSYS);
299  }
300 
301  attr = av_malloc_array(nb_attr, sizeof(*attr));
302  if (!attr)
303  return AVERROR(ENOMEM);
304 
305  vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
306  attr, &nb_attr);
307  if (vas != VA_STATUS_SUCCESS) {
308  av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
309  "%d (%s).\n", vas, vaErrorStr(vas));
310  av_freep(&attr);
311  return AVERROR(ENOSYS);
312  }
313 
314  best_format = AV_PIX_FMT_NONE;
315 
316  for (i = 0; i < nb_attr; i++) {
317  if (attr[i].type != VASurfaceAttribPixelFormat)
318  continue;
319 
320  fourcc = attr[i].value.value.i;
321  for (j = 0; j < FF_ARRAY_ELEMS(vaapi_format_map); j++) {
322  if (fourcc == vaapi_format_map[j].fourcc)
323  break;
324  }
325  if (j >= FF_ARRAY_ELEMS(vaapi_format_map)) {
326  av_log(avctx, AV_LOG_DEBUG, "Ignoring unknown format %#x.\n",
327  fourcc);
328  continue;
329  }
330  format = vaapi_format_map[j].pix_fmt;
331  av_log(avctx, AV_LOG_DEBUG, "Considering format %#x -> %s.\n",
333 
334  best_format = av_find_best_pix_fmt_of_2(format, best_format,
335  source_format, 0, NULL);
336  if (format == best_format)
337  best_fourcc = fourcc;
338  }
339 
340  av_freep(&attr);
341 
342  if (best_format == AV_PIX_FMT_NONE) {
343  av_log(avctx, AV_LOG_ERROR, "No usable formats for decoding!\n");
344  return AVERROR(EINVAL);
345  }
346 
347  av_log(avctx, AV_LOG_DEBUG, "Picked %s (%#x) as best match for %s.\n",
348  av_get_pix_fmt_name(best_format), best_fourcc,
349  av_get_pix_fmt_name(source_format));
350 
351  frames->sw_format = best_format;
352  if (avctx->internal->hwaccel_priv_data) {
354  AVVAAPIFramesContext *avfc = frames->hwctx;
355 
356  ctx->pixel_format_attribute = (VASurfaceAttrib) {
357  .type = VASurfaceAttribPixelFormat,
358  .value.value.i = best_fourcc,
359  };
360 
361  avfc->attributes = &ctx->pixel_format_attribute;
362  avfc->nb_attributes = 1;
363  }
364 
365  return 0;
366 }
367 
368 static const struct {
369  enum AVCodecID codec_id;
371  VAProfile va_profile;
372  VAProfile (*profile_parser)(AVCodecContext *avctx);
373 } vaapi_profile_map[] = {
374 #define MAP(c, p, v, ...) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v, __VA_ARGS__ }
375  MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ),
376  MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ),
377  MAP(H263, UNKNOWN, H263Baseline),
378  MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ),
379  MAP(MPEG4, MPEG4_ADVANCED_SIMPLE,
380  MPEG4AdvancedSimple),
381  MAP(MPEG4, MPEG4_MAIN, MPEG4Main ),
382  MAP(H264, H264_CONSTRAINED_BASELINE,
383  H264ConstrainedBaseline),
384  MAP(H264, H264_MAIN, H264Main ),
385  MAP(H264, H264_HIGH, H264High ),
386 #if VA_CHECK_VERSION(0, 37, 0)
387  MAP(HEVC, HEVC_MAIN, HEVCMain ),
388  MAP(HEVC, HEVC_MAIN_10, HEVCMain10 ),
389  MAP(HEVC, HEVC_MAIN_STILL_PICTURE,
390  HEVCMain ),
391 #endif
392 #if VA_CHECK_VERSION(1, 2, 0) && CONFIG_HEVC_VAAPI_HWACCEL
393  MAP(HEVC, HEVC_REXT, None,
395 #endif
396  MAP(MJPEG, MJPEG_HUFFMAN_BASELINE_DCT,
397  JPEGBaseline),
398  MAP(WMV3, VC1_SIMPLE, VC1Simple ),
399  MAP(WMV3, VC1_MAIN, VC1Main ),
400  MAP(WMV3, VC1_COMPLEX, VC1Advanced ),
401  MAP(WMV3, VC1_ADVANCED, VC1Advanced ),
402  MAP(VC1, VC1_SIMPLE, VC1Simple ),
403  MAP(VC1, VC1_MAIN, VC1Main ),
404  MAP(VC1, VC1_COMPLEX, VC1Advanced ),
405  MAP(VC1, VC1_ADVANCED, VC1Advanced ),
406  MAP(VP8, UNKNOWN, VP8Version0_3 ),
407 #if VA_CHECK_VERSION(0, 38, 0)
408  MAP(VP9, VP9_0, VP9Profile0 ),
409 #endif
410 #if VA_CHECK_VERSION(0, 39, 0)
411  MAP(VP9, VP9_2, VP9Profile2 ),
412 #endif
413 #if VA_CHECK_VERSION(1, 8, 0)
414  MAP(AV1, AV1_MAIN, AV1Profile0),
415  MAP(AV1, AV1_HIGH, AV1Profile1),
416 #endif
417 
418 #undef MAP
419 };
420 
421 /*
422  * Set *va_config and the frames_ref fields from the current codec parameters
423  * in avctx.
424  */
426  AVBufferRef *device_ref,
427  VAConfigID *va_config,
428  AVBufferRef *frames_ref)
429 {
430  AVVAAPIHWConfig *hwconfig = NULL;
431  AVHWFramesConstraints *constraints = NULL;
432  VAStatus vas;
433  int err, i, j;
434  const AVCodecDescriptor *codec_desc;
435  VAProfile *profile_list = NULL, matched_va_profile, va_profile;
436  int profile_count, exact_match, matched_ff_profile, codec_profile;
437 
438  AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data;
439  AVVAAPIDeviceContext *hwctx = device->hwctx;
440 
441  codec_desc = avcodec_descriptor_get(avctx->codec_id);
442  if (!codec_desc) {
443  err = AVERROR(EINVAL);
444  goto fail;
445  }
446 
447  profile_count = vaMaxNumProfiles(hwctx->display);
448  profile_list = av_malloc_array(profile_count,
449  sizeof(VAProfile));
450  if (!profile_list) {
451  err = AVERROR(ENOMEM);
452  goto fail;
453  }
454 
455  vas = vaQueryConfigProfiles(hwctx->display,
456  profile_list, &profile_count);
457  if (vas != VA_STATUS_SUCCESS) {
458  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "
459  "%d (%s).\n", vas, vaErrorStr(vas));
460  err = AVERROR(ENOSYS);
461  goto fail;
462  }
463 
464  matched_va_profile = VAProfileNone;
465  exact_match = 0;
466 
467  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
468  int profile_match = 0;
469  if (avctx->codec_id != vaapi_profile_map[i].codec_id)
470  continue;
471  if (avctx->profile == vaapi_profile_map[i].codec_profile ||
472  vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
473  profile_match = 1;
474 
475  va_profile = vaapi_profile_map[i].profile_parser ?
476  vaapi_profile_map[i].profile_parser(avctx) :
477  vaapi_profile_map[i].va_profile;
478  codec_profile = vaapi_profile_map[i].codec_profile;
479 
480  for (j = 0; j < profile_count; j++) {
481  if (va_profile == profile_list[j]) {
482  exact_match = profile_match;
483  break;
484  }
485  }
486  if (j < profile_count) {
487  matched_va_profile = va_profile;
488  matched_ff_profile = codec_profile;
489  if (exact_match)
490  break;
491  }
492  }
493  av_freep(&profile_list);
494 
495  if (matched_va_profile == VAProfileNone) {
496  av_log(avctx, AV_LOG_ERROR, "No support for codec %s "
497  "profile %d.\n", codec_desc->name, avctx->profile);
498  err = AVERROR(ENOSYS);
499  goto fail;
500  }
501  if (!exact_match) {
502  if (avctx->hwaccel_flags &
504  av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
505  "supported for hardware decode.\n",
506  codec_desc->name, avctx->profile);
507  av_log(avctx, AV_LOG_WARNING, "Using possibly-"
508  "incompatible profile %d instead.\n",
509  matched_ff_profile);
510  } else {
511  av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
512  "supported for hardware decode.\n",
513  codec_desc->name, avctx->profile);
514  err = AVERROR(EINVAL);
515  goto fail;
516  }
517  }
518 
519  vas = vaCreateConfig(hwctx->display, matched_va_profile,
520  VAEntrypointVLD, NULL, 0,
521  va_config);
522  if (vas != VA_STATUS_SUCCESS) {
523  av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
524  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
525  err = AVERROR(EIO);
526  goto fail;
527  }
528 
529  hwconfig = av_hwdevice_hwconfig_alloc(device_ref);
530  if (!hwconfig) {
531  err = AVERROR(ENOMEM);
532  goto fail;
533  }
534  hwconfig->config_id = *va_config;
535 
536  constraints =
537  av_hwdevice_get_hwframe_constraints(device_ref, hwconfig);
538  if (!constraints) {
539  err = AVERROR(ENOMEM);
540  goto fail;
541  }
542 
543  if (avctx->coded_width < constraints->min_width ||
544  avctx->coded_height < constraints->min_height ||
545  avctx->coded_width > constraints->max_width ||
546  avctx->coded_height > constraints->max_height) {
547  av_log(avctx, AV_LOG_ERROR, "Hardware does not support image "
548  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
549  avctx->coded_width, avctx->coded_height,
550  constraints->min_width, constraints->max_width,
551  constraints->min_height, constraints->max_height);
552  err = AVERROR(EINVAL);
553  goto fail;
554  }
555  if (!constraints->valid_sw_formats ||
556  constraints->valid_sw_formats[0] == AV_PIX_FMT_NONE) {
557  av_log(avctx, AV_LOG_ERROR, "Hardware does not offer any "
558  "usable surface formats.\n");
559  err = AVERROR(EINVAL);
560  goto fail;
561  }
562 
563  if (frames_ref) {
565 
566  frames->format = AV_PIX_FMT_VAAPI;
567  frames->width = avctx->coded_width;
568  frames->height = avctx->coded_height;
569 
570  err = vaapi_decode_find_best_format(avctx, device,
571  *va_config, frames);
572  if (err < 0)
573  goto fail;
574 
575  frames->initial_pool_size = 1;
576  // Add per-codec number of surfaces used for storing reference frames.
577  switch (avctx->codec_id) {
578  case AV_CODEC_ID_H264:
579  case AV_CODEC_ID_HEVC:
580  case AV_CODEC_ID_AV1:
581  frames->initial_pool_size += 16;
582  break;
583  case AV_CODEC_ID_VP9:
584  frames->initial_pool_size += 8;
585  break;
586  case AV_CODEC_ID_VP8:
587  frames->initial_pool_size += 3;
588  break;
589  default:
590  frames->initial_pool_size += 2;
591  }
592  }
593 
594  av_hwframe_constraints_free(&constraints);
595  av_freep(&hwconfig);
596 
597  return 0;
598 
599 fail:
600  av_hwframe_constraints_free(&constraints);
601  av_freep(&hwconfig);
602  if (*va_config != VA_INVALID_ID) {
603  vaDestroyConfig(hwctx->display, *va_config);
604  *va_config = VA_INVALID_ID;
605  }
606  av_freep(&profile_list);
607  return err;
608 }
609 
611  AVBufferRef *hw_frames_ctx)
612 {
613  AVHWFramesContext *hw_frames = (AVHWFramesContext *)hw_frames_ctx->data;
614  AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
615  AVVAAPIDeviceContext *hwctx;
616  VAConfigID va_config = VA_INVALID_ID;
617  int err;
618 
619  if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI)
620  return AVERROR(EINVAL);
621  hwctx = device_ctx->hwctx;
622 
623  err = vaapi_decode_make_config(avctx, hw_frames->device_ref, &va_config,
624  hw_frames_ctx);
625  if (err)
626  return err;
627 
628  if (va_config != VA_INVALID_ID)
629  vaDestroyConfig(hwctx->display, va_config);
630 
631  return 0;
632 }
633 
635 {
637  VAStatus vas;
638  int err;
639 
640  ctx->va_config = VA_INVALID_ID;
641  ctx->va_context = VA_INVALID_ID;
642 
643 #if FF_API_STRUCT_VAAPI_CONTEXT
644  if (avctx->hwaccel_context) {
645  av_log(avctx, AV_LOG_WARNING, "Using deprecated struct "
646  "vaapi_context in decode.\n");
647 
648  ctx->have_old_context = 1;
649  ctx->old_context = avctx->hwaccel_context;
650 
651  // Really we only want the VAAPI device context, but this
652  // allocates a whole generic device context because we don't
653  // have any other way to determine how big it should be.
654  ctx->device_ref =
656  if (!ctx->device_ref) {
657  err = AVERROR(ENOMEM);
658  goto fail;
659  }
660  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
661  ctx->hwctx = ctx->device->hwctx;
662 
663  ctx->hwctx->display = ctx->old_context->display;
664 
665  // The old VAAPI decode setup assumed this quirk was always
666  // present, so set it here to avoid the behaviour changing.
667  ctx->hwctx->driver_quirks =
669 
670  }
671 #endif
672 
673 #if FF_API_STRUCT_VAAPI_CONTEXT
674  if (ctx->have_old_context) {
675  ctx->va_config = ctx->old_context->config_id;
676  ctx->va_context = ctx->old_context->context_id;
677 
678  av_log(avctx, AV_LOG_DEBUG, "Using user-supplied decoder "
679  "context: %#x/%#x.\n", ctx->va_config, ctx->va_context);
680  } else {
681 #endif
682 
684  if (err < 0)
685  goto fail;
686 
687  ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
688  ctx->hwfc = ctx->frames->hwctx;
689  ctx->device = ctx->frames->device_ctx;
690  ctx->hwctx = ctx->device->hwctx;
691 
692  err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
693  &ctx->va_config, avctx->hw_frames_ctx);
694  if (err)
695  goto fail;
696 
697  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
698  avctx->coded_width, avctx->coded_height,
699  VA_PROGRESSIVE,
700  ctx->hwfc->surface_ids,
701  ctx->hwfc->nb_surfaces,
702  &ctx->va_context);
703  if (vas != VA_STATUS_SUCCESS) {
704  av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
705  "context: %d (%s).\n", vas, vaErrorStr(vas));
706  err = AVERROR(EIO);
707  goto fail;
708  }
709 
710  av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: "
711  "%#x/%#x.\n", ctx->va_config, ctx->va_context);
712 #if FF_API_STRUCT_VAAPI_CONTEXT
713  }
714 #endif
715 
716  return 0;
717 
718 fail:
719  ff_vaapi_decode_uninit(avctx);
720  return err;
721 }
722 
724 {
726  VAStatus vas;
727 
728 #if FF_API_STRUCT_VAAPI_CONTEXT
729  if (ctx->have_old_context) {
730  av_buffer_unref(&ctx->device_ref);
731  } else {
732 #endif
733 
734  if (ctx->va_context != VA_INVALID_ID) {
735  vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context);
736  if (vas != VA_STATUS_SUCCESS) {
737  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
738  "context %#x: %d (%s).\n",
739  ctx->va_context, vas, vaErrorStr(vas));
740  }
741  }
742  if (ctx->va_config != VA_INVALID_ID) {
743  vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
744  if (vas != VA_STATUS_SUCCESS) {
745  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
746  "configuration %#x: %d (%s).\n",
747  ctx->va_config, vas, vaErrorStr(vas));
748  }
749  }
750 
751 #if FF_API_STRUCT_VAAPI_CONTEXT
752  }
753 #endif
754 
755  return 0;
756 }
static const char *const format[]
Definition: af_aiir.c:456
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
Libavcodec external API header.
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1859
#define V
Definition: avdct.c:30
#define fail()
Definition: checkasm.h:133
common internal and external API header
#define CONFIG_VAAPI_1
Definition: config.h:696
#define NULL
Definition: coverity.c:32
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
Definition: decode.c:1177
@ UNKNOWN
Definition: ftp.c:37
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3501
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
@ AV_CODEC_ID_AV1
Definition: codec_id.h:279
@ AV_CODEC_ID_VP8
Definition: codec_id.h:189
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
#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:2634
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:125
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array.
Definition: mem.c:198
int index
Definition: gxfenc.c:89
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:142
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:601
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:576
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:565
@ AV_HWDEVICE_TYPE_VAAPI
Definition: hwcontext.h:31
cl_device_type type
@ AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
int i
Definition: input.c:407
common internal API header
#define P
const char data[16]
Definition: mxf.c:142
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:2864
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:2489
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
@ AV_PIX_FMT_VAAPI
Definition: pixfmt.h:122
static char buffer[20]
Definition: seek.c:32
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
Definition: buffer.h:84
uint8_t * data
The data buffer.
Definition: buffer.h:92
main external API structure.
Definition: avcodec.h:536
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition: avcodec.h:2279
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:2078
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:2218
int profile
profile
Definition: avcodec.h:1858
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:1692
int coded_height
Definition: avcodec.h:724
enum AVCodecID codec_id
Definition: avcodec.h:546
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:724
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:571
This struct describes the properties of a single codec described by an AVCodecID.
Definition: codec_desc.h:38
const char * name
Name of the codec described by this descriptor.
Definition: codec_desc.h:46
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:180
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:453
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:478
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
Definition: hwcontext.h:465
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:471
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:141
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:149
VAAPI connection details.
VADisplay display
The VADisplay handle, to be filled by the user.
VAAPI-specific data associated with a frame pool.
VASurfaceAttrib * attributes
Set by the user to apply surface attributes to all surfaces in the frame pool.
VAAPI hardware pipeline configuration details.
VAConfigID config_id
ID of a VAAPI pipeline configuration.
VABufferID * slice_buffers
Definition: vaapi_decode.h:51
VABufferID param_buffers[MAX_PARAM_BUFFERS]
Definition: vaapi_decode.h:48
VASurfaceID output_surface
Definition: vaapi_decode.h:45
#define av_malloc_array(a, b)
#define av_freep(p)
#define av_log(a,...)
int frames
Definition: movenc.c:66
AVFormatContext * ctx
Definition: movenc.c:48
int size
enum AVCodecID codec_id
Definition: vaapi_decode.c:369
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:59
static int vaapi_decode_make_config(AVCodecContext *avctx, AVBufferRef *device_ref, VAConfigID *va_config, AVBufferRef *frames_ref)
Definition: vaapi_decode.c:425
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:30
enum AVPixelFormat pix_fmt
Definition: vaapi_decode.c:240
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:610
VAProfile va_profile
Definition: vaapi_decode.c:371
#define MAP(va, av)
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:151
VAProfile(* profile_parser)(AVCodecContext *avctx)
Definition: vaapi_decode.c:372
uint32_t fourcc
Definition: vaapi_decode.c:239
static const struct @149 vaapi_format_map[]
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:634
static const struct @150 vaapi_profile_map[]
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:723
static int vaapi_decode_find_best_format(AVCodecContext *avctx, AVHWDeviceContext *device, VAConfigID config_id, AVHWFramesContext *frames)
Definition: vaapi_decode.c:278
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:225
static void ff_vaapi_decode_destroy_buffers(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:123
int codec_profile
Definition: vaapi_decode.c:370
@ MAX_PARAM_BUFFERS
Definition: vaapi_decode.h:41
VAProfile ff_vaapi_parse_hevc_rext_profile(AVCodecContext *avctx)
Definition: vaapi_hevc.c:526
@ H
Definition: vf_addroi.c:26
if(ret< 0)
Definition: vf_mcdeint.c:282