FFmpeg
vaapi_vpp.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <string.h>
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/pixdesc.h"
23 #include "formats.h"
24 #include "internal.h"
25 #include "vaapi_vpp.h"
26 
28 {
29  enum AVPixelFormat pix_fmts[] = {
31  };
32  int err;
33 
34  if ((err = ff_formats_ref(ff_make_format_list(pix_fmts),
35  &avctx->inputs[0]->out_formats)) < 0)
36  return err;
37  if ((err = ff_formats_ref(ff_make_format_list(pix_fmts),
38  &avctx->outputs[0]->in_formats)) < 0)
39  return err;
40 
41  return 0;
42 }
43 
45 {
46  VAAPIVPPContext *ctx = avctx->priv;
47  int i;
48  for (i = 0; i < ctx->nb_filter_buffers; i++) {
49  if (ctx->filter_buffers[i] != VA_INVALID_ID) {
50  vaDestroyBuffer(ctx->hwctx->display, ctx->filter_buffers[i]);
51  ctx->filter_buffers[i] = VA_INVALID_ID;
52  }
53  }
54  ctx->nb_filter_buffers = 0;
55 
56  if (ctx->va_context != VA_INVALID_ID) {
57  vaDestroyContext(ctx->hwctx->display, ctx->va_context);
58  ctx->va_context = VA_INVALID_ID;
59  }
60 
61  if (ctx->va_config != VA_INVALID_ID) {
62  vaDestroyConfig(ctx->hwctx->display, ctx->va_config);
63  ctx->va_config = VA_INVALID_ID;
64  }
65 
67  ctx->hwctx = NULL;
68 }
69 
71 {
72  AVFilterContext *avctx = inlink->dst;
73  VAAPIVPPContext *ctx = avctx->priv;
74 
75  if (ctx->pipeline_uninit)
76  ctx->pipeline_uninit(avctx);
77 
78  if (!inlink->hw_frames_ctx) {
79  av_log(avctx, AV_LOG_ERROR, "A hardware frames reference is "
80  "required to associate the processing device.\n");
81  return AVERROR(EINVAL);
82  }
83 
85  if (!ctx->input_frames_ref) {
86  av_log(avctx, AV_LOG_ERROR, "A input frames reference create "
87  "failed.\n");
88  return AVERROR(ENOMEM);
89  }
91 
92  return 0;
93 }
94 
96 {
97  AVFilterContext *avctx = outlink->src;
98  VAAPIVPPContext *ctx = avctx->priv;
99  AVVAAPIHWConfig *hwconfig = NULL;
100  AVHWFramesConstraints *constraints = NULL;
101  AVHWFramesContext *output_frames;
102  AVVAAPIFramesContext *va_frames;
103  VAStatus vas;
104  int err, i;
105 
106  if (ctx->pipeline_uninit)
107  ctx->pipeline_uninit(avctx);
108 
109  if (!ctx->output_width)
110  ctx->output_width = avctx->inputs[0]->w;
111  if (!ctx->output_height)
112  ctx->output_height = avctx->inputs[0]->h;
113 
114  av_assert0(ctx->input_frames);
116  if (!ctx->device_ref) {
117  av_log(avctx, AV_LOG_ERROR, "A device reference create "
118  "failed.\n");
119  return AVERROR(ENOMEM);
120  }
121  ctx->hwctx = ((AVHWDeviceContext*)ctx->device_ref->data)->hwctx;
122 
123  av_assert0(ctx->va_config == VA_INVALID_ID);
124  vas = vaCreateConfig(ctx->hwctx->display, VAProfileNone,
125  VAEntrypointVideoProc, NULL, 0, &ctx->va_config);
126  if (vas != VA_STATUS_SUCCESS) {
127  av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline "
128  "config: %d (%s).\n", vas, vaErrorStr(vas));
129  err = AVERROR(EIO);
130  goto fail;
131  }
132 
133  hwconfig = av_hwdevice_hwconfig_alloc(ctx->device_ref);
134  if (!hwconfig) {
135  err = AVERROR(ENOMEM);
136  goto fail;
137  }
138  hwconfig->config_id = ctx->va_config;
139 
141  hwconfig);
142  if (!constraints) {
143  err = AVERROR(ENOMEM);
144  goto fail;
145  }
146 
147  if (ctx->output_format == AV_PIX_FMT_NONE)
148  ctx->output_format = ctx->input_frames->sw_format;
149  if (constraints->valid_sw_formats) {
150  for (i = 0; constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) {
151  if (ctx->output_format == constraints->valid_sw_formats[i])
152  break;
153  }
154  if (constraints->valid_sw_formats[i] == AV_PIX_FMT_NONE) {
155  av_log(avctx, AV_LOG_ERROR, "Hardware does not support output "
156  "format %s.\n", av_get_pix_fmt_name(ctx->output_format));
157  err = AVERROR(EINVAL);
158  goto fail;
159  }
160  }
161 
162  if (ctx->output_width < constraints->min_width ||
163  ctx->output_height < constraints->min_height ||
164  ctx->output_width > constraints->max_width ||
165  ctx->output_height > constraints->max_height) {
166  av_log(avctx, AV_LOG_ERROR, "Hardware does not support scaling to "
167  "size %dx%d (constraints: width %d-%d height %d-%d).\n",
168  ctx->output_width, ctx->output_height,
169  constraints->min_width, constraints->max_width,
170  constraints->min_height, constraints->max_height);
171  err = AVERROR(EINVAL);
172  goto fail;
173  }
174 
176  if (!outlink->hw_frames_ctx) {
177  av_log(avctx, AV_LOG_ERROR, "Failed to create HW frame context "
178  "for output.\n");
179  err = AVERROR(ENOMEM);
180  goto fail;
181  }
182 
183  output_frames = (AVHWFramesContext*)outlink->hw_frames_ctx->data;
184 
185  output_frames->format = AV_PIX_FMT_VAAPI;
186  output_frames->sw_format = ctx->output_format;
187  output_frames->width = ctx->output_width;
188  output_frames->height = ctx->output_height;
189 
190  output_frames->initial_pool_size = 4;
191 
192  err = ff_filter_init_hw_frames(avctx, outlink, 10);
193  if (err < 0)
194  goto fail;
195 
196  err = av_hwframe_ctx_init(outlink->hw_frames_ctx);
197  if (err < 0) {
198  av_log(avctx, AV_LOG_ERROR, "Failed to initialise VAAPI frame "
199  "context for output: %d\n", err);
200  goto fail;
201  }
202 
203  va_frames = output_frames->hwctx;
204 
205  av_assert0(ctx->va_context == VA_INVALID_ID);
206  vas = vaCreateContext(ctx->hwctx->display, ctx->va_config,
207  ctx->output_width, ctx->output_height,
208  VA_PROGRESSIVE,
209  va_frames->surface_ids, va_frames->nb_surfaces,
210  &ctx->va_context);
211  if (vas != VA_STATUS_SUCCESS) {
212  av_log(avctx, AV_LOG_ERROR, "Failed to create processing pipeline "
213  "context: %d (%s).\n", vas, vaErrorStr(vas));
214  return AVERROR(EIO);
215  }
216 
217  outlink->w = ctx->output_width;
218  outlink->h = ctx->output_height;
219 
220  if (ctx->build_filter_params) {
221  err = ctx->build_filter_params(avctx);
222  if (err < 0)
223  goto fail;
224  }
225 
226  av_freep(&hwconfig);
227  av_hwframe_constraints_free(&constraints);
228  return 0;
229 
230 fail:
231  av_buffer_unref(&outlink->hw_frames_ctx);
232  av_freep(&hwconfig);
233  av_hwframe_constraints_free(&constraints);
234  return err;
235 }
236 
237 typedef struct VAAPIColourProperties {
238  VAProcColorStandardType va_color_standard;
239 
243 
246 
250 
252  { VAProcColorStandardBT601, 5, 6, 5 },
253  { VAProcColorStandardBT601, 6, 6, 6 },
254  { VAProcColorStandardBT709, 1, 1, 1 },
255  { VAProcColorStandardBT470M, 4, 4, 4 },
256  { VAProcColorStandardBT470BG, 5, 5, 5 },
257  { VAProcColorStandardSMPTE170M, 6, 6, 6 },
258  { VAProcColorStandardSMPTE240M, 7, 7, 7 },
259  { VAProcColorStandardGenericFilm, 8, 1, 1 },
260 #if VA_CHECK_VERSION(1, 1, 0)
261  { VAProcColorStandardSRGB, 1, 13, 0 },
262  { VAProcColorStandardXVYCC601, 1, 11, 5 },
263  { VAProcColorStandardXVYCC709, 1, 11, 1 },
264  { VAProcColorStandardBT2020, 9, 14, 9 },
265 #endif
266 };
267 
269  VAProcColorStandardType *vacs,
270  int nb_vacs)
271 {
272  const VAAPIColourProperties *t;
273  int i, j, score, best_score, worst_score;
274  VAProcColorStandardType best_standard;
275 
276 #if VA_CHECK_VERSION(1, 3, 0)
277  // If the driver supports explicit use of the standard values then just
278  // use them and avoid doing any mapping. (The driver may not support
279  // some particular code point, but it still has enough information to
280  // make a better fallback choice than we do in that case.)
281  for (i = 0; i < nb_vacs; i++) {
282  if (vacs[i] == VAProcColorStandardExplicit) {
283  props->va_color_standard = VAProcColorStandardExplicit;
284  return;
285  }
286  }
287 #endif
288 
289  // Give scores to the possible options and choose the lowest one.
290  // An exact match will score zero and therefore always be chosen, as
291  // will a partial match where all unmatched elements are explicitly
292  // unspecified. If no options match at all then just pass "none" to
293  // the driver and let it make its own choice.
294  best_standard = VAProcColorStandardNone;
295  best_score = -1;
296  worst_score = 4 * (props->colorspace != AVCOL_SPC_UNSPECIFIED &&
297  props->colorspace != AVCOL_SPC_RGB) +
298  2 * (props->color_trc != AVCOL_TRC_UNSPECIFIED) +
300 
301  if (worst_score == 0) {
302  // No properties are specified, so we aren't going to be able to
303  // make a useful choice.
304  props->va_color_standard = VAProcColorStandardNone;
305  return;
306  }
307 
308  for (i = 0; i < nb_vacs; i++) {
309  for (j = 0; j < FF_ARRAY_ELEMS(vaapi_colour_standard_map); j++) {
310  t = &vaapi_colour_standard_map[j];
311  if (t->va_color_standard != vacs[i])
312  continue;
313 
314  score = 0;
315  if (props->colorspace != AVCOL_SPC_UNSPECIFIED &&
316  props->colorspace != AVCOL_SPC_RGB)
317  score += 4 * (props->colorspace != t->colorspace);
318  if (props->color_trc != AVCOL_TRC_UNSPECIFIED)
319  score += 2 * (props->color_trc != t->color_trc);
321  score += (props->color_primaries != t->color_primaries);
322 
323  // Only include choices which matched something.
324  if (score < worst_score &&
325  (best_score == -1 || score < best_score)) {
326  best_score = score;
327  best_standard = t->va_color_standard;
328  }
329  }
330  }
331  props->va_color_standard = best_standard;
332 }
333 
335 {
336 #if VA_CHECK_VERSION(1, 1, 0)
337  static const struct {
338  enum AVChromaLocation av;
339  uint8_t va;
340  } csl_map[] = {
341  { AVCHROMA_LOC_UNSPECIFIED, VA_CHROMA_SITING_UNKNOWN },
342  { AVCHROMA_LOC_LEFT, VA_CHROMA_SITING_VERTICAL_CENTER |
343  VA_CHROMA_SITING_HORIZONTAL_LEFT },
344  { AVCHROMA_LOC_CENTER, VA_CHROMA_SITING_VERTICAL_CENTER |
345  VA_CHROMA_SITING_HORIZONTAL_CENTER },
346  { AVCHROMA_LOC_TOPLEFT, VA_CHROMA_SITING_VERTICAL_TOP |
347  VA_CHROMA_SITING_HORIZONTAL_LEFT },
348  { AVCHROMA_LOC_TOP, VA_CHROMA_SITING_VERTICAL_TOP |
349  VA_CHROMA_SITING_HORIZONTAL_CENTER },
350  { AVCHROMA_LOC_BOTTOMLEFT, VA_CHROMA_SITING_VERTICAL_BOTTOM |
351  VA_CHROMA_SITING_HORIZONTAL_LEFT },
352  { AVCHROMA_LOC_BOTTOM, VA_CHROMA_SITING_VERTICAL_BOTTOM |
353  VA_CHROMA_SITING_HORIZONTAL_CENTER },
354  };
355  int i;
356 
357  for (i = 0; i < FF_ARRAY_ELEMS(csl_map); i++) {
358  if (props->chroma_sample_location == csl_map[i].av) {
359  props->va_chroma_sample_location = csl_map[i].va;
360  return;
361  }
362  }
363  props->va_chroma_sample_location = VA_CHROMA_SITING_UNKNOWN;
364 #else
365  props->va_chroma_sample_location = 0;
366 #endif
367 }
368 
370 {
371 #if VA_CHECK_VERSION(1, 1, 0)
372  switch (props->color_range) {
373  case AVCOL_RANGE_MPEG:
374  props->va_color_range = VA_SOURCE_RANGE_REDUCED;
375  break;
376  case AVCOL_RANGE_JPEG:
377  props->va_color_range = VA_SOURCE_RANGE_FULL;
378  break;
380  default:
381  props->va_color_range = VA_SOURCE_RANGE_UNKNOWN;
382  }
383 #else
384  props->va_color_range = 0;
385 #endif
386 }
387 
389  VAAPIColourProperties *props,
390  VAProcColorStandardType *vacs,
391  int nb_vacs)
392 {
393  vaapi_vpp_fill_colour_standard(props, vacs, nb_vacs);
396 
397  av_log(avctx, AV_LOG_DEBUG, "Mapped colour properties %s %s/%s/%s %s "
398  "to VA standard %d chroma siting %#x range %#x.\n",
404  props->va_color_standard,
406 }
407 
409 {
410  const AVHWFramesContext *hwfc;
411  const AVPixFmtDescriptor *desc;
412  av_assert0(frame->format == AV_PIX_FMT_VAAPI &&
413  frame->hw_frames_ctx);
414  hwfc = (const AVHWFramesContext*)frame->hw_frames_ctx->data;
415  desc = av_pix_fmt_desc_get(hwfc->sw_format);
416  av_assert0(desc);
417  return !!(desc->flags & AV_PIX_FMT_FLAG_RGB);
418 }
419 
421  VAProcPipelineParameterBuffer *params,
422  const AVFrame *input_frame,
424 {
425  VAAPIVPPContext *ctx = avctx->priv;
426  VAAPIColourProperties input_props, output_props;
427  VAProcPipelineCaps caps;
428  VAStatus vas;
429 
430  vas = vaQueryVideoProcPipelineCaps(ctx->hwctx->display, ctx->va_context,
432  &caps);
433  if (vas != VA_STATUS_SUCCESS) {
434  av_log(avctx, AV_LOG_ERROR, "Failed to query capabilities for "
435  "colour standard support: %d (%s).\n", vas, vaErrorStr(vas));
436  return AVERROR_EXTERNAL;
437  }
438 
439  input_props = (VAAPIColourProperties) {
440  .colorspace = vaapi_vpp_frame_is_rgb(input_frame)
441  ? AVCOL_SPC_RGB : input_frame->colorspace,
442  .color_primaries = input_frame->color_primaries,
443  .color_trc = input_frame->color_trc,
444  .color_range = input_frame->color_range,
445  .chroma_sample_location = input_frame->chroma_location,
446  };
447 
448  vaapi_vpp_fill_colour_properties(avctx, &input_props,
449  caps.input_color_standards,
450  caps.num_input_color_standards);
451 
452  output_props = (VAAPIColourProperties) {
453  .colorspace = vaapi_vpp_frame_is_rgb(output_frame)
454  ? AVCOL_SPC_RGB : output_frame->colorspace,
455  .color_primaries = output_frame->color_primaries,
456  .color_trc = output_frame->color_trc,
457  .color_range = output_frame->color_range,
458  .chroma_sample_location = output_frame->chroma_location,
459  };
460  vaapi_vpp_fill_colour_properties(avctx, &output_props,
461  caps.output_color_standards,
462  caps.num_output_color_standards);
463 
464  // If the properties weren't filled completely in the output frame and
465  // we chose a fixed standard then fill the known values in here.
466 #if VA_CHECK_VERSION(1, 3, 0)
467  if (output_props.va_color_standard != VAProcColorStandardExplicit)
468 #endif
469  {
470  const VAAPIColourProperties *output_standard = NULL;
471  int i;
472 
473  for (i = 0; i < FF_ARRAY_ELEMS(vaapi_colour_standard_map); i++) {
474  if (output_props.va_color_standard ==
475  vaapi_colour_standard_map[i].va_color_standard) {
476  output_standard = &vaapi_colour_standard_map[i];
477  break;
478  }
479  }
480  if (output_standard) {
481  output_frame->colorspace = vaapi_vpp_frame_is_rgb(output_frame)
482  ? AVCOL_SPC_RGB : output_standard->colorspace;
483  output_frame->color_primaries = output_standard->color_primaries;
484  output_frame->color_trc = output_standard->color_trc;
485  }
486  }
487 
488  params->surface_color_standard = input_props.va_color_standard;
489  params->output_color_standard = output_props.va_color_standard;
490 
491 #if VA_CHECK_VERSION(1, 1, 0)
492  params->input_color_properties = (VAProcColorProperties) {
493  .chroma_sample_location = input_props.va_chroma_sample_location,
494  .color_range = input_props.va_color_range,
495 #if VA_CHECK_VERSION(1, 3, 0)
496  .colour_primaries = input_props.color_primaries,
497  .transfer_characteristics = input_props.color_trc,
498  .matrix_coefficients = input_props.colorspace,
499 #endif
500  };
501  params->output_color_properties = (VAProcColorProperties) {
502  .chroma_sample_location = output_props.va_chroma_sample_location,
503  .color_range = output_props.va_color_range,
504 #if VA_CHECK_VERSION(1, 3, 0)
505  .colour_primaries = output_props.color_primaries,
506  .transfer_characteristics = output_props.color_trc,
507  .matrix_coefficients = output_props.colorspace,
508 #endif
509  };
510 #endif
511 
512  return 0;
513 }
514 
516  VAProcPipelineParameterBuffer *params,
517  const AVFrame *input_frame,
519 {
520  VAAPIVPPContext *ctx = avctx->priv;
521  VASurfaceID input_surface;
522  int err;
523 
524  ctx->input_region = (VARectangle) {
525  .x = input_frame->crop_left,
526  .y = input_frame->crop_top,
527  .width = input_frame->width -
528  (input_frame->crop_left + input_frame->crop_right),
529  .height = input_frame->height -
530  (input_frame->crop_top + input_frame->crop_bottom),
531  };
532  output_frame->crop_top = 0;
533  output_frame->crop_bottom = 0;
534  output_frame->crop_left = 0;
535  output_frame->crop_right = 0;
536 
537  input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3],
538 
539  *params = (VAProcPipelineParameterBuffer) {
540  .surface = input_surface,
541  .surface_region = &ctx->input_region,
542  .output_region = NULL,
543  .output_background_color = VAAPI_VPP_BACKGROUND_BLACK,
544  .pipeline_flags = 0,
545  .filter_flags = VA_FRAME_PICTURE,
546 
547  // Filter and reference data filled by the filter itself.
548 
549 #if VA_CHECK_VERSION(1, 1, 0)
550  .rotation_state = VA_ROTATION_NONE,
551  .mirror_state = VA_MIRROR_NONE,
552 #endif
553  };
554 
555  err = vaapi_vpp_colour_properties(avctx, params,
556  input_frame, output_frame);
557  if (err < 0)
558  return err;
559 
560  return 0;
561 }
562 
564  int type,
565  const void *data,
566  size_t size,
567  int count)
568 {
569  VAStatus vas;
570  VABufferID buffer;
571  VAAPIVPPContext *ctx = avctx->priv;
572 
573  av_assert0(ctx->nb_filter_buffers + 1 <= VAProcFilterCount);
574 
575  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
576  type, size, count, (void*)data, &buffer);
577  if (vas != VA_STATUS_SUCCESS) {
578  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter "
579  "buffer (type %d): %d (%s).\n",
580  type, vas, vaErrorStr(vas));
581  return AVERROR(EIO);
582  }
583 
584  ctx->filter_buffers[ctx->nb_filter_buffers++] = buffer;
585 
586  av_log(avctx, AV_LOG_DEBUG, "Param buffer (type %d, %zu bytes, count %d) "
587  "is %#x.\n", type, size, count, buffer);
588  return 0;
589 }
590 
591 
593  VAProcPipelineParameterBuffer *params,
595 {
596  VAAPIVPPContext *ctx = avctx->priv;
597  VASurfaceID output_surface;
598  VABufferID params_id;
599  VAStatus vas;
600  int err;
601 
602  output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];
603 
604  vas = vaBeginPicture(ctx->hwctx->display,
605  ctx->va_context, output_surface);
606  if (vas != VA_STATUS_SUCCESS) {
607  av_log(avctx, AV_LOG_ERROR, "Failed to attach new picture: "
608  "%d (%s).\n", vas, vaErrorStr(vas));
609  err = AVERROR(EIO);
610  goto fail;
611  }
612 
613  vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,
614  VAProcPipelineParameterBufferType,
615  sizeof(*params), 1, params, &params_id);
616  if (vas != VA_STATUS_SUCCESS) {
617  av_log(avctx, AV_LOG_ERROR, "Failed to create parameter buffer: "
618  "%d (%s).\n", vas, vaErrorStr(vas));
619  err = AVERROR(EIO);
620  goto fail_after_begin;
621  }
622  av_log(avctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n",
623  params_id);
624 
625  vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,
626  &params_id, 1);
627  if (vas != VA_STATUS_SUCCESS) {
628  av_log(avctx, AV_LOG_ERROR, "Failed to render parameter buffer: "
629  "%d (%s).\n", vas, vaErrorStr(vas));
630  err = AVERROR(EIO);
631  goto fail_after_begin;
632  }
633 
634  vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);
635  if (vas != VA_STATUS_SUCCESS) {
636  av_log(avctx, AV_LOG_ERROR, "Failed to start picture processing: "
637  "%d (%s).\n", vas, vaErrorStr(vas));
638  err = AVERROR(EIO);
639  goto fail_after_render;
640  }
641 
642  if (CONFIG_VAAPI_1 || ctx->hwctx->driver_quirks &
644  vas = vaDestroyBuffer(ctx->hwctx->display, params_id);
645  if (vas != VA_STATUS_SUCCESS) {
646  av_log(avctx, AV_LOG_ERROR, "Failed to free parameter buffer: "
647  "%d (%s).\n", vas, vaErrorStr(vas));
648  // And ignore.
649  }
650  }
651 
652  return 0;
653 
654  // We want to make sure that if vaBeginPicture has been called, we also
655  // call vaRenderPicture and vaEndPicture. These calls may well fail or
656  // do something else nasty, but once we're in this failure case there
657  // isn't much else we can do.
658 fail_after_begin:
659  vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_id, 1);
660 fail_after_render:
661  vaEndPicture(ctx->hwctx->display, ctx->va_context);
662 fail:
663  return err;
664 }
665 
667 {
668  int i;
669  VAAPIVPPContext *ctx = avctx->priv;
670 
671  ctx->va_config = VA_INVALID_ID;
672  ctx->va_context = VA_INVALID_ID;
673  ctx->valid_ids = 1;
674 
675  for (i = 0; i < VAProcFilterCount; i++)
676  ctx->filter_buffers[i] = VA_INVALID_ID;
677  ctx->nb_filter_buffers = 0;
678 }
679 
681 {
682  VAAPIVPPContext *ctx = avctx->priv;
683  if (ctx->valid_ids && ctx->pipeline_uninit)
684  ctx->pipeline_uninit(avctx);
685 
688 }
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
static int vaapi_vpp_colour_properties(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, const AVFrame *input_frame, AVFrame *output_frame)
Definition: vaapi_vpp.c:420
#define NULL
Definition: coverity.c:32
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
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:125
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
MPEG-2/4 4:2:0, H.264 default for 4:2:0.
Definition: pixfmt.h:544
VAAPI-specific data associated with a frame pool.
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
int ff_vaapi_vpp_config_input(AVFilterLink *inlink)
Definition: vaapi_vpp.c:70
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int ff_vaapi_vpp_config_output(AVFilterLink *outlink)
Definition: vaapi_vpp.c:95
const char * desc
Definition: nvenc.c:68
int nb_filter_buffers
Definition: vaapi_vpp.h:52
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:228
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
Definition: hwcontext.c:526
GLint GLenum type
Definition: opengl_enc.c:104
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:208
size_t crop_bottom
Definition: frame.h:656
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
Definition: pixfmt.h:498
int max_width
The maximum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:457
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:468
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:2915
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
Definition: hwcontext.c:562
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
Definition: frame.h:634
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t
enum AVColorRange color_range
Definition: vaapi_vpp.c:247
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:497
size_t crop_left
Definition: frame.h:657
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:2848
#define height
AVColorRange
MPEG vs JPEG YUV range.
Definition: pixfmt.h:520
ptrdiff_t size
Definition: opengl_enc.c:100
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:443
#define av_log(a,...)
const char * av_chroma_location_name(enum AVChromaLocation location)
Definition: pixdesc.c:2939
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
VAAPI hardware pipeline configuration details.
static void vaapi_vpp_fill_chroma_sample_location(VAAPIColourProperties *props)
Definition: vaapi_vpp.c:334
AVBufferRef * input_frames_ref
Definition: vaapi_vpp.h:43
#define AV_PIX_FMT_FLAG_RGB
The pixel format contains RGB-like data (as opposed to YUV/grayscale).
Definition: pixdesc.h:148
static void vaapi_vpp_fill_colour_properties(AVFilterContext *avctx, VAAPIColourProperties *props, VAProcColorStandardType *vacs, int nb_vacs)
Definition: vaapi_vpp.c:388
void * priv
private data for use by the filter
Definition: avfilter.h:353
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:539
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
GLenum GLint * params
Definition: opengl_enc.c:113
enum AVColorSpace colorspace
YUV colorspace type.
Definition: frame.h:550
simple assert() macros that are a bit more flexible than ISO C assert().
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:329
GLsizei count
Definition: opengl_enc.c:108
int ff_vaapi_vpp_make_param_buffers(AVFilterContext *avctx, int type, const void *data, size_t size, int count)
Definition: vaapi_vpp.c:563
#define fail()
Definition: checkasm.h:122
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:2867
enum AVColorSpace colorspace
Definition: vaapi_vpp.c:242
size_t crop_top
Definition: frame.h:655
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:198
enum AVChromaLocation chroma_sample_location
Definition: vaapi_vpp.c:248
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:439
void ff_vaapi_vpp_pipeline_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:44
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:546
AVFormatContext * ctx
Definition: movenc.c:48
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
enum AVColorPrimaries color_primaries
Definition: vaapi_vpp.c:240
#define FF_ARRAY_ELEMS(a)
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:523
VADisplay display
The VADisplay handle, to be filled by the user.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:368
int min_width
The minimum size of frames in this hw_frames_ctx.
Definition: hwcontext.h:450
enum AVColorTransferCharacteristic color_trc
Definition: vaapi_vpp.c:241
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
Definition: hwcontext.h:432
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
static int vaapi_vpp_frame_is_rgb(const AVFrame *frame)
Definition: vaapi_vpp.c:408
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:537
static const VAAPIColourProperties vaapi_colour_standard_map[]
Definition: vaapi_vpp.c:251
uint8_t * data
The data buffer.
Definition: buffer.h:89
VABufferID filter_buffers[VAProcFilterCount]
Definition: vaapi_vpp.h:51
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:161
unsigned int driver_quirks
Driver quirks to apply - this is filled by av_hwdevice_ctx_init(), with reference to a table of known...
size_t crop_right
Definition: frame.h:658
static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp)
Definition: h264dec.c:837
VAConfigID va_config
Definition: vaapi_vpp.h:40
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
enum AVChromaLocation chroma_location
Definition: frame.h:552
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
VAContextID va_context
Definition: vaapi_vpp.h:41
enum AVPixelFormat output_format
Definition: vaapi_vpp.h:47
VARectangle input_region
Definition: vaapi_vpp.h:45
AVVAAPIDeviceContext * hwctx
Definition: vaapi_vpp.h:36
uint8_t va_chroma_sample_location
Definition: vaapi_vpp.c:244
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:140
int ff_vaapi_vpp_render_picture(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, AVFrame *output_frame)
Definition: vaapi_vpp.c:592
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
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:522
static void vaapi_vpp_fill_colour_standard(VAAPIColourProperties *props, VAProcColorStandardType *vacs, int nb_vacs)
Definition: vaapi_vpp.c:268
int ff_vaapi_vpp_query_formats(AVFilterContext *avctx)
Definition: vaapi_vpp.c:27
void ff_vaapi_vpp_ctx_init(AVFilterContext *avctx)
Definition: vaapi_vpp.c:666
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:2891
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:243
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
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:1653
static void vaapi_vpp_fill_colour_range(VAAPIColourProperties *props)
Definition: vaapi_vpp.c:369
AVHWFramesContext * input_frames
Definition: vaapi_vpp.h:44
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:444
#define VAAPI_VPP_BACKGROUND_BLACK
Definition: vaapi_vpp.h:31
enum AVColorPrimaries color_primaries
Definition: frame.h:541
VAConfigID config_id
ID of a VAAPI pipeline configuration.
An instance of a filter.
Definition: avfilter.h:338
int height
Definition: frame.h:353
#define av_freep(p)
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
AVBufferRef * device_ref
Definition: vaapi_vpp.h:37
AVChromaLocation
Location of chroma samples.
Definition: pixfmt.h:542
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:543
MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0.
Definition: pixfmt.h:545
int ff_vaapi_vpp_init_params(AVFilterContext *avctx, VAProcPipelineParameterBuffer *params, const AVFrame *input_frame, AVFrame *output_frame)
Definition: vaapi_vpp.c:515
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:2438
int(* build_filter_params)(AVFilterContext *avctx)
Definition: vaapi_vpp.h:54
internal API functions
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
VAProcColorStandardType va_color_standard
Definition: vaapi_vpp.c:238
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:221
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
void(* pipeline_uninit)(AVFilterContext *avctx)
Definition: vaapi_vpp.h:56
void ff_vaapi_vpp_ctx_uninit(AVFilterContext *avctx)
Definition: vaapi_vpp.c:680
GLuint buffer
Definition: opengl_enc.c:101