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