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/emms.h"
23 #include "libavutil/imgutils.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/pixdesc.h"
26 #include "avfilter.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, .unit = "mp" },
47  { "y", "luma", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "mp" },
48  { "u", "chroma blue", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "mp" },
49  { "v", "chroma red", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, .unit = "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_copy2(b->planes, s->planewidth,
670  in->data, in->linesize,
671  inlink->format, inlink->w, inlink->h);
672 
673  p = (in->flags & AV_FRAME_FLAG_INTERLACED) ?
675  pullup_submit_field(s, b, p );
676  pullup_submit_field(s, b, p^1);
677 
678  if (in->repeat_pict)
679  pullup_submit_field(s, b, p);
680 
682 
683  f = pullup_get_frame(s);
684  if (!f)
685  goto end;
686 
687  if (f->length < 2) {
689  f = pullup_get_frame(s);
690  if (!f)
691  goto end;
692  if (f->length < 2) {
694  if (!in->repeat_pict)
695  goto end;
696  f = pullup_get_frame(s);
697  if (!f)
698  goto end;
699  if (f->length < 2) {
701  goto end;
702  }
703  }
704  }
705 
706  /* If the frame isn't already exportable... */
707  if (!f->buffer)
709 
710  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
711  if (!out) {
712  ret = AVERROR(ENOMEM);
713  goto end;
714  }
716 
717  av_image_copy2(out->data, out->linesize,
718  f->buffer->planes, s->planewidth,
719  inlink->format, inlink->w, inlink->h);
720 
721  ret = ff_filter_frame(outlink, out);
723 end:
724  av_frame_free(&in);
725  return ret;
726 }
727 
729 {
730  PullupContext *s = ctx->priv;
731  int i;
732 
733  free_field_queue(s->head);
734  s->last = NULL;
735 
736  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
737  av_freep(&s->buffers[i].planes[0]);
738  av_freep(&s->buffers[i].planes[1]);
739  av_freep(&s->buffers[i].planes[2]);
740  }
741 }
742 
743 static const AVFilterPad pullup_inputs[] = {
744  {
745  .name = "default",
746  .type = AVMEDIA_TYPE_VIDEO,
747  .filter_frame = filter_frame,
748  .config_props = config_input,
749  },
750 };
751 
753  .name = "pullup",
754  .description = NULL_IF_CONFIG_SMALL("Pullup from field sequence to frames."),
755  .priv_size = sizeof(PullupContext),
756  .priv_class = &pullup_class,
757  .uninit = uninit,
761 };
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:112
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:71
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:1007
ff_vf_pullup
const AVFilter ff_vf_pullup
Definition: vf_pullup.c:752
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:2968
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:162
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:100
mp
static double mp(int i, double w0, double r)
Definition: af_atilt.c:59
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:340
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:294
b
#define b
Definition: input.c:41
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:106
vf_pullup.h
max
#define max(a, b)
Definition: cuda_runtime.h:33
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:649
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
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:361
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
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:641
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:3008
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:202
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
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:283
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:743
ff_video_default_filterpad
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition: video.c:37
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:86
emms_c
#define emms_c()
Definition: emms.h:63
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:198
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
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:73
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
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:87
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:736
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:85
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:81
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:121
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:106
parity
mcdeint parity
Definition: vf_mcdeint.c:281
PullupField::buffer
PullupBuffer * buffer
Definition: vf_pullup.h:31
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:164
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
emms.h
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:255
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
fb
#define fb(width, name)
Definition: cbs_av1.c:585
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:107
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:254
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:728
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:636
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
stride
#define stride
Definition: h264pred_template.c:537
AVFilter
Filter definition.
Definition: avfilter.h:166
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
PullupField::prev
struct PullupField * prev
Definition: vf_pullup.h:38
av_image_copy2
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition: imgutils.h:184
PullupBuffer
Definition: vf_pullup.h:24
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
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:78
AVFilterContext
An instance of a filter.
Definition: avfilter.h:409
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:77
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
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:183
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:80
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:385
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:79
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
Number of fields in this frame which should be repeated, i.e.
Definition: frame.h:521