FFmpeg
vf_vpp_qsv.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 /**
20  ** @file
21  ** Hardware accelerated common filters based on Intel Quick Sync Video VPP
22  **/
23 
24 #include <float.h>
25 
26 #include "libavutil/opt.h"
27 #include "libavutil/eval.h"
28 #include "libavutil/avassert.h"
29 #include "libavutil/pixdesc.h"
30 #include "libavutil/mathematics.h"
31 
32 #include "formats.h"
33 #include "internal.h"
34 #include "avfilter.h"
35 #include "libavcodec/avcodec.h"
36 #include "libavformat/avformat.h"
37 
38 #include "qsvvpp.h"
39 #include "transpose.h"
40 
41 #define OFFSET(x) offsetof(VPPContext, x)
42 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
43 
44 /* number of video enhancement filters */
45 #define ENH_FILTERS_COUNT (7)
46 #define QSV_HAVE_ROTATION QSV_VERSION_ATLEAST(1, 17)
47 #define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)
48 
49 typedef struct VPPContext{
50  const AVClass *class;
51 
53 
54  /* Video Enhancement Algorithms */
55  mfxExtVPPDeinterlacing deinterlace_conf;
56  mfxExtVPPFrameRateConversion frc_conf;
57  mfxExtVPPDenoise denoise_conf;
58  mfxExtVPPDetail detail_conf;
59  mfxExtVPPProcAmp procamp_conf;
60  mfxExtVPPRotation rotation_conf;
61  mfxExtVPPMirroring mirroring_conf;
62 
63  int out_width;
65  /**
66  * Output sw format. AV_PIX_FMT_NONE for no conversion.
67  */
69 
70  AVRational framerate; /* target framerate */
71  int use_frc; /* use framerate conversion */
72  int deinterlace; /* deinterlace mode : 0=off, 1=bob, 2=advanced */
73  int denoise; /* Enable Denoise algorithm. Value [0, 100] */
74  int detail; /* Enable Detail Enhancement algorithm. */
75  /* Level is the optional, value [0, 100] */
76  int use_crop; /* 1 = use crop; 0=none */
77  int crop_w;
78  int crop_h;
79  int crop_x;
80  int crop_y;
81 
82  int transpose;
83  int rotate; /* rotate angle : [0, 90, 180, 270] */
84  int hflip; /* flip mode : 0 = off, 1 = HORIZONTAL flip */
85 
86  /* param for the procamp */
87  int procamp; /* enable procamp */
88  float hue;
89  float saturation;
90  float contrast;
91  float brightness;
92 
93  char *cx, *cy, *cw, *ch;
94  char *ow, *oh;
96 } VPPContext;
97 
98 static const AVOption options[] = {
99  { "deinterlace", "deinterlace mode: 0=off, 1=bob, 2=advanced", OFFSET(deinterlace), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MFX_DEINTERLACING_ADVANCED, .flags = FLAGS, "deinterlace" },
100  { "bob", "Bob deinterlace mode.", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_BOB }, .flags = FLAGS, "deinterlace" },
101  { "advanced", "Advanced deinterlace mode. ", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_ADVANCED }, .flags = FLAGS, "deinterlace" },
102 
103  { "denoise", "denoise level [0, 100]", OFFSET(denoise), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS },
104  { "detail", "enhancement level [0, 100]", OFFSET(detail), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS },
105  { "framerate", "output framerate", OFFSET(framerate), AV_OPT_TYPE_RATIONAL, { .dbl = 0.0 },0, DBL_MAX, .flags = FLAGS },
106  { "procamp", "Enable ProcAmp", OFFSET(procamp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS},
107  { "hue", "ProcAmp hue", OFFSET(hue), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, -180.0, 180.0, .flags = FLAGS},
108  { "saturation", "ProcAmp saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
109  { "contrast", "ProcAmp contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
110  { "brightness", "ProcAmp brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},
111 
112  { "transpose", "set transpose direction", OFFSET(transpose), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, FLAGS, "transpose"},
113  { "cclock_hflip", "rotate counter-clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
114  { "clock", "rotate clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK }, .flags=FLAGS, .unit = "transpose" },
115  { "cclock", "rotate counter-clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK }, .flags=FLAGS, .unit = "transpose" },
116  { "clock_hflip", "rotate clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
117  { "reversal", "rotate by half-turn", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL }, .flags=FLAGS, .unit = "transpose" },
118  { "hflip", "flip horizontally", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP }, .flags=FLAGS, .unit = "transpose" },
119  { "vflip", "flip vertically", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP }, .flags=FLAGS, .unit = "transpose" },
120 
121  { "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, 0, 0, FLAGS },
122  { "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, 0, 0, FLAGS },
123  { "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS },
124  { "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS },
125 
126  { "w", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS },
127  { "width", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS },
128  { "h", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
129  { "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
130  { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
131 
132  { NULL }
133 };
134 
135 static const char *const var_names[] = {
136  "iw", "in_w",
137  "ih", "in_h",
138  "ow", "out_w", "w",
139  "oh", "out_h", "h",
140  "cw",
141  "ch",
142  "cx",
143  "cy",
144  NULL
145 };
146 
147 enum var_name {
152  CW,
153  CH,
154  CX,
155  CY,
157 };
158 
160 {
161 #define PASS_EXPR(e, s) {\
162  ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \
163  if (ret < 0) {\
164  av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s);\
165  goto release;\
166  }\
167 }
168 #define CALC_EXPR(e, v, i) {\
169  i = v = av_expr_eval(e, var_values, NULL); \
170 }
171  VPPContext *vpp = ctx->priv;
172  double var_values[VAR_VARS_NB] = { NAN };
173  AVExpr *w_expr = NULL, *h_expr = NULL;
174  AVExpr *cw_expr = NULL, *ch_expr = NULL;
175  AVExpr *cx_expr = NULL, *cy_expr = NULL;
176  int ret = 0;
177 
178  PASS_EXPR(cw_expr, vpp->cw);
179  PASS_EXPR(ch_expr, vpp->ch);
180 
181  PASS_EXPR(w_expr, vpp->ow);
182  PASS_EXPR(h_expr, vpp->oh);
183 
184  PASS_EXPR(cx_expr, vpp->cx);
185  PASS_EXPR(cy_expr, vpp->cy);
186 
187  var_values[VAR_iW] =
188  var_values[VAR_IN_W] = ctx->inputs[0]->w;
189 
190  var_values[VAR_iH] =
191  var_values[VAR_IN_H] = ctx->inputs[0]->h;
192 
193  /* crop params */
194  CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w);
195  CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h);
196 
197  /* calc again in case cw is relative to ch */
198  CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w);
199 
200  CALC_EXPR(w_expr,
201  var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W],
202  vpp->out_width);
203  CALC_EXPR(h_expr,
204  var_values[VAR_OUT_H] = var_values[VAR_oH] = var_values[VAR_H],
205  vpp->out_height);
206 
207  /* calc again in case ow is relative to oh */
208  CALC_EXPR(w_expr,
209  var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W],
210  vpp->out_width);
211 
212 
213  CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x);
214  CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y);
215 
216  /* calc again in case cx is relative to cy */
217  CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x);
218 
219  if ((vpp->crop_w != var_values[VAR_iW]) || (vpp->crop_h != var_values[VAR_iH]))
220  vpp->use_crop = 1;
221 
222 release:
223  av_expr_free(w_expr);
224  av_expr_free(h_expr);
225  av_expr_free(cw_expr);
226  av_expr_free(ch_expr);
227  av_expr_free(cx_expr);
228  av_expr_free(cy_expr);
229 #undef PASS_EXPR
230 #undef CALC_EXPR
231 
232  return ret;
233 }
234 
236 {
237  VPPContext *vpp = ctx->priv;
238 
239  if (!strcmp(vpp->output_format_str, "same")) {
241  } else {
243  if (vpp->out_format == AV_PIX_FMT_NONE) {
244  av_log(ctx, AV_LOG_ERROR, "Unrecognized output pixel format: %s\n", vpp->output_format_str);
245  return AVERROR(EINVAL);
246  }
247  }
248 
249  return 0;
250 }
251 
253 {
254  AVFilterContext *ctx = inlink->dst;
255  VPPContext *vpp = ctx->priv;
256  int ret;
257 
258  if (vpp->framerate.den == 0 || vpp->framerate.num == 0)
259  vpp->framerate = inlink->frame_rate;
260 
261  if (av_cmp_q(vpp->framerate, inlink->frame_rate))
262  vpp->use_frc = 1;
263 
264  ret = eval_expr(ctx);
265  if (ret != 0) {
266  av_log(ctx, AV_LOG_ERROR, "Fail to eval expr.\n");
267  return ret;
268  }
269 
270  if (vpp->out_height == 0 || vpp->out_width == 0) {
271  vpp->out_width = inlink->w;
272  vpp->out_height = inlink->h;
273  }
274 
275  if (vpp->use_crop) {
276  vpp->crop_x = FFMAX(vpp->crop_x, 0);
277  vpp->crop_y = FFMAX(vpp->crop_y, 0);
278 
279  if(vpp->crop_w + vpp->crop_x > inlink->w)
280  vpp->crop_x = inlink->w - vpp->crop_w;
281  if(vpp->crop_h + vpp->crop_y > inlink->h)
282  vpp->crop_y = inlink->h - vpp->crop_h;
283  }
284 
285  return 0;
286 }
287 
288 static int config_output(AVFilterLink *outlink)
289 {
290  AVFilterContext *ctx = outlink->src;
291  VPPContext *vpp = ctx->priv;
292  QSVVPPParam param = { NULL };
293  QSVVPPCrop crop = { 0 };
294  mfxExtBuffer *ext_buf[ENH_FILTERS_COUNT];
295  AVFilterLink *inlink = ctx->inputs[0];
296  enum AVPixelFormat in_format;
297 
298  outlink->w = vpp->out_width;
299  outlink->h = vpp->out_height;
300  outlink->frame_rate = vpp->framerate;
301  outlink->time_base = av_inv_q(vpp->framerate);
302 
303  param.filter_frame = NULL;
304  param.num_ext_buf = 0;
305  param.ext_buf = ext_buf;
306 
307  if (inlink->format == AV_PIX_FMT_QSV) {
308  if (!inlink->hw_frames_ctx || !inlink->hw_frames_ctx->data)
309  return AVERROR(EINVAL);
310  else
311  in_format = ((AVHWFramesContext*)inlink->hw_frames_ctx->data)->sw_format;
312  } else
313  in_format = inlink->format;
314 
315  if (vpp->out_format == AV_PIX_FMT_NONE)
316  vpp->out_format = in_format;
317  param.out_sw_format = vpp->out_format;
318 
319  if (vpp->use_crop) {
320  crop.in_idx = 0;
321  crop.x = vpp->crop_x;
322  crop.y = vpp->crop_y;
323  crop.w = vpp->crop_w;
324  crop.h = vpp->crop_h;
325 
326  param.num_crop = 1;
327  param.crop = &crop;
328  }
329 
330  if (vpp->deinterlace) {
331  memset(&vpp->deinterlace_conf, 0, sizeof(mfxExtVPPDeinterlacing));
332  vpp->deinterlace_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING;
333  vpp->deinterlace_conf.Header.BufferSz = sizeof(mfxExtVPPDeinterlacing);
334  vpp->deinterlace_conf.Mode = vpp->deinterlace == 1 ?
335  MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED;
336 
337  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->deinterlace_conf;
338  }
339 
340  if (vpp->use_frc) {
341  memset(&vpp->frc_conf, 0, sizeof(mfxExtVPPFrameRateConversion));
342  vpp->frc_conf.Header.BufferId = MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION;
343  vpp->frc_conf.Header.BufferSz = sizeof(mfxExtVPPFrameRateConversion);
344  vpp->frc_conf.Algorithm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP;
345 
346  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->frc_conf;
347  }
348 
349  if (vpp->denoise) {
350  memset(&vpp->denoise_conf, 0, sizeof(mfxExtVPPDenoise));
351  vpp->denoise_conf.Header.BufferId = MFX_EXTBUFF_VPP_DENOISE;
352  vpp->denoise_conf.Header.BufferSz = sizeof(mfxExtVPPDenoise);
353  vpp->denoise_conf.DenoiseFactor = vpp->denoise;
354 
355  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->denoise_conf;
356  }
357 
358  if (vpp->detail) {
359  memset(&vpp->detail_conf, 0, sizeof(mfxExtVPPDetail));
360  vpp->detail_conf.Header.BufferId = MFX_EXTBUFF_VPP_DETAIL;
361  vpp->detail_conf.Header.BufferSz = sizeof(mfxExtVPPDetail);
362  vpp->detail_conf.DetailFactor = vpp->detail;
363 
364  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->detail_conf;
365  }
366 
367  if (vpp->procamp) {
368  memset(&vpp->procamp_conf, 0, sizeof(mfxExtVPPProcAmp));
369  vpp->procamp_conf.Header.BufferId = MFX_EXTBUFF_VPP_PROCAMP;
370  vpp->procamp_conf.Header.BufferSz = sizeof(mfxExtVPPProcAmp);
371  vpp->procamp_conf.Hue = vpp->hue;
372  vpp->procamp_conf.Saturation = vpp->saturation;
373  vpp->procamp_conf.Contrast = vpp->contrast;
374  vpp->procamp_conf.Brightness = vpp->brightness;
375 
376  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf;
377  }
378 
379  if (vpp->transpose >= 0) {
380 #ifdef QSV_HAVE_ROTATION
381  switch (vpp->transpose) {
383  vpp->rotate = MFX_ANGLE_270;
384  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
385  break;
386  case TRANSPOSE_CLOCK:
387  vpp->rotate = MFX_ANGLE_90;
388  vpp->hflip = MFX_MIRRORING_DISABLED;
389  break;
390  case TRANSPOSE_CCLOCK:
391  vpp->rotate = MFX_ANGLE_270;
392  vpp->hflip = MFX_MIRRORING_DISABLED;
393  break;
395  vpp->rotate = MFX_ANGLE_90;
396  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
397  break;
398  case TRANSPOSE_REVERSAL:
399  vpp->rotate = MFX_ANGLE_180;
400  vpp->hflip = MFX_MIRRORING_DISABLED;
401  break;
402  case TRANSPOSE_HFLIP:
403  vpp->rotate = MFX_ANGLE_0;
404  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
405  break;
406  case TRANSPOSE_VFLIP:
407  vpp->rotate = MFX_ANGLE_180;
408  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
409  break;
410  default:
411  av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode to %d.\n", vpp->transpose);
412  return AVERROR(EINVAL);
413  }
414 #else
415  av_log(ctx, AV_LOG_WARNING, "The QSV VPP transpose option is "
416  "not supported with this MSDK version.\n");
417  vpp->transpose = 0;
418 #endif
419  }
420 
421  if (vpp->rotate) {
422 #ifdef QSV_HAVE_ROTATION
423  memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
424  vpp->rotation_conf.Header.BufferId = MFX_EXTBUFF_VPP_ROTATION;
425  vpp->rotation_conf.Header.BufferSz = sizeof(mfxExtVPPRotation);
426  vpp->rotation_conf.Angle = vpp->rotate;
427 
428  if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) {
429  FFSWAP(int, vpp->out_width, vpp->out_height);
430  FFSWAP(int, outlink->w, outlink->h);
431  av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock rotation.\n");
432  }
433 
434  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->rotation_conf;
435 #else
436  av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
437  "not supported with this MSDK version.\n");
438  vpp->rotate = 0;
439 #endif
440  }
441 
442  if (vpp->hflip) {
443 #ifdef QSV_HAVE_MIRRORING
444  memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
445  vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
446  vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
447  vpp->mirroring_conf.Type = vpp->hflip;
448 
449  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->mirroring_conf;
450 #else
451  av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
452  "not supported with this MSDK version.\n");
453  vpp->hflip = 0;
454 #endif
455  }
456 
457  if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise ||
458  vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip ||
459  inlink->w != outlink->w || inlink->h != outlink->h || in_format != vpp->out_format)
460  return ff_qsvvpp_create(ctx, &vpp->qsv, &param);
461  else {
462  av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n");
463  if (inlink->hw_frames_ctx)
464  outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
465  }
466 
467  return 0;
468 }
469 
471 {
472  int ret = 0;
473  AVFilterContext *ctx = inlink->dst;
474  VPPContext *vpp = inlink->dst->priv;
475  AVFilterLink *outlink = ctx->outputs[0];
476 
477  if (vpp->qsv) {
478  ret = ff_qsvvpp_filter_frame(vpp->qsv, inlink, picref);
479  av_frame_free(&picref);
480  } else {
481  if (picref->pts != AV_NOPTS_VALUE)
482  picref->pts = av_rescale_q(picref->pts, inlink->time_base, outlink->time_base);
483  ret = ff_filter_frame(outlink, picref);
484  }
485 
486  return ret;
487 }
488 
490 {
491  int ret;
492  static const enum AVPixelFormat in_pix_fmts[] = {
499  };
500  static const enum AVPixelFormat out_pix_fmts[] = {
505  };
506 
508  &ctx->inputs[0]->outcfg.formats);
509  if (ret < 0)
510  return ret;
512  &ctx->outputs[0]->incfg.formats);
513 }
514 
516 {
517  VPPContext *vpp = ctx->priv;
518 
519  ff_qsvvpp_free(&vpp->qsv);
520 }
521 
522 static const AVClass vpp_class = {
523  .class_name = "vpp_qsv",
524  .item_name = av_default_item_name,
525  .option = options,
526  .version = LIBAVUTIL_VERSION_INT,
527 };
528 
529 static const AVFilterPad vpp_inputs[] = {
530  {
531  .name = "default",
532  .type = AVMEDIA_TYPE_VIDEO,
533  .config_props = config_input,
534  .filter_frame = filter_frame,
535  },
536  { NULL }
537 };
538 
539 static const AVFilterPad vpp_outputs[] = {
540  {
541  .name = "default",
542  .type = AVMEDIA_TYPE_VIDEO,
543  .config_props = config_output,
544  },
545  { NULL }
546 };
547 
549  .name = "vpp_qsv",
550  .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."),
551  .priv_size = sizeof(VPPContext),
553  .init = vpp_init,
554  .uninit = vpp_uninit,
555  .inputs = vpp_inputs,
556  .outputs = vpp_outputs,
557  .priv_class = &vpp_class,
558  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
559 };
VAR_oW
@ VAR_oW
Definition: vf_vpp_qsv.c:150
QSVVPPCrop::in_idx
int in_idx
Input index.
Definition: qsvvpp.h:45
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
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
opt.h
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
OFFSET
#define OFFSET(x)
Definition: vf_vpp_qsv.c:41
FFSWAP
#define FFSWAP(type, a, b)
Definition: common.h:108
FF_FILTER_FLAG_HWFRAME_AWARE
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
Definition: internal.h:339
QSVVPPParam::crop
QSVVPPCrop * crop
Definition: qsvvpp.h:62
QSVVPPParam::out_sw_format
enum AVPixelFormat out_sw_format
Definition: qsvvpp.h:58
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
VPPContext::cx
char * cx
Definition: vf_vpp_qsv.c:93
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
VPPContext::crop_w
int crop_w
Definition: vf_vpp_qsv.c:77
VPPContext::crop_h
int crop_h
Definition: vf_vpp_qsv.c:78
VPPContext::detail
int detail
Definition: vf_vpp_qsv.c:74
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:411
AVOption
AVOption.
Definition: opt.h:248
VPPContext::contrast
float contrast
Definition: vf_vpp_qsv.c:90
vpp_uninit
static av_cold void vpp_uninit(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:515
VPPContext::qsv
QSVVPPContext * qsv
Definition: vf_vpp_qsv.c:52
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
float.h
TRANSPOSE_CLOCK_FLIP
@ TRANSPOSE_CLOCK_FLIP
Definition: transpose.h:34
VAR_OUT_H
@ VAR_OUT_H
Definition: vf_vpp_qsv.c:151
VPPContext::hue
float hue
Definition: vf_vpp_qsv.c:88
mathematics.h
CY
@ CY
Definition: vf_vpp_qsv.c:155
VAR_IN_H
@ VAR_IN_H
Definition: vf_vpp_qsv.c:149
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
AV_OPT_TYPE_RATIONAL
@ AV_OPT_TYPE_RATIONAL
Definition: opt.h:230
formats.h
TRANSPOSE_CCLOCK
@ TRANSPOSE_CCLOCK
Definition: transpose.h:33
framerate
int framerate
Definition: h264_levels.c:65
VAR_oH
@ VAR_oH
Definition: vf_vpp_qsv.c:151
VPPContext::saturation
float saturation
Definition: vf_vpp_qsv.c:89
qsvvpp.h
VAR_IN_W
@ VAR_IN_W
Definition: vf_vpp_qsv.c:148
VPPContext::transpose
int transpose
Definition: vf_vpp_qsv.c:82
PASS_EXPR
#define PASS_EXPR(e, s)
VPPContext::out_format
enum AVPixelFormat out_format
Output sw format.
Definition: vf_vpp_qsv.c:68
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
AVRational::num
int num
Numerator.
Definition: rational.h:59
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
VPPContext::out_width
int out_width
Definition: vf_vpp_qsv.c:63
FLAGS
#define FLAGS
Definition: vf_vpp_qsv.c:42
TRANSPOSE_HFLIP
@ TRANSPOSE_HFLIP
Definition: transpose.h:36
in_pix_fmts
static enum AVPixelFormat in_pix_fmts[]
Definition: vf_ciescope.c:124
avassert.h
VPPContext::crop_x
int crop_x
Definition: vf_vpp_qsv.c:79
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
av_cold
#define av_cold
Definition: attributes.h:90
var_name
var_name
Definition: setts_bsf.c:50
VPPContext::use_frc
int use_frc
Definition: vf_vpp_qsv.c:71
QSVVPPCrop::w
int w
Definition: qsvvpp.h:46
VPPContext::denoise_conf
mfxExtVPPDenoise denoise_conf
Definition: vf_vpp_qsv.c:57
ff_qsvvpp_create
int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param)
Definition: qsvvpp.c:669
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:466
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVExpr
Definition: eval.c:157
VPPContext::detail_conf
mfxExtVPPDetail detail_conf
Definition: vf_vpp_qsv.c:58
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
NAN
#define NAN
Definition: mathematics.h:64
options
static const AVOption options[]
Definition: vf_vpp_qsv.c:98
VAR_iW
@ VAR_iW
Definition: vf_vpp_qsv.c:148
QSVVPPContext
Definition: qsvvpp.c:48
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
ENH_FILTERS_COUNT
#define ENH_FILTERS_COUNT
Definition: vf_vpp_qsv.c:45
QSVVPPParam::num_crop
int num_crop
Definition: qsvvpp.h:61
QSVVPPParam
Definition: qsvvpp.h:49
QSVVPPCrop::x
int x
Definition: qsvvpp.h:46
VPPContext::cw
char * cw
Definition: vf_vpp_qsv.c:93
AV_PIX_FMT_YUYV422
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:67
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
VPPContext::deinterlace
int deinterlace
Definition: vf_vpp_qsv.c:72
CALC_EXPR
#define CALC_EXPR(e, v, i)
VAR_H
@ VAR_H
Definition: vf_vpp_qsv.c:151
VPPContext::deinterlace_conf
mfxExtVPPDeinterlacing deinterlace_conf
Definition: vf_vpp_qsv.c:55
VPPContext::frc_conf
mfxExtVPPFrameRateConversion frc_conf
Definition: vf_vpp_qsv.c:56
vpp_inputs
static const AVFilterPad vpp_inputs[]
Definition: vf_vpp_qsv.c:529
VPPContext::denoise
int denoise
Definition: vf_vpp_qsv.c:73
inputs
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 inputs
Definition: filter_design.txt:243
AV_PIX_FMT_QSV
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:222
VPPContext
Definition: vf_vpp_qsv.c:49
ff_qsvvpp_free
int ff_qsvvpp_free(QSVVPPContext **vpp)
Definition: qsvvpp.c:777
VPPContext::ow
char * ow
Definition: vf_vpp_qsv.c:94
VPPContext::hflip
int hflip
Definition: vf_vpp_qsv.c:84
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:489
eval.h
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
VAR_W
@ VAR_W
Definition: vf_vpp_qsv.c:150
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_vpp_qsv.c:252
VPPContext::rotate
int rotate
Definition: vf_vpp_qsv.c:83
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
VAR_iH
@ VAR_iH
Definition: vf_vpp_qsv.c:149
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
VAR_OUT_W
@ VAR_OUT_W
Definition: vf_vpp_qsv.c:150
VPPContext::output_format_str
char * output_format_str
Definition: vf_vpp_qsv.c:95
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_vpp_qsv.c:156
VPPContext::ch
char * ch
Definition: vf_vpp_qsv.c:93
VPPContext::procamp_conf
mfxExtVPPProcAmp procamp_conf
Definition: vf_vpp_qsv.c:59
CH
@ CH
Definition: vf_vpp_qsv.c:153
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:372
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
denoise
#define denoise(...)
Definition: vf_hqdn3d.c:156
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_vpp_qsv.c:288
ff_vf_vpp_qsv
AVFilter ff_vf_vpp_qsv
Definition: vf_vpp_qsv.c:548
VPPContext::rotation_conf
mfxExtVPPRotation rotation_conf
Definition: vf_vpp_qsv.c:60
out_pix_fmts
static enum AVPixelFormat out_pix_fmts[]
Definition: vf_ciescope.c:133
QSVVPPParam::num_ext_buf
int num_ext_buf
Definition: qsvvpp.h:54
TRANSPOSE_CLOCK
@ TRANSPOSE_CLOCK
Definition: transpose.h:32
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
QSVVPPParam::filter_frame
int(* filter_frame)(AVFilterLink *outlink, AVFrame *frame)
Definition: qsvvpp.h:51
VPPContext::crop_y
int crop_y
Definition: vf_vpp_qsv.c:80
VPPContext::framerate
AVRational framerate
Definition: vf_vpp_qsv.c:70
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
VPPContext::out_height
int out_height
Definition: vf_vpp_qsv.c:64
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
Definition: vf_vpp_qsv.c:470
vpp_init
static av_cold int vpp_init(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:235
avcodec.h
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
AVFilter
Filter definition.
Definition: avfilter.h:145
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:89
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
avformat.h
av_get_pix_fmt
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:2501
QSVVPPCrop::h
int h
Crop rectangle.
Definition: qsvvpp.h:46
QSVVPPCrop::y
int y
Definition: qsvvpp.h:46
VPPContext::oh
char * oh
Definition: vf_vpp_qsv.c:94
TRANSPOSE_CCLOCK_FLIP
@ TRANSPOSE_CCLOCK_FLIP
Definition: transpose.h:31
ff_qsvvpp_filter_frame
int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picref)
Definition: qsvvpp.c:801
eval_expr
static int eval_expr(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:159
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
vpp_class
static const AVClass vpp_class
Definition: vf_vpp_qsv.c:522
VPPContext::use_crop
int use_crop
Definition: vf_vpp_qsv.c:76
transpose.h
TRANSPOSE_REVERSAL
@ TRANSPOSE_REVERSAL
Definition: transpose.h:35
VPPContext::cy
char * cy
Definition: vf_vpp_qsv.c:93
av_buffer_ref
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
AVFilterContext
An instance of a filter.
Definition: avfilter.h:341
TRANSPOSE_VFLIP
@ TRANSPOSE_VFLIP
Definition: transpose.h:37
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:448
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
var_names
static const char *const var_names[]
Definition: vf_vpp_qsv.c:135
CW
@ CW
Definition: vf_vpp_qsv.c:152
VPPContext::mirroring_conf
mfxExtVPPMirroring mirroring_conf
Definition: vf_vpp_qsv.c:61
CX
@ CX
Definition: vf_vpp_qsv.c:154
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
QSVVPPCrop
Definition: qsvvpp.h:44
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
transpose
#define transpose(x)
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
VPPContext::brightness
float brightness
Definition: vf_vpp_qsv.c:91
VPPContext::procamp
int procamp
Definition: vf_vpp_qsv.c:87
QSVVPPParam::ext_buf
mfxExtBuffer ** ext_buf
Definition: qsvvpp.h:55
vpp_outputs
static const AVFilterPad vpp_outputs[]
Definition: vf_vpp_qsv.c:539