FFmpeg
vf_perspective.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (c) 2013 Paul B Mahol
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/avassert.h"
23 #include "libavutil/eval.h"
24 #include "libavutil/imgutils.h"
25 #include "libavutil/pixdesc.h"
26 #include "libavutil/opt.h"
27 #include "avfilter.h"
28 #include "formats.h"
29 #include "internal.h"
30 #include "video.h"
31 
32 #define SUB_PIXEL_BITS 8
33 #define SUB_PIXELS (1 << SUB_PIXEL_BITS)
34 #define COEFF_BITS 11
35 
36 #define LINEAR 0
37 #define CUBIC 1
38 
39 typedef struct PerspectiveContext {
40  const AVClass *class;
41  char *expr_str[4][2];
42  double ref[4][2];
43  int32_t (*pv)[2];
46  int linesize[4];
47  int height[4];
48  int hsub, vsub;
49  int nb_planes;
50  int sense;
51  int eval_mode;
52 
54  void *arg, int job, int nb_jobs);
56 
57 #define OFFSET(x) offsetof(PerspectiveContext, x)
58 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
59 
61  PERSPECTIVE_SENSE_SOURCE = 0, ///< coordinates give locations in source of corners of destination.
62  PERSPECTIVE_SENSE_DESTINATION = 1, ///< coordinates give locations in destination of corners of source.
63 };
64 
65 enum EvalMode {
69 };
70 
71 static const AVOption perspective_options[] = {
72  { "x0", "set top left x coordinate", OFFSET(expr_str[0][0]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
73  { "y0", "set top left y coordinate", OFFSET(expr_str[0][1]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
74  { "x1", "set top right x coordinate", OFFSET(expr_str[1][0]), AV_OPT_TYPE_STRING, {.str="W"}, 0, 0, FLAGS },
75  { "y1", "set top right y coordinate", OFFSET(expr_str[1][1]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
76  { "x2", "set bottom left x coordinate", OFFSET(expr_str[2][0]), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, FLAGS },
77  { "y2", "set bottom left y coordinate", OFFSET(expr_str[2][1]), AV_OPT_TYPE_STRING, {.str="H"}, 0, 0, FLAGS },
78  { "x3", "set bottom right x coordinate", OFFSET(expr_str[3][0]), AV_OPT_TYPE_STRING, {.str="W"}, 0, 0, FLAGS },
79  { "y3", "set bottom right y coordinate", OFFSET(expr_str[3][1]), AV_OPT_TYPE_STRING, {.str="H"}, 0, 0, FLAGS },
80  { "interpolation", "set interpolation", OFFSET(interpolation), AV_OPT_TYPE_INT, {.i64=LINEAR}, 0, 1, FLAGS, "interpolation" },
81  { "linear", "", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, FLAGS, "interpolation" },
82  { "cubic", "", 0, AV_OPT_TYPE_CONST, {.i64=CUBIC}, 0, 0, FLAGS, "interpolation" },
83  { "sense", "specify the sense of the coordinates", OFFSET(sense), AV_OPT_TYPE_INT, {.i64=PERSPECTIVE_SENSE_SOURCE}, 0, 1, FLAGS, "sense"},
84  { "source", "specify locations in source to send to corners in destination",
85  0, AV_OPT_TYPE_CONST, {.i64=PERSPECTIVE_SENSE_SOURCE}, 0, 0, FLAGS, "sense"},
86  { "destination", "specify locations in destination to send corners of source",
87  0, AV_OPT_TYPE_CONST, {.i64=PERSPECTIVE_SENSE_DESTINATION}, 0, 0, FLAGS, "sense"},
88  { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
89  { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
90  { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
91 
92  { NULL }
93 };
94 
96 
98 {
99  static const enum AVPixelFormat pix_fmts[] = {
104  };
105 
106  AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
107  if (!fmts_list)
108  return AVERROR(ENOMEM);
109  return ff_set_common_formats(ctx, fmts_list);
110 }
111 
112 static inline double get_coeff(double d)
113 {
114  double coeff, A = -0.60;
115 
116  d = fabs(d);
117 
118  if (d < 1.0)
119  coeff = (1.0 - (A + 3.0) * d * d + (A + 2.0) * d * d * d);
120  else if (d < 2.0)
121  coeff = (-4.0 * A + 8.0 * A * d - 5.0 * A * d * d + A * d * d * d);
122  else
123  coeff = 0.0;
124 
125  return coeff;
126 }
127 
128 static const char *const var_names[] = { "W", "H", "in", "on", NULL };
130 
132 {
133  PerspectiveContext *s = ctx->priv;
134  AVFilterLink *outlink = ctx->outputs[0];
135  double (*ref)[2] = s->ref;
136 
137  double values[VAR_VARS_NB] = { [VAR_W] = inlink->w, [VAR_H] = inlink->h,
138  [VAR_IN] = inlink->frame_count_out + 1,
139  [VAR_ON] = outlink->frame_count_in + 1 };
140  const int h = values[VAR_H];
141  const int w = values[VAR_W];
142  double x0, x1, x2, x3, x4, x5, x6, x7, x8, q;
143  double t0, t1, t2, t3;
144  int x, y, i, j, ret;
145 
146  for (i = 0; i < 4; i++) {
147  for (j = 0; j < 2; j++) {
148  if (!s->expr_str[i][j])
149  return AVERROR(EINVAL);
150  ret = av_expr_parse_and_eval(&s->ref[i][j], s->expr_str[i][j],
151  var_names, &values[0],
152  NULL, NULL, NULL, NULL,
153  0, 0, ctx);
154  if (ret < 0)
155  return ret;
156  }
157  }
158 
159  switch (s->sense) {
161  x6 = ((ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
162  (ref[2][1] - ref[3][1]) -
163  ( ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
164  (ref[2][0] - ref[3][0])) * h;
165  x7 = ((ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1]) *
166  (ref[1][0] - ref[3][0]) -
167  ( ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0]) *
168  (ref[1][1] - ref[3][1])) * w;
169  q = ( ref[1][0] - ref[3][0]) * (ref[2][1] - ref[3][1]) -
170  ( ref[2][0] - ref[3][0]) * (ref[1][1] - ref[3][1]);
171 
172  x0 = q * (ref[1][0] - ref[0][0]) * h + x6 * ref[1][0];
173  x1 = q * (ref[2][0] - ref[0][0]) * w + x7 * ref[2][0];
174  x2 = q * ref[0][0] * w * h;
175  x3 = q * (ref[1][1] - ref[0][1]) * h + x6 * ref[1][1];
176  x4 = q * (ref[2][1] - ref[0][1]) * w + x7 * ref[2][1];
177  x5 = q * ref[0][1] * w * h;
178  x8 = q * w * h;
179  break;
181  t0 = ref[0][0] * (ref[3][1] - ref[1][1]) +
182  ref[1][0] * (ref[0][1] - ref[3][1]) +
183  ref[3][0] * (ref[1][1] - ref[0][1]);
184  t1 = ref[1][0] * (ref[2][1] - ref[3][1]) +
185  ref[2][0] * (ref[3][1] - ref[1][1]) +
186  ref[3][0] * (ref[1][1] - ref[2][1]);
187  t2 = ref[0][0] * (ref[3][1] - ref[2][1]) +
188  ref[2][0] * (ref[0][1] - ref[3][1]) +
189  ref[3][0] * (ref[2][1] - ref[0][1]);
190  t3 = ref[0][0] * (ref[1][1] - ref[2][1]) +
191  ref[1][0] * (ref[2][1] - ref[0][1]) +
192  ref[2][0] * (ref[0][1] - ref[1][1]);
193 
194  x0 = t0 * t1 * w * (ref[2][1] - ref[0][1]);
195  x1 = t0 * t1 * w * (ref[0][0] - ref[2][0]);
196  x2 = t0 * t1 * w * (ref[0][1] * ref[2][0] - ref[0][0] * ref[2][1]);
197  x3 = t1 * t2 * h * (ref[1][1] - ref[0][1]);
198  x4 = t1 * t2 * h * (ref[0][0] - ref[1][0]);
199  x5 = t1 * t2 * h * (ref[0][1] * ref[1][0] - ref[0][0] * ref[1][1]);
200  x6 = t1 * t2 * (ref[1][1] - ref[0][1]) +
201  t0 * t3 * (ref[2][1] - ref[3][1]);
202  x7 = t1 * t2 * (ref[0][0] - ref[1][0]) +
203  t0 * t3 * (ref[3][0] - ref[2][0]);
204  x8 = t1 * t2 * (ref[0][1] * ref[1][0] - ref[0][0] * ref[1][1]) +
205  t0 * t3 * (ref[2][0] * ref[3][1] - ref[2][1] * ref[3][0]);
206  break;
207  default:
208  av_assert0(0);
209  }
210 
211  for (y = 0; y < h; y++){
212  for (x = 0; x < w; x++){
213  int u, v;
214 
215  u = lrint(SUB_PIXELS * (x0 * x + x1 * y + x2) /
216  (x6 * x + x7 * y + x8));
217  v = lrint(SUB_PIXELS * (x3 * x + x4 * y + x5) /
218  (x6 * x + x7 * y + x8));
219 
220  s->pv[x + y * w][0] = u;
221  s->pv[x + y * w][1] = v;
222  }
223  }
224 
225  return 0;
226 }
227 
229 {
230  AVFilterContext *ctx = inlink->dst;
231  PerspectiveContext *s = ctx->priv;
233  int h = inlink->h;
234  int w = inlink->w;
235  int i, j, ret;
236  s->hsub = desc->log2_chroma_w;
237  s->vsub = desc->log2_chroma_h;
239  if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0)
240  return ret;
241 
242  s->height[1] = s->height[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
243  s->height[0] = s->height[3] = inlink->h;
244 
245  s->pv = av_realloc_f(s->pv, w * h, 2 * sizeof(*s->pv));
246  if (!s->pv)
247  return AVERROR(ENOMEM);
248 
249  if (s->eval_mode == EVAL_MODE_INIT) {
250  if ((ret = calc_persp_luts(ctx, inlink)) < 0) {
251  return ret;
252  }
253  }
254 
255  for (i = 0; i < SUB_PIXELS; i++){
256  double d = i / (double)SUB_PIXELS;
257  double temp[4];
258  double sum = 0;
259 
260  for (j = 0; j < 4; j++)
261  temp[j] = get_coeff(j - d - 1);
262 
263  for (j = 0; j < 4; j++)
264  sum += temp[j];
265 
266  for (j = 0; j < 4; j++)
267  s->coeff[i][j] = lrint((1 << COEFF_BITS) * temp[j] / sum);
268  }
269 
270  return 0;
271 }
272 
273 typedef struct ThreadData {
277  int src_linesize;
278  int w, h;
279  int hsub, vsub;
280 } ThreadData;
281 
283  int job, int nb_jobs)
284 {
285  PerspectiveContext *s = ctx->priv;
286  ThreadData *td = arg;
287  uint8_t *dst = td->dst;
288  int dst_linesize = td->dst_linesize;
289  uint8_t *src = td->src;
290  int src_linesize = td->src_linesize;
291  int w = td->w;
292  int h = td->h;
293  int hsub = td->hsub;
294  int vsub = td->vsub;
295  int start = (h * job) / nb_jobs;
296  int end = (h * (job+1)) / nb_jobs;
297  const int linesize = s->linesize[0];
298  int x, y;
299 
300  for (y = start; y < end; y++) {
301  int sy = y << vsub;
302  for (x = 0; x < w; x++) {
303  int u, v, subU, subV, sum, sx;
304 
305  sx = x << hsub;
306  u = s->pv[sx + sy * linesize][0] >> hsub;
307  v = s->pv[sx + sy * linesize][1] >> vsub;
308  subU = u & (SUB_PIXELS - 1);
309  subV = v & (SUB_PIXELS - 1);
310  u >>= SUB_PIXEL_BITS;
311  v >>= SUB_PIXEL_BITS;
312 
313  if (u > 0 && v > 0 && u < w - 2 && v < h - 2){
314  const int index = u + v*src_linesize;
315  const int a = s->coeff[subU][0];
316  const int b = s->coeff[subU][1];
317  const int c = s->coeff[subU][2];
318  const int d = s->coeff[subU][3];
319 
320  sum = s->coeff[subV][0] * (a * src[index - 1 - src_linesize] + b * src[index - 0 - src_linesize] +
321  c * src[index + 1 - src_linesize] + d * src[index + 2 - src_linesize]) +
322  s->coeff[subV][1] * (a * src[index - 1 ] + b * src[index - 0 ] +
323  c * src[index + 1 ] + d * src[index + 2 ]) +
324  s->coeff[subV][2] * (a * src[index - 1 + src_linesize] + b * src[index - 0 + src_linesize] +
325  c * src[index + 1 + src_linesize] + d * src[index + 2 + src_linesize]) +
326  s->coeff[subV][3] * (a * src[index - 1 + 2 * src_linesize] + b * src[index - 0 + 2 * src_linesize] +
327  c * src[index + 1 + 2 * src_linesize] + d * src[index + 2 + 2 * src_linesize]);
328  } else {
329  int dx, dy;
330 
331  sum = 0;
332 
333  for (dy = 0; dy < 4; dy++) {
334  int iy = v + dy - 1;
335 
336  if (iy < 0)
337  iy = 0;
338  else if (iy >= h)
339  iy = h-1;
340  for (dx = 0; dx < 4; dx++) {
341  int ix = u + dx - 1;
342 
343  if (ix < 0)
344  ix = 0;
345  else if (ix >= w)
346  ix = w - 1;
347 
348  sum += s->coeff[subU][dx] * s->coeff[subV][dy] * src[ ix + iy * src_linesize];
349  }
350  }
351  }
352 
353  sum = (sum + (1<<(COEFF_BITS * 2 - 1))) >> (COEFF_BITS * 2);
354  sum = av_clip_uint8(sum);
355  dst[x + y * dst_linesize] = sum;
356  }
357  }
358  return 0;
359 }
360 
362  int job, int nb_jobs)
363 {
364  PerspectiveContext *s = ctx->priv;
365  ThreadData *td = arg;
366  uint8_t *dst = td->dst;
367  int dst_linesize = td->dst_linesize;
368  uint8_t *src = td->src;
369  int src_linesize = td->src_linesize;
370  int w = td->w;
371  int h = td->h;
372  int hsub = td->hsub;
373  int vsub = td->vsub;
374  int start = (h * job) / nb_jobs;
375  int end = (h * (job+1)) / nb_jobs;
376  const int linesize = s->linesize[0];
377  int x, y;
378 
379  for (y = start; y < end; y++){
380  int sy = y << vsub;
381  for (x = 0; x < w; x++){
382  int u, v, subU, subV, sum, sx, index, subUI, subVI;
383 
384  sx = x << hsub;
385  u = s->pv[sx + sy * linesize][0] >> hsub;
386  v = s->pv[sx + sy * linesize][1] >> vsub;
387  subU = u & (SUB_PIXELS - 1);
388  subV = v & (SUB_PIXELS - 1);
389  u >>= SUB_PIXEL_BITS;
390  v >>= SUB_PIXEL_BITS;
391 
392  index = u + v * src_linesize;
393  subUI = SUB_PIXELS - subU;
394  subVI = SUB_PIXELS - subV;
395 
396  if ((unsigned)u < (unsigned)(w - 1)){
397  if((unsigned)v < (unsigned)(h - 1)){
398  sum = subVI * (subUI * src[index] + subU * src[index + 1]) +
399  subV * (subUI * src[index + src_linesize] + subU * src[index + src_linesize + 1]);
400  sum = (sum + (1 << (SUB_PIXEL_BITS * 2 - 1)))>> (SUB_PIXEL_BITS * 2);
401  } else {
402  if (v < 0)
403  v = 0;
404  else
405  v = h - 1;
406  index = u + v * src_linesize;
407  sum = subUI * src[index] + subU * src[index + 1];
408  sum = (sum + (1 << (SUB_PIXEL_BITS - 1))) >> SUB_PIXEL_BITS;
409  }
410  } else {
411  if (u < 0)
412  u = 0;
413  else
414  u = w - 1;
415  if ((unsigned)v < (unsigned)(h - 1)){
416  index = u + v * src_linesize;
417  sum = subVI * src[index] + subV * src[index + src_linesize];
418  sum = (sum + (1 << (SUB_PIXEL_BITS - 1))) >> SUB_PIXEL_BITS;
419  } else {
420  if (v < 0)
421  v = 0;
422  else
423  v = h - 1;
424  index = u + v * src_linesize;
425  sum = src[index];
426  }
427  }
428 
429  sum = av_clip_uint8(sum);
430  dst[x + y * dst_linesize] = sum;
431  }
432  }
433  return 0;
434 }
435 
437 {
438  PerspectiveContext *s = ctx->priv;
439 
440  switch (s->interpolation) {
441  case LINEAR: s->perspective = resample_linear; break;
442  case CUBIC: s->perspective = resample_cubic; break;
443  }
444 
445  return 0;
446 }
447 
449 {
450  AVFilterContext *ctx = inlink->dst;
451  AVFilterLink *outlink = ctx->outputs[0];
452  PerspectiveContext *s = ctx->priv;
453  AVFrame *out;
454  int plane;
455  int ret;
456 
457  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
458  if (!out) {
459  av_frame_free(&frame);
460  return AVERROR(ENOMEM);
461  }
462  av_frame_copy_props(out, frame);
463 
464  if (s->eval_mode == EVAL_MODE_FRAME) {
465  if ((ret = calc_persp_luts(ctx, inlink)) < 0) {
466  av_frame_free(&out);
467  return ret;
468  }
469  }
470 
471  for (plane = 0; plane < s->nb_planes; plane++) {
472  int hsub = plane == 1 || plane == 2 ? s->hsub : 0;
473  int vsub = plane == 1 || plane == 2 ? s->vsub : 0;
474  ThreadData td = {.dst = out->data[plane],
475  .dst_linesize = out->linesize[plane],
476  .src = frame->data[plane],
477  .src_linesize = frame->linesize[plane],
478  .w = s->linesize[plane],
479  .h = s->height[plane],
480  .hsub = hsub,
481  .vsub = vsub };
482  ctx->internal->execute(ctx, s->perspective, &td, NULL, FFMIN(td.h, ff_filter_get_nb_threads(ctx)));
483  }
484 
485  av_frame_free(&frame);
486  return ff_filter_frame(outlink, out);
487 }
488 
490 {
491  PerspectiveContext *s = ctx->priv;
492 
493  av_freep(&s->pv);
494 }
495 
496 static const AVFilterPad perspective_inputs[] = {
497  {
498  .name = "default",
499  .type = AVMEDIA_TYPE_VIDEO,
500  .filter_frame = filter_frame,
501  .config_props = config_input,
502  },
503  { NULL }
504 };
505 
507  {
508  .name = "default",
509  .type = AVMEDIA_TYPE_VIDEO,
510  },
511  { NULL }
512 };
513 
515  .name = "perspective",
516  .description = NULL_IF_CONFIG_SMALL("Correct the perspective of video."),
517  .priv_size = sizeof(PerspectiveContext),
518  .init = init,
519  .uninit = uninit,
521  .inputs = perspective_inputs,
522  .outputs = perspective_outputs,
523  .priv_class = &perspective_class,
525 };
int plane
Definition: avisynth_c.h:384
#define NULL
Definition: coverity.c:32
static int resample_linear(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
double ref[4][2]
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
#define av_realloc_f(p, o, n)
AVOption.
Definition: opt.h:246
int(* perspective)(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
misc image utilities
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2562
Main libavfilter public API header.
else temp
Definition: vf_mcdeint.c:256
const char * desc
Definition: nvenc.c:68
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
AVFILTER_DEFINE_CLASS(perspective)
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
static int resample_cubic(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
#define COEFF_BITS
coordinates give locations in destination of corners of source.
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:99
static int query_formats(AVFilterContext *ctx)
#define src
Definition: vp8dsp.c:254
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:92
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:125
static int config_input(AVFilterLink *inlink)
const char * name
Pad name.
Definition: internal.h:60
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
uint8_t * src
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
static av_cold void uninit(AVFilterContext *ctx)
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
uint8_t
#define av_cold
Definition: attributes.h:82
int32_t coeff[SUB_PIXELS][4]
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
#define t0
Definition: regdef.h:28
AVFrame * dst
Definition: vf_blend.c:55
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range...
Definition: pixfmt.h:100
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
static const AVFilterPad perspective_inputs[]
#define A(x)
Definition: vp56_arith.h:28
A filter pad used for either input or output.
Definition: internal.h:54
int32_t(* pv)[2]
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition: eval.c:744
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
#define td
Definition: regdef.h:70
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
#define t1
Definition: regdef.h:29
const char * arg
Definition: jacosubdec.c:66
simple assert() macros that are a bit more flexible than ISO C assert().
#define t3
Definition: regdef.h:31
#define FLAGS
const uint8_t * src
Definition: vf_bm3d.c:56
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
PERSPECTIVESense
#define b
Definition: input.c:41
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
#define FFMIN(a, b)
Definition: common.h:96
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
uint8_t w
Definition: llviddspenc.c:38
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 the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return values
#define SUB_PIXELS
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
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 the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
#define s(width, name)
Definition: cbs_vp9.c:257
EvalMode
Definition: af_volume.h:39
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
static int calc_persp_luts(AVFilterContext *ctx, AVFilterLink *inlink)
coordinates give locations in source of corners of destination.
Used for passing data between threads.
Definition: af_adeclick.c:487
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
#define SUB_PIXEL_BITS
char * expr_str[4][2]
#define CUBIC
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
#define LINEAR
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
Fill plane linesizes for an image with pixel format pix_fmt and width width.
Definition: imgutils.c:89
int index
Definition: gxfenc.c:89
static const char *const var_names[]
#define OFFSET(x)
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
uint8_t * dst
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
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
int
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
Y , 8bpp.
Definition: pixfmt.h:74
static av_cold int init(AVFilterContext *ctx)
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
avfilter_execute_func * execute
Definition: internal.h:155
static double get_coeff(double d)
AVFilter ff_vf_perspective
A list of supported formats for one end of a filter link.
Definition: formats.h:64
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:258
#define lrint
Definition: tablegen.h:53
An instance of a filter.
Definition: avfilter.h:338
FILE * out
Definition: movenc.c:54
#define av_freep(p)
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
static const AVFilterPad perspective_outputs[]
void INT64 start
Definition: avisynth_c.h:766
static const AVOption perspective_options[]
internal API functions
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int src_linesize
Definition: vf_bm3d.c:57
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:654
#define t2
Definition: regdef.h:30
simple arithmetic expression evaluator
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58