FFmpeg
vf_fieldmatch.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Fredrik Mellbin
3  * Copyright (c) 2013 Clément Bœsch
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 Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 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 GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along 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 /**
23  * @file
24  * Fieldmatching filter, ported from VFM filter (VapourSynth) by Clément.
25  * Fredrik Mellbin is the author of the VIVTC/VFM filter, which is itself a
26  * light clone of the TIVTC/TFM (AviSynth) filter written by Kevin Stone
27  * (tritical), the original author.
28  *
29  * @see http://bengal.missouri.edu/~kes25c/
30  * @see http://www.vapoursynth.com/about/
31  */
32 
33 #include <inttypes.h>
34 
35 #include "libavutil/avassert.h"
36 #include "libavutil/imgutils.h"
37 #include "libavutil/mem.h"
38 #include "libavutil/opt.h"
39 #include "libavutil/timestamp.h"
40 #include "avfilter.h"
41 #include "filters.h"
42 #include "formats.h"
43 #include "internal.h"
44 #include "video.h"
45 
46 #define INPUT_MAIN 0
47 #define INPUT_CLEANSRC 1
48 
53 };
54 
63 };
64 
70 };
71 
72 enum comb_dbg {
77 };
78 
79 typedef struct FieldMatchContext {
80  const AVClass *class;
81 
82  AVFrame *prv, *src, *nxt; ///< main sliding window of 3 frames
83  AVFrame *prv2, *src2, *nxt2; ///< sliding window of the optional second stream
84  int got_frame[2]; ///< frame request flag for each input stream
85  int hsub[2], vsub[2]; ///< chroma subsampling values
86  int bpc; ///< bytes per component
87  uint32_t eof; ///< bitmask for end of stream
88  int64_t lastscdiff;
89  int64_t lastn;
90 
91  /* options */
92  int order;
93  int ppsrc;
94  int mode; ///< matching_mode
95  int field;
96  int mchroma;
97  int y0, y1;
98  int64_t scthresh;
99  double scthresh_flt;
100  int combmatch; ///< comb_matching_mode
101  int combdbg;
102  int cthresh;
103  int chroma;
105  int combpel;
106 
107  /* misc buffers */
108  uint8_t *map_data[4];
109  int map_linesize[4];
110  uint8_t *cmask_data[4];
112  int *c_array;
114  uint8_t *tbuffer;
116 
117 #define OFFSET(x) offsetof(FieldMatchContext, x)
118 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
119 
120 static const AVOption fieldmatch_options[] = {
121  { "order", "specify the assumed field order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=FM_PARITY_AUTO}, -1, 1, FLAGS, .unit = "order" },
122  { "auto", "auto detect parity", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_AUTO}, INT_MIN, INT_MAX, FLAGS, .unit = "order" },
123  { "bff", "assume bottom field first", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_BOTTOM}, INT_MIN, INT_MAX, FLAGS, .unit = "order" },
124  { "tff", "assume top field first", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_TOP}, INT_MIN, INT_MAX, FLAGS, .unit = "order" },
125  { "mode", "set the matching mode or strategy to use", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_PC_N}, MODE_PC, NB_MODE-1, FLAGS, .unit = "mode" },
126  { "pc", "2-way match (p/c)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PC}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
127  { "pc_n", "2-way match + 3rd match on combed (p/c + u)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PC_N}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
128  { "pc_u", "2-way match + 3rd match (same order) on combed (p/c + u)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PC_U}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
129  { "pc_n_ub", "2-way match + 3rd match on combed + 4th/5th matches if still combed (p/c + u + u/b)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PC_N_UB}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
130  { "pcn", "3-way match (p/c/n)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PCN}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
131  { "pcn_ub", "3-way match + 4th/5th matches on combed (p/c/n + u/b)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PCN_UB}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
132  { "ppsrc", "mark main input as a pre-processed input and activate clean source input stream", OFFSET(ppsrc), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
133  { "field", "set the field to match from", OFFSET(field), AV_OPT_TYPE_INT, {.i64=FM_PARITY_AUTO}, -1, 1, FLAGS, .unit = "field" },
134  { "auto", "automatic (same value as 'order')", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_AUTO}, INT_MIN, INT_MAX, FLAGS, .unit = "field" },
135  { "bottom", "bottom field", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_BOTTOM}, INT_MIN, INT_MAX, FLAGS, .unit = "field" },
136  { "top", "top field", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_TOP}, INT_MIN, INT_MAX, FLAGS, .unit = "field" },
137  { "mchroma", "set whether or not chroma is included during the match comparisons", OFFSET(mchroma), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
138  { "y0", "define an exclusion band which excludes the lines between y0 and y1 from the field matching decision", OFFSET(y0), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
139  { "y1", "define an exclusion band which excludes the lines between y0 and y1 from the field matching decision", OFFSET(y1), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
140  { "scthresh", "set scene change detection threshold", OFFSET(scthresh_flt), AV_OPT_TYPE_DOUBLE, {.dbl=12}, 0, 100, FLAGS },
141  { "combmatch", "set combmatching mode", OFFSET(combmatch), AV_OPT_TYPE_INT, {.i64=COMBMATCH_SC}, COMBMATCH_NONE, NB_COMBMATCH-1, FLAGS, .unit = "combmatching" },
142  { "none", "disable combmatching", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_NONE}, INT_MIN, INT_MAX, FLAGS, .unit = "combmatching" },
143  { "sc", "enable combmatching only on scene change", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_SC}, INT_MIN, INT_MAX, FLAGS, .unit = "combmatching" },
144  { "full", "enable combmatching all the time", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_FULL}, INT_MIN, INT_MAX, FLAGS, .unit = "combmatching" },
145  { "combdbg", "enable comb debug", OFFSET(combdbg), AV_OPT_TYPE_INT, {.i64=COMBDBG_NONE}, COMBDBG_NONE, NB_COMBDBG-1, FLAGS, .unit = "dbglvl" },
146  { "none", "no forced calculation", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_NONE}, INT_MIN, INT_MAX, FLAGS, .unit = "dbglvl" },
147  { "pcn", "calculate p/c/n", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_PCN}, INT_MIN, INT_MAX, FLAGS, .unit = "dbglvl" },
148  { "pcnub", "calculate p/c/n/u/b", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_PCNUB}, INT_MIN, INT_MAX, FLAGS, .unit = "dbglvl" },
149  { "cthresh", "set the area combing threshold used for combed frame detection", OFFSET(cthresh), AV_OPT_TYPE_INT, {.i64= 9}, -1, 0xff, FLAGS },
150  { "chroma", "set whether or not chroma is considered in the combed frame decision", OFFSET(chroma), AV_OPT_TYPE_BOOL,{.i64= 0}, 0, 1, FLAGS },
151  { "blockx", "set the x-axis size of the window used during combed frame detection", OFFSET(blockx), AV_OPT_TYPE_INT, {.i64=16}, 4, 1<<9, FLAGS },
152  { "blocky", "set the y-axis size of the window used during combed frame detection", OFFSET(blocky), AV_OPT_TYPE_INT, {.i64=16}, 4, 1<<9, FLAGS },
153  { "combpel", "set the number of combed pixels inside any of the blocky by blockx size blocks on the frame for the frame to be detected as combed", OFFSET(combpel), AV_OPT_TYPE_INT, {.i64=80}, 0, INT_MAX, FLAGS },
154  { NULL }
155 };
156 
157 AVFILTER_DEFINE_CLASS(fieldmatch);
158 
159 static int get_width(const FieldMatchContext *fm, const AVFrame *f, int plane, int input)
160 {
161  return plane ? AV_CEIL_RSHIFT(f->width, fm->hsub[input]) : f->width;
162 }
163 
164 static int get_height(const FieldMatchContext *fm, const AVFrame *f, int plane, int input)
165 {
166  return plane ? AV_CEIL_RSHIFT(f->height, fm->vsub[input]) : f->height;
167 }
168 
169 static int64_t luma_abs_diff(const AVFrame *f1, const AVFrame *f2)
170 {
171  int x, y;
172  const uint8_t *srcp1 = f1->data[0];
173  const uint8_t *srcp2 = f2->data[0];
174  const int src1_linesize = f1->linesize[0];
175  const int src2_linesize = f2->linesize[0];
176  const int width = f1->width;
177  const int height = f1->height;
178  int64_t acc = 0;
179 
180  for (y = 0; y < height; y++) {
181  for (x = 0; x < width; x++)
182  acc += abs(srcp1[x] - srcp2[x]);
183  srcp1 += src1_linesize;
184  srcp2 += src2_linesize;
185  }
186  return acc;
187 }
188 
189 static void fill_buf(uint8_t *data, int w, int h, int linesize, uint8_t v)
190 {
191  int y;
192 
193  for (y = 0; y < h; y++) {
194  memset(data, v, w);
195  data += linesize;
196  }
197 }
198 
199 static int calc_combed_score(const FieldMatchContext *fm, const AVFrame *src)
200 {
201  int x, y, plane, max_v = 0;
202  const int cthresh = fm->cthresh;
203  const int cthresh6 = cthresh * 6;
204 
205  for (plane = 0; plane < (fm->chroma ? 3 : 1); plane++) {
206  const uint8_t *srcp = src->data[plane];
207  const int src_linesize = src->linesize[plane];
208  const int width = get_width (fm, src, plane, INPUT_MAIN);
209  const int height = get_height(fm, src, plane, INPUT_MAIN);
210  uint8_t *cmkp = fm->cmask_data[plane];
211  const int cmk_linesize = fm->cmask_linesize[plane];
212 
213  if (cthresh < 0) {
214  fill_buf(cmkp, width, height, cmk_linesize, 0xff);
215  continue;
216  }
217  fill_buf(cmkp, width, height, cmk_linesize, 0);
218 
219  /* [1 -3 4 -3 1] vertical filter */
220 #define FILTER(xm2, xm1, xp1, xp2) \
221  abs( 4 * srcp[x] \
222  -3 * (srcp[x + (xm1)*src_linesize] + srcp[x + (xp1)*src_linesize]) \
223  + (srcp[x + (xm2)*src_linesize] + srcp[x + (xp2)*src_linesize])) > cthresh6
224 
225  /* first line */
226  for (x = 0; x < width; x++) {
227  const int s1 = abs(srcp[x] - srcp[x + src_linesize]);
228  if (s1 > cthresh && FILTER(2, 1, 1, 2))
229  cmkp[x] = 0xff;
230  }
231  srcp += src_linesize;
232  cmkp += cmk_linesize;
233 
234  /* second line */
235  for (x = 0; x < width; x++) {
236  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
237  const int s2 = abs(srcp[x] - srcp[x + src_linesize]);
238  if (s1 > cthresh && s2 > cthresh && FILTER(2, -1, 1, 2))
239  cmkp[x] = 0xff;
240  }
241  srcp += src_linesize;
242  cmkp += cmk_linesize;
243 
244  /* all lines minus first two and last two */
245  for (y = 2; y < height-2; y++) {
246  for (x = 0; x < width; x++) {
247  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
248  const int s2 = abs(srcp[x] - srcp[x + src_linesize]);
249  if (s1 > cthresh && s2 > cthresh && FILTER(-2, -1, 1, 2))
250  cmkp[x] = 0xff;
251  }
252  srcp += src_linesize;
253  cmkp += cmk_linesize;
254  }
255 
256  /* before-last line */
257  for (x = 0; x < width; x++) {
258  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
259  const int s2 = abs(srcp[x] - srcp[x + src_linesize]);
260  if (s1 > cthresh && s2 > cthresh && FILTER(-2, -1, 1, -2))
261  cmkp[x] = 0xff;
262  }
263  srcp += src_linesize;
264  cmkp += cmk_linesize;
265 
266  /* last line */
267  for (x = 0; x < width; x++) {
268  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
269  if (s1 > cthresh && FILTER(-2, -1, -1, -2))
270  cmkp[x] = 0xff;
271  }
272  }
273 
274  if (fm->chroma) {
275  uint8_t *cmkp = fm->cmask_data[0];
276  uint8_t *cmkpU = fm->cmask_data[1];
277  uint8_t *cmkpV = fm->cmask_data[2];
278  const int width = AV_CEIL_RSHIFT(src->width, fm->hsub[INPUT_MAIN]);
279  const int height = AV_CEIL_RSHIFT(src->height, fm->vsub[INPUT_MAIN]);
280  const int cmk_linesize = fm->cmask_linesize[0] << 1;
281  const int cmk_linesizeUV = fm->cmask_linesize[2];
282  uint8_t *cmkpp = cmkp - (cmk_linesize>>1);
283  uint8_t *cmkpn = cmkp + (cmk_linesize>>1);
284  uint8_t *cmkpnn = cmkp + cmk_linesize;
285  for (y = 1; y < height - 1; y++) {
286  cmkpp += cmk_linesize;
287  cmkp += cmk_linesize;
288  cmkpn += cmk_linesize;
289  cmkpnn += cmk_linesize;
290  cmkpV += cmk_linesizeUV;
291  cmkpU += cmk_linesizeUV;
292  for (x = 1; x < width - 1; x++) {
293 #define HAS_FF_AROUND(p, lz) (p[(x)-1 - (lz)] == 0xff || p[(x) - (lz)] == 0xff || p[(x)+1 - (lz)] == 0xff || \
294  p[(x)-1 ] == 0xff || p[(x)+1 ] == 0xff || \
295  p[(x)-1 + (lz)] == 0xff || p[(x) + (lz)] == 0xff || p[(x)+1 + (lz)] == 0xff)
296  if ((cmkpV[x] == 0xff && HAS_FF_AROUND(cmkpV, cmk_linesizeUV)) ||
297  (cmkpU[x] == 0xff && HAS_FF_AROUND(cmkpU, cmk_linesizeUV))) {
298  ((uint16_t*)cmkp)[x] = 0xffff;
299  ((uint16_t*)cmkpn)[x] = 0xffff;
300  if (y&1) ((uint16_t*)cmkpp)[x] = 0xffff;
301  else ((uint16_t*)cmkpnn)[x] = 0xffff;
302  }
303  }
304  }
305  }
306 
307  {
308  const int blockx = fm->blockx;
309  const int blocky = fm->blocky;
310  const int xhalf = blockx/2;
311  const int yhalf = blocky/2;
312  const int cmk_linesize = fm->cmask_linesize[0];
313  const uint8_t *cmkp = fm->cmask_data[0] + cmk_linesize;
314  const int width = src->width;
315  const int height = src->height;
316  const int xblocks = ((width+xhalf)/blockx) + 1;
317  const int xblocks4 = xblocks<<2;
318  const int yblocks = ((height+yhalf)/blocky) + 1;
319  int *c_array = fm->c_array;
320  const int arraysize = (xblocks*yblocks)<<2;
321  int heighta = (height/(blocky/2))*(blocky/2);
322  const int widtha = (width /(blockx/2))*(blockx/2);
323  if (heighta == height)
324  heighta = height - yhalf;
325  memset(c_array, 0, arraysize * sizeof(*c_array));
326 
327 #define C_ARRAY_ADD(v) do { \
328  const int box1 = (x / blockx) * 4; \
329  const int box2 = ((x + xhalf) / blockx) * 4; \
330  c_array[temp1 + box1 ] += v; \
331  c_array[temp1 + box2 + 1] += v; \
332  c_array[temp2 + box1 + 2] += v; \
333  c_array[temp2 + box2 + 3] += v; \
334 } while (0)
335 
336 #define VERTICAL_HALF(y_start, y_end) do { \
337  for (y = y_start; y < y_end; y++) { \
338  const int temp1 = (y / blocky) * xblocks4; \
339  const int temp2 = ((y + yhalf) / blocky) * xblocks4; \
340  for (x = 0; x < width; x++) \
341  if (cmkp[x - cmk_linesize] == 0xff && \
342  cmkp[x ] == 0xff && \
343  cmkp[x + cmk_linesize] == 0xff) \
344  C_ARRAY_ADD(1); \
345  cmkp += cmk_linesize; \
346  } \
347 } while (0)
348 
349  VERTICAL_HALF(1, yhalf);
350 
351  for (y = yhalf; y < heighta; y += yhalf) {
352  const int temp1 = (y / blocky) * xblocks4;
353  const int temp2 = ((y + yhalf) / blocky) * xblocks4;
354 
355  for (x = 0; x < widtha; x += xhalf) {
356  const uint8_t *cmkp_tmp = cmkp + x;
357  int u, v, sum = 0;
358  for (u = 0; u < yhalf; u++) {
359  for (v = 0; v < xhalf; v++)
360  if (cmkp_tmp[v - cmk_linesize] == 0xff &&
361  cmkp_tmp[v ] == 0xff &&
362  cmkp_tmp[v + cmk_linesize] == 0xff)
363  sum++;
364  cmkp_tmp += cmk_linesize;
365  }
366  if (sum)
367  C_ARRAY_ADD(sum);
368  }
369 
370  for (x = widtha; x < width; x++) {
371  const uint8_t *cmkp_tmp = cmkp + x;
372  int u, sum = 0;
373  for (u = 0; u < yhalf; u++) {
374  if (cmkp_tmp[-cmk_linesize] == 0xff &&
375  cmkp_tmp[ 0] == 0xff &&
376  cmkp_tmp[ cmk_linesize] == 0xff)
377  sum++;
378  cmkp_tmp += cmk_linesize;
379  }
380  if (sum)
381  C_ARRAY_ADD(sum);
382  }
383 
384  cmkp += cmk_linesize * yhalf;
385  }
386 
387  VERTICAL_HALF(heighta, height - 1);
388 
389  for (x = 0; x < arraysize; x++)
390  if (c_array[x] > max_v)
391  max_v = c_array[x];
392  }
393  return max_v;
394 }
395 
396 // the secret is that tbuffer is an interlaced, offset subset of all the lines
397 static void build_abs_diff_mask(const uint8_t *prvp, int prv_linesize,
398  const uint8_t *nxtp, int nxt_linesize,
399  uint8_t *tbuffer, int tbuf_linesize,
400  int width, int height)
401 {
402  int y, x;
403 
404  prvp -= prv_linesize;
405  nxtp -= nxt_linesize;
406  for (y = 0; y < height; y++) {
407  for (x = 0; x < width; x++)
408  tbuffer[x] = FFABS(prvp[x] - nxtp[x]);
409  prvp += prv_linesize;
410  nxtp += nxt_linesize;
411  tbuffer += tbuf_linesize;
412  }
413 }
414 
415 /**
416  * Build a map over which pixels differ a lot/a little
417  */
419  const uint8_t *prvp, int prv_linesize,
420  const uint8_t *nxtp, int nxt_linesize,
421  uint8_t *dstp, int dst_linesize, int height,
422  int width, int plane)
423 {
424  int x, y, u, diff, count;
425  int tpitch = plane ? fm->tpitchuv : fm->tpitchy;
426  const uint8_t *dp = fm->tbuffer + tpitch;
427 
428  build_abs_diff_mask(prvp, prv_linesize, nxtp, nxt_linesize,
429  fm->tbuffer, tpitch, width, height>>1);
430 
431  for (y = 2; y < height - 2; y += 2) {
432  for (x = 1; x < width - 1; x++) {
433  diff = dp[x];
434  if (diff > 3) {
435  for (count = 0, u = x-1; u < x+2 && count < 2; u++) {
436  count += dp[u-tpitch] > 3;
437  count += dp[u ] > 3;
438  count += dp[u+tpitch] > 3;
439  }
440  if (count > 1) {
441  dstp[x] = 1;
442  if (diff > 19) {
443  int upper = 0, lower = 0;
444  for (count = 0, u = x-1; u < x+2 && count < 6; u++) {
445  if (dp[u-tpitch] > 19) { count++; upper = 1; }
446  if (dp[u ] > 19) count++;
447  if (dp[u+tpitch] > 19) { count++; lower = 1; }
448  }
449  if (count > 3) {
450  if (upper && lower) {
451  dstp[x] |= 1<<1;
452  } else {
453  int upper2 = 0, lower2 = 0;
454  for (u = FFMAX(x-4,0); u < FFMIN(x+5,width); u++) {
455  if (y != 2 && dp[u-2*tpitch] > 19) upper2 = 1;
456  if ( dp[u- tpitch] > 19) upper = 1;
457  if ( dp[u+ tpitch] > 19) lower = 1;
458  if (y != height-4 && dp[u+2*tpitch] > 19) lower2 = 1;
459  }
460  if ((upper && (lower || upper2)) ||
461  (lower && (upper || lower2)))
462  dstp[x] |= 1<<1;
463  else if (count > 5)
464  dstp[x] |= 1<<2;
465  }
466  }
467  }
468  }
469  }
470  }
471  dp += tpitch;
472  dstp += dst_linesize;
473  }
474 }
475 
476 enum { mP, mC, mN, mB, mU };
477 
478 static int get_field_base(int match, int field)
479 {
480  return match < 3 ? 2 - field : 1 + field;
481 }
482 
483 static AVFrame *select_frame(FieldMatchContext *fm, int match)
484 {
485  if (match == mP || match == mB) return fm->prv;
486  else if (match == mN || match == mU) return fm->nxt;
487  else /* match == mC */ return fm->src;
488 }
489 
490 static int compare_fields(FieldMatchContext *fm, int match1, int match2, int field)
491 {
492  int plane, ret;
493  uint64_t accumPc = 0, accumPm = 0, accumPml = 0;
494  uint64_t accumNc = 0, accumNm = 0, accumNml = 0;
495  int norm1, norm2, mtn1, mtn2;
496  float c1, c2, mr;
497  const AVFrame *src = fm->src;
498 
499  for (plane = 0; plane < (fm->mchroma ? 3 : 1); plane++) {
500  int x, y, temp1, temp2, fbase;
501  const AVFrame *prev, *next;
502  uint8_t *mapp = fm->map_data[plane];
503  int map_linesize = fm->map_linesize[plane];
504  const uint8_t *srcp = src->data[plane];
505  const int src_linesize = src->linesize[plane];
506  const int srcf_linesize = src_linesize << 1;
507  int prv_linesize, nxt_linesize;
508  int prvf_linesize, nxtf_linesize;
509  const int width = get_width (fm, src, plane, INPUT_MAIN);
510  const int height = get_height(fm, src, plane, INPUT_MAIN);
511  const int y0a = fm->y0 >> (plane ? fm->vsub[INPUT_MAIN] : 0);
512  const int y1a = fm->y1 >> (plane ? fm->vsub[INPUT_MAIN] : 0);
513  const int startx = (plane == 0 ? 8 : 8 >> fm->hsub[INPUT_MAIN]);
514  const int stopx = width - startx;
515  const uint8_t *srcpf, *srcf, *srcnf;
516  const uint8_t *prvpf, *prvnf, *nxtpf, *nxtnf;
517 
518  fill_buf(mapp, width, height, map_linesize, 0);
519 
520  /* match1 */
521  fbase = get_field_base(match1, field);
522  srcf = srcp + (fbase + 1) * src_linesize;
523  srcpf = srcf - srcf_linesize;
524  srcnf = srcf + srcf_linesize;
525  mapp = mapp + fbase * map_linesize;
526  prev = select_frame(fm, match1);
527  prv_linesize = prev->linesize[plane];
528  prvf_linesize = prv_linesize << 1;
529  prvpf = prev->data[plane] + fbase * prv_linesize; // previous frame, previous field
530  prvnf = prvpf + prvf_linesize; // previous frame, next field
531 
532  /* match2 */
533  fbase = get_field_base(match2, field);
534  next = select_frame(fm, match2);
535  nxt_linesize = next->linesize[plane];
536  nxtf_linesize = nxt_linesize << 1;
537  nxtpf = next->data[plane] + fbase * nxt_linesize; // next frame, previous field
538  nxtnf = nxtpf + nxtf_linesize; // next frame, next field
539 
540  map_linesize <<= 1;
541  if ((match1 >= 3 && field == 1) || (match1 < 3 && field != 1))
542  build_diff_map(fm, prvpf, prvf_linesize, nxtpf, nxtf_linesize,
543  mapp, map_linesize, height, width, plane);
544  else
545  build_diff_map(fm, prvnf, prvf_linesize, nxtnf, nxtf_linesize,
546  mapp + map_linesize, map_linesize, height, width, plane);
547 
548  for (y = 2; y < height - 2; y += 2) {
549  if (y0a == y1a || y < y0a || y > y1a) {
550  for (x = startx; x < stopx; x++) {
551  if (mapp[x] > 0 || mapp[x + map_linesize] > 0) {
552  temp1 = srcpf[x] + (srcf[x] << 2) + srcnf[x]; // [1 4 1]
553 
554  temp2 = abs(3 * (prvpf[x] + prvnf[x]) - temp1);
555  if (temp2 > 23 && ((mapp[x]&1) || (mapp[x + map_linesize]&1)))
556  accumPc += temp2;
557  if (temp2 > 42) {
558  if ((mapp[x]&2) || (mapp[x + map_linesize]&2))
559  accumPm += temp2;
560  if ((mapp[x]&4) || (mapp[x + map_linesize]&4))
561  accumPml += temp2;
562  }
563 
564  temp2 = abs(3 * (nxtpf[x] + nxtnf[x]) - temp1);
565  if (temp2 > 23 && ((mapp[x]&1) || (mapp[x + map_linesize]&1)))
566  accumNc += temp2;
567  if (temp2 > 42) {
568  if ((mapp[x]&2) || (mapp[x + map_linesize]&2))
569  accumNm += temp2;
570  if ((mapp[x]&4) || (mapp[x + map_linesize]&4))
571  accumNml += temp2;
572  }
573  }
574  }
575  }
576  prvpf += prvf_linesize;
577  prvnf += prvf_linesize;
578  srcpf += srcf_linesize;
579  srcf += srcf_linesize;
580  srcnf += srcf_linesize;
581  nxtpf += nxtf_linesize;
582  nxtnf += nxtf_linesize;
583  mapp += map_linesize;
584  }
585  }
586 
587  if (accumPm < 500 && accumNm < 500 && (accumPml >= 500 || accumNml >= 500) &&
588  FFMAX(accumPml,accumNml) > 3*FFMIN(accumPml,accumNml)) {
589  accumPm = accumPml;
590  accumNm = accumNml;
591  }
592 
593  norm1 = (int)((accumPc / 6.0f) + 0.5f);
594  norm2 = (int)((accumNc / 6.0f) + 0.5f);
595  mtn1 = (int)((accumPm / 6.0f) + 0.5f);
596  mtn2 = (int)((accumNm / 6.0f) + 0.5f);
597  c1 = ((float)FFMAX(norm1,norm2)) / ((float)FFMAX(FFMIN(norm1,norm2),1));
598  c2 = ((float)FFMAX(mtn1, mtn2)) / ((float)FFMAX(FFMIN(mtn1, mtn2), 1));
599  mr = ((float)FFMAX(mtn1, mtn2)) / ((float)FFMAX(FFMAX(norm1,norm2),1));
600  if (((mtn1 >= 500 || mtn2 >= 500) && (mtn1*2 < mtn2*1 || mtn2*2 < mtn1*1)) ||
601  ((mtn1 >= 1000 || mtn2 >= 1000) && (mtn1*3 < mtn2*2 || mtn2*3 < mtn1*2)) ||
602  ((mtn1 >= 2000 || mtn2 >= 2000) && (mtn1*5 < mtn2*4 || mtn2*5 < mtn1*4)) ||
603  ((mtn1 >= 4000 || mtn2 >= 4000) && c2 > c1))
604  ret = mtn1 > mtn2 ? match2 : match1;
605  else if (mr > 0.005 && FFMAX(mtn1, mtn2) > 150 && (mtn1*2 < mtn2*1 || mtn2*2 < mtn1*1))
606  ret = mtn1 > mtn2 ? match2 : match1;
607  else
608  ret = norm1 > norm2 ? match2 : match1;
609  return ret;
610 }
611 
612 static void copy_fields(const FieldMatchContext *fm, AVFrame *dst,
613  const AVFrame *src, int field, int input)
614 {
615  int plane;
616  for (plane = 0; plane < 4 && src->data[plane] && src->linesize[plane]; plane++) {
617  const int plane_h = get_height(fm, src, plane, input);
618  const int nb_copy_fields = (plane_h >> 1) + (field ? 0 : (plane_h & 1));
619  av_image_copy_plane(dst->data[plane] + field*dst->linesize[plane], dst->linesize[plane] << 1,
620  src->data[plane] + field*src->linesize[plane], src->linesize[plane] << 1,
621  get_width(fm, src, plane, input) * fm->bpc, nb_copy_fields);
622  }
623 }
624 
626  const AVFrame *prv, AVFrame *src, const AVFrame *nxt, int input)
627 {
628  AVFrame *dst;
629  FieldMatchContext *fm = ctx->priv;
630 
631  if (match == mC) {
632  dst = av_frame_clone(src);
633  } else {
634  AVFilterLink *link = input == INPUT_CLEANSRC ? ctx->outputs[0] : ctx->inputs[INPUT_MAIN];
635 
636  dst = ff_get_video_buffer(link, link->w, link->h);
637  if (!dst)
638  return NULL;
639  av_frame_copy_props(dst, src);
640 
641  switch (match) {
642  case mP: copy_fields(fm, dst, src, 1-field, input); copy_fields(fm, dst, prv, field, input); break;
643  case mN: copy_fields(fm, dst, src, 1-field, input); copy_fields(fm, dst, nxt, field, input); break;
644  case mB: copy_fields(fm, dst, src, field, input); copy_fields(fm, dst, prv, 1-field, input); break;
645  case mU: copy_fields(fm, dst, src, field, input); copy_fields(fm, dst, nxt, 1-field, input); break;
646  default: av_assert0(0);
647  }
648  }
649  return dst;
650 }
651 
652 static int checkmm(AVFilterContext *ctx, int *combs, int m1, int m2,
653  AVFrame **gen_frames, int field)
654 {
655  const FieldMatchContext *fm = ctx->priv;
656 
657 #define LOAD_COMB(mid) do { \
658  if (combs[mid] < 0) { \
659  if (!gen_frames[mid]) \
660  gen_frames[mid] = create_weave_frame(ctx, mid, field, \
661  fm->prv, fm->src, fm->nxt, \
662  INPUT_MAIN); \
663  combs[mid] = calc_combed_score(fm, gen_frames[mid]); \
664  } \
665 } while (0)
666 
667  LOAD_COMB(m1);
668  LOAD_COMB(m2);
669 
670  if ((combs[m2] * 3 < combs[m1] || (combs[m2] * 2 < combs[m1] && combs[m1] > fm->combpel)) &&
671  abs(combs[m2] - combs[m1]) >= 30 && combs[m2] < fm->combpel)
672  return m2;
673  else
674  return m1;
675 }
676 
677 static const int fxo0m[] = { mP, mC, mN, mB, mU };
678 static const int fxo1m[] = { mN, mC, mP, mU, mB };
679 
681 {
682  AVFilterContext *ctx = inlink->dst;
683  AVFilterLink *outlink = ctx->outputs[0];
684  FieldMatchContext *fm = ctx->priv;
685  int combs[] = { -1, -1, -1, -1, -1 };
686  int order, field, i, match, interlaced_frame, sc = 0, ret = 0;
687  const int *fxo;
688  AVFrame *gen_frames[] = { NULL, NULL, NULL, NULL, NULL };
689  AVFrame *dst = NULL;
690 
691  /* update frames queue(s) */
692 #define SLIDING_FRAME_WINDOW(prv, src, nxt) do { \
693  if (prv != src) /* 2nd loop exception (1st has prv==src and we don't want to loose src) */ \
694  av_frame_free(&prv); \
695  prv = src; \
696  src = nxt; \
697  if (in) \
698  nxt = in; \
699  if (!prv) \
700  prv = src; \
701  if (!prv) /* received only one frame at that point */ \
702  return 0; \
703  av_assert0(prv && src && nxt); \
704 } while (0)
705  if (FF_INLINK_IDX(inlink) == INPUT_MAIN) {
706  av_assert0(fm->got_frame[INPUT_MAIN] == 0);
707  SLIDING_FRAME_WINDOW(fm->prv, fm->src, fm->nxt);
708  fm->got_frame[INPUT_MAIN] = 1;
709  } else {
711  SLIDING_FRAME_WINDOW(fm->prv2, fm->src2, fm->nxt2);
712  fm->got_frame[INPUT_CLEANSRC] = 1;
713  }
714  if (!fm->got_frame[INPUT_MAIN] || (fm->ppsrc && !fm->got_frame[INPUT_CLEANSRC]))
715  return 0;
717  in = fm->src;
718 
719  /* parity */
720  order = fm->order != FM_PARITY_AUTO ? fm->order : ((in->flags & AV_FRAME_FLAG_INTERLACED) ?
721  !!(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1);
722  field = fm->field != FM_PARITY_AUTO ? fm->field : order;
723  av_assert0(order == 0 || order == 1 || field == 0 || field == 1);
724  fxo = field ^ order ? fxo1m : fxo0m;
725 
726  /* debug mode: we generate all the fields combinations and their associated
727  * combed score. XXX: inject as frame metadata? */
728  if (fm->combdbg) {
729  for (i = 0; i < FF_ARRAY_ELEMS(combs); i++) {
730  if (i > mN && fm->combdbg == COMBDBG_PCN)
731  break;
732  gen_frames[i] = create_weave_frame(ctx, i, field, fm->prv, fm->src, fm->nxt, INPUT_MAIN);
733  if (!gen_frames[i]) {
734  ret = AVERROR(ENOMEM);
735  goto fail;
736  }
737  combs[i] = calc_combed_score(fm, gen_frames[i]);
738  }
739  av_log(ctx, AV_LOG_INFO, "COMBS: %3d %3d %3d %3d %3d\n",
740  combs[0], combs[1], combs[2], combs[3], combs[4]);
741  } else {
742  gen_frames[mC] = av_frame_clone(fm->src);
743  if (!gen_frames[mC]) {
744  ret = AVERROR(ENOMEM);
745  goto fail;
746  }
747  }
748 
749  /* p/c selection and optional 3-way p/c/n matches */
750  match = compare_fields(fm, fxo[mC], fxo[mP], field);
751  if (fm->mode == MODE_PCN || fm->mode == MODE_PCN_UB)
752  match = compare_fields(fm, match, fxo[mN], field);
753 
754  /* scene change check */
755  if (fm->combmatch == COMBMATCH_SC) {
756  if (fm->lastn == outlink->frame_count_in - 1) {
757  if (fm->lastscdiff > fm->scthresh)
758  sc = 1;
759  } else if (luma_abs_diff(fm->prv, fm->src) > fm->scthresh) {
760  sc = 1;
761  }
762 
763  if (!sc) {
764  fm->lastn = outlink->frame_count_in;
765  fm->lastscdiff = luma_abs_diff(fm->src, fm->nxt);
766  sc = fm->lastscdiff > fm->scthresh;
767  }
768  }
769 
770  if (fm->combmatch == COMBMATCH_FULL || (fm->combmatch == COMBMATCH_SC && sc)) {
771  switch (fm->mode) {
772  /* 2-way p/c matches */
773  case MODE_PC:
774  match = checkmm(ctx, combs, match, match == fxo[mP] ? fxo[mC] : fxo[mP], gen_frames, field);
775  break;
776  case MODE_PC_N:
777  match = checkmm(ctx, combs, match, fxo[mN], gen_frames, field);
778  break;
779  case MODE_PC_U:
780  match = checkmm(ctx, combs, match, fxo[mU], gen_frames, field);
781  break;
782  case MODE_PC_N_UB:
783  match = checkmm(ctx, combs, match, fxo[mN], gen_frames, field);
784  match = checkmm(ctx, combs, match, fxo[mU], gen_frames, field);
785  match = checkmm(ctx, combs, match, fxo[mB], gen_frames, field);
786  break;
787  /* 3-way p/c/n matches */
788  case MODE_PCN:
789  match = checkmm(ctx, combs, match, match == fxo[mP] ? fxo[mC] : fxo[mP], gen_frames, field);
790  break;
791  case MODE_PCN_UB:
792  match = checkmm(ctx, combs, match, fxo[mU], gen_frames, field);
793  match = checkmm(ctx, combs, match, fxo[mB], gen_frames, field);
794  break;
795  default:
796  av_assert0(0);
797  }
798  }
799 
800  /* keep fields as-is if not matched properly */
801  interlaced_frame = combs[match] >= fm->combpel;
802  if (interlaced_frame && fm->combmatch == COMBMATCH_FULL) {
803  match = mC;
804  }
805 
806  /* get output frame and drop the others */
807  if (fm->ppsrc) {
808  /* field matching was based on a filtered/post-processed input, we now
809  * pick the untouched fields from the clean source */
810  dst = create_weave_frame(ctx, match, field, fm->prv2, fm->src2, fm->nxt2, INPUT_CLEANSRC);
811  } else {
812  if (!gen_frames[match]) { // XXX: is that possible?
813  dst = create_weave_frame(ctx, match, field, fm->prv, fm->src, fm->nxt, INPUT_MAIN);
814  } else {
815  dst = gen_frames[match];
816  gen_frames[match] = NULL;
817  }
818  }
819  if (!dst) {
820  ret = AVERROR(ENOMEM);
821  goto fail;
822  }
823 
824  /* mark the frame we are unable to match properly as interlaced so a proper
825  * de-interlacer can take the relay */
826 #if FF_API_INTERLACED_FRAME
828  dst->interlaced_frame = interlaced_frame;
830 #endif
831  if (interlaced_frame) {
833  av_log(ctx, AV_LOG_WARNING, "Frame #%"PRId64" at %s is still interlaced\n",
834  outlink->frame_count_in, av_ts2timestr(in->pts, &inlink->time_base));
835 #if FF_API_INTERLACED_FRAME
837  dst->top_field_first = field;
839 #endif
840  if (field)
842  else
844  } else
846 
847  av_log(ctx, AV_LOG_DEBUG, "SC:%d | COMBS: %3d %3d %3d %3d %3d (combpel=%d)"
848  " match=%d combed=%s\n", sc, combs[0], combs[1], combs[2], combs[3], combs[4],
849  fm->combpel, match, (dst->flags & AV_FRAME_FLAG_INTERLACED) ? "YES" : "NO");
850 
851 fail:
852  for (i = 0; i < FF_ARRAY_ELEMS(gen_frames); i++)
853  av_frame_free(&gen_frames[i]);
854 
855  if (ret >= 0)
856  return ff_filter_frame(outlink, dst);
857  return ret;
858 }
859 
861 {
862  FieldMatchContext *fm = ctx->priv;
863  AVFrame *frame = NULL;
864  int ret = 0, status;
865  int64_t pts;
866 
868 
869  if ((fm->got_frame[INPUT_MAIN] == 0) &&
870  (ret = ff_inlink_consume_frame(ctx->inputs[INPUT_MAIN], &frame)) > 0) {
871  ret = filter_frame(ctx->inputs[INPUT_MAIN], frame);
872  if (ret < 0)
873  return ret;
874  }
875  if (ret < 0)
876  return ret;
877  if (fm->ppsrc &&
878  (fm->got_frame[INPUT_CLEANSRC] == 0) &&
879  (ret = ff_inlink_consume_frame(ctx->inputs[INPUT_CLEANSRC], &frame)) > 0) {
880  ret = filter_frame(ctx->inputs[INPUT_CLEANSRC], frame);
881  if (ret < 0)
882  return ret;
883  }
884  if (ret < 0) {
885  return ret;
886  } else if (ff_inlink_acknowledge_status(ctx->inputs[INPUT_MAIN], &status, &pts)) {
887  if (status == AVERROR_EOF) { // flushing
888  fm->eof |= 1 << INPUT_MAIN;
889  ret = filter_frame(ctx->inputs[INPUT_MAIN], NULL);
890  }
891  ff_outlink_set_status(ctx->outputs[0], status, pts);
892  return ret;
893  } else if (fm->ppsrc && ff_inlink_acknowledge_status(ctx->inputs[INPUT_CLEANSRC], &status, &pts)) {
894  if (status == AVERROR_EOF) { // flushing
895  fm->eof |= 1 << INPUT_CLEANSRC;
896  ret = filter_frame(ctx->inputs[INPUT_CLEANSRC], NULL);
897  }
898  ff_outlink_set_status(ctx->outputs[0], status, pts);
899  return ret;
900  } else {
901  if (ff_outlink_frame_wanted(ctx->outputs[0])) {
902  if (fm->got_frame[INPUT_MAIN] == 0)
904  if (fm->ppsrc && (fm->got_frame[INPUT_CLEANSRC] == 0))
906  }
907  return 0;
908  }
909 }
910 
912 {
913  FieldMatchContext *fm = ctx->priv;
914 
915  static const enum AVPixelFormat pix_fmts[] = {
919  };
920  static const enum AVPixelFormat unproc_pix_fmts[] = {
935  };
936  int ret;
937 
939  if (!fmts_list)
940  return AVERROR(ENOMEM);
941  if (!fm->ppsrc) {
942  return ff_set_common_formats(ctx, fmts_list);
943  }
944 
945  if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_MAIN]->outcfg.formats)) < 0)
946  return ret;
947  fmts_list = ff_make_format_list(unproc_pix_fmts);
948  if (!fmts_list)
949  return AVERROR(ENOMEM);
950  if ((ret = ff_formats_ref(fmts_list, &ctx->outputs[0]->incfg.formats)) < 0)
951  return ret;
952  if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_CLEANSRC]->outcfg.formats)) < 0)
953  return ret;
954  return 0;
955 }
956 
958 {
959  int ret;
960  AVFilterContext *ctx = inlink->dst;
961  FieldMatchContext *fm = ctx->priv;
962  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
963  const int w = inlink->w;
964  const int h = inlink->h;
965 
966  fm->scthresh = (int64_t)((w * h * 255.0 * fm->scthresh_flt) / 100.0);
967 
968  if ((ret = av_image_alloc(fm->map_data, fm->map_linesize, w, h, inlink->format, 32)) < 0 ||
969  (ret = av_image_alloc(fm->cmask_data, fm->cmask_linesize, w, h, inlink->format, 32)) < 0)
970  return ret;
971 
972  fm->hsub[INPUT_MAIN] = pix_desc->log2_chroma_w;
973  fm->vsub[INPUT_MAIN] = pix_desc->log2_chroma_h;
974  if (fm->ppsrc) {
975  pix_desc = av_pix_fmt_desc_get(ctx->inputs[INPUT_CLEANSRC]->format);
976  fm->hsub[INPUT_CLEANSRC] = pix_desc->log2_chroma_w;
977  fm->vsub[INPUT_CLEANSRC] = pix_desc->log2_chroma_h;
978  }
979 
980  fm->tpitchy = FFALIGN(w, 16);
981  fm->tpitchuv = FFALIGN(w >> 1, 16);
982 
983  fm->tbuffer = av_calloc((h/2 + 4) * fm->tpitchy, sizeof(*fm->tbuffer));
984  fm->c_array = av_malloc_array((((w + fm->blockx/2)/fm->blockx)+1) *
985  (((h + fm->blocky/2)/fm->blocky)+1),
986  4 * sizeof(*fm->c_array));
987  if (!fm->tbuffer || !fm->c_array)
988  return AVERROR(ENOMEM);
989 
990  return 0;
991 }
992 
994 {
995  const FieldMatchContext *fm = ctx->priv;
996  AVFilterPad pad = {
997  .name = "main",
998  .type = AVMEDIA_TYPE_VIDEO,
999  .config_props = config_input,
1000  };
1001  int ret;
1002 
1003  if ((ret = ff_append_inpad(ctx, &pad)) < 0)
1004  return ret;
1005 
1006  if (fm->ppsrc) {
1007  pad.name = "clean_src";
1008  pad.config_props = NULL;
1009  if ((ret = ff_append_inpad(ctx, &pad)) < 0)
1010  return ret;
1011  }
1012 
1013  if ((fm->blockx & (fm->blockx - 1)) ||
1014  (fm->blocky & (fm->blocky - 1))) {
1015  av_log(ctx, AV_LOG_ERROR, "blockx and blocky settings must be power of two\n");
1016  return AVERROR(EINVAL);
1017  }
1018 
1019  if (fm->combpel > fm->blockx * fm->blocky) {
1020  av_log(ctx, AV_LOG_ERROR, "Combed pixel should not be larger than blockx x blocky\n");
1021  return AVERROR(EINVAL);
1022  }
1023 
1024  return 0;
1025 }
1026 
1028 {
1029  FieldMatchContext *fm = ctx->priv;
1030 
1031  if (fm->prv != fm->src)
1032  av_frame_free(&fm->prv);
1033  if (fm->nxt != fm->src)
1034  av_frame_free(&fm->nxt);
1035  if (fm->prv2 != fm->src2)
1036  av_frame_free(&fm->prv2);
1037  if (fm->nxt2 != fm->src2)
1038  av_frame_free(&fm->nxt2);
1039  av_frame_free(&fm->src);
1040  av_frame_free(&fm->src2);
1041  av_freep(&fm->map_data[0]);
1042  av_freep(&fm->cmask_data[0]);
1043  av_freep(&fm->tbuffer);
1044  av_freep(&fm->c_array);
1045 }
1046 
1047 static int config_output(AVFilterLink *outlink)
1048 {
1049  AVFilterContext *ctx = outlink->src;
1050  FieldMatchContext *fm = ctx->priv;
1051  const AVFilterLink *inlink =
1052  ctx->inputs[fm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN];
1054 
1055  fm->bpc = (desc->comp[0].depth + 7) / 8;
1056  outlink->time_base = inlink->time_base;
1057  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
1058  outlink->frame_rate = inlink->frame_rate;
1059  outlink->w = inlink->w;
1060  outlink->h = inlink->h;
1061  return 0;
1062 }
1063 
1065  {
1066  .name = "default",
1067  .type = AVMEDIA_TYPE_VIDEO,
1068  .config_props = config_output,
1069  },
1070 };
1071 
1073  .name = "fieldmatch",
1074  .description = NULL_IF_CONFIG_SMALL("Field matching for inverse telecine."),
1075  .priv_size = sizeof(FieldMatchContext),
1076  .init = fieldmatch_init,
1077  .activate = activate,
1079  .inputs = NULL,
1082  .priv_class = &fieldmatch_class,
1084 };
FieldMatchContext::order
int order
Definition: vf_fieldmatch.c:92
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:112
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
FieldMatchContext::mode
int mode
matching_mode
Definition: vf_fieldmatch.c:94
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
build_diff_map
static void build_diff_map(FieldMatchContext *fm, const uint8_t *prvp, int prv_linesize, const uint8_t *nxtp, int nxt_linesize, uint8_t *dstp, int dst_linesize, int height, int width, int plane)
Build a map over which pixels differ a lot/a little.
Definition: vf_fieldmatch.c:418
FLAGS
#define FLAGS
Definition: vf_fieldmatch.c:118
acc
int acc
Definition: yuv2rgb.c:553
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:436
FieldMatchContext::blocky
int blocky
Definition: vf_fieldmatch.c:104
NB_COMBMATCH
@ NB_COMBMATCH
Definition: vf_fieldmatch.c:69
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:251
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2965
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
FieldMatchContext::mchroma
int mchroma
Definition: vf_fieldmatch.c:96
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
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
build_abs_diff_mask
static void build_abs_diff_mask(const uint8_t *prvp, int prv_linesize, const uint8_t *nxtp, int nxt_linesize, uint8_t *tbuffer, int tbuf_linesize, int width, int height)
Definition: vf_fieldmatch.c:397
FieldMatchContext::src
AVFrame * src
Definition: vf_fieldmatch.c:82
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:486
AVFrame::width
int width
Definition: frame.h:446
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:346
chroma
static av_always_inline void chroma(WaveformContext *s, AVFrame *in, AVFrame *out, int component, int intensity, int offset_y, int offset_x, int column, int mirror, int jobnr, int nb_jobs)
Definition: vf_waveform.c:1639
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:159
COMBDBG_PCN
@ COMBDBG_PCN
Definition: vf_fieldmatch.c:74
data
const char data[16]
Definition: mxf.c:148
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:478
LOAD_COMB
#define LOAD_COMB(mid)
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
activate
static int activate(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:860
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:646
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
c1
static const uint64_t c1
Definition: murmur3.c:52
MODE_PC_U
@ MODE_PC_U
Definition: vf_fieldmatch.c:58
video.h
compare_fields
static int compare_fields(FieldMatchContext *fm, int match1, int match2, int field)
Definition: vf_fieldmatch.c:490
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:395
av_image_copy_plane
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:374
FieldMatchContext::map_data
uint8_t * map_data[4]
Definition: vf_fieldmatch.c:108
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:638
formats.h
ff_inlink_consume_frame
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1442
FF_FILTER_FORWARD_STATUS_BACK_ALL
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
Definition: filters.h:212
MODE_PCN_UB
@ MODE_PCN_UB
Definition: vf_fieldmatch.c:61
ff_append_inpad
int ff_append_inpad(AVFilterContext *f, AVFilterPad *p)
Append a new input/output pad to the filter's list of such pads.
Definition: avfilter.c:127
fxo0m
static const int fxo0m[]
Definition: vf_fieldmatch.c:677
MODE_PC
@ MODE_PC
Definition: vf_fieldmatch.c:56
checkmm
static int checkmm(AVFilterContext *ctx, int *combs, int m1, int m2, AVFrame **gen_frames, int field)
Definition: vf_fieldmatch.c:652
fail
#define fail()
Definition: checkasm.h:179
FieldMatchContext::src2
AVFrame * src2
Definition: vf_fieldmatch.c:83
copy_fields
static void copy_fields(const FieldMatchContext *fm, AVFrame *dst, const AVFrame *src, int field, int input)
Definition: vf_fieldmatch.c:612
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:476
NB_COMBDBG
@ NB_COMBDBG
Definition: vf_fieldmatch.c:76
FieldMatchContext::cmask_data
uint8_t * cmask_data[4]
Definition: vf_fieldmatch.c:110
HAS_FF_AROUND
#define HAS_FF_AROUND(p, lz)
pts
static int64_t pts
Definition: transcode_aac.c:644
AVFILTER_FLAG_DYNAMIC_INPUTS
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
Definition: avfilter.h:106
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:481
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:283
AVFrame::interlaced_frame
attribute_deprecated int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:551
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:490
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:868
FieldMatchContext::y1
int y1
Definition: vf_fieldmatch.c:97
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
float
float
Definition: af_crystalizer.c:121
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
FieldMatchContext::map_linesize
int map_linesize[4]
Definition: vf_fieldmatch.c:109
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1568
width
#define width
FieldMatchContext::scthresh_flt
double scthresh_flt
Definition: vf_fieldmatch.c:99
get_height
static int get_height(const FieldMatchContext *fm, const AVFrame *f, int plane, int input)
Definition: vf_fieldmatch.c:164
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:491
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:59
OFFSET
#define OFFSET(x)
Definition: vf_fieldmatch.c:117
fieldmatch_parity
fieldmatch_parity
Definition: vf_fieldmatch.c:49
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:237
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_fieldmatch.c:1047
s1
#define s1
Definition: regdef.h:38
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:679
fieldmatch_outputs
static const AVFilterPad fieldmatch_outputs[]
Definition: vf_fieldmatch.c:1064
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
filters.h
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:304
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:475
mN
@ mN
Definition: vf_fieldmatch.c:476
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
FieldMatchContext::chroma
int chroma
Definition: vf_fieldmatch.c:103
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:489
ctx
AVFormatContext * ctx
Definition: movenc.c:49
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:593
field
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this field
Definition: writing_filters.txt:78
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
MODE_PC_N_UB
@ MODE_PC_N_UB
Definition: vf_fieldmatch.c:59
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
link
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 link
Definition: filter_design.txt:23
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
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:73
FM_PARITY_AUTO
@ FM_PARITY_AUTO
Definition: vf_fieldmatch.c:50
FieldMatchContext::nxt
AVFrame * nxt
main sliding window of 3 frames
Definition: vf_fieldmatch.c:82
FieldMatchContext::hsub
int hsub[2]
Definition: vf_fieldmatch.c:85
COMBMATCH_SC
@ COMBMATCH_SC
Definition: vf_fieldmatch.c:67
fieldmatch_options
static const AVOption fieldmatch_options[]
Definition: vf_fieldmatch.c:120
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:709
FieldMatchContext::scthresh
int64_t scthresh
Definition: vf_fieldmatch.c:98
FieldMatchContext::combmatch
int combmatch
comb_matching_mode
Definition: vf_fieldmatch.c:100
fill_buf
static void fill_buf(uint8_t *data, int w, int h, int linesize, uint8_t v)
Definition: vf_fieldmatch.c:189
FieldMatchContext::field
int field
Definition: vf_fieldmatch.c:95
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
FieldMatchContext::bpc
int bpc
bytes per component
Definition: vf_fieldmatch.c:86
FieldMatchContext::combpel
int combpel
Definition: vf_fieldmatch.c:105
AV_PIX_FMT_YUV440P10
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:480
FieldMatchContext::ppsrc
int ppsrc
Definition: vf_fieldmatch.c:93
FieldMatchContext::got_frame
int got_frame[2]
frame request flag for each input stream
Definition: vf_fieldmatch.c:84
abs
#define abs(x)
Definition: cuda_runtime.h:35
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:479
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
COMBMATCH_FULL
@ COMBMATCH_FULL
Definition: vf_fieldmatch.c:68
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1389
FieldMatchContext::vsub
int vsub[2]
chroma subsampling values
Definition: vf_fieldmatch.c:85
FieldMatchContext
Definition: vf_fieldmatch.c:79
comb_dbg
comb_dbg
Definition: vf_fieldmatch.c:72
av_image_alloc
int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align)
Allocate an image with size w and h and pixel format pix_fmt, and fill pointers and linesizes accordi...
Definition: imgutils.c:218
AVFilterPad::config_props
int(* config_props)(AVFilterLink *link)
Link configuration callback.
Definition: internal.h:113
s2
#define s2
Definition: regdef.h:39
NB_MODE
@ NB_MODE
Definition: vf_fieldmatch.c:62
mP
@ mP
Definition: vf_fieldmatch.c:476
f
f
Definition: af_crystalizer.c:121
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
av_ts2timestr
#define av_ts2timestr(ts, tb)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: timestamp.h:83
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:94
MODE_PC_N
@ MODE_PC_N
Definition: vf_fieldmatch.c:57
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:483
ff_vf_fieldmatch
const AVFilter ff_vf_fieldmatch
Definition: vf_fieldmatch.c:1072
comb_matching_mode
comb_matching_mode
Definition: vf_fieldmatch.c:65
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:485
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_fieldmatch.c:957
FieldMatchContext::tbuffer
uint8_t * tbuffer
Definition: vf_fieldmatch.c:114
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:165
FieldMatchContext::cthresh
int cthresh
Definition: vf_fieldmatch.c:102
height
#define height
FM_PARITY_BOTTOM
@ FM_PARITY_BOTTOM
Definition: vf_fieldmatch.c:51
INPUT_MAIN
#define INPUT_MAIN
Definition: vf_fieldmatch.c:46
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:911
FieldMatchContext::nxt2
AVFrame * nxt2
sliding window of the optional second stream
Definition: vf_fieldmatch.c:83
FieldMatchContext::blockx
int blockx
Definition: vf_fieldmatch.c:104
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
C_ARRAY_ADD
#define C_ARRAY_ADD(v)
matching_mode
matching_mode
Definition: vf_fieldmatch.c:55
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
internal.h
get_field_base
static int get_field_base(int match, int field)
Definition: vf_fieldmatch.c:478
mU
@ mU
Definition: vf_fieldmatch.c:476
COMBDBG_PCNUB
@ COMBDBG_PCNUB
Definition: vf_fieldmatch.c:75
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
SLIDING_FRAME_WINDOW
#define SLIDING_FRAME_WINDOW(prv, src, nxt)
mC
@ mC
Definition: vf_fieldmatch.c:476
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FieldMatchContext::tpitchuv
int tpitchuv
Definition: vf_fieldmatch.c:113
AVFrame::top_field_first
attribute_deprecated int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:559
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:107
MODE_PCN
@ MODE_PCN
Definition: vf_fieldmatch.c:60
INPUT_CLEANSRC
#define INPUT_CLEANSRC
Definition: vf_fieldmatch.c:47
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:633
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:477
create_weave_frame
static AVFrame * create_weave_frame(AVFilterContext *ctx, int match, int field, const AVFrame *prv, AVFrame *src, const AVFrame *nxt, int input)
Definition: vf_fieldmatch.c:625
AVFilter
Filter definition.
Definition: avfilter.h:166
VERTICAL_HALF
#define VERTICAL_HALF(y_start, y_end)
ret
ret
Definition: filter_design.txt:187
FieldMatchContext::combdbg
int combdbg
Definition: vf_fieldmatch.c:101
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
FieldMatchContext::c_array
int * c_array
Definition: vf_fieldmatch.c:112
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:482
FieldMatchContext::prv
AVFrame * prv
Definition: vf_fieldmatch.c:82
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:487
fxo1m
static const int fxo1m[]
Definition: vf_fieldmatch.c:678
AVFrame::height
int height
Definition: frame.h:446
c2
static const uint64_t c2
Definition: murmur3.c:53
status
ov_status_e status
Definition: dnn_backend_openvino.c:121
luma_abs_diff
static int64_t luma_abs_diff(const AVFrame *f1, const AVFrame *f2)
Definition: vf_fieldmatch.c:169
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
FF_INLINK_IDX
#define FF_INLINK_IDX(link)
Find the index of a link.
Definition: internal.h:331
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avfilter.h
FieldMatchContext::prv2
AVFrame * prv2
Definition: vf_fieldmatch.c:83
FieldMatchContext::cmask_linesize
int cmask_linesize[4]
Definition: vf_fieldmatch.c:111
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_fieldmatch.c:680
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
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
FM_PARITY_TOP
@ FM_PARITY_TOP
Definition: vf_fieldmatch.c:52
desc
const char * desc
Definition: libsvtav1.c:79
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(fieldmatch)
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
mem.h
FieldMatchContext::y0
int y0
Definition: vf_fieldmatch.c:97
fieldmatch_uninit
static av_cold void fieldmatch_uninit(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:1027
fieldmatch_init
static av_cold int fieldmatch_init(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:993
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FieldMatchContext::lastscdiff
int64_t lastscdiff
Definition: vf_fieldmatch.c:88
select_frame
static AVFrame * select_frame(FieldMatchContext *fm, int match)
Definition: vf_fieldmatch.c:483
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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
FILTER
#define FILTER(xm2, xm1, xp1, xp2)
get_width
static int get_width(const FieldMatchContext *fm, const AVFrame *f, int plane, int input)
Definition: vf_fieldmatch.c:159
imgutils.h
timestamp.h
FieldMatchContext::tpitchy
int tpitchy
Definition: vf_fieldmatch.c:113
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:419
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
COMBMATCH_NONE
@ COMBMATCH_NONE
Definition: vf_fieldmatch.c:66
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:484
h
h
Definition: vp9dsp_template.c:2038
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:488
FieldMatchContext::eof
uint32_t eof
bitmask for end of stream
Definition: vf_fieldmatch.c:87
mB
@ mB
Definition: vf_fieldmatch.c:476
int
int
Definition: ffmpeg_filter.c:424
FieldMatchContext::lastn
int64_t lastn
Definition: vf_fieldmatch.c:89
calc_combed_score
static int calc_combed_score(const FieldMatchContext *fm, const AVFrame *src)
Definition: vf_fieldmatch.c:199
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
COMBDBG_NONE
@ COMBDBG_NONE
Definition: vf_fieldmatch.c:73
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:486