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" }, CHAR_MIN, CHAR_MAX, FLAGS },
122  { "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, CHAR_MIN, CHAR_MAX, FLAGS },
123  { "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, CHAR_MIN, CHAR_MAX, FLAGS },
124  { "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, CHAR_MIN, CHAR_MAX, 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  AVFilterFormats *in_fmts, *out_fmts;
493  static const enum AVPixelFormat in_pix_fmts[] = {
500  };
501  static const enum AVPixelFormat out_pix_fmts[] = {
505  AV_PIX_FMT_NONE
506  };
507 
508  in_fmts = ff_make_format_list(in_pix_fmts);
509  out_fmts = ff_make_format_list(out_pix_fmts);
510  ret = ff_formats_ref(in_fmts, &ctx->inputs[0]->out_formats);
511  if (ret < 0)
512  return ret;
513  ret = ff_formats_ref(out_fmts, &ctx->outputs[0]->in_formats);
514  if (ret < 0)
515  return ret;
516 
517  return 0;
518 }
519 
521 {
522  VPPContext *vpp = ctx->priv;
523 
524  ff_qsvvpp_free(&vpp->qsv);
525 }
526 
527 static const AVClass vpp_class = {
528  .class_name = "vpp_qsv",
529  .item_name = av_default_item_name,
530  .option = options,
531  .version = LIBAVUTIL_VERSION_INT,
532 };
533 
534 static const AVFilterPad vpp_inputs[] = {
535  {
536  .name = "default",
537  .type = AVMEDIA_TYPE_VIDEO,
538  .config_props = config_input,
539  .filter_frame = filter_frame,
540  },
541  { NULL }
542 };
543 
544 static const AVFilterPad vpp_outputs[] = {
545  {
546  .name = "default",
547  .type = AVMEDIA_TYPE_VIDEO,
548  .config_props = config_output,
549  },
550  { NULL }
551 };
552 
554  .name = "vpp_qsv",
555  .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."),
556  .priv_size = sizeof(VPPContext),
558  .init = vpp_init,
559  .uninit = vpp_uninit,
560  .inputs = vpp_inputs,
561  .outputs = vpp_outputs,
562  .priv_class = &vpp_class,
563  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
564 };
#define ENH_FILTERS_COUNT
Definition: vf_vpp_qsv.c:45
#define NULL
Definition: coverity.c:32
#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:385
int use_frc
Definition: vf_vpp_qsv.c:71
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
float brightness
Definition: vf_vpp_qsv.c:91
int crop_w
Definition: vf_vpp_qsv.c:77
static int config_output(AVFilterLink *outlink)
Definition: vf_vpp_qsv.c:288
AVOption.
Definition: opt.h:246
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
Main libavfilter public API header.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static av_cold int vpp_init(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:235
int num
Numerator.
Definition: rational.h:59
char * ch
Definition: vf_vpp_qsv.c:93
static int config_input(AVFilterLink *inlink)
Definition: vf_vpp_qsv.c:252
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
enum AVPixelFormat out_format
Output sw format.
Definition: vf_vpp_qsv.c:68
static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
Definition: vf_vpp_qsv.c:470
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
const char * name
Pad name.
Definition: internal.h:60
#define AV_PIX_FMT_P010
Definition: pixfmt.h:436
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
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
#define OFFSET(x)
Definition: vf_vpp_qsv.c:41
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1093
mfxExtVPPProcAmp procamp_conf
Definition: vf_vpp_qsv.c:59
int crop_y
Definition: vf_vpp_qsv.c:80
AVRational framerate
Definition: vf_vpp_qsv.c:70
#define CALC_EXPR(e, v, i)
int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param)
Definition: qsvvpp.c:561
AVFilter ff_vf_vpp_qsv
Definition: vf_vpp_qsv.c:553
#define av_cold
Definition: attributes.h:82
char * cw
Definition: vf_vpp_qsv.c:93
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:279
AVOptions.
static int eval_expr(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:159
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
Definition: eval.c:157
float saturation
Definition: vf_vpp_qsv.c:89
int crop_h
Definition: vf_vpp_qsv.c:78
int detail
Definition: vf_vpp_qsv.c:74
int use_crop
Definition: vf_vpp_qsv.c:76
int w
Definition: qsvvpp.h:46
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define av_log(a,...)
mfxExtVPPDetail detail_conf
Definition: vf_vpp_qsv.c:58
int num_ext_buf
Definition: qsvvpp.h:54
char * cy
Definition: vf_vpp_qsv.c:93
A filter pad used for either input or output.
Definition: internal.h:54
float contrast
Definition: vf_vpp_qsv.c:90
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
int procamp
Definition: vf_vpp_qsv.c:87
mfxExtVPPDeinterlacing deinterlace_conf
Definition: vf_vpp_qsv.c:55
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int deinterlace
Definition: vf_vpp_qsv.c:72
int out_width
Definition: vf_vpp_qsv.c:63
int crop_x
Definition: vf_vpp_qsv.c:79
static int query_formats(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:489
char * cx
Definition: vf_vpp_qsv.c:93
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
Definition: vf_vpp_qsv.c:153
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
simple assert() macros that are a bit more flexible than ISO C assert().
static const char *const var_names[]
Definition: vf_vpp_qsv.c:135
static enum AVPixelFormat in_pix_fmts[]
Definition: vf_ciescope.c:124
#define FFMAX(a, b)
Definition: common.h:94
QSVVPPContext * qsv
Definition: vf_vpp_qsv.c:52
static const AVFilterPad vpp_outputs[]
Definition: vf_vpp_qsv.c:544
int transpose
Definition: vf_vpp_qsv.c:82
float hue
Definition: vf_vpp_qsv.c:88
var_name
Definition: aeval.c:46
char * oh
Definition: vf_vpp_qsv.c:94
int x
Definition: qsvvpp.h:46
#define NAN
Definition: mathematics.h:64
Definition: vf_vpp_qsv.c:154
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:439
char * output_format_str
Definition: vf_vpp_qsv.c:95
AVFormatContext * ctx
Definition: movenc.c:48
int num_crop
Definition: qsvvpp.h:61
char * ow
Definition: vf_vpp_qsv.c:94
#define FLAGS
Definition: vf_vpp_qsv.c:42
mfxExtVPPRotation rotation_conf
Definition: vf_vpp_qsv.c:60
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
int rotate
Definition: vf_vpp_qsv.c:83
Libavcodec external API header.
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:336
int y
Definition: qsvvpp.h:46
int ff_qsvvpp_filter_frame(QSVVPPContext *s, AVFilterLink *inlink, AVFrame *picref)
Definition: qsvvpp.c:688
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:360
uint8_t * data
The data buffer.
Definition: buffer.h:89
static const AVFilterPad vpp_inputs[]
Definition: vf_vpp_qsv.c:534
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:67
static const AVClass vpp_class
Definition: vf_vpp_qsv.c:527
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
Describe the class of an AVClass context structure.
Definition: log.h:67
int ff_qsvvpp_free(QSVVPPContext **vpp)
Definition: qsvvpp.c:664
Filter definition.
Definition: avfilter.h:144
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int out_height
Definition: vf_vpp_qsv.c:64
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:123
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:222
const char * name
Filter name.
Definition: avfilter.h:148
GLsizei GLboolean transpose
Definition: opengl_enc.c:108
#define PASS_EXPR(e, s)
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
Definition: vf_vpp_qsv.c:152
mfxExtBuffer ** ext_buf
Definition: qsvvpp.h:55
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
mfxExtVPPFrameRateConversion frc_conf
Definition: vf_vpp_qsv.c:56
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
Main libavformat public API header.
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
int h
Crop rectangle.
Definition: qsvvpp.h:46
mfxExtVPPDenoise denoise_conf
Definition: vf_vpp_qsv.c:57
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
static enum AVPixelFormat out_pix_fmts[]
Definition: vf_ciescope.c:133
int den
Denominator.
Definition: rational.h:60
static const AVOption options[]
Definition: vf_vpp_qsv.c:98
int in_idx
Input index.
Definition: qsvvpp.h:45
static av_cold void vpp_uninit(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:520
A list of supported formats for one end of a filter link.
Definition: formats.h:64
int denoise
Definition: vf_vpp_qsv.c:73
An instance of a filter.
Definition: avfilter.h:338
QSVVPPCrop * crop
Definition: qsvvpp.h:62
enum AVPixelFormat out_sw_format
Definition: qsvvpp.h:58
Intel Quick Sync Video VPP base function.
Definition: vf_vpp_qsv.c:155
int(* filter_frame)(AVFilterLink *outlink, AVFrame *frame)
Definition: qsvvpp.h:51
#define FFSWAP(type, a, b)
Definition: common.h:99
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition: pixdesc.c:2450
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
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
simple arithmetic expression evaluator
mfxExtVPPMirroring mirroring_conf
Definition: vf_vpp_qsv.c:61