pullup.c
Go to the documentation of this file.
1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include "libavutil/x86/asm.h"
24 #include "config.h"
25 #include "pullup.h"
26 
27 
28 
29 #if ARCH_X86
30 #if HAVE_MMX
31 static int diff_y_mmx(unsigned char *a, unsigned char *b, int s)
32 {
33  int ret;
34  __asm__ volatile (
35  "movl $4, %%ecx \n\t"
36  "pxor %%mm4, %%mm4 \n\t"
37  "pxor %%mm7, %%mm7 \n\t"
38 
39  "1: \n\t"
40 
41  "movq (%%"REG_S"), %%mm0 \n\t"
42  "movq (%%"REG_S"), %%mm2 \n\t"
43  "add %%"REG_a", %%"REG_S" \n\t"
44  "movq (%%"REG_D"), %%mm1 \n\t"
45  "add %%"REG_a", %%"REG_D" \n\t"
46  "psubusb %%mm1, %%mm2 \n\t"
47  "psubusb %%mm0, %%mm1 \n\t"
48  "movq %%mm2, %%mm0 \n\t"
49  "movq %%mm1, %%mm3 \n\t"
50  "punpcklbw %%mm7, %%mm0 \n\t"
51  "punpcklbw %%mm7, %%mm1 \n\t"
52  "punpckhbw %%mm7, %%mm2 \n\t"
53  "punpckhbw %%mm7, %%mm3 \n\t"
54  "paddw %%mm0, %%mm4 \n\t"
55  "paddw %%mm1, %%mm4 \n\t"
56  "paddw %%mm2, %%mm4 \n\t"
57  "paddw %%mm3, %%mm4 \n\t"
58 
59  "decl %%ecx \n\t"
60  "jnz 1b \n\t"
61 
62  "movq %%mm4, %%mm3 \n\t"
63  "punpcklwd %%mm7, %%mm4 \n\t"
64  "punpckhwd %%mm7, %%mm3 \n\t"
65  "paddd %%mm4, %%mm3 \n\t"
66  "movd %%mm3, %%eax \n\t"
67  "psrlq $32, %%mm3 \n\t"
68  "movd %%mm3, %%edx \n\t"
69  "addl %%edx, %%eax \n\t"
70  "emms \n\t"
71  : "=a" (ret)
72  : "S" (a), "D" (b), "a" (s)
73  : "%ecx", "%edx"
74  );
75  return ret;
76 }
77 
78 static int licomb_y_mmx(unsigned char *a, unsigned char *b, int s)
79 {
80  int ret;
81  __asm__ volatile (
82  "movl $4, %%ecx \n\t"
83  "pxor %%mm6, %%mm6 \n\t"
84  "pxor %%mm7, %%mm7 \n\t"
85  "sub %%"REG_a", %%"REG_D" \n\t"
86 
87  "2: \n\t"
88 
89  "movq (%%"REG_D"), %%mm0 \n\t"
90  "movq (%%"REG_D"), %%mm1 \n\t"
91  "punpcklbw %%mm7, %%mm0 \n\t"
92  "movq (%%"REG_D",%%"REG_a"), %%mm2 \n\t"
93  "punpcklbw %%mm7, %%mm1 \n\t"
94  "punpcklbw %%mm7, %%mm2 \n\t"
95  "paddw %%mm0, %%mm0 \n\t"
96  "paddw %%mm2, %%mm1 \n\t"
97  "movq %%mm0, %%mm2 \n\t"
98  "psubusw %%mm1, %%mm0 \n\t"
99  "psubusw %%mm2, %%mm1 \n\t"
100  "paddw %%mm0, %%mm6 \n\t"
101  "paddw %%mm1, %%mm6 \n\t"
102 
103  "movq (%%"REG_S"), %%mm0 \n\t"
104  "movq (%%"REG_D"), %%mm1 \n\t"
105  "punpckhbw %%mm7, %%mm0 \n\t"
106  "movq (%%"REG_D",%%"REG_a"), %%mm2 \n\t"
107  "punpckhbw %%mm7, %%mm1 \n\t"
108  "punpckhbw %%mm7, %%mm2 \n\t"
109  "paddw %%mm0, %%mm0 \n\t"
110  "paddw %%mm2, %%mm1 \n\t"
111  "movq %%mm0, %%mm2 \n\t"
112  "psubusw %%mm1, %%mm0 \n\t"
113  "psubusw %%mm2, %%mm1 \n\t"
114  "paddw %%mm0, %%mm6 \n\t"
115  "paddw %%mm1, %%mm6 \n\t"
116 
117  "movq (%%"REG_D",%%"REG_a"), %%mm0 \n\t"
118  "movq (%%"REG_S"), %%mm1 \n\t"
119  "punpcklbw %%mm7, %%mm0 \n\t"
120  "movq (%%"REG_S",%%"REG_a"), %%mm2 \n\t"
121  "punpcklbw %%mm7, %%mm1 \n\t"
122  "punpcklbw %%mm7, %%mm2 \n\t"
123  "paddw %%mm0, %%mm0 \n\t"
124  "paddw %%mm2, %%mm1 \n\t"
125  "movq %%mm0, %%mm2 \n\t"
126  "psubusw %%mm1, %%mm0 \n\t"
127  "psubusw %%mm2, %%mm1 \n\t"
128  "paddw %%mm0, %%mm6 \n\t"
129  "paddw %%mm1, %%mm6 \n\t"
130 
131  "movq (%%"REG_D",%%"REG_a"), %%mm0 \n\t"
132  "movq (%%"REG_S"), %%mm1 \n\t"
133  "punpckhbw %%mm7, %%mm0 \n\t"
134  "movq (%%"REG_S",%%"REG_a"), %%mm2 \n\t"
135  "punpckhbw %%mm7, %%mm1 \n\t"
136  "punpckhbw %%mm7, %%mm2 \n\t"
137  "paddw %%mm0, %%mm0 \n\t"
138  "paddw %%mm2, %%mm1 \n\t"
139  "movq %%mm0, %%mm2 \n\t"
140  "psubusw %%mm1, %%mm0 \n\t"
141  "psubusw %%mm2, %%mm1 \n\t"
142  "paddw %%mm0, %%mm6 \n\t"
143  "paddw %%mm1, %%mm6 \n\t"
144 
145  "add %%"REG_a", %%"REG_S" \n\t"
146  "add %%"REG_a", %%"REG_D" \n\t"
147  "decl %%ecx \n\t"
148  "jnz 2b \n\t"
149 
150  "movq %%mm6, %%mm5 \n\t"
151  "punpcklwd %%mm7, %%mm6 \n\t"
152  "punpckhwd %%mm7, %%mm5 \n\t"
153  "paddd %%mm6, %%mm5 \n\t"
154  "movd %%mm5, %%eax \n\t"
155  "psrlq $32, %%mm5 \n\t"
156  "movd %%mm5, %%edx \n\t"
157  "addl %%edx, %%eax \n\t"
158 
159  "emms \n\t"
160  : "=a" (ret)
161  : "S" (a), "D" (b), "a" (s)
162  : "%ecx", "%edx"
163  );
164  return ret;
165 }
166 
167 static int var_y_mmx(unsigned char *a, unsigned char *b, int s)
168 {
169  int ret;
170  __asm__ volatile (
171  "movl $3, %%ecx \n\t"
172  "pxor %%mm4, %%mm4 \n\t"
173  "pxor %%mm7, %%mm7 \n\t"
174 
175  "1: \n\t"
176 
177  "movq (%%"REG_S"), %%mm0 \n\t"
178  "movq (%%"REG_S"), %%mm2 \n\t"
179  "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t"
180  "add %%"REG_a", %%"REG_S" \n\t"
181  "psubusb %%mm1, %%mm2 \n\t"
182  "psubusb %%mm0, %%mm1 \n\t"
183  "movq %%mm2, %%mm0 \n\t"
184  "movq %%mm1, %%mm3 \n\t"
185  "punpcklbw %%mm7, %%mm0 \n\t"
186  "punpcklbw %%mm7, %%mm1 \n\t"
187  "punpckhbw %%mm7, %%mm2 \n\t"
188  "punpckhbw %%mm7, %%mm3 \n\t"
189  "paddw %%mm0, %%mm4 \n\t"
190  "paddw %%mm1, %%mm4 \n\t"
191  "paddw %%mm2, %%mm4 \n\t"
192  "paddw %%mm3, %%mm4 \n\t"
193 
194  "decl %%ecx \n\t"
195  "jnz 1b \n\t"
196 
197  "movq %%mm4, %%mm3 \n\t"
198  "punpcklwd %%mm7, %%mm4 \n\t"
199  "punpckhwd %%mm7, %%mm3 \n\t"
200  "paddd %%mm4, %%mm3 \n\t"
201  "movd %%mm3, %%eax \n\t"
202  "psrlq $32, %%mm3 \n\t"
203  "movd %%mm3, %%edx \n\t"
204  "addl %%edx, %%eax \n\t"
205  "emms \n\t"
206  : "=a" (ret)
207  : "S" (a), "a" (s)
208  : "%ecx", "%edx"
209  );
210  return 4*ret;
211 }
212 #endif
213 #endif
214 
215 #define ABS(a) (((a)^((a)>>31))-((a)>>31))
216 
217 static int diff_y(unsigned char *a, unsigned char *b, int s)
218 {
219  int i, j, diff=0;
220  for (i=4; i; i--) {
221  for (j=0; j<8; j++) diff += ABS(a[j]-b[j]);
222  a+=s; b+=s;
223  }
224  return diff;
225 }
226 
227 static int licomb_y(unsigned char *a, unsigned char *b, int s)
228 {
229  int i, j, diff=0;
230  for (i=4; i; i--) {
231  for (j=0; j<8; j++)
232  diff += ABS((a[j]<<1) - b[j-s] - b[j])
233  + ABS((b[j]<<1) - a[j] - a[j+s]);
234  a+=s; b+=s;
235  }
236  return diff;
237 }
238 
239 #if 0
240 static int qpcomb_y(unsigned char *a, unsigned char *b, int s)
241 {
242  int i, j, diff=0;
243  for (i=4; i; i--) {
244  for (j=0; j<8; j++)
245  diff += ABS(a[j] - 3*b[j-s] + 3*a[j+s] - b[j]);
246  a+=s; b+=s;
247  }
248  return diff;
249 }
250 
251 static int licomb_y_test(unsigned char *a, unsigned char *b, int s)
252 {
253  int c = licomb_y(a,b,s);
254  int m = licomb_y_mmx(a,b,s);
255  if (c != m) printf("%d != %d\n", c, m);
256  return m;
257 }
258 #endif
259 
260 static int var_y(unsigned char *a, unsigned char *b, int s)
261 {
262  int i, j, var=0;
263  for (i=3; i; i--) {
264  for (j=0; j<8; j++) {
265  var += ABS(a[j]-a[j+s]);
266  }
267  a+=s; b+=s;
268  }
269  return 4*var; /* match comb scaling */
270 }
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 static void alloc_buffer(struct pullup_context *c, struct pullup_buffer *b)
281 {
282  int i;
283  if (b->planes) return;
284  b->planes = calloc(c->nplanes, sizeof(unsigned char *));
285  for (i = 0; i < c->nplanes; i++) {
286  b->planes[i] = malloc(c->h[i]*c->stride[i]);
287  /* Deal with idiotic 128=0 for chroma: */
288  memset(b->planes[i], c->background[i], c->h[i]*c->stride[i]);
289  }
290 }
291 
293 {
294  if (!b) return 0;
295  if ((parity+1) & 1) b->lock[0]++;
296  if ((parity+1) & 2) b->lock[1]++;
297  return b;
298 }
299 
301 {
302  if (!b) return;
303  if ((parity+1) & 1) b->lock[0]--;
304  if ((parity+1) & 2) b->lock[1]--;
305 }
306 
308 {
309  int i;
310 
311  /* Try first to get the sister buffer for the previous field */
312  if (parity < 2 && c->last && parity != c->last->parity
313  && !c->last->buffer->lock[parity]) {
314  alloc_buffer(c, c->last->buffer);
315  return ff_pullup_lock_buffer(c->last->buffer, parity);
316  }
317 
318  /* Prefer a buffer with both fields open */
319  for (i = 0; i < c->nbuffers; i++) {
320  if (c->buffers[i].lock[0]) continue;
321  if (c->buffers[i].lock[1]) continue;
322  alloc_buffer(c, &c->buffers[i]);
323  return ff_pullup_lock_buffer(&c->buffers[i], parity);
324  }
325 
326  if (parity == 2) return 0;
327 
328  /* Search for any half-free buffer */
329  for (i = 0; i < c->nbuffers; i++) {
330  if (((parity+1) & 1) && c->buffers[i].lock[0]) continue;
331  if (((parity+1) & 2) && c->buffers[i].lock[1]) continue;
332  alloc_buffer(c, &c->buffers[i]);
333  return ff_pullup_lock_buffer(&c->buffers[i], parity);
334  }
335 
336  return 0;
337 }
338 
339 
340 
341 
342 
343 
344 static void compute_metric(struct pullup_context *c,
345  struct pullup_field *fa, int pa,
346  struct pullup_field *fb, int pb,
347  int (*func)(unsigned char *, unsigned char *, int), int *dest)
348 {
349  unsigned char *a, *b;
350  int x, y;
351  int mp = c->metric_plane;
352  int xstep = c->bpp[mp];
353  int ystep = c->stride[mp]<<3;
354  int s = c->stride[mp]<<1; /* field stride */
355  int w = c->metric_w*xstep;
356 
357  if (!fa->buffer || !fb->buffer) return;
358 
359  /* Shortcut for duplicate fields (e.g. from RFF flag) */
360  if (fa->buffer == fb->buffer && pa == pb) {
361  memset(dest, 0, c->metric_len * sizeof(int));
362  return;
363  }
364 
365  a = fa->buffer->planes[mp] + pa * c->stride[mp] + c->metric_offset;
366  b = fb->buffer->planes[mp] + pb * c->stride[mp] + c->metric_offset;
367 
368  for (y = c->metric_h; y; y--) {
369  for (x = 0; x < w; x += xstep) {
370  *dest++ = func(a + x, b + x, s);
371  }
372  a += ystep; b += ystep;
373  }
374 }
375 
376 
377 
378 
379 
380 static void alloc_metrics(struct pullup_context *c, struct pullup_field *f)
381 {
382  f->diffs = calloc(c->metric_len, sizeof(int));
383  f->comb = calloc(c->metric_len, sizeof(int));
384  f->var = calloc(c->metric_len, sizeof(int));
385  /* add more metrics here as needed */
386 }
387 
388 static struct pullup_field *make_field_queue(struct pullup_context *c, int len)
389 {
390  struct pullup_field *head, *f;
391  f = head = calloc(1, sizeof(struct pullup_field));
392  alloc_metrics(c, f);
393  for (; len > 0; len--) {
394  f->next = calloc(1, sizeof(struct pullup_field));
395  f->next->prev = f;
396  f = f->next;
397  alloc_metrics(c, f);
398  }
399  f->next = head;
400  head->prev = f;
401  return head;
402 }
403 
404 static void check_field_queue(struct pullup_context *c)
405 {
406  if (c->head->next == c->first) {
407  struct pullup_field *f = calloc(1, sizeof(struct pullup_field));
408  alloc_metrics(c, f);
409  f->prev = c->head;
410  f->next = c->first;
411  c->head->next = f;
412  c->first->prev = f;
413  }
414 }
415 
417 {
418  struct pullup_field *f;
419 
420  /* Grow the circular list if needed */
422 
423  /* Cannot have two fields of same parity in a row; drop the new one */
424  if (c->last && c->last->parity == parity) return;
425 
426  f = c->head;
427  f->parity = parity;
428  f->buffer = ff_pullup_lock_buffer(b, parity);
429  f->flags = 0;
430  f->breaks = 0;
431  f->affinity = 0;
432 
433  compute_metric(c, f, parity, f->prev->prev, parity, c->diff, f->diffs);
434  compute_metric(c, parity?f->prev:f, 0, parity?f:f->prev, 1, c->comb, f->comb);
435  compute_metric(c, f, parity, f, -1, c->var, f->var);
436 
437  /* Advance the circular list */
438  if (!c->first) c->first = c->head;
439  c->last = c->head;
440  c->head = c->head->next;
441 }
442 
444 {
445  struct pullup_field *f;
446 
447  for (f = c->first; f && f != c->head; f = f->next) {
449  f->buffer = 0;
450  }
451  c->first = c->last = 0;
452 }
453 
454 
455 
456 
457 
458 
459 
460 
461 #define F_HAVE_BREAKS 1
462 #define F_HAVE_AFFINITY 2
463 
464 
465 #define BREAK_LEFT 1
466 #define BREAK_RIGHT 2
467 
468 
469 
470 
471 static int queue_length(struct pullup_field *begin, struct pullup_field *end)
472 {
473  int count = 1;
474  struct pullup_field *f;
475 
476  if (!begin || !end) return 0;
477  for (f = begin; f != end; f = f->next) count++;
478  return count;
479 }
480 
481 static int find_first_break(struct pullup_field *f, int max)
482 {
483  int i;
484  for (i = 0; i < max; i++) {
485  if (f->breaks & BREAK_RIGHT || f->next->breaks & BREAK_LEFT)
486  return i+1;
487  f = f->next;
488  }
489  return 0;
490 }
491 
492 static void compute_breaks(struct pullup_context *c, struct pullup_field *f0)
493 {
494  int i;
495  struct pullup_field *f1 = f0->next;
496  struct pullup_field *f2 = f1->next;
497  struct pullup_field *f3 = f2->next;
498  int l, max_l=0, max_r=0;
499  //struct pullup_field *ff;
500  //for (i=0, ff=c->first; ff != f0; i++, ff=ff->next);
501 
502  if (f0->flags & F_HAVE_BREAKS) return;
503  //printf("\n%d: ", i);
504  f0->flags |= F_HAVE_BREAKS;
505 
506  /* Special case when fields are 100% identical */
507  if (f0->buffer == f2->buffer && f1->buffer != f3->buffer) {
508  f2->breaks |= BREAK_RIGHT;
509  return;
510  }
511  if (f0->buffer != f2->buffer && f1->buffer == f3->buffer) {
512  f1->breaks |= BREAK_LEFT;
513  return;
514  }
515 
516  for (i = 0; i < c->metric_len; i++) {
517  l = f2->diffs[i] - f3->diffs[i];
518  if (l > max_l) max_l = l;
519  if (-l > max_r) max_r = -l;
520  }
521  /* Don't get tripped up when differences are mostly quant error */
522  //printf("%d %d\n", max_l, max_r);
523  if (max_l + max_r < 128) return;
524  if (max_l > 4*max_r) f1->breaks |= BREAK_LEFT;
525  if (max_r > 4*max_l) f2->breaks |= BREAK_RIGHT;
526 }
527 
528 static void compute_affinity(struct pullup_context *c, struct pullup_field *f)
529 {
530  int i;
531  int max_l=0, max_r=0, l;
532  if (f->flags & F_HAVE_AFFINITY) return;
533  f->flags |= F_HAVE_AFFINITY;
534  if (f->buffer == f->next->next->buffer) {
535  f->affinity = 1;
536  f->next->affinity = 0;
537  f->next->next->affinity = -1;
538  f->next->flags |= F_HAVE_AFFINITY;
539  f->next->next->flags |= F_HAVE_AFFINITY;
540  return;
541  }
542  if (1) {
543  for (i = 0; i < c->metric_len; i++) {
544  int lv = f->prev->var[i];
545  int rv = f->next->var[i];
546  int v = f->var[i];
547  int lc = f->comb[i] - (v+lv) + ABS(v-lv);
548  int rc = f->next->comb[i] - (v+rv) + ABS(v-rv);
549  lc = lc>0 ? lc : 0;
550  rc = rc>0 ? rc : 0;
551  l = lc - rc;
552  if (l > max_l) max_l = l;
553  if (-l > max_r) max_r = -l;
554  }
555  if (max_l + max_r < 64) return;
556  if (max_r > 6*max_l) f->affinity = -1;
557  else if (max_l > 6*max_r) f->affinity = 1;
558  } else {
559  for (i = 0; i < c->metric_len; i++) {
560  l = f->comb[i] - f->next->comb[i];
561  if (l > max_l) max_l = l;
562  if (-l > max_r) max_r = -l;
563  }
564  if (max_l + max_r < 64) return;
565  if (max_r > 2*max_l) f->affinity = -1;
566  else if (max_l > 2*max_r) f->affinity = 1;
567  }
568 }
569 
570 static void foo(struct pullup_context *c)
571 {
572  struct pullup_field *f = c->first;
573  int i, n = queue_length(f, c->last);
574  for (i = 0; i < n-1; i++) {
575  if (i < n-3) compute_breaks(c, f);
576  compute_affinity(c, f);
577  f = f->next;
578  }
579 }
580 
581 static int decide_frame_length(struct pullup_context *c)
582 {
583  struct pullup_field *f0 = c->first;
584  struct pullup_field *f1 = f0->next;
585  struct pullup_field *f2 = f1->next;
586  int l;
587 
588  if (queue_length(c->first, c->last) < 4) return 0;
589  foo(c);
590 
591  if (f0->affinity == -1) return 1;
592 
593  l = find_first_break(f0, 3);
594  if (l == 1 && c->strict_breaks < 0) l = 0;
595 
596  switch (l) {
597  case 1:
598  if (c->strict_breaks < 1 && f0->affinity == 1 && f1->affinity == -1)
599  return 2;
600  else return 1;
601  case 2:
602  /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
603  if (c->strict_pairs
604  && (f0->prev->breaks & BREAK_RIGHT) && (f2->breaks & BREAK_LEFT)
605  && (f0->affinity != 1 || f1->affinity != -1) )
606  return 1;
607  if (f1->affinity == 1) return 1;
608  else return 2;
609  case 3:
610  if (f2->affinity == 1) return 2;
611  else return 3;
612  default:
613  /* 9 possibilities covered before switch */
614  if (f1->affinity == 1) return 1; /* covers 6 */
615  else if (f1->affinity == -1) return 2; /* covers 6 */
616  else if (f2->affinity == -1) { /* covers 2 */
617  if (f0->affinity == 1) return 3;
618  else return 1;
619  }
620  else return 2; /* the remaining 6 */
621  }
622 }
623 
624 
625 static void print_aff_and_breaks(struct pullup_context *c, struct pullup_field *f)
626 {
627  int i;
628  struct pullup_field *f0 = f;
629  const char aff_l[] = "+..", aff_r[] = "..+";
630  printf("\naffinity: ");
631  for (i = 0; i < 4; i++) {
632  printf("%c%d%c", aff_l[1+f->affinity], i, aff_r[1+f->affinity]);
633  f = f->next;
634  }
635  f = f0;
636  printf("\nbreaks: ");
637  for (i=0; i<4; i++) {
638  printf("%c%d%c", f->breaks & BREAK_LEFT ? '|' : '.', i, f->breaks & BREAK_RIGHT ? '|' : '.');
639  f = f->next;
640  }
641  printf("\n");
642 }
643 
644 
645 
646 
647 
649 {
650  int i;
651  struct pullup_frame *fr = c->frame;
652  int n = decide_frame_length(c);
653  int aff = c->first->next->affinity;
654 
655  if (!n) return 0;
656  if (fr->lock) return 0;
657 
658  if (c->verbose) {
660  printf("duration: %d \n", n);
661  }
662 
663  fr->lock++;
664  fr->length = n;
665  fr->parity = c->first->parity;
666  fr->buffer = 0;
667  for (i = 0; i < n; i++) {
668  /* We cheat and steal the buffer without release+relock */
669  fr->ifields[i] = c->first->buffer;
670  c->first->buffer = 0;
671  c->first = c->first->next;
672  }
673 
674  if (n == 1) {
675  fr->ofields[fr->parity] = fr->ifields[0];
676  fr->ofields[fr->parity^1] = 0;
677  } else if (n == 2) {
678  fr->ofields[fr->parity] = fr->ifields[0];
679  fr->ofields[fr->parity^1] = fr->ifields[1];
680  } else if (n == 3) {
681  if (aff == 0)
682  aff = (fr->ifields[0] == fr->ifields[1]) ? -1 : 1;
683  /* else if (c->verbose) printf("forced aff: %d \n", aff); */
684  fr->ofields[fr->parity] = fr->ifields[1+aff];
685  fr->ofields[fr->parity^1] = fr->ifields[1];
686  }
687  ff_pullup_lock_buffer(fr->ofields[0], 0);
688  ff_pullup_lock_buffer(fr->ofields[1], 1);
689 
690  if (fr->ofields[0] == fr->ofields[1]) {
691  fr->buffer = fr->ofields[0];
693  return fr;
694  }
695  return fr;
696 }
697 
698 static void copy_field(struct pullup_context *c, struct pullup_buffer *dest,
699  struct pullup_buffer *src, int parity)
700 {
701  int i, j;
702  unsigned char *d, *s;
703  for (i = 0; i < c->nplanes; i++) {
704  s = src->planes[i] + parity*c->stride[i];
705  d = dest->planes[i] + parity*c->stride[i];
706  for (j = c->h[i]>>1; j; j--) {
707  memcpy(d, s, c->stride[i]);
708  s += c->stride[i]<<1;
709  d += c->stride[i]<<1;
710  }
711  }
712 }
713 
715 {
716  int i;
717  if (fr->buffer) return;
718  if (fr->length < 2) return; /* FIXME: deal with this */
719  for (i = 0; i < 2; i++)
720  {
721  if (fr->ofields[i]->lock[i^1]) continue;
722  fr->buffer = fr->ofields[i];
724  copy_field(c, fr->buffer, fr->ofields[i^1], i^1);
725  return;
726  }
727  fr->buffer = ff_pullup_get_buffer(c, 2);
728  copy_field(c, fr->buffer, fr->ofields[0], 0);
729  copy_field(c, fr->buffer, fr->ofields[1], 1);
730 }
731 
733 {
734  int i;
735  for (i = 0; i < fr->length; i++)
736  ff_pullup_release_buffer(fr->ifields[i], fr->parity ^ (i&1));
739  if (fr->buffer) ff_pullup_release_buffer(fr->buffer, 2);
740  fr->lock--;
741 }
742 
743 
744 
745 
746 
747 
749 {
750  struct pullup_context *c;
751 
752  c = calloc(1, sizeof(struct pullup_context));
753 
754  return c;
755 }
756 
758 {
759  c->bpp = calloc(c->nplanes, sizeof(int));
760  c->w = calloc(c->nplanes, sizeof(int));
761  c->h = calloc(c->nplanes, sizeof(int));
762  c->stride = calloc(c->nplanes, sizeof(int));
763  c->background = calloc(c->nplanes, sizeof(int));
764 }
765 
767 {
768  int mp = c->metric_plane;
769  if (c->nbuffers < 10) c->nbuffers = 10;
770  c->buffers = calloc(c->nbuffers, sizeof (struct pullup_buffer));
771 
772  c->metric_w = (c->w[mp] - ((c->junk_left + c->junk_right) << 3)) >> 3;
773  c->metric_h = (c->h[mp] - ((c->junk_top + c->junk_bottom) << 1)) >> 3;
774  c->metric_offset = c->junk_left*c->bpp[mp] + (c->junk_top<<1)*c->stride[mp];
775  c->metric_len = c->metric_w * c->metric_h;
776 
777  c->head = make_field_queue(c, 8);
778 
779  c->frame = calloc(1, sizeof (struct pullup_frame));
780  c->frame->ifields = calloc(3, sizeof (struct pullup_buffer *));
781 
782  switch(c->format) {
783  case PULLUP_FMT_Y:
784  c->diff = diff_y;
785  c->comb = licomb_y;
786  c->var = var_y;
787 #if ARCH_X86
788 #if HAVE_MMX
789  if (c->cpu & PULLUP_CPU_MMX) {
790  c->diff = diff_y_mmx;
791  c->comb = licomb_y_mmx;
792  c->var = var_y_mmx;
793  }
794 #endif
795 #endif
796  /* c->comb = qpcomb_y; */
797  break;
798 #if 0
799  case PULLUP_FMT_YUY2:
800  c->diff = diff_yuy2;
801  break;
802  case PULLUP_FMT_RGB32:
803  c->diff = diff_rgb32;
804  break;
805 #endif
806  }
807 }
808 
810 {
811  struct pullup_field *f;
812  free(c->buffers);
813  f = c->head;
814  do {
815  if (!f) break;
816  free(f->diffs);
817  free(f->comb);
818  f = f->next;
819  free(f->prev);
820  } while (f != c->head);
821  free(c->frame);
822  free(c);
823 }
static void check_field_queue(struct pullup_context *c)
Definition: pullup.c:404
int breaks
Definition: pullup.h:45
float v
const char * s
Definition: avisynth_c.h:668
struct pullup_field * head
Definition: pullup.h:75
int metric_offset
Definition: pullup.h:81
int * background
Definition: pullup.h:67
struct pullup_buffer * ff_pullup_lock_buffer(struct pullup_buffer *b, int parity)
Definition: pullup.c:292
int junk_bottom
Definition: pullup.h:69
static int licomb_y(unsigned char *a, unsigned char *b, int s)
Definition: pullup.c:227
int format
Definition: pullup.h:65
if max(w)>1 w=0.9 *w/max(w)
static void compute_breaks(struct pullup_context *c, struct pullup_field *f0)
Definition: pullup.c:492
static void compute_metric(struct pullup_context *c, struct pullup_field *fa, int pa, struct pullup_field *fb, int pb, int(*func)(unsigned char *, unsigned char *, int), int *dest)
Definition: pullup.c:344
Sinusoidal phase f
#define PULLUP_CPU_MMX
Definition: pullup.h:22
int(* comb)(unsigned char *, unsigned char *, int)
Definition: pullup.h:79
int metric_h
Definition: pullup.h:81
struct pullup_buffer * buffer
Definition: pullup.h:59
output residual component w
struct pullup_frame * ff_pullup_get_frame(struct pullup_context *c)
Definition: pullup.c:648
set threshold d
void ff_pullup_release_frame(struct pullup_frame *fr)
Definition: pullup.c:732
struct pullup_buffer ** ifields
Definition: pullup.h:58
struct pullup_field * first
Definition: pullup.h:75
int * h
Definition: pullup.h:67
struct pullup_frame * frame
Definition: pullup.h:82
void ff_pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr)
Definition: pullup.c:714
int nbuffers
Definition: pullup.h:77
static void foo(struct pullup_context *c)
Definition: pullup.c:570
window constants for m
int metric_plane
Definition: pullup.h:71
struct pullup_field * prev
Definition: pullup.h:50
#define b
Definition: input.c:42
end end
static int queue_length(struct pullup_field *begin, struct pullup_field *end)
Definition: pullup.c:471
int(* var)(unsigned char *, unsigned char *, int)
Definition: pullup.h:80
function f0
int * var
Definition: pullup.h:49
int parity
Definition: pullup.h:42
f2
Definition: genspecsines3.m:4
Discrete Time axis x
static void alloc_buffer(struct pullup_context *c, struct pullup_buffer *b)
Definition: pullup.c:280
int metric_w
Definition: pullup.h:81
#define BREAK_LEFT
Definition: pullup.c:465
static int decide_frame_length(struct pullup_context *c)
Definition: pullup.c:581
int parity
Definition: pullup.h:57
unsigned char ** planes
Definition: pullup.h:37
void ff_pullup_free_context(struct pullup_context *c)
Definition: pullup.c:809
int metric_len
Definition: pullup.h:81
struct pullup_buffer * ofields[2]
Definition: pullup.h:58
int lock[2]
Definition: pullup.h:36
#define F_HAVE_BREAKS
Definition: pullup.c:461
int length
Definition: pullup.h:56
ret
Definition: avfilter.c:821
int junk_top
Definition: pullup.h:69
void ff_pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity)
Definition: pullup.c:416
int verbose
Definition: pullup.h:70
int * bpp
Definition: pullup.h:67
#define diff(a, as, b, bs)
Definition: vf_phase.c:80
static void print_aff_and_breaks(struct pullup_context *c, struct pullup_field *f)
Definition: pullup.c:625
static int var_y(unsigned char *a, unsigned char *b, int s)
Definition: pullup.c:260
int strict_breaks
Definition: pullup.h:72
struct pullup_buffer * buffer
Definition: pullup.h:43
unsigned int cpu
Definition: pullup.h:68
static void alloc_metrics(struct pullup_context *c, struct pullup_field *f)
Definition: pullup.c:380
int junk_left
Definition: pullup.h:69
static int find_first_break(struct pullup_field *f, int max)
Definition: pullup.c:481
#define F_HAVE_AFFINITY
Definition: pullup.c:462
dest
Definition: start.py:60
f3
Definition: genspecsines3.m:5
AVS_Value src
Definition: avisynth_c.h:523
static struct pullup_field * make_field_queue(struct pullup_context *c, int len)
Definition: pullup.c:388
#define ABS(a)
Definition: pullup.c:215
int * diffs
Definition: pullup.h:47
static int diff_y(unsigned char *a, unsigned char *b, int s)
Definition: pullup.c:217
void ff_pullup_flush_fields(struct pullup_context *c)
Definition: pullup.c:443
int(* func)(AVBPrint *dst, const char *in, const char *arg)
synthesis window for stochastic i
int * w
Definition: pullup.h:67
int lock
Definition: pullup.h:55
int(* diff)(unsigned char *, unsigned char *, int)
Definition: pullup.h:78
void ff_pullup_preinit_context(struct pullup_context *c)
Definition: pullup.c:757
struct pullup_context * ff_pullup_alloc_context(void)
Definition: pullup.c:748
#define PULLUP_FMT_Y
Definition: pullup.h:29
unsigned int flags
Definition: pullup.h:44
#define PULLUP_FMT_RGB32
Definition: pullup.h:32
void ff_pullup_init_context(struct pullup_context *c)
Definition: pullup.c:766
static double c[64]
int * comb
Definition: pullup.h:48
function y
Definition: D.m:1
static void copy_field(struct pullup_context *c, struct pullup_buffer *dest, struct pullup_buffer *src, int parity)
Definition: pullup.c:698
void ff_pullup_release_buffer(struct pullup_buffer *b, int parity)
Definition: pullup.c:300
int len
#define BREAK_RIGHT
Definition: pullup.c:466
struct pullup_field * last
Definition: pullup.h:75
printf("static const uint8_t my_array[100] = {\n")
int nplanes
Definition: pullup.h:66
p parity
Definition: vf_mcdeint.c:178
void INT64 INT64 count
Definition: avisynth_c.h:594
static void compute_affinity(struct pullup_context *c, struct pullup_field *f)
Definition: pullup.c:528
int * stride
Definition: pullup.h:67
struct pullup_buffer * buffers
Definition: pullup.h:76
int strict_pairs
Definition: pullup.h:73
#define PULLUP_FMT_YUY2
Definition: pullup.h:30
f1
Definition: genspecsines3.m:3
int junk_right
Definition: pullup.h:69
MUSIC TECHNOLOGY GROUP UNIVERSITAT POMPEU FABRA Free Non Commercial Binary License Agreement UNIVERSITAT POMPEU OR INDICATING ACCEPTANCE BY SELECTING THE ACCEPT BUTTON ON ANY DOWNLOAD OR INSTALL YOU ACCEPT THE TERMS OF THE LICENSE SUMMARY TABLE Software MELODIA Melody Extraction vamp plug in Licensor Music Technology Group Universitat Pompeu Plaça de la Spain Permitted purposes Non commercial internal research and validation and educational purposes only All commercial uses in a production either internal or are prohibited by this license and require an additional commercial exploitation license TERMS AND CONDITIONS SOFTWARE Software means the software programs identified herein in binary any other machine readable any updates or error corrections provided by and any user programming guides and other documentation provided to you by UPF under this Agreement LICENSE Subject to the terms and conditions of this UPF grants you a royalty free
int affinity
Definition: pullup.h:46
struct pullup_buffer * ff_pullup_get_buffer(struct pullup_context *c, int parity)
Definition: pullup.c:307
struct pullup_field * next
Definition: pullup.h:50