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",
327  fourcc, av_get_pix_fmt_name(format));
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) {
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 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
#define NULL
Definition: coverity.c:32
#define P
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
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
VAAPI-specific data associated with a frame pool.
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1756
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
VASurfaceAttrib * attributes
Set by the user to apply surface attributes to all surfaces in the frame pool.
static void ff_vaapi_decode_destroy_buffers(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:122
int ff_vaapi_decode_make_param_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, int type, const void *data, size_t size)
Definition: vaapi_decode.c:29
uint32_t fourcc
Definition: vaapi_decode.c:238
VASurfaceAttrib pixel_format_attribute
Definition: vaapi_decode.h:76
enum AVPixelFormat pix_fmt
Definition: vaapi_decode.c:239
uint32_t context_id
Context ID (video decode pipeline)
Definition: vaapi.h:79
FF_ENABLE_DEPRECATION_WARNINGS AVHWDeviceContext * device
Definition: vaapi_decode.h:67
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:228
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:526
GLint GLenum type
Definition: opengl_enc.c:104
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:208
int profile
profile
Definition: avcodec.h:2901
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
if it could not because there are no more frames
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:457
Definition: ftp.c:34
int ff_vaapi_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: vaapi_decode.c:586
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:562
static int vaapi_decode_find_best_format(AVCodecContext *avctx, AVHWDeviceContext *device, VAConfigID config_id, AVHWFramesContext *frames)
Definition: vaapi_decode.c:273
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_vaapi_decode_uninit(AVCodecContext *avctx)
Definition: vaapi_decode.c:699
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:2744
int ff_vaapi_decode_issue(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:150
AVHWFramesContext * frames
Definition: vaapi_decode.h:70
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:91
AVVAAPIDeviceContext * hwctx
Definition: vaapi_decode.h:68
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
ptrdiff_t size
Definition: opengl_enc.c:100
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:198
#define av_log(a,...)
int codec_profile
Definition: vaapi_decode.c:365
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVVAAPIFramesContext * hwfc
Definition: vaapi_decode.h:71
VAAPI hardware pipeline configuration details.
static const struct @169 vaapi_profile_map[]
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
simple assert() macros that are a bit more flexible than ISO C assert().
VAProfile va_profile
Definition: vaapi_decode.c:366
#define fail()
Definition: checkasm.h:122
FF_DISABLE_DEPRECATION_WARNINGS int have_old_context
Definition: vaapi_decode.h:61
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3276
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:198
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:148
int ff_vaapi_decode_init(AVCodecContext *avctx)
Definition: vaapi_decode.c:610
AVBufferRef * device_ref
Definition: vaapi_decode.h:63
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:3265
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2902
AVFormatContext * ctx
Definition: movenc.c:48
VABufferID * slice_buffers
Definition: vaapi_decode.h:51
enum AVCodecID codec_id
Definition: vaapi_decode.c:364
struct vaapi_context * old_context
Definition: vaapi_decode.h:62
#define FF_ARRAY_ELEMS(a)
VABufferID param_buffers[MAX_PARAM_BUFFERS]
Definition: vaapi_decode.h:48
if(ret)
VADisplay display
The VADisplay handle, to be filled by the user.
VASurfaceID output_surface
Definition: vaapi_decode.h:45
void * display
Window system dependent data.
Definition: vaapi.h:63
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:450
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given hardware type.
Definition: hwcontext.c:138
Libavcodec external API header.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:432
enum AVCodecID codec_id
Definition: avcodec.h:1578
main external API structure.
Definition: avcodec.h:1568
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
uint8_t * data
The data buffer.
Definition: buffer.h:89
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:161
unsigned int driver_quirks
Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), with reference to a table of known...
int coded_height
Definition: avcodec.h:1756
int index
Definition: gxfenc.c:89
static const struct @168 vaapi_format_map[]
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
const char * name
Name of the codec described by this descriptor.
Definition: avcodec.h:727
int ff_vaapi_decode_cancel(AVCodecContext *avctx, VAAPIDecodePicture *pic)
Definition: vaapi_decode.c:224
This struct describes the properties of a single codec described by an AVCodecID. ...
Definition: avcodec.h:719
VAContextID va_context
Definition: vaapi_decode.h:57
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
Definition: decode.c:1221
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:140
A reference to a data buffer.
Definition: buffer.h:81
common internal api header.
common internal and external API header
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:190
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
VAConfigID va_config
Definition: vaapi_decode.h:56
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:1603
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
#define H
Definition: pixlet.c:39
VAAPI connection details.
#define MAP(va, av)
VAConfigID config_id
ID of a VAAPI pipeline configuration.
static int vaapi_decode_make_config(AVCodecContext *avctx, AVBufferRef *device_ref, VAConfigID *va_config, AVBufferRef *frames_ref)
Definition: vaapi_decode.c:408
#define av_freep(p)
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH
Hardware acceleration should still be attempted for decoding when the codec profile does not match th...
Definition: avcodec.h:3856
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active)...
Definition: avcodec.h:3326
#define av_malloc_array(a, b)
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2438
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
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:221
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int ff_vaapi_decode_make_slice_buffer(AVCodecContext *avctx, VAAPIDecodePicture *pic, const void *params_data, size_t params_size, const void *slice_data, size_t slice_size)
Definition: vaapi_decode.c:58
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:3115
GLuint buffer
Definition: opengl_enc.c:101
uint32_t config_id
Configuration ID.
Definition: vaapi.h:71
#define V
Definition: avdct.c:30