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 #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  frames->initial_pool_size += 16;
581  break;
582  case AV_CODEC_ID_VP9:
583  case AV_CODEC_ID_AV1:
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 
644  if (err < 0)
645  goto fail;
646 
647  ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
648  ctx->hwfc = ctx->frames->hwctx;
649  ctx->device = ctx->frames->device_ctx;
650  ctx->hwctx = ctx->device->hwctx;
651 
652  err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
653  &ctx->va_config, avctx->hw_frames_ctx);
654  if (err)
655  goto fail;
656 
657  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
658  avctx->coded_width, avctx->coded_height,
659  VA_PROGRESSIVE,
660  ctx->hwfc->surface_ids,
661  ctx->hwfc->nb_surfaces,
662  &ctx->va_context);
663  if (vas != VA_STATUS_SUCCESS) {
664  av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
665  "context: %d (%s).\n", vas, vaErrorStr(vas));
666  err = AVERROR(EIO);
667  goto fail;
668  }
669 
670  av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: "
671  "%#x/%#x.\n", ctx->va_config, ctx->va_context);
672 
673  return 0;
674 
675 fail:
676  ff_vaapi_decode_uninit(avctx);
677  return err;
678 }
679 
681 {
683  VAStatus vas;
684 
685  if (ctx->va_context != VA_INVALID_ID) {
686  vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context);
687  if (vas != VA_STATUS_SUCCESS) {
688  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
689  "context %#x: %d (%s).\n",
690  ctx->va_context, vas, vaErrorStr(vas));
691  }
692  }
693  if (ctx->va_config != VA_INVALID_ID) {
694  vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
695  if (vas != VA_STATUS_SUCCESS) {
696  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
697  "configuration %#x: %d (%s).\n",
698  ctx->va_config, vas, vaErrorStr(vas));
699  }
700  }
701 
702  return 0;
703 }
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
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
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:46
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:50
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
vaapi_decode.h
AVCodecDescriptor::name
const char * name
Name of the codec described by this descriptor.
Definition: codec_desc.h:46
VAAPIDecodePicture
Definition: vaapi_decode.h:39
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
index
fg index
Definition: ffmpeg_filter.c:168
internal.h
data
const char data[16]
Definition: mxf.c:143
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:196
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:42
AVVAAPIHWConfig::config_id
VAConfigID config_id
ID of a VAAPI pipeline configuration.
Definition: hwcontext_vaapi.h:114
ff_vaapi_decode_make_param_buffer
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:30
vaapi_profile_map
static const struct @146 vaapi_profile_map[]
fail
#define fail()
Definition: checkasm.h:136
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:567
VAAPIDecodePicture::output_surface
VASurfaceID output_surface
Definition: vaapi_decode.h:40
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h: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:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
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
AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
@ AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
Definition: hwcontext_vaapi.h:47
AVCodecDescriptor
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:634
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:204
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:218
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:610
FF_PROFILE_UNKNOWN
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1522
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
MAX_PARAM_BUFFERS
@ MAX_PARAM_BUFFERS
Definition: vaapi_decode.h:36
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
decode.h
ff_vaapi_decode_uninit
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:680
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:369
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
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:934
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:389
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
NULL
#define NULL
Definition: coverity.c:32
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:279
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:414
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:2229
V
#define V
Definition: avdct.c:30
VAAPIDecodePicture::slices_allocated
int slices_allocated
Definition: vaapi_decode.h:47
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
VAAPIDecodePicture::nb_slices
int nb_slices
Definition: vaapi_decode.h:45
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:183
P
#define P
size
int size
Definition: twinvq_data.h:10344
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
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:119
AV_HWDEVICE_TYPE_VAAPI
@ AV_HWDEVICE_TYPE_VAAPI
Definition: hwcontext.h:31
i
int i
Definition: input.c:406
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:1911
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:224
vaapi_format_map
static const struct @145 vaapi_format_map[]
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:1853
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:425
AVHWFramesConstraints::max_height
int max_height
Definition: hwcontext.h:479
AVCodecContext
main external API structure.
Definition: avcodec.h:379
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:2831
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:1521
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:567
MAP
#define MAP(va, av)
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVVAAPIFramesContext
VAAPI-specific data associated with a frame pool.
Definition: hwcontext_vaapi.h:88
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
VAAPIDecodePicture::param_buffers
VABufferID param_buffers[MAX_PARAM_BUFFERS]
Definition: vaapi_decode.h:43
format
fg outputs[0] format
Definition: ffmpeg_filter.c:175
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:190
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:3507
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1713
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:2460