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