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 "video.h"
44 
45 #define INPUT_MAIN 0
46 #define INPUT_CLEANSRC 1
47 
52 };
53 
62 };
63 
69 };
70 
71 enum comb_dbg {
76 };
77 
78 typedef struct FieldMatchContext {
79  const AVClass *class;
80 
81  AVFrame *prv, *src, *nxt; ///< main sliding window of 3 frames
82  AVFrame *prv2, *src2, *nxt2; ///< sliding window of the optional second stream
83  int got_frame[2]; ///< frame request flag for each input stream
84  int hsub[2], vsub[2]; ///< chroma subsampling values
85  int bpc; ///< bytes per component
86  uint32_t eof; ///< bitmask for end of stream
89 
90  /* options */
91  int order;
92  int ppsrc;
93  int mode; ///< matching_mode
94  int field;
95  int mchroma;
96  int y0, y1;
98  double scthresh_flt;
99  int combmatch; ///< comb_matching_mode
100  int combdbg;
101  int cthresh;
102  int chroma;
104  int combpel;
105 
106  /* misc buffers */
107  uint8_t *map_data[4];
108  int map_linesize[4];
109  uint8_t *cmask_data[4];
111  int *c_array;
113  uint8_t *tbuffer;
115 
116 #define OFFSET(x) offsetof(FieldMatchContext, x)
117 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
118 
119 static const AVOption fieldmatch_options[] = {
120  { "order", "specify the assumed field order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=FM_PARITY_AUTO}, -1, 1, FLAGS, .unit = "order" },
121  { "auto", "auto detect parity", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_AUTO}, INT_MIN, INT_MAX, FLAGS, .unit = "order" },
122  { "bff", "assume bottom field first", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_BOTTOM}, INT_MIN, INT_MAX, FLAGS, .unit = "order" },
123  { "tff", "assume top field first", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_TOP}, INT_MIN, INT_MAX, FLAGS, .unit = "order" },
124  { "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" },
125  { "pc", "2-way match (p/c)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PC}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
126  { "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" },
127  { "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" },
128  { "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" },
129  { "pcn", "3-way match (p/c/n)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PCN}, INT_MIN, INT_MAX, FLAGS, .unit = "mode" },
130  { "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" },
131  { "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 },
132  { "field", "set the field to match from", OFFSET(field), AV_OPT_TYPE_INT, {.i64=FM_PARITY_AUTO}, -1, 1, FLAGS, .unit = "field" },
133  { "auto", "automatic (same value as 'order')", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_AUTO}, INT_MIN, INT_MAX, FLAGS, .unit = "field" },
134  { "bottom", "bottom field", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_BOTTOM}, INT_MIN, INT_MAX, FLAGS, .unit = "field" },
135  { "top", "top field", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_TOP}, INT_MIN, INT_MAX, FLAGS, .unit = "field" },
136  { "mchroma", "set whether or not chroma is included during the match comparisons", OFFSET(mchroma), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
137  { "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 },
138  { "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 },
139  { "scthresh", "set scene change detection threshold", OFFSET(scthresh_flt), AV_OPT_TYPE_DOUBLE, {.dbl=12}, 0, 100, FLAGS },
140  { "combmatch", "set combmatching mode", OFFSET(combmatch), AV_OPT_TYPE_INT, {.i64=COMBMATCH_SC}, COMBMATCH_NONE, NB_COMBMATCH-1, FLAGS, .unit = "combmatching" },
141  { "none", "disable combmatching", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_NONE}, INT_MIN, INT_MAX, FLAGS, .unit = "combmatching" },
142  { "sc", "enable combmatching only on scene change", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_SC}, INT_MIN, INT_MAX, FLAGS, .unit = "combmatching" },
143  { "full", "enable combmatching all the time", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_FULL}, INT_MIN, INT_MAX, FLAGS, .unit = "combmatching" },
144  { "combdbg", "enable comb debug", OFFSET(combdbg), AV_OPT_TYPE_INT, {.i64=COMBDBG_NONE}, COMBDBG_NONE, NB_COMBDBG-1, FLAGS, .unit = "dbglvl" },
145  { "none", "no forced calculation", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_NONE}, INT_MIN, INT_MAX, FLAGS, .unit = "dbglvl" },
146  { "pcn", "calculate p/c/n", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_PCN}, INT_MIN, INT_MAX, FLAGS, .unit = "dbglvl" },
147  { "pcnub", "calculate p/c/n/u/b", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_PCNUB}, INT_MIN, INT_MAX, FLAGS, .unit = "dbglvl" },
148  { "cthresh", "set the area combing threshold used for combed frame detection", OFFSET(cthresh), AV_OPT_TYPE_INT, {.i64= 9}, -1, 0xff, FLAGS },
149  { "chroma", "set whether or not chroma is considered in the combed frame decision", OFFSET(chroma), AV_OPT_TYPE_BOOL,{.i64= 0}, 0, 1, FLAGS },
150  { "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 },
151  { "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 },
152  { "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 },
153  { NULL }
154 };
155 
156 AVFILTER_DEFINE_CLASS(fieldmatch);
157 
158 static int get_width(const FieldMatchContext *fm, const AVFrame *f, int plane, int input)
159 {
160  return plane ? AV_CEIL_RSHIFT(f->width, fm->hsub[input]) : f->width;
161 }
162 
163 static int get_height(const FieldMatchContext *fm, const AVFrame *f, int plane, int input)
164 {
165  return plane ? AV_CEIL_RSHIFT(f->height, fm->vsub[input]) : f->height;
166 }
167 
168 static int64_t luma_abs_diff(const AVFrame *f1, const AVFrame *f2)
169 {
170  int x, y;
171  const uint8_t *srcp1 = f1->data[0];
172  const uint8_t *srcp2 = f2->data[0];
173  const int src1_linesize = f1->linesize[0];
174  const int src2_linesize = f2->linesize[0];
175  const int width = f1->width;
176  const int height = f1->height;
177  int64_t acc = 0;
178 
179  for (y = 0; y < height; y++) {
180  for (x = 0; x < width; x++)
181  acc += abs(srcp1[x] - srcp2[x]);
182  srcp1 += src1_linesize;
183  srcp2 += src2_linesize;
184  }
185  return acc;
186 }
187 
188 static void fill_buf(uint8_t *data, int w, int h, int linesize, uint8_t v)
189 {
190  int y;
191 
192  for (y = 0; y < h; y++) {
193  memset(data, v, w);
194  data += linesize;
195  }
196 }
197 
198 static int calc_combed_score(const FieldMatchContext *fm, const AVFrame *src)
199 {
200  int x, y, plane, max_v = 0;
201  const int cthresh = fm->cthresh;
202  const int cthresh6 = cthresh * 6;
203 
204  for (plane = 0; plane < (fm->chroma ? 3 : 1); plane++) {
205  const uint8_t *srcp = src->data[plane];
206  const int src_linesize = src->linesize[plane];
207  const int width = get_width (fm, src, plane, INPUT_MAIN);
208  const int height = get_height(fm, src, plane, INPUT_MAIN);
209  uint8_t *cmkp = fm->cmask_data[plane];
210  const int cmk_linesize = fm->cmask_linesize[plane];
211 
212  if (cthresh < 0) {
213  fill_buf(cmkp, width, height, cmk_linesize, 0xff);
214  continue;
215  }
216  fill_buf(cmkp, width, height, cmk_linesize, 0);
217 
218  /* [1 -3 4 -3 1] vertical filter */
219 #define FILTER(xm2, xm1, xp1, xp2) \
220  abs( 4 * srcp[x] \
221  -3 * (srcp[x + (xm1)*src_linesize] + srcp[x + (xp1)*src_linesize]) \
222  + (srcp[x + (xm2)*src_linesize] + srcp[x + (xp2)*src_linesize])) > cthresh6
223 
224  /* first line */
225  for (x = 0; x < width; x++) {
226  const int s1 = abs(srcp[x] - srcp[x + src_linesize]);
227  if (s1 > cthresh && FILTER(2, 1, 1, 2))
228  cmkp[x] = 0xff;
229  }
230  srcp += src_linesize;
231  cmkp += cmk_linesize;
232 
233  /* second line */
234  for (x = 0; x < width; x++) {
235  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
236  const int s2 = abs(srcp[x] - srcp[x + src_linesize]);
237  if (s1 > cthresh && s2 > cthresh && FILTER(2, -1, 1, 2))
238  cmkp[x] = 0xff;
239  }
240  srcp += src_linesize;
241  cmkp += cmk_linesize;
242 
243  /* all lines minus first two and last two */
244  for (y = 2; y < height-2; y++) {
245  for (x = 0; x < width; x++) {
246  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
247  const int s2 = abs(srcp[x] - srcp[x + src_linesize]);
248  if (s1 > cthresh && s2 > cthresh && FILTER(-2, -1, 1, 2))
249  cmkp[x] = 0xff;
250  }
251  srcp += src_linesize;
252  cmkp += cmk_linesize;
253  }
254 
255  /* before-last line */
256  for (x = 0; x < width; x++) {
257  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
258  const int s2 = abs(srcp[x] - srcp[x + src_linesize]);
259  if (s1 > cthresh && s2 > cthresh && FILTER(-2, -1, 1, -2))
260  cmkp[x] = 0xff;
261  }
262  srcp += src_linesize;
263  cmkp += cmk_linesize;
264 
265  /* last line */
266  for (x = 0; x < width; x++) {
267  const int s1 = abs(srcp[x] - srcp[x - src_linesize]);
268  if (s1 > cthresh && FILTER(-2, -1, -1, -2))
269  cmkp[x] = 0xff;
270  }
271  }
272 
273  if (fm->chroma) {
274  uint8_t *cmkp = fm->cmask_data[0];
275  uint8_t *cmkpU = fm->cmask_data[1];
276  uint8_t *cmkpV = fm->cmask_data[2];
277  const int width = AV_CEIL_RSHIFT(src->width, fm->hsub[INPUT_MAIN]);
278  const int height = AV_CEIL_RSHIFT(src->height, fm->vsub[INPUT_MAIN]);
279  const int cmk_linesize = fm->cmask_linesize[0] << 1;
280  const int cmk_linesizeUV = fm->cmask_linesize[2];
281  uint8_t *cmkpp = cmkp - (cmk_linesize>>1);
282  uint8_t *cmkpn = cmkp + (cmk_linesize>>1);
283  uint8_t *cmkpnn = cmkp + cmk_linesize;
284  for (y = 1; y < height - 1; y++) {
285  cmkpp += cmk_linesize;
286  cmkp += cmk_linesize;
287  cmkpn += cmk_linesize;
288  cmkpnn += cmk_linesize;
289  cmkpV += cmk_linesizeUV;
290  cmkpU += cmk_linesizeUV;
291  for (x = 1; x < width - 1; x++) {
292 #define HAS_FF_AROUND(p, lz) (p[(x)-1 - (lz)] == 0xff || p[(x) - (lz)] == 0xff || p[(x)+1 - (lz)] == 0xff || \
293  p[(x)-1 ] == 0xff || p[(x)+1 ] == 0xff || \
294  p[(x)-1 + (lz)] == 0xff || p[(x) + (lz)] == 0xff || p[(x)+1 + (lz)] == 0xff)
295  if ((cmkpV[x] == 0xff && HAS_FF_AROUND(cmkpV, cmk_linesizeUV)) ||
296  (cmkpU[x] == 0xff && HAS_FF_AROUND(cmkpU, cmk_linesizeUV))) {
297  ((uint16_t*)cmkp)[x] = 0xffff;
298  ((uint16_t*)cmkpn)[x] = 0xffff;
299  if (y&1) ((uint16_t*)cmkpp)[x] = 0xffff;
300  else ((uint16_t*)cmkpnn)[x] = 0xffff;
301  }
302  }
303  }
304  }
305 
306  {
307  const int blockx = fm->blockx;
308  const int blocky = fm->blocky;
309  const int xhalf = blockx/2;
310  const int yhalf = blocky/2;
311  const int cmk_linesize = fm->cmask_linesize[0];
312  const uint8_t *cmkp = fm->cmask_data[0] + cmk_linesize;
313  const int width = src->width;
314  const int height = src->height;
315  const int xblocks = ((width+xhalf)/blockx) + 1;
316  const int xblocks4 = xblocks<<2;
317  const int yblocks = ((height+yhalf)/blocky) + 1;
318  int *c_array = fm->c_array;
319  const int arraysize = (xblocks*yblocks)<<2;
320  int heighta = (height/(blocky/2))*(blocky/2);
321  const int widtha = (width /(blockx/2))*(blockx/2);
322  if (heighta == height)
323  heighta = height - yhalf;
324  memset(c_array, 0, arraysize * sizeof(*c_array));
325 
326 #define C_ARRAY_ADD(v) do { \
327  const int box1 = (x / blockx) * 4; \
328  const int box2 = ((x + xhalf) / blockx) * 4; \
329  c_array[temp1 + box1 ] += v; \
330  c_array[temp1 + box2 + 1] += v; \
331  c_array[temp2 + box1 + 2] += v; \
332  c_array[temp2 + box2 + 3] += v; \
333 } while (0)
334 
335 #define VERTICAL_HALF(y_start, y_end) do { \
336  for (y = y_start; y < y_end; y++) { \
337  const int temp1 = (y / blocky) * xblocks4; \
338  const int temp2 = ((y + yhalf) / blocky) * xblocks4; \
339  for (x = 0; x < width; x++) \
340  if (cmkp[x - cmk_linesize] == 0xff && \
341  cmkp[x ] == 0xff && \
342  cmkp[x + cmk_linesize] == 0xff) \
343  C_ARRAY_ADD(1); \
344  cmkp += cmk_linesize; \
345  } \
346 } while (0)
347 
348  VERTICAL_HALF(1, yhalf);
349 
350  for (y = yhalf; y < heighta; y += yhalf) {
351  const int temp1 = (y / blocky) * xblocks4;
352  const int temp2 = ((y + yhalf) / blocky) * xblocks4;
353 
354  for (x = 0; x < widtha; x += xhalf) {
355  const uint8_t *cmkp_tmp = cmkp + x;
356  int u, v, sum = 0;
357  for (u = 0; u < yhalf; u++) {
358  for (v = 0; v < xhalf; v++)
359  if (cmkp_tmp[v - cmk_linesize] == 0xff &&
360  cmkp_tmp[v ] == 0xff &&
361  cmkp_tmp[v + cmk_linesize] == 0xff)
362  sum++;
363  cmkp_tmp += cmk_linesize;
364  }
365  if (sum)
366  C_ARRAY_ADD(sum);
367  }
368 
369  for (x = widtha; x < width; x++) {
370  const uint8_t *cmkp_tmp = cmkp + x;
371  int u, sum = 0;
372  for (u = 0; u < yhalf; u++) {
373  if (cmkp_tmp[-cmk_linesize] == 0xff &&
374  cmkp_tmp[ 0] == 0xff &&
375  cmkp_tmp[ cmk_linesize] == 0xff)
376  sum++;
377  cmkp_tmp += cmk_linesize;
378  }
379  if (sum)
380  C_ARRAY_ADD(sum);
381  }
382 
383  cmkp += cmk_linesize * yhalf;
384  }
385 
386  VERTICAL_HALF(heighta, height - 1);
387 
388  for (x = 0; x < arraysize; x++)
389  if (c_array[x] > max_v)
390  max_v = c_array[x];
391  }
392  return max_v;
393 }
394 
395 // the secret is that tbuffer is an interlaced, offset subset of all the lines
396 static void build_abs_diff_mask(const uint8_t *prvp, int prv_linesize,
397  const uint8_t *nxtp, int nxt_linesize,
398  uint8_t *tbuffer, int tbuf_linesize,
399  int width, int height)
400 {
401  int y, x;
402 
403  prvp -= prv_linesize;
404  nxtp -= nxt_linesize;
405  for (y = 0; y < height; y++) {
406  for (x = 0; x < width; x++)
407  tbuffer[x] = FFABS(prvp[x] - nxtp[x]);
408  prvp += prv_linesize;
409  nxtp += nxt_linesize;
410  tbuffer += tbuf_linesize;
411  }
412 }
413 
414 /**
415  * Build a map over which pixels differ a lot/a little
416  */
418  const uint8_t *prvp, int prv_linesize,
419  const uint8_t *nxtp, int nxt_linesize,
420  uint8_t *dstp, int dst_linesize, int height,
421  int width, int plane)
422 {
423  int x, y, u, diff, count;
424  int tpitch = plane ? fm->tpitchuv : fm->tpitchy;
425  const uint8_t *dp = fm->tbuffer + tpitch;
426 
427  build_abs_diff_mask(prvp, prv_linesize, nxtp, nxt_linesize,
428  fm->tbuffer, tpitch, width, height>>1);
429 
430  for (y = 2; y < height - 2; y += 2) {
431  for (x = 1; x < width - 1; x++) {
432  diff = dp[x];
433  if (diff > 3) {
434  for (count = 0, u = x-1; u < x+2 && count < 2; u++) {
435  count += dp[u-tpitch] > 3;
436  count += dp[u ] > 3;
437  count += dp[u+tpitch] > 3;
438  }
439  if (count > 1) {
440  dstp[x] = 1;
441  if (diff > 19) {
442  int upper = 0, lower = 0;
443  for (count = 0, u = x-1; u < x+2 && count < 6; u++) {
444  if (dp[u-tpitch] > 19) { count++; upper = 1; }
445  if (dp[u ] > 19) count++;
446  if (dp[u+tpitch] > 19) { count++; lower = 1; }
447  }
448  if (count > 3) {
449  if (upper && lower) {
450  dstp[x] |= 1<<1;
451  } else {
452  int upper2 = 0, lower2 = 0;
453  for (u = FFMAX(x-4,0); u < FFMIN(x+5,width); u++) {
454  if (y != 2 && dp[u-2*tpitch] > 19) upper2 = 1;
455  if ( dp[u- tpitch] > 19) upper = 1;
456  if ( dp[u+ tpitch] > 19) lower = 1;
457  if (y != height-4 && dp[u+2*tpitch] > 19) lower2 = 1;
458  }
459  if ((upper && (lower || upper2)) ||
460  (lower && (upper || lower2)))
461  dstp[x] |= 1<<1;
462  else if (count > 5)
463  dstp[x] |= 1<<2;
464  }
465  }
466  }
467  }
468  }
469  }
470  dp += tpitch;
471  dstp += dst_linesize;
472  }
473 }
474 
475 enum { mP, mC, mN, mB, mU };
476 
477 static int get_field_base(int match, int field)
478 {
479  return match < 3 ? 2 - field : 1 + field;
480 }
481 
482 static AVFrame *select_frame(FieldMatchContext *fm, int match)
483 {
484  if (match == mP || match == mB) return fm->prv;
485  else if (match == mN || match == mU) return fm->nxt;
486  else /* match == mC */ return fm->src;
487 }
488 
489 static int compare_fields(FieldMatchContext *fm, int match1, int match2, int field)
490 {
491  int plane, ret;
492  uint64_t accumPc = 0, accumPm = 0, accumPml = 0;
493  uint64_t accumNc = 0, accumNm = 0, accumNml = 0;
494  int norm1, norm2, mtn1, mtn2;
495  float c1, c2, mr;
496  const AVFrame *src = fm->src;
497 
498  for (plane = 0; plane < (fm->mchroma ? 3 : 1); plane++) {
499  int x, y, temp1, temp2, fbase;
500  const AVFrame *prev, *next;
501  uint8_t *mapp = fm->map_data[plane];
502  int map_linesize = fm->map_linesize[plane];
503  const uint8_t *srcp = src->data[plane];
504  const int src_linesize = src->linesize[plane];
505  const int srcf_linesize = src_linesize << 1;
506  int prv_linesize, nxt_linesize;
507  int prvf_linesize, nxtf_linesize;
508  const int width = get_width (fm, src, plane, INPUT_MAIN);
509  const int height = get_height(fm, src, plane, INPUT_MAIN);
510  const int y0a = fm->y0 >> (plane ? fm->vsub[INPUT_MAIN] : 0);
511  const int y1a = fm->y1 >> (plane ? fm->vsub[INPUT_MAIN] : 0);
512  const int startx = (plane == 0 ? 8 : 8 >> fm->hsub[INPUT_MAIN]);
513  const int stopx = width - startx;
514  const uint8_t *srcpf, *srcf, *srcnf;
515  const uint8_t *prvpf, *prvnf, *nxtpf, *nxtnf;
516 
517  fill_buf(mapp, width, height, map_linesize, 0);
518 
519  /* match1 */
520  fbase = get_field_base(match1, field);
521  srcf = srcp + (fbase + 1) * src_linesize;
522  srcpf = srcf - srcf_linesize;
523  srcnf = srcf + srcf_linesize;
524  mapp = mapp + fbase * map_linesize;
525  prev = select_frame(fm, match1);
526  prv_linesize = prev->linesize[plane];
527  prvf_linesize = prv_linesize << 1;
528  prvpf = prev->data[plane] + fbase * prv_linesize; // previous frame, previous field
529  prvnf = prvpf + prvf_linesize; // previous frame, next field
530 
531  /* match2 */
532  fbase = get_field_base(match2, field);
533  next = select_frame(fm, match2);
534  nxt_linesize = next->linesize[plane];
535  nxtf_linesize = nxt_linesize << 1;
536  nxtpf = next->data[plane] + fbase * nxt_linesize; // next frame, previous field
537  nxtnf = nxtpf + nxtf_linesize; // next frame, next field
538 
539  map_linesize <<= 1;
540  if ((match1 >= 3 && field == 1) || (match1 < 3 && field != 1))
541  build_diff_map(fm, prvpf, prvf_linesize, nxtpf, nxtf_linesize,
542  mapp, map_linesize, height, width, plane);
543  else
544  build_diff_map(fm, prvnf, prvf_linesize, nxtnf, nxtf_linesize,
545  mapp + map_linesize, map_linesize, height, width, plane);
546 
547  for (y = 2; y < height - 2; y += 2) {
548  if (y0a == y1a || y < y0a || y > y1a) {
549  for (x = startx; x < stopx; x++) {
550  if (mapp[x] > 0 || mapp[x + map_linesize] > 0) {
551  temp1 = srcpf[x] + (srcf[x] << 2) + srcnf[x]; // [1 4 1]
552 
553  temp2 = abs(3 * (prvpf[x] + prvnf[x]) - temp1);
554  if (temp2 > 23 && ((mapp[x]&1) || (mapp[x + map_linesize]&1)))
555  accumPc += temp2;
556  if (temp2 > 42) {
557  if ((mapp[x]&2) || (mapp[x + map_linesize]&2))
558  accumPm += temp2;
559  if ((mapp[x]&4) || (mapp[x + map_linesize]&4))
560  accumPml += temp2;
561  }
562 
563  temp2 = abs(3 * (nxtpf[x] + nxtnf[x]) - temp1);
564  if (temp2 > 23 && ((mapp[x]&1) || (mapp[x + map_linesize]&1)))
565  accumNc += temp2;
566  if (temp2 > 42) {
567  if ((mapp[x]&2) || (mapp[x + map_linesize]&2))
568  accumNm += temp2;
569  if ((mapp[x]&4) || (mapp[x + map_linesize]&4))
570  accumNml += temp2;
571  }
572  }
573  }
574  }
575  prvpf += prvf_linesize;
576  prvnf += prvf_linesize;
577  srcpf += srcf_linesize;
578  srcf += srcf_linesize;
579  srcnf += srcf_linesize;
580  nxtpf += nxtf_linesize;
581  nxtnf += nxtf_linesize;
582  mapp += map_linesize;
583  }
584  }
585 
586  if (accumPm < 500 && accumNm < 500 && (accumPml >= 500 || accumNml >= 500) &&
587  FFMAX(accumPml,accumNml) > 3*FFMIN(accumPml,accumNml)) {
588  accumPm = accumPml;
589  accumNm = accumNml;
590  }
591 
592  norm1 = (int)((accumPc / 6.0f) + 0.5f);
593  norm2 = (int)((accumNc / 6.0f) + 0.5f);
594  mtn1 = (int)((accumPm / 6.0f) + 0.5f);
595  mtn2 = (int)((accumNm / 6.0f) + 0.5f);
596  c1 = ((float)FFMAX(norm1,norm2)) / ((float)FFMAX(FFMIN(norm1,norm2),1));
597  c2 = ((float)FFMAX(mtn1, mtn2)) / ((float)FFMAX(FFMIN(mtn1, mtn2), 1));
598  mr = ((float)FFMAX(mtn1, mtn2)) / ((float)FFMAX(FFMAX(norm1,norm2),1));
599  if (((mtn1 >= 500 || mtn2 >= 500) && (mtn1*2 < mtn2*1 || mtn2*2 < mtn1*1)) ||
600  ((mtn1 >= 1000 || mtn2 >= 1000) && (mtn1*3 < mtn2*2 || mtn2*3 < mtn1*2)) ||
601  ((mtn1 >= 2000 || mtn2 >= 2000) && (mtn1*5 < mtn2*4 || mtn2*5 < mtn1*4)) ||
602  ((mtn1 >= 4000 || mtn2 >= 4000) && c2 > c1))
603  ret = mtn1 > mtn2 ? match2 : match1;
604  else if (mr > 0.005 && FFMAX(mtn1, mtn2) > 150 && (mtn1*2 < mtn2*1 || mtn2*2 < mtn1*1))
605  ret = mtn1 > mtn2 ? match2 : match1;
606  else
607  ret = norm1 > norm2 ? match2 : match1;
608  return ret;
609 }
610 
611 static void copy_fields(const FieldMatchContext *fm, AVFrame *dst,
612  const AVFrame *src, int field, int input)
613 {
614  int plane;
615  for (plane = 0; plane < 4 && src->data[plane] && src->linesize[plane]; plane++) {
616  const int plane_h = get_height(fm, src, plane, input);
617  const int nb_copy_fields = (plane_h >> 1) + (field ? 0 : (plane_h & 1));
618  av_image_copy_plane(dst->data[plane] + field*dst->linesize[plane], dst->linesize[plane] << 1,
619  src->data[plane] + field*src->linesize[plane], src->linesize[plane] << 1,
620  get_width(fm, src, plane, input) * fm->bpc, nb_copy_fields);
621  }
622 }
623 
625  const AVFrame *prv, AVFrame *src, const AVFrame *nxt, int input)
626 {
627  AVFrame *dst;
628  FieldMatchContext *fm = ctx->priv;
629 
630  if (match == mC) {
632  } else {
633  AVFilterLink *link = input == INPUT_CLEANSRC ? ctx->outputs[0] : ctx->inputs[INPUT_MAIN];
634 
635  dst = ff_get_video_buffer(link, link->w, link->h);
636  if (!dst)
637  return NULL;
639 
640  switch (match) {
641  case mP: copy_fields(fm, dst, src, 1-field, input); copy_fields(fm, dst, prv, field, input); break;
642  case mN: copy_fields(fm, dst, src, 1-field, input); copy_fields(fm, dst, nxt, field, input); break;
643  case mB: copy_fields(fm, dst, src, field, input); copy_fields(fm, dst, prv, 1-field, input); break;
644  case mU: copy_fields(fm, dst, src, field, input); copy_fields(fm, dst, nxt, 1-field, input); break;
645  default: av_assert0(0);
646  }
647  }
648  return dst;
649 }
650 
651 static int checkmm(AVFilterContext *ctx, int *combs, int m1, int m2,
652  AVFrame **gen_frames, int field)
653 {
654  const FieldMatchContext *fm = ctx->priv;
655 
656 #define LOAD_COMB(mid) do { \
657  if (combs[mid] < 0) { \
658  if (!gen_frames[mid]) \
659  gen_frames[mid] = create_weave_frame(ctx, mid, field, \
660  fm->prv, fm->src, fm->nxt, \
661  INPUT_MAIN); \
662  combs[mid] = calc_combed_score(fm, gen_frames[mid]); \
663  } \
664 } while (0)
665 
666  LOAD_COMB(m1);
667  LOAD_COMB(m2);
668 
669  if ((combs[m2] * 3 < combs[m1] || (combs[m2] * 2 < combs[m1] && combs[m1] > fm->combpel)) &&
670  abs(combs[m2] - combs[m1]) >= 30 && combs[m2] < fm->combpel)
671  return m2;
672  else
673  return m1;
674 }
675 
676 static const int fxo0m[] = { mP, mC, mN, mB, mU };
677 static const int fxo1m[] = { mN, mC, mP, mU, mB };
678 
680 {
681  AVFilterContext *ctx = inlink->dst;
682  AVFilterLink *outlink = ctx->outputs[0];
683  FilterLink *outl = ff_filter_link(outlink);
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 == outl->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 = outl->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) {
832  dst->flags |= AV_FRAME_FLAG_INTERLACED;
833  av_log(ctx, AV_LOG_WARNING, "Frame #%"PRId64" at %s is still interlaced\n",
834  outl->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
845  dst->flags &= ~AV_FRAME_FLAG_INTERLACED;
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  AVFilterFormatsConfig **cfg_in,
913  AVFilterFormatsConfig **cfg_out)
914 {
915  const FieldMatchContext *fm = ctx->priv;
916 
917  static const enum AVPixelFormat pix_fmts[] = {
921  };
922  static const enum AVPixelFormat unproc_pix_fmts[] = {
937  };
938  int ret;
939 
941  if (!fmts_list)
942  return AVERROR(ENOMEM);
943  if (!fm->ppsrc) {
944  return ff_set_common_formats2(ctx, cfg_in, cfg_out, fmts_list);
945  }
946 
947  if ((ret = ff_formats_ref(fmts_list, &cfg_in[INPUT_MAIN]->formats)) < 0)
948  return ret;
949  fmts_list = ff_make_format_list(unproc_pix_fmts);
950  if (!fmts_list)
951  return AVERROR(ENOMEM);
952  if ((ret = ff_formats_ref(fmts_list, &cfg_out[0]->formats)) < 0)
953  return ret;
954  if ((ret = ff_formats_ref(fmts_list, &cfg_in[INPUT_CLEANSRC]->formats)) < 0)
955  return ret;
956  return 0;
957 }
958 
960 {
961  int ret;
962  AVFilterContext *ctx = inlink->dst;
963  FieldMatchContext *fm = ctx->priv;
964  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
965  const int w = inlink->w;
966  const int h = inlink->h;
967 
968  fm->scthresh = (int64_t)((w * h * 255.0 * fm->scthresh_flt) / 100.0);
969 
970  if ((ret = av_image_alloc(fm->map_data, fm->map_linesize, w, h, inlink->format, 32)) < 0 ||
971  (ret = av_image_alloc(fm->cmask_data, fm->cmask_linesize, w, h, inlink->format, 32)) < 0)
972  return ret;
973 
974  fm->hsub[INPUT_MAIN] = pix_desc->log2_chroma_w;
975  fm->vsub[INPUT_MAIN] = pix_desc->log2_chroma_h;
976  if (fm->ppsrc) {
977  pix_desc = av_pix_fmt_desc_get(ctx->inputs[INPUT_CLEANSRC]->format);
978  fm->hsub[INPUT_CLEANSRC] = pix_desc->log2_chroma_w;
979  fm->vsub[INPUT_CLEANSRC] = pix_desc->log2_chroma_h;
980  }
981 
982  fm->tpitchy = FFALIGN(w, 16);
983  fm->tpitchuv = FFALIGN(w >> 1, 16);
984 
985  fm->tbuffer = av_calloc((h/2 + 4) * fm->tpitchy, sizeof(*fm->tbuffer));
986  fm->c_array = av_malloc_array((((w + fm->blockx/2)/fm->blockx)+1) *
987  (((h + fm->blocky/2)/fm->blocky)+1),
988  4 * sizeof(*fm->c_array));
989  if (!fm->tbuffer || !fm->c_array)
990  return AVERROR(ENOMEM);
991 
992  return 0;
993 }
994 
996 {
997  const FieldMatchContext *fm = ctx->priv;
998  AVFilterPad pad = {
999  .name = "main",
1000  .type = AVMEDIA_TYPE_VIDEO,
1001  .config_props = config_input,
1002  };
1003  int ret;
1004 
1005  if ((ret = ff_append_inpad(ctx, &pad)) < 0)
1006  return ret;
1007 
1008  if (fm->ppsrc) {
1009  pad.name = "clean_src";
1010  pad.config_props = NULL;
1011  if ((ret = ff_append_inpad(ctx, &pad)) < 0)
1012  return ret;
1013  }
1014 
1015  if ((fm->blockx & (fm->blockx - 1)) ||
1016  (fm->blocky & (fm->blocky - 1))) {
1017  av_log(ctx, AV_LOG_ERROR, "blockx and blocky settings must be power of two\n");
1018  return AVERROR(EINVAL);
1019  }
1020 
1021  if (fm->combpel > fm->blockx * fm->blocky) {
1022  av_log(ctx, AV_LOG_ERROR, "Combed pixel should not be larger than blockx x blocky\n");
1023  return AVERROR(EINVAL);
1024  }
1025 
1026  return 0;
1027 }
1028 
1030 {
1031  FieldMatchContext *fm = ctx->priv;
1032 
1033  if (fm->prv != fm->src)
1034  av_frame_free(&fm->prv);
1035  if (fm->nxt != fm->src)
1036  av_frame_free(&fm->nxt);
1037  if (fm->prv2 != fm->src2)
1038  av_frame_free(&fm->prv2);
1039  if (fm->nxt2 != fm->src2)
1040  av_frame_free(&fm->nxt2);
1041  av_frame_free(&fm->src);
1042  av_frame_free(&fm->src2);
1043  av_freep(&fm->map_data[0]);
1044  av_freep(&fm->cmask_data[0]);
1045  av_freep(&fm->tbuffer);
1046  av_freep(&fm->c_array);
1047 }
1048 
1049 static int config_output(AVFilterLink *outlink)
1050 {
1051  FilterLink *outl = ff_filter_link(outlink);
1052  AVFilterContext *ctx = outlink->src;
1053  FieldMatchContext *fm = ctx->priv;
1054  const AVFilterLink *inlink =
1055  ctx->inputs[fm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN];
1056  FilterLink *inl = ff_filter_link(ctx->inputs[fm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN]);
1058 
1059  fm->bpc = (desc->comp[0].depth + 7) / 8;
1060  outlink->time_base = inlink->time_base;
1061  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
1062  outl->frame_rate = inl->frame_rate;
1063  outlink->w = inlink->w;
1064  outlink->h = inlink->h;
1065  return 0;
1066 }
1067 
1069  {
1070  .name = "default",
1071  .type = AVMEDIA_TYPE_VIDEO,
1072  .config_props = config_output,
1073  },
1074 };
1075 
1077  .name = "fieldmatch",
1078  .description = NULL_IF_CONFIG_SMALL("Field matching for inverse telecine."),
1079  .priv_size = sizeof(FieldMatchContext),
1080  .init = fieldmatch_init,
1081  .activate = activate,
1083  .inputs = NULL,
1086  .priv_class = &fieldmatch_class,
1088 };
FieldMatchContext::order
int order
Definition: vf_fieldmatch.c:91
formats
formats
Definition: signature.h:47
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:116
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:73
FieldMatchContext::mode
int mode
matching_mode
Definition: vf_fieldmatch.c:93
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
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:417
FLAGS
#define FLAGS
Definition: vf_fieldmatch.c:117
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:435
FieldMatchContext::blocky
int blocky
Definition: vf_fieldmatch.c:103
NB_COMBMATCH
@ NB_COMBMATCH
Definition: vf_fieldmatch.c:68
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:1062
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
ff_set_common_formats2
int ff_set_common_formats2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, AVFilterFormats *formats)
Definition: formats.c:1007
int64_t
long long int64_t
Definition: coverity.c:34
FieldMatchContext::mchroma
int mchroma
Definition: vf_fieldmatch.c:95
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:162
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:396
FieldMatchContext::src
AVFrame * src
Definition: vf_fieldmatch.c:81
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:501
AVFrame::width
int width
Definition: frame.h:461
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:429
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
COMBDBG_PCN
@ COMBDBG_PCN
Definition: vf_fieldmatch.c:73
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:661
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
c1
static const uint64_t c1
Definition: murmur3.c:52
MODE_PC_U
@ MODE_PC_U
Definition: vf_fieldmatch.c:57
video.h
compare_fields
static int compare_fields(FieldMatchContext *fm, int match1, int match2, int field)
Definition: vf_fieldmatch.c:489
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:410
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:107
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:653
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:1491
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:447
MODE_PCN_UB
@ MODE_PCN_UB
Definition: vf_fieldmatch.c:60
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:676
MODE_PC
@ MODE_PC
Definition: vf_fieldmatch.c:55
checkmm
static int checkmm(AVFilterContext *ctx, int *combs, int m1, int m2, AVFrame **gen_frames, int field)
Definition: vf_fieldmatch.c:651
fail
#define fail()
Definition: checkasm.h:188
FieldMatchContext::src2
AVFrame * src2
Definition: vf_fieldmatch.c:82
copy_fields
static void copy_fields(const FieldMatchContext *fm, AVFrame *dst, const AVFrame *src, int field, int input)
Definition: vf_fieldmatch.c:611
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:476
NB_COMBDBG
@ NB_COMBDBG
Definition: vf_fieldmatch.c:75
FieldMatchContext::cmask_data
uint8_t * cmask_data[4]
Definition: vf_fieldmatch.c:109
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:141
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
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
query_formats
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: vf_fieldmatch.c:911
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
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
FieldMatchContext::y1
int y1
Definition: vf_fieldmatch.c:96
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:122
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:424
FieldMatchContext::map_linesize
int map_linesize[4]
Definition: vf_fieldmatch.c:108
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1594
FieldMatchContext::scthresh_flt
double scthresh_flt
Definition: vf_fieldmatch.c:98
get_height
static int get_height(const FieldMatchContext *fm, const AVFrame *f, int plane, int input)
Definition: vf_fieldmatch.c:163
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:60
OFFSET
#define OFFSET(x)
Definition: vf_fieldmatch.c:116
fieldmatch_parity
fieldmatch_parity
Definition: vf_fieldmatch.c:48
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
Definition: opt.h:267
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_fieldmatch.c:1049
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:678
fieldmatch_outputs
static const AVFilterPad fieldmatch_outputs[]
Definition: vf_fieldmatch.c:1068
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
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
FieldMatchContext::chroma
int chroma
Definition: vf_fieldmatch.c:102
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:597
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:58
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
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
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:74
FM_PARITY_AUTO
@ FM_PARITY_AUTO
Definition: vf_fieldmatch.c:49
FieldMatchContext::nxt
AVFrame * nxt
main sliding window of 3 frames
Definition: vf_fieldmatch.c:81
FieldMatchContext::hsub
int hsub[2]
Definition: vf_fieldmatch.c:84
COMBMATCH_SC
@ COMBMATCH_SC
Definition: vf_fieldmatch.c:66
fieldmatch_options
static const AVOption fieldmatch_options[]
Definition: vf_fieldmatch.c:119
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
mN
@ mN
Definition: vf_fieldmatch.c:475
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:713
FieldMatchContext::scthresh
int64_t scthresh
Definition: vf_fieldmatch.c:97
FieldMatchContext::combmatch
int combmatch
comb_matching_mode
Definition: vf_fieldmatch.c:99
fill_buf
static void fill_buf(uint8_t *data, int w, int h, int linesize, uint8_t v)
Definition: vf_fieldmatch.c:188
FieldMatchContext::field
int field
Definition: vf_fieldmatch.c:94
mU
@ mU
Definition: vf_fieldmatch.c:475
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:85
FieldMatchContext::combpel
int combpel
Definition: vf_fieldmatch.c:104
AV_PIX_FMT_YUV440P10
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:480
FieldMatchContext::ppsrc
int ppsrc
Definition: vf_fieldmatch.c:92
FieldMatchContext::got_frame
int got_frame[2]
frame request flag for each input stream
Definition: vf_fieldmatch.c:83
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:67
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:1438
FieldMatchContext::vsub
int vsub[2]
chroma subsampling values
Definition: vf_fieldmatch.c:84
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:111
ff_filter_link
static FilterLink * ff_filter_link(AVFilterLink *link)
Definition: filters.h:197
FieldMatchContext
Definition: vf_fieldmatch.c:78
comb_dbg
comb_dbg
Definition: vf_fieldmatch.c:71
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: filters.h:118
NB_MODE
@ NB_MODE
Definition: vf_fieldmatch.c:61
f
f
Definition: af_crystalizer.c:122
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
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
height
#define height
Definition: dsp.h:85
MODE_PC_N
@ MODE_PC_N
Definition: vf_fieldmatch.c:56
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
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:1076
comb_matching_mode
comb_matching_mode
Definition: vf_fieldmatch.c:64
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:959
FieldMatchContext::tbuffer
uint8_t * tbuffer
Definition: vf_fieldmatch.c:113
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:164
FieldMatchContext::cthresh
int cthresh
Definition: vf_fieldmatch.c:101
FM_PARITY_BOTTOM
@ FM_PARITY_BOTTOM
Definition: vf_fieldmatch.c:50
INPUT_MAIN
#define INPUT_MAIN
Definition: vf_fieldmatch.c:45
FieldMatchContext::nxt2
AVFrame * nxt2
sliding window of the optional second stream
Definition: vf_fieldmatch.c:82
FieldMatchContext::blockx
int blockx
Definition: vf_fieldmatch.c:103
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:54
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
get_field_base
static int get_field_base(int match, int field)
Definition: vf_fieldmatch.c:477
COMBDBG_PCNUB
@ COMBDBG_PCNUB
Definition: vf_fieldmatch.c:74
uninit
static void uninit(AVBSFContext *ctx)
Definition: pcm_rechunk.c:68
SLIDING_FRAME_WINDOW
#define SLIDING_FRAME_WINDOW(prv, src, nxt)
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FF_INLINK_IDX
#define FF_INLINK_IDX(link)
Find the index of a link.
Definition: filters.h:213
FieldMatchContext::tpitchuv
int tpitchuv
Definition: vf_fieldmatch.c:112
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
mB
@ mB
Definition: vf_fieldmatch.c:475
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
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:59
INPUT_CLEANSRC
#define INPUT_CLEANSRC
Definition: vf_fieldmatch.c:46
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:648
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:624
AVFilter
Filter definition.
Definition: avfilter.h:201
VERTICAL_HALF
#define VERTICAL_HALF(y_start, y_end)
ret
ret
Definition: filter_design.txt:187
FieldMatchContext::combdbg
int combdbg
Definition: vf_fieldmatch.c:100
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:111
mC
@ mC
Definition: vf_fieldmatch.c:475
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:482
FieldMatchContext::prv
AVFrame * prv
Definition: vf_fieldmatch.c:81
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:487
fxo1m
static const int fxo1m[]
Definition: vf_fieldmatch.c:677
AVFrame::height
int height
Definition: frame.h:461
c2
static const uint64_t c2
Definition: murmur3.c:53
status
ov_status_e status
Definition: dnn_backend_openvino.c:100
luma_abs_diff
static int64_t luma_abs_diff(const AVFrame *f1, const AVFrame *f2)
Definition: vf_fieldmatch.c:168
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
Underlying C type is int.
Definition: opt.h:259
avfilter.h
FieldMatchContext::prv2
AVFrame * prv2
Definition: vf_fieldmatch.c:82
FieldMatchContext::cmask_linesize
int cmask_linesize[4]
Definition: vf_fieldmatch.c:110
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_fieldmatch.c:679
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:457
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:72
FM_PARITY_TOP
@ FM_PARITY_TOP
Definition: vf_fieldmatch.c:51
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:96
fieldmatch_uninit
static av_cold void fieldmatch_uninit(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:1029
mP
@ mP
Definition: vf_fieldmatch.c:475
fieldmatch_init
static av_cold int fieldmatch_init(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:995
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:87
select_frame
static AVFrame * select_frame(FieldMatchContext *fm, int match)
Definition: vf_fieldmatch.c:482
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:158
imgutils.h
timestamp.h
FieldMatchContext::tpitchy
int tpitchy
Definition: vf_fieldmatch.c:112
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:434
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:65
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:2070
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
width
#define width
Definition: dsp.h:85
FieldMatchContext::eof
uint32_t eof
bitmask for end of stream
Definition: vf_fieldmatch.c:86
FieldMatchContext::lastn
int64_t lastn
Definition: vf_fieldmatch.c:88
calc_combed_score
static int calc_combed_score(const FieldMatchContext *fm, const AVFrame *src)
Definition: vf_fieldmatch.c:198
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
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
src
#define src
Definition: vp8dsp.c:248
COMBDBG_NONE
@ COMBDBG_NONE
Definition: vf_fieldmatch.c:72
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:486