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  return 0;
213 }
214 
216 {
217  if (!b)
218  return NULL;
219 
220  if ((parity + 1) & 1)
221  b->lock[0]++;
222  if ((parity + 1) & 2)
223  b->lock[1]++;
224 
225  return b;
226 }
227 
229 {
230  if (!b)
231  return;
232 
233  if ((parity + 1) & 1)
234  b->lock[0]--;
235  if ((parity + 1) & 2)
236  b->lock[1]--;
237 }
238 
240 {
241  int i;
242 
243  if (b->planes[0])
244  return 0;
245  for (i = 0; i < s->nb_planes; i++) {
246  b->planes[i] = av_malloc(s->planeheight[i] * s->planewidth[i]);
247  }
248  if (s->nb_planes == 1)
249  b->planes[1] = av_malloc(4*256);
250 
251  return 0;
252 }
253 
255 {
256  int i;
257 
258  /* Try first to get the sister buffer for the previous field */
259  if (parity < 2 && s->last && parity != s->last->parity
260  && !s->last->buffer->lock[parity]) {
261  alloc_buffer(s, s->last->buffer);
262  return pullup_lock_buffer(s->last->buffer, parity);
263  }
264 
265  /* Prefer a buffer with both fields open */
266  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
267  if (s->buffers[i].lock[0])
268  continue;
269  if (s->buffers[i].lock[1])
270  continue;
271  alloc_buffer(s, &s->buffers[i]);
272  return pullup_lock_buffer(&s->buffers[i], parity);
273  }
274 
275  if (parity == 2)
276  return 0;
277 
278  /* Search for any half-free buffer */
279  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
280  if (((parity + 1) & 1) && s->buffers[i].lock[0])
281  continue;
282  if (((parity + 1) & 2) && s->buffers[i].lock[1])
283  continue;
284  alloc_buffer(s, &s->buffers[i]);
285  return pullup_lock_buffer(&s->buffers[i], parity);
286  }
287 
288  return NULL;
289 }
290 
291 static int queue_length(PullupField *begin, PullupField *end)
292 {
293  PullupField *f;
294  int count = 1;
295 
296  if (!begin || !end)
297  return 0;
298 
299  for (f = begin; f != end; f = f->next)
300  count++;
301 
302  return count;
303 }
304 
306 {
307  int i;
308 
309  for (i = 0; i < max; i++) {
310  if (f->breaks & BREAK_RIGHT || f->next->breaks & BREAK_LEFT)
311  return i + 1;
312  f = f->next;
313  }
314 
315  return 0;
316 }
317 
319 {
320  PullupField *f1 = f0->next;
321  PullupField *f2 = f1->next;
322  PullupField *f3 = f2->next;
323  int i, l, max_l = 0, max_r = 0;
324 
325  if (f0->flags & F_HAVE_BREAKS)
326  return;
327 
328  f0->flags |= F_HAVE_BREAKS;
329 
330  /* Special case when fields are 100% identical */
331  if (f0->buffer == f2->buffer && f1->buffer != f3->buffer) {
332  f2->breaks |= BREAK_RIGHT;
333  return;
334  }
335 
336  if (f0->buffer != f2->buffer && f1->buffer == f3->buffer) {
337  f1->breaks |= BREAK_LEFT;
338  return;
339  }
340 
341  for (i = 0; i < s->metric_length; i++) {
342  l = f2->diffs[i] - f3->diffs[i];
343 
344  if ( l > max_l)
345  max_l = l;
346  if (-l > max_r)
347  max_r = -l;
348  }
349 
350  /* Don't get tripped up when differences are mostly quant error */
351  if (max_l + max_r < 128)
352  return;
353  if (max_l > 4 * max_r)
354  f1->breaks |= BREAK_LEFT;
355  if (max_r > 4 * max_l)
356  f2->breaks |= BREAK_RIGHT;
357 }
358 
360 {
361  int i, max_l = 0, max_r = 0, l;
362 
363  if (f->flags & F_HAVE_AFFINITY)
364  return;
365 
366  f->flags |= F_HAVE_AFFINITY;
367 
368  if (f->buffer == f->next->next->buffer) {
369  f->affinity = 1;
370  f->next->affinity = 0;
371  f->next->next->affinity = -1;
372  f->next->flags |= F_HAVE_AFFINITY;
373  f->next->next->flags |= F_HAVE_AFFINITY;
374  return;
375  }
376 
377  for (i = 0; i < s->metric_length; i++) {
378  int v = f->vars[i];
379  int lv = f->prev->vars[i];
380  int rv = f->next->vars[i];
381  int lc = f-> combs[i] - 2*(v < lv ? v : lv);
382  int rc = f->next->combs[i] - 2*(v < rv ? v : rv);
383 
384  lc = FFMAX(lc, 0);
385  rc = FFMAX(rc, 0);
386  l = lc - rc;
387 
388  if ( l > max_l)
389  max_l = l;
390  if (-l > max_r)
391  max_r = -l;
392  }
393 
394  if (max_l + max_r < 64)
395  return;
396 
397  if (max_r > 6 * max_l)
398  f->affinity = -1;
399  else if (max_l > 6 * max_r)
400  f->affinity = 1;
401 }
402 
404 {
405  PullupField *f0 = s->first;
406  PullupField *f1 = f0->next;
407  PullupField *f2 = f1->next;
408  PullupField *f;
409  int i, l, n;
410 
411  if (queue_length(s->first, s->last) < 4)
412  return 0;
413 
414  f = s->first;
415  n = queue_length(f, s->last);
416  for (i = 0; i < n - 1; i++) {
417  if (i < n - 3)
418  compute_breaks(s, f);
419 
420  compute_affinity(s, f);
421 
422  f = f->next;
423  }
424 
425  if (f0->affinity == -1)
426  return 1;
427 
428  l = find_first_break(f0, 3);
429 
430  if (l == 1 && s->strict_breaks < 0)
431  l = 0;
432 
433  switch (l) {
434  case 1:
435  return 1 + (s->strict_breaks < 1 && f0->affinity == 1 && f1->affinity == -1);
436  case 2:
437  /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
438  if (s->strict_pairs
439  && (f0->prev->breaks & BREAK_RIGHT) && (f2->breaks & BREAK_LEFT)
440  && (f0->affinity != 1 || f1->affinity != -1) )
441  return 1;
442  return 1 + (f1->affinity != 1);
443  case 3:
444  return 2 + (f2->affinity != 1);
445  default:
446  /* 9 possibilities covered before switch */
447  if (f1->affinity == 1)
448  return 1; /* covers 6 */
449  else if (f1->affinity == -1)
450  return 2; /* covers 6 */
451  else if (f2->affinity == -1) { /* covers 2 */
452  return (f0->affinity == 1) ? 3 : 1;
453  } else {
454  return 2; /* the remaining 6 */
455  }
456  }
457 }
458 
460 {
461  PullupFrame *fr = &s->frame;
462  int i, n = decide_frame_length(s);
463  int aff = s->first->next->affinity;
464 
466  if (!n || fr->lock)
467  return NULL;
468 
469  fr->lock++;
470  fr->length = n;
471  fr->parity = s->first->parity;
472  fr->buffer = 0;
473 
474  for (i = 0; i < n; i++) {
475  /* We cheat and steal the buffer without release+relock */
476  fr->ifields[i] = s->first->buffer;
477  s->first->buffer = 0;
478  s->first = s->first->next;
479  }
480 
481  if (n == 1) {
482  fr->ofields[fr->parity ] = fr->ifields[0];
483  fr->ofields[fr->parity ^ 1] = 0;
484  } else if (n == 2) {
485  fr->ofields[fr->parity ] = fr->ifields[0];
486  fr->ofields[fr->parity ^ 1] = fr->ifields[1];
487  } else if (n == 3) {
488  if (!aff)
489  aff = (fr->ifields[0] == fr->ifields[1]) ? -1 : 1;
490  fr->ofields[fr->parity ] = fr->ifields[1 + aff];
491  fr->ofields[fr->parity ^ 1] = fr->ifields[1 ];
492  }
493 
494  pullup_lock_buffer(fr->ofields[0], 0);
495  pullup_lock_buffer(fr->ofields[1], 1);
496 
497  if (fr->ofields[0] == fr->ofields[1]) {
498  fr->buffer = fr->ofields[0];
499  pullup_lock_buffer(fr->buffer, 2);
500  return fr;
501  }
502 
503  return fr;
504 }
505 
507 {
508  int i;
509 
510  for (i = 0; i < f->length; i++)
511  pullup_release_buffer(f->ifields[i], f->parity ^ (i & 1));
512 
513  pullup_release_buffer(f->ofields[0], 0);
514  pullup_release_buffer(f->ofields[1], 1);
515 
516  if (f->buffer)
517  pullup_release_buffer(f->buffer, 2);
518  f->lock--;
519 }
520 
521 static void compute_metric(PullupContext *s, int *dest,
522  PullupField *fa, int pa, PullupField *fb, int pb,
523  int (*func)(const uint8_t *, const uint8_t *, ptrdiff_t))
524 {
525  int mp = s->metric_plane;
526  int xstep = 8;
527  int ystep = s->planewidth[mp] << 3;
528  int stride = s->planewidth[mp] << 1; /* field stride */
529  int w = s->metric_w * xstep;
530  uint8_t *a, *b;
531  int x, y;
532 
533  if (!fa->buffer || !fb->buffer)
534  return;
535 
536  /* Shortcut for duplicate fields (e.g. from RFF flag) */
537  if (fa->buffer == fb->buffer && pa == pb) {
538  memset(dest, 0, s->metric_length * sizeof(*dest));
539  return;
540  }
541 
542  a = fa->buffer->planes[mp] + pa * s->planewidth[mp] + s->metric_offset;
543  b = fb->buffer->planes[mp] + pb * s->planewidth[mp] + s->metric_offset;
544 
545  for (y = 0; y < s->metric_h; y++) {
546  for (x = 0; x < w; x += xstep)
547  *dest++ = func(a + x, b + x, stride);
548  a += ystep; b += ystep;
549  }
550 }
551 
553 {
554  int ret;
555 
556  if (s->head->next == s->first) {
557  PullupField *f = av_mallocz(sizeof(*f));
558 
559  if (!f)
560  return AVERROR(ENOMEM);
561 
562  if ((ret = alloc_metrics(s, f)) < 0) {
563  av_free(f);
564  return ret;
565  }
566 
567  f->prev = s->head;
568  f->next = s->first;
569  s->head->next = f;
570  s->first->prev = f;
571  }
572 
573  return 0;
574 }
575 
577 {
578  PullupField *f;
579 
580  /* Grow the circular list if needed */
581  if (check_field_queue(s) < 0)
582  return;
583 
584  /* Cannot have two fields of same parity in a row; drop the new one */
585  if (s->last && s->last->parity == parity)
586  return;
587 
588  f = s->head;
589  f->parity = parity;
590  f->buffer = pullup_lock_buffer(b, parity);
591  f->flags = 0;
592  f->breaks = 0;
593  f->affinity = 0;
594 
595  compute_metric(s, f->diffs, f, parity, f->prev->prev, parity, s->diff);
596  compute_metric(s, f->combs, parity ? f->prev : f, 0, parity ? f : f->prev, 1, s->comb);
597  compute_metric(s, f->vars, f, parity, f, -1, s->var);
598  emms_c();
599 
600  /* Advance the circular list */
601  if (!s->first)
602  s->first = s->head;
603 
604  s->last = s->head;
605  s->head = s->head->next;
606 }
607 
609  PullupBuffer *dst, PullupBuffer *src, int parity)
610 {
611  uint8_t *dd, *ss;
612  int i;
613 
614  for (i = 0; i < s->nb_planes; i++) {
615  ss = src->planes[i] + parity * s->planewidth[i];
616  dd = dst->planes[i] + parity * s->planewidth[i];
617 
618  av_image_copy_plane(dd, s->planewidth[i] << 1,
619  ss, s->planewidth[i] << 1,
620  s->planewidth[i], s->planeheight[i] >> 1);
621  }
622 }
623 
625 {
626  int i;
627 
628  if (fr->buffer)
629  return;
630 
631  if (fr->length < 2)
632  return; /* FIXME: deal with this */
633 
634  for (i = 0; i < 2; i++) {
635  if (fr->ofields[i]->lock[i^1])
636  continue;
637 
638  fr->buffer = fr->ofields[i];
639  pullup_lock_buffer(fr->buffer, 2);
640  copy_field(s, fr->buffer, fr->ofields[i^1], i^1);
641  return;
642  }
643 
644  fr->buffer = pullup_get_buffer(s, 2);
645 
646  copy_field(s, fr->buffer, fr->ofields[0], 0);
647  copy_field(s, fr->buffer, fr->ofields[1], 1);
648 }
649 
651 {
652  AVFilterContext *ctx = inlink->dst;
653  AVFilterLink *outlink = ctx->outputs[0];
654  PullupContext *s = ctx->priv;
655  PullupBuffer *b;
656  PullupFrame *f;
657  AVFrame *out;
658  int p, ret = 0;
659 
660  b = pullup_get_buffer(s, 2);
661  if (!b) {
662  av_log(ctx, AV_LOG_WARNING, "Could not get buffer!\n");
663  f = pullup_get_frame(s);
665  goto end;
666  }
667 
668  av_image_copy(b->planes, s->planewidth,
669  (const uint8_t**)in->data, in->linesize,
670  inlink->format, inlink->w, inlink->h);
671 
672  p = in->interlaced_frame ? !in->top_field_first : 0;
673  pullup_submit_field(s, b, p );
674  pullup_submit_field(s, b, p^1);
675 
676  if (in->repeat_pict)
677  pullup_submit_field(s, b, p);
678 
680 
681  f = pullup_get_frame(s);
682  if (!f)
683  goto end;
684 
685  if (f->length < 2) {
687  f = pullup_get_frame(s);
688  if (!f)
689  goto end;
690  if (f->length < 2) {
692  if (!in->repeat_pict)
693  goto end;
694  f = pullup_get_frame(s);
695  if (!f)
696  goto end;
697  if (f->length < 2) {
699  goto end;
700  }
701  }
702  }
703 
704  /* If the frame isn't already exportable... */
705  if (!f->buffer)
707 
708  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
709  if (!out) {
710  ret = AVERROR(ENOMEM);
711  goto end;
712  }
714 
715  av_image_copy(out->data, out->linesize,
716  (const uint8_t**)f->buffer->planes, s->planewidth,
717  inlink->format, inlink->w, inlink->h);
718 
719  ret = ff_filter_frame(outlink, out);
721 end:
722  av_frame_free(&in);
723  return ret;
724 }
725 
727 {
728  PullupContext *s = ctx->priv;
729  int i;
730 
731  free_field_queue(s->head);
732  s->last = NULL;
733 
734  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
735  av_freep(&s->buffers[i].planes[0]);
736  av_freep(&s->buffers[i].planes[1]);
737  av_freep(&s->buffers[i].planes[2]);
738  }
739 }
740 
741 static const AVFilterPad pullup_inputs[] = {
742  {
743  .name = "default",
744  .type = AVMEDIA_TYPE_VIDEO,
745  .filter_frame = filter_frame,
746  .config_props = config_input,
747  },
748 };
749 
750 static const AVFilterPad pullup_outputs[] = {
751  {
752  .name = "default",
753  .type = AVMEDIA_TYPE_VIDEO,
754  },
755 };
756 
758  .name = "pullup",
759  .description = NULL_IF_CONFIG_SMALL("Pullup from field sequence to frames."),
760  .priv_size = sizeof(PullupContext),
761  .priv_class = &pullup_class,
762  .uninit = uninit,
766 };
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:459
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1018
ff_vf_pullup
const AVFilter ff_vf_pullup
Definition: vf_pullup.c:757
pullup_get_buffer
static PullupBuffer * pullup_get_buffer(PullupContext *s, int parity)
Definition: vf_pullup.c:254
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2660
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:171
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:109
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:239
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
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:474
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
pullup_outputs
static const AVFilterPad pullup_outputs[]
Definition: vf_pullup.c:750
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:169
pullup_pack_frame
static void pullup_pack_frame(PullupContext *s, PullupFrame *fr)
Definition: vf_pullup.c:624
queue_length
static int queue_length(PullupField *begin, PullupField *end)
Definition: vf_pullup.c:291
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:338
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:81
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2700
ABS
#define ABS(a)
Definition: vf_pullup.c:65
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_pullup.c:650
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:521
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:741
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:228
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:215
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:191
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:552
decide_frame_length
static int decide_frame_length(PullupContext *s)
Definition: vf_pullup.c:403
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: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
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_pullup.c:55
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:576
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:318
AVFrame::interlaced_frame
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:469
PullupFrame::parity
int parity
Definition: vf_pullup.h:44
compute_affinity
static void compute_affinity(PullupContext *s, PullupField *f)
Definition: vf_pullup.c:359
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
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:305
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:608
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:263
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:726
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:56
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:271
AVFilter
Filter definition.
Definition: avfilter.h:165
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:224
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:402
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:139
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:192
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, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:362
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:506
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:464