FFmpeg  4.3
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;
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",
332  fourcc, av_get_pix_fmt_name(format));
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 {
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 #undef MAP
414 };
415 
416 /*
417  * Set *va_config and the frames_ref fields from the current codec parameters
418  * in avctx.
419  */
421  AVBufferRef *device_ref,
422  VAConfigID *va_config,
423  AVBufferRef *frames_ref)
424 {
425  AVVAAPIHWConfig *hwconfig = NULL;
426  AVHWFramesConstraints *constraints = NULL;
427  VAStatus vas;
428  int err, i, j;
429  const AVCodecDescriptor *codec_desc;
430  VAProfile *profile_list = NULL, matched_va_profile, va_profile;
431  int profile_count, exact_match, matched_ff_profile, codec_profile;
432 
433  AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data;
434  AVVAAPIDeviceContext *hwctx = device->hwctx;
435 
436  codec_desc = avcodec_descriptor_get(avctx->codec_id);
437  if (!codec_desc) {
438  err = AVERROR(EINVAL);
439  goto fail;
440  }
441 
442  profile_count = vaMaxNumProfiles(hwctx->display);
443  profile_list = av_malloc_array(profile_count,
444  sizeof(VAProfile));
445  if (!profile_list) {
446  err = AVERROR(ENOMEM);
447  goto fail;
448  }
449 
450  vas = vaQueryConfigProfiles(hwctx->display,
451  profile_list, &profile_count);
452  if (vas != VA_STATUS_SUCCESS) {
453  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "
454  "%d (%s).\n", vas, vaErrorStr(vas));
455  err = AVERROR(ENOSYS);
456  goto fail;
457  }
458 
459  matched_va_profile = VAProfileNone;
460  exact_match = 0;
461 
462  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
463  int profile_match = 0;
464  if (avctx->codec_id != vaapi_profile_map[i].codec_id)
465  continue;
466  if (avctx->profile == vaapi_profile_map[i].codec_profile ||
467  vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
468  profile_match = 1;
469 
470  va_profile = vaapi_profile_map[i].profile_parser ?
471  vaapi_profile_map[i].profile_parser(avctx) :
472  vaapi_profile_map[i].va_profile;
473  codec_profile = vaapi_profile_map[i].codec_profile;
474 
475  for (j = 0; j < profile_count; j++) {
476  if (va_profile == profile_list[j]) {
477  exact_match = profile_match;
478  break;
479  }
480  }
481  if (j < profile_count) {
482  matched_va_profile = va_profile;
483  matched_ff_profile = codec_profile;
484  if (exact_match)
485  break;
486  }
487  }
488  av_freep(&profile_list);
489 
490  if (matched_va_profile == VAProfileNone) {
491  av_log(avctx, AV_LOG_ERROR, "No support for codec %s "
492  "profile %d.\n", codec_desc->name, avctx->profile);
493  err = AVERROR(ENOSYS);
494  goto fail;
495  }
496  if (!exact_match) {
497  if (avctx->hwaccel_flags &
499  av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
500  "supported for hardware decode.\n",
501  codec_desc->name, avctx->profile);
502  av_log(avctx, AV_LOG_WARNING, "Using possibly-"
503  "incompatible profile %d instead.\n",
504  matched_ff_profile);
505  } else {
506  av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
507  "supported for hardware decode.\n",
508  codec_desc->name, avctx->profile);
509  err = AVERROR(EINVAL);
510  goto fail;
511  }
512  }
513 
514  vas = vaCreateConfig(hwctx->display, matched_va_profile,
515  VAEntrypointVLD, NULL, 0,
516  va_config);
517  if (vas != VA_STATUS_SUCCESS) {
518  av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
519  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
520  err = AVERROR(EIO);
521  goto fail;
522  }
523 
524  hwconfig = av_hwdevice_hwconfig_alloc(device_ref);
525  if (!hwconfig) {
526  err = AVERROR(ENOMEM);
527  goto fail;
528  }
529  hwconfig->config_id = *va_config;
530 
531  constraints =
532  av_hwdevice_get_hwframe_constraints(device_ref, hwconfig);
533  if (!constraints) {
534  err = AVERROR(ENOMEM);
535  goto fail;
536  }
537 
538  if (avctx->coded_width < constraints->min_width ||
539  avctx->coded_height < constraints->min_height ||
540  avctx->coded_width > constraints->max_width ||
541  avctx->coded_height > constraints->max_height) {
542  av_log(avctx, AV_LOG_ERROR, "Hardware does not support image "
543  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
544  avctx->coded_width, avctx->coded_height,
545  constraints->min_width, constraints->max_width,
546  constraints->min_height, constraints->max_height);
547  err = AVERROR(EINVAL);
548  goto fail;
549  }
550  if (!constraints->valid_sw_formats ||
551  constraints->valid_sw_formats[0] == AV_PIX_FMT_NONE) {
552  av_log(avctx, AV_LOG_ERROR, "Hardware does not offer any "
553  "usable surface formats.\n");
554  err = AVERROR(EINVAL);
555  goto fail;
556  }
557 
558  if (frames_ref) {
560 
561  frames->format = AV_PIX_FMT_VAAPI;
562  frames->width = avctx->coded_width;
563  frames->height = avctx->coded_height;
564 
565  err = vaapi_decode_find_best_format(avctx, device,
566  *va_config, frames);
567  if (err < 0)
568  goto fail;
569 
570  frames->initial_pool_size = 1;
571  // Add per-codec number of surfaces used for storing reference frames.
572  switch (avctx->codec_id) {
573  case AV_CODEC_ID_H264:
574  case AV_CODEC_ID_HEVC:
575  frames->initial_pool_size += 16;
576  break;
577  case AV_CODEC_ID_VP9:
578  frames->initial_pool_size += 8;
579  break;
580  case AV_CODEC_ID_VP8:
581  frames->initial_pool_size += 3;
582  break;
583  default:
584  frames->initial_pool_size += 2;
585  }
586  }
587 
588  av_hwframe_constraints_free(&constraints);
589  av_freep(&hwconfig);
590 
591  return 0;
592 
593 fail:
594  av_hwframe_constraints_free(&constraints);
595  av_freep(&hwconfig);
596  if (*va_config != VA_INVALID_ID) {
597  vaDestroyConfig(hwctx->display, *va_config);
598  *va_config = VA_INVALID_ID;
599  }
600  av_freep(&profile_list);
601  return err;
602 }
603 
605  AVBufferRef *hw_frames_ctx)
606 {
607  AVHWFramesContext *hw_frames = (AVHWFramesContext *)hw_frames_ctx->data;
608  AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
609  AVVAAPIDeviceContext *hwctx;
610  VAConfigID va_config = VA_INVALID_ID;
611  int err;
612 
613  if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI)
614  return AVERROR(EINVAL);
615  hwctx = device_ctx->hwctx;
616 
617  err = vaapi_decode_make_config(avctx, hw_frames->device_ref, &va_config,
618  hw_frames_ctx);
619  if (err)
620  return err;
621 
622  if (va_config != VA_INVALID_ID)
623  vaDestroyConfig(hwctx->display, va_config);
624 
625  return 0;
626 }
627 
629 {
631  VAStatus vas;
632  int err;
633 
634  ctx->va_config = VA_INVALID_ID;
635  ctx->va_context = VA_INVALID_ID;
636 
637 #if FF_API_STRUCT_VAAPI_CONTEXT
638  if (avctx->hwaccel_context) {
639  av_log(avctx, AV_LOG_WARNING, "Using deprecated struct "
640  "vaapi_context in decode.\n");
641 
642  ctx->have_old_context = 1;
643  ctx->old_context = avctx->hwaccel_context;
644 
645  // Really we only want the VAAPI device context, but this
646  // allocates a whole generic device context because we don't
647  // have any other way to determine how big it should be.
648  ctx->device_ref =
650  if (!ctx->device_ref) {
651  err = AVERROR(ENOMEM);
652  goto fail;
653  }
654  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
655  ctx->hwctx = ctx->device->hwctx;
656 
657  ctx->hwctx->display = ctx->old_context->display;
658 
659  // The old VAAPI decode setup assumed this quirk was always
660  // present, so set it here to avoid the behaviour changing.
661  ctx->hwctx->driver_quirks =
663 
664  }
665 #endif
666 
667 #if FF_API_STRUCT_VAAPI_CONTEXT
668  if (ctx->have_old_context) {
669  ctx->va_config = ctx->old_context->config_id;
670  ctx->va_context = ctx->old_context->context_id;
671 
672  av_log(avctx, AV_LOG_DEBUG, "Using user-supplied decoder "
673  "context: %#x/%#x.\n", ctx->va_config, ctx->va_context);
674  } else {
675 #endif
676 
678  if (err < 0)
679  goto fail;
680 
681  ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
682  ctx->hwfc = ctx->frames->hwctx;
683  ctx->device = ctx->frames->device_ctx;
684  ctx->hwctx = ctx->device->hwctx;
685 
686  err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
687  &ctx->va_config, avctx->hw_frames_ctx);
688  if (err)
689  goto fail;
690 
691  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
692  avctx->coded_width, avctx->coded_height,
693  VA_PROGRESSIVE,
694  ctx->hwfc->surface_ids,
695  ctx->hwfc->nb_surfaces,
696  &ctx->va_context);
697  if (vas != VA_STATUS_SUCCESS) {
698  av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
699  "context: %d (%s).\n", vas, vaErrorStr(vas));
700  err = AVERROR(EIO);
701  goto fail;
702  }
703 
704  av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: "
705  "%#x/%#x.\n", ctx->va_config, ctx->va_context);
706 #if FF_API_STRUCT_VAAPI_CONTEXT
707  }
708 #endif
709 
710  return 0;
711 
712 fail:
713  ff_vaapi_decode_uninit(avctx);
714  return err;
715 }
716 
718 {
720  VAStatus vas;
721 
722 #if FF_API_STRUCT_VAAPI_CONTEXT
723  if (ctx->have_old_context) {
725  } else {
726 #endif
727 
728  if (ctx->va_context != VA_INVALID_ID) {
729  vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context);
730  if (vas != VA_STATUS_SUCCESS) {
731  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
732  "context %#x: %d (%s).\n",
733  ctx->va_context, vas, vaErrorStr(vas));
734  }
735  }
736  if (ctx->va_config != VA_INVALID_ID) {
737  vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
738  if (vas != VA_STATUS_SUCCESS) {
739  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
740  "configuration %#x: %d (%s).\n",
741  ctx->va_config, vas, vaErrorStr(vas));
742  }
743  }
744 
745 #if FF_API_STRUCT_VAAPI_CONTEXT
746  }
747 #endif
748 
749  return 0;
750 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
#define NULL
Definition: coverity.c:32
#define P
static const char * format[]
Definition: af_aiir.c:339
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
int size
VAAPI-specific data associated with a frame pool.
if(ret< 0)
Definition: vf_mcdeint.c:279
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:714
VAProfile(* profile_parser)(AVCodecContext *avctx)
Definition: vaapi_decode.c:372
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
VASurfaceAttrib * attributes
Set by the user to apply surface attributes to all surfaces in the frame pool.
static void ff_vaapi_decode_destroy_buffers(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:123
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:30
static const struct @150 vaapi_format_map[]
uint32_t fourcc
Definition: vaapi_decode.c:239
VASurfaceAttrib pixel_format_attribute
Definition: vaapi_decode.h:76
enum AVPixelFormat pix_fmt
Definition: vaapi_decode.c:240
uint32_t context_id
Context ID (video decode pipeline)
Definition: vaapi.h:79
FF_ENABLE_DEPRECATION_WARNINGS AVHWDeviceContext * device
Definition: vaapi_decode.h:67
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:229
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:565
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:209
int profile
profile
Definition: avcodec.h:1859
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:478
Definition: ftp.c:37
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:604
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:601
static int vaapi_decode_find_best_format(AVCodecContext *avctx, AVHWDeviceContext *device, VAConfigID config_id, AVHWFramesContext *frames)
Definition: vaapi_decode.c:278
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:717
static char buffer[20]
Definition: seek.c:32
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:1702
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:151
AVHWFramesContext * frames
Definition: vaapi_decode.h:70
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
const char data[16]
Definition: mxf.c:91
Definition: vf_addroi.c:26
#define CONFIG_VAAPI_1
Definition: config.h:688
AVVAAPIDeviceContext * hwctx
Definition: vaapi_decode.h:68
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array.
Definition: mem.c:200
#define av_log(a,...)
int codec_profile
Definition: vaapi_decode.c:370
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVVAAPIFramesContext * hwfc
Definition: vaapi_decode.h:71
VAAPI hardware pipeline configuration details.
static const struct @151 vaapi_profile_map[]
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
simple assert() macros that are a bit more flexible than ISO C assert().
VAProfile va_profile
Definition: vaapi_decode.c:371
#define fail()
Definition: checkasm.h:123
FF_DISABLE_DEPRECATION_WARNINGS int have_old_context
Definition: vaapi_decode.h:61
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:199
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:149
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:628
AVBufferRef * device_ref
Definition: vaapi_decode.h:63
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:2226
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1860
AVFormatContext * ctx
Definition: movenc.c:48
VABufferID * slice_buffers
Definition: vaapi_decode.h:51
enum AVCodecID codec_id
Definition: vaapi_decode.c:369
struct vaapi_context * old_context
Definition: vaapi_decode.h:62
int frames
Definition: movenc.c:65
#define FF_ARRAY_ELEMS(a)
VABufferID param_buffers[MAX_PARAM_BUFFERS]
Definition: vaapi_decode.h:48
VAProfile ff_vaapi_parse_hevc_rext_profile(AVCodecContext *avctx)
Definition: vaapi_hevc.c:526
VADisplay display
The VADisplay handle, to be filled by the user.
VASurfaceID output_surface
Definition: vaapi_decode.h:45
void * display
Window system dependent data.
Definition: vaapi.h:63
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:471
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:142
Libavcodec external API header.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:453
enum AVCodecID codec_id
Definition: avcodec.h:536
main external API structure.
Definition: avcodec.h:526
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
uint8_t * data
The data buffer.
Definition: buffer.h:89
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:162
unsigned int driver_quirks
Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), with reference to a table of known...
int coded_height
Definition: avcodec.h:714
int index
Definition: gxfenc.c:89
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
cl_device_type type
const char * name
Name of the codec described by this descriptor.
Definition: codec_desc.h:46
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:225
This struct describes the properties of a single codec described by an AVCodecID. ...
Definition: codec_desc.h:38
VAContextID va_context
Definition: vaapi_decode.h:57
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
Definition: decode.c:1130
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:141
A reference to a data buffer.
Definition: buffer.h:81
common internal api header.
common internal and external API header
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:162
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:2838
VAConfigID va_config
Definition: vaapi_decode.h:56
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:561
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
VAAPI connection details.
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3394
#define MAP(va, av)
VAConfigID config_id
ID of a VAAPI pipeline configuration.
static int vaapi_decode_make_config(AVCodecContext *avctx, AVBufferRef *device_ref, VAConfigID *va_config, AVBufferRef *frames_ref)
Definition: vaapi_decode.c:420
#define av_freep(p)
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
#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:2606
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active)...
Definition: avcodec.h:2287
#define av_malloc_array(a, b)
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:2465
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:222
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
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
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:2076
uint32_t config_id
Configuration ID.
Definition: vaapi.h:71
#define V
Definition: avdct.c:30