FFmpeg
vf_pullup.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003 Rich Felker
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/avassert.h"
22 #include "libavutil/imgutils.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/pixdesc.h"
25 #include "avfilter.h"
26 #include "formats.h"
27 #include "internal.h"
28 #include "video.h"
29 #include "vf_pullup.h"
30 
31 #define F_HAVE_BREAKS 1
32 #define F_HAVE_AFFINITY 2
33 
34 #define BREAK_LEFT 1
35 #define BREAK_RIGHT 2
36 
37 #define OFFSET(x) offsetof(PullupContext, x)
38 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
39 
40 static const AVOption pullup_options[] = {
41  { "jl", "set left junk size", OFFSET(junk_left), AV_OPT_TYPE_INT, {.i64=1}, 0, INT_MAX, FLAGS },
42  { "jr", "set right junk size", OFFSET(junk_right), AV_OPT_TYPE_INT, {.i64=1}, 0, INT_MAX, FLAGS },
43  { "jt", "set top junk size", OFFSET(junk_top), AV_OPT_TYPE_INT, {.i64=4}, 1, INT_MAX, FLAGS },
44  { "jb", "set bottom junk size", OFFSET(junk_bottom), AV_OPT_TYPE_INT, {.i64=4}, 1, INT_MAX, FLAGS },
45  { "sb", "set strict breaks", OFFSET(strict_breaks), AV_OPT_TYPE_BOOL,{.i64=0},-1, 1, FLAGS },
46  { "mp", "set metric plane", OFFSET(metric_plane), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "mp" },
47  { "y", "luma", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mp" },
48  { "u", "chroma blue", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mp" },
49  { "v", "chroma red", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "mp" },
50  { NULL }
51 };
52 
53 AVFILTER_DEFINE_CLASS(pullup);
54 
55 static const enum AVPixelFormat pix_fmts[] = {
63 };
64 
65 #define ABS(a) (((a) ^ ((a) >> 31)) - ((a) >> 31))
66 
67 static int diff_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
68 {
69  int i, j, diff = 0;
70 
71  for (i = 0; i < 4; i++) {
72  for (j = 0; j < 8; j++)
73  diff += ABS(a[j] - b[j]);
74  a += s;
75  b += s;
76  }
77 
78  return diff;
79 }
80 
81 static int comb_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
82 {
83  int i, j, comb = 0;
84 
85  for (i = 0; i < 4; i++) {
86  for (j = 0; j < 8; j++)
87  comb += ABS((a[j] << 1) - b[j - s] - b[j ]) +
88  ABS((b[j] << 1) - a[j ] - a[j + s]);
89  a += s;
90  b += s;
91  }
92 
93  return comb;
94 }
95 
96 static int var_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
97 {
98  int i, j, var = 0;
99 
100  for (i = 0; i < 3; i++) {
101  for (j = 0; j < 8; j++)
102  var += ABS(a[j] - a[j + s]);
103  a += s;
104  }
105 
106  return 4 * var; /* match comb scaling */
107 }
108 
110 {
111  f->diffs = av_calloc(FFALIGN(s->metric_length, 16), sizeof(*f->diffs));
112  f->combs = av_calloc(FFALIGN(s->metric_length, 16), sizeof(*f->combs));
113  f->vars = av_calloc(FFALIGN(s->metric_length, 16), sizeof(*f->vars));
114 
115  if (!f->diffs || !f->combs || !f->vars) {
116  av_freep(&f->diffs);
117  av_freep(&f->combs);
118  av_freep(&f->vars);
119  return AVERROR(ENOMEM);
120  }
121  return 0;
122 }
123 
124 static void free_field_queue(PullupField *head)
125 {
126  PullupField *f = head;
127  do {
128  PullupField *next;
129  if (!f)
130  break;
131  av_free(f->diffs);
132  av_free(f->combs);
133  av_free(f->vars);
134  next = f->next;
135  memset(f, 0, sizeof(*f)); // clear all pointers to avoid stale ones
136  av_free(f);
137  f = next;
138  } while (f != head);
139 }
140 
142 {
143  PullupField *head, *f;
144 
145  f = head = av_mallocz(sizeof(*head));
146  if (!f)
147  return NULL;
148 
149  if (alloc_metrics(s, f) < 0) {
150  av_free(f);
151  return NULL;
152  }
153 
154  for (; len > 0; len--) {
155  f->next = av_mallocz(sizeof(*f->next));
156  if (!f->next) {
157  free_field_queue(head);
158  return NULL;
159  }
160 
161  f->next->prev = f;
162  f = f->next;
163  if (alloc_metrics(s, f) < 0) {
164  free_field_queue(head);
165  return NULL;
166  }
167  }
168 
169  f->next = head;
170  head->prev = f;
171 
172  return head;
173 }
174 
176 {
177  AVFilterContext *ctx = inlink->dst;
178  PullupContext *s = ctx->priv;
180  int mp = s->metric_plane;
181 
182  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
183 
184  if (mp + 1 > s->nb_planes) {
185  av_log(ctx, AV_LOG_ERROR, "input format does not have such plane\n");
186  return AVERROR(EINVAL);
187  }
188 
189  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
190  s->planeheight[0] = s->planeheight[3] = inlink->h;
191  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
192  s->planewidth[0] = s->planewidth[3] = inlink->w;
193 
194  s->metric_w = (s->planewidth[mp] - ((s->junk_left + s->junk_right) << 3)) >> 3;
195  s->metric_h = (s->planeheight[mp] - ((s->junk_top + s->junk_bottom) << 1)) >> 3;
196  s->metric_offset = (s->junk_left << 3) + (s->junk_top << 1) * s->planewidth[mp];
197  s->metric_length = s->metric_w * s->metric_h;
198 
199  av_log(ctx, AV_LOG_DEBUG, "w: %d h: %d\n", s->metric_w, s->metric_h);
200  av_log(ctx, AV_LOG_DEBUG, "offset: %d length: %d\n", s->metric_offset, s->metric_length);
201 
202  s->head = make_field_queue(s, 8);
203  if (!s->head)
204  return AVERROR(ENOMEM);
205 
206  s->diff = diff_c;
207  s->comb = comb_c;
208  s->var = var_c;
209 
210 #if ARCH_X86
212 #endif
213  return 0;
214 }
215 
217 {
218  if (!b)
219  return NULL;
220 
221  if ((parity + 1) & 1)
222  b->lock[0]++;
223  if ((parity + 1) & 2)
224  b->lock[1]++;
225 
226  return b;
227 }
228 
230 {
231  if (!b)
232  return;
233 
234  if ((parity + 1) & 1)
235  b->lock[0]--;
236  if ((parity + 1) & 2)
237  b->lock[1]--;
238 }
239 
241 {
242  int i;
243 
244  if (b->planes[0])
245  return 0;
246  for (i = 0; i < s->nb_planes; i++) {
247  b->planes[i] = av_malloc(s->planeheight[i] * s->planewidth[i]);
248  }
249  if (s->nb_planes == 1)
250  b->planes[1] = av_malloc(4*256);
251 
252  return 0;
253 }
254 
256 {
257  int i;
258 
259  /* Try first to get the sister buffer for the previous field */
260  if (parity < 2 && s->last && parity != s->last->parity
261  && !s->last->buffer->lock[parity]) {
262  alloc_buffer(s, s->last->buffer);
263  return pullup_lock_buffer(s->last->buffer, parity);
264  }
265 
266  /* Prefer a buffer with both fields open */
267  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
268  if (s->buffers[i].lock[0])
269  continue;
270  if (s->buffers[i].lock[1])
271  continue;
272  alloc_buffer(s, &s->buffers[i]);
273  return pullup_lock_buffer(&s->buffers[i], parity);
274  }
275 
276  if (parity == 2)
277  return 0;
278 
279  /* Search for any half-free buffer */
280  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
281  if (((parity + 1) & 1) && s->buffers[i].lock[0])
282  continue;
283  if (((parity + 1) & 2) && s->buffers[i].lock[1])
284  continue;
285  alloc_buffer(s, &s->buffers[i]);
286  return pullup_lock_buffer(&s->buffers[i], parity);
287  }
288 
289  return NULL;
290 }
291 
292 static int queue_length(PullupField *begin, PullupField *end)
293 {
294  PullupField *f;
295  int count = 1;
296 
297  if (!begin || !end)
298  return 0;
299 
300  for (f = begin; f != end; f = f->next)
301  count++;
302 
303  return count;
304 }
305 
307 {
308  int i;
309 
310  for (i = 0; i < max; i++) {
311  if (f->breaks & BREAK_RIGHT || f->next->breaks & BREAK_LEFT)
312  return i + 1;
313  f = f->next;
314  }
315 
316  return 0;
317 }
318 
320 {
321  PullupField *f1 = f0->next;
322  PullupField *f2 = f1->next;
323  PullupField *f3 = f2->next;
324  int i, l, max_l = 0, max_r = 0;
325 
326  if (f0->flags & F_HAVE_BREAKS)
327  return;
328 
329  f0->flags |= F_HAVE_BREAKS;
330 
331  /* Special case when fields are 100% identical */
332  if (f0->buffer == f2->buffer && f1->buffer != f3->buffer) {
333  f2->breaks |= BREAK_RIGHT;
334  return;
335  }
336 
337  if (f0->buffer != f2->buffer && f1->buffer == f3->buffer) {
338  f1->breaks |= BREAK_LEFT;
339  return;
340  }
341 
342  for (i = 0; i < s->metric_length; i++) {
343  l = f2->diffs[i] - f3->diffs[i];
344 
345  if ( l > max_l)
346  max_l = l;
347  if (-l > max_r)
348  max_r = -l;
349  }
350 
351  /* Don't get tripped up when differences are mostly quant error */
352  if (max_l + max_r < 128)
353  return;
354  if (max_l > 4 * max_r)
355  f1->breaks |= BREAK_LEFT;
356  if (max_r > 4 * max_l)
357  f2->breaks |= BREAK_RIGHT;
358 }
359 
361 {
362  int i, max_l = 0, max_r = 0, l;
363 
364  if (f->flags & F_HAVE_AFFINITY)
365  return;
366 
367  f->flags |= F_HAVE_AFFINITY;
368 
369  if (f->buffer == f->next->next->buffer) {
370  f->affinity = 1;
371  f->next->affinity = 0;
372  f->next->next->affinity = -1;
373  f->next->flags |= F_HAVE_AFFINITY;
374  f->next->next->flags |= F_HAVE_AFFINITY;
375  return;
376  }
377 
378  for (i = 0; i < s->metric_length; i++) {
379  int v = f->vars[i];
380  int lv = f->prev->vars[i];
381  int rv = f->next->vars[i];
382  int lc = f-> combs[i] - 2*(v < lv ? v : lv);
383  int rc = f->next->combs[i] - 2*(v < rv ? v : rv);
384 
385  lc = FFMAX(lc, 0);
386  rc = FFMAX(rc, 0);
387  l = lc - rc;
388 
389  if ( l > max_l)
390  max_l = l;
391  if (-l > max_r)
392  max_r = -l;
393  }
394 
395  if (max_l + max_r < 64)
396  return;
397 
398  if (max_r > 6 * max_l)
399  f->affinity = -1;
400  else if (max_l > 6 * max_r)
401  f->affinity = 1;
402 }
403 
405 {
406  PullupField *f0 = s->first;
407  PullupField *f1 = f0->next;
408  PullupField *f2 = f1->next;
409  PullupField *f;
410  int i, l, n;
411 
412  if (queue_length(s->first, s->last) < 4)
413  return 0;
414 
415  f = s->first;
416  n = queue_length(f, s->last);
417  for (i = 0; i < n - 1; i++) {
418  if (i < n - 3)
419  compute_breaks(s, f);
420 
421  compute_affinity(s, f);
422 
423  f = f->next;
424  }
425 
426  if (f0->affinity == -1)
427  return 1;
428 
429  l = find_first_break(f0, 3);
430 
431  if (l == 1 && s->strict_breaks < 0)
432  l = 0;
433 
434  switch (l) {
435  case 1:
436  return 1 + (s->strict_breaks < 1 && f0->affinity == 1 && f1->affinity == -1);
437  case 2:
438  /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
439  if (s->strict_pairs
440  && (f0->prev->breaks & BREAK_RIGHT) && (f2->breaks & BREAK_LEFT)
441  && (f0->affinity != 1 || f1->affinity != -1) )
442  return 1;
443  return 1 + (f1->affinity != 1);
444  case 3:
445  return 2 + (f2->affinity != 1);
446  default:
447  /* 9 possibilities covered before switch */
448  if (f1->affinity == 1)
449  return 1; /* covers 6 */
450  else if (f1->affinity == -1)
451  return 2; /* covers 6 */
452  else if (f2->affinity == -1) { /* covers 2 */
453  return (f0->affinity == 1) ? 3 : 1;
454  } else {
455  return 2; /* the remaining 6 */
456  }
457  }
458 }
459 
461 {
462  PullupFrame *fr = &s->frame;
463  int i, n = decide_frame_length(s);
464  int aff = s->first->next->affinity;
465 
467  if (!n || fr->lock)
468  return NULL;
469 
470  fr->lock++;
471  fr->length = n;
472  fr->parity = s->first->parity;
473  fr->buffer = 0;
474 
475  for (i = 0; i < n; i++) {
476  /* We cheat and steal the buffer without release+relock */
477  fr->ifields[i] = s->first->buffer;
478  s->first->buffer = 0;
479  s->first = s->first->next;
480  }
481 
482  if (n == 1) {
483  fr->ofields[fr->parity ] = fr->ifields[0];
484  fr->ofields[fr->parity ^ 1] = 0;
485  } else if (n == 2) {
486  fr->ofields[fr->parity ] = fr->ifields[0];
487  fr->ofields[fr->parity ^ 1] = fr->ifields[1];
488  } else if (n == 3) {
489  if (!aff)
490  aff = (fr->ifields[0] == fr->ifields[1]) ? -1 : 1;
491  fr->ofields[fr->parity ] = fr->ifields[1 + aff];
492  fr->ofields[fr->parity ^ 1] = fr->ifields[1 ];
493  }
494 
495  pullup_lock_buffer(fr->ofields[0], 0);
496  pullup_lock_buffer(fr->ofields[1], 1);
497 
498  if (fr->ofields[0] == fr->ofields[1]) {
499  fr->buffer = fr->ofields[0];
500  pullup_lock_buffer(fr->buffer, 2);
501  return fr;
502  }
503 
504  return fr;
505 }
506 
508 {
509  int i;
510 
511  for (i = 0; i < f->length; i++)
512  pullup_release_buffer(f->ifields[i], f->parity ^ (i & 1));
513 
514  pullup_release_buffer(f->ofields[0], 0);
515  pullup_release_buffer(f->ofields[1], 1);
516 
517  if (f->buffer)
518  pullup_release_buffer(f->buffer, 2);
519  f->lock--;
520 }
521 
522 static void compute_metric(PullupContext *s, int *dest,
523  PullupField *fa, int pa, PullupField *fb, int pb,
524  int (*func)(const uint8_t *, const uint8_t *, ptrdiff_t))
525 {
526  int mp = s->metric_plane;
527  int xstep = 8;
528  int ystep = s->planewidth[mp] << 3;
529  int stride = s->planewidth[mp] << 1; /* field stride */
530  int w = s->metric_w * xstep;
531  uint8_t *a, *b;
532  int x, y;
533 
534  if (!fa->buffer || !fb->buffer)
535  return;
536 
537  /* Shortcut for duplicate fields (e.g. from RFF flag) */
538  if (fa->buffer == fb->buffer && pa == pb) {
539  memset(dest, 0, s->metric_length * sizeof(*dest));
540  return;
541  }
542 
543  a = fa->buffer->planes[mp] + pa * s->planewidth[mp] + s->metric_offset;
544  b = fb->buffer->planes[mp] + pb * s->planewidth[mp] + s->metric_offset;
545 
546  for (y = 0; y < s->metric_h; y++) {
547  for (x = 0; x < w; x += xstep)
548  *dest++ = func(a + x, b + x, stride);
549  a += ystep; b += ystep;
550  }
551 }
552 
554 {
555  int ret;
556 
557  if (s->head->next == s->first) {
558  PullupField *f = av_mallocz(sizeof(*f));
559 
560  if (!f)
561  return AVERROR(ENOMEM);
562 
563  if ((ret = alloc_metrics(s, f)) < 0) {
564  av_free(f);
565  return ret;
566  }
567 
568  f->prev = s->head;
569  f->next = s->first;
570  s->head->next = f;
571  s->first->prev = f;
572  }
573 
574  return 0;
575 }
576 
578 {
579  PullupField *f;
580 
581  /* Grow the circular list if needed */
582  if (check_field_queue(s) < 0)
583  return;
584 
585  /* Cannot have two fields of same parity in a row; drop the new one */
586  if (s->last && s->last->parity == parity)
587  return;
588 
589  f = s->head;
590  f->parity = parity;
591  f->buffer = pullup_lock_buffer(b, parity);
592  f->flags = 0;
593  f->breaks = 0;
594  f->affinity = 0;
595 
596  compute_metric(s, f->diffs, f, parity, f->prev->prev, parity, s->diff);
597  compute_metric(s, f->combs, parity ? f->prev : f, 0, parity ? f : f->prev, 1, s->comb);
598  compute_metric(s, f->vars, f, parity, f, -1, s->var);
599  emms_c();
600 
601  /* Advance the circular list */
602  if (!s->first)
603  s->first = s->head;
604 
605  s->last = s->head;
606  s->head = s->head->next;
607 }
608 
610  PullupBuffer *dst, PullupBuffer *src, int parity)
611 {
612  uint8_t *dd, *ss;
613  int i;
614 
615  for (i = 0; i < s->nb_planes; i++) {
616  ss = src->planes[i] + parity * s->planewidth[i];
617  dd = dst->planes[i] + parity * s->planewidth[i];
618 
619  av_image_copy_plane(dd, s->planewidth[i] << 1,
620  ss, s->planewidth[i] << 1,
621  s->planewidth[i], s->planeheight[i] >> 1);
622  }
623 }
624 
626 {
627  int i;
628 
629  if (fr->buffer)
630  return;
631 
632  if (fr->length < 2)
633  return; /* FIXME: deal with this */
634 
635  for (i = 0; i < 2; i++) {
636  if (fr->ofields[i]->lock[i^1])
637  continue;
638 
639  fr->buffer = fr->ofields[i];
640  pullup_lock_buffer(fr->buffer, 2);
641  copy_field(s, fr->buffer, fr->ofields[i^1], i^1);
642  return;
643  }
644 
645  fr->buffer = pullup_get_buffer(s, 2);
646 
647  copy_field(s, fr->buffer, fr->ofields[0], 0);
648  copy_field(s, fr->buffer, fr->ofields[1], 1);
649 }
650 
652 {
653  AVFilterContext *ctx = inlink->dst;
654  AVFilterLink *outlink = ctx->outputs[0];
655  PullupContext *s = ctx->priv;
656  PullupBuffer *b;
657  PullupFrame *f;
658  AVFrame *out;
659  int p, ret = 0;
660 
661  b = pullup_get_buffer(s, 2);
662  if (!b) {
663  av_log(ctx, AV_LOG_WARNING, "Could not get buffer!\n");
664  f = pullup_get_frame(s);
666  goto end;
667  }
668 
669  av_image_copy(b->planes, s->planewidth,
670  (const uint8_t**)in->data, in->linesize,
671  inlink->format, inlink->w, inlink->h);
672 
673  p = in->interlaced_frame ? !in->top_field_first : 0;
674  pullup_submit_field(s, b, p );
675  pullup_submit_field(s, b, p^1);
676 
677  if (in->repeat_pict)
678  pullup_submit_field(s, b, p);
679 
681 
682  f = pullup_get_frame(s);
683  if (!f)
684  goto end;
685 
686  if (f->length < 2) {
688  f = pullup_get_frame(s);
689  if (!f)
690  goto end;
691  if (f->length < 2) {
693  if (!in->repeat_pict)
694  goto end;
695  f = pullup_get_frame(s);
696  if (!f)
697  goto end;
698  if (f->length < 2) {
700  goto end;
701  }
702  }
703  }
704 
705  /* If the frame isn't already exportable... */
706  if (!f->buffer)
708 
709  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
710  if (!out) {
711  ret = AVERROR(ENOMEM);
712  goto end;
713  }
715 
716  av_image_copy(out->data, out->linesize,
717  (const uint8_t**)f->buffer->planes, s->planewidth,
718  inlink->format, inlink->w, inlink->h);
719 
720  ret = ff_filter_frame(outlink, out);
722 end:
723  av_frame_free(&in);
724  return ret;
725 }
726 
728 {
729  PullupContext *s = ctx->priv;
730  int i;
731 
732  free_field_queue(s->head);
733  s->last = NULL;
734 
735  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
736  av_freep(&s->buffers[i].planes[0]);
737  av_freep(&s->buffers[i].planes[1]);
738  av_freep(&s->buffers[i].planes[2]);
739  }
740 }
741 
742 static const AVFilterPad pullup_inputs[] = {
743  {
744  .name = "default",
745  .type = AVMEDIA_TYPE_VIDEO,
746  .filter_frame = filter_frame,
747  .config_props = config_input,
748  },
749 };
750 
751 static const AVFilterPad pullup_outputs[] = {
752  {
753  .name = "default",
754  .type = AVMEDIA_TYPE_VIDEO,
755  },
756 };
757 
759  .name = "pullup",
760  .description = NULL_IF_CONFIG_SMALL("Pullup from field sequence to frames."),
761  .priv_size = sizeof(PullupContext),
762  .priv_class = &pullup_class,
763  .uninit = uninit,
767 };
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
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:68
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
pullup_options
static const AVOption pullup_options[]
Definition: vf_pullup.c:40
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
pullup_get_frame
static PullupFrame * pullup_get_frame(PullupContext *s)
Definition: vf_pullup.c:460
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:999
ff_vf_pullup
const AVFilter ff_vf_pullup
Definition: vf_pullup.c:758
pullup_get_buffer
static PullupBuffer * pullup_get_buffer(PullupContext *s, int parity)
Definition: vf_pullup.c:255
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2675
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:170
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
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_pullup.c:175
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:116
mp
static double mp(int i, double w0, double r)
Definition: af_atilt.c:60
alloc_buffer
static int alloc_buffer(PullupContext *s, PullupBuffer *b)
Definition: vf_pullup.c:240
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
AVFrame::top_field_first
int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:482
AVOption
AVOption.
Definition: opt.h:251
b
#define b
Definition: input.c:34
pullup_outputs
static const AVFilterPad pullup_outputs[]
Definition: vf_pullup.c:751
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
vf_pullup.h
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:175
pullup_pack_frame
static void pullup_pack_frame(PullupContext *s, PullupFrame *fr)
Definition: vf_pullup.c:625
queue_length
static int queue_length(PullupField *begin, PullupField *end)
Definition: vf_pullup.c:292
video.h
var_c
static int var_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
Definition: vf_pullup.c:96
FLAGS
#define FLAGS
Definition: vf_pullup.c:38
PullupField
Definition: vf_pullup.h:29
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:346
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
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
formats.h
comb_c
static int comb_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
Definition: vf_pullup.c:81
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2715
ABS
#define ABS(a)
Definition: vf_pullup.c:65
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_pullup.c:651
F_HAVE_BREAKS
#define F_HAVE_BREAKS
Definition: vf_pullup.c:31
compute_metric
static void compute_metric(PullupContext *s, int *dest, PullupField *fa, int pa, PullupField *fb, int pb, int(*func)(const uint8_t *, const uint8_t *, ptrdiff_t))
Definition: vf_pullup.c:522
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:260
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
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:248
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
PullupField::affinity
int affinity
Definition: vf_pullup.h:34
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
pullup_inputs
static const AVFilterPad pullup_inputs[]
Definition: vf_pullup.c:742
PullupBuffer::planes
uint8_t * planes[4]
Definition: vf_pullup.h:26
OFFSET
#define OFFSET(x)
Definition: vf_pullup.c:37
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
BREAK_LEFT
#define BREAK_LEFT
Definition: vf_pullup.c:34
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(pullup)
pullup_release_buffer
static void pullup_release_buffer(PullupBuffer *b, int parity)
Definition: vf_pullup.c:229
s
#define s(width, name)
Definition: cbs_vp9.c:256
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:50
pullup_lock_buffer
static PullupBuffer * pullup_lock_buffer(PullupBuffer *b, int parity)
Definition: vf_pullup.c:216
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
PullupContext
Definition: vf_pullup.h:49
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:190
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
check_field_queue
static int check_field_queue(PullupContext *s)
Definition: vf_pullup.c:553
decide_frame_length
static int decide_frame_length(PullupContext *s)
Definition: vf_pullup.c:404
PullupFrame::length
int length
Definition: vf_pullup.h:43
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:603
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
PullupFrame::ifields
PullupBuffer * ifields[4]
Definition: vf_pullup.h:45
F_HAVE_AFFINITY
#define F_HAVE_AFFINITY
Definition: vf_pullup.c:32
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
PullupFrame::buffer
PullupBuffer * buffer
Definition: vf_pullup.h:46
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_pullup.c:55
f
f
Definition: af_crystalizer.c:122
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:117
parity
mcdeint parity
Definition: vf_mcdeint.c:266
PullupField::buffer
PullupBuffer * buffer
Definition: vf_pullup.h:31
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
PullupFrame::lock
int lock
Definition: vf_pullup.h:42
pullup_submit_field
static void pullup_submit_field(PullupContext *s, PullupBuffer *b, int parity)
Definition: vf_pullup.c:577
internal.h
alloc_metrics
static int alloc_metrics(PullupContext *s, PullupField *f)
Definition: vf_pullup.c:109
compute_breaks
static void compute_breaks(PullupContext *s, PullupField *f0)
Definition: vf_pullup.c:319
AVFrame::interlaced_frame
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:477
PullupFrame::parity
int parity
Definition: vf_pullup.h:44
compute_affinity
static void compute_affinity(PullupContext *s, PullupField *f)
Definition: vf_pullup.c:360
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
fb
#define fb(width, name)
Definition: cbs_av1.c:549
find_first_break
static int find_first_break(PullupField *f, int max)
Definition: vf_pullup.c:306
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
copy_field
static void copy_field(PullupContext *s, PullupBuffer *dst, PullupBuffer *src, int parity)
Definition: vf_pullup.c:609
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:264
BREAK_RIGHT
#define BREAK_RIGHT
Definition: vf_pullup.c:35
len
int len
Definition: vorbis_enc_data.h:426
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_pullup.c:727
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
stride
#define stride
Definition: h264pred_template.c:537
AVFilter
Filter definition.
Definition: avfilter.h:171
ret
ret
Definition: filter_design.txt:187
PullupFrame::ofields
PullupBuffer * ofields[2]
Definition: vf_pullup.h:45
free_field_queue
static void free_field_queue(PullupField *head)
Definition: vf_pullup.c:124
PullupField::next
struct PullupField * next
Definition: vf_pullup.h:38
make_field_queue
static PullupField * make_field_queue(PullupContext *s, int len)
Definition: vf_pullup.c:141
PullupBuffer::lock
int lock[2]
Definition: vf_pullup.h:25
av_image_copy
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
Definition: imgutils.c:422
PullupField::prev
struct PullupField * prev
Definition: vf_pullup.h:38
PullupBuffer
Definition: vf_pullup.h:24
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
diff_c
static int diff_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
Definition: vf_pullup.c:67
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:408
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
PullupField::flags
unsigned flags
Definition: vf_pullup.h:32
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
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
ff_pullup_init_x86
void ff_pullup_init_x86(PullupContext *s)
Definition: vf_pullup_init.c:29
diff
static av_always_inline int diff(const uint32_t a, const uint32_t b)
Definition: vf_palettegen.c:139
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
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:191
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
PullupField::diffs
int * diffs
Definition: vf_pullup.h:35
imgutils.h
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:370
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
PullupFrame
Definition: vf_pullup.h:41
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
pullup_release_frame
static void pullup_release_frame(PullupFrame *f)
Definition: vf_pullup.c:507
PullupField::breaks
int breaks
Definition: vf_pullup.h:33
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
AVFrame::repeat_pict
int repeat_pict
When decoding, this signals how much the picture must be delayed.
Definition: frame.h:472