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