FFmpeg: libavfilter/vf_pullup.c Source File

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/mem.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/pixdesc.h"
26 #include "avfilter.h"
27 #include "filters.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[] = {
56  AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P,
57  AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
58  AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV440P,
59  AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
60  AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
61  AV_PIX_FMT_YUVJ411P, AV_PIX_FMT_GRAY8,
62  AV_PIX_FMT_NONE
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 
109  static int alloc_metrics(PullupContext *s, PullupField *f)
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 
141  static PullupField *make_field_queue(PullupContext *s, int len)
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 
175  static int config_input(AVFilterLink *inlink)
176 {
177  AVFilterContext *ctx = inlink->dst;
178  PullupContext *s = ctx->priv;
179  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
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
211  ff_pullup_init_x86(s);
212 #endif
213  return 0;
214 }
215 
216  static PullupBuffer *pullup_lock_buffer(PullupBuffer *b, int parity)
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 
229  static void pullup_release_buffer(PullupBuffer *b, int parity)
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 
240  static int alloc_buffer(PullupContext *s, PullupBuffer *b)
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 
255  static PullupBuffer *pullup_get_buffer(PullupContext *s, int parity)
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 
306  static int find_first_break(PullupField *f, int max)
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 
319  static void compute_breaks(PullupContext *s, PullupField *f0)
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 
360  static void compute_affinity(PullupContext *s, PullupField *f)
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 
404  static int decide_frame_length(PullupContext *s)
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 
460  static PullupFrame *pullup_get_frame(PullupContext *s)
461 {
462  PullupFrame *fr = &s->frame;
463  int i, n = decide_frame_length(s);
464  int aff = s->first->next->affinity;
465 
466  av_assert1(n < FF_ARRAY_ELEMS(fr->ifields));
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 
507  static void pullup_release_frame(PullupFrame *f)
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 
553  static int check_field_queue(PullupContext *s)
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 
577  static void pullup_submit_field(PullupContext *s, PullupBuffer *b, int parity)
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 
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 
608  static void copy_field(PullupContext *s,
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 
624  static void pullup_pack_frame(PullupContext *s, PullupFrame *fr)
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 
650  static int filter_frame(AVFilterLink *inlink, AVFrame *in)
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);
664  pullup_release_frame(f);
665  goto end;
666  }
667 
668  av_image_copy2(b->planes, s->planewidth,
669  in->data, in->linesize,
670  inlink->format, inlink->w, inlink->h);
671 
672  p = (in->flags & AV_FRAME_FLAG_INTERLACED) ?
673  !(in->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) : 0;
674  pullup_submit_field(s, b, p );
675  pullup_submit_field(s, b, p^1);
676 
677  if (in->repeat_pict)
678  pullup_submit_field(s, b, p);
679 
680  pullup_release_buffer(b, 2);
681 
682  f = pullup_get_frame(s);
683  if (!f)
684  goto end;
685 
686  if (f->length < 2) {
687  pullup_release_frame(f);
688  f = pullup_get_frame(s);
689  if (!f)
690  goto end;
691  if (f->length < 2) {
692  pullup_release_frame(f);
693  if (!in->repeat_pict)
694  goto end;
695  f = pullup_get_frame(s);
696  if (!f)
697  goto end;
698  if (f->length < 2) {
699  pullup_release_frame(f);
700  goto end;
701  }
702  }
703  }
704 
705  /* If the frame isn't already exportable... */
706  if (!f->buffer)
707  pullup_pack_frame(s, f);
708 
709  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
710  if (!out) {
711  ret = AVERROR(ENOMEM);
712  goto end;
713  }
714  av_frame_copy_props(out, in);
715 
716  av_image_copy2(out->data, out->linesize,
717  f->buffer->planes, s->planewidth,
718  inlink->format, inlink->w, inlink->h);
719 
720  ret = ff_filter_frame(outlink, out);
721  pullup_release_frame(f);
722 end:
723  av_frame_free(&in);
724  return ret;
725 }
726 
727  static av_cold void uninit(AVFilterContext *ctx)
728 {
729  PullupContext *s = ctx->priv;
730  int i;
731 
732  free_field_queue(s->head);
733  s->last = NULL;
734 
735  for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) {
736  av_freep(&s->buffers[i].planes[0]);
737  av_freep(&s->buffers[i].planes[1]);
738  av_freep(&s->buffers[i].planes[2]);
739  }
740 }
741 
742  static const AVFilterPad pullup_inputs[] = {
743  {
744  .name = "default",
745  .type = AVMEDIA_TYPE_VIDEO,
746  .filter_frame = filter_frame,
747  .config_props = config_input,
748  },
749 };
750 
751  const FFFilter ff_vf_pullup = {
752  .p.name = "pullup",
753  .p.description = NULL_IF_CONFIG_SMALL("Pullup from field sequence to frames."),
754  .p.priv_class = &pullup_class,
755  .priv_size = sizeof(PullupContext),
756  .uninit = uninit,
757  FILTER_INPUTS(pullup_inputs),
758  FILTER_OUTPUTS(ff_video_default_filterpad),
759  FILTER_PIXFMTS_ARRAY(pix_fmts),
760 };
fb
#define fb(width, name)
Definition: cbs_av1.c:617
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:117
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:216
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
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: filters.h:243
out
FILE * out
Definition: movenc.c:55
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:1067
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:3447
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
ff_vf_pullup
const FFFilter ff_vf_pullup
Definition: vf_pullup.c:751
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:64
mp
static double mp(int i, double w0, double r)
Definition: af_atilt.c:60
alloc_buffer
static int alloc_buffer(PullupContext *s, PullupBuffer *b)
Definition: vf_pullup.c:240
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: filters.h:263
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:429
b
#define b
Definition: input.c:42
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:671
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:220
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: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:448
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
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:655
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:3487
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:522
ss
#define ss(width, name, subs,...)
Definition: cbs_vp9.c:202
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:39
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:210
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:106
pullup_inputs
static const AVFilterPad pullup_inputs[]
Definition: vf_pullup.c:742
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
FFFilter
Definition: filters.h:266
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
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:60
pullup_lock_buffer
static PullupBuffer * pullup_lock_buffer(PullupBuffer *b, int parity)
Definition: vf_pullup.c:216
filters.h
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
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:264
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:599
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: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:87
parity
mcdeint parity
Definition: vf_mcdeint.c:289
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:577
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
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:256
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:57
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: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:256
BREAK_RIGHT
#define BREAK_RIGHT
Definition: vf_pullup.c:35
len
int len
Definition: vorbis_enc_data.h:426
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_pullup.c:727
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:45
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:650
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
stride
#define stride
Definition: h264pred_template.c:536
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
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:67
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
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:274
desc
const char * desc
Definition: libsvtav1.c:79
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:270
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:34
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: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: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:472
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
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:585
src
#define src
Definition: vp8dsp.c:248

Generated on Sat Oct 18 2025 19:23:10 for FFmpeg by   doxygen 1.8.17

AltStyle によって変換されたページ (->オリジナル) /