FFmpeg
vf_cropdetect.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002 A'rpi
3  * This file is part of FFmpeg.
4  *
5  * FFmpeg is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * FFmpeg is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 /**
21  * @file
22  * border detection filter
23  * Ported from MPlayer libmpcodecs/vf_cropdetect.c.
24  */
25 
26 #include "libavutil/imgutils.h"
27 #include "libavutil/internal.h"
28 #include "libavutil/opt.h"
30 #include "libavutil/qsort.h"
31 
32 #include "avfilter.h"
33 #include "internal.h"
34 #include "video.h"
35 #include "edge_common.h"
36 
37 typedef struct CropDetectContext {
38  const AVClass *class;
39  int x1, y1, x2, y2;
40  float limit;
42  int round;
43  int skip;
45  int frame_nb;
46  int max_pixsteps[4];
48  int mode;
51  int bitdepth;
52  float low, high;
53  uint8_t low_u8, high_u8;
54  uint8_t *filterbuf;
55  uint8_t *tmpbuf;
56  uint16_t *gradients;
57  char *directions;
58  int *bboxes[4];
60 
61 static const enum AVPixelFormat pix_fmts[] = {
76 };
77 
78 enum CropMode {
82 };
83 
84 static int comp(const int *a,const int *b)
85 {
86  return FFDIFFSIGN(*a, *b);
87 }
88 
89 static int checkline(void *ctx, const unsigned char *src, int stride, int len, int bpp)
90 {
91  int total = 0;
92  int div = len;
93  const uint16_t *src16 = (const uint16_t *)src;
94 
95  switch (bpp) {
96  case 1:
97  while (len >= 8) {
98  total += src[ 0] + src[ stride] + src[2*stride] + src[3*stride]
99  + src[4*stride] + src[5*stride] + src[6*stride] + src[7*stride];
100  src += 8*stride;
101  len -= 8;
102  }
103  while (--len >= 0) {
104  total += src[0];
105  src += stride;
106  }
107  break;
108  case 2:
109  stride >>= 1;
110  while (len >= 8) {
111  total += src16[ 0] + src16[ stride] + src16[2*stride] + src16[3*stride]
112  + src16[4*stride] + src16[5*stride] + src16[6*stride] + src16[7*stride];
113  src16 += 8*stride;
114  len -= 8;
115  }
116  while (--len >= 0) {
117  total += src16[0];
118  src16 += stride;
119  }
120  break;
121  case 3:
122  case 4:
123  while (len >= 4) {
124  total += src[0] + src[1 ] + src[2 ]
125  + src[ stride] + src[1+ stride] + src[2+ stride]
126  + src[2*stride] + src[1+2*stride] + src[2+2*stride]
127  + src[3*stride] + src[1+3*stride] + src[2+3*stride];
128  src += 4*stride;
129  len -= 4;
130  }
131  while (--len >= 0) {
132  total += src[0] + src[1] + src[2];
133  src += stride;
134  }
135  div *= 3;
136  break;
137  }
138  total /= div;
139 
140  av_log(ctx, AV_LOG_DEBUG, "total:%d\n", total);
141  return total;
142 }
143 
144 static int checkline_edge(void *ctx, const unsigned char *src, int stride, int len, int bpp)
145 {
146  const uint16_t *src16 = (const uint16_t *)src;
147 
148  switch (bpp) {
149  case 1:
150  while (--len >= 0) {
151  if (src[0]) return 0;
152  src += stride;
153  }
154  break;
155  case 2:
156  stride >>= 1;
157  while (--len >= 0) {
158  if (src16[0]) return 0;
159  src16 += stride;
160  }
161  break;
162  case 3:
163  case 4:
164  while (--len >= 0) {
165  if (src[0] || src[1] || src[2]) return 0;
166  src += stride;
167  }
168  break;
169  }
170 
171  return 1;
172 }
173 
175 {
176  CropDetectContext *s = ctx->priv;
177 
178  s->frame_nb = -1 * s->skip;
179  s->low_u8 = s->low * 255. + .5;
180  s->high_u8 = s->high * 255. + .5;
181 
182  av_log(ctx, AV_LOG_VERBOSE, "limit:%f round:%d skip:%d reset_count:%d\n",
183  s->limit, s->round, s->skip, s->reset_count);
184 
185  return 0;
186 }
187 
189 {
190  CropDetectContext *s = ctx->priv;
191 
192  av_freep(&s->tmpbuf);
193  av_freep(&s->filterbuf);
194  av_freep(&s->gradients);
195  av_freep(&s->directions);
196  av_freep(&s->bboxes[0]);
197  av_freep(&s->bboxes[1]);
198  av_freep(&s->bboxes[2]);
199  av_freep(&s->bboxes[3]);
200 }
201 
203 {
204  AVFilterContext *ctx = inlink->dst;
205  CropDetectContext *s = ctx->priv;
207  const int bufsize = inlink->w * inlink->h;
208 
209  av_image_fill_max_pixsteps(s->max_pixsteps, NULL, desc);
210 
211  s->bitdepth = desc->comp[0].depth;
212 
213  if (s->limit < 1.0)
214  s->limit_upscaled = s->limit * ((1 << s->bitdepth) - 1);
215  else
216  s->limit_upscaled = s->limit;
217 
218  s->x1 = inlink->w - 1;
219  s->y1 = inlink->h - 1;
220  s->x2 = 0;
221  s->y2 = 0;
222 
223  s->window_size = FFMAX(s->reset_count, 15);
224  s->tmpbuf = av_malloc(bufsize);
225  s->filterbuf = av_malloc(bufsize * s->max_pixsteps[0]);
226  s->gradients = av_calloc(bufsize, sizeof(*s->gradients));
227  s->directions = av_malloc(bufsize);
228  s->bboxes[0] = av_malloc(s->window_size * sizeof(*s->bboxes[0]));
229  s->bboxes[1] = av_malloc(s->window_size * sizeof(*s->bboxes[1]));
230  s->bboxes[2] = av_malloc(s->window_size * sizeof(*s->bboxes[2]));
231  s->bboxes[3] = av_malloc(s->window_size * sizeof(*s->bboxes[3]));
232 
233  if (!s->tmpbuf || !s->filterbuf || !s->gradients || !s->directions ||
234  !s->bboxes[0] || !s->bboxes[1] || !s->bboxes[2] || !s->bboxes[3])
235  return AVERROR(ENOMEM);
236 
237  return 0;
238 }
239 
240 #define SET_META(key, value) \
241  av_dict_set_int(metadata, key, value, 0)
242 
244 {
245  AVFilterContext *ctx = inlink->dst;
246  CropDetectContext *s = ctx->priv;
247  int bpp = s->max_pixsteps[0];
248  int w, h, x, y, shrink_by, i;
249  AVDictionary **metadata;
250  int outliers, last_y;
251  int limit_upscaled = lrint(s->limit_upscaled);
252  char limit_str[22];
253 
254  const int inw = inlink->w;
255  const int inh = inlink->h;
256  uint8_t *tmpbuf = s->tmpbuf;
257  uint8_t *filterbuf = s->filterbuf;
258  uint16_t *gradients = s->gradients;
259  int8_t *directions = s->directions;
260  const AVFrameSideData *sd = NULL;
261  int scan_w, scan_h, bboff;
262 
263  void (*sobel)(int w, int h, uint16_t *dst, int dst_linesize,
264  int8_t *dir, int dir_linesize,
265  const uint8_t *src, int src_linesize, int src_stride) = (bpp == 2) ? &ff_sobel_16 : &ff_sobel_8;
266  void (*gaussian_blur)(int w, int h,
267  uint8_t *dst, int dst_linesize,
268  const uint8_t *src, int src_linesize, int src_stride) = (bpp == 2) ? &ff_gaussian_blur_16 : &ff_gaussian_blur_8;
269 
270 
271  // ignore first s->skip frames
272  if (++s->frame_nb > 0) {
273  metadata = &frame->metadata;
274 
275  // Reset the crop area every reset_count frames, if reset_count is > 0
276  if (s->reset_count > 0 && s->frame_nb > s->reset_count) {
277  s->x1 = frame->width - 1;
278  s->y1 = frame->height - 1;
279  s->x2 = 0;
280  s->y2 = 0;
281  s->frame_nb = 1;
282  }
283 
284 #define FIND(DST, FROM, NOEND, INC, STEP0, STEP1, LEN) \
285  outliers = 0;\
286  for (last_y = y = FROM; NOEND; y = y INC) {\
287  if (checkline(ctx, frame->data[0] + STEP0 * y, STEP1, LEN, bpp) > limit_upscaled) {\
288  if (++outliers > s->max_outliers) { \
289  DST = last_y;\
290  break;\
291  }\
292  } else\
293  last_y = y INC;\
294  }
295 
296  if (s->mode == MODE_BLACK) {
297  FIND(s->y1, 0, y < s->y1, +1, frame->linesize[0], bpp, frame->width);
298  FIND(s->y2, frame->height - 1, y > FFMAX(s->y2, s->y1), -1, frame->linesize[0], bpp, frame->width);
299  FIND(s->x1, 0, y < s->x1, +1, bpp, frame->linesize[0], frame->height);
300  FIND(s->x2, frame->width - 1, y > FFMAX(s->x2, s->x1), -1, bpp, frame->linesize[0], frame->height);
301  } else { // MODE_MV_EDGES
303  s->x1 = 0;
304  s->y1 = 0;
305  s->x2 = inw - 1;
306  s->y2 = inh - 1;
307 
308  if (!sd) {
309  av_log(ctx, AV_LOG_WARNING, "Cannot detect: no motion vectors available");
310  } else {
311  // gaussian filter to reduce noise
312  gaussian_blur(inw, inh,
313  filterbuf, inw*bpp,
314  frame->data[0], frame->linesize[0], bpp);
315 
316  // compute the 16-bits gradients and directions for the next step
317  sobel(inw, inh, gradients, inw, directions, inw, filterbuf, inw*bpp, bpp);
318 
319  // non_maximum_suppression() will actually keep & clip what's necessary and
320  // ignore the rest, so we need a clean output buffer
321  memset(tmpbuf, 0, inw * inh);
322  ff_non_maximum_suppression(inw, inh, tmpbuf, inw, directions, inw, gradients, inw);
323 
324 
325  // keep high values, or low values surrounded by high values
326  ff_double_threshold(s->low_u8, s->high_u8, inw, inh,
327  tmpbuf, inw, tmpbuf, inw);
328 
329  // scan all MVs and store bounding box
330  s->x1 = inw - 1;
331  s->y1 = inh - 1;
332  s->x2 = 0;
333  s->y2 = 0;
334  for (i = 0; i < sd->size / sizeof(AVMotionVector); i++) {
335  const AVMotionVector *mv = (const AVMotionVector*)sd->data + i;
336  const int mx = mv->dst_x - mv->src_x;
337  const int my = mv->dst_y - mv->src_y;
338 
339  if (mv->dst_x >= 0 && mv->dst_x < inw &&
340  mv->dst_y >= 0 && mv->dst_y < inh &&
341  mv->src_x >= 0 && mv->src_x < inw &&
342  mv->src_y >= 0 && mv->src_y < inh &&
343  mx * mx + my * my >= s->mv_threshold * s->mv_threshold) {
344  s->x1 = mv->dst_x < s->x1 ? mv->dst_x : s->x1;
345  s->y1 = mv->dst_y < s->y1 ? mv->dst_y : s->y1;
346  s->x2 = mv->dst_x > s->x2 ? mv->dst_x : s->x2;
347  s->y2 = mv->dst_y > s->y2 ? mv->dst_y : s->y2;
348  }
349  }
350 
351  // assert x1<x2, y1<y2
352  if (s->x1 > s->x2) FFSWAP(int, s->x1, s->x2);
353  if (s->y1 > s->y2) FFSWAP(int, s->y1, s->y2);
354 
355  // scan outward looking for 0-edge-lines in edge image
356  scan_w = s->x2 - s->x1;
357  scan_h = s->y2 - s->y1;
358 
359 #define FIND_EDGE(DST, FROM, NOEND, INC, STEP0, STEP1, LEN) \
360  for (last_y = y = FROM; NOEND; y = y INC) { \
361  if (checkline_edge(ctx, tmpbuf + STEP0 * y, STEP1, LEN, bpp)) { \
362  if (last_y INC == y) { \
363  DST = y; \
364  break; \
365  } else \
366  last_y = y; \
367  } \
368  } \
369  if (!(NOEND)) { \
370  DST = y -(INC); \
371  }
372 
373  FIND_EDGE(s->y1, s->y1, y >= 0, -1, inw, bpp, scan_w);
374  FIND_EDGE(s->y2, s->y2, y < inh, +1, inw, bpp, scan_w);
375  FIND_EDGE(s->x1, s->x1, y >= 0, -1, bpp, inw, scan_h);
376  FIND_EDGE(s->x2, s->x2, y < inw, +1, bpp, inw, scan_h);
377 
378  // queue bboxes
379  bboff = (s->frame_nb - 1) % s->window_size;
380  s->bboxes[0][bboff] = s->x1;
381  s->bboxes[1][bboff] = s->x2;
382  s->bboxes[2][bboff] = s->y1;
383  s->bboxes[3][bboff] = s->y2;
384 
385  // sort queue
386  bboff = FFMIN(s->frame_nb, s->window_size);
387  AV_QSORT(s->bboxes[0], bboff, int, comp);
388  AV_QSORT(s->bboxes[1], bboff, int, comp);
389  AV_QSORT(s->bboxes[2], bboff, int, comp);
390  AV_QSORT(s->bboxes[3], bboff, int, comp);
391 
392  // return median of window_size elems
393  s->x1 = s->bboxes[0][bboff/2];
394  s->x2 = s->bboxes[1][bboff/2];
395  s->y1 = s->bboxes[2][bboff/2];
396  s->y2 = s->bboxes[3][bboff/2];
397  }
398  }
399 
400  // round x and y (up), important for yuv colorspaces
401  // make sure they stay rounded!
402  x = (s->x1+1) & ~1;
403  y = (s->y1+1) & ~1;
404 
405  w = s->x2 - x + 1;
406  h = s->y2 - y + 1;
407 
408  // w and h must be divisible by 2 as well because of yuv
409  // colorspace problems.
410  if (s->round <= 1)
411  s->round = 16;
412  if (s->round % 2)
413  s->round *= 2;
414 
415  shrink_by = w % s->round;
416  w -= shrink_by;
417  x += (shrink_by/2 + 1) & ~1;
418 
419  shrink_by = h % s->round;
420  h -= shrink_by;
421  y += (shrink_by/2 + 1) & ~1;
422 
423  SET_META("lavfi.cropdetect.x1", s->x1);
424  SET_META("lavfi.cropdetect.x2", s->x2);
425  SET_META("lavfi.cropdetect.y1", s->y1);
426  SET_META("lavfi.cropdetect.y2", s->y2);
427  SET_META("lavfi.cropdetect.w", w);
428  SET_META("lavfi.cropdetect.h", h);
429  SET_META("lavfi.cropdetect.x", x);
430  SET_META("lavfi.cropdetect.y", y);
431 
432  snprintf(limit_str, sizeof(limit_str), "%f", s->limit);
433  av_dict_set(metadata, "lavfi.cropdetect.limit", limit_str, 0);
434 
436  "x1:%d x2:%d y1:%d y2:%d w:%d h:%d x:%d y:%d pts:%"PRId64" t:%f limit:%f crop=%d:%d:%d:%d\n",
437  s->x1, s->x2, s->y1, s->y2, w, h, x, y, frame->pts,
438  frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
439  s->limit, w, h, x, y);
440  }
441 
442  return ff_filter_frame(inlink->dst->outputs[0], frame);
443 }
444 
445 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
446  char *res, int res_len, int flags)
447 {
448  CropDetectContext *s = ctx->priv;
449  float old_limit = s->limit;
450  int ret;
451 
452  if ((ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags)) < 0)
453  return ret;
454 
455  if (old_limit != s->limit) {
456  if (s->limit < 1.0)
457  s->limit_upscaled = s->limit * ((1 << s->bitdepth) - 1);
458  else
459  s->limit_upscaled = s->limit;
460  s->frame_nb = s->reset_count;
461  }
462 
463  return 0;
464 }
465 
466 #define OFFSET(x) offsetof(CropDetectContext, x)
467 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
468 #define TFLAGS AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_RUNTIME_PARAM
469 
470 static const AVOption cropdetect_options[] = {
471  { "limit", "Threshold below which the pixel is considered black", OFFSET(limit), AV_OPT_TYPE_FLOAT, { .dbl = 24.0/255 }, 0, 65535, TFLAGS },
472  { "round", "Value by which the width/height should be divisible", OFFSET(round), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, INT_MAX, FLAGS },
473  { "reset", "Recalculate the crop area after this many frames", OFFSET(reset_count), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
474  { "skip", "Number of initial frames to skip", OFFSET(skip), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, INT_MAX, FLAGS },
475  { "reset_count", "Recalculate the crop area after this many frames",OFFSET(reset_count),AV_OPT_TYPE_INT,{ .i64 = 0 }, 0, INT_MAX, FLAGS },
476  { "max_outliers", "Threshold count of outliers", OFFSET(max_outliers),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
477  { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_BLACK}, 0, MODE_NB-1, FLAGS, .unit = "mode" },
478  { "black", "detect black pixels surrounding the video", 0, AV_OPT_TYPE_CONST, {.i64=MODE_BLACK}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
479  { "mvedges", "detect motion and edged surrounding the video", 0, AV_OPT_TYPE_CONST, {.i64=MODE_MV_EDGES}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
480  { "high", "Set high threshold for edge detection", OFFSET(high), AV_OPT_TYPE_FLOAT, {.dbl=25/255.}, 0, 1, FLAGS },
481  { "low", "Set low threshold for edge detection", OFFSET(low), AV_OPT_TYPE_FLOAT, {.dbl=15/255.}, 0, 1, FLAGS },
482  { "mv_threshold", "motion vector threshold when estimating video window size", OFFSET(mv_threshold), AV_OPT_TYPE_INT, {.i64=8}, 0, 100, FLAGS},
483  { NULL }
484 };
485 
486 AVFILTER_DEFINE_CLASS(cropdetect);
487 
489  {
490  .name = "default",
491  .type = AVMEDIA_TYPE_VIDEO,
492  .config_props = config_input,
493  .filter_frame = filter_frame,
494  },
495 };
496 
498  .name = "cropdetect",
499  .description = NULL_IF_CONFIG_SMALL("Auto-detect crop size."),
500  .priv_size = sizeof(CropDetectContext),
501  .priv_class = &cropdetect_class,
502  .init = init,
503  .uninit = uninit,
508  .process_command = process_command,
509 };
CropDetectContext::high_u8
uint8_t high_u8
Definition: vf_cropdetect.c:53
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_cropdetect.c:174
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
gaussian_blur
void fn() gaussian_blur(int w, int h, uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int src_stride)
Definition: edge_template.c:73
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:858
AVMotionVector
Definition: motion_vector.h:24
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:162
mv
static const int8_t mv[256][2]
Definition: 4xm.c:80
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
SET_META
#define SET_META(key, value)
Definition: vf_cropdetect.c:240
CropDetectContext::filterbuf
uint8_t * filterbuf
Definition: vf_cropdetect.c:54
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
w
uint8_t w
Definition: llviddspenc.c:38
CropDetectContext::tmpbuf
uint8_t * tmpbuf
Definition: vf_cropdetect.c:55
edge_common.h
AVOption
AVOption.
Definition: opt.h:346
b
#define b
Definition: input.c:41
CropMode
CropMode
Definition: vf_cropdetect.c:78
CropDetectContext::low
float low
Definition: vf_cropdetect.c:52
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:478
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:102
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:106
AVDictionary
Definition: dict.c:34
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
comp
static int comp(const int *a, const int *b)
Definition: vf_cropdetect.c:84
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
MODE_BLACK
@ MODE_BLACK
Definition: vf_cropdetect.c:79
video.h
checkline
static int checkline(void *ctx, const unsigned char *src, int stride, int len, int bpp)
Definition: vf_cropdetect.c:89
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
CropDetectContext::gradients
uint16_t * gradients
Definition: vf_cropdetect.c:56
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:476
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
FFDIFFSIGN
#define FFDIFFSIGN(x, y)
Comparator.
Definition: macros.h:45
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:481
lrint
#define lrint
Definition: tablegen.h:53
CropDetectContext::window_size
int window_size
Definition: vf_cropdetect.c:49
AVFrameSideData::size
size_t size
Definition: frame.h:253
av_cold
#define av_cold
Definition: attributes.h:90
CropDetectContext::skip
int skip
Definition: vf_cropdetect.c:43
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:490
ff_video_default_filterpad
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition: video.c:37
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:86
motion_vector.h
CropDetectContext
Definition: vf_cropdetect.c:37
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:491
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
CropDetectContext::low_u8
uint8_t low_u8
Definition: vf_cropdetect.c:53
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:475
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:489
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(cropdetect)
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:73
CropDetectContext::y1
int y1
Definition: vf_cropdetect.c:39
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
CropDetectContext::max_pixsteps
int max_pixsteps[4]
Definition: vf_cropdetect.c:46
AV_PIX_FMT_RGBA
@ AV_PIX_FMT_RGBA
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
Definition: pixfmt.h:100
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:87
if
if(ret)
Definition: filter_design.txt:179
CropDetectContext::limit_upscaled
float limit_upscaled
Definition: vf_cropdetect.c:41
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: vf_cropdetect.c:243
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
FLAGS
#define FLAGS
Definition: vf_cropdetect.c:467
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:85
CropDetectContext::y2
int y2
Definition: vf_cropdetect.c:39
cropdetect_options
static const AVOption cropdetect_options[]
Definition: vf_cropdetect.c:470
ff_non_maximum_suppression
void ff_non_maximum_suppression(int w, int h, uint8_t *dst, int dst_linesize, const int8_t *dir, int dir_linesize, const uint16_t *src, int src_linesize)
Filters rounded gradients to drop all non-maxima pixels in the magnitude image Expects gradients gene...
Definition: edge_common.c:60
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:479
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:81
TFLAGS
#define TFLAGS
Definition: vf_cropdetect.c:468
CropDetectContext::x1
int x1
Definition: vf_cropdetect.c:39
qsort.h
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
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:106
ff_double_threshold
void ff_double_threshold(int low, int high, int w, int h, uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize)
Filters all pixels in src to keep all pixels > high, and keep all pixels > low where all surrounding ...
Definition: edge_common.c:89
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_cropdetect.c:61
FIND
#define FIND(DST, FROM, NOEND, INC, STEP0, STEP1, LEN)
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:483
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:485
AVFrameSideData::data
uint8_t * data
Definition: frame.h:252
OFFSET
#define OFFSET(x)
Definition: vf_cropdetect.c:466
CropDetectContext::max_outliers
int max_outliers
Definition: vf_cropdetect.c:47
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:890
CropDetectContext::reset_count
int reset_count
Definition: vf_cropdetect.c:44
CropDetectContext::bboxes
int * bboxes[4]
Definition: vf_cropdetect.c:58
MODE_MV_EDGES
@ MODE_MV_EDGES
Definition: vf_cropdetect.c:80
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
CropDetectContext::limit
float limit
Definition: vf_cropdetect.c:40
CropDetectContext::round
int round
Definition: vf_cropdetect.c:42
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_cropdetect.c:202
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
CropDetectContext::frame_nb
int frame_nb
Definition: vf_cropdetect.c:45
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:147
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:238
FIND_EDGE
#define FIND_EDGE(DST, FROM, NOEND, INC, STEP0, STEP1, LEN)
CropDetectContext::directions
char * directions
Definition: vf_cropdetect.c:57
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
AV_QSORT
#define AV_QSORT(p, num, type, cmp)
Quicksort This sort is fast, and fully inplace but not stable and it is possible to construct input t...
Definition: qsort.h:33
round
static av_always_inline av_const double round(double x)
Definition: libm.h:444
internal.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
MODE_NB
@ MODE_NB
Definition: vf_cropdetect.c:81
AV_PIX_FMT_NV21
@ AV_PIX_FMT_NV21
as above, but U and V bytes are swapped
Definition: pixfmt.h:97
len
int len
Definition: vorbis_enc_data.h:426
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:477
limit
static double limit(double x)
Definition: vf_pseudocolor.c:142
stride
#define stride
Definition: h264pred_template.c:537
CropDetectContext::mv_threshold
int mv_threshold
Definition: vf_cropdetect.c:50
AVFilter
Filter definition.
Definition: avfilter.h:166
ret
ret
Definition: filter_design.txt:187
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:96
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
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
CropDetectContext::bitdepth
int bitdepth
Definition: vf_cropdetect.c:51
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:482
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:487
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avfilter.h
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: vf_cropdetect.c:445
AVFILTER_FLAG_METADATA_ONLY
#define AVFILTER_FLAG_METADATA_ONLY
The filter is a "metadata" filter - it does not modify the frame data in any way.
Definition: avfilter.h:133
sobel
void fn() sobel(int w, int h, uint16_t *dst, int dst_linesize, int8_t *dir, int dir_linesize, const uint8_t *src, int src_linesize, int src_stride)
Definition: edge_template.c:42
CropDetectContext::x2
int x2
Definition: vf_cropdetect.c:39
av_image_fill_max_pixsteps
void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], const AVPixFmtDescriptor *pixdesc)
Compute the max pixel step for each plane of an image with a format described by pixdesc.
Definition: imgutils.c:35
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:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
desc
const char * desc
Definition: libsvtav1.c:75
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
checkline_edge
static int checkline_edge(void *ctx, const unsigned char *src, int stride, int len, int bpp)
Definition: vf_cropdetect.c:144
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:77
avfilter_vf_cropdetect_inputs
static const AVFilterPad avfilter_vf_cropdetect_inputs[]
Definition: vf_cropdetect.c:488
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:250
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
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:80
imgutils.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
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:79
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_FRAME_DATA_MOTION_VECTORS
@ AV_FRAME_DATA_MOTION_VECTORS
Motion vectors exported by some codecs (on demand through the export_mvs flag set in the libavcodec A...
Definition: frame.h:97
h
h
Definition: vp9dsp_template.c:2038
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:488
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_cropdetect.c:188
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
snprintf
#define snprintf
Definition: snprintf.h:34
CropDetectContext::high
float high
Definition: vf_cropdetect.c:52
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
CropDetectContext::mode
int mode
Definition: vf_cropdetect.c:48
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:486
ff_vf_cropdetect
const AVFilter ff_vf_cropdetect
Definition: vf_cropdetect.c:497