Mercurial > mplayer.hg
annotate libmpcodecs/pullup.c @ 10730:67449e5936f3
fix 10l (computation based on uninitialized data which led to
incorrect field matching) and greatly improve selection logic. the
pullup core should be very accurate now, so try throwing tough samples
at it and report any failures! :)
| author | rfelker |
|---|---|
| date | Sun, 31 Aug 2003 17:46:32 +0000 |
| parents | d47ca466c97b |
| children | af906af4cf18 |
| rev | line source |
|---|---|
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
1 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
2 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
3 #include <stdlib.h> |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
4 #include "pullup.h" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
5 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
6 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
7 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
8 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
9 #ifdef HAVE_MMX |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
10 static int diff_y_mmx(unsigned char *a, unsigned char *b, int s) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
11 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
12 int ret; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
13 asm ( |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
14 "movl $4, %%ecx \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
15 "pxor %%mm4, %%mm4 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
16 "pxor %%mm7, %%mm7 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
17 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
18 ".balign 16 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
19 "1: \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
20 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
21 "movq (%%esi), %%mm0 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
22 "movq (%%esi), %%mm2 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
23 "addl %%eax, %%esi \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
24 "movq (%%edi), %%mm1 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
25 "addl %%eax, %%edi \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
26 "psubusb %%mm1, %%mm2 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
27 "psubusb %%mm0, %%mm1 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
28 "movq %%mm2, %%mm0 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
29 "movq %%mm1, %%mm3 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
30 "punpcklbw %%mm7, %%mm0 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
31 "punpcklbw %%mm7, %%mm1 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
32 "punpckhbw %%mm7, %%mm2 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
33 "punpckhbw %%mm7, %%mm3 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
34 "paddw %%mm0, %%mm4 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
35 "paddw %%mm1, %%mm4 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
36 "paddw %%mm2, %%mm4 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
37 "paddw %%mm3, %%mm4 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
38 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
39 "decl %%ecx \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
40 "jnz fb \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
41 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
42 "movq %%mm4, %%mm3 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
43 "punpcklwl %%mm7, %%mm4 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
44 "punpckhwl %%mm7, %%mm3 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
45 "paddl %%mm4, %%mm3 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
46 "movq %%mm3, %%mm2 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
47 "punpckllq %%mm7, %%mm3 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
48 "punpckhlq %%mm7, %%mm2 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
49 "paddl %%mm3, %%mm2 \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
50 "movl %%mm2, %eax" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
51 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
52 "emms \n\t" |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
53 : "=a" (ret) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
54 : "S" (a), "D" (b), "a" (s) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
55 : |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
56 ); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
57 return ret; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
58 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
59 #endif |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
60 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
61 #define ABS(a) (((a)^((a)>>31))-((a)>>31)) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
62 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
63 static int diff_y(unsigned char *a, unsigned char *b, int s) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
64 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
65 int i, j, diff=0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
66 for (i=4; i; i--) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
67 for (j=0; j<8; j++) diff += ABS(a[j]-b[j]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
68 a+=s; b+=s; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
69 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
70 return diff; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
71 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
72 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
73 static int licomb_y(unsigned char *a, unsigned char *b, int s) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
74 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
75 int i, j, diff=0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
76 for (i=8; i; i--) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
77 for (j=0; j<8; j++) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
78 diff += ABS((a[j]<<1) - b[j-s] - b[j]) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
79 + ABS((b[j]<<1) - a[j] - a[j+s]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
80 a+=s; b+=s; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
81 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
82 return diff; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
83 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
84 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
85 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
86 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
87 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
88 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
89 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
90 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
91 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
92 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
93 static void alloc_buffer(struct pullup_context *c, struct pullup_buffer *b) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
94 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
95 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
96 if (b->planes) return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
97 b->planes = calloc(c->nplanes, sizeof(unsigned char *)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
98 for (i = 0; i < c->nplanes; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
99 b->planes[i] = malloc(c->h[i]*c->stride[i]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
100 /* Deal with idiotic 128=0 for chroma: */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
101 memset(b->planes[i], c->background[i], c->h[i]*c->stride[i]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
102 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
103 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
104 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
105 struct pullup_buffer *pullup_lock_buffer(struct pullup_buffer *b, int parity) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
106 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
107 if (parity+1 & 1) b->lock[0]++; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
108 if (parity+1 & 2) b->lock[1]++; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
109 return b; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
110 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
111 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
112 void pullup_release_buffer(struct pullup_buffer *b, int parity) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
113 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
114 if (parity+1 & 1) b->lock[0]--; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
115 if (parity+1 & 2) b->lock[1]--; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
116 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
117 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
118 struct pullup_buffer *pullup_get_buffer(struct pullup_context *c, int parity) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
119 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
120 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
121 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
122 /* Try first to get the sister buffer for the previous field */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
123 if (parity < 2 && c->last && parity != c->last->parity |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
124 && !c->last->buffer->lock[parity]) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
125 alloc_buffer(c, c->last->buffer); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
126 return pullup_lock_buffer(c->last->buffer, parity); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
127 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
128 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
129 /* Prefer a buffer with both fields open */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
130 for (i = 0; i < c->nbuffers; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
131 if (c->buffers[i].lock[0]) continue; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
132 if (c->buffers[i].lock[1]) continue; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
133 alloc_buffer(c, &c->buffers[i]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
134 return pullup_lock_buffer(&c->buffers[i], parity); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
135 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
136 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
137 if (parity == 2) return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
138 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
139 /* Search for any half-free buffer */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
140 for (i = 0; i < c->nbuffers; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
141 if (parity+1 & 1 && c->buffers[i].lock[0]) continue; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
142 if (parity+1 & 2 && c->buffers[i].lock[1]) continue; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
143 alloc_buffer(c, &c->buffers[i]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
144 return pullup_lock_buffer(&c->buffers[i], parity); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
145 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
146 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
147 return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
148 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
149 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
150 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
151 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
152 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
153 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
154 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
155 static void compute_metric(struct pullup_context *c, |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
156 struct pullup_field *fa, int pa, |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
157 struct pullup_field *fb, int pb, |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
158 int (*func)(unsigned char *, unsigned char *, int), int *dest) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
159 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
160 unsigned char *a, *b; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
161 int x, y; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
162 int xstep = c->bpp[0]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
163 int ystep = c->stride[0]<<3; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
164 int s = c->stride[0]<<1; /* field stride */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
165 int w = c->metric_w*xstep; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
166 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
167 if (!fa->buffer || !fb->buffer) return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
168 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
169 /* Shortcut for duplicate fields (e.g. from RFF flag) */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
170 if (fa->buffer == fb->buffer && pa == pb) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
171 memset(dest, 0, c->metric_len * sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
172 return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
173 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
174 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
175 a = fa->buffer->planes[0] + pa * c->stride[0] + c->metric_offset; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
176 b = fb->buffer->planes[0] + pb * c->stride[0] + c->metric_offset; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
177 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
178 for (y = c->metric_h; y; y--) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
179 for (x = 0; x < w; x += xstep) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
180 *dest++ = func(a + x, b + x, s); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
181 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
182 a += ystep; b += ystep; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
183 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
184 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
185 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
186 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
187 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
188 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
189 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
190 static void alloc_metrics(struct pullup_context *c, struct pullup_field *f) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
191 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
192 f->diffs = calloc(c->metric_len, sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
193 f->licomb = calloc(c->metric_len, sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
194 /* add more metrics here as needed */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
195 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
196 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
197 static struct pullup_field *make_field_queue(struct pullup_context *c, int len) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
198 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
199 struct pullup_field *head, *f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
200 f = head = calloc(1, sizeof(struct pullup_field)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
201 alloc_metrics(c, f); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
202 for (; len > 0; len--) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
203 f->next = calloc(1, sizeof(struct pullup_field)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
204 f->next->prev = f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
205 f = f->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
206 alloc_metrics(c, f); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
207 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
208 f->next = head; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
209 head->prev = f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
210 return head; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
211 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
212 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
213 static void check_field_queue(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
214 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
215 if (c->head->next == c->first) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
216 struct pullup_field *f = calloc(1, sizeof(struct pullup_field)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
217 alloc_metrics(c, f); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
218 f->prev = c->head; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
219 f->next = c->first; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
220 c->head->next = f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
221 c->first->prev = f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
222 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
223 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
224 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
225 int pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
226 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
227 struct pullup_field *f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
228 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
229 /* Grow the circular list if needed */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
230 check_field_queue(c); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
231 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
232 /* Cannot have two fields of same parity in a row; drop the new one */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
233 if (c->last && c->last->parity == parity) return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
234 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
235 f = c->head; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
236 f->parity = parity; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
237 f->buffer = pullup_lock_buffer(b, parity); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
238 f->flags = 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
239 f->breaks = 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
240 f->affinity = 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
241 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
242 compute_metric(c, f, parity, f->prev->prev, parity, c->diff, f->diffs); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
243 compute_metric(c, parity?f->prev:f, 0, parity?f:f->prev, 1, c->licomb, f->licomb); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
244 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
245 /* Advance the circular list */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
246 if (!c->first) c->first = c->head; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
247 c->last = c->head; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
248 c->head = c->head->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
249 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
250 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
251 void pullup_flush_fields(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
252 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
253 struct pullup_field *f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
254 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
255 for (f = c->first; f && f != c->head; f = f->next) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
256 pullup_release_buffer(f->buffer, f->parity); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
257 f->buffer = 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
258 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
259 c->first = c->last = 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
260 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
261 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
262 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
263 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
264 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
265 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
266 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
267 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
268 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
269 #define F_HAVE_BREAKS 1 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
270 #define F_HAVE_AFFINITY 2 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
271 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
272 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
273 #define BREAK_LEFT 1 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
274 #define BREAK_RIGHT 2 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
275 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
276 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
277 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
278 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
279 static int queue_length(struct pullup_field *begin, struct pullup_field *end) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
280 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
281 int count = 1; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
282 struct pullup_field *f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
283 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
284 if (!begin || !end) return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
285 for (f = begin; f != end; f = f->next) count++; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
286 return count; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
287 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
288 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
289 static int find_first_break(struct pullup_field *f, int max) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
290 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
291 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
292 for (i = 0; i < max; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
293 if (f->breaks & BREAK_RIGHT || f->next->breaks & BREAK_LEFT) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
294 return i+1; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
295 f = f->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
296 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
297 return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
298 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
299 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
300 static void compute_breaks(struct pullup_context *c, struct pullup_field *f0) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
301 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
302 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
303 struct pullup_field *f1 = f0->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
304 struct pullup_field *f2 = f1->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
305 struct pullup_field *f3 = f2->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
306 int l, max_l=0, max_r=0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
307 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
308 if (f0->flags & F_HAVE_BREAKS) return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
309 f0->flags |= F_HAVE_BREAKS; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
310 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
311 /* Special case when fields are 100% identical */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
312 if (f0->buffer == f2->buffer && f1->buffer != f3->buffer) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
313 f0->breaks |= BREAK_LEFT; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
314 f2->breaks |= BREAK_RIGHT; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
315 return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
316 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
317 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
318 for (i = 0; i < c->metric_len; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
319 l = f2->diffs[i] - f3->diffs[i]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
320 if (l > max_l) max_l = l; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
321 if (-l > max_r) max_r = -l; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
322 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
323 /* Don't get tripped up when differences are mostly quant error */ |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
324 if (max_l + max_r < 256) return; |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
325 if (max_l > 4*max_r) f1->breaks |= BREAK_LEFT; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
326 if (max_r > 4*max_l) f2->breaks |= BREAK_RIGHT; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
327 //printf("max_l=%d max_r=%d\n", max_l, max_r); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
328 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
329 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
330 static void compute_affinity(struct pullup_context *c, struct pullup_field *f) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
331 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
332 int i; |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
333 int max_l=0, max_r=0, l, t; |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
334 if (f->flags & F_HAVE_AFFINITY) return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
335 f->flags |= F_HAVE_AFFINITY; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
336 for (i = 0; i < c->metric_len; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
337 l = f->licomb[i] - f->next->licomb[i]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
338 if (l > max_l) max_l = l; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
339 if (-l > max_r) max_r = -l; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
340 } |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
341 if (max_l + max_r < 256) return; |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
342 if (max_r > 3*max_l) f->affinity = -1; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
343 else if (max_l > 3*max_r) f->affinity = 1; |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
344 else if (max_l + max_r > 2048) { |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
345 for (i = 0; i < c->metric_len; i++) { |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
346 l += f->licomb[i] - f->next->licomb[i]; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
347 t += ABS(f->licomb[i] - f->next->licomb[i]); |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
348 } |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
349 if (-l*4 > t) f->affinity = -1; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
350 else if (l*4 > t) f->affinity = 1; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
351 //printf("affinity from avg: %d\n", f->affinity); |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
352 } |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
353 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
354 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
355 static void foo(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
356 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
357 struct pullup_field *f = c->first; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
358 int i, n = queue_length(f, c->last); |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
359 for (i = 0; i < n-1; i++) { |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
360 if (i < n-3) compute_breaks(c, f); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
361 compute_affinity(c, f); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
362 f = f->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
363 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
364 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
365 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
366 static int decide_frame_length(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
367 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
368 int n; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
369 struct pullup_field *f0 = c->first; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
370 struct pullup_field *f1 = f0->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
371 struct pullup_field *f2 = f1->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
372 struct pullup_field *f3 = f2->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
373 struct pullup_field *f4 = f3->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
374 struct pullup_field *f5 = f4->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
375 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
376 if (queue_length(c->first, c->last) < 6) return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
377 foo(c); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
378 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
379 n = find_first_break(f0, 3); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
380 |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
381 if (f0->affinity == -1) return 1; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
382 |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
383 switch (n) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
384 case 1: |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
385 return 1; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
386 case 2: |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
387 if (f1->affinity == 1) return 1; |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
388 else return 2; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
389 case 3: |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
390 if (f1->affinity == -1) return 2; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
391 else if (f1->affinity == 1) return 1; |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
392 else return 3; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
393 default: |
|
10730
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
394 if (f1->affinity == 1) return 1; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
395 else if (f1->affinity == -1) return 2; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
396 else if (f2->affinity == 1) return 2; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
397 else if (f0->affinity == 1 && f2->affinity == -1) return 3; |
|
67449e5936f3
fix 10l (computation based on uninitialized data which led to
rfelker
parents:
10664
diff
changeset
|
398 else if (f2->affinity == 0 && f3->affinity == 1) return 3; |
|
10664
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
399 else return 2; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
400 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
401 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
402 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
403 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
404 static void print_aff_and_breaks(struct pullup_context *c, struct pullup_field *f) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
405 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
406 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
407 int max_l, max_r, l; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
408 struct pullup_field *f0 = f; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
409 const char aff_l[] = "+..", aff_r[] = "..+"; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
410 printf("\naffinity: "); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
411 for (i = 0; i < 6; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
412 printf("%c%d%c", aff_l[1+f->affinity], i, aff_r[1+f->affinity]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
413 f = f->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
414 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
415 f = f0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
416 printf("\nbreaks: "); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
417 for (i=0; i<6; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
418 printf("%c%d%c", f->breaks & BREAK_LEFT ? '|' : '.', i, f->breaks & BREAK_RIGHT ? '|' : '.'); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
419 f = f->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
420 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
421 printf("\n"); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
422 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
423 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
424 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
425 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
426 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
427 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
428 struct pullup_frame *pullup_get_frame(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
429 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
430 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
431 struct pullup_frame *fr = c->frame; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
432 int n = decide_frame_length(c); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
433 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
434 if (!n) return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
435 if (fr->lock) return 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
436 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
437 print_aff_and_breaks(c, c->first); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
438 printf("duration: %d \n", n); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
439 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
440 fr->lock++; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
441 fr->length = n; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
442 fr->parity = c->first->parity; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
443 fr->buffer = 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
444 for (i = 0; i < n; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
445 /* We cheat and steal the buffer without release+relock */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
446 fr->fields[i] = c->first->buffer; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
447 c->first->buffer = 0; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
448 c->first = c->first->next; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
449 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
450 /* Export the entire frame as one buffer, if possible! */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
451 if (n == 2 && fr->fields[0] == fr->fields[1]) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
452 fr->buffer = fr->fields[0]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
453 pullup_lock_buffer(fr->buffer, 2); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
454 return fr; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
455 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
456 /* (loop is in case we ever support frames longer than 3 fields) */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
457 for (i = 1; i < n-1; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
458 if (fr->fields[i] == fr->fields[i-1] |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
459 || fr->fields[i] == fr->fields[i+1]) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
460 fr->buffer = fr->fields[i]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
461 pullup_lock_buffer(fr->buffer, 2); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
462 break; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
463 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
464 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
465 return fr; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
466 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
467 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
468 static void copy_field(struct pullup_context *c, struct pullup_buffer *dest, |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
469 struct pullup_buffer *src, int parity) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
470 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
471 int i, j; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
472 unsigned char *d, *s; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
473 for (i = 0; i < c->nplanes; i++) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
474 s = src->planes[i] + parity*c->stride[i]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
475 d = dest->planes[i] + parity*c->stride[i]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
476 for (j = c->h[i]>>1; j; j--) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
477 memcpy(d, s, c->stride[i]); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
478 s += c->stride[i]<<1; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
479 d += c->stride[i]<<1; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
480 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
481 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
482 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
483 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
484 void pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
485 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
486 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
487 int par = fr->parity; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
488 if (fr->buffer) return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
489 if (fr->length < 2) return; /* FIXME: deal with this */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
490 for (i = 0; i < fr->length; i++) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
491 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
492 if (fr->fields[i]->lock[par ^ (i&1) ^ 1]) continue; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
493 fr->buffer = fr->fields[i]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
494 pullup_lock_buffer(fr->buffer, 2); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
495 copy_field(c, fr->buffer, fr->fields[i+(i>0?-1:1)], par^(i&1)^1); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
496 return; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
497 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
498 fr->buffer = pullup_get_buffer(c, 2); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
499 copy_field(c, fr->buffer, fr->fields[0], par); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
500 copy_field(c, fr->buffer, fr->fields[1], par^1); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
501 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
502 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
503 void pullup_release_frame(struct pullup_frame *fr) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
504 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
505 int i; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
506 for (i = 0; i < fr->length; i++) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
507 pullup_release_buffer(fr->fields[i], fr->parity ^ (i&1)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
508 if (fr->buffer) pullup_release_buffer(fr->buffer, 2); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
509 fr->lock--; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
510 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
511 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
512 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
513 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
514 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
515 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
516 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
517 struct pullup_context *pullup_alloc_context() |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
518 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
519 struct pullup_context *c; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
520 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
521 c = calloc(1, sizeof(struct pullup_context)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
522 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
523 return c; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
524 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
525 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
526 void pullup_preinit_context(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
527 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
528 c->bpp = calloc(c->nplanes, sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
529 c->w = calloc(c->nplanes, sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
530 c->h = calloc(c->nplanes, sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
531 c->stride = calloc(c->nplanes, sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
532 c->background = calloc(c->nplanes, sizeof(int)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
533 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
534 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
535 void pullup_init_context(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
536 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
537 if (c->nbuffers < 10) c->nbuffers = 10; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
538 c->buffers = calloc(c->nbuffers, sizeof (struct pullup_buffer)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
539 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
540 c->metric_w = (c->w[0] - (c->junk_left + c->junk_right << 3)) >> 3; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
541 c->metric_h = (c->h[0] - (c->junk_top + c->junk_bottom << 1)) >> 3; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
542 c->metric_offset = c->junk_left*c->bpp[0] + (c->junk_top<<1)*c->stride[0]; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
543 c->metric_len = c->metric_w * c->metric_h; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
544 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
545 c->head = make_field_queue(c, 8); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
546 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
547 c->frame = calloc(1, sizeof (struct pullup_frame)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
548 c->frame->fields = calloc(3, sizeof (struct pullup_buffer *)); |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
549 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
550 switch(c->format) { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
551 case PULLUP_FMT_Y: |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
552 c->diff = diff_y; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
553 c->licomb = licomb_y; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
554 #ifdef HAVE_MMX |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
555 if (c->cpu & PULLUP_CPU_MMX) c->diff = diff_y_mmx; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
556 #endif |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
557 break; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
558 #if 0 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
559 case PULLUP_FMT_YUY2: |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
560 c->diff = diff_yuy2; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
561 break; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
562 case PULLUP_FMT_RGB32: |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
563 c->diff = diff_rgb32; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
564 break; |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
565 #endif |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
566 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
567 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
568 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
569 void pullup_free_context(struct pullup_context *c) |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
570 { |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
571 /* FIXME: free! */ |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
572 } |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
573 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
574 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
575 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
576 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
577 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
578 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
579 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
580 |
|
d47ca466c97b
pullup -- third generation inverse telecine engine. the backend
rfelker
parents:
diff
changeset
|
581 |
