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