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/pixdesc.h"
29 #include "libavutil/mathematics.h"
30 
31 #include "formats.h"
32 #include "internal.h"
33 #include "avfilter.h"
34 #include "filters.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 
98  int eof;
99 } VPPContext;
100 
101 static const AVOption options[] = {
102  { "deinterlace", "deinterlace mode: 0=off, 1=bob, 2=advanced", OFFSET(deinterlace), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MFX_DEINTERLACING_ADVANCED, .flags = FLAGS, "deinterlace" },
103  { "bob", "Bob deinterlace mode.", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_BOB }, .flags = FLAGS, "deinterlace" },
104  { "advanced", "Advanced deinterlace mode. ", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_ADVANCED }, .flags = FLAGS, "deinterlace" },
105 
106  { "denoise", "denoise level [0, 100]", OFFSET(denoise), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS },
107  { "detail", "enhancement level [0, 100]", OFFSET(detail), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS },
108  { "framerate", "output framerate", OFFSET(framerate), AV_OPT_TYPE_RATIONAL, { .dbl = 0.0 },0, DBL_MAX, .flags = FLAGS },
109  { "procamp", "Enable ProcAmp", OFFSET(procamp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS},
110  { "hue", "ProcAmp hue", OFFSET(hue), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, -180.0, 180.0, .flags = FLAGS},
111  { "saturation", "ProcAmp saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
112  { "contrast", "ProcAmp contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
113  { "brightness", "ProcAmp brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},
114 
115  { "transpose", "set transpose direction", OFFSET(transpose), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, FLAGS, "transpose"},
116  { "cclock_hflip", "rotate counter-clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
117  { "clock", "rotate clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK }, .flags=FLAGS, .unit = "transpose" },
118  { "cclock", "rotate counter-clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK }, .flags=FLAGS, .unit = "transpose" },
119  { "clock_hflip", "rotate clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
120  { "reversal", "rotate by half-turn", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL }, .flags=FLAGS, .unit = "transpose" },
121  { "hflip", "flip horizontally", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP }, .flags=FLAGS, .unit = "transpose" },
122  { "vflip", "flip vertically", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP }, .flags=FLAGS, .unit = "transpose" },
123 
124  { "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, 0, 0, FLAGS },
125  { "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, 0, 0, FLAGS },
126  { "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS },
127  { "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS },
128 
129  { "w", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS },
130  { "width", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS },
131  { "h", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
132  { "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
133  { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
134  { "async_depth", "Internal parallelization depth, the higher the value the higher the latency.", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, .flags = FLAGS },
135 
136  { NULL }
137 };
138 
139 static const char *const var_names[] = {
140  "iw", "in_w",
141  "ih", "in_h",
142  "ow", "out_w", "w",
143  "oh", "out_h", "h",
144  "cw",
145  "ch",
146  "cx",
147  "cy",
148  NULL
149 };
150 
151 enum var_name {
156  CW,
157  CH,
158  CX,
159  CY,
161 };
162 
164 {
165 #define PASS_EXPR(e, s) {\
166  ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \
167  if (ret < 0) {\
168  av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s);\
169  goto release;\
170  }\
171 }
172 #define CALC_EXPR(e, v, i) {\
173  i = v = av_expr_eval(e, var_values, NULL); \
174 }
175  VPPContext *vpp = ctx->priv;
176  double var_values[VAR_VARS_NB] = { NAN };
177  AVExpr *w_expr = NULL, *h_expr = NULL;
178  AVExpr *cw_expr = NULL, *ch_expr = NULL;
179  AVExpr *cx_expr = NULL, *cy_expr = NULL;
180  int ret = 0;
181 
182  PASS_EXPR(cw_expr, vpp->cw);
183  PASS_EXPR(ch_expr, vpp->ch);
184 
185  PASS_EXPR(w_expr, vpp->ow);
186  PASS_EXPR(h_expr, vpp->oh);
187 
188  PASS_EXPR(cx_expr, vpp->cx);
189  PASS_EXPR(cy_expr, vpp->cy);
190 
191  var_values[VAR_iW] =
192  var_values[VAR_IN_W] = ctx->inputs[0]->w;
193 
194  var_values[VAR_iH] =
195  var_values[VAR_IN_H] = ctx->inputs[0]->h;
196 
197  /* crop params */
198  CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w);
199  CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h);
200 
201  /* calc again in case cw is relative to ch */
202  CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w);
203 
204  CALC_EXPR(w_expr,
205  var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W],
206  vpp->out_width);
207  CALC_EXPR(h_expr,
208  var_values[VAR_OUT_H] = var_values[VAR_oH] = var_values[VAR_H],
209  vpp->out_height);
210 
211  /* calc again in case ow is relative to oh */
212  CALC_EXPR(w_expr,
213  var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W],
214  vpp->out_width);
215 
216 
217  CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x);
218  CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y);
219 
220  /* calc again in case cx is relative to cy */
221  CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x);
222 
223  if ((vpp->crop_w != var_values[VAR_iW]) || (vpp->crop_h != var_values[VAR_iH]))
224  vpp->use_crop = 1;
225 
226 release:
227  av_expr_free(w_expr);
228  av_expr_free(h_expr);
229  av_expr_free(cw_expr);
230  av_expr_free(ch_expr);
231  av_expr_free(cx_expr);
232  av_expr_free(cy_expr);
233 #undef PASS_EXPR
234 #undef CALC_EXPR
235 
236  return ret;
237 }
238 
240 {
241  VPPContext *vpp = ctx->priv;
242 
243  if (!strcmp(vpp->output_format_str, "same")) {
245  } else {
247  if (vpp->out_format == AV_PIX_FMT_NONE) {
248  av_log(ctx, AV_LOG_ERROR, "Unrecognized output pixel format: %s\n", vpp->output_format_str);
249  return AVERROR(EINVAL);
250  }
251  }
252 
253  return 0;
254 }
255 
257 {
258  AVFilterContext *ctx = inlink->dst;
259  VPPContext *vpp = ctx->priv;
260  int ret;
261 
262  if (vpp->framerate.den == 0 || vpp->framerate.num == 0)
263  vpp->framerate = inlink->frame_rate;
264 
265  if (av_cmp_q(vpp->framerate, inlink->frame_rate))
266  vpp->use_frc = 1;
267 
268  ret = eval_expr(ctx);
269  if (ret != 0) {
270  av_log(ctx, AV_LOG_ERROR, "Fail to eval expr.\n");
271  return ret;
272  }
273 
274  if (vpp->out_height == 0 || vpp->out_width == 0) {
275  vpp->out_width = inlink->w;
276  vpp->out_height = inlink->h;
277  }
278 
279  if (vpp->use_crop) {
280  vpp->crop_x = FFMAX(vpp->crop_x, 0);
281  vpp->crop_y = FFMAX(vpp->crop_y, 0);
282 
283  if(vpp->crop_w + vpp->crop_x > inlink->w)
284  vpp->crop_x = inlink->w - vpp->crop_w;
285  if(vpp->crop_h + vpp->crop_y > inlink->h)
286  vpp->crop_y = inlink->h - vpp->crop_h;
287  }
288 
289  return 0;
290 }
291 
292 static int config_output(AVFilterLink *outlink)
293 {
294  AVFilterContext *ctx = outlink->src;
295  VPPContext *vpp = ctx->priv;
296  QSVVPPParam param = { NULL };
297  QSVVPPCrop crop = { 0 };
298  mfxExtBuffer *ext_buf[ENH_FILTERS_COUNT];
299  AVFilterLink *inlink = ctx->inputs[0];
300  enum AVPixelFormat in_format;
301 
302  outlink->w = vpp->out_width;
303  outlink->h = vpp->out_height;
304  outlink->frame_rate = vpp->framerate;
305  outlink->time_base = inlink->time_base;
306 
307  param.filter_frame = NULL;
308  param.num_ext_buf = 0;
309  param.ext_buf = ext_buf;
310  param.async_depth = vpp->async_depth;
311 
312  if (inlink->format == AV_PIX_FMT_QSV) {
313  if (!inlink->hw_frames_ctx || !inlink->hw_frames_ctx->data)
314  return AVERROR(EINVAL);
315  else
316  in_format = ((AVHWFramesContext*)inlink->hw_frames_ctx->data)->sw_format;
317  } else
318  in_format = inlink->format;
319 
320  if (vpp->out_format == AV_PIX_FMT_NONE)
321  vpp->out_format = in_format;
322  param.out_sw_format = vpp->out_format;
323 
324  if (vpp->use_crop) {
325  crop.in_idx = 0;
326  crop.x = vpp->crop_x;
327  crop.y = vpp->crop_y;
328  crop.w = vpp->crop_w;
329  crop.h = vpp->crop_h;
330 
331  param.num_crop = 1;
332  param.crop = &crop;
333  }
334 
335  if (vpp->deinterlace) {
336  memset(&vpp->deinterlace_conf, 0, sizeof(mfxExtVPPDeinterlacing));
337  vpp->deinterlace_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING;
338  vpp->deinterlace_conf.Header.BufferSz = sizeof(mfxExtVPPDeinterlacing);
339  vpp->deinterlace_conf.Mode = vpp->deinterlace == 1 ?
340  MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED;
341 
342  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->deinterlace_conf;
343  }
344 
345  if (vpp->use_frc) {
346  memset(&vpp->frc_conf, 0, sizeof(mfxExtVPPFrameRateConversion));
347  vpp->frc_conf.Header.BufferId = MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION;
348  vpp->frc_conf.Header.BufferSz = sizeof(mfxExtVPPFrameRateConversion);
349  vpp->frc_conf.Algorithm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP;
350 
351  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->frc_conf;
352  }
353 
354  if (vpp->denoise) {
355  memset(&vpp->denoise_conf, 0, sizeof(mfxExtVPPDenoise));
356  vpp->denoise_conf.Header.BufferId = MFX_EXTBUFF_VPP_DENOISE;
357  vpp->denoise_conf.Header.BufferSz = sizeof(mfxExtVPPDenoise);
358  vpp->denoise_conf.DenoiseFactor = vpp->denoise;
359 
360  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->denoise_conf;
361  }
362 
363  if (vpp->detail) {
364  memset(&vpp->detail_conf, 0, sizeof(mfxExtVPPDetail));
365  vpp->detail_conf.Header.BufferId = MFX_EXTBUFF_VPP_DETAIL;
366  vpp->detail_conf.Header.BufferSz = sizeof(mfxExtVPPDetail);
367  vpp->detail_conf.DetailFactor = vpp->detail;
368 
369  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->detail_conf;
370  }
371 
372  if (vpp->procamp) {
373  memset(&vpp->procamp_conf, 0, sizeof(mfxExtVPPProcAmp));
374  vpp->procamp_conf.Header.BufferId = MFX_EXTBUFF_VPP_PROCAMP;
375  vpp->procamp_conf.Header.BufferSz = sizeof(mfxExtVPPProcAmp);
376  vpp->procamp_conf.Hue = vpp->hue;
377  vpp->procamp_conf.Saturation = vpp->saturation;
378  vpp->procamp_conf.Contrast = vpp->contrast;
379  vpp->procamp_conf.Brightness = vpp->brightness;
380 
381  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf;
382  }
383 
384  if (vpp->transpose >= 0) {
385 #ifdef QSV_HAVE_ROTATION
386  switch (vpp->transpose) {
388  vpp->rotate = MFX_ANGLE_270;
389  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
390  break;
391  case TRANSPOSE_CLOCK:
392  vpp->rotate = MFX_ANGLE_90;
393  vpp->hflip = MFX_MIRRORING_DISABLED;
394  break;
395  case TRANSPOSE_CCLOCK:
396  vpp->rotate = MFX_ANGLE_270;
397  vpp->hflip = MFX_MIRRORING_DISABLED;
398  break;
400  vpp->rotate = MFX_ANGLE_90;
401  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
402  break;
403  case TRANSPOSE_REVERSAL:
404  vpp->rotate = MFX_ANGLE_180;
405  vpp->hflip = MFX_MIRRORING_DISABLED;
406  break;
407  case TRANSPOSE_HFLIP:
408  vpp->rotate = MFX_ANGLE_0;
409  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
410  break;
411  case TRANSPOSE_VFLIP:
412  vpp->rotate = MFX_ANGLE_180;
413  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
414  break;
415  default:
416  av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode to %d.\n", vpp->transpose);
417  return AVERROR(EINVAL);
418  }
419 #else
420  av_log(ctx, AV_LOG_WARNING, "The QSV VPP transpose option is "
421  "not supported with this MSDK version.\n");
422  vpp->transpose = 0;
423 #endif
424  }
425 
426  if (vpp->rotate) {
427 #ifdef QSV_HAVE_ROTATION
428  memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
429  vpp->rotation_conf.Header.BufferId = MFX_EXTBUFF_VPP_ROTATION;
430  vpp->rotation_conf.Header.BufferSz = sizeof(mfxExtVPPRotation);
431  vpp->rotation_conf.Angle = vpp->rotate;
432 
433  if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) {
434  FFSWAP(int, vpp->out_width, vpp->out_height);
435  FFSWAP(int, outlink->w, outlink->h);
436  av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock rotation.\n");
437  }
438 
439  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->rotation_conf;
440 #else
441  av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
442  "not supported with this MSDK version.\n");
443  vpp->rotate = 0;
444 #endif
445  }
446 
447  if (vpp->hflip) {
448 #ifdef QSV_HAVE_MIRRORING
449  memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
450  vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
451  vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
452  vpp->mirroring_conf.Type = vpp->hflip;
453 
454  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->mirroring_conf;
455 #else
456  av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
457  "not supported with this MSDK version.\n");
458  vpp->hflip = 0;
459 #endif
460  }
461 
462  if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise ||
463  vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip ||
464  inlink->w != outlink->w || inlink->h != outlink->h || in_format != vpp->out_format)
465  return ff_qsvvpp_create(ctx, &vpp->qsv, &param);
466  else {
467  av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n");
468  if (inlink->hw_frames_ctx)
469  outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
470  }
471 
472  return 0;
473 }
474 
476 {
477  AVFilterLink *inlink = ctx->inputs[0];
478  AVFilterLink *outlink = ctx->outputs[0];
479  VPPContext *s =ctx->priv;
480  QSVVPPContext *qsv = s->qsv;
481  AVFrame *in = NULL;
482  int ret, status;
483  int64_t pts;
484 
486 
487  if (!s->eof) {
489  if (ret < 0)
490  return ret;
491 
493  if (status == AVERROR_EOF) {
494  s->eof = 1;
495  }
496  }
497  }
498 
499  if (qsv) {
500  if (in || s->eof) {
501  qsv->eof = s->eof;
502  ret = ff_qsvvpp_filter_frame(qsv, inlink, in);
503  av_frame_free(&in);
504 
505  if (s->eof) {
506  ff_outlink_set_status(outlink, status, pts);
507  return 0;
508  }
509 
510  if (qsv->got_frame) {
511  qsv->got_frame = 0;
512  return ret;
513  }
514  }
515  } else {
516  if (in) {
517  if (in->pts != AV_NOPTS_VALUE)
518  in->pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base);
519 
520  ret = ff_filter_frame(outlink, in);
521  return ret;
522  }
523  }
524 
525  if (s->eof) {
526  ff_outlink_set_status(outlink, status, pts);
527  return 0;
528  } else {
530  }
531 
532  return FFERROR_NOT_READY;
533 }
534 
536 {
537  int ret;
538  static const enum AVPixelFormat in_pix_fmts[] = {
545  };
546  static const enum AVPixelFormat out_pix_fmts[] = {
551  };
552 
554  &ctx->inputs[0]->outcfg.formats);
555  if (ret < 0)
556  return ret;
558  &ctx->outputs[0]->incfg.formats);
559 }
560 
562 {
563  VPPContext *vpp = ctx->priv;
564 
565  ff_qsvvpp_free(&vpp->qsv);
566 }
567 
568 static const AVClass vpp_class = {
569  .class_name = "vpp_qsv",
570  .item_name = av_default_item_name,
571  .option = options,
572  .version = LIBAVUTIL_VERSION_INT,
573 };
574 
575 static const AVFilterPad vpp_inputs[] = {
576  {
577  .name = "default",
578  .type = AVMEDIA_TYPE_VIDEO,
579  .config_props = config_input,
580  },
581  { NULL }
582 };
583 
584 static const AVFilterPad vpp_outputs[] = {
585  {
586  .name = "default",
587  .type = AVMEDIA_TYPE_VIDEO,
588  .config_props = config_output,
589  },
590  { NULL }
591 };
592 
594  .name = "vpp_qsv",
595  .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."),
596  .priv_size = sizeof(VPPContext),
598  .init = vpp_init,
599  .uninit = vpp_uninit,
600  .inputs = vpp_inputs,
601  .outputs = vpp_outputs,
602  .activate = activate,
603  .priv_class = &vpp_class,
604  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
605 };
VAR_oW
@ VAR_oW
Definition: vf_vpp_qsv.c:154
QSVVPPCrop::in_idx
int in_idx
Input index.
Definition: qsvvpp.h:80
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
ff_vf_vpp_qsv
const AVFilter ff_vf_vpp_qsv
Definition: vf_vpp_qsv.c:593
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
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
VPPContext::eof
int eof
Definition: vf_vpp_qsv.c:98
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:97
QSVVPPParam::out_sw_format
enum AVPixelFormat out_sw_format
Definition: qsvvpp.h:93
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
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:112
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
pixdesc.h
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:396
AVOption
AVOption.
Definition: opt.h:247
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:561
VPPContext::qsv
QSVVPPContext * qsv
Definition: vf_vpp_qsv.c:52
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
float.h
TRANSPOSE_CLOCK_FLIP
@ TRANSPOSE_CLOCK_FLIP
Definition: transpose.h:34
VAR_OUT_H
@ VAR_OUT_H
Definition: vf_vpp_qsv.c:155
VPPContext::hue
float hue
Definition: vf_vpp_qsv.c:88
mathematics.h
CY
@ CY
Definition: vf_vpp_qsv.c:159
VAR_IN_H
@ VAR_IN_H
Definition: vf_vpp_qsv.c:153
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
AV_OPT_TYPE_RATIONAL
@ AV_OPT_TYPE_RATIONAL
Definition: opt.h:229
FF_FILTER_FORWARD_STATUS_BACK
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
formats.h
TRANSPOSE_CCLOCK
@ TRANSPOSE_CCLOCK
Definition: transpose.h:33
framerate
int framerate
Definition: h264_levels.c:65
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1376
VAR_oH
@ VAR_oH
Definition: vf_vpp_qsv.c:155
VPPContext::saturation
float saturation
Definition: vf_vpp_qsv.c:89
qsvvpp.h
VAR_IN_W
@ VAR_IN_W
Definition: vf_vpp_qsv.c:152
VPPContext::transpose
int transpose
Definition: vf_vpp_qsv.c:82
pts
static int64_t pts
Definition: transcode_aac.c:653
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
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:180
av_cold
#define av_cold
Definition: attributes.h:90
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
var_name
var_name
Definition: setts_bsf.c:50
VPPContext::use_frc
int use_frc
Definition: vf_vpp_qsv.c:71
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
QSVVPPCrop::w
int w
Definition: qsvvpp.h:81
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:650
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:459
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
filters.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
activate
static int activate(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:475
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:141
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:101
QSVVPPParam::async_depth
int async_depth
Definition: qsvvpp.h:99
VAR_iW
@ VAR_iW
Definition: vf_vpp_qsv.c:152
QSVVPPContext
Definition: qsvvpp.h:50
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:96
QSVVPPParam
Definition: qsvvpp.h:84
QSVVPPCrop::x
int x
Definition: qsvvpp.h:81
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:155
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:575
VPPContext::denoise
int denoise
Definition: vf_vpp_qsv.c:73
AV_PIX_FMT_QSV
@ AV_PIX_FMT_QSV
HW acceleration through QSV, data[3] contains a pointer to the mfxFrameSurface1 structure.
Definition: pixfmt.h:212
VPPContext
Definition: vf_vpp_qsv.c:49
QSVVPPContext::got_frame
int got_frame
Definition: qsvvpp.h:72
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1331
ff_qsvvpp_free
int ff_qsvvpp_free(QSVVPPContext **vpp)
Definition: qsvvpp.c:768
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:535
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:116
VAR_W
@ VAR_W
Definition: vf_vpp_qsv.c:154
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_vpp_qsv.c:256
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:153
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:154
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:160
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:157
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:362
FF_FILTER_FORWARD_WANTED
FF_FILTER_FORWARD_WANTED(outlink, inlink)
QSVVPPContext::eof
int eof
Definition: qsvvpp.h:74
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:227
denoise
#define denoise(...)
Definition: vf_hqdn3d.c:156
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_vpp_qsv.c:292
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:89
TRANSPOSE_CLOCK
@ TRANSPOSE_CLOCK
Definition: transpose.h:32
QSVVPPParam::filter_frame
int(* filter_frame)(AVFilterLink *outlink, AVFrame *frame)
Definition: qsvvpp.h:86
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
vpp_init
static av_cold int vpp_init(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:239
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
VPPContext::async_depth
int async_depth
Definition: vf_vpp_qsv.c:97
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:71
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:2472
QSVVPPCrop::h
int h
Crop rectangle.
Definition: qsvvpp.h:81
QSVVPPCrop::y
int y
Definition: qsvvpp.h:81
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:793
eval_expr
static int eval_expr(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:163
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:224
avfilter.h
vpp_class
static const AVClass vpp_class
Definition: vf_vpp_qsv.c:568
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:333
TRANSPOSE_VFLIP
@ TRANSPOSE_VFLIP
Definition: transpose.h:37
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:438
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
var_names
static const char *const var_names[]
Definition: vf_vpp_qsv.c:139
CW
@ CW
Definition: vf_vpp_qsv.c:156
VPPContext::mirroring_conf
mfxExtVPPMirroring mirroring_conf
Definition: vf_vpp_qsv.c:61
CX
@ CX
Definition: vf_vpp_qsv.c:158
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:79
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
transpose
#define transpose(x)
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
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:90
vpp_outputs
static const AVFilterPad vpp_outputs[]
Definition: vf_vpp_qsv.c:584