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/mem.h"
23 #include "libavutil/pixdesc.h"
24 
25 #include "filters.h"
26 #include "formats.h"
27 #include "vaapi_vpp.h"
28 
30  AVFilterFormatsConfig **cfg_in,
31  AVFilterFormatsConfig **cfg_out)
32 {
33  static const enum AVPixelFormat pix_fmts[] = {
35  };
36  int err;
37 
38  err = ff_set_common_formats_from_list2(avctx, cfg_in, cfg_out, pix_fmts);
39  if (err < 0)
40  return err;
41 
42  return 0;
43 }
44 
46 {
47  VAAPIVPPContext *ctx = avctx->priv;
48  int i;
49  for (i = 0; i < ctx->nb_filter_buffers; i++) {
50  if (ctx->filter_buffers[i] != VA_INVALID_ID) {
51  vaDestroyBuffer(ctx->hwctx->display, ctx->filter_buffers[i]);
52  ctx->filter_buffers[i] = VA_INVALID_ID;
53  }
54  }
55  ctx->nb_filter_buffers = 0;
56 
57  if (ctx->va_context != VA_INVALID_ID) {
58  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
59  ctx->va_context = VA_INVALID_ID;
60  }
61 
62  if (ctx->va_config != VA_INVALID_ID) {
63  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
64  ctx->va_config = VA_INVALID_ID;
65  }
66 
67  av_buffer_unref(&ctx->device_ref);
68  ctx->hwctx = NULL;
69 }
70 
72 {
74  AVFilterContext *avctx = inlink->dst;
75  VAAPIVPPContext *ctx = avctx->priv;
76 
77  if (ctx->pipeline_uninit)
78  ctx->pipeline_uninit(avctx);
79 
80  if (!l->hw_frames_ctx) {
81  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
82  "required to associate the processing device.\n");
83  return AVERROR(EINVAL);
84  }
85 
86  ctx->input_frames_ref = av_buffer_ref(l->hw_frames_ctx);
87  if (!ctx->input_frames_ref) {
88  av_log(avctx, AV_LOG_ERROR, "A input frames reference create "
89  "failed.\n");
90  return AVERROR(ENOMEM);
91  }
92  ctx->input_frames = (AVHWFramesContext*)ctx->input_frames_ref->data;
93 
94  return 0;
95 }
96 
98 {
99  FilterLink *outl = ff_filter_link(outlink);
100  AVFilterContext *avctx = outlink->src;
101  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 (inl->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  outl->hw_frames_ctx = av_hwframe_ctx_alloc(ctx->device_ref);
192  if (!outl->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*)outl->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  if (CONFIG_VAAPI_1)
207  output_frames->initial_pool_size = 0;
208  else
209  output_frames->initial_pool_size = 4;
210 
211  err = ff_filter_init_hw_frames(avctx, outlink, 10);
212  if (err < 0)
213  goto fail;
214 
215  err = av_hwframe_ctx_init(outl->hw_frames_ctx);
216  if (err < 0) {
217  av_log(avctx, AV_LOG_ERROR, "Failed to initialise VAAPI frame "
218  "context for output: %d\n", err);
219  goto fail;
220  }
221 
222  va_frames = output_frames->hwctx;
223 
224  av_assert0(ctx->va_context == VA_INVALID_ID);
225  av_assert0(output_frames->initial_pool_size ||
226  (va_frames->surface_ids == NULL && va_frames->nb_surfaces == 0));
227  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
228  ctx->output_width, ctx->output_height,
229  VA_PROGRESSIVE,
230  va_frames->surface_ids, va_frames->nb_surfaces,
231  &ctx->va_context);
232  if (vas != VA_STATUS_SUCCESS) {
233  av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline "
234  "context: %d (%s).\n", vas, vaErrorStr(vas));
235  return AVERROR(EIO);
236  }
237 
238  if (ctx->build_filter_params) {
239  err = ctx->build_filter_params(avctx);
240  if (err < 0)
241  goto fail;
242  }
243 
244  av_freep(&hwconfig);
245  av_hwframe_constraints_free(&constraints);
246  return 0;
247 
248 fail:
250  av_freep(&hwconfig);
251  av_hwframe_constraints_free(&constraints);
252  return err;
253 }
254 
255 typedef struct VAAPIColourProperties {
256  VAProcColorStandardType va_color_standard;
257 
261 
263  uint8_t va_color_range;
264 
268 
270  { VAProcColorStandardBT601, 5, 6, 5 },
271  { VAProcColorStandardBT601, 6, 6, 6 },
272  { VAProcColorStandardBT709, 1, 1, 1 },
273  { VAProcColorStandardBT470M, 4, 4, 4 },
274  { VAProcColorStandardBT470BG, 5, 5, 5 },
275  { VAProcColorStandardSMPTE170M, 6, 6, 6 },
276  { VAProcColorStandardSMPTE240M, 7, 7, 7 },
277  { VAProcColorStandardGenericFilm, 8, 1, 1 },
278 #if VA_CHECK_VERSION(1, 1, 0)
279  { VAProcColorStandardSRGB, 1, 13, 0 },
280  { VAProcColorStandardXVYCC601, 1, 11, 5 },
281  { VAProcColorStandardXVYCC709, 1, 11, 1 },
282  { VAProcColorStandardBT2020, 9, 14, 9 },
283 #endif
284 };
285 
287  VAProcColorStandardType *vacs,
288  int nb_vacs)
289 {
290  const VAAPIColourProperties *t;
291  int i, j, score, best_score, worst_score;
292  VAProcColorStandardType best_standard;
293 
294 #if VA_CHECK_VERSION(1, 3, 0)
295  // If the driver supports explicit use of the standard values then just
296  // use them and avoid doing any mapping. (The driver may not support
297  // some particular code point, but it still has enough information to
298  // make a better fallback choice than we do in that case.)
299  for (i = 0; i < nb_vacs; i++) {
300  if (vacs[i] == VAProcColorStandardExplicit) {
301  props->va_color_standard = VAProcColorStandardExplicit;
302  return;
303  }
304  }
305 #endif
306 
307  // Give scores to the possible options and choose the lowest one.
308  // An exact match will score zero and therefore always be chosen, as
309  // will a partial match where all unmatched elements are explicitly
310  // unspecified. If no options match at all then just pass "none" to
311  // the driver and let it make its own choice.
312  best_standard = VAProcColorStandardNone;
313  best_score = -1;
314  worst_score = 4 * (props->colorspace != AVCOL_SPC_UNSPECIFIED &&
315  props->colorspace != AVCOL_SPC_RGB) +
316  2 * (props->color_trc != AVCOL_TRC_UNSPECIFIED) +
318 
319  if (worst_score == 0) {
320  // No properties are specified, so we aren't going to be able to
321  // make a useful choice.
322  props->va_color_standard = VAProcColorStandardNone;
323  return;
324  }
325 
326  for (i = 0; i < nb_vacs; i++) {
327  for (j = 0; j < FF_ARRAY_ELEMS(vaapi_colour_standard_map); j++) {
329  if (t->va_color_standard != vacs[i])
330  continue;
331 
332  score = 0;
333  if (props->colorspace != AVCOL_SPC_UNSPECIFIED &&
334  props->colorspace != AVCOL_SPC_RGB)
335  score += 4 * (props->colorspace != t->colorspace);
336  if (props->color_trc != AVCOL_TRC_UNSPECIFIED)
337  score += 2 * (props->color_trc != t->color_trc);
339  score += (props->color_primaries != t->color_primaries);
340 
341  // Only include choices which matched something.
342  if (score < worst_score &&
343  (best_score == -1 || score < best_score)) {
344  best_score = score;
345  best_standard = t->va_color_standard;
346  }
347  }
348  }
349  props->va_color_standard = best_standard;
350 }
351 
353 {
354 #if VA_CHECK_VERSION(1, 1, 0)
355  static const struct {
356  enum AVChromaLocation av;
357  uint8_t va;
358  } csl_map[] = {
359  { AVCHROMA_LOC_UNSPECIFIED, VA_CHROMA_SITING_UNKNOWN },
360  { AVCHROMA_LOC_LEFT, VA_CHROMA_SITING_VERTICAL_CENTER |
361  VA_CHROMA_SITING_HORIZONTAL_LEFT },
362  { AVCHROMA_LOC_CENTER, VA_CHROMA_SITING_VERTICAL_CENTER |
363  VA_CHROMA_SITING_HORIZONTAL_CENTER },
364  { AVCHROMA_LOC_TOPLEFT, VA_CHROMA_SITING_VERTICAL_TOP |
365  VA_CHROMA_SITING_HORIZONTAL_LEFT },
366  { AVCHROMA_LOC_TOP, VA_CHROMA_SITING_VERTICAL_TOP |
367  VA_CHROMA_SITING_HORIZONTAL_CENTER },
368  { AVCHROMA_LOC_BOTTOMLEFT, VA_CHROMA_SITING_VERTICAL_BOTTOM |
369  VA_CHROMA_SITING_HORIZONTAL_LEFT },
370  { AVCHROMA_LOC_BOTTOM, VA_CHROMA_SITING_VERTICAL_BOTTOM |
371  VA_CHROMA_SITING_HORIZONTAL_CENTER },
372  };
373  int i;
374 
375  for (i = 0; i < FF_ARRAY_ELEMS(csl_map); i++) {
376  if (props->chroma_sample_location == csl_map[i].av) {
377  props->va_chroma_sample_location = csl_map[i].va;
378  return;
379  }
380  }
381  props->va_chroma_sample_location = VA_CHROMA_SITING_UNKNOWN;
382 #else
383  props->va_chroma_sample_location = 0;
384 #endif
385 }
386 
388 {
389 #if VA_CHECK_VERSION(1, 1, 0)
390  switch (props->color_range) {
391  case AVCOL_RANGE_MPEG:
392  props->va_color_range = VA_SOURCE_RANGE_REDUCED;
393  break;
394  case AVCOL_RANGE_JPEG:
395  props->va_color_range = VA_SOURCE_RANGE_FULL;
396  break;
398  default:
399  props->va_color_range = VA_SOURCE_RANGE_UNKNOWN;
400  }
401 #else
402  props->va_color_range = 0;
403 #endif
404 }
405 
407  VAAPIColourProperties *props,
408  VAProcColorStandardType *vacs,
409  int nb_vacs)
410 {
411  vaapi_vpp_fill_colour_standard(props, vacs, nb_vacs);
414 
415  av_log(avctx, AV_LOG_DEBUG, "Mapped colour properties %s %s/%s/%s %s "
416  "to VA standard %d chroma siting %#x range %#x.\n",
422  props->va_color_standard,
424 }
425 
427 {
428  const AVHWFramesContext *hwfc;
429  const AVPixFmtDescriptor *desc;
430  av_assert0(frame->format == AV_PIX_FMT_VAAPI &&
431  frame->hw_frames_ctx);
432  hwfc = (const AVHWFramesContext*)frame->hw_frames_ctx->data;
434  av_assert0(desc);
435  return !!(desc->flags & AV_PIX_FMT_FLAG_RGB);
436 }
437 
439  VAProcPipelineParameterBuffer *params,
440  const AVFrame *input_frame,
442 {
443  VAAPIVPPContext *ctx = avctx->priv;
444  VAAPIColourProperties input_props, output_props;
445  VAProcPipelineCaps caps;
446  VAStatus vas;
447 
448  vas = vaQueryVideoProcPipelineCaps(ctx->hwctx->display, ctx->va_context,
449  ctx->filter_buffers, ctx->nb_filter_buffers,
450  &caps);
451  if (vas != VA_STATUS_SUCCESS) {
452  av_log(avctx, AV_LOG_ERROR, "Failed to query capabilities for "
453  "colour standard support: %d (%s).\n", vas, vaErrorStr(vas));
454  return AVERROR_EXTERNAL;
455  }
456 
457  input_props = (VAAPIColourProperties) {
458  .colorspace = vaapi_vpp_frame_is_rgb(input_frame)
459  ? AVCOL_SPC_RGB : input_frame->colorspace,
460  .color_primaries = input_frame->color_primaries,
461  .color_trc = input_frame->color_trc,
462  .color_range = input_frame->color_range,
463  .chroma_sample_location = input_frame->chroma_location,
464  };
465 
466  vaapi_vpp_fill_colour_properties(avctx, &input_props,
467  caps.input_color_standards,
468  caps.num_input_color_standards);
469 
470  output_props = (VAAPIColourProperties) {
472  ? AVCOL_SPC_RGB : output_frame->colorspace,
473  .color_primaries = output_frame->color_primaries,
474  .color_trc = output_frame->color_trc,
475  .color_range = output_frame->color_range,
476  .chroma_sample_location = output_frame->chroma_location,
477  };
478  vaapi_vpp_fill_colour_properties(avctx, &output_props,
479  caps.output_color_standards,
480  caps.num_output_color_standards);
481 
482  // If the properties weren't filled completely in the output frame and
483  // we chose a fixed standard then fill the known values in here.
484 #if VA_CHECK_VERSION(1, 3, 0)
485  if (output_props.va_color_standard != VAProcColorStandardExplicit)
486 #endif
487  {
488  const VAAPIColourProperties *output_standard = NULL;
489  int i;
490 
491  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_colour_standard_map); i++) {
492  if (output_props.va_color_standard ==
494  output_standard = &vaapi_colour_standard_map[i];
495  break;
496  }
497  }
498  if (output_standard) {
500  ? AVCOL_SPC_RGB : output_standard->colorspace;
501  output_frame->color_primaries = output_standard->color_primaries;
502  output_frame->color_trc = output_standard->color_trc;
503  }
504  }
505 
506  params->surface_color_standard = input_props.va_color_standard;
507  params->output_color_standard = output_props.va_color_standard;
508 
509 #if VA_CHECK_VERSION(1, 1, 0)
510  params->input_color_properties = (VAProcColorProperties) {
511  .chroma_sample_location = input_props.va_chroma_sample_location,
512  .color_range = input_props.va_color_range,
513 #if VA_CHECK_VERSION(1, 3, 0)
514  .colour_primaries = input_props.color_primaries,
515  .transfer_characteristics = input_props.color_trc,
516  .matrix_coefficients = input_props.colorspace,
517 #endif
518  };
519  params->output_color_properties = (VAProcColorProperties) {
520  .chroma_sample_location = output_props.va_chroma_sample_location,
521  .color_range = output_props.va_color_range,
522 #if VA_CHECK_VERSION(1, 3, 0)
523  .colour_primaries = output_props.color_primaries,
524  .transfer_characteristics = output_props.color_trc,
525  .matrix_coefficients = output_props.colorspace,
526 #endif
527  };
528 #endif
529 
530  return 0;
531 }
532 
534  VAProcPipelineParameterBuffer *params,
535  const AVFrame *input_frame,
537 {
538  VAAPIVPPContext *ctx = avctx->priv;
539  int err;
540 
541  ctx->input_region = (VARectangle) {
542  .x = input_frame->crop_left,
543  .y = input_frame->crop_top,
544  .width = input_frame->width -
545  (input_frame->crop_left + input_frame->crop_right),
546  .height = input_frame->height -
547  (input_frame->crop_top + input_frame->crop_bottom),
548  };
549  output_frame->crop_top = 0;
550  output_frame->crop_bottom = 0;
551  output_frame->crop_left = 0;
552  output_frame->crop_right = 0;
553 
554  *params = (VAProcPipelineParameterBuffer) {
555  .surface = ff_vaapi_vpp_get_surface_id(input_frame),
556  .surface_region = &ctx->input_region,
557  .output_region = NULL,
558  .output_background_color = VAAPI_VPP_BACKGROUND_BLACK,
559  .pipeline_flags = 0,
560  .filter_flags = VA_FRAME_PICTURE,
561 
562  // Filter and reference data filled by the filter itself.
563 
564 #if VA_CHECK_VERSION(1, 1, 0)
565  .rotation_state = VA_ROTATION_NONE,
566  .mirror_state = VA_MIRROR_NONE,
567 #endif
568  };
569 
570  err = vaapi_vpp_colour_properties(avctx, params,
571  input_frame, output_frame);
572  if (err < 0)
573  return err;
574 
575  av_log(avctx, AV_LOG_DEBUG, "Filter frame from surface %#x to %#x.\n",
576  ff_vaapi_vpp_get_surface_id(input_frame),
578 
579  return 0;
580 }
581 
583  int type,
584  const void *data,
585  size_t size,
586  int count)
587 {
588  VAStatus vas;
589  VABufferID buffer;
590  VAAPIVPPContext *ctx = avctx->priv;
591 
592  av_assert0(ctx->nb_filter_buffers + 1 <= VAProcFilterCount);
593 
594  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
595  type, size, count, (void*)data, &buffer);
596  if (vas != VA_STATUS_SUCCESS) {
597  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter "
598  "buffer (type %d): %d (%s).\n",
599  type, vas, vaErrorStr(vas));
600  return AVERROR(EIO);
601  }
602 
603  ctx->filter_buffers[ctx->nb_filter_buffers++] = buffer;
604 
605  av_log(avctx, AV_LOG_DEBUG, "Param buffer (type %d, %zu bytes, count %d) "
606  "is %#x.\n", type, size, count, buffer);
607  return 0;
608 }
609 
611  VAProcPipelineParameterBuffer *params,
612  VABufferID *params_id)
613 {
614  VAAPIVPPContext *ctx = avctx->priv;
615  VAStatus vas;
616 
617  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
618  VAProcPipelineParameterBufferType,
619  sizeof(*params), 1, params, params_id);
620  if (vas != VA_STATUS_SUCCESS) {
621  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
622  "%d (%s).\n", vas, vaErrorStr(vas));
623  *params_id = VA_INVALID_ID;
624 
625  return AVERROR(EIO);
626  }
627  av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n", *params_id);
628 
629  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, params_id, 1);
630  if (vas != VA_STATUS_SUCCESS) {
631  av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
632  "%d (%s).\n", vas, vaErrorStr(vas));
633  return AVERROR(EIO);
634  }
635 
636  return 0;
637 }
638 
640  VAProcPipelineParameterBuffer *params_list,
641  int cout,
643 {
644  VAAPIVPPContext *ctx = avctx->priv;
645  VABufferID *params_ids;
646  VAStatus vas;
647  int err;
648 
649  params_ids = (VABufferID *)av_malloc_array(cout, sizeof(VABufferID));
650  if (!params_ids)
651  return AVERROR(ENOMEM);
652 
653  for (int i = 0; i < cout; i++)
654  params_ids[i] = VA_INVALID_ID;
655 
656  vas = vaBeginPicture(ctx->hwctx->display,
658  if (vas != VA_STATUS_SUCCESS) {
659  av_log(avctx, AV_LOG_ERROR, "Failed to attach new picture: "
660  "%d (%s).\n", vas, vaErrorStr(vas));
661  err = AVERROR(EIO);
662  goto fail;
663  }
664 
665  for (int i = 0; i < cout; i++) {
666  err = vaapi_vpp_render_single_pipeline_buffer(avctx, &params_list[i], &params_ids[i]);
667  if (err)
668  goto fail_after_begin;
669  }
670 
671  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
672  if (vas != VA_STATUS_SUCCESS) {
673  av_log(avctx, AV_LOG_ERROR, "Failed to start picture processing: "
674  "%d (%s).\n", vas, vaErrorStr(vas));
675  err = AVERROR(EIO);
676  goto fail_after_render;
677  }
678 
679  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
681  for (int i = 0; i < cout && params_ids[i] != VA_INVALID_ID; i++) {
682  vas = vaDestroyBuffer(ctx->hwctx->display, params_ids[i]);
683  if (vas != VA_STATUS_SUCCESS) {
684  av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: "
685  "%d (%s).\n", vas, vaErrorStr(vas));
686  // And ignore.
687  }
688  }
689  }
690 
691  av_freep(&params_ids);
692  return 0;
693 
694  // We want to make sure that if vaBeginPicture has been called, we also
695  // call vaRenderPicture and vaEndPicture. These calls may well fail or
696  // do something else nasty, but once we're in this failure case there
697  // isn't much else we can do.
698 fail_after_begin:
699  vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_ids[0], 1);
700 fail_after_render:
701  vaEndPicture(ctx->hwctx->display, ctx->va_context);
702 fail:
703  av_freep(&params_ids);
704  return err;
705 }
706 
708  VAProcPipelineParameterBuffer *params,
710 {
711  return ff_vaapi_vpp_render_pictures(avctx, params, 1, output_frame);
712 }
713 
715 {
716  int i;
717  VAAPIVPPContext *ctx = avctx->priv;
718 
719  ctx->va_config = VA_INVALID_ID;
720  ctx->va_context = VA_INVALID_ID;
721  ctx->valid_ids = 1;
722 
723  for (i = 0; i < VAProcFilterCount; i++)
724  ctx->filter_buffers[i] = VA_INVALID_ID;
725  ctx->nb_filter_buffers = 0;
726 }
727 
729 {
730  VAAPIVPPContext *ctx = avctx->priv;
731  if (ctx->valid_ids && ctx->pipeline_uninit)
732  ctx->pipeline_uninit(avctx);
733 
734  av_buffer_unref(&ctx->input_frames_ref);
735  av_buffer_unref(&ctx->device_ref);
736 }
AVFrame::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:672
ff_vaapi_vpp_pipeline_uninit
void ff_vaapi_vpp_pipeline_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:45
ff_vaapi_vpp_ctx_init
void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
Definition: vaapi_vpp.c:714
vaapi_vpp_frame_is_rgb
static int vaapi_vpp_frame_is_rgb(const AVFrame *frame)
Definition: vaapi_vpp.c:426
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:668
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
AVVAAPIHWConfig
VAAPI hardware pipeline configuration details.
Definition: hwcontext_vaapi.h:110
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:611
ff_vaapi_vpp_render_picture
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, AVFrame *output_frame)
Definition: vaapi_vpp.c:707
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:3170
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AVCHROMA_LOC_BOTTOM
@ AVCHROMA_LOC_BOTTOM
Definition: pixfmt.h:743
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:670
AVFrame::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:679
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:389
pixdesc.h
AVFrame::width
int width
Definition: frame.h:461
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:717
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:614
data
const char data[16]
Definition: mxf.c:149
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:639
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
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:641
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:586
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:3567
ff_vaapi_vpp_query_formats
int ff_vaapi_vpp_query_formats(const AVFilterContext *avctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vaapi_vpp.c:29
VAAPIColourProperties::color_primaries
enum AVColorPrimaries color_primaries
Definition: vaapi_vpp.c:258
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:681
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:3546
AVFilterContext::priv
void * priv
private data for use by the filter
Definition: avfilter.h:472
fail
#define fail()
Definition: checkasm.h:188
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:209
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:260
AVCHROMA_LOC_TOP
@ AVCHROMA_LOC_TOP
Definition: pixfmt.h:741
VAAPIColourProperties::color_range
enum AVColorRange color_range
Definition: vaapi_vpp.c:265
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
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
filters.h
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:230
ctx
AVFormatContext * ctx
Definition: movenc.c:49
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:582
vaapi_vpp_fill_chroma_sample_location
static void vaapi_vpp_fill_chroma_sample_location(VAAPIColourProperties *props)
Definition: vaapi_vpp.c:352
AVFrame::crop_right
size_t crop_right
Definition: frame.h:769
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:589
if
if(ret)
Definition: filter_design.txt:179
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:3486
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:738
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:438
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:740
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:465
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3504
ff_vaapi_vpp_config_input
int ff_vaapi_vpp_config_input(AVFilterLink *inlink)
Definition: vaapi_vpp.c:71
vaapi_colour_standard_map
static const VAAPIColourProperties vaapi_colour_standard_map[]
Definition: vaapi_vpp.c:269
ff_vaapi_vpp_ctx_uninit
void ff_vaapi_vpp_ctx_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:728
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:683
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:111
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
AVFrame::crop_bottom
size_t crop_bottom
Definition: frame.h:767
AVFrame::crop_left
size_t crop_left
Definition: frame.h:768
vaapi_vpp.h
height
#define height
Definition: dsp.h:85
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:737
output_frame
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:877
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
AVChromaLocation
AVChromaLocation
Location of chroma samples.
Definition: pixfmt.h:736
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AVColorSpace
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:640
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:643
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:700
VAAPIColourProperties::va_color_range
uint8_t va_color_range
Definition: vaapi_vpp.c:263
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
VAAPIVPPContext
Definition: vaapi_vpp.h:38
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: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:387
AVFrame::height
int height
Definition: frame.h:461
ff_set_common_formats_from_list2
int ff_set_common_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *fmts)
Definition: formats.c:1016
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:406
ff_vaapi_vpp_config_output
int ff_vaapi_vpp_config_output(AVFilterLink *outlink)
Definition: vaapi_vpp.c:97
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:739
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
VAAPIColourProperties::va_color_standard
VAProcColorStandardType va_color_standard
Definition: vaapi_vpp.c:256
VAAPIColourProperties::va_chroma_sample_location
uint8_t va_chroma_sample_location
Definition: vaapi_vpp.c:262
VAAPIColourProperties::chroma_sample_location
enum AVChromaLocation chroma_sample_location
Definition: vaapi_vpp.c:266
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
vaapi_vpp_fill_colour_standard
static void vaapi_vpp_fill_colour_standard(VAAPIColourProperties *props, VAProcColorStandardType *vacs, int nb_vacs)
Definition: vaapi_vpp.c:286
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:79
mem.h
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:610
AVFrame::crop_top
size_t crop_top
Definition: frame.h:766
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
VAAPIColourProperties::color_trc
enum AVColorTransferCharacteristic color_trc
Definition: vaapi_vpp.c:259
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:682
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3525
AVCHROMA_LOC_BOTTOMLEFT
@ AVCHROMA_LOC_BOTTOMLEFT
Definition: pixfmt.h:742
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:3090
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:1639
VAAPIColourProperties
Definition: vaapi_vpp.c:255
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:533