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