FFmpeg
vaapi_vpp.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 <string.h>
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/pixdesc.h"
23 #include "formats.h"
24 #include "internal.h"
25 #include "vaapi_vpp.h"
26 
28 {
29  enum AVPixelFormat pix_fmts[] = {
31  };
32  int err;
33 
35  &avctx->inputs[0]->outcfg.formats)) < 0)
36  return err;
38  &avctx->outputs[0]->incfg.formats)) < 0)
39  return err;
40 
41  if ((err = ff_set_common_all_color_spaces(avctx)) < 0 ||
42  (err = ff_set_common_all_color_ranges(avctx)) < 0)
43  return err;
44 
45  return 0;
46 }
47 
49 {
50  VAAPIVPPContext *ctx = avctx->priv;
51  int i;
52  for (i = 0; i < ctx->nb_filter_buffers; i++) {
53  if (ctx->filter_buffers[i] != VA_INVALID_ID) {
54  vaDestroyBuffer(ctx->hwctx->display, ctx->filter_buffers[i]);
55  ctx->filter_buffers[i] = VA_INVALID_ID;
56  }
57  }
58  ctx->nb_filter_buffers = 0;
59 
60  if (ctx->va_context != VA_INVALID_ID) {
61  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
62  ctx->va_context = VA_INVALID_ID;
63  }
64 
65  if (ctx->va_config != VA_INVALID_ID) {
66  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
67  ctx->va_config = VA_INVALID_ID;
68  }
69 
70  av_buffer_unref(&ctx->device_ref);
71  ctx->hwctx = NULL;
72 }
73 
75 {
76  AVFilterContext *avctx = inlink->dst;
77  VAAPIVPPContext *ctx = avctx->priv;
78 
79  if (ctx->pipeline_uninit)
80  ctx->pipeline_uninit(avctx);
81 
82  if (!inlink->hw_frames_ctx) {
83  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
84  "required to associate the processing device.\n");
85  return AVERROR(EINVAL);
86  }
87 
88  ctx->input_frames_ref = av_buffer_ref(inlink->hw_frames_ctx);
89  if (!ctx->input_frames_ref) {
90  av_log(avctx, AV_LOG_ERROR, "A input frames reference create "
91  "failed.\n");
92  return AVERROR(ENOMEM);
93  }
94  ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
95 
96  return 0;
97 }
98 
100 {
101  AVFilterContext *avctx = outlink->src;
102  AVFilterLink *inlink = avctx->inputs[0];
103  VAAPIVPPContext *ctx = avctx->priv;
104  AVVAAPIHWConfig *hwconfig = NULL;
105  AVHWFramesConstraints *constraints = NULL;
106  AVHWFramesContext *output_frames;
107  AVVAAPIFramesContext *va_frames;
108  VAStatus vas;
109  int err, i;
110 
111  if (ctx->pipeline_uninit)
112  ctx->pipeline_uninit(avctx);
113 
114  if (!ctx->output_width)
115  ctx->output_width = avctx->inputs[0]->w;
116  if (!ctx->output_height)
117  ctx->output_height = avctx->inputs[0]->h;
118 
119  outlink->w = ctx->output_width;
120  outlink->h = ctx->output_height;
121 
122  if (ctx->passthrough) {
123  if (inlink->hw_frames_ctx)
124  outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
125  av_log(ctx, AV_LOG_VERBOSE, "Using VAAPI filter passthrough mode.\n");
126 
127  return 0;
128  }
129 
130  av_assert0(ctx->input_frames);
131  ctx->device_ref = av_buffer_ref(ctx->input_frames->device_ref);
132  if (!ctx->device_ref) {
133  av_log(avctx, AV_LOG_ERROR, "A device reference create "
134  "failed.\n");
135  return AVERROR(ENOMEM);
136  }
137  ctx->hwctx = ((AVHWDeviceContext*)ctx->device_ref->data)->hwctx;
138 
139  av_assert0(ctx->va_config == VA_INVALID_ID);
140  vas = vaCreateConfig(ctx->hwctx->display, VAProfileNone,
141  VAEntrypointVideoProc, NULL, 0, &ctx->va_config);
142  if (vas != VA_STATUS_SUCCESS) {
143  av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline "
144  "config: %d (%s).\n", vas, vaErrorStr(vas));
145  err = AVERROR(EIO);
146  goto fail;
147  }
148 
149  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
150  if (!hwconfig) {
151  err = AVERROR(ENOMEM);
152  goto fail;
153  }
154  hwconfig->config_id = ctx->va_config;
155 
156  constraints = av_hwdevice_get_hwframe_constraints(ctx->device_ref,
157  hwconfig);
158  if (!constraints) {
159  err = AVERROR(ENOMEM);
160  goto fail;
161  }
162 
163  if (ctx->output_format == AV_PIX_FMT_NONE)
164  ctx->output_format = ctx->input_frames->sw_format;
165  if (constraints->valid_sw_formats) {
166  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
167  if (ctx->output_format == constraints->valid_sw_formats[i])
168  break;
169  }
170  if (constraints->valid_sw_formats[i] == AV_PIX_FMT_NONE) {
171  av_log(avctx, AV_LOG_ERROR, "Hardware does not support output "
172  "format %s.\n", av_get_pix_fmt_name(ctx->output_format));
173  err = AVERROR(EINVAL);
174  goto fail;
175  }
176  }
177 
178  if (ctx->output_width < constraints->min_width ||
179  ctx->output_height < constraints->min_height ||
180  ctx->output_width > constraints->max_width ||
181  ctx->output_height > constraints->max_height) {
182  av_log(avctx, AV_LOG_ERROR, "Hardware does not support scaling to "
183  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
184  ctx->output_width, ctx->output_height,
185  constraints->min_width, constraints->max_width,
186  constraints->min_height, constraints->max_height);
187  err = AVERROR(EINVAL);
188  goto fail;
189  }
190 
191  outlink->hw_frames_ctx = av_hwframe_ctx_alloc(ctx->device_ref);
192  if (!outlink->hw_frames_ctx) {
193  av_log(avctx, AV_LOG_ERROR, "Failed to create HW frame context "
194  "for output.\n");
195  err = AVERROR(ENOMEM);
196  goto fail;
197  }
198 
199  output_frames = (AVHWFramesContext*)outlink->hw_frames_ctx->data;
200 
201  output_frames->format = AV_PIX_FMT_VAAPI;
202  output_frames->sw_format = ctx->output_format;
203  output_frames->width = ctx->output_width;
204  output_frames->height = ctx->output_height;
205 
206  output_frames->initial_pool_size = 4;
207 
208  err = ff_filter_init_hw_frames(avctx, outlink, 10);
209  if (err < 0)
210  goto fail;
211 
212  err = av_hwframe_ctx_init(outlink->hw_frames_ctx);
213  if (err < 0) {
214  av_log(avctx, AV_LOG_ERROR, "Failed to initialise VAAPI frame "
215  "context for output: %d\n", err);
216  goto fail;
217  }
218 
219  va_frames = output_frames->hwctx;
220 
221  av_assert0(ctx->va_context == VA_INVALID_ID);
222  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
223  ctx->output_width, ctx->output_height,
224  VA_PROGRESSIVE,
225  va_frames->surface_ids, va_frames->nb_surfaces,
226  &ctx->va_context);
227  if (vas != VA_STATUS_SUCCESS) {
228  av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline "
229  "context: %d (%s).\n", vas, vaErrorStr(vas));
230  return AVERROR(EIO);
231  }
232 
233  if (ctx->build_filter_params) {
234  err = ctx->build_filter_params(avctx);
235  if (err < 0)
236  goto fail;
237  }
238 
239  av_freep(&hwconfig);
240  av_hwframe_constraints_free(&constraints);
241  return 0;
242 
243 fail:
244  av_buffer_unref(&outlink->hw_frames_ctx);
245  av_freep(&hwconfig);
246  av_hwframe_constraints_free(&constraints);
247  return err;
248 }
249 
250 typedef struct VAAPIColourProperties {
251  VAProcColorStandardType va_color_standard;
252 
256 
258  uint8_t va_color_range;
259 
263 
265  { VAProcColorStandardBT601, 5, 6, 5 },
266  { VAProcColorStandardBT601, 6, 6, 6 },
267  { VAProcColorStandardBT709, 1, 1, 1 },
268  { VAProcColorStandardBT470M, 4, 4, 4 },
269  { VAProcColorStandardBT470BG, 5, 5, 5 },
270  { VAProcColorStandardSMPTE170M, 6, 6, 6 },
271  { VAProcColorStandardSMPTE240M, 7, 7, 7 },
272  { VAProcColorStandardGenericFilm, 8, 1, 1 },
273 #if VA_CHECK_VERSION(1, 1, 0)
274  { VAProcColorStandardSRGB, 1, 13, 0 },
275  { VAProcColorStandardXVYCC601, 1, 11, 5 },
276  { VAProcColorStandardXVYCC709, 1, 11, 1 },
277  { VAProcColorStandardBT2020, 9, 14, 9 },
278 #endif
279 };
280 
282  VAProcColorStandardType *vacs,
283  int nb_vacs)
284 {
285  const VAAPIColourProperties *t;
286  int i, j, score, best_score, worst_score;
287  VAProcColorStandardType best_standard;
288 
289 #if VA_CHECK_VERSION(1, 3, 0)
290  // If the driver supports explicit use of the standard values then just
291  // use them and avoid doing any mapping. (The driver may not support
292  // some particular code point, but it still has enough information to
293  // make a better fallback choice than we do in that case.)
294  for (i = 0; i < nb_vacs; i++) {
295  if (vacs[i] == VAProcColorStandardExplicit) {
296  props->va_color_standard = VAProcColorStandardExplicit;
297  return;
298  }
299  }
300 #endif
301 
302  // Give scores to the possible options and choose the lowest one.
303  // An exact match will score zero and therefore always be chosen, as
304  // will a partial match where all unmatched elements are explicitly
305  // unspecified. If no options match at all then just pass "none" to
306  // the driver and let it make its own choice.
307  best_standard = VAProcColorStandardNone;
308  best_score = -1;
309  worst_score = 4 * (props->colorspace != AVCOL_SPC_UNSPECIFIED &&
310  props->colorspace != AVCOL_SPC_RGB) +
311  2 * (props->color_trc != AVCOL_TRC_UNSPECIFIED) +
313 
314  if (worst_score == 0) {
315  // No properties are specified, so we aren't going to be able to
316  // make a useful choice.
317  props->va_color_standard = VAProcColorStandardNone;
318  return;
319  }
320 
321  for (i = 0; i < nb_vacs; i++) {
322  for (j = 0; j < FF_ARRAY_ELEMS(vaapi_colour_standard_map); j++) {
324  if (t->va_color_standard != vacs[i])
325  continue;
326 
327  score = 0;
328  if (props->colorspace != AVCOL_SPC_UNSPECIFIED &&
329  props->colorspace != AVCOL_SPC_RGB)
330  score += 4 * (props->colorspace != t->colorspace);
331  if (props->color_trc != AVCOL_TRC_UNSPECIFIED)
332  score += 2 * (props->color_trc != t->color_trc);
334  score += (props->color_primaries != t->color_primaries);
335 
336  // Only include choices which matched something.
337  if (score < worst_score &&
338  (best_score == -1 || score < best_score)) {
339  best_score = score;
340  best_standard = t->va_color_standard;
341  }
342  }
343  }
344  props->va_color_standard = best_standard;
345 }
346 
348 {
349 #if VA_CHECK_VERSION(1, 1, 0)
350  static const struct {
351  enum AVChromaLocation av;
352  uint8_t va;
353  } csl_map[] = {
354  { AVCHROMA_LOC_UNSPECIFIED, VA_CHROMA_SITING_UNKNOWN },
355  { AVCHROMA_LOC_LEFT, VA_CHROMA_SITING_VERTICAL_CENTER |
356  VA_CHROMA_SITING_HORIZONTAL_LEFT },
357  { AVCHROMA_LOC_CENTER, VA_CHROMA_SITING_VERTICAL_CENTER |
358  VA_CHROMA_SITING_HORIZONTAL_CENTER },
359  { AVCHROMA_LOC_TOPLEFT, VA_CHROMA_SITING_VERTICAL_TOP |
360  VA_CHROMA_SITING_HORIZONTAL_LEFT },
361  { AVCHROMA_LOC_TOP, VA_CHROMA_SITING_VERTICAL_TOP |
362  VA_CHROMA_SITING_HORIZONTAL_CENTER },
363  { AVCHROMA_LOC_BOTTOMLEFT, VA_CHROMA_SITING_VERTICAL_BOTTOM |
364  VA_CHROMA_SITING_HORIZONTAL_LEFT },
365  { AVCHROMA_LOC_BOTTOM, VA_CHROMA_SITING_VERTICAL_BOTTOM |
366  VA_CHROMA_SITING_HORIZONTAL_CENTER },
367  };
368  int i;
369 
370  for (i = 0; i < FF_ARRAY_ELEMS(csl_map); i++) {
371  if (props->chroma_sample_location == csl_map[i].av) {
372  props->va_chroma_sample_location = csl_map[i].va;
373  return;
374  }
375  }
376  props->va_chroma_sample_location = VA_CHROMA_SITING_UNKNOWN;
377 #else
378  props->va_chroma_sample_location = 0;
379 #endif
380 }
381 
383 {
384 #if VA_CHECK_VERSION(1, 1, 0)
385  switch (props->color_range) {
386  case AVCOL_RANGE_MPEG:
387  props->va_color_range = VA_SOURCE_RANGE_REDUCED;
388  break;
389  case AVCOL_RANGE_JPEG:
390  props->va_color_range = VA_SOURCE_RANGE_FULL;
391  break;
393  default:
394  props->va_color_range = VA_SOURCE_RANGE_UNKNOWN;
395  }
396 #else
397  props->va_color_range = 0;
398 #endif
399 }
400 
402  VAAPIColourProperties *props,
403  VAProcColorStandardType *vacs,
404  int nb_vacs)
405 {
406  vaapi_vpp_fill_colour_standard(props, vacs, nb_vacs);
409 
410  av_log(avctx, AV_LOG_DEBUG, "Mapped colour properties %s %s/%s/%s %s "
411  "to VA standard %d chroma siting %#x range %#x.\n",
417  props->va_color_standard,
419 }
420 
422 {
423  const AVHWFramesContext *hwfc;
424  const AVPixFmtDescriptor *desc;
427  hwfc = (const AVHWFramesContext*)frame->hw_frames_ctx->data;
429  av_assert0(desc);
430  return !!(desc->flags & AV_PIX_FMT_FLAG_RGB);
431 }
432 
434  VAProcPipelineParameterBuffer *params,
435  const AVFrame *input_frame,
437 {
438  VAAPIVPPContext *ctx = avctx->priv;
439  VAAPIColourProperties input_props, output_props;
440  VAProcPipelineCaps caps;
441  VAStatus vas;
442 
443  vas = vaQueryVideoProcPipelineCaps(ctx->hwctx->display, ctx->va_context,
444  ctx->filter_buffers, ctx->nb_filter_buffers,
445  &caps);
446  if (vas != VA_STATUS_SUCCESS) {
447  av_log(avctx, AV_LOG_ERROR, "Failed to query capabilities for "
448  "colour standard support: %d (%s).\n", vas, vaErrorStr(vas));
449  return AVERROR_EXTERNAL;
450  }
451 
452  input_props = (VAAPIColourProperties) {
453  .colorspace = vaapi_vpp_frame_is_rgb(input_frame)
454  ? AVCOL_SPC_RGB : input_frame->colorspace,
455  .color_primaries = input_frame->color_primaries,
456  .color_trc = input_frame->color_trc,
457  .color_range = input_frame->color_range,
458  .chroma_sample_location = input_frame->chroma_location,
459  };
460 
461  vaapi_vpp_fill_colour_properties(avctx, &input_props,
462  caps.input_color_standards,
463  caps.num_input_color_standards);
464 
465  output_props = (VAAPIColourProperties) {
467  ? AVCOL_SPC_RGB : output_frame->colorspace,
468  .color_primaries = output_frame->color_primaries,
469  .color_trc = output_frame->color_trc,
470  .color_range = output_frame->color_range,
471  .chroma_sample_location = output_frame->chroma_location,
472  };
473  vaapi_vpp_fill_colour_properties(avctx, &output_props,
474  caps.output_color_standards,
475  caps.num_output_color_standards);
476 
477  // If the properties weren't filled completely in the output frame and
478  // we chose a fixed standard then fill the known values in here.
479 #if VA_CHECK_VERSION(1, 3, 0)
480  if (output_props.va_color_standard != VAProcColorStandardExplicit)
481 #endif
482  {
483  const VAAPIColourProperties *output_standard = NULL;
484  int i;
485 
486  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_colour_standard_map); i++) {
487  if (output_props.va_color_standard ==
489  output_standard = &vaapi_colour_standard_map[i];
490  break;
491  }
492  }
493  if (output_standard) {
495  ? AVCOL_SPC_RGB : output_standard->colorspace;
496  output_frame->color_primaries = output_standard->color_primaries;
497  output_frame->color_trc = output_standard->color_trc;
498  }
499  }
500 
501  params->surface_color_standard = input_props.va_color_standard;
502  params->output_color_standard = output_props.va_color_standard;
503 
504 #if VA_CHECK_VERSION(1, 1, 0)
505  params->input_color_properties = (VAProcColorProperties) {
506  .chroma_sample_location = input_props.va_chroma_sample_location,
507  .color_range = input_props.va_color_range,
508 #if VA_CHECK_VERSION(1, 3, 0)
509  .colour_primaries = input_props.color_primaries,
510  .transfer_characteristics = input_props.color_trc,
511  .matrix_coefficients = input_props.colorspace,
512 #endif
513  };
514  params->output_color_properties = (VAProcColorProperties) {
515  .chroma_sample_location = output_props.va_chroma_sample_location,
516  .color_range = output_props.va_color_range,
517 #if VA_CHECK_VERSION(1, 3, 0)
518  .colour_primaries = output_props.color_primaries,
519  .transfer_characteristics = output_props.color_trc,
520  .matrix_coefficients = output_props.colorspace,
521 #endif
522  };
523 #endif
524 
525  return 0;
526 }
527 
529  VAProcPipelineParameterBuffer *params,
530  const AVFrame *input_frame,
532 {
533  VAAPIVPPContext *ctx = avctx->priv;
534  int err;
535 
536  ctx->input_region = (VARectangle) {
537  .x = input_frame->crop_left,
538  .y = input_frame->crop_top,
539  .width = input_frame->width -
540  (input_frame->crop_left + input_frame->crop_right),
541  .height = input_frame->height -
542  (input_frame->crop_top + input_frame->crop_bottom),
543  };
544  output_frame->crop_top = 0;
545  output_frame->crop_bottom = 0;
546  output_frame->crop_left = 0;
547  output_frame->crop_right = 0;
548 
549  *params = (VAProcPipelineParameterBuffer) {
550  .surface = ff_vaapi_vpp_get_surface_id(input_frame),
551  .surface_region = &ctx->input_region,
552  .output_region = NULL,
553  .output_background_color = VAAPI_VPP_BACKGROUND_BLACK,
554  .pipeline_flags = 0,
555  .filter_flags = VA_FRAME_PICTURE,
556 
557  // Filter and reference data filled by the filter itself.
558 
559 #if VA_CHECK_VERSION(1, 1, 0)
560  .rotation_state = VA_ROTATION_NONE,
561  .mirror_state = VA_MIRROR_NONE,
562 #endif
563  };
564 
565  err = vaapi_vpp_colour_properties(avctx, params,
566  input_frame, output_frame);
567  if (err < 0)
568  return err;
569 
570  av_log(avctx, AV_LOG_DEBUG, "Filter frame from surface %#x to %#x.\n",
571  ff_vaapi_vpp_get_surface_id(input_frame),
573 
574  return 0;
575 }
576 
578  int type,
579  const void *data,
580  size_t size,
581  int count)
582 {
583  VAStatus vas;
584  VABufferID buffer;
585  VAAPIVPPContext *ctx = avctx->priv;
586 
587  av_assert0(ctx->nb_filter_buffers + 1 <= VAProcFilterCount);
588 
589  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
590  type, size, count, (void*)data, &buffer);
591  if (vas != VA_STATUS_SUCCESS) {
592  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter "
593  "buffer (type %d): %d (%s).\n",
594  type, vas, vaErrorStr(vas));
595  return AVERROR(EIO);
596  }
597 
598  ctx->filter_buffers[ctx->nb_filter_buffers++] = buffer;
599 
600  av_log(avctx, AV_LOG_DEBUG, "Param buffer (type %d, %zu bytes, count %d) "
601  "is %#x.\n", type, size, count, buffer);
602  return 0;
603 }
604 
606  VAProcPipelineParameterBuffer *params,
607  VABufferID *params_id)
608 {
609  VAAPIVPPContext *ctx = avctx->priv;
610  VAStatus vas;
611 
612  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
613  VAProcPipelineParameterBufferType,
614  sizeof(*params), 1, params, params_id);
615  if (vas != VA_STATUS_SUCCESS) {
616  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
617  "%d (%s).\n", vas, vaErrorStr(vas));
618  *params_id = VA_INVALID_ID;
619 
620  return AVERROR(EIO);
621  }
622  av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n", *params_id);
623 
624  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, params_id, 1);
625  if (vas != VA_STATUS_SUCCESS) {
626  av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
627  "%d (%s).\n", vas, vaErrorStr(vas));
628  return AVERROR(EIO);
629  }
630 
631  return 0;
632 }
633 
635  VAProcPipelineParameterBuffer *params_list,
636  int cout,
638 {
639  VAAPIVPPContext *ctx = avctx->priv;
640  VABufferID *params_ids;
641  VAStatus vas;
642  int err;
643 
644  params_ids = (VABufferID *)av_malloc_array(cout, sizeof(VABufferID));
645  if (!params_ids)
646  return AVERROR(ENOMEM);
647 
648  for (int i = 0; i < cout; i++)
649  params_ids[i] = VA_INVALID_ID;
650 
651  vas = vaBeginPicture(ctx->hwctx->display,
653  if (vas != VA_STATUS_SUCCESS) {
654  av_log(avctx, AV_LOG_ERROR, "Failed to attach new picture: "
655  "%d (%s).\n", vas, vaErrorStr(vas));
656  err = AVERROR(EIO);
657  goto fail;
658  }
659 
660  for (int i = 0; i < cout; i++) {
661  err = vaapi_vpp_render_single_pipeline_buffer(avctx, &params_list[i], &params_ids[i]);
662  if (err)
663  goto fail_after_begin;
664  }
665 
666  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
667  if (vas != VA_STATUS_SUCCESS) {
668  av_log(avctx, AV_LOG_ERROR, "Failed to start picture processing: "
669  "%d (%s).\n", vas, vaErrorStr(vas));
670  err = AVERROR(EIO);
671  goto fail_after_render;
672  }
673 
674  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
676  for (int i = 0; i < cout && params_ids[i] != VA_INVALID_ID; i++) {
677  vas = vaDestroyBuffer(ctx->hwctx->display, params_ids[i]);
678  if (vas != VA_STATUS_SUCCESS) {
679  av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: "
680  "%d (%s).\n", vas, vaErrorStr(vas));
681  // And ignore.
682  }
683  }
684  }
685 
686  av_freep(&params_ids);
687  return 0;
688 
689  // We want to make sure that if vaBeginPicture has been called, we also
690  // call vaRenderPicture and vaEndPicture. These calls may well fail or
691  // do something else nasty, but once we're in this failure case there
692  // isn't much else we can do.
693 fail_after_begin:
694  vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_ids[0], 1);
695 fail_after_render:
696  vaEndPicture(ctx->hwctx->display, ctx->va_context);
697 fail:
698  av_freep(&params_ids);
699  return err;
700 }
701 
703  VAProcPipelineParameterBuffer *params,
705 {
706  return ff_vaapi_vpp_render_pictures(avctx, params, 1, output_frame);
707 }
708 
710 {
711  int i;
712  VAAPIVPPContext *ctx = avctx->priv;
713 
714  ctx->va_config = VA_INVALID_ID;
715  ctx->va_context = VA_INVALID_ID;
716  ctx->valid_ids = 1;
717 
718  for (i = 0; i < VAProcFilterCount; i++)
719  ctx->filter_buffers[i] = VA_INVALID_ID;
720  ctx->nb_filter_buffers = 0;
721 }
722 
724 {
725  VAAPIVPPContext *ctx = avctx->priv;
726  if (ctx->valid_ids && ctx->pipeline_uninit)
727  ctx->pipeline_uninit(avctx);
728 
729  av_buffer_unref(&ctx->input_frames_ref);
730  av_buffer_unref(&ctx->device_ref);
731 }
AVFrame::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:623
ff_vaapi_vpp_pipeline_uninit
void ff_vaapi_vpp_pipeline_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:48
ff_vaapi_vpp_ctx_init
void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
Definition: vaapi_vpp.c:709
vaapi_vpp_frame_is_rgb
static int vaapi_vpp_frame_is_rgb(const AVFrame *frame)
Definition: vaapi_vpp.c:421
ff_vaapi_vpp_get_surface_id
static VASurfaceID ff_vaapi_vpp_get_surface_id(const AVFrame *frame)
Definition: vaapi_vpp.h:30
AVFrame::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:619
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
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
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
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:435
AVVAAPIHWConfig
VAAPI hardware pipeline configuration details.
Definition: hwcontext_vaapi.h:110
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:580
ff_vaapi_vpp_render_picture
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, AVFrame *output_frame)
Definition: vaapi_vpp.c:702
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:555
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AVCHROMA_LOC_BOTTOM
@ AVCHROMA_LOC_BOTTOM
Definition: pixfmt.h:709
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:197
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
AVFrame::color_primaries
enum AVColorPrimaries color_primaries
Definition: frame.h:621
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:630
ff_set_common_all_color_spaces
int ff_set_common_all_color_spaces(AVFilterContext *ctx)
Equivalent to ff_set_common_color_spaces(ctx, ff_all_color_spaces())
Definition: formats.c:839
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:322
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
pixdesc.h
AVFrame::width
int width
Definition: frame.h:412
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:683
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:248
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:583
data
const char data[16]
Definition: mxf.c:148
ff_vaapi_vpp_render_pictures
int ff_vaapi_vpp_render_pictures(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params_list, int cout, AVFrame *output_frame)
Definition: vaapi_vpp.c:634
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:610
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:555
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:217
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:566
av_chroma_location_name
const char * av_chroma_location_name(enum AVChromaLocation location)
Definition: pixdesc.c:3359
VAAPIColourProperties::color_primaries
enum AVColorPrimaries color_primaries
Definition: vaapi_vpp.c:253
AVHWFramesConstraints
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:441
formats.h
AVVAAPIHWConfig::config_id
VAConfigID config_id
ID of a VAAPI pipeline configuration.
Definition: hwcontext_vaapi.h:114
AVFrame::chroma_location
enum AVChromaLocation chroma_location
Definition: frame.h:632
AVVAAPIFramesContext::surface_ids
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
Definition: hwcontext_vaapi.h:101
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3338
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:422
fail
#define fail()
Definition: checkasm.h:179
AVHWFramesConstraints::min_width
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:459
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
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
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
AVHWFramesContext::height
int height
Definition: hwcontext.h:217
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:453
av_hwframe_constraints_free
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:591
VAAPIColourProperties::colorspace
enum AVColorSpace colorspace
Definition: vaapi_vpp.c:255
AVCHROMA_LOC_TOP
@ AVCHROMA_LOC_TOP
Definition: pixfmt.h:707
VAAPIColourProperties::color_range
enum AVColorRange color_range
Definition: vaapi_vpp.c:260
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:678
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:304
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
ff_vaapi_vpp_make_param_buffers
int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx, int type, const void *data, size_t size, int count)
Definition: vaapi_vpp.c:577
vaapi_vpp_fill_chroma_sample_location
static void vaapi_vpp_fill_chroma_sample_location(VAAPIColourProperties *props)
Definition: vaapi_vpp.c:347
AVFrame::crop_right
size_t crop_right
Definition: frame.h:720
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:558
frame
static AVFrame * frame
Definition: demux_decode.c:54
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:3278
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:210
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:139
AVCHROMA_LOC_LEFT
@ AVCHROMA_LOC_LEFT
MPEG-2/4 4:2:0, H.264 default for 4:2:0.
Definition: pixfmt.h:704
vaapi_vpp_colour_properties
static int vaapi_vpp_colour_properties(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, const AVFrame *input_frame, AVFrame *output_frame)
Definition: vaapi_vpp.c:433
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:706
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:415
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3296
ff_vaapi_vpp_config_input
int ff_vaapi_vpp_config_input(AVFilterLink *inlink)
Definition: vaapi_vpp.c:74
vaapi_colour_standard_map
static const VAAPIColourProperties vaapi_colour_standard_map[]
Definition: vaapi_vpp.c:264
ff_vaapi_vpp_ctx_uninit
void ff_vaapi_vpp_ctx_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:723
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:649
ff_vaapi_vpp_query_formats
int ff_vaapi_vpp_query_formats(AVFilterContext *avctx)
Definition: vaapi_vpp.c:27
AVFrame::crop_bottom
size_t crop_bottom
Definition: frame.h:718
AVFrame::crop_left
size_t crop_left
Definition: frame.h:719
vaapi_vpp.h
AV_PIX_FMT_FLAG_RGB
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:136
size
int size
Definition: twinvq_data.h:10344
AVCHROMA_LOC_UNSPECIFIED
@ AVCHROMA_LOC_UNSPECIFIED
Definition: pixfmt.h:703
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:427
height
#define height
output_frame
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:874
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
AVHWFramesConstraints::max_width
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:466
AV_PIX_FMT_VAAPI
@ AV_PIX_FMT_VAAPI
Hardware acceleration through VA-API, data[3] contains a VASurfaceID.
Definition: pixfmt.h:126
internal.h
AVChromaLocation
AVChromaLocation
Location of chroma samples.
Definition: pixfmt.h:702
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AVColorSpace
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:609
ff_set_common_all_color_ranges
int ff_set_common_all_color_ranges(AVFilterContext *ctx)
Equivalent to ff_set_common_color_ranges(ctx, ff_all_color_ranges())
Definition: formats.c:857
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:612
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:666
VAAPIColourProperties::va_color_range
uint8_t va_color_range
Definition: vaapi_vpp.c:258
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
VAAPIVPPContext
Definition: vaapi_vpp.h:38
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:150
AVHWFramesConstraints::max_height
int max_height
Definition: hwcontext.h:467
vaapi_vpp_fill_colour_range
static void vaapi_vpp_fill_colour_range(VAAPIColourProperties *props)
Definition: vaapi_vpp.c:382
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:691
AVFrame::height
int height
Definition: frame.h:412
vaapi_vpp_fill_colour_properties
static void vaapi_vpp_fill_colour_properties(AVFilterContext *avctx, VAAPIColourProperties *props, VAProcColorStandardType *vacs, int nb_vacs)
Definition: vaapi_vpp.c:401
ff_vaapi_vpp_config_output
int ff_vaapi_vpp_config_output(AVFilterLink *outlink)
Definition: vaapi_vpp.c:99
AVHWFramesConstraints::min_height
int min_height
Definition: hwcontext.h:460
AVVAAPIFramesContext::nb_surfaces
int nb_surfaces
Definition: hwcontext_vaapi.h:102
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
AVCHROMA_LOC_CENTER
@ AVCHROMA_LOC_CENTER
MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0.
Definition: pixfmt.h:705
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
VAAPIColourProperties::va_color_standard
VAProcColorStandardType va_color_standard
Definition: vaapi_vpp.c:251
VAAPIColourProperties::va_chroma_sample_location
uint8_t va_chroma_sample_location
Definition: vaapi_vpp.c:257
VAAPIColourProperties::chroma_sample_location
enum AVChromaLocation chroma_sample_location
Definition: vaapi_vpp.c:261
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
vaapi_vpp_fill_colour_standard
static void vaapi_vpp_fill_colour_standard(VAAPIColourProperties *props, VAProcColorStandardType *vacs, int nb_vacs)
Definition: vaapi_vpp.c:281
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:187
desc
const char * desc
Definition: libsvtav1.c:73
AVFilterFormatsConfig::formats
AVFilterFormats * formats
List of supported formats (pixel or sample).
Definition: avfilter.h:510
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
AVVAAPIFramesContext
VAAPI-specific data associated with a frame pool.
Definition: hwcontext_vaapi.h:88
vaapi_vpp_render_single_pipeline_buffer
static int vaapi_vpp_render_single_pipeline_buffer(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, VABufferID *params_id)
Definition: vaapi_vpp.c:605
AVFrame::crop_top
size_t crop_top
Definition: frame.h:717
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
VAAPIColourProperties::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: vaapi_vpp.c:254
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
VAAPI_VPP_BACKGROUND_BLACK
#define VAAPI_VPP_BACKGROUND_BLACK
Definition: vaapi_vpp.h:36
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:648
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3317
AVCHROMA_LOC_BOTTOMLEFT
@ AVCHROMA_LOC_BOTTOMLEFT
Definition: pixfmt.h:708
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:2882
ff_filter_init_hw_frames
int ff_filter_init_hw_frames(AVFilterContext *avctx, AVFilterLink *link, int default_pool_size)
Perform any additional setup required for hardware frames.
Definition: avfilter.c:1616
VAAPIColourProperties
Definition: vaapi_vpp.c:250
ff_vaapi_vpp_init_params
int ff_vaapi_vpp_init_params(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, const AVFrame *input_frame, AVFrame *output_frame)
Definition: vaapi_vpp.c:528
AVFilterContext::outputs
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:419