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/opt.h"
38 #include "libavutil/timestamp.h"
39 #include "avfilter.h"
40 #include "filters.h"
41 #include "formats.h"
42 #include "internal.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
87  int64_t lastscdiff;
88  int64_t lastn;
89 
90  /* options */
91  int order;
92  int ppsrc;
93  int mode; ///< matching_mode
94  int field;
95  int mchroma;
96  int y0, y1;
97  int64_t scthresh;
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, "order" },
121  { "auto", "auto detect parity", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_AUTO}, INT_MIN, INT_MAX, FLAGS, "order" },
122  { "bff", "assume bottom field first", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_BOTTOM}, INT_MIN, INT_MAX, FLAGS, "order" },
123  { "tff", "assume top field first", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_TOP}, INT_MIN, INT_MAX, FLAGS, "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, "mode" },
125  { "pc", "2-way match (p/c)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PC}, INT_MIN, INT_MAX, FLAGS, "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, "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, "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, "mode" },
129  { "pcn", "3-way match (p/c/n)", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PCN}, INT_MIN, INT_MAX, FLAGS, "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, "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, "field" },
133  { "auto", "automatic (same value as 'order')", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_AUTO}, INT_MIN, INT_MAX, FLAGS, "field" },
134  { "bottom", "bottom field", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_BOTTOM}, INT_MIN, INT_MAX, FLAGS, "field" },
135  { "top", "top field", 0, AV_OPT_TYPE_CONST, {.i64=FM_PARITY_TOP}, INT_MIN, INT_MAX, FLAGS, "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, "combmatching" },
141  { "none", "disable combmatching", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_NONE}, INT_MIN, INT_MAX, FLAGS, "combmatching" },
142  { "sc", "enable combmatching only on scene change", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_SC}, INT_MIN, INT_MAX, FLAGS, "combmatching" },
143  { "full", "enable combmatching all the time", 0, AV_OPT_TYPE_CONST, {.i64=COMBMATCH_FULL}, INT_MIN, INT_MAX, FLAGS, "combmatching" },
144  { "combdbg", "enable comb debug", OFFSET(combdbg), AV_OPT_TYPE_INT, {.i64=COMBDBG_NONE}, COMBDBG_NONE, NB_COMBDBG-1, FLAGS, "dbglvl" },
145  { "none", "no forced calculation", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_NONE}, INT_MIN, INT_MAX, FLAGS, "dbglvl" },
146  { "pcn", "calculate p/c/n", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_PCN}, INT_MIN, INT_MAX, FLAGS, "dbglvl" },
147  { "pcnub", "calculate p/c/n/u/b", 0, AV_OPT_TYPE_CONST, {.i64=COMBDBG_PCNUB}, INT_MIN, INT_MAX, FLAGS, "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) {
631  dst = av_frame_clone(src);
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;
638  av_frame_copy_props(dst, src);
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  FieldMatchContext *fm = ctx->priv;
684  int combs[] = { -1, -1, -1, -1, -1 };
685  int order, field, i, match, interlaced_frame, sc = 0, ret = 0;
686  const int *fxo;
687  AVFrame *gen_frames[] = { NULL, NULL, NULL, NULL, NULL };
688  AVFrame *dst = NULL;
689 
690  /* update frames queue(s) */
691 #define SLIDING_FRAME_WINDOW(prv, src, nxt) do { \
692  if (prv != src) /* 2nd loop exception (1st has prv==src and we don't want to loose src) */ \
693  av_frame_free(&prv); \
694  prv = src; \
695  src = nxt; \
696  if (in) \
697  nxt = in; \
698  if (!prv) \
699  prv = src; \
700  if (!prv) /* received only one frame at that point */ \
701  return 0; \
702  av_assert0(prv && src && nxt); \
703 } while (0)
704  if (FF_INLINK_IDX(inlink) == INPUT_MAIN) {
705  av_assert0(fm->got_frame[INPUT_MAIN] == 0);
706  SLIDING_FRAME_WINDOW(fm->prv, fm->src, fm->nxt);
707  fm->got_frame[INPUT_MAIN] = 1;
708  } else {
710  SLIDING_FRAME_WINDOW(fm->prv2, fm->src2, fm->nxt2);
711  fm->got_frame[INPUT_CLEANSRC] = 1;
712  }
713  if (!fm->got_frame[INPUT_MAIN] || (fm->ppsrc && !fm->got_frame[INPUT_CLEANSRC]))
714  return 0;
716  in = fm->src;
717 
718  /* parity */
719  order = fm->order != FM_PARITY_AUTO ? fm->order : ((in->flags & AV_FRAME_FLAG_INTERLACED) ?
720  !!(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 1);
721  field = fm->field != FM_PARITY_AUTO ? fm->field : order;
722  av_assert0(order == 0 || order == 1 || field == 0 || field == 1);
723  fxo = field ^ order ? fxo1m : fxo0m;
724 
725  /* debug mode: we generate all the fields combinations and their associated
726  * combed score. XXX: inject as frame metadata? */
727  if (fm->combdbg) {
728  for (i = 0; i < FF_ARRAY_ELEMS(combs); i++) {
729  if (i > mN && fm->combdbg == COMBDBG_PCN)
730  break;
731  gen_frames[i] = create_weave_frame(ctx, i, field, fm->prv, fm->src, fm->nxt, INPUT_MAIN);
732  if (!gen_frames[i]) {
733  ret = AVERROR(ENOMEM);
734  goto fail;
735  }
736  combs[i] = calc_combed_score(fm, gen_frames[i]);
737  }
738  av_log(ctx, AV_LOG_INFO, "COMBS: %3d %3d %3d %3d %3d\n",
739  combs[0], combs[1], combs[2], combs[3], combs[4]);
740  } else {
741  gen_frames[mC] = av_frame_clone(fm->src);
742  if (!gen_frames[mC]) {
743  ret = AVERROR(ENOMEM);
744  goto fail;
745  }
746  }
747 
748  /* p/c selection and optional 3-way p/c/n matches */
749  match = compare_fields(fm, fxo[mC], fxo[mP], field);
750  if (fm->mode == MODE_PCN || fm->mode == MODE_PCN_UB)
751  match = compare_fields(fm, match, fxo[mN], field);
752 
753  /* scene change check */
754  if (fm->combmatch == COMBMATCH_SC) {
755  if (fm->lastn == outlink->frame_count_in - 1) {
756  if (fm->lastscdiff > fm->scthresh)
757  sc = 1;
758  } else if (luma_abs_diff(fm->prv, fm->src) > fm->scthresh) {
759  sc = 1;
760  }
761 
762  if (!sc) {
763  fm->lastn = outlink->frame_count_in;
764  fm->lastscdiff = luma_abs_diff(fm->src, fm->nxt);
765  sc = fm->lastscdiff > fm->scthresh;
766  }
767  }
768 
769  if (fm->combmatch == COMBMATCH_FULL || (fm->combmatch == COMBMATCH_SC && sc)) {
770  switch (fm->mode) {
771  /* 2-way p/c matches */
772  case MODE_PC:
773  match = checkmm(ctx, combs, match, match == fxo[mP] ? fxo[mC] : fxo[mP], gen_frames, field);
774  break;
775  case MODE_PC_N:
776  match = checkmm(ctx, combs, match, fxo[mN], gen_frames, field);
777  break;
778  case MODE_PC_U:
779  match = checkmm(ctx, combs, match, fxo[mU], gen_frames, field);
780  break;
781  case MODE_PC_N_UB:
782  match = checkmm(ctx, combs, match, fxo[mN], gen_frames, field);
783  match = checkmm(ctx, combs, match, fxo[mU], gen_frames, field);
784  match = checkmm(ctx, combs, match, fxo[mB], gen_frames, field);
785  break;
786  /* 3-way p/c/n matches */
787  case MODE_PCN:
788  match = checkmm(ctx, combs, match, match == fxo[mP] ? fxo[mC] : fxo[mP], gen_frames, field);
789  break;
790  case MODE_PCN_UB:
791  match = checkmm(ctx, combs, match, fxo[mU], gen_frames, field);
792  match = checkmm(ctx, combs, match, fxo[mB], gen_frames, field);
793  break;
794  default:
795  av_assert0(0);
796  }
797  }
798 
799  /* keep fields as-is if not matched properly */
800  interlaced_frame = combs[match] >= fm->combpel;
801  if (interlaced_frame && fm->combmatch == COMBMATCH_FULL) {
802  match = mC;
803  }
804 
805  /* get output frame and drop the others */
806  if (fm->ppsrc) {
807  /* field matching was based on a filtered/post-processed input, we now
808  * pick the untouched fields from the clean source */
809  dst = create_weave_frame(ctx, match, field, fm->prv2, fm->src2, fm->nxt2, INPUT_CLEANSRC);
810  } else {
811  if (!gen_frames[match]) { // XXX: is that possible?
812  dst = create_weave_frame(ctx, match, field, fm->prv, fm->src, fm->nxt, INPUT_MAIN);
813  } else {
814  dst = gen_frames[match];
815  gen_frames[match] = NULL;
816  }
817  }
818  if (!dst) {
819  ret = AVERROR(ENOMEM);
820  goto fail;
821  }
822 
823  /* mark the frame we are unable to match properly as interlaced so a proper
824  * de-interlacer can take the relay */
825 #if FF_API_INTERLACED_FRAME
827  dst->interlaced_frame = interlaced_frame;
829 #endif
830  if (interlaced_frame) {
832  av_log(ctx, AV_LOG_WARNING, "Frame #%"PRId64" at %s is still interlaced\n",
833  outlink->frame_count_in, av_ts2timestr(in->pts, &inlink->time_base));
834 #if FF_API_INTERLACED_FRAME
836  dst->top_field_first = field;
838 #endif
839  if (field)
841  else
843  } else
845 
846  av_log(ctx, AV_LOG_DEBUG, "SC:%d | COMBS: %3d %3d %3d %3d %3d (combpel=%d)"
847  " match=%d combed=%s\n", sc, combs[0], combs[1], combs[2], combs[3], combs[4],
848  fm->combpel, match, (dst->flags & AV_FRAME_FLAG_INTERLACED) ? "YES" : "NO");
849 
850 fail:
851  for (i = 0; i < FF_ARRAY_ELEMS(gen_frames); i++)
852  av_frame_free(&gen_frames[i]);
853 
854  if (ret >= 0)
855  return ff_filter_frame(outlink, dst);
856  return ret;
857 }
858 
860 {
861  FieldMatchContext *fm = ctx->priv;
862  AVFrame *frame = NULL;
863  int ret = 0, status;
864  int64_t pts;
865 
867 
868  if ((fm->got_frame[INPUT_MAIN] == 0) &&
869  (ret = ff_inlink_consume_frame(ctx->inputs[INPUT_MAIN], &frame)) > 0) {
870  ret = filter_frame(ctx->inputs[INPUT_MAIN], frame);
871  if (ret < 0)
872  return ret;
873  }
874  if (ret < 0)
875  return ret;
876  if (fm->ppsrc &&
877  (fm->got_frame[INPUT_CLEANSRC] == 0) &&
878  (ret = ff_inlink_consume_frame(ctx->inputs[INPUT_CLEANSRC], &frame)) > 0) {
879  ret = filter_frame(ctx->inputs[INPUT_CLEANSRC], frame);
880  if (ret < 0)
881  return ret;
882  }
883  if (ret < 0) {
884  return ret;
885  } else if (ff_inlink_acknowledge_status(ctx->inputs[INPUT_MAIN], &status, &pts)) {
886  if (status == AVERROR_EOF) { // flushing
887  fm->eof |= 1 << INPUT_MAIN;
888  ret = filter_frame(ctx->inputs[INPUT_MAIN], NULL);
889  }
890  ff_outlink_set_status(ctx->outputs[0], status, pts);
891  return ret;
892  } else if (fm->ppsrc && ff_inlink_acknowledge_status(ctx->inputs[INPUT_CLEANSRC], &status, &pts)) {
893  if (status == AVERROR_EOF) { // flushing
894  fm->eof |= 1 << INPUT_CLEANSRC;
895  ret = filter_frame(ctx->inputs[INPUT_CLEANSRC], NULL);
896  }
897  ff_outlink_set_status(ctx->outputs[0], status, pts);
898  return ret;
899  } else {
900  if (ff_outlink_frame_wanted(ctx->outputs[0])) {
901  if (fm->got_frame[INPUT_MAIN] == 0)
903  if (fm->ppsrc && (fm->got_frame[INPUT_CLEANSRC] == 0))
905  }
906  return 0;
907  }
908 }
909 
911 {
912  FieldMatchContext *fm = ctx->priv;
913 
914  static const enum AVPixelFormat pix_fmts[] = {
918  };
919  static const enum AVPixelFormat unproc_pix_fmts[] = {
934  };
935  int ret;
936 
938  if (!fmts_list)
939  return AVERROR(ENOMEM);
940  if (!fm->ppsrc) {
941  return ff_set_common_formats(ctx, fmts_list);
942  }
943 
944  if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_MAIN]->outcfg.formats)) < 0)
945  return ret;
946  fmts_list = ff_make_format_list(unproc_pix_fmts);
947  if (!fmts_list)
948  return AVERROR(ENOMEM);
949  if ((ret = ff_formats_ref(fmts_list, &ctx->outputs[0]->incfg.formats)) < 0)
950  return ret;
951  if ((ret = ff_formats_ref(fmts_list, &ctx->inputs[INPUT_CLEANSRC]->outcfg.formats)) < 0)
952  return ret;
953  return 0;
954 }
955 
957 {
958  int ret;
959  AVFilterContext *ctx = inlink->dst;
960  FieldMatchContext *fm = ctx->priv;
961  const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
962  const int w = inlink->w;
963  const int h = inlink->h;
964 
965  fm->scthresh = (int64_t)((w * h * 255.0 * fm->scthresh_flt) / 100.0);
966 
967  if ((ret = av_image_alloc(fm->map_data, fm->map_linesize, w, h, inlink->format, 32)) < 0 ||
968  (ret = av_image_alloc(fm->cmask_data, fm->cmask_linesize, w, h, inlink->format, 32)) < 0)
969  return ret;
970 
971  fm->hsub[INPUT_MAIN] = pix_desc->log2_chroma_w;
972  fm->vsub[INPUT_MAIN] = pix_desc->log2_chroma_h;
973  if (fm->ppsrc) {
974  pix_desc = av_pix_fmt_desc_get(ctx->inputs[INPUT_CLEANSRC]->format);
975  fm->hsub[INPUT_CLEANSRC] = pix_desc->log2_chroma_w;
976  fm->vsub[INPUT_CLEANSRC] = pix_desc->log2_chroma_h;
977  }
978 
979  fm->tpitchy = FFALIGN(w, 16);
980  fm->tpitchuv = FFALIGN(w >> 1, 16);
981 
982  fm->tbuffer = av_calloc((h/2 + 4) * fm->tpitchy, sizeof(*fm->tbuffer));
983  fm->c_array = av_malloc_array((((w + fm->blockx/2)/fm->blockx)+1) *
984  (((h + fm->blocky/2)/fm->blocky)+1),
985  4 * sizeof(*fm->c_array));
986  if (!fm->tbuffer || !fm->c_array)
987  return AVERROR(ENOMEM);
988 
989  return 0;
990 }
991 
993 {
994  const FieldMatchContext *fm = ctx->priv;
995  AVFilterPad pad = {
996  .name = "main",
997  .type = AVMEDIA_TYPE_VIDEO,
998  .config_props = config_input,
999  };
1000  int ret;
1001 
1002  if ((ret = ff_append_inpad(ctx, &pad)) < 0)
1003  return ret;
1004 
1005  if (fm->ppsrc) {
1006  pad.name = "clean_src";
1007  pad.config_props = NULL;
1008  if ((ret = ff_append_inpad(ctx, &pad)) < 0)
1009  return ret;
1010  }
1011 
1012  if ((fm->blockx & (fm->blockx - 1)) ||
1013  (fm->blocky & (fm->blocky - 1))) {
1014  av_log(ctx, AV_LOG_ERROR, "blockx and blocky settings must be power of two\n");
1015  return AVERROR(EINVAL);
1016  }
1017 
1018  if (fm->combpel > fm->blockx * fm->blocky) {
1019  av_log(ctx, AV_LOG_ERROR, "Combed pixel should not be larger than blockx x blocky\n");
1020  return AVERROR(EINVAL);
1021  }
1022 
1023  return 0;
1024 }
1025 
1027 {
1028  FieldMatchContext *fm = ctx->priv;
1029 
1030  if (fm->prv != fm->src)
1031  av_frame_free(&fm->prv);
1032  if (fm->nxt != fm->src)
1033  av_frame_free(&fm->nxt);
1034  if (fm->prv2 != fm->src2)
1035  av_frame_free(&fm->prv2);
1036  if (fm->nxt2 != fm->src2)
1037  av_frame_free(&fm->nxt2);
1038  av_frame_free(&fm->src);
1039  av_frame_free(&fm->src2);
1040  av_freep(&fm->map_data[0]);
1041  av_freep(&fm->cmask_data[0]);
1042  av_freep(&fm->tbuffer);
1043  av_freep(&fm->c_array);
1044 }
1045 
1046 static int config_output(AVFilterLink *outlink)
1047 {
1048  AVFilterContext *ctx = outlink->src;
1049  FieldMatchContext *fm = ctx->priv;
1050  const AVFilterLink *inlink =
1051  ctx->inputs[fm->ppsrc ? INPUT_CLEANSRC : INPUT_MAIN];
1053 
1054  fm->bpc = (desc->comp[0].depth + 7) / 8;
1055  outlink->time_base = inlink->time_base;
1056  outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
1057  outlink->frame_rate = inlink->frame_rate;
1058  outlink->w = inlink->w;
1059  outlink->h = inlink->h;
1060  return 0;
1061 }
1062 
1064  {
1065  .name = "default",
1066  .type = AVMEDIA_TYPE_VIDEO,
1067  .config_props = config_output,
1068  },
1069 };
1070 
1072  .name = "fieldmatch",
1073  .description = NULL_IF_CONFIG_SMALL("Field matching for inverse telecine."),
1074  .priv_size = sizeof(FieldMatchContext),
1075  .init = fieldmatch_init,
1076  .activate = activate,
1078  .inputs = NULL,
1081  .priv_class = &fieldmatch_class,
1083 };
FieldMatchContext::order
int order
Definition: vf_fieldmatch.c:91
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:108
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:186
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
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
acc
int acc
Definition: yuv2rgb.c:554
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:401
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:250
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2964
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
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
mC
@ mC
Definition: vf_fieldmatch.c:475
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
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:340
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:452
AVFrame::width
int width
Definition: frame.h:412
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:251
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:169
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:468
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:99
activate
static int activate(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:859
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:649
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: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:361
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:641
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:1383
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: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:138
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:466
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:643
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:47
mP
@ mP
Definition: vf_fieldmatch.c:475
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:471
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:276
AVFrame::interlaced_frame
attribute_deprecated int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:530
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:480
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:770
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:79
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:108
ff_inlink_request_frame
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Definition: avfilter.c:1506
width
#define width
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:481
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:51
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
Definition: opt.h:227
config_output
static int config_output(AVFilterLink *outlink)
Definition: vf_fieldmatch.c:1046
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:617
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
fieldmatch_outputs
static const AVFilterPad fieldmatch_outputs[]
Definition: vf_fieldmatch.c:1063
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:465
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:102
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:479
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:609
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:66
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:80
frame
static AVFrame * frame
Definition: demux_decode.c:54
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:65
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: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:736
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
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
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:470
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:469
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:1337
FieldMatchContext::vsub
int vsub[2]
chroma subsampling values
Definition: vf_fieldmatch.c:84
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: internal.h:127
s2
#define s2
Definition: regdef.h:39
NB_MODE
@ NB_MODE
Definition: vf_fieldmatch.c:61
f
f
Definition: af_crystalizer.c:121
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:76
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
MODE_PC_N
@ MODE_PC_N
Definition: vf_fieldmatch.c:56
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:473
mN
@ mN
Definition: vf_fieldmatch.c:475
ff_vf_fieldmatch
const AVFilter ff_vf_fieldmatch
Definition: vf_fieldmatch.c:1071
comb_matching_mode
comb_matching_mode
Definition: vf_fieldmatch.c:64
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:475
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_fieldmatch.c:956
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
height
#define height
FM_PARITY_BOTTOM
@ FM_PARITY_BOTTOM
Definition: vf_fieldmatch.c:50
INPUT_MAIN
#define INPUT_MAIN
Definition: vf_fieldmatch.c:45
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:910
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
mB
@ mB
Definition: vf_fieldmatch.c:475
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:191
internal.h
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
SLIDING_FRAME_WINDOW
#define SLIDING_FRAME_WINDOW(prv, src, nxt)
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
FieldMatchContext::tpitchuv
int tpitchuv
Definition: vf_fieldmatch.c:112
AVFrame::top_field_first
attribute_deprecated int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:538
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:100
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: internal.h:53
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:636
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:467
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: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:100
FieldMatchContext::c_array
int * c_array
Definition: vf_fieldmatch.c:111
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:472
FieldMatchContext::prv
AVFrame * prv
Definition: vf_fieldmatch.c:81
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:477
fxo1m
static const int fxo1m[]
Definition: vf_fieldmatch.c:677
AVFrame::height
int height
Definition: frame.h:412
c2
static const uint64_t c2
Definition: murmur3.c:53
status
ov_status_e status
Definition: dnn_backend_openvino.c:119
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:65
FF_INLINK_IDX
#define FF_INLINK_IDX(link)
Find the index of a link.
Definition: internal.h:327
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
FieldMatchContext::prv2
AVFrame * prv2
Definition: vf_fieldmatch.c:82
mU
@ mU
Definition: vf_fieldmatch.c:475
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:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:397
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:83
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:70
FieldMatchContext::y0
int y0
Definition: vf_fieldmatch.c:96
fieldmatch_uninit
static av_cold void fieldmatch_uninit(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:1026
fieldmatch_init
static av_cold int fieldmatch_init(AVFilterContext *ctx)
Definition: vf_fieldmatch.c:992
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
Definition: opt.h:244
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:193
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:73
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:385
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
COMBMATCH_NONE
@ COMBMATCH_NONE
Definition: vf_fieldmatch.c:65
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
uninit
static av_cold int uninit(AVCodecContext *avctx)
Definition: crystalhd.c:285
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:474
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:478
FieldMatchContext::eof
uint32_t eof
bitmask for end of stream
Definition: vf_fieldmatch.c:86
int
int
Definition: ffmpeg_filter.c:368
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
Definition: opt.h:234
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:72
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:476