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