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 
95 AVFILTER_DEFINE_CLASS(perspective);
96 
98 {
99  static const enum AVPixelFormat pix_fmts[] = {
104  };
105 
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;
238  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
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 {
274  uint8_t *dst;
275  int dst_linesize;
276  uint8_t *src;
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) {
460  return AVERROR(ENOMEM);
461  }
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 
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,
523  .priv_class = &perspective_class,
525 };
get_coeff
static double get_coeff(double d)
Definition: vf_perspective.c:112
ff_get_video_buffer
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
PerspectiveContext::sense
int sense
Definition: vf_perspective.c:50
ThreadData::hsub
int hsub
Definition: vf_perspective.c:279
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_perspective.c:129
PerspectiveContext::coeff
int32_t coeff[SUB_PIXELS][4]
Definition: vf_perspective.c:44
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
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
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
out
FILE * out
Definition: movenc.c:54
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
PerspectiveContext::height
int height[4]
Definition: vf_perspective.c:47
PerspectiveContext::expr_str
char * expr_str[4][2]
Definition: vf_perspective.c:41
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2541
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
PerspectiveContext::interpolation
int interpolation
Definition: vf_perspective.c:45
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
PerspectiveContext::perspective
int(* perspective)(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_perspective.c:53
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
pixdesc.h
index
fg index
Definition: ffmpeg_filter.c:168
EVAL_MODE_FRAME
@ EVAL_MODE_FRAME
Definition: vf_perspective.c:67
w
uint8_t w
Definition: llviddspenc.c:39
calc_persp_luts
static int calc_persp_luts(AVFilterContext *ctx, AVFilterLink *inlink)
Definition: vf_perspective.c:131
AVOption
AVOption.
Definition: opt.h:248
t0
#define t0
Definition: regdef.h:28
b
#define b
Definition: input.c:41
PerspectiveContext::nb_planes
int nb_planes
Definition: vf_perspective.c:49
PERSPECTIVESense
PERSPECTIVESense
Definition: vf_perspective.c:60
t1
#define t1
Definition: regdef.h:29
ThreadData::w
int w
Definition: vf_blend.c:59
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:149
VAR_IN
@ VAR_IN
Definition: vf_perspective.c:129
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1555
PERSPECTIVE_SENSE_SOURCE
@ PERSPECTIVE_SENSE_SOURCE
coordinates give locations in source of corners of destination.
Definition: vf_perspective.c:61
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:75
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:65
VAR_W
@ VAR_W
Definition: vf_perspective.c:129
formats.h
A
#define A(x)
Definition: vp56_arith.h:28
VAR_ON
@ VAR_ON
Definition: vf_perspective.c:129
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2581
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:205
PerspectiveContext::ref
double ref[4][2]
Definition: vf_perspective.c:42
COEFF_BITS
#define COEFF_BITS
Definition: vf_perspective.c:34
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
AV_PIX_FMT_YUVJ411P
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:248
EVAL_MODE_NB
@ EVAL_MODE_NB
Definition: vf_perspective.c:68
avassert.h
lrint
#define lrint
Definition: tablegen.h:53
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
ff_set_common_formats
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:580
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_perspective.c:436
SUB_PIXEL_BITS
#define SUB_PIXEL_BITS
Definition: vf_perspective.c:32
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
resample_linear
static int resample_linear(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_perspective.c:361
av_image_fill_linesizes
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
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
PerspectiveContext::linesize
int linesize[4]
Definition: vf_perspective.c:46
LINEAR
#define LINEAR
Definition: vf_perspective.c:36
ThreadData::src
uint8_t * src
Definition: vf_perspective.c:276
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:290
ctx
AVFormatContext * ctx
Definition: movenc.c:48
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
ThreadData::h
int h
Definition: vf_blend.c:59
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
arg
const char * arg
Definition: jacosubdec.c:67
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
perspective_options
static const AVOption perspective_options[]
Definition: vf_perspective.c:71
perspective_inputs
static const AVFilterPad perspective_inputs[]
Definition: vf_perspective.c:496
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:536
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
src
#define src
Definition: vp8dsp.c:255
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
c
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
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
av_expr_parse_and_eval
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:776
OFFSET
#define OFFSET(x)
Definition: vf_perspective.c:57
ff_vf_perspective
const AVFilter ff_vf_perspective
Definition: vf_perspective.c:514
perspective_outputs
static const AVFilterPad perspective_outputs[]
Definition: vf_perspective.c:506
PERSPECTIVE_SENSE_DESTINATION
@ PERSPECTIVE_SENSE_DESTINATION
coordinates give locations in destination of corners of source.
Definition: vf_perspective.c:62
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(perspective)
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
a
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:41
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:167
interpolation
static int interpolation(DeclickChannel *c, const double *src, int ar_order, double *acoefficients, int *index, int nb_errors, double *auxiliary, double *interpolated)
Definition: af_adeclick.c:365
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#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:126
i
int i
Definition: input.c:407
t3
#define t3
Definition: regdef.h:31
ThreadData::dst
uint8_t * dst
Definition: vf_perspective.c:274
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:762
ThreadData
Used for passing data between threads.
Definition: dsddec.c:67
EvalMode
EvalMode
Definition: af_volume.h:39
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_perspective.c:228
AV_PIX_FMT_YUVJ440P
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition: pixfmt.h:100
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_perspective.c:489
AVFilter
Filter definition.
Definition: avfilter.h:145
ret
ret
Definition: filter_design.txt:187
frame
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
Definition: filter_design.txt:264
PerspectiveContext
Definition: vf_perspective.c:39
ThreadData::vsub
int vsub
Definition: vf_perspective.c:279
EVAL_MODE_INIT
@ EVAL_MODE_INIT
Definition: vf_perspective.c:66
PerspectiveContext::vsub
int vsub
Definition: vf_perspective.c:48
ThreadData::src_linesize
int src_linesize
Definition: vf_bm3d.c:57
resample_cubic
static int resample_cubic(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
Definition: vf_perspective.c:282
t2
#define t2
Definition: regdef.h:30
PerspectiveContext::hsub
int hsub
Definition: vf_perspective.c:48
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
var_names
static const char *const var_names[]
Definition: vf_perspective.c:128
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_perspective.c:97
values
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
Definition: filter_design.txt:263
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
temp
else temp
Definition: vf_mcdeint.c:259
SUB_PIXELS
#define SUB_PIXELS
Definition: vf_perspective.c:33
av_clip_uint8
#define av_clip_uint8
Definition: common.h:128
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:333
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
desc
const char * desc
Definition: libsvtav1.c:79
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
ThreadData::dst_linesize
int dst_linesize
Definition: vf_colorlevels.c:99
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:70
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
PerspectiveContext::eval_mode
int eval_mode
Definition: vf_perspective.c:51
d
d
Definition: ffmpeg_filter.c:156
int32_t
int32_t
Definition: audioconvert.c:56
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:73
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: vf_perspective.c:448
h
h
Definition: vp9dsp_template.c:2038
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
int
int
Definition: ffmpeg_filter.c:156
PerspectiveContext::pv
int32_t(* pv)[2]
Definition: vf_perspective.c:43
FLAGS
#define FLAGS
Definition: vf_perspective.c:58
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:166
VAR_H
@ VAR_H
Definition: vf_perspective.c:129
CUBIC
#define CUBIC
Definition: vf_perspective.c:37