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 "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",
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) {
724  av_buffer_unref(&ctx->device_ref);
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 }
profile_parser
VAProfile(* profile_parser)(AVCodecContext *avctx)
Definition: vaapi_decode.c:372
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
AVVAAPIFramesContext::attributes
VASurfaceAttrib * attributes
Set by the user to apply surface attributes to all surfaces in the frame pool.
Definition: hwcontext_vaapi.h:93
AVCodecContext::hwaccel_context
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:1702
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVVAAPIHWConfig
VAAPI hardware pipeline configuration details.
Definition: hwcontext_vaapi.h:110
VAAPIDecodePicture::slice_buffers
VABufferID * slice_buffers
Definition: vaapi_decode.h:51
pix_fmt
enum AVPixelFormat pix_fmt
Definition: vaapi_decode.c:240
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:565
VAAPIDecodeContext
Definition: vaapi_decode.h:55
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:89
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:44
pixdesc.h
ff_vaapi_decode_make_slice_buffer
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, size_t params_size, const void *slice_data, size_t slice_size)
Definition: vaapi_decode.c:59
internal.h
data
const char data[16]
Definition: mxf.c:91
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:278
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
AVVAAPIDeviceContext::display
VADisplay display
The VADisplay handle, to be filled by the user.
Definition: hwcontext_vaapi.h:72
UNKNOWN
@ UNKNOWN
Definition: ftp.c:37
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:576
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:453
VAAPIDecodePicture::nb_param_buffers
int nb_param_buffers
Definition: vaapi_decode.h:47
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:30
fail
#define fail()
Definition: checkasm.h:123
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:123
AVHWFramesConstraints::min_width
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:471
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:714
vaapi_profile_map
static const struct @151 vaapi_profile_map[]
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:45
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
codec_profile
int codec_profile
Definition: vaapi_decode.c:370
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_hwdevice_ctx_alloc
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:142
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:465
av_hwframe_constraints_free
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:601
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:628
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:198
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:217
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:604
FF_PROFILE_UNKNOWN
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1860
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
ctx
AVFormatContext * ctx
Definition: movenc.c:48
decode.h
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:717
MAX_PARAM_BUFFERS
@ MAX_PARAM_BUFFERS
Definition: vaapi_decode.h:41
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:369
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
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:1130
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:536
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:151
if
if(ret)
Definition: filter_design.txt:179
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
NULL
#define NULL
Definition: coverity.c:32
av_buffer_unref
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
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:141
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:561
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:2606
V
#define V
Definition: avdct.c:30
VAAPIDecodePicture::slices_allocated
int slices_allocated
Definition: vaapi_decode.h:52
index
int index
Definition: gxfenc.c:89
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
VAAPIDecodePicture::nb_slices
int nb_slices
Definition: vaapi_decode.h:50
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:162
P
#define P
size
int size
Definition: twinvq_data.h:11134
va_profile
VAProfile va_profile
Definition: vaapi_decode.c:371
vaapi_hevc.h
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:225
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:478
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Definition: pixfmt.h:122
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:269
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
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:2287
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
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:2226
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:149
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:420
AVHWFramesConstraints::max_height
int max_height
Definition: hwcontext.h:479
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
AVCodecContext
main external API structure.
Definition: avcodec.h:526
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:2838
AVHWFramesConstraints::min_height
int min_height
Definition: hwcontext.h:472
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1859
ff_vaapi_parse_hevc_rext_profile
VAProfile ff_vaapi_parse_hevc_rext_profile(AVCodecContext *avctx)
Definition: vaapi_hevc.c:526
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:714
MAP
#define MAP(va, av)
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:81
AVVAAPIFramesContext
VAAPI-specific data associated with a frame pool.
Definition: hwcontext_vaapi.h:88
vaapi_format_map
static const struct @150 vaapi_format_map[]
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
VAAPIDecodePicture::param_buffers
VABufferID param_buffers[MAX_PARAM_BUFFERS]
Definition: vaapi_decode.h:48
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:189
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVVAAPIDeviceContext
VAAPI connection details.
Definition: hwcontext_vaapi.h:68
avcodec_descriptor_get
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3394
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:2076
fourcc
uint32_t fourcc
Definition: vaapi_decode.c:239
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:2465