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 
28 
30  VAAPIDecodePicture *pic,
31  int type,
32  const void *data,
33  size_t size)
34 {
36  VAStatus vas;
37  VABufferID buffer;
38 
40 
41  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
42  type, size, 1, (void*)data, &buffer);
43  if (vas != VA_STATUS_SUCCESS) {
44  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter "
45  "buffer (type %d): %d (%s).\n",
46  type, vas, vaErrorStr(vas));
47  return AVERROR(EIO);
48  }
49 
50  pic->param_buffers[pic->nb_param_buffers++] = buffer;
51 
52  av_log(avctx, AV_LOG_DEBUG, "Param buffer (type %d, %zu bytes) "
53  "is %#x.\n", type, size, buffer);
54  return 0;
55 }
56 
57 
59  VAAPIDecodePicture *pic,
60  const void *params_data,
61  size_t params_size,
62  const void *slice_data,
63  size_t slice_size)
64 {
66  VAStatus vas;
67  int index;
68 
70  if (pic->nb_slices == pic->slices_allocated) {
71  if (pic->slices_allocated > 0)
72  pic->slices_allocated *= 2;
73  else
74  pic->slices_allocated = 64;
75 
76  pic->slice_buffers =
78  pic->slices_allocated,
79  2 * sizeof(*pic->slice_buffers));
80  if (!pic->slice_buffers)
81  return AVERROR(ENOMEM);
82  }
83  av_assert0(pic->nb_slices + 1 <= pic->slices_allocated);
84 
85  index = 2 * pic->nb_slices;
86 
87  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
88  VASliceParameterBufferType,
89  params_size, 1, (void*)params_data,
90  &pic->slice_buffers[index]);
91  if (vas != VA_STATUS_SUCCESS) {
92  av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
93  "parameter buffer: %d (%s).\n", vas, vaErrorStr(vas));
94  return AVERROR(EIO);
95  }
96 
97  av_log(avctx, AV_LOG_DEBUG, "Slice %d param buffer (%zu bytes) "
98  "is %#x.\n", pic->nb_slices, params_size,
99  pic->slice_buffers[index]);
100 
101  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
102  VASliceDataBufferType,
103  slice_size, 1, (void*)slice_data,
104  &pic->slice_buffers[index + 1]);
105  if (vas != VA_STATUS_SUCCESS) {
106  av_log(avctx, AV_LOG_ERROR, "Failed to create slice "
107  "data buffer (size %zu): %d (%s).\n",
108  slice_size, vas, vaErrorStr(vas));
109  vaDestroyBuffer(ctx->hwctx->display,
110  pic->slice_buffers[index]);
111  return AVERROR(EIO);
112  }
113 
114  av_log(avctx, AV_LOG_DEBUG, "Slice %d data buffer (%zu bytes) "
115  "is %#x.\n", pic->nb_slices, slice_size,
116  pic->slice_buffers[index + 1]);
117 
118  ++pic->nb_slices;
119  return 0;
120 }
121 
123  VAAPIDecodePicture *pic)
124 {
126  VAStatus vas;
127  int i;
128 
129  for (i = 0; i < pic->nb_param_buffers; i++) {
130  vas = vaDestroyBuffer(ctx->hwctx->display,
131  pic->param_buffers[i]);
132  if (vas != VA_STATUS_SUCCESS) {
133  av_log(avctx, AV_LOG_ERROR, "Failed to destroy "
134  "parameter buffer %#x: %d (%s).\n",
135  pic->param_buffers[i], vas, vaErrorStr(vas));
136  }
137  }
138 
139  for (i = 0; i < 2 * pic->nb_slices; i++) {
140  vas = vaDestroyBuffer(ctx->hwctx->display,
141  pic->slice_buffers[i]);
142  if (vas != VA_STATUS_SUCCESS) {
143  av_log(avctx, AV_LOG_ERROR, "Failed to destroy slice "
144  "slice buffer %#x: %d (%s).\n",
145  pic->slice_buffers[i], vas, vaErrorStr(vas));
146  }
147  }
148 }
149 
151  VAAPIDecodePicture *pic)
152 {
154  VAStatus vas;
155  int err;
156 
157  av_log(avctx, AV_LOG_DEBUG, "Decode to surface %#x.\n",
158  pic->output_surface);
159 
160  vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context,
161  pic->output_surface);
162  if (vas != VA_STATUS_SUCCESS) {
163  av_log(avctx, AV_LOG_ERROR, "Failed to begin picture decode "
164  "issue: %d (%s).\n", vas, vaErrorStr(vas));
165  err = AVERROR(EIO);
166  goto fail_with_picture;
167  }
168 
169  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
170  pic->param_buffers, pic->nb_param_buffers);
171  if (vas != VA_STATUS_SUCCESS) {
172  av_log(avctx, AV_LOG_ERROR, "Failed to upload decode "
173  "parameters: %d (%s).\n", vas, vaErrorStr(vas));
174  err = AVERROR(EIO);
175  goto fail_with_picture;
176  }
177 
178  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
179  pic->slice_buffers, 2 * pic->nb_slices);
180  if (vas != VA_STATUS_SUCCESS) {
181  av_log(avctx, AV_LOG_ERROR, "Failed to upload slices: "
182  "%d (%s).\n", vas, vaErrorStr(vas));
183  err = AVERROR(EIO);
184  goto fail_with_picture;
185  }
186 
187  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
188  if (vas != VA_STATUS_SUCCESS) {
189  av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode "
190  "issue: %d (%s).\n", vas, vaErrorStr(vas));
191  err = AVERROR(EIO);
192  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
194  goto fail;
195  else
196  goto fail_at_end;
197  }
198 
199  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
202 
203  err = 0;
204  goto exit;
205 
206 fail_with_picture:
207  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
208  if (vas != VA_STATUS_SUCCESS) {
209  av_log(avctx, AV_LOG_ERROR, "Failed to end picture decode "
210  "after error: %d (%s).\n", vas, vaErrorStr(vas));
211  }
212 fail:
214 fail_at_end:
215 exit:
216  pic->nb_param_buffers = 0;
217  pic->nb_slices = 0;
218  pic->slices_allocated = 0;
219  av_freep(&pic->slice_buffers);
220 
221  return err;
222 }
223 
225  VAAPIDecodePicture *pic)
226 {
228 
229  pic->nb_param_buffers = 0;
230  pic->nb_slices = 0;
231  pic->slices_allocated = 0;
232  av_freep(&pic->slice_buffers);
233 
234  return 0;
235 }
236 
237 static const struct {
238  uint32_t fourcc;
240 } vaapi_format_map[] = {
241 #define MAP(va, av) { VA_FOURCC_ ## va, AV_PIX_FMT_ ## av }
242  // 4:0:0
243  MAP(Y800, GRAY8),
244  // 4:2:0
245  MAP(NV12, NV12),
246  MAP(YV12, YUV420P),
247  MAP(IYUV, YUV420P),
248 #ifdef VA_FOURCC_I420
249  MAP(I420, YUV420P),
250 #endif
251  MAP(IMC3, YUV420P),
252  // 4:1:1
253  MAP(411P, YUV411P),
254  // 4:2:2
255  MAP(422H, YUV422P),
256 #ifdef VA_FOURCC_YV16
257  MAP(YV16, YUV422P),
258 #endif
259  // 4:4:0
260  MAP(422V, YUV440P),
261  // 4:4:4
262  MAP(444P, YUV444P),
263  // 4:2:0 10-bit
264 #ifdef VA_FOURCC_P010
265  MAP(P010, P010),
266 #endif
267 #ifdef VA_FOURCC_I010
268  MAP(I010, YUV420P10),
269 #endif
270 #undef MAP
271 };
272 
274  AVHWDeviceContext *device,
275  VAConfigID config_id,
277 {
278  AVVAAPIDeviceContext *hwctx = device->hwctx;
279  VAStatus vas;
280  VASurfaceAttrib *attr;
281  enum AVPixelFormat source_format, best_format, format;
282  uint32_t best_fourcc, fourcc;
283  int i, j, nb_attr;
284 
285  source_format = avctx->sw_pix_fmt;
286  av_assert0(source_format != AV_PIX_FMT_NONE);
287 
288  vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
289  NULL, &nb_attr);
290  if (vas != VA_STATUS_SUCCESS) {
291  av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
292  "%d (%s).\n", vas, vaErrorStr(vas));
293  return AVERROR(ENOSYS);
294  }
295 
296  attr = av_malloc_array(nb_attr, sizeof(*attr));
297  if (!attr)
298  return AVERROR(ENOMEM);
299 
300  vas = vaQuerySurfaceAttributes(hwctx->display, config_id,
301  attr, &nb_attr);
302  if (vas != VA_STATUS_SUCCESS) {
303  av_log(avctx, AV_LOG_ERROR, "Failed to query surface attributes: "
304  "%d (%s).\n", vas, vaErrorStr(vas));
305  av_freep(&attr);
306  return AVERROR(ENOSYS);
307  }
308 
309  best_format = AV_PIX_FMT_NONE;
310 
311  for (i = 0; i < nb_attr; i++) {
312  if (attr[i].type != VASurfaceAttribPixelFormat)
313  continue;
314 
315  fourcc = attr[i].value.value.i;
316  for (j = 0; j < FF_ARRAY_ELEMS(vaapi_format_map); j++) {
317  if (fourcc == vaapi_format_map[j].fourcc)
318  break;
319  }
320  if (j >= FF_ARRAY_ELEMS(vaapi_format_map)) {
321  av_log(avctx, AV_LOG_DEBUG, "Ignoring unknown format %#x.\n",
322  fourcc);
323  continue;
324  }
325  format = vaapi_format_map[j].pix_fmt;
326  av_log(avctx, AV_LOG_DEBUG, "Considering format %#x -> %s.\n",
328 
329  best_format = av_find_best_pix_fmt_of_2(format, best_format,
330  source_format, 0, NULL);
331  if (format == best_format)
332  best_fourcc = fourcc;
333  }
334 
335  av_freep(&attr);
336 
337  if (best_format == AV_PIX_FMT_NONE) {
338  av_log(avctx, AV_LOG_ERROR, "No usable formats for decoding!\n");
339  return AVERROR(EINVAL);
340  }
341 
342  av_log(avctx, AV_LOG_DEBUG, "Picked %s (%#x) as best match for %s.\n",
343  av_get_pix_fmt_name(best_format), best_fourcc,
344  av_get_pix_fmt_name(source_format));
345 
346  frames->sw_format = best_format;
347  if (avctx->internal->hwaccel_priv_data) {
349  AVVAAPIFramesContext *avfc = frames->hwctx;
350 
351  ctx->pixel_format_attribute = (VASurfaceAttrib) {
352  .type = VASurfaceAttribPixelFormat,
353  .value.value.i = best_fourcc,
354  };
355 
356  avfc->attributes = &ctx->pixel_format_attribute;
357  avfc->nb_attributes = 1;
358  }
359 
360  return 0;
361 }
362 
363 static const struct {
366  VAProfile va_profile;
367 } vaapi_profile_map[] = {
368 #define MAP(c, p, v) { AV_CODEC_ID_ ## c, FF_PROFILE_ ## p, VAProfile ## v }
369  MAP(MPEG2VIDEO, MPEG2_SIMPLE, MPEG2Simple ),
370  MAP(MPEG2VIDEO, MPEG2_MAIN, MPEG2Main ),
371  MAP(H263, UNKNOWN, H263Baseline),
372  MAP(MPEG4, MPEG4_SIMPLE, MPEG4Simple ),
373  MAP(MPEG4, MPEG4_ADVANCED_SIMPLE,
374  MPEG4AdvancedSimple),
375  MAP(MPEG4, MPEG4_MAIN, MPEG4Main ),
376  MAP(H264, H264_CONSTRAINED_BASELINE,
377  H264ConstrainedBaseline),
378  MAP(H264, H264_MAIN, H264Main ),
379  MAP(H264, H264_HIGH, H264High ),
380 #if VA_CHECK_VERSION(0, 37, 0)
381  MAP(HEVC, HEVC_MAIN, HEVCMain ),
382  MAP(HEVC, HEVC_MAIN_10, HEVCMain10 ),
383 #endif
384  MAP(MJPEG, MJPEG_HUFFMAN_BASELINE_DCT,
385  JPEGBaseline),
386  MAP(WMV3, VC1_SIMPLE, VC1Simple ),
387  MAP(WMV3, VC1_MAIN, VC1Main ),
388  MAP(WMV3, VC1_COMPLEX, VC1Advanced ),
389  MAP(WMV3, VC1_ADVANCED, VC1Advanced ),
390  MAP(VC1, VC1_SIMPLE, VC1Simple ),
391  MAP(VC1, VC1_MAIN, VC1Main ),
392  MAP(VC1, VC1_COMPLEX, VC1Advanced ),
393  MAP(VC1, VC1_ADVANCED, VC1Advanced ),
394  MAP(VP8, UNKNOWN, VP8Version0_3 ),
395 #if VA_CHECK_VERSION(0, 38, 0)
396  MAP(VP9, VP9_0, VP9Profile0 ),
397 #endif
398 #if VA_CHECK_VERSION(0, 39, 0)
399  MAP(VP9, VP9_2, VP9Profile2 ),
400 #endif
401 #undef MAP
402 };
403 
404 /*
405  * Set *va_config and the frames_ref fields from the current codec parameters
406  * in avctx.
407  */
409  AVBufferRef *device_ref,
410  VAConfigID *va_config,
411  AVBufferRef *frames_ref)
412 {
413  AVVAAPIHWConfig *hwconfig = NULL;
414  AVHWFramesConstraints *constraints = NULL;
415  VAStatus vas;
416  int err, i, j;
417  const AVCodecDescriptor *codec_desc;
418  VAProfile *profile_list = NULL, matched_va_profile;
419  int profile_count, exact_match, matched_ff_profile;
420 
421  AVHWDeviceContext *device = (AVHWDeviceContext*)device_ref->data;
422  AVVAAPIDeviceContext *hwctx = device->hwctx;
423 
424  codec_desc = avcodec_descriptor_get(avctx->codec_id);
425  if (!codec_desc) {
426  err = AVERROR(EINVAL);
427  goto fail;
428  }
429 
430  profile_count = vaMaxNumProfiles(hwctx->display);
431  profile_list = av_malloc_array(profile_count,
432  sizeof(VAProfile));
433  if (!profile_list) {
434  err = AVERROR(ENOMEM);
435  goto fail;
436  }
437 
438  vas = vaQueryConfigProfiles(hwctx->display,
439  profile_list, &profile_count);
440  if (vas != VA_STATUS_SUCCESS) {
441  av_log(avctx, AV_LOG_ERROR, "Failed to query profiles: "
442  "%d (%s).\n", vas, vaErrorStr(vas));
443  err = AVERROR(ENOSYS);
444  goto fail;
445  }
446 
447  matched_va_profile = VAProfileNone;
448  exact_match = 0;
449 
450  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_profile_map); i++) {
451  int profile_match = 0;
452  if (avctx->codec_id != vaapi_profile_map[i].codec_id)
453  continue;
454  if (avctx->profile == vaapi_profile_map[i].codec_profile ||
455  vaapi_profile_map[i].codec_profile == FF_PROFILE_UNKNOWN)
456  profile_match = 1;
457  for (j = 0; j < profile_count; j++) {
458  if (vaapi_profile_map[i].va_profile == profile_list[j]) {
459  exact_match = profile_match;
460  break;
461  }
462  }
463  if (j < profile_count) {
464  matched_va_profile = vaapi_profile_map[i].va_profile;
465  matched_ff_profile = vaapi_profile_map[i].codec_profile;
466  if (exact_match)
467  break;
468  }
469  }
470  av_freep(&profile_list);
471 
472  if (matched_va_profile == VAProfileNone) {
473  av_log(avctx, AV_LOG_ERROR, "No support for codec %s "
474  "profile %d.\n", codec_desc->name, avctx->profile);
475  err = AVERROR(ENOSYS);
476  goto fail;
477  }
478  if (!exact_match) {
479  if (avctx->hwaccel_flags &
481  av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
482  "supported for hardware decode.\n",
483  codec_desc->name, avctx->profile);
484  av_log(avctx, AV_LOG_WARNING, "Using possibly-"
485  "incompatible profile %d instead.\n",
486  matched_ff_profile);
487  } else {
488  av_log(avctx, AV_LOG_VERBOSE, "Codec %s profile %d not "
489  "supported for hardware decode.\n",
490  codec_desc->name, avctx->profile);
491  err = AVERROR(EINVAL);
492  goto fail;
493  }
494  }
495 
496  vas = vaCreateConfig(hwctx->display, matched_va_profile,
497  VAEntrypointVLD, NULL, 0,
498  va_config);
499  if (vas != VA_STATUS_SUCCESS) {
500  av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
501  "configuration: %d (%s).\n", vas, vaErrorStr(vas));
502  err = AVERROR(EIO);
503  goto fail;
504  }
505 
506  hwconfig = av_hwdevice_hwconfig_alloc(device_ref);
507  if (!hwconfig) {
508  err = AVERROR(ENOMEM);
509  goto fail;
510  }
511  hwconfig->config_id = *va_config;
512 
513  constraints =
514  av_hwdevice_get_hwframe_constraints(device_ref, hwconfig);
515  if (!constraints) {
516  err = AVERROR(ENOMEM);
517  goto fail;
518  }
519 
520  if (avctx->coded_width < constraints->min_width ||
521  avctx->coded_height < constraints->min_height ||
522  avctx->coded_width > constraints->max_width ||
523  avctx->coded_height > constraints->max_height) {
524  av_log(avctx, AV_LOG_ERROR, "Hardware does not support image "
525  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
526  avctx->coded_width, avctx->coded_height,
527  constraints->min_width, constraints->max_width,
528  constraints->min_height, constraints->max_height);
529  err = AVERROR(EINVAL);
530  goto fail;
531  }
532  if (!constraints->valid_sw_formats ||
533  constraints->valid_sw_formats[0] == AV_PIX_FMT_NONE) {
534  av_log(avctx, AV_LOG_ERROR, "Hardware does not offer any "
535  "usable surface formats.\n");
536  err = AVERROR(EINVAL);
537  goto fail;
538  }
539 
540  if (frames_ref) {
542 
543  frames->format = AV_PIX_FMT_VAAPI;
544  frames->width = avctx->coded_width;
545  frames->height = avctx->coded_height;
546 
547  err = vaapi_decode_find_best_format(avctx, device,
548  *va_config, frames);
549  if (err < 0)
550  goto fail;
551 
552  frames->initial_pool_size = 1;
553  // Add per-codec number of surfaces used for storing reference frames.
554  switch (avctx->codec_id) {
555  case AV_CODEC_ID_H264:
556  case AV_CODEC_ID_HEVC:
557  frames->initial_pool_size += 16;
558  break;
559  case AV_CODEC_ID_VP9:
560  frames->initial_pool_size += 8;
561  break;
562  case AV_CODEC_ID_VP8:
563  frames->initial_pool_size += 3;
564  break;
565  default:
566  frames->initial_pool_size += 2;
567  }
568  }
569 
570  av_hwframe_constraints_free(&constraints);
571  av_freep(&hwconfig);
572 
573  return 0;
574 
575 fail:
576  av_hwframe_constraints_free(&constraints);
577  av_freep(&hwconfig);
578  if (*va_config != VA_INVALID_ID) {
579  vaDestroyConfig(hwctx->display, *va_config);
580  *va_config = VA_INVALID_ID;
581  }
582  av_freep(&profile_list);
583  return err;
584 }
585 
587  AVBufferRef *hw_frames_ctx)
588 {
589  AVHWFramesContext *hw_frames = (AVHWFramesContext *)hw_frames_ctx->data;
590  AVHWDeviceContext *device_ctx = hw_frames->device_ctx;
591  AVVAAPIDeviceContext *hwctx;
592  VAConfigID va_config = VA_INVALID_ID;
593  int err;
594 
595  if (device_ctx->type != AV_HWDEVICE_TYPE_VAAPI)
596  return AVERROR(EINVAL);
597  hwctx = device_ctx->hwctx;
598 
599  err = vaapi_decode_make_config(avctx, hw_frames->device_ref, &va_config,
600  hw_frames_ctx);
601  if (err)
602  return err;
603 
604  if (va_config != VA_INVALID_ID)
605  vaDestroyConfig(hwctx->display, va_config);
606 
607  return 0;
608 }
609 
611 {
613  VAStatus vas;
614  int err;
615 
616  ctx->va_config = VA_INVALID_ID;
617  ctx->va_context = VA_INVALID_ID;
618 
619 #if FF_API_STRUCT_VAAPI_CONTEXT
620  if (avctx->hwaccel_context) {
621  av_log(avctx, AV_LOG_WARNING, "Using deprecated struct "
622  "vaapi_context in decode.\n");
623 
624  ctx->have_old_context = 1;
625  ctx->old_context = avctx->hwaccel_context;
626 
627  // Really we only want the VAAPI device context, but this
628  // allocates a whole generic device context because we don't
629  // have any other way to determine how big it should be.
630  ctx->device_ref =
632  if (!ctx->device_ref) {
633  err = AVERROR(ENOMEM);
634  goto fail;
635  }
636  ctx->device = (AVHWDeviceContext*)ctx->device_ref->data;
637  ctx->hwctx = ctx->device->hwctx;
638 
639  ctx->hwctx->display = ctx->old_context->display;
640 
641  // The old VAAPI decode setup assumed this quirk was always
642  // present, so set it here to avoid the behaviour changing.
643  ctx->hwctx->driver_quirks =
645 
646  }
647 #endif
648 
649 #if FF_API_STRUCT_VAAPI_CONTEXT
650  if (ctx->have_old_context) {
651  ctx->va_config = ctx->old_context->config_id;
652  ctx->va_context = ctx->old_context->context_id;
653 
654  av_log(avctx, AV_LOG_DEBUG, "Using user-supplied decoder "
655  "context: %#x/%#x.\n", ctx->va_config, ctx->va_context);
656  } else {
657 #endif
658 
660  if (err < 0)
661  goto fail;
662 
663  ctx->frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
664  ctx->hwfc = ctx->frames->hwctx;
665  ctx->device = ctx->frames->device_ctx;
666  ctx->hwctx = ctx->device->hwctx;
667 
668  err = vaapi_decode_make_config(avctx, ctx->frames->device_ref,
669  &ctx->va_config, avctx->hw_frames_ctx);
670  if (err)
671  goto fail;
672 
673  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
674  avctx->coded_width, avctx->coded_height,
675  VA_PROGRESSIVE,
676  ctx->hwfc->surface_ids,
677  ctx->hwfc->nb_surfaces,
678  &ctx->va_context);
679  if (vas != VA_STATUS_SUCCESS) {
680  av_log(avctx, AV_LOG_ERROR, "Failed to create decode "
681  "context: %d (%s).\n", vas, vaErrorStr(vas));
682  err = AVERROR(EIO);
683  goto fail;
684  }
685 
686  av_log(avctx, AV_LOG_DEBUG, "Decode context initialised: "
687  "%#x/%#x.\n", ctx->va_config, ctx->va_context);
688 #if FF_API_STRUCT_VAAPI_CONTEXT
689  }
690 #endif
691 
692  return 0;
693 
694 fail:
695  ff_vaapi_decode_uninit(avctx);
696  return err;
697 }
698 
700 {
702  VAStatus vas;
703 
704 #if FF_API_STRUCT_VAAPI_CONTEXT
705  if (ctx->have_old_context) {
706  av_buffer_unref(&ctx->device_ref);
707  } else {
708 #endif
709 
710  if (ctx->va_context != VA_INVALID_ID) {
711  vas = vaDestroyContext(ctx->hwctx->display, ctx->va_context);
712  if (vas != VA_STATUS_SUCCESS) {
713  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
714  "context %#x: %d (%s).\n",
715  ctx->va_context, vas, vaErrorStr(vas));
716  }
717  }
718  if (ctx->va_config != VA_INVALID_ID) {
719  vas = vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
720  if (vas != VA_STATUS_SUCCESS) {
721  av_log(avctx, AV_LOG_ERROR, "Failed to destroy decode "
722  "configuration %#x: %d (%s).\n",
723  ctx->va_config, vas, vaErrorStr(vas));
724  }
725  }
726 
727 #if FF_API_STRUCT_VAAPI_CONTEXT
728  }
729 #endif
730 
731  return 0;
732 }
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:91
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:2741
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:239
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:526
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: avcodec.h:724
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:58
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:273
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:34
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:537
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:432
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:29
fail
#define fail()
Definition: checkasm.h:120
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:122
AVHWFramesConstraints::min_width
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:450
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:1753
MAX_PARAM_BUFFERS
@ MAX_PARAM_BUFFERS
Definition: vaapi_decode.h:41
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:60
codec_profile
int codec_profile
Definition: vaapi_decode.c:365
avassert.h
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
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:138
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:444
av_hwframe_constraints_free
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:562
AVCodecDescriptor
This struct describes the properties of a single codec described by an AVCodecID.
Definition: avcodec.h:716
ff_vaapi_decode_init
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:610
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: avcodec.h:386
ff_vaapi_common_frame_params
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:586
FF_PROFILE_UNKNOWN
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2899
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:699
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:364
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: avcodec.h:245
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:1222
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:1575
ff_vaapi_decode_issue
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:150
if
if(ret)
Definition: filter_design.txt:179
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:140
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:1600
H
F H1 F F H1 F F F F H1<-F-------F-------F v v v H2 H3 H2 ^ ^ ^ F-------F-------F-> H1<-F-------F-------F|||||||||F H1 F|||||||||F H1 Funavailable fullpel samples(outside the picture for example) shall be equalto the closest available fullpel sampleSmaller pel interpolation:--------------------------if diag_mc is set then points which lie on a line between 2 vertically, horizontally or diagonally adjacent halfpel points shall be interpolatedlinearly with rounding to nearest and halfway values rounded up.points which lie on 2 diagonals at the same time should only use the onediagonal not containing the fullpel point F--> O q O<--h1-> O q O<--F v \/v \/v O O O O O O O|/|\|q q q q q|/|\|O O O O O O O ^/\ ^/\ ^ h2--> O q O<--h3-> O q O<--h2 v \/v \/v O O O O O O O|\|/|q q q q q|\|/|O O O O O O O ^/\ ^/\ ^ F--> O q O<--h1-> O q O<--Fthe remaining points shall be bilinearly interpolated from theup to 4 surrounding halfpel and fullpel points, again rounding should be tonearest and halfway values rounded upcompliant Snow decoders MUST support 1-1/8 pel luma and 1/2-1/16 pel chromainterpolation at leastOverlapped block motion compensation:-------------------------------------FIXMELL band prediction:===================Each sample in the LL0 subband is predicted by the median of the left, top andleft+top-topleft samples, samples outside the subband shall be considered tobe 0. To reverse this prediction in the decoder apply the following.for(y=0;y< height;y++){ for(x=0;x< width;x++){ sample[y][x]+=median(sample[y-1][x], sample[y][x-1], sample[y-1][x]+sample[y][x-1]-sample[y-1][x-1]);}}sample[-1][ *]=sample[ *][-1]=0;width, height here are the width and height of the LL0 subband not of the finalvideoDequantization:===============FIXMEWavelet Transform:==================Snow supports 2 wavelet transforms, the symmetric biorthogonal 5/3 integertransform and an integer approximation of the symmetric biorthogonal 9/7daubechies wavelet.2D IDWT(inverse discrete wavelet transform) --------------------------------------------The 2D IDWT applies a 2D filter recursively, each time combining the4 lowest frequency subbands into a single subband until only 1 subbandremains.The 2D filter is done by first applying a 1D filter in the vertical directionand then applying it in the horizontal one. --------------- --------------- --------------- ---------------|LL0|HL0|||||||||||||---+---|HL1||L0|H0|HL1||LL1|HL1|||||LH0|HH0|||||||||||||-------+-------|-> L1 H1 LH1 HH1 LH1 HH1 LH1 HH1 this can end with a L or a H
Definition: snow.txt:555
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:3845
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: avcodec.h:215
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:190
P
#define P
size
int size
Definition: twinvq_data.h:11134
va_profile
VAProfile va_profile
Definition: vaapi_decode.c:366
ff_vaapi_decode_cancel
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:224
AVHWFramesConstraints::max_width
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:457
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:259
avcodec_descriptor_get
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3257
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:3323
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: avcodec.h:392
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:3262
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:148
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:408
AVHWFramesConstraints::max_height
int max_height
Definition: hwcontext.h:458
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
vaapi_profile_map
static const struct @164 vaapi_profile_map[]
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
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:2811
AVHWFramesConstraints::min_height
int min_height
Definition: hwcontext.h:451
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:2898
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1753
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
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: avcodec.h:358
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVVAAPIDeviceContext
VAAPI connection details.
Definition: hwcontext_vaapi.h:68
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:3112
fourcc
uint32_t fourcc
Definition: vaapi_decode.c:238
vaapi_format_map
static const struct @163 vaapi_format_map[]
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:2438