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 
56 {
57  static const enum AVPixelFormat pix_fmts[] = {
65  };
66 
68 }
69 
70 #define ABS(a) (((a) ^ ((a) >> 31)) - ((a) >> 31))
71 
72 static int diff_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
73 {
74  int i, j, diff = 0;
75 
76  for (i = 0; i < 4; i++) {
77  for (j = 0; j < 8; j++)
78  diff += ABS(a[j] - b[j]);
79  a += s;
80  b += s;
81  }
82 
83  return diff;
84 }
85 
86 static int comb_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
87 {
88  int i, j, comb = 0;
89 
90  for (i = 0; i < 4; i++) {
91  for (j = 0; j < 8; j++)
92  comb += ABS((a[j] << 1) - b[j - s] - b[j ]) +
93  ABS((b[j] << 1) - a[j ] - a[j + s]);
94  a += s;
95  b += s;
96  }
97 
98  return comb;
99 }
100 
101 static int var_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
102 {
103  int i, j, var = 0;
104 
105  for (i = 0; i < 3; i++) {
106  for (j = 0; j < 8; j++)
107  var += ABS(a[j] - a[j + s]);
108  a += s;
109  }
110 
111  return 4 * var; /* match comb scaling */
112 }
113 
115 {
116  f->diffs = av_calloc(FFALIGN(s->metric_length, 16), sizeof(*f->diffs));
117  f->combs = av_calloc(FFALIGN(s->metric_length, 16), sizeof(*f->combs));
118  f->vars = av_calloc(FFALIGN(s->metric_length, 16), sizeof(*f->vars));
119 
120  if (!f->diffs || !f->combs || !f->vars) {
121  av_freep(&f->diffs);
122  av_freep(&f->combs);
123  av_freep(&f->vars);
124  return AVERROR(ENOMEM);
125  }
126  return 0;
127 }
128 
129 static void free_field_queue(PullupField *head)
130 {
131  PullupField *f = head;
132  do {
133  PullupField *next;
134  if (!f)
135  break;
136  av_free(f->diffs);
137  av_free(f->combs);
138  av_free(f->vars);
139  next = f->next;
140  memset(f, 0, sizeof(*f)); // clear all pointers to avoid stale ones
141  av_free(f);
142  f = next;
143  } while (f != head);
144 }
145 
147 {
148  PullupField *head, *f;
149 
150  f = head = av_mallocz(sizeof(*head));
151  if (!f)
152  return NULL;
153 
154  if (alloc_metrics(s, f) < 0) {
155  av_free(f);
156  return NULL;
157  }
158 
159  for (; len > 0; len--) {
160  f->next = av_mallocz(sizeof(*f->next));
161  if (!f->next) {
162  free_field_queue(head);
163  return NULL;
164  }
165 
166  f->next->prev = f;
167  f = f->next;
168  if (alloc_metrics(s, f) < 0) {
169  free_field_queue(head);
170  return NULL;
171  }
172  }
173 
174  f->next = head;
175  head->prev = f;
176 
177  return head;
178 }
179 
181 {
182  AVFilterContext *ctx = inlink->dst;
183  PullupContext *s = ctx->priv;
185  int mp = s->metric_plane;
186 
187  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
188 
189  if (mp + 1 > s->nb_planes) {
190  av_log(ctx, AV_LOG_ERROR, "input format does not have such plane\n");
191  return AVERROR(EINVAL);
192  }
193 
194  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
195  s->planeheight[0] = s->planeheight[3] = inlink->h;
196  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
197  s->planewidth[0] = s->planewidth[3] = inlink->w;
198 
199  s->metric_w = (s->planewidth[mp] - ((s->junk_left + s->junk_right) << 3)) >> 3;
200  s->metric_h = (s->planeheight[mp] - ((s->junk_top + s->junk_bottom) << 1)) >> 3;
201  s->metric_offset = (s->junk_left << 3) + (s->junk_top << 1) * s->planewidth[mp];
202  s->metric_length = s->metric_w * s->metric_h;
203 
204  av_log(ctx, AV_LOG_DEBUG, "w: %d h: %d\n", s->metric_w, s->metric_h);
205  av_log(ctx, AV_LOG_DEBUG, "offset: %d length: %d\n", s->metric_offset, s->metric_length);
206 
207  s->head = make_field_queue(s, 8);
208  if (!s->head)
209  return AVERROR(ENOMEM);
210 
211  s->diff = diff_c;
212  s->comb = comb_c;
213  s->var = var_c;
214 
215  if (ARCH_X86)
217  return 0;
218 }
219 
221 {
222  if (!b)
223  return NULL;
224 
225  if ((parity + 1) & 1)
226  b->lock[0]++;
227  if ((parity + 1) & 2)
228  b->lock[1]++;
229 
230  return b;
231 }
232 
234 {
235  if (!b)
236  return;
237 
238  if ((parity + 1) & 1)
239  b->lock[0]--;
240  if ((parity + 1) & 2)
241  b->lock[1]--;
242 }
243 
245 {
246  int i;
247 
248  if (b->planes[0])
249  return 0;
250  for (i = 0; i < s->nb_planes; i++) {
251  b->planes[i] = av_malloc(s->planeheight[i] * s->planewidth[i]);
252  }
253  if (s->nb_planes == 1)
254  b->planes[1] = av_malloc(4*256);
255 
256  return 0;
257 }
258 
260 {
261  int i;
262 
263  /* Try first to get the sister buffer for the previous field */
264  if (parity < 2 && s->last && parity != s->last->parity
265  && !s->last->buffer->lock[parity]) {
266  alloc_buffer(s, s->last->buffer);
267  return pullup_lock_buffer(s->last->buffer, parity);
268  }
269 
270  /* Prefer a buffer with both fields open */
271  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
272  if (s->buffers[i].lock[0])
273  continue;
274  if (s->buffers[i].lock[1])
275  continue;
276  alloc_buffer(s, &s->buffers[i]);
277  return pullup_lock_buffer(&s->buffers[i], parity);
278  }
279 
280  if (parity == 2)
281  return 0;
282 
283  /* Search for any half-free buffer */
284  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
285  if (((parity + 1) & 1) && s->buffers[i].lock[0])
286  continue;
287  if (((parity + 1) & 2) && s->buffers[i].lock[1])
288  continue;
289  alloc_buffer(s, &s->buffers[i]);
290  return pullup_lock_buffer(&s->buffers[i], parity);
291  }
292 
293  return NULL;
294 }
295 
296 static int queue_length(PullupField *begin, PullupField *end)
297 {
298  PullupField *f;
299  int count = 1;
300 
301  if (!begin || !end)
302  return 0;
303 
304  for (f = begin; f != end; f = f->next)
305  count++;
306 
307  return count;
308 }
309 
311 {
312  int i;
313 
314  for (i = 0; i < max; i++) {
315  if (f->breaks & BREAK_RIGHT || f->next->breaks & BREAK_LEFT)
316  return i + 1;
317  f = f->next;
318  }
319 
320  return 0;
321 }
322 
324 {
325  PullupField *f1 = f0->next;
326  PullupField *f2 = f1->next;
327  PullupField *f3 = f2->next;
328  int i, l, max_l = 0, max_r = 0;
329 
330  if (f0->flags & F_HAVE_BREAKS)
331  return;
332 
333  f0->flags |= F_HAVE_BREAKS;
334 
335  /* Special case when fields are 100% identical */
336  if (f0->buffer == f2->buffer && f1->buffer != f3->buffer) {
337  f2->breaks |= BREAK_RIGHT;
338  return;
339  }
340 
341  if (f0->buffer != f2->buffer && f1->buffer == f3->buffer) {
342  f1->breaks |= BREAK_LEFT;
343  return;
344  }
345 
346  for (i = 0; i < s->metric_length; i++) {
347  l = f2->diffs[i] - f3->diffs[i];
348 
349  if ( l > max_l)
350  max_l = l;
351  if (-l > max_r)
352  max_r = -l;
353  }
354 
355  /* Don't get tripped up when differences are mostly quant error */
356  if (max_l + max_r < 128)
357  return;
358  if (max_l > 4 * max_r)
359  f1->breaks |= BREAK_LEFT;
360  if (max_r > 4 * max_l)
361  f2->breaks |= BREAK_RIGHT;
362 }
363 
365 {
366  int i, max_l = 0, max_r = 0, l;
367 
368  if (f->flags & F_HAVE_AFFINITY)
369  return;
370 
371  f->flags |= F_HAVE_AFFINITY;
372 
373  if (f->buffer == f->next->next->buffer) {
374  f->affinity = 1;
375  f->next->affinity = 0;
376  f->next->next->affinity = -1;
377  f->next->flags |= F_HAVE_AFFINITY;
378  f->next->next->flags |= F_HAVE_AFFINITY;
379  return;
380  }
381 
382  for (i = 0; i < s->metric_length; i++) {
383  int v = f->vars[i];
384  int lv = f->prev->vars[i];
385  int rv = f->next->vars[i];
386  int lc = f-> combs[i] - 2*(v < lv ? v : lv);
387  int rc = f->next->combs[i] - 2*(v < rv ? v : rv);
388 
389  lc = FFMAX(lc, 0);
390  rc = FFMAX(rc, 0);
391  l = lc - rc;
392 
393  if ( l > max_l)
394  max_l = l;
395  if (-l > max_r)
396  max_r = -l;
397  }
398 
399  if (max_l + max_r < 64)
400  return;
401 
402  if (max_r > 6 * max_l)
403  f->affinity = -1;
404  else if (max_l > 6 * max_r)
405  f->affinity = 1;
406 }
407 
409 {
410  PullupField *f0 = s->first;
411  PullupField *f1 = f0->next;
412  PullupField *f2 = f1->next;
413  PullupField *f;
414  int i, l, n;
415 
416  if (queue_length(s->first, s->last) < 4)
417  return 0;
418 
419  f = s->first;
420  n = queue_length(f, s->last);
421  for (i = 0; i < n - 1; i++) {
422  if (i < n - 3)
423  compute_breaks(s, f);
424 
425  compute_affinity(s, f);
426 
427  f = f->next;
428  }
429 
430  if (f0->affinity == -1)
431  return 1;
432 
433  l = find_first_break(f0, 3);
434 
435  if (l == 1 && s->strict_breaks < 0)
436  l = 0;
437 
438  switch (l) {
439  case 1:
440  return 1 + (s->strict_breaks < 1 && f0->affinity == 1 && f1->affinity == -1);
441  case 2:
442  /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
443  if (s->strict_pairs
444  && (f0->prev->breaks & BREAK_RIGHT) && (f2->breaks & BREAK_LEFT)
445  && (f0->affinity != 1 || f1->affinity != -1) )
446  return 1;
447  return 1 + (f1->affinity != 1);
448  case 3:
449  return 2 + (f2->affinity != 1);
450  default:
451  /* 9 possibilities covered before switch */
452  if (f1->affinity == 1)
453  return 1; /* covers 6 */
454  else if (f1->affinity == -1)
455  return 2; /* covers 6 */
456  else if (f2->affinity == -1) { /* covers 2 */
457  return (f0->affinity == 1) ? 3 : 1;
458  } else {
459  return 2; /* the remaining 6 */
460  }
461  }
462 }
463 
465 {
466  PullupFrame *fr = &s->frame;
467  int i, n = decide_frame_length(s);
468  int aff = s->first->next->affinity;
469 
471  if (!n || fr->lock)
472  return NULL;
473 
474  fr->lock++;
475  fr->length = n;
476  fr->parity = s->first->parity;
477  fr->buffer = 0;
478 
479  for (i = 0; i < n; i++) {
480  /* We cheat and steal the buffer without release+relock */
481  fr->ifields[i] = s->first->buffer;
482  s->first->buffer = 0;
483  s->first = s->first->next;
484  }
485 
486  if (n == 1) {
487  fr->ofields[fr->parity ] = fr->ifields[0];
488  fr->ofields[fr->parity ^ 1] = 0;
489  } else if (n == 2) {
490  fr->ofields[fr->parity ] = fr->ifields[0];
491  fr->ofields[fr->parity ^ 1] = fr->ifields[1];
492  } else if (n == 3) {
493  if (!aff)
494  aff = (fr->ifields[0] == fr->ifields[1]) ? -1 : 1;
495  fr->ofields[fr->parity ] = fr->ifields[1 + aff];
496  fr->ofields[fr->parity ^ 1] = fr->ifields[1 ];
497  }
498 
499  pullup_lock_buffer(fr->ofields[0], 0);
500  pullup_lock_buffer(fr->ofields[1], 1);
501 
502  if (fr->ofields[0] == fr->ofields[1]) {
503  fr->buffer = fr->ofields[0];
504  pullup_lock_buffer(fr->buffer, 2);
505  return fr;
506  }
507 
508  return fr;
509 }
510 
512 {
513  int i;
514 
515  for (i = 0; i < f->length; i++)
516  pullup_release_buffer(f->ifields[i], f->parity ^ (i & 1));
517 
518  pullup_release_buffer(f->ofields[0], 0);
519  pullup_release_buffer(f->ofields[1], 1);
520 
521  if (f->buffer)
522  pullup_release_buffer(f->buffer, 2);
523  f->lock--;
524 }
525 
526 static void compute_metric(PullupContext *s, int *dest,
527  PullupField *fa, int pa, PullupField *fb, int pb,
528  int (*func)(const uint8_t *, const uint8_t *, ptrdiff_t))
529 {
530  int mp = s->metric_plane;
531  int xstep = 8;
532  int ystep = s->planewidth[mp] << 3;
533  int stride = s->planewidth[mp] << 1; /* field stride */
534  int w = s->metric_w * xstep;
535  uint8_t *a, *b;
536  int x, y;
537 
538  if (!fa->buffer || !fb->buffer)
539  return;
540 
541  /* Shortcut for duplicate fields (e.g. from RFF flag) */
542  if (fa->buffer == fb->buffer && pa == pb) {
543  memset(dest, 0, s->metric_length * sizeof(*dest));
544  return;
545  }
546 
547  a = fa->buffer->planes[mp] + pa * s->planewidth[mp] + s->metric_offset;
548  b = fb->buffer->planes[mp] + pb * s->planewidth[mp] + s->metric_offset;
549 
550  for (y = 0; y < s->metric_h; y++) {
551  for (x = 0; x < w; x += xstep)
552  *dest++ = func(a + x, b + x, stride);
553  a += ystep; b += ystep;
554  }
555 }
556 
558 {
559  int ret;
560 
561  if (s->head->next == s->first) {
562  PullupField *f = av_mallocz(sizeof(*f));
563 
564  if (!f)
565  return AVERROR(ENOMEM);
566 
567  if ((ret = alloc_metrics(s, f)) < 0) {
568  av_free(f);
569  return ret;
570  }
571 
572  f->prev = s->head;
573  f->next = s->first;
574  s->head->next = f;
575  s->first->prev = f;
576  }
577 
578  return 0;
579 }
580 
582 {
583  PullupField *f;
584 
585  /* Grow the circular list if needed */
586  if (check_field_queue(s) < 0)
587  return;
588 
589  /* Cannot have two fields of same parity in a row; drop the new one */
590  if (s->last && s->last->parity == parity)
591  return;
592 
593  f = s->head;
594  f->parity = parity;
595  f->buffer = pullup_lock_buffer(b, parity);
596  f->flags = 0;
597  f->breaks = 0;
598  f->affinity = 0;
599 
600  compute_metric(s, f->diffs, f, parity, f->prev->prev, parity, s->diff);
601  compute_metric(s, f->combs, parity ? f->prev : f, 0, parity ? f : f->prev, 1, s->comb);
602  compute_metric(s, f->vars, f, parity, f, -1, s->var);
603  emms_c();
604 
605  /* Advance the circular list */
606  if (!s->first)
607  s->first = s->head;
608 
609  s->last = s->head;
610  s->head = s->head->next;
611 }
612 
614  PullupBuffer *dst, PullupBuffer *src, int parity)
615 {
616  uint8_t *dd, *ss;
617  int i;
618 
619  for (i = 0; i < s->nb_planes; i++) {
620  ss = src->planes[i] + parity * s->planewidth[i];
621  dd = dst->planes[i] + parity * s->planewidth[i];
622 
623  av_image_copy_plane(dd, s->planewidth[i] << 1,
624  ss, s->planewidth[i] << 1,
625  s->planewidth[i], s->planeheight[i] >> 1);
626  }
627 }
628 
630 {
631  int i;
632 
633  if (fr->buffer)
634  return;
635 
636  if (fr->length < 2)
637  return; /* FIXME: deal with this */
638 
639  for (i = 0; i < 2; i++) {
640  if (fr->ofields[i]->lock[i^1])
641  continue;
642 
643  fr->buffer = fr->ofields[i];
644  pullup_lock_buffer(fr->buffer, 2);
645  copy_field(s, fr->buffer, fr->ofields[i^1], i^1);
646  return;
647  }
648 
649  fr->buffer = pullup_get_buffer(s, 2);
650 
651  copy_field(s, fr->buffer, fr->ofields[0], 0);
652  copy_field(s, fr->buffer, fr->ofields[1], 1);
653 }
654 
656 {
657  AVFilterContext *ctx = inlink->dst;
658  AVFilterLink *outlink = ctx->outputs[0];
659  PullupContext *s = ctx->priv;
660  PullupBuffer *b;
661  PullupFrame *f;
662  AVFrame *out;
663  int p, ret = 0;
664 
665  b = pullup_get_buffer(s, 2);
666  if (!b) {
667  av_log(ctx, AV_LOG_WARNING, "Could not get buffer!\n");
668  f = pullup_get_frame(s);
670  goto end;
671  }
672 
673  av_image_copy(b->planes, s->planewidth,
674  (const uint8_t**)in->data, in->linesize,
675  inlink->format, inlink->w, inlink->h);
676 
677  p = in->interlaced_frame ? !in->top_field_first : 0;
678  pullup_submit_field(s, b, p );
679  pullup_submit_field(s, b, p^1);
680 
681  if (in->repeat_pict)
682  pullup_submit_field(s, b, p);
683 
685 
686  f = pullup_get_frame(s);
687  if (!f)
688  goto end;
689 
690  if (f->length < 2) {
692  f = pullup_get_frame(s);
693  if (!f)
694  goto end;
695  if (f->length < 2) {
697  if (!in->repeat_pict)
698  goto end;
699  f = pullup_get_frame(s);
700  if (!f)
701  goto end;
702  if (f->length < 2) {
704  goto end;
705  }
706  }
707  }
708 
709  /* If the frame isn't already exportable... */
710  if (!f->buffer)
712 
713  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
714  if (!out) {
715  ret = AVERROR(ENOMEM);
716  goto end;
717  }
719 
720  av_image_copy(out->data, out->linesize,
721  (const uint8_t**)f->buffer->planes, s->planewidth,
722  inlink->format, inlink->w, inlink->h);
723 
724  ret = ff_filter_frame(outlink, out);
726 end:
727  av_frame_free(&in);
728  return ret;
729 }
730 
732 {
733  PullupContext *s = ctx->priv;
734  int i;
735 
736  free_field_queue(s->head);
737  s->last = NULL;
738 
739  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
740  av_freep(&s->buffers[i].planes[0]);
741  av_freep(&s->buffers[i].planes[1]);
742  av_freep(&s->buffers[i].planes[2]);
743  }
744 }
745 
746 static const AVFilterPad pullup_inputs[] = {
747  {
748  .name = "default",
749  .type = AVMEDIA_TYPE_VIDEO,
750  .filter_frame = filter_frame,
751  .config_props = config_input,
752  },
753 };
754 
755 static const AVFilterPad pullup_outputs[] = {
756  {
757  .name = "default",
758  .type = AVMEDIA_TYPE_VIDEO,
759  },
760 };
761 
763  .name = "pullup",
764  .description = NULL_IF_CONFIG_SMALL("Pullup from field sequence to frames."),
765  .priv_size = sizeof(PullupContext),
766  .priv_class = &pullup_class,
767  .uninit = uninit,
771 };
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:98
func
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:68
stride
int stride
Definition: mace.c:144
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:464
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1017
ff_vf_pullup
const AVFilter ff_vf_pullup
Definition: vf_pullup.c:762
pullup_get_buffer
static PullupBuffer * pullup_get_buffer(PullupContext *s, int parity)
Definition: vf_pullup.c:259
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2540
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:180
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:112
mp
static double mp(int i, double w0, double r)
Definition: af_atilt.c:79
alloc_buffer
static int alloc_buffer(PullupContext *s, PullupBuffer *b)
Definition: vf_pullup.c:244
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
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:438
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
pullup_outputs
static const AVFilterPad pullup_outputs[]
Definition: vf_pullup.c:755
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:153
pullup_pack_frame
static void pullup_pack_frame(PullupContext *s, PullupFrame *fr)
Definition: vf_pullup.c:629
queue_length
static int queue_length(PullupField *begin, PullupField *end)
Definition: vf_pullup.c:296
video.h
var_c
static int var_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
Definition: vf_pullup.c:101
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:317
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
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:86
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2580
ABS
#define ABS(a)
Definition: vf_pullup.c:70
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_pullup.c:655
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:526
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:261
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
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:746
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:233
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:51
pullup_lock_buffer
static PullupBuffer * pullup_lock_buffer(PullupBuffer *b, int parity)
Definition: vf_pullup.c:220
ff_set_common_formats_from_list
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
Equivalent to ff_set_common_formats(ctx, ff_make_format_list(fmts))
Definition: formats.c:703
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:290
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
f
#define f(width, name)
Definition: cbs_vp9.c:255
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:152
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:557
decide_frame_length
static int decide_frame_length(PullupContext *s)
Definition: vf_pullup.c:408
PullupFrame::length
int length
Definition: vf_pullup.h:43
NULL
#define NULL
Definition: coverity.c:32
rv
int32_t rv
Definition: input.c:404
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:537
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
src
#define src
Definition: vp8dsp.c:255
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
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:274
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:581
internal.h
alloc_metrics
static int alloc_metrics(PullupContext *s, PullupField *f)
Definition: vf_pullup.c:114
compute_breaks
static void compute_breaks(PullupContext *s, PullupField *f0)
Definition: vf_pullup.c:323
AVFrame::interlaced_frame
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:433
PullupFrame::parity
int parity
Definition: vf_pullup.h:44
compute_affinity
static void compute_affinity(PullupContext *s, PullupField *f)
Definition: vf_pullup.c:364
i
int i
Definition: input.c:406
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:310
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:613
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:261
BREAK_RIGHT
#define BREAK_RIGHT
Definition: vf_pullup.c:35
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_pullup.c:55
len
int len
Definition: vorbis_enc_data.h:426
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_pullup.c:731
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
AVFilter
Filter definition.
Definition: avfilter.h:149
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:129
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:146
PullupBuffer::lock
int lock[2]
Definition: vf_pullup.h:25
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Equivalent of av_mallocz_array().
Definition: mem.c:269
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:224
avfilter.h
diff_c
static int diff_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s)
Definition: vf_pullup.c:72
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:346
desc
const char * desc
Definition: libsvtav1.c:79
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:136
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:153
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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, size in bytes of each picture line.
Definition: frame.h:334
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:28
pullup_release_frame
static void pullup_release_frame(PullupFrame *f)
Definition: vf_pullup.c:511
PullupField::breaks
int breaks
Definition: vf_pullup.h:33
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
AVFrame::repeat_pict
int repeat_pict
When decoding, this signals how much the picture must be delayed.
Definition: frame.h:428