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/hwcontext.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 "filters.h"
36 #include "libavcodec/avcodec.h"
37 #include "libavformat/avformat.h"
38 
39 #include "qsvvpp.h"
40 #include "transpose.h"
41 
42 #define OFFSET(x) offsetof(VPPContext, x)
43 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
44 
45 /* number of video enhancement filters */
46 #define ENH_FILTERS_COUNT (8)
47 #define QSV_HAVE_ROTATION QSV_VERSION_ATLEAST(1, 17)
48 #define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)
49 #define QSV_HAVE_SCALING_CONFIG QSV_VERSION_ATLEAST(1, 19)
50 
51 typedef struct VPPContext{
52  const AVClass *class;
53 
55 
56  /* Video Enhancement Algorithms */
57  mfxExtVPPDeinterlacing deinterlace_conf;
58  mfxExtVPPFrameRateConversion frc_conf;
59  mfxExtVPPDenoise denoise_conf;
60  mfxExtVPPDetail detail_conf;
61  mfxExtVPPProcAmp procamp_conf;
62  mfxExtVPPRotation rotation_conf;
63  mfxExtVPPMirroring mirroring_conf;
64 #ifdef QSV_HAVE_SCALING_CONFIG
65  mfxExtVPPScaling scale_conf;
66 #endif
67 
68  int out_width;
70  /**
71  * Output sw format. AV_PIX_FMT_NONE for no conversion.
72  */
74 
75  AVRational framerate; /* target framerate */
76  int use_frc; /* use framerate conversion */
77  int deinterlace; /* deinterlace mode : 0=off, 1=bob, 2=advanced */
78  int denoise; /* Enable Denoise algorithm. Value [0, 100] */
79  int detail; /* Enable Detail Enhancement algorithm. */
80  /* Level is the optional, value [0, 100] */
81  int use_crop; /* 1 = use crop; 0=none */
82  int crop_w;
83  int crop_h;
84  int crop_x;
85  int crop_y;
86 
87  int transpose;
88  int rotate; /* rotate angle : [0, 90, 180, 270] */
89  int hflip; /* flip mode : 0 = off, 1 = HORIZONTAL flip */
90 
91  int scale_mode; /* scale mode : 0 = auto, 1 = low power, 2 = high quality */
92 
93  /* param for the procamp */
94  int procamp; /* enable procamp */
95  float hue;
96  float saturation;
97  float contrast;
98  float brightness;
99 
100  char *cx, *cy, *cw, *ch;
101  char *ow, *oh;
103 
105  int eof;
106 } VPPContext;
107 
108 static const AVOption options[] = {
109  { "deinterlace", "deinterlace mode: 0=off, 1=bob, 2=advanced", OFFSET(deinterlace), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MFX_DEINTERLACING_ADVANCED, .flags = FLAGS, "deinterlace" },
110  { "bob", "Bob deinterlace mode.", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_BOB }, .flags = FLAGS, "deinterlace" },
111  { "advanced", "Advanced deinterlace mode. ", 0, AV_OPT_TYPE_CONST, { .i64 = MFX_DEINTERLACING_ADVANCED }, .flags = FLAGS, "deinterlace" },
112 
113  { "denoise", "denoise level [0, 100]", OFFSET(denoise), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS },
114  { "detail", "enhancement level [0, 100]", OFFSET(detail), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, .flags = FLAGS },
115  { "framerate", "output framerate", OFFSET(framerate), AV_OPT_TYPE_RATIONAL, { .dbl = 0.0 },0, DBL_MAX, .flags = FLAGS },
116  { "procamp", "Enable ProcAmp", OFFSET(procamp), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS},
117  { "hue", "ProcAmp hue", OFFSET(hue), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, -180.0, 180.0, .flags = FLAGS},
118  { "saturation", "ProcAmp saturation", OFFSET(saturation), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
119  { "contrast", "ProcAmp contrast", OFFSET(contrast), AV_OPT_TYPE_FLOAT, { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
120  { "brightness", "ProcAmp brightness", OFFSET(brightness), AV_OPT_TYPE_FLOAT, { .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},
121 
122  { "transpose", "set transpose direction", OFFSET(transpose), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, FLAGS, "transpose"},
123  { "cclock_hflip", "rotate counter-clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
124  { "clock", "rotate clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK }, .flags=FLAGS, .unit = "transpose" },
125  { "cclock", "rotate counter-clockwise", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CCLOCK }, .flags=FLAGS, .unit = "transpose" },
126  { "clock_hflip", "rotate clockwise with horizontal flip", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_CLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
127  { "reversal", "rotate by half-turn", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_REVERSAL }, .flags=FLAGS, .unit = "transpose" },
128  { "hflip", "flip horizontally", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_HFLIP }, .flags=FLAGS, .unit = "transpose" },
129  { "vflip", "flip vertically", 0, AV_OPT_TYPE_CONST, { .i64 = TRANSPOSE_VFLIP }, .flags=FLAGS, .unit = "transpose" },
130 
131  { "cw", "set the width crop area expression", OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, 0, 0, FLAGS },
132  { "ch", "set the height crop area expression", OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, 0, 0, FLAGS },
133  { "cx", "set the x crop area expression", OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, 0, 0, FLAGS },
134  { "cy", "set the y crop area expression", OFFSET(cy), AV_OPT_TYPE_STRING, { .str = "(in_h-out_h)/2" }, 0, 0, FLAGS },
135 
136  { "w", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS },
137  { "width", "Output video width", OFFSET(ow), AV_OPT_TYPE_STRING, { .str="cw" }, 0, 255, .flags = FLAGS },
138  { "h", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
139  { "height", "Output video height", OFFSET(oh), AV_OPT_TYPE_STRING, { .str="w*ch/cw" }, 0, 255, .flags = FLAGS },
140  { "format", "Output pixel format", OFFSET(output_format_str), AV_OPT_TYPE_STRING, { .str = "same" }, .flags = FLAGS },
141  { "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 },
142  { "scale_mode", "scale mode: 0=auto, 1=low power, 2=high quality", OFFSET(scale_mode), AV_OPT_TYPE_INT, { .i64 = MFX_SCALING_MODE_DEFAULT }, MFX_SCALING_MODE_DEFAULT, MFX_SCALING_MODE_QUALITY, .flags = FLAGS, "scale mode" },
143 
144  { NULL }
145 };
146 
147 static const char *const var_names[] = {
148  "iw", "in_w",
149  "ih", "in_h",
150  "ow", "out_w", "w",
151  "oh", "out_h", "h",
152  "cw",
153  "ch",
154  "cx",
155  "cy",
156  NULL
157 };
158 
159 enum var_name {
164  CW,
165  CH,
166  CX,
167  CY,
169 };
170 
172 {
173 #define PASS_EXPR(e, s) {\
174  ret = av_expr_parse(&e, s, var_names, NULL, NULL, NULL, NULL, 0, ctx); \
175  if (ret < 0) {\
176  av_log(ctx, AV_LOG_ERROR, "Error when passing '%s'.\n", s);\
177  goto release;\
178  }\
179 }
180 #define CALC_EXPR(e, v, i) {\
181  i = v = av_expr_eval(e, var_values, NULL); \
182 }
183  VPPContext *vpp = ctx->priv;
184  double var_values[VAR_VARS_NB] = { NAN };
185  AVExpr *w_expr = NULL, *h_expr = NULL;
186  AVExpr *cw_expr = NULL, *ch_expr = NULL;
187  AVExpr *cx_expr = NULL, *cy_expr = NULL;
188  int ret = 0;
189 
190  PASS_EXPR(cw_expr, vpp->cw);
191  PASS_EXPR(ch_expr, vpp->ch);
192 
193  PASS_EXPR(w_expr, vpp->ow);
194  PASS_EXPR(h_expr, vpp->oh);
195 
196  PASS_EXPR(cx_expr, vpp->cx);
197  PASS_EXPR(cy_expr, vpp->cy);
198 
199  var_values[VAR_iW] =
200  var_values[VAR_IN_W] = ctx->inputs[0]->w;
201 
202  var_values[VAR_iH] =
203  var_values[VAR_IN_H] = ctx->inputs[0]->h;
204 
205  /* crop params */
206  CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w);
207  CALC_EXPR(ch_expr, var_values[CH], vpp->crop_h);
208 
209  /* calc again in case cw is relative to ch */
210  CALC_EXPR(cw_expr, var_values[CW], vpp->crop_w);
211 
212  CALC_EXPR(w_expr,
213  var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W],
214  vpp->out_width);
215  CALC_EXPR(h_expr,
216  var_values[VAR_OUT_H] = var_values[VAR_oH] = var_values[VAR_H],
217  vpp->out_height);
218 
219  /* calc again in case ow is relative to oh */
220  CALC_EXPR(w_expr,
221  var_values[VAR_OUT_W] = var_values[VAR_oW] = var_values[VAR_W],
222  vpp->out_width);
223 
224 
225  CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x);
226  CALC_EXPR(cy_expr, var_values[CY], vpp->crop_y);
227 
228  /* calc again in case cx is relative to cy */
229  CALC_EXPR(cx_expr, var_values[CX], vpp->crop_x);
230 
231  if ((vpp->crop_w != var_values[VAR_iW]) || (vpp->crop_h != var_values[VAR_iH]))
232  vpp->use_crop = 1;
233 
234 release:
235  av_expr_free(w_expr);
236  av_expr_free(h_expr);
237  av_expr_free(cw_expr);
238  av_expr_free(ch_expr);
239  av_expr_free(cx_expr);
240  av_expr_free(cy_expr);
241 #undef PASS_EXPR
242 #undef CALC_EXPR
243 
244  return ret;
245 }
246 
248 {
249  VPPContext *vpp = ctx->priv;
250 
251  if (!strcmp(vpp->output_format_str, "same")) {
253  } else {
255  if (vpp->out_format == AV_PIX_FMT_NONE) {
256  av_log(ctx, AV_LOG_ERROR, "Unrecognized output pixel format: %s\n", vpp->output_format_str);
257  return AVERROR(EINVAL);
258  }
259  }
260 
261  return 0;
262 }
263 
265 {
266  AVFilterContext *ctx = inlink->dst;
267  VPPContext *vpp = ctx->priv;
268  int ret;
269 
270  if (vpp->framerate.den == 0 || vpp->framerate.num == 0)
271  vpp->framerate = inlink->frame_rate;
272 
273  if (av_cmp_q(vpp->framerate, inlink->frame_rate))
274  vpp->use_frc = 1;
275 
276  ret = eval_expr(ctx);
277  if (ret != 0) {
278  av_log(ctx, AV_LOG_ERROR, "Fail to eval expr.\n");
279  return ret;
280  }
281 
282  if (vpp->out_height == 0 || vpp->out_width == 0) {
283  vpp->out_width = inlink->w;
284  vpp->out_height = inlink->h;
285  }
286 
287  if (vpp->use_crop) {
288  vpp->crop_x = FFMAX(vpp->crop_x, 0);
289  vpp->crop_y = FFMAX(vpp->crop_y, 0);
290 
291  if(vpp->crop_w + vpp->crop_x > inlink->w)
292  vpp->crop_x = inlink->w - vpp->crop_w;
293  if(vpp->crop_h + vpp->crop_y > inlink->h)
294  vpp->crop_y = inlink->h - vpp->crop_h;
295  }
296 
297  return 0;
298 }
299 
300 static int config_output(AVFilterLink *outlink)
301 {
302  AVFilterContext *ctx = outlink->src;
303  VPPContext *vpp = ctx->priv;
304  QSVVPPParam param = { NULL };
305  QSVVPPCrop crop = { 0 };
306  mfxExtBuffer *ext_buf[ENH_FILTERS_COUNT];
307  AVFilterLink *inlink = ctx->inputs[0];
308  enum AVPixelFormat in_format;
309 
310  outlink->w = vpp->out_width;
311  outlink->h = vpp->out_height;
312  outlink->frame_rate = vpp->framerate;
313  outlink->time_base = inlink->time_base;
314 
315  param.filter_frame = NULL;
316  param.num_ext_buf = 0;
317  param.ext_buf = ext_buf;
318  param.async_depth = vpp->async_depth;
319 
320  if (inlink->format == AV_PIX_FMT_QSV) {
321  if (!inlink->hw_frames_ctx || !inlink->hw_frames_ctx->data)
322  return AVERROR(EINVAL);
323  else
324  in_format = ((AVHWFramesContext*)inlink->hw_frames_ctx->data)->sw_format;
325  } else
326  in_format = inlink->format;
327 
328  if (vpp->out_format == AV_PIX_FMT_NONE)
329  vpp->out_format = in_format;
330  param.out_sw_format = vpp->out_format;
331 
332  if (vpp->use_crop) {
333  crop.in_idx = 0;
334  crop.x = vpp->crop_x;
335  crop.y = vpp->crop_y;
336  crop.w = vpp->crop_w;
337  crop.h = vpp->crop_h;
338 
339  param.num_crop = 1;
340  param.crop = &crop;
341  }
342 
343  if (vpp->deinterlace) {
344  memset(&vpp->deinterlace_conf, 0, sizeof(mfxExtVPPDeinterlacing));
345  vpp->deinterlace_conf.Header.BufferId = MFX_EXTBUFF_VPP_DEINTERLACING;
346  vpp->deinterlace_conf.Header.BufferSz = sizeof(mfxExtVPPDeinterlacing);
347  vpp->deinterlace_conf.Mode = vpp->deinterlace == 1 ?
348  MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED;
349 
350  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->deinterlace_conf;
351  }
352 
353  if (vpp->use_frc) {
354  memset(&vpp->frc_conf, 0, sizeof(mfxExtVPPFrameRateConversion));
355  vpp->frc_conf.Header.BufferId = MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION;
356  vpp->frc_conf.Header.BufferSz = sizeof(mfxExtVPPFrameRateConversion);
357  vpp->frc_conf.Algorithm = MFX_FRCALGM_DISTRIBUTED_TIMESTAMP;
358 
359  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->frc_conf;
360  }
361 
362  if (vpp->denoise) {
363  memset(&vpp->denoise_conf, 0, sizeof(mfxExtVPPDenoise));
364  vpp->denoise_conf.Header.BufferId = MFX_EXTBUFF_VPP_DENOISE;
365  vpp->denoise_conf.Header.BufferSz = sizeof(mfxExtVPPDenoise);
366  vpp->denoise_conf.DenoiseFactor = vpp->denoise;
367 
368  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->denoise_conf;
369  }
370 
371  if (vpp->detail) {
372  memset(&vpp->detail_conf, 0, sizeof(mfxExtVPPDetail));
373  vpp->detail_conf.Header.BufferId = MFX_EXTBUFF_VPP_DETAIL;
374  vpp->detail_conf.Header.BufferSz = sizeof(mfxExtVPPDetail);
375  vpp->detail_conf.DetailFactor = vpp->detail;
376 
377  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->detail_conf;
378  }
379 
380  if (vpp->procamp) {
381  memset(&vpp->procamp_conf, 0, sizeof(mfxExtVPPProcAmp));
382  vpp->procamp_conf.Header.BufferId = MFX_EXTBUFF_VPP_PROCAMP;
383  vpp->procamp_conf.Header.BufferSz = sizeof(mfxExtVPPProcAmp);
384  vpp->procamp_conf.Hue = vpp->hue;
385  vpp->procamp_conf.Saturation = vpp->saturation;
386  vpp->procamp_conf.Contrast = vpp->contrast;
387  vpp->procamp_conf.Brightness = vpp->brightness;
388 
389  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf;
390  }
391 
392  if (vpp->transpose >= 0) {
393 #ifdef QSV_HAVE_ROTATION
394  switch (vpp->transpose) {
396  vpp->rotate = MFX_ANGLE_270;
397  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
398  break;
399  case TRANSPOSE_CLOCK:
400  vpp->rotate = MFX_ANGLE_90;
401  vpp->hflip = MFX_MIRRORING_DISABLED;
402  break;
403  case TRANSPOSE_CCLOCK:
404  vpp->rotate = MFX_ANGLE_270;
405  vpp->hflip = MFX_MIRRORING_DISABLED;
406  break;
408  vpp->rotate = MFX_ANGLE_90;
409  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
410  break;
411  case TRANSPOSE_REVERSAL:
412  vpp->rotate = MFX_ANGLE_180;
413  vpp->hflip = MFX_MIRRORING_DISABLED;
414  break;
415  case TRANSPOSE_HFLIP:
416  vpp->rotate = MFX_ANGLE_0;
417  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
418  break;
419  case TRANSPOSE_VFLIP:
420  vpp->rotate = MFX_ANGLE_180;
421  vpp->hflip = MFX_MIRRORING_HORIZONTAL;
422  break;
423  default:
424  av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode to %d.\n", vpp->transpose);
425  return AVERROR(EINVAL);
426  }
427 #else
428  av_log(ctx, AV_LOG_WARNING, "The QSV VPP transpose option is "
429  "not supported with this MSDK version.\n");
430  vpp->transpose = 0;
431 #endif
432  }
433 
434  if (vpp->rotate) {
435 #ifdef QSV_HAVE_ROTATION
436  memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
437  vpp->rotation_conf.Header.BufferId = MFX_EXTBUFF_VPP_ROTATION;
438  vpp->rotation_conf.Header.BufferSz = sizeof(mfxExtVPPRotation);
439  vpp->rotation_conf.Angle = vpp->rotate;
440 
441  if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 == vpp->rotate) {
442  FFSWAP(int, vpp->out_width, vpp->out_height);
443  FFSWAP(int, outlink->w, outlink->h);
444  av_log(ctx, AV_LOG_DEBUG, "Swap width and height for clock/cclock rotation.\n");
445  }
446 
447  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->rotation_conf;
448 #else
449  av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
450  "not supported with this MSDK version.\n");
451  vpp->rotate = 0;
452 #endif
453  }
454 
455  if (vpp->hflip) {
456 #ifdef QSV_HAVE_MIRRORING
457  memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
458  vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
459  vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
460  vpp->mirroring_conf.Type = vpp->hflip;
461 
462  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->mirroring_conf;
463 #else
464  av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
465  "not supported with this MSDK version.\n");
466  vpp->hflip = 0;
467 #endif
468  }
469 
470  if (inlink->w != outlink->w || inlink->h != outlink->h) {
471 #ifdef QSV_HAVE_SCALING_CONFIG
472  memset(&vpp->scale_conf, 0, sizeof(mfxExtVPPScaling));
473  vpp->scale_conf.Header.BufferId = MFX_EXTBUFF_VPP_SCALING;
474  vpp->scale_conf.Header.BufferSz = sizeof(mfxExtVPPScaling);
475  vpp->scale_conf.ScalingMode = vpp->scale_mode;
476 
477  param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->scale_conf;
478 #else
479  av_log(ctx, AV_LOG_WARNING, "The QSV VPP Scale option is "
480  "not supported with this MSDK version.\n");
481 #endif
482  }
483 
484  if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise ||
485  vpp->detail || vpp->procamp || vpp->rotate || vpp->hflip ||
486  inlink->w != outlink->w || inlink->h != outlink->h || in_format != vpp->out_format)
487  return ff_qsvvpp_create(ctx, &vpp->qsv, &param);
488  else {
489  av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n");
490  if (inlink->hw_frames_ctx)
491  outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx);
492  }
493 
494  return 0;
495 }
496 
498 {
499  AVFilterLink *inlink = ctx->inputs[0];
500  AVFilterLink *outlink = ctx->outputs[0];
501  VPPContext *s =ctx->priv;
502  QSVVPPContext *qsv = s->qsv;
503  AVFrame *in = NULL;
504  int ret, status = 0;
505  int64_t pts = AV_NOPTS_VALUE;
506 
508 
509  if (!s->eof) {
511  if (ret < 0)
512  return ret;
513 
515  if (status == AVERROR_EOF) {
516  s->eof = 1;
517  }
518  }
519  }
520 
521  if (qsv) {
522  if (in || s->eof) {
523  qsv->eof = s->eof;
524  ret = ff_qsvvpp_filter_frame(qsv, inlink, in);
525  av_frame_free(&in);
526 
527  if (s->eof) {
528  ff_outlink_set_status(outlink, status, pts);
529  return 0;
530  }
531 
532  if (qsv->got_frame) {
533  qsv->got_frame = 0;
534  return ret;
535  }
536  }
537  } else {
538  if (in) {
539  if (in->pts != AV_NOPTS_VALUE)
540  in->pts = av_rescale_q(in->pts, inlink->time_base, outlink->time_base);
541 
542  ret = ff_filter_frame(outlink, in);
543  return ret;
544  }
545  }
546 
547  if (s->eof) {
548  ff_outlink_set_status(outlink, status, pts);
549  return 0;
550  } else {
552  }
553 
554  return FFERROR_NOT_READY;
555 }
556 
558 {
559  int ret;
560  static const enum AVPixelFormat in_pix_fmts[] = {
567  };
568  static const enum AVPixelFormat out_pix_fmts[] = {
573  };
574 
576  &ctx->inputs[0]->outcfg.formats);
577  if (ret < 0)
578  return ret;
580  &ctx->outputs[0]->incfg.formats);
581 }
582 
584 {
585  VPPContext *vpp = ctx->priv;
586 
587  ff_qsvvpp_free(&vpp->qsv);
588 }
589 
590 static const AVClass vpp_class = {
591  .class_name = "vpp_qsv",
592  .item_name = av_default_item_name,
593  .option = options,
594  .version = LIBAVUTIL_VERSION_INT,
595 };
596 
597 static const AVFilterPad vpp_inputs[] = {
598  {
599  .name = "default",
600  .type = AVMEDIA_TYPE_VIDEO,
601  .config_props = config_input,
602  },
603 };
604 
605 static const AVFilterPad vpp_outputs[] = {
606  {
607  .name = "default",
608  .type = AVMEDIA_TYPE_VIDEO,
609  .config_props = config_output,
610  },
611 };
612 
614  .name = "vpp_qsv",
615  .description = NULL_IF_CONFIG_SMALL("Quick Sync Video VPP."),
616  .priv_size = sizeof(VPPContext),
618  .init = vpp_init,
619  .uninit = vpp_uninit,
622  .activate = activate,
623  .priv_class = &vpp_class,
624  .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
625 };
VAR_oW
@ VAR_oW
Definition: vf_vpp_qsv.c:162
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:613
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:105
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:380
OFFSET
#define OFFSET(x)
Definition: vf_vpp_qsv.c:42
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:334
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:1019
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
VPPContext::cx
char * cx
Definition: vf_vpp_qsv.c:100
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:82
VPPContext::crop_h
int crop_h
Definition: vf_vpp_qsv.c:83
VPPContext::detail
int detail
Definition: vf_vpp_qsv.c:79
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::scale_mode
int scale_mode
Definition: vf_vpp_qsv.c:91
VPPContext::contrast
float contrast
Definition: vf_vpp_qsv.c:97
vpp_uninit
static av_cold void vpp_uninit(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:583
VPPContext::qsv
QSVVPPContext * qsv
Definition: vf_vpp_qsv.c:54
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:163
VPPContext::hue
float hue
Definition: vf_vpp_qsv.c:95
mathematics.h
CY
@ CY
Definition: vf_vpp_qsv.c:167
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
VAR_IN_H
@ VAR_IN_H
Definition: vf_vpp_qsv.c:161
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:153
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:1418
VAR_oH
@ VAR_oH
Definition: vf_vpp_qsv.c:163
VPPContext::saturation
float saturation
Definition: vf_vpp_qsv.c:96
qsvvpp.h
VAR_IN_W
@ VAR_IN_W
Definition: vf_vpp_qsv.c:160
VPPContext::transpose
int transpose
Definition: vf_vpp_qsv.c:87
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:73
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:50
VPPContext::out_width
int out_width
Definition: vf_vpp_qsv.c:68
FLAGS
#define FLAGS
Definition: vf_vpp_qsv.c:43
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:84
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
VPPContext::use_frc
int use_frc
Definition: vf_vpp_qsv.c:76
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:59
ff_qsvvpp_create
int ff_qsvvpp_create(AVFilterContext *avctx, QSVVPPContext **vpp, QSVVPPParam *param)
Definition: qsvvpp.c:655
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:548
filters.h
var_name
var_name
Definition: noise_bsf.c:47
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:497
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:60
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
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:152
options
static const AVOption options[]
Definition: vf_vpp_qsv.c:108
QSVVPPParam::async_depth
int async_depth
Definition: qsvvpp.h:99
VAR_iW
@ VAR_iW
Definition: vf_vpp_qsv.c:160
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:46
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:100
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:77
CALC_EXPR
#define CALC_EXPR(e, v, i)
VAR_H
@ VAR_H
Definition: vf_vpp_qsv.c:163
VPPContext::deinterlace_conf
mfxExtVPPDeinterlacing deinterlace_conf
Definition: vf_vpp_qsv.c:57
VPPContext::frc_conf
mfxExtVPPFrameRateConversion frc_conf
Definition: vf_vpp_qsv.c:58
vpp_inputs
static const AVFilterPad vpp_inputs[]
Definition: vf_vpp_qsv.c:597
VPPContext::denoise
int denoise
Definition: vf_vpp_qsv.c:78
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:51
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:1372
ff_qsvvpp_free
int ff_qsvvpp_free(QSVVPPContext **vpp)
Definition: qsvvpp.c:773
VPPContext::ow
char * ow
Definition: vf_vpp_qsv.c:101
VPPContext::hflip
int hflip
Definition: vf_vpp_qsv.c:89
VPPContext::scale_conf
mfxExtVPPScaling scale_conf
Definition: vf_vpp_qsv.c:65
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:557
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:162
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_vpp_qsv.c:264
VPPContext::rotate
int rotate
Definition: vf_vpp_qsv.c:88
VAR_iH
@ VAR_iH
Definition: vf_vpp_qsv.c:161
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:162
VPPContext::output_format_str
char * output_format_str
Definition: vf_vpp_qsv.c:102
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_vpp_qsv.c:168
VPPContext::ch
char * ch
Definition: vf_vpp_qsv.c:100
VPPContext::procamp_conf
mfxExtVPPProcAmp procamp_conf
Definition: vf_vpp_qsv.c:61
CH
@ CH
Definition: vf_vpp_qsv.c:165
AV_PIX_FMT_RGB32
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:364
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:300
VPPContext::rotation_conf
mfxExtVPPRotation rotation_conf
Definition: vf_vpp_qsv.c:62
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:85
VPPContext::framerate
AVRational framerate
Definition: vf_vpp_qsv.c:75
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
VPPContext::out_height
int out_height
Definition: vf_vpp_qsv.c:69
vpp_init
static av_cold int vpp_init(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:247
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:149
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:104
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
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
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:2496
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:101
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:798
eval_expr
static int eval_expr(AVFilterContext *ctx)
Definition: vf_vpp_qsv.c:171
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:590
VPPContext::use_crop
int use_crop
Definition: vf_vpp_qsv.c:81
transpose.h
TRANSPOSE_REVERSAL
@ TRANSPOSE_REVERSAL
Definition: transpose.h:35
VPPContext::cy
char * cy
Definition: vf_vpp_qsv.c:100
AVFilterContext
An instance of a filter.
Definition: avfilter.h:346
TRANSPOSE_VFLIP
@ TRANSPOSE_VFLIP
Definition: transpose.h:37
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:440
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
var_names
static const char *const var_names[]
Definition: vf_vpp_qsv.c:147
CW
@ CW
Definition: vf_vpp_qsv.c:164
VPPContext::mirroring_conf
mfxExtVPPMirroring mirroring_conf
Definition: vf_vpp_qsv.c:63
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:153
CX
@ CX
Definition: vf_vpp_qsv.c:166
hwcontext.h
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:98
VPPContext::procamp
int procamp
Definition: vf_vpp_qsv.c:94
QSVVPPParam::ext_buf
mfxExtBuffer ** ext_buf
Definition: qsvvpp.h:90
vpp_outputs
static const AVFilterPad vpp_outputs[]
Definition: vf_vpp_qsv.c:605