FFmpeg
vf_tinterlace.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Thomas Mundt <tmundt75@gmail.com>
3  * Copyright (c) 2011 Stefano Sabatini
4  * Copyright (c) 2010 Baptiste Coudurier
5  * Copyright (c) 2003 Michael Zucchi <notzed@ximian.com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with FFmpeg if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /**
25  * @file
26  * temporal field interlace filter, ported from MPlayer/libmpcodecs
27  */
28 
29 #include "libavutil/opt.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/avassert.h"
32 #include "avfilter.h"
33 #include "internal.h"
34 #include "tinterlace.h"
35 
36 #define OFFSET(x) offsetof(TInterlaceContext, x)
37 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
38 
39 static const AVOption tinterlace_options[] = {
40  {"mode", "select interlace mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=MODE_MERGE}, 0, MODE_NB-1, FLAGS, "mode"},
41  {"merge", "merge fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_MERGE}, INT_MIN, INT_MAX, FLAGS, "mode"},
42  {"drop_even", "drop even fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_DROP_EVEN}, INT_MIN, INT_MAX, FLAGS, "mode"},
43  {"drop_odd", "drop odd fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_DROP_ODD}, INT_MIN, INT_MAX, FLAGS, "mode"},
44  {"pad", "pad alternate lines with black", 0, AV_OPT_TYPE_CONST, {.i64=MODE_PAD}, INT_MIN, INT_MAX, FLAGS, "mode"},
45  {"interleave_top", "interleave top and bottom fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_TOP}, INT_MIN, INT_MAX, FLAGS, "mode"},
46  {"interleave_bottom", "interleave bottom and top fields", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLEAVE_BOTTOM}, INT_MIN, INT_MAX, FLAGS, "mode"},
47  {"interlacex2", "interlace fields from two consecutive frames", 0, AV_OPT_TYPE_CONST, {.i64=MODE_INTERLACEX2}, INT_MIN, INT_MAX, FLAGS, "mode"},
48  {"mergex2", "merge fields keeping same frame rate", 0, AV_OPT_TYPE_CONST, {.i64=MODE_MERGEX2}, INT_MIN, INT_MAX, FLAGS, "mode"},
49 
50  {"flags", "set flags", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, 0, "flags" },
51  {"low_pass_filter", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
52  {"vlpf", "enable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_VLPF}, INT_MIN, INT_MAX, FLAGS, "flags" },
53  {"complex_filter", "enable complex vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
54  {"cvlpf", "enable complex vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_CVLPF},INT_MIN, INT_MAX, FLAGS, "flags" },
55  {"exact_tb", "force a timebase which can represent timestamps exactly", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_EXACT_TB}, INT_MIN, INT_MAX, FLAGS, "flags" },
56  {"bypass_il", "bypass already interlaced frames", 0, AV_OPT_TYPE_CONST, {.i64 = TINTERLACE_FLAG_BYPASS_IL}, INT_MIN, INT_MAX, FLAGS, "flags" },
57 
58  {NULL}
59 };
60 
61 AVFILTER_DEFINE_CLASS(tinterlace);
62 
63 static const AVOption interlace_options[] = {
64  { "scan", "scanning mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64 = MODE_TFF}, 0, 1, FLAGS, "mode"},
65  { "tff", "top field first", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_TFF}, INT_MIN, INT_MAX, FLAGS, .unit = "mode"},
66  { "bff", "bottom field first", 0, AV_OPT_TYPE_CONST, {.i64 = MODE_BFF}, INT_MIN, INT_MAX, FLAGS, .unit = "mode"},
67  { "lowpass", "set vertical low-pass filter", OFFSET(lowpass), AV_OPT_TYPE_INT, {.i64 = VLPF_LIN}, 0, 2, FLAGS, "lowpass" },
68  { "off", "disable vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = VLPF_OFF}, INT_MIN, INT_MAX, FLAGS, "lowpass" },
69  { "linear", "linear vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = VLPF_LIN}, INT_MIN, INT_MAX, FLAGS, "lowpass" },
70  { "complex", "complex vertical low-pass filter", 0, AV_OPT_TYPE_CONST, {.i64 = VLPF_CMP}, INT_MIN, INT_MAX, FLAGS, "lowpass" },
71 
72  { NULL }
73 };
74 
75 AVFILTER_DEFINE_CLASS(interlace);
76 
77 #define FULL_SCALE_YUVJ_FORMATS \
78  AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P
79 
80 static const enum AVPixelFormat full_scale_yuvj_pix_fmts[] = {
82 };
83 
84 static const AVRational standard_tbs[] = {
85  {1, 25},
86  {1, 30},
87  {1001, 30000},
88 };
89 
90 static const enum AVPixelFormat pix_fmts[] = {
102 };
103 
104 static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
105  ptrdiff_t mref, ptrdiff_t pref, int clip_max)
106 {
107  const uint8_t *srcp_above = srcp + mref;
108  const uint8_t *srcp_below = srcp + pref;
109  int i;
110  for (i = 0; i < width; i++) {
111  // this calculation is an integer representation of
112  // '0.5 * current + 0.25 * above + 0.25 * below'
113  // '1 +' is for rounding.
114  dstp[i] = (1 + srcp[i] + srcp[i] + srcp_above[i] + srcp_below[i]) >> 2;
115  }
116 }
117 
118 static void lowpass_line_c_16(uint8_t *dst8, ptrdiff_t width, const uint8_t *src8,
119  ptrdiff_t mref, ptrdiff_t pref, int clip_max)
120 {
121  uint16_t *dstp = (uint16_t *)dst8;
122  const uint16_t *srcp = (const uint16_t *)src8;
123  const uint16_t *srcp_above = srcp + mref / 2;
124  const uint16_t *srcp_below = srcp + pref / 2;
125  int i, src_x;
126  for (i = 0; i < width; i++) {
127  // this calculation is an integer representation of
128  // '0.5 * current + 0.25 * above + 0.25 * below'
129  // '1 +' is for rounding.
130  src_x = av_le2ne16(srcp[i]) << 1;
131  dstp[i] = av_le2ne16((1 + src_x + av_le2ne16(srcp_above[i])
132  + av_le2ne16(srcp_below[i])) >> 2);
133  }
134 }
135 
136 static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp,
137  ptrdiff_t mref, ptrdiff_t pref, int clip_max)
138 {
139  const uint8_t *srcp_above = srcp + mref;
140  const uint8_t *srcp_below = srcp + pref;
141  const uint8_t *srcp_above2 = srcp + mref * 2;
142  const uint8_t *srcp_below2 = srcp + pref * 2;
143  int i, src_x, src_ab;
144  for (i = 0; i < width; i++) {
145  // this calculation is an integer representation of
146  // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2'
147  // '4 +' is for rounding.
148  src_x = srcp[i] << 1;
149  src_ab = srcp_above[i] + srcp_below[i];
150  dstp[i] = av_clip_uint8((4 + ((srcp[i] + src_x + src_ab) << 1)
151  - srcp_above2[i] - srcp_below2[i]) >> 3);
152  // Prevent over-sharpening:
153  // dst must not exceed src when the average of above and below
154  // is less than src. And the other way around.
155  if (src_ab > src_x) {
156  if (dstp[i] < srcp[i])
157  dstp[i] = srcp[i];
158  } else if (dstp[i] > srcp[i])
159  dstp[i] = srcp[i];
160  }
161 }
162 
163 static void lowpass_line_complex_c_16(uint8_t *dst8, ptrdiff_t width, const uint8_t *src8,
164  ptrdiff_t mref, ptrdiff_t pref, int clip_max)
165 {
166  uint16_t *dstp = (uint16_t *)dst8;
167  const uint16_t *srcp = (const uint16_t *)src8;
168  const uint16_t *srcp_above = srcp + mref / 2;
169  const uint16_t *srcp_below = srcp + pref / 2;
170  const uint16_t *srcp_above2 = srcp + mref;
171  const uint16_t *srcp_below2 = srcp + pref;
172  int i, dst_le, src_le, src_x, src_ab;
173  for (i = 0; i < width; i++) {
174  // this calculation is an integer representation of
175  // '0.75 * current + 0.25 * above + 0.25 * below - 0.125 * above2 - 0.125 * below2'
176  // '4 +' is for rounding.
177  src_le = av_le2ne16(srcp[i]);
178  src_x = src_le << 1;
179  src_ab = av_le2ne16(srcp_above[i]) + av_le2ne16(srcp_below[i]);
180  dst_le = av_clip((4 + ((src_le + src_x + src_ab) << 1)
181  - av_le2ne16(srcp_above2[i])
182  - av_le2ne16(srcp_below2[i])) >> 3, 0, clip_max);
183  // Prevent over-sharpening:
184  // dst must not exceed src when the average of above and below
185  // is less than src. And the other way around.
186  if (src_ab > src_x) {
187  if (dst_le < src_le)
188  dstp[i] = av_le2ne16(src_le);
189  else
190  dstp[i] = av_le2ne16(dst_le);
191  } else if (dst_le > src_le) {
192  dstp[i] = av_le2ne16(src_le);
193  } else
194  dstp[i] = av_le2ne16(dst_le);
195  }
196 }
197 
199 {
200  TInterlaceContext *tinterlace = ctx->priv;
201 
202  av_frame_free(&tinterlace->cur );
203  av_frame_free(&tinterlace->next);
204  av_freep(&tinterlace->black_data[0][0]);
205  av_freep(&tinterlace->black_data[1][0]);
206 }
207 
208 static int config_out_props(AVFilterLink *outlink)
209 {
210  AVFilterContext *ctx = outlink->src;
211  AVFilterLink *inlink = outlink->src->inputs[0];
213  TInterlaceContext *tinterlace = ctx->priv;
214  int i;
215 
216  tinterlace->vsub = desc->log2_chroma_h;
217  outlink->w = inlink->w;
218  outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD || tinterlace->mode == MODE_MERGEX2?
219  inlink->h*2 : inlink->h;
220  if (tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD || tinterlace->mode == MODE_MERGEX2)
221  outlink->sample_aspect_ratio = av_mul_q(inlink->sample_aspect_ratio,
222  av_make_q(2, 1));
223 
224  if (tinterlace->mode == MODE_PAD) {
225  uint8_t black[4] = { 0, 0, 0, 16 };
226  int ret;
227  ff_draw_init(&tinterlace->draw, outlink->format, 0);
228  ff_draw_color(&tinterlace->draw, &tinterlace->color, black);
229  /* limited range */
230  if (!ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts)) {
231  ret = av_image_alloc(tinterlace->black_data[0], tinterlace->black_linesize,
232  outlink->w, outlink->h, outlink->format, 16);
233  if (ret < 0)
234  return ret;
235  ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data[0],
236  tinterlace->black_linesize, 0, 0, outlink->w, outlink->h);
237  }
238  /* full range */
239  tinterlace->color.comp[0].u8[0] = 0;
240  ret = av_image_alloc(tinterlace->black_data[1], tinterlace->black_linesize,
241  outlink->w, outlink->h, outlink->format, 16);
242  if (ret < 0)
243  return ret;
244  ff_fill_rectangle(&tinterlace->draw, &tinterlace->color, tinterlace->black_data[1],
245  tinterlace->black_linesize, 0, 0, outlink->w, outlink->h);
246  }
247  if (tinterlace->flags & (TINTERLACE_FLAG_VLPF | TINTERLACE_FLAG_CVLPF)
248  && !(tinterlace->mode == MODE_INTERLEAVE_TOP
249  || tinterlace->mode == MODE_INTERLEAVE_BOTTOM)) {
250  av_log(ctx, AV_LOG_WARNING, "low_pass_filter flags ignored with mode %d\n",
251  tinterlace->mode);
253  }
254  tinterlace->preout_time_base = inlink->time_base;
255  if (tinterlace->mode == MODE_INTERLACEX2) {
256  tinterlace->preout_time_base.den *= 2;
257  outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){2,1});
258  outlink->time_base = av_mul_q(inlink->time_base , (AVRational){1,2});
259  } else if (tinterlace->mode == MODE_MERGEX2) {
260  outlink->frame_rate = inlink->frame_rate;
261  outlink->time_base = inlink->time_base;
262  } else if (tinterlace->mode != MODE_PAD) {
263  outlink->frame_rate = av_mul_q(inlink->frame_rate, (AVRational){1,2});
264  outlink->time_base = av_mul_q(inlink->time_base , (AVRational){2,1});
265  }
266 
267  for (i = 0; i<FF_ARRAY_ELEMS(standard_tbs); i++){
268  if (!av_cmp_q(standard_tbs[i], outlink->time_base))
269  break;
270  }
271  if (i == FF_ARRAY_ELEMS(standard_tbs) ||
272  (tinterlace->flags & TINTERLACE_FLAG_EXACT_TB))
273  outlink->time_base = tinterlace->preout_time_base;
274 
275  tinterlace->csp = av_pix_fmt_desc_get(outlink->format);
276  if (tinterlace->flags & TINTERLACE_FLAG_CVLPF) {
277  if (tinterlace->csp->comp[0].depth > 8)
279  else
280  tinterlace->lowpass_line = lowpass_line_complex_c;
281 #if ARCH_X86
282  ff_tinterlace_init_x86(tinterlace);
283 #endif
284  } else if (tinterlace->flags & TINTERLACE_FLAG_VLPF) {
285  if (tinterlace->csp->comp[0].depth > 8)
286  tinterlace->lowpass_line = lowpass_line_c_16;
287  else
288  tinterlace->lowpass_line = lowpass_line_c;
289 #if ARCH_X86
290  ff_tinterlace_init_x86(tinterlace);
291 #endif
292  }
293 
294  av_log(ctx, AV_LOG_VERBOSE, "mode:%d filter:%s h:%d -> h:%d\n", tinterlace->mode,
295  (tinterlace->flags & TINTERLACE_FLAG_CVLPF) ? "complex" :
296  (tinterlace->flags & TINTERLACE_FLAG_VLPF) ? "linear" : "off",
297  inlink->h, outlink->h);
298 
299  return 0;
300 }
301 
302 #define FIELD_UPPER 0
303 #define FIELD_LOWER 1
304 #define FIELD_UPPER_AND_LOWER 2
305 
306 /**
307  * Copy picture field from src to dst.
308  *
309  * @param src_field copy from upper, lower field or both
310  * @param interleave leave a padding line between each copied line
311  * @param dst_field copy to upper or lower field,
312  * only meaningful when interleave is selected
313  * @param flags context flags
314  */
315 static inline
317  uint8_t *dst[4], int dst_linesize[4],
318  const uint8_t *src[4], int src_linesize[4],
319  enum AVPixelFormat format, int w, int src_h,
320  int src_field, int interleave, int dst_field,
321  int flags)
322 {
324  int hsub = desc->log2_chroma_w;
325  int plane, vsub = desc->log2_chroma_h;
326  int k = src_field == FIELD_UPPER_AND_LOWER ? 1 : 2;
327  int h;
328 
329  for (plane = 0; plane < desc->nb_components; plane++) {
330  int lines = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT(src_h, vsub) : src_h;
331  int cols = plane == 1 || plane == 2 ? AV_CEIL_RSHIFT( w, hsub) : w;
332  uint8_t *dstp = dst[plane];
333  const uint8_t *srcp = src[plane];
334  int srcp_linesize = src_linesize[plane] * k;
335  int dstp_linesize = dst_linesize[plane] * (interleave ? 2 : 1);
336  int clip_max = (1 << tinterlace->csp->comp[plane].depth) - 1;
337 
338  lines = (lines + (src_field == FIELD_UPPER)) / k;
339  if (src_field == FIELD_LOWER)
340  srcp += src_linesize[plane];
341  if (interleave && dst_field == FIELD_LOWER)
342  dstp += dst_linesize[plane];
343  // Low-pass filtering is required when creating an interlaced destination from
344  // a progressive source which contains high-frequency vertical detail.
345  // Filtering will reduce interlace 'twitter' and Moire patterning.
347  int x = !!(flags & TINTERLACE_FLAG_CVLPF);
348  for (h = lines; h > 0; h--) {
349  ptrdiff_t pref = src_linesize[plane];
350  ptrdiff_t mref = -pref;
351  if (h >= (lines - x)) mref = 0; // there is no line above
352  else if (h <= (1 + x)) pref = 0; // there is no line below
353 
354  tinterlace->lowpass_line(dstp, cols, srcp, mref, pref, clip_max);
355  dstp += dstp_linesize;
356  srcp += srcp_linesize;
357  }
358  } else {
359  if (tinterlace->csp->comp[plane].depth > 8)
360  cols *= 2;
361  av_image_copy_plane(dstp, dstp_linesize, srcp, srcp_linesize, cols, lines);
362  }
363  }
364 }
365 
367 {
368  AVFilterContext *ctx = inlink->dst;
369  AVFilterLink *outlink = ctx->outputs[0];
370  TInterlaceContext *tinterlace = ctx->priv;
371  AVFrame *cur, *next, *out;
372  int field, tff, full, ret;
373 
374  av_frame_free(&tinterlace->cur);
375  tinterlace->cur = tinterlace->next;
376  tinterlace->next = picref;
377 
378  cur = tinterlace->cur;
379  next = tinterlace->next;
380  /* we need at least two frames */
381  if (!tinterlace->cur)
382  return 0;
383 
384  switch (tinterlace->mode) {
385  case MODE_MERGEX2: /* move the odd frame into the upper field of the new image, even into
386  * the lower field, generating a double-height video at same framerate */
387  case MODE_MERGE: /* move the odd frame into the upper field of the new image, even into
388  * the lower field, generating a double-height video at half framerate */
389  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
390  if (!out)
391  return AVERROR(ENOMEM);
392  av_frame_copy_props(out, cur);
393  out->height = outlink->h;
394  out->interlaced_frame = 1;
395  out->top_field_first = 1;
396  out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio, av_make_q(2, 1));
397 
398  /* write odd frame lines into the upper field of the new frame */
399  copy_picture_field(tinterlace, out->data, out->linesize,
400  (const uint8_t **)cur->data, cur->linesize,
401  inlink->format, inlink->w, inlink->h,
402  FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? (1 + inlink->frame_count_out) & 1 ? FIELD_LOWER : FIELD_UPPER : FIELD_UPPER, tinterlace->flags);
403  /* write even frame lines into the lower field of the new frame */
404  copy_picture_field(tinterlace, out->data, out->linesize,
405  (const uint8_t **)next->data, next->linesize,
406  inlink->format, inlink->w, inlink->h,
407  FIELD_UPPER_AND_LOWER, 1, tinterlace->mode == MODE_MERGEX2 ? (1 + inlink->frame_count_out) & 1 ? FIELD_UPPER : FIELD_LOWER : FIELD_LOWER, tinterlace->flags);
408  if (tinterlace->mode != MODE_MERGEX2)
409  av_frame_free(&tinterlace->next);
410  break;
411 
412  case MODE_DROP_ODD: /* only output even frames, odd frames are dropped; height unchanged, half framerate */
413  case MODE_DROP_EVEN: /* only output odd frames, even frames are dropped; height unchanged, half framerate */
414  out = av_frame_clone(tinterlace->mode == MODE_DROP_EVEN ? cur : next);
415  if (!out)
416  return AVERROR(ENOMEM);
417  av_frame_free(&tinterlace->next);
418  break;
419 
420  case MODE_PAD: /* expand each frame to double height, but pad alternate
421  * lines with black; framerate unchanged */
422  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
423  if (!out)
424  return AVERROR(ENOMEM);
425  av_frame_copy_props(out, cur);
426  out->height = outlink->h;
427  out->sample_aspect_ratio = av_mul_q(cur->sample_aspect_ratio, av_make_q(2, 1));
428 
429  field = (1 + outlink->frame_count_in) & 1 ? FIELD_UPPER : FIELD_LOWER;
430  full = out->color_range == AVCOL_RANGE_JPEG || ff_fmt_is_in(out->format, full_scale_yuvj_pix_fmts);
431  /* copy upper and lower fields */
432  copy_picture_field(tinterlace, out->data, out->linesize,
433  (const uint8_t **)cur->data, cur->linesize,
434  inlink->format, inlink->w, inlink->h,
435  FIELD_UPPER_AND_LOWER, 1, field, tinterlace->flags);
436  /* pad with black the other field */
437  copy_picture_field(tinterlace, out->data, out->linesize,
438  (const uint8_t **)tinterlace->black_data[full], tinterlace->black_linesize,
439  inlink->format, inlink->w, inlink->h,
440  FIELD_UPPER_AND_LOWER, 1, !field, tinterlace->flags);
441  break;
442 
443  /* interleave upper/lower lines from odd frames with lower/upper lines from even frames,
444  * halving the frame rate and preserving image height */
445  case MODE_INTERLEAVE_TOP: /* top field first */
446  case MODE_INTERLEAVE_BOTTOM: /* bottom field first */
447  if ((tinterlace->flags & TINTERLACE_FLAG_BYPASS_IL) && cur->interlaced_frame) {
449  "video is already interlaced, adjusting framerate only\n");
450  out = av_frame_clone(cur);
451  if (!out)
452  return AVERROR(ENOMEM);
453  out->pts /= 2; // adjust pts to new framerate
454  ret = ff_filter_frame(outlink, out);
455  return ret;
456  }
457  tff = tinterlace->mode == MODE_INTERLEAVE_TOP;
458  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
459  if (!out)
460  return AVERROR(ENOMEM);
461  av_frame_copy_props(out, cur);
462  out->interlaced_frame = 1;
463  out->top_field_first = tff;
464 
465  /* copy upper/lower field from cur */
466  copy_picture_field(tinterlace, out->data, out->linesize,
467  (const uint8_t **)cur->data, cur->linesize,
468  inlink->format, inlink->w, inlink->h,
469  tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,
470  tinterlace->flags);
471  /* copy lower/upper field from next */
472  copy_picture_field(tinterlace, out->data, out->linesize,
473  (const uint8_t **)next->data, next->linesize,
474  inlink->format, inlink->w, inlink->h,
475  tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
476  tinterlace->flags);
477  av_frame_free(&tinterlace->next);
478  break;
479  case MODE_INTERLACEX2: /* re-interlace preserving image height, double frame rate */
480  /* output current frame first */
481  out = av_frame_clone(cur);
482  if (!out)
483  return AVERROR(ENOMEM);
484  out->interlaced_frame = 1;
485  if (cur->pts != AV_NOPTS_VALUE)
486  out->pts = cur->pts*2;
487 
488  out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base, outlink->time_base);
489  if ((ret = ff_filter_frame(outlink, out)) < 0)
490  return ret;
491 
492  /* output mix of current and next frame */
493  tff = next->top_field_first;
494  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
495  if (!out)
496  return AVERROR(ENOMEM);
497  av_frame_copy_props(out, next);
498  out->interlaced_frame = 1;
499  out->top_field_first = !tff;
500 
501  if (next->pts != AV_NOPTS_VALUE && cur->pts != AV_NOPTS_VALUE)
502  out->pts = cur->pts + next->pts;
503  else
504  out->pts = AV_NOPTS_VALUE;
505  /* write current frame second field lines into the second field of the new frame */
506  copy_picture_field(tinterlace, out->data, out->linesize,
507  (const uint8_t **)cur->data, cur->linesize,
508  inlink->format, inlink->w, inlink->h,
509  tff ? FIELD_LOWER : FIELD_UPPER, 1, tff ? FIELD_LOWER : FIELD_UPPER,
510  tinterlace->flags);
511  /* write next frame first field lines into the first field of the new frame */
512  copy_picture_field(tinterlace, out->data, out->linesize,
513  (const uint8_t **)next->data, next->linesize,
514  inlink->format, inlink->w, inlink->h,
515  tff ? FIELD_UPPER : FIELD_LOWER, 1, tff ? FIELD_UPPER : FIELD_LOWER,
516  tinterlace->flags);
517  break;
518  default:
519  av_assert0(0);
520  }
521 
522  out->pts = av_rescale_q(out->pts, tinterlace->preout_time_base, outlink->time_base);
523  out->duration = av_rescale_q(1, av_inv_q(outlink->frame_rate), outlink->time_base);
524  ret = ff_filter_frame(outlink, out);
525 
526  return ret;
527 }
528 
530 {
531  TInterlaceContext *tinterlace = ctx->priv;
532 
533  if (tinterlace->mode <= MODE_BFF)
534  tinterlace->mode += MODE_INTERLEAVE_TOP;
535 
536  tinterlace->flags |= TINTERLACE_FLAG_BYPASS_IL;
537  if (tinterlace->lowpass == VLPF_LIN)
538  tinterlace->flags |= TINTERLACE_FLAG_VLPF;
539  if (tinterlace->lowpass == VLPF_CMP)
540  tinterlace->flags |= TINTERLACE_FLAG_CVLPF;
541 
542  return 0;
543 }
544 
545 static const AVFilterPad tinterlace_inputs[] = {
546  {
547  .name = "default",
548  .type = AVMEDIA_TYPE_VIDEO,
549  .filter_frame = filter_frame,
550  },
551 };
552 
553 static const AVFilterPad tinterlace_outputs[] = {
554  {
555  .name = "default",
556  .type = AVMEDIA_TYPE_VIDEO,
557  .config_props = config_out_props,
558  },
559 };
560 
562  .name = "tinterlace",
563  .description = NULL_IF_CONFIG_SMALL("Perform temporal field interlacing."),
564  .priv_size = sizeof(TInterlaceContext),
565  .uninit = uninit,
569  .priv_class = &tinterlace_class,
570 };
571 
572 
574  .name = "interlace",
575  .description = NULL_IF_CONFIG_SMALL("Convert progressive video into interlaced."),
576  .priv_size = sizeof(TInterlaceContext),
577  .init = init_interlace,
578  .uninit = uninit,
582  .priv_class = &interlace_class,
583 };
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:101
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *picref)
Definition: vf_tinterlace.c:366
MODE_MERGE
@ MODE_MERGE
Definition: tinterlace.h:48
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
av_clip
#define av_clip
Definition: common.h:95
init_interlace
static int init_interlace(AVFilterContext *ctx)
Definition: vf_tinterlace.c:529
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
out
FILE * out
Definition: movenc.c:54
TINTERLACE_FLAG_BYPASS_IL
#define TINTERLACE_FLAG_BYPASS_IL
Definition: tinterlace.h:39
standard_tbs
static const AVRational standard_tbs[]
Definition: vf_tinterlace.c:84
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:969
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2888
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:174
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
TInterlaceContext::lowpass_line
void(* lowpass_line)(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, ptrdiff_t mref, ptrdiff_t pref, int clip_max)
Definition: tinterlace.h:78
lowpass_line_complex_c
static void lowpass_line_complex_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, ptrdiff_t mref, ptrdiff_t pref, int clip_max)
Definition: vf_tinterlace.c:136
FIELD_UPPER_AND_LOWER
#define FIELD_UPPER_AND_LOWER
Definition: vf_tinterlace.c:304
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:99
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:437
w
uint8_t w
Definition: llviddspenc.c:38
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:661
TInterlaceContext
Definition: tinterlace.h:64
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
TInterlaceContext::color
FFDrawColor color
Definition: tinterlace.h:76
AVOption
AVOption.
Definition: opt.h:251
TInterlaceContext::black_linesize
int black_linesize[4]
Definition: tinterlace.h:74
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:165
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:351
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
hsub
static void hsub(htype *dst, const htype *src, int bins)
Definition: vf_median.c:74
VLPF_LIN
@ VLPF_LIN
Definition: tinterlace.h:43
MODE_INTERLEAVE_TOP
@ MODE_INTERLEAVE_TOP
Definition: tinterlace.h:52
TInterlaceContext::vsub
int vsub
chroma vertical subsampling
Definition: tinterlace.h:70
TInterlaceContext::preout_time_base
AVRational preout_time_base
Definition: tinterlace.h:67
AV_PIX_FMT_YUV420P12LE
@ AV_PIX_FMT_YUV420P12LE
planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:261
OFFSET
#define OFFSET(x)
Definition: vf_tinterlace.c:36
config_out_props
static int config_out_props(AVFilterLink *outlink)
Definition: vf_tinterlace.c:208
FIELD_LOWER
#define FIELD_LOWER
Definition: vf_tinterlace.c:303
tinterlace_inputs
static const AVFilterPad tinterlace_inputs[]
Definition: vf_tinterlace.c:545
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
AV_PIX_FMT_YUV420P10LE
@ AV_PIX_FMT_YUV420P10LE
planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
Definition: pixfmt.h:149
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_tinterlace.c:198
AV_PIX_FMT_YUV444P12LE
@ AV_PIX_FMT_YUV444P12LE
planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:269
avassert.h
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
MODE_MERGEX2
@ MODE_MERGEX2
Definition: tinterlace.h:55
TInterlaceContext::flags
int flags
flags affecting interlacing algorithm
Definition: tinterlace.h:68
TInterlaceContext::csp
const AVPixFmtDescriptor * csp
Definition: tinterlace.h:77
width
#define width
TInterlaceContext::cur
AVFrame * cur
Definition: tinterlace.h:71
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:50
format
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 format(the sample packing is implied by the sample format) and sample rate. The lists are not just lists
VLPF_CMP
@ VLPF_CMP
Definition: tinterlace.h:44
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
TInterlaceContext::next
AVFrame * next
Definition: tinterlace.h:72
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:465
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
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
ff_draw_init
int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
Definition: drawutils.c:151
TInterlaceContext::black_data
uint8_t * black_data[2][4]
buffer used to fill padded lines (limited/full)
Definition: tinterlace.h:73
ff_tinterlace_init_x86
void ff_tinterlace_init_x86(TInterlaceContext *interlace)
Definition: vf_tinterlace_init.c:57
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
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:194
ff_vf_tinterlace
const AVFilter ff_vf_tinterlace
Definition: vf_tinterlace.c:561
AV_PIX_FMT_YUV444P10LE
@ AV_PIX_FMT_YUV444P10LE
planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
Definition: pixfmt.h:155
AV_PIX_FMT_YUVA422P10LE
@ AV_PIX_FMT_YUVA422P10LE
planar YUV 4:2:2 30bpp, (1 Cr & Cb sample per 2x1 Y & A samples, little-endian)
Definition: pixfmt.h:177
TINTERLACE_FLAG_EXACT_TB
#define TINTERLACE_FLAG_EXACT_TB
Definition: tinterlace.h:38
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:594
tinterlace_options
static const AVOption tinterlace_options[]
Definition: vf_tinterlace.c:39
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ff_vf_interlace
const AVFilter ff_vf_interlace
Definition: vf_tinterlace.c:573
AVFilterContext::inputs
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:400
TInterlaceContext::mode
int mode
TInterlaceMode, interlace mode selected.
Definition: tinterlace.h:66
ff_fmt_is_in
int ff_fmt_is_in(int fmt, const int *fmts)
Tell if an integer is contained in the provided -1-terminated list of integers.
Definition: formats.c:351
MODE_DROP_EVEN
@ MODE_DROP_EVEN
Definition: tinterlace.h:49
FFDrawColor::u8
uint8_t u8[16]
Definition: drawutils.h:55
AV_PIX_FMT_YUV440P10LE
@ AV_PIX_FMT_YUV440P10LE
planar YUV 4:4:0,20bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
Definition: pixfmt.h:295
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
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
interleave
static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dst_linesize, int src_linesize, enum FilterMode mode, int swap)
Definition: vf_il.c:108
lowpass
@ lowpass
Definition: af_biquads.c:85
AV_PIX_FMT_YUV440P12LE
@ AV_PIX_FMT_YUV440P12LE
planar YUV 4:4:0,24bpp, (1 Cr & Cb sample per 1x2 Y samples), little-endian
Definition: pixfmt.h:297
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:115
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_tinterlace.c:90
AV_PIX_FMT_YUV422P10LE
@ AV_PIX_FMT_YUV422P10LE
planar YUV 4:2:2, 20bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:151
FFDrawColor::comp
union FFDrawColor::@222 comp[MAX_PLANES]
TINTERLACE_FLAG_CVLPF
#define TINTERLACE_FLAG_CVLPF
Definition: tinterlace.h:37
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
ff_fill_rectangle
void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color, uint8_t *dst[], int dst_linesize[], int dst_x, int dst_y, int w, int h)
Fill a rectangle with an uniform color.
Definition: drawutils.c:231
av_le2ne16
#define av_le2ne16(x)
Definition: bswap.h:97
AV_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:167
FULL_SCALE_YUVJ_FORMATS
#define FULL_SCALE_YUVJ_FORMATS
Definition: vf_tinterlace.c:77
copy_picture_field
static void copy_picture_field(TInterlaceContext *tinterlace, uint8_t *dst[4], int dst_linesize[4], const uint8_t *src[4], int src_linesize[4], enum AVPixelFormat format, int w, int src_h, int src_field, int interleave, int dst_field, int flags)
Copy picture field from src to dst.
Definition: vf_tinterlace.c:316
AV_PIX_FMT_YUVA420P10LE
@ AV_PIX_FMT_YUVA420P10LE
planar YUV 4:2:0 25bpp, (1 Cr & Cb sample per 2x2 Y & A samples, little-endian)
Definition: pixfmt.h:175
internal.h
AVFrame::interlaced_frame
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:486
MODE_NB
@ MODE_NB
Definition: avf_avectorscope.c:41
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
MODE_INTERLEAVE_BOTTOM
@ MODE_INTERLEAVE_BOTTOM
Definition: tinterlace.h:53
FIELD_UPPER
#define FIELD_UPPER
Definition: vf_tinterlace.c:302
MODE_BFF
@ MODE_BFF
Definition: tinterlace.h:61
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
ff_draw_color
void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
Prepare a color.
Definition: drawutils.c:156
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
AVFilter
Filter definition.
Definition: avfilter.h:161
TInterlaceContext::lowpass
int lowpass
legacy interlace filter lowpass mode
Definition: tinterlace.h:69
ret
ret
Definition: filter_design.txt:187
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:432
tinterlace.h
AVRational::den
int den
Denominator.
Definition: rational.h:60
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
MODE_PAD
@ MODE_PAD
Definition: tinterlace.h:51
avfilter.h
TInterlaceContext::draw
FFDrawContext draw
Definition: tinterlace.h:75
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
av_mul_q
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition: rational.c:80
av_clip_uint8
#define av_clip_uint8
Definition: common.h:101
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:392
MODE_INTERLACEX2
@ MODE_INTERLACEX2
Definition: tinterlace.h:54
lowpass_line_c
static void lowpass_line_c(uint8_t *dstp, ptrdiff_t width, const uint8_t *srcp, ptrdiff_t mref, ptrdiff_t pref, int clip_max)
Definition: vf_tinterlace.c:104
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
VLPF_OFF
@ VLPF_OFF
Definition: tinterlace.h:42
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
full_scale_yuvj_pix_fmts
static enum AVPixelFormat full_scale_yuvj_pix_fmts[]
Definition: vf_tinterlace.c:80
AV_PIX_FMT_YUVA444P10LE
@ AV_PIX_FMT_YUVA444P10LE
planar YUV 4:4:4 40bpp, (1 Cr & Cb sample per 1x1 Y & A samples, little-endian)
Definition: pixfmt.h:179
lowpass_line_complex_c_16
static void lowpass_line_complex_c_16(uint8_t *dst8, ptrdiff_t width, const uint8_t *src8, ptrdiff_t mref, ptrdiff_t pref, int clip_max)
Definition: vf_tinterlace.c:163
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:195
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
MODE_TFF
@ MODE_TFF
Definition: tinterlace.h:60
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
TINTERLACE_FLAG_VLPF
#define TINTERLACE_FLAG_VLPF
Definition: tinterlace.h:36
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:224
imgutils.h
interlace_options
static const AVOption interlace_options[]
Definition: vf_tinterlace.c:63
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
lowpass_line_c_16
static void lowpass_line_c_16(uint8_t *dst8, ptrdiff_t width, const uint8_t *src8, ptrdiff_t mref, ptrdiff_t pref, int clip_max)
Definition: vf_tinterlace.c:118
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:375
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
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
FLAGS
#define FLAGS
Definition: vf_tinterlace.c:37
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
AV_PIX_FMT_YUV422P12LE
@ AV_PIX_FMT_YUV422P12LE
planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
Definition: pixfmt.h:265
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(tinterlace)
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:166
MODE_DROP_ODD
@ MODE_DROP_ODD
Definition: tinterlace.h:50
tinterlace_outputs
static const AVFilterPad tinterlace_outputs[]
Definition: vf_tinterlace.c:553