Mercurial > mplayer.hg
annotate libmpcodecs/vf_yadif.c @ 31816:ab9824b6acc7
dvd: Improve seeking by chapters.
The current code seeks to the start of the chapter. From this position, it then
tries to figure out the starting cell. This is completely suboptimal and error
prone since the starting cell can be directly deduced from the chapter.
patch by Olivier Rolland, billl users.sourceforge net
author | diego |
---|---|
date | Sun, 01 Aug 2010 22:51:15 +0000 |
parents | a972c1a4a012 |
children | 3525dc14e3dc |
rev | line source |
---|---|
18608 | 1 /* |
26727 | 2 * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at> |
3 * | |
4 * This file is part of MPlayer. | |
5 * | |
6 * MPlayer is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * MPlayer is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License along | |
17 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 */ | |
18608 | 20 |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <string.h> | |
24 #include <inttypes.h> | |
25 #include <math.h> | |
26 | |
27 #include "config.h" | |
19830 | 28 #include "cpudetect.h" |
18608 | 29 |
30 #include "mp_msg.h" | |
31 #include "img_format.h" | |
32 #include "mp_image.h" | |
33 #include "vf.h" | |
34 #include "libvo/fastmemcpy.h" | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
35 #include "libavutil/common.h" |
18608 | 36 |
37 //===========================================================================// | |
38 | |
39 struct vf_priv_s { | |
40 int mode; | |
41 int parity; | |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
42 int buffered_i; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
43 int buffered_tff; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
44 double buffered_pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
45 mp_image_t *buffered_mpi; |
18608 | 46 int stride[3]; |
18625 | 47 uint8_t *ref[4][3]; |
21060 | 48 int do_deinterlace; |
18608 | 49 }; |
50 | |
19830 | 51 static void (*filter_line)(struct vf_priv_s *p, uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int refs, int parity); |
52 | |
18608 | 53 static void store_ref(struct vf_priv_s *p, uint8_t *src[3], int src_stride[3], int width, int height){ |
54 int i; | |
55 | |
23458
973e53dc7df5
Do not use fast_memcpy for small size copy, esp. when the size is constant
reimar
parents:
23457
diff
changeset
|
56 memcpy (p->ref[3], p->ref[0], sizeof(uint8_t *)*3); |
18625 | 57 memmove(p->ref[0], p->ref[1], sizeof(uint8_t *)*3*3); |
18608 | 58 |
59 for(i=0; i<3; i++){ | |
60 int is_chroma= !!i; | |
61 | |
18625 | 62 memcpy_pic(p->ref[2][i], src[i], width>>is_chroma, height>>is_chroma, p->stride[i], src_stride[i]); |
18608 | 63 } |
64 } | |
65 | |
28292
d6001126678f
More #ifdef HAVE_MMX etc. missed by earlier search.
reimar
parents:
28174
diff
changeset
|
66 #if HAVE_MMX && defined(NAMED_ASM_ARGS) |
19830 | 67 |
68 #define LOAD4(mem,dst) \ | |
69 "movd "mem", "#dst" \n\t"\ | |
70 "punpcklbw %%mm7, "#dst" \n\t" | |
71 | |
72 #define PABS(tmp,dst) \ | |
73 "pxor "#tmp", "#tmp" \n\t"\ | |
74 "psubw "#dst", "#tmp" \n\t"\ | |
75 "pmaxsw "#tmp", "#dst" \n\t" | |
76 | |
77 #define CHECK(pj,mj) \ | |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
78 "movq "#pj"(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1+j] */\ |
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
79 "movq "#mj"(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1-j] */\ |
19830 | 80 "movq %%mm2, %%mm4 \n\t"\ |
81 "movq %%mm2, %%mm5 \n\t"\ | |
82 "pxor %%mm3, %%mm4 \n\t"\ | |
83 "pavgb %%mm3, %%mm5 \n\t"\ | |
84 "pand %[pb1], %%mm4 \n\t"\ | |
85 "psubusb %%mm4, %%mm5 \n\t"\ | |
86 "psrlq $8, %%mm5 \n\t"\ | |
87 "punpcklbw %%mm7, %%mm5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\ | |
88 "movq %%mm2, %%mm4 \n\t"\ | |
89 "psubusb %%mm3, %%mm2 \n\t"\ | |
90 "psubusb %%mm4, %%mm3 \n\t"\ | |
91 "pmaxub %%mm3, %%mm2 \n\t"\ | |
92 "movq %%mm2, %%mm3 \n\t"\ | |
93 "movq %%mm2, %%mm4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\ | |
94 "psrlq $8, %%mm3 \n\t" /* ABS(cur[x-refs +j] - cur[x+refs -j]) */\ | |
95 "psrlq $16, %%mm4 \n\t" /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\ | |
96 "punpcklbw %%mm7, %%mm2 \n\t"\ | |
97 "punpcklbw %%mm7, %%mm3 \n\t"\ | |
98 "punpcklbw %%mm7, %%mm4 \n\t"\ | |
99 "paddw %%mm3, %%mm2 \n\t"\ | |
100 "paddw %%mm4, %%mm2 \n\t" /* score */ | |
101 | |
102 #define CHECK1 \ | |
103 "movq %%mm0, %%mm3 \n\t"\ | |
104 "pcmpgtw %%mm2, %%mm3 \n\t" /* if(score < spatial_score) */\ | |
105 "pminsw %%mm2, %%mm0 \n\t" /* spatial_score= score; */\ | |
106 "movq %%mm3, %%mm6 \n\t"\ | |
107 "pand %%mm3, %%mm5 \n\t"\ | |
108 "pandn %%mm1, %%mm3 \n\t"\ | |
109 "por %%mm5, %%mm3 \n\t"\ | |
110 "movq %%mm3, %%mm1 \n\t" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */ | |
111 | |
112 #define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\ | |
113 hurts both quality and speed, but matches the C version. */\ | |
114 "paddw %[pw1], %%mm6 \n\t"\ | |
115 "psllw $14, %%mm6 \n\t"\ | |
116 "paddsw %%mm6, %%mm2 \n\t"\ | |
117 "movq %%mm0, %%mm3 \n\t"\ | |
118 "pcmpgtw %%mm2, %%mm3 \n\t"\ | |
119 "pminsw %%mm2, %%mm0 \n\t"\ | |
120 "pand %%mm3, %%mm5 \n\t"\ | |
121 "pandn %%mm1, %%mm3 \n\t"\ | |
122 "por %%mm5, %%mm3 \n\t"\ | |
123 "movq %%mm3, %%mm1 \n\t" | |
124 | |
125 static void filter_line_mmx2(struct vf_priv_s *p, uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int refs, int parity){ | |
126 static const uint64_t pw_1 = 0x0001000100010001ULL; | |
127 static const uint64_t pb_1 = 0x0101010101010101ULL; | |
128 const int mode = p->mode; | |
129 uint64_t tmp0, tmp1, tmp2, tmp3; | |
130 int x; | |
131 | |
132 #define FILTER\ | |
133 for(x=0; x<w; x+=4){\ | |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
26727
diff
changeset
|
134 __asm__ volatile(\ |
19830 | 135 "pxor %%mm7, %%mm7 \n\t"\ |
136 LOAD4("(%[cur],%[mrefs])", %%mm0) /* c = cur[x-refs] */\ | |
137 LOAD4("(%[cur],%[prefs])", %%mm1) /* e = cur[x+refs] */\ | |
138 LOAD4("(%["prev2"])", %%mm2) /* prev2[x] */\ | |
139 LOAD4("(%["next2"])", %%mm3) /* next2[x] */\ | |
140 "movq %%mm3, %%mm4 \n\t"\ | |
141 "paddw %%mm2, %%mm3 \n\t"\ | |
142 "psraw $1, %%mm3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\ | |
143 "movq %%mm0, %[tmp0] \n\t" /* c */\ | |
144 "movq %%mm3, %[tmp1] \n\t" /* d */\ | |
145 "movq %%mm1, %[tmp2] \n\t" /* e */\ | |
146 "psubw %%mm4, %%mm2 \n\t"\ | |
147 PABS( %%mm4, %%mm2) /* temporal_diff0 */\ | |
148 LOAD4("(%[prev],%[mrefs])", %%mm3) /* prev[x-refs] */\ | |
149 LOAD4("(%[prev],%[prefs])", %%mm4) /* prev[x+refs] */\ | |
150 "psubw %%mm0, %%mm3 \n\t"\ | |
151 "psubw %%mm1, %%mm4 \n\t"\ | |
152 PABS( %%mm5, %%mm3)\ | |
153 PABS( %%mm5, %%mm4)\ | |
154 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff1 */\ | |
155 "psrlw $1, %%mm2 \n\t"\ | |
156 "psrlw $1, %%mm3 \n\t"\ | |
157 "pmaxsw %%mm3, %%mm2 \n\t"\ | |
158 LOAD4("(%[next],%[mrefs])", %%mm3) /* next[x-refs] */\ | |
159 LOAD4("(%[next],%[prefs])", %%mm4) /* next[x+refs] */\ | |
160 "psubw %%mm0, %%mm3 \n\t"\ | |
161 "psubw %%mm1, %%mm4 \n\t"\ | |
162 PABS( %%mm5, %%mm3)\ | |
163 PABS( %%mm5, %%mm4)\ | |
164 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff2 */\ | |
165 "psrlw $1, %%mm3 \n\t"\ | |
166 "pmaxsw %%mm3, %%mm2 \n\t"\ | |
167 "movq %%mm2, %[tmp3] \n\t" /* diff */\ | |
168 \ | |
169 "paddw %%mm0, %%mm1 \n\t"\ | |
170 "paddw %%mm0, %%mm0 \n\t"\ | |
171 "psubw %%mm1, %%mm0 \n\t"\ | |
172 "psrlw $1, %%mm1 \n\t" /* spatial_pred */\ | |
173 PABS( %%mm2, %%mm0) /* ABS(c-e) */\ | |
174 \ | |
175 "movq -1(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1] */\ | |
176 "movq -1(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1] */\ | |
177 "movq %%mm2, %%mm4 \n\t"\ | |
178 "psubusb %%mm3, %%mm2 \n\t"\ | |
179 "psubusb %%mm4, %%mm3 \n\t"\ | |
180 "pmaxub %%mm3, %%mm2 \n\t"\ | |
181 "pshufw $9,%%mm2, %%mm3 \n\t"\ | |
182 "punpcklbw %%mm7, %%mm2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\ | |
183 "punpcklbw %%mm7, %%mm3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\ | |
184 "paddw %%mm2, %%mm0 \n\t"\ | |
185 "paddw %%mm3, %%mm0 \n\t"\ | |
186 "psubw %[pw1], %%mm0 \n\t" /* spatial_score */\ | |
187 \ | |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
188 CHECK(-2,0)\ |
19830 | 189 CHECK1\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
190 CHECK(-3,1)\ |
19830 | 191 CHECK2\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
192 CHECK(0,-2)\ |
19830 | 193 CHECK1\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
194 CHECK(1,-3)\ |
19830 | 195 CHECK2\ |
196 \ | |
197 /* if(p->mode<2) ... */\ | |
198 "movq %[tmp3], %%mm6 \n\t" /* diff */\ | |
199 "cmp $2, %[mode] \n\t"\ | |
200 "jge 1f \n\t"\ | |
201 LOAD4("(%["prev2"],%[mrefs],2)", %%mm2) /* prev2[x-2*refs] */\ | |
202 LOAD4("(%["next2"],%[mrefs],2)", %%mm4) /* next2[x-2*refs] */\ | |
203 LOAD4("(%["prev2"],%[prefs],2)", %%mm3) /* prev2[x+2*refs] */\ | |
204 LOAD4("(%["next2"],%[prefs],2)", %%mm5) /* next2[x+2*refs] */\ | |
205 "paddw %%mm4, %%mm2 \n\t"\ | |
206 "paddw %%mm5, %%mm3 \n\t"\ | |
207 "psrlw $1, %%mm2 \n\t" /* b */\ | |
208 "psrlw $1, %%mm3 \n\t" /* f */\ | |
209 "movq %[tmp0], %%mm4 \n\t" /* c */\ | |
210 "movq %[tmp1], %%mm5 \n\t" /* d */\ | |
211 "movq %[tmp2], %%mm7 \n\t" /* e */\ | |
212 "psubw %%mm4, %%mm2 \n\t" /* b-c */\ | |
213 "psubw %%mm7, %%mm3 \n\t" /* f-e */\ | |
214 "movq %%mm5, %%mm0 \n\t"\ | |
215 "psubw %%mm4, %%mm5 \n\t" /* d-c */\ | |
216 "psubw %%mm7, %%mm0 \n\t" /* d-e */\ | |
217 "movq %%mm2, %%mm4 \n\t"\ | |
218 "pminsw %%mm3, %%mm2 \n\t"\ | |
219 "pmaxsw %%mm4, %%mm3 \n\t"\ | |
220 "pmaxsw %%mm5, %%mm2 \n\t"\ | |
221 "pminsw %%mm5, %%mm3 \n\t"\ | |
222 "pmaxsw %%mm0, %%mm2 \n\t" /* max */\ | |
223 "pminsw %%mm0, %%mm3 \n\t" /* min */\ | |
224 "pxor %%mm4, %%mm4 \n\t"\ | |
225 "pmaxsw %%mm3, %%mm6 \n\t"\ | |
226 "psubw %%mm2, %%mm4 \n\t" /* -max */\ | |
227 "pmaxsw %%mm4, %%mm6 \n\t" /* diff= MAX3(diff, min, -max); */\ | |
228 "1: \n\t"\ | |
229 \ | |
230 "movq %[tmp1], %%mm2 \n\t" /* d */\ | |
231 "movq %%mm2, %%mm3 \n\t"\ | |
232 "psubw %%mm6, %%mm2 \n\t" /* d-diff */\ | |
233 "paddw %%mm6, %%mm3 \n\t" /* d+diff */\ | |
234 "pmaxsw %%mm2, %%mm1 \n\t"\ | |
235 "pminsw %%mm3, %%mm1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\ | |
236 "packuswb %%mm1, %%mm1 \n\t"\ | |
237 \ | |
238 :[tmp0]"=m"(tmp0),\ | |
239 [tmp1]"=m"(tmp1),\ | |
240 [tmp2]"=m"(tmp2),\ | |
241 [tmp3]"=m"(tmp3)\ | |
242 :[prev] "r"(prev),\ | |
243 [cur] "r"(cur),\ | |
244 [next] "r"(next),\ | |
29040
963f578121c6
Use x86_reg instead of long in several video filters to fix compilation on MinGW64.
reimar
parents:
28594
diff
changeset
|
245 [prefs]"r"((x86_reg)refs),\ |
963f578121c6
Use x86_reg instead of long in several video filters to fix compilation on MinGW64.
reimar
parents:
28594
diff
changeset
|
246 [mrefs]"r"((x86_reg)-refs),\ |
19830 | 247 [pw1] "m"(pw_1),\ |
248 [pb1] "m"(pb_1),\ | |
249 [mode] "g"(mode)\ | |
250 );\ | |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
26727
diff
changeset
|
251 __asm__ volatile("movd %%mm1, %0" :"=m"(*dst));\ |
19830 | 252 dst += 4;\ |
253 prev+= 4;\ | |
254 cur += 4;\ | |
255 next+= 4;\ | |
256 } | |
257 | |
258 if(parity){ | |
259 #define prev2 "prev" | |
260 #define next2 "cur" | |
261 FILTER | |
262 #undef prev2 | |
263 #undef next2 | |
264 }else{ | |
265 #define prev2 "cur" | |
266 #define next2 "next" | |
267 FILTER | |
268 #undef prev2 | |
269 #undef next2 | |
270 } | |
271 } | |
272 #undef LOAD4 | |
273 #undef PABS | |
274 #undef CHECK | |
275 #undef CHECK1 | |
276 #undef CHECK2 | |
277 #undef FILTER | |
278 | |
28292
d6001126678f
More #ifdef HAVE_MMX etc. missed by earlier search.
reimar
parents:
28174
diff
changeset
|
279 #endif /* HAVE_MMX && defined(NAMED_ASM_ARGS) */ |
19830 | 280 |
281 static void filter_line_c(struct vf_priv_s *p, uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int refs, int parity){ | |
19828 | 282 int x; |
283 uint8_t *prev2= parity ? prev : cur ; | |
284 uint8_t *next2= parity ? cur : next; | |
19829 | 285 for(x=0; x<w; x++){ |
286 int c= cur[-refs]; | |
287 int d= (prev2[0] + next2[0])>>1; | |
288 int e= cur[+refs]; | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
289 int temporal_diff0= FFABS(prev2[0] - next2[0]); |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
290 int temporal_diff1=( FFABS(prev[-refs] - c) + FFABS(prev[+refs] - e) )>>1; |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
291 int temporal_diff2=( FFABS(next[-refs] - c) + FFABS(next[+refs] - e) )>>1; |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
292 int diff= FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); |
19829 | 293 int spatial_pred= (c+e)>>1; |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
294 int spatial_score= FFABS(cur[-refs-1] - cur[+refs-1]) + FFABS(c-e) |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
295 + FFABS(cur[-refs+1] - cur[+refs+1]) - 1; |
18621 | 296 |
18657 | 297 #define CHECK(j)\ |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
298 { int score= FFABS(cur[-refs-1+j] - cur[+refs-1-j])\ |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
299 + FFABS(cur[-refs +j] - cur[+refs -j])\ |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
300 + FFABS(cur[-refs+1+j] - cur[+refs+1-j]);\ |
18657 | 301 if(score < spatial_score){\ |
302 spatial_score= score;\ | |
303 spatial_pred= (cur[-refs +j] + cur[+refs -j])>>1;\ | |
18608 | 304 |
19829 | 305 CHECK(-1) CHECK(-2) }} }} |
306 CHECK( 1) CHECK( 2) }} }} | |
18657 | 307 |
19829 | 308 if(p->mode<2){ |
309 int b= (prev2[-2*refs] + next2[-2*refs])>>1; | |
310 int f= (prev2[+2*refs] + next2[+2*refs])>>1; | |
18608 | 311 #if 0 |
19829 | 312 int a= cur[-3*refs]; |
313 int g= cur[+3*refs]; | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
314 int max= FFMAX3(d-e, d-c, FFMIN3(FFMAX(b-c,f-e),FFMAX(b-c,b-a),FFMAX(f-g,f-e)) ); |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
315 int min= FFMIN3(d-e, d-c, FFMAX3(FFMIN(b-c,f-e),FFMIN(b-c,b-a),FFMIN(f-g,f-e)) ); |
18608 | 316 #else |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
317 int max= FFMAX3(d-e, d-c, FFMIN(b-c, f-e)); |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
318 int min= FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); |
18608 | 319 #endif |
320 | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
321 diff= FFMAX3(diff, min, -max); |
19829 | 322 } |
18608 | 323 |
19829 | 324 if(spatial_pred > d + diff) |
325 spatial_pred = d + diff; | |
326 else if(spatial_pred < d - diff) | |
327 spatial_pred = d - diff; | |
19828 | 328 |
19829 | 329 dst[0] = spatial_pred; |
19828 | 330 |
19829 | 331 dst++; |
332 cur++; | |
333 prev++; | |
334 next++; | |
335 prev2++; | |
336 next2++; | |
337 } | |
19828 | 338 } |
18608 | 339 |
19828 | 340 static void filter(struct vf_priv_s *p, uint8_t *dst[3], int dst_stride[3], int width, int height, int parity, int tff){ |
23381
300e9b7c499f
Remove some unused variables, patch by timwoj ieee org.
diego
parents:
22117
diff
changeset
|
341 int y, i; |
19828 | 342 |
343 for(i=0; i<3; i++){ | |
344 int is_chroma= !!i; | |
345 int w= width >>is_chroma; | |
346 int h= height>>is_chroma; | |
347 int refs= p->stride[i]; | |
348 | |
349 for(y=0; y<h; y++){ | |
350 if((y ^ parity) & 1){ | |
351 uint8_t *prev= &p->ref[0][i][y*refs]; | |
352 uint8_t *cur = &p->ref[1][i][y*refs]; | |
353 uint8_t *next= &p->ref[2][i][y*refs]; | |
354 uint8_t *dst2= &dst[i][y*dst_stride[i]]; | |
355 filter_line(p, dst2, prev, cur, next, w, refs, parity ^ tff); | |
18608 | 356 }else{ |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23381
diff
changeset
|
357 fast_memcpy(&dst[i][y*dst_stride[i]], &p->ref[1][i][y*refs], w); |
18608 | 358 } |
359 } | |
360 } | |
28292
d6001126678f
More #ifdef HAVE_MMX etc. missed by earlier search.
reimar
parents:
28174
diff
changeset
|
361 #if HAVE_MMX && defined(NAMED_ASM_ARGS) |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
26727
diff
changeset
|
362 if(gCpuCaps.hasMMX2) __asm__ volatile("emms \n\t" : : : "memory"); |
19942
0983feab2dc2
Add forgotten emms which caused weird bugs like nan pts values.
reimar
parents:
19923
diff
changeset
|
363 #endif |
18608 | 364 } |
365 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
366 static int config(struct vf_instance *vf, |
18608 | 367 int width, int height, int d_width, int d_height, |
368 unsigned int flags, unsigned int outfmt){ | |
18625 | 369 int i, j; |
18608 | 370 |
371 for(i=0; i<3; i++){ | |
372 int is_chroma= !!i; | |
18625 | 373 int w= ((width + 31) & (~31))>>is_chroma; |
374 int h= ((height+6+ 31) & (~31))>>is_chroma; | |
18608 | 375 |
376 vf->priv->stride[i]= w; | |
18625 | 377 for(j=0; j<3; j++) |
378 vf->priv->ref[j][i]= malloc(w*h*sizeof(uint8_t))+3*w; | |
18608 | 379 } |
380 | |
381 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
382 } | |
383 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
384 static int continue_buffered_image(struct vf_instance *vf); |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
385 extern int correct_pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
386 |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
387 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
388 int tff; |
18608 | 389 |
390 if(vf->priv->parity < 0) { | |
391 if (mpi->fields & MP_IMGFIELD_ORDERED) | |
392 tff = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST); | |
393 else | |
394 tff = 1; | |
395 } | |
396 else tff = (vf->priv->parity&1)^1; | |
397 | |
18625 | 398 store_ref(vf->priv, mpi->planes, mpi->stride, mpi->w, mpi->h); |
399 | |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
400 vf->priv->buffered_mpi = mpi; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
401 vf->priv->buffered_tff = tff; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
402 vf->priv->buffered_i = 0; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
403 vf->priv->buffered_pts = pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
404 |
22116 | 405 if(vf->priv->do_deinterlace == 0) |
406 return vf_next_put_image(vf, mpi, pts); | |
407 else if(vf->priv->do_deinterlace == 1){ | |
408 vf->priv->do_deinterlace= 2; | |
409 return 0; | |
410 }else | |
22117 | 411 return continue_buffered_image(vf); |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
412 } |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
413 |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
414 static int continue_buffered_image(struct vf_instance *vf) |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
415 { |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
416 mp_image_t *mpi = vf->priv->buffered_mpi; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
417 int tff = vf->priv->buffered_tff; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
418 double pts = vf->priv->buffered_pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
419 int i; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
420 int ret=0; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
421 mp_image_t *dmpi; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
422 |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
423 pts += vf->priv->buffered_i * .02; // XXX not right |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
424 |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
425 for(i = vf->priv->buffered_i; i<=(vf->priv->mode&1); i++){ |
18608 | 426 dmpi=vf_get_image(vf->next,mpi->imgfmt, |
427 MP_IMGTYPE_TEMP, | |
428 MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, | |
429 mpi->width,mpi->height); | |
430 vf_clone_mpi_attributes(dmpi, mpi); | |
18625 | 431 filter(vf->priv, dmpi->planes, dmpi->stride, mpi->w, mpi->h, i ^ tff ^ 1, tff); |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
432 if (correct_pts && i < (vf->priv->mode & 1)) |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
433 vf_queue_frame(vf, continue_buffered_image); |
18608 | 434 ret |= vf_next_put_image(vf, dmpi, pts /*FIXME*/); |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
435 if (correct_pts) |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
436 break; |
18626 | 437 if(i<(vf->priv->mode&1)) |
28174 | 438 vf_extra_flip(vf); |
18608 | 439 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
440 vf->priv->buffered_i = 1; |
18608 | 441 return ret; |
442 } | |
443 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
444 static void uninit(struct vf_instance *vf){ |
18608 | 445 int i; |
446 if(!vf->priv) return; | |
447 | |
18625 | 448 for(i=0; i<3*3; i++){ |
449 uint8_t **p= &vf->priv->ref[i%3][i/3]; | |
450 if(*p) free(*p - 3*vf->priv->stride[i/3]); | |
451 *p= NULL; | |
18608 | 452 } |
453 free(vf->priv); | |
454 vf->priv=NULL; | |
455 } | |
456 | |
457 //===========================================================================// | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
458 static int query_format(struct vf_instance *vf, unsigned int fmt){ |
18608 | 459 switch(fmt){ |
460 case IMGFMT_YV12: | |
461 case IMGFMT_I420: | |
462 case IMGFMT_IYUV: | |
463 case IMGFMT_Y800: | |
464 case IMGFMT_Y8: | |
465 return vf_next_query_format(vf,fmt); | |
466 } | |
467 return 0; | |
468 } | |
469 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
470 static int control(struct vf_instance *vf, int request, void* data){ |
21060 | 471 switch (request){ |
472 case VFCTRL_GET_DEINTERLACE: | |
473 *(int*)data = vf->priv->do_deinterlace; | |
474 return CONTROL_OK; | |
475 case VFCTRL_SET_DEINTERLACE: | |
22116 | 476 vf->priv->do_deinterlace = 2*!!*(int*)data; |
21060 | 477 return CONTROL_OK; |
478 } | |
479 return vf_next_control (vf, request, data); | |
480 } | |
481 | |
30638
a7b908875c14
Rename open() vf initialization function to vf_open().
diego
parents:
29087
diff
changeset
|
482 static int vf_open(vf_instance_t *vf, char *args){ |
18608 | 483 |
484 vf->config=config; | |
485 vf->put_image=put_image; | |
486 vf->query_format=query_format; | |
487 vf->uninit=uninit; | |
488 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
21060 | 489 vf->control=control; |
18608 | 490 memset(vf->priv, 0, sizeof(struct vf_priv_s)); |
491 | |
492 vf->priv->mode=0; | |
493 vf->priv->parity= -1; | |
21060 | 494 vf->priv->do_deinterlace=1; |
18608 | 495 |
496 if (args) sscanf(args, "%d:%d", &vf->priv->mode, &vf->priv->parity); | |
497 | |
19830 | 498 filter_line = filter_line_c; |
28292
d6001126678f
More #ifdef HAVE_MMX etc. missed by earlier search.
reimar
parents:
28174
diff
changeset
|
499 #if HAVE_MMX && defined(NAMED_ASM_ARGS) |
19830 | 500 if(gCpuCaps.hasMMX2) filter_line = filter_line_mmx2; |
501 #endif | |
502 | |
18608 | 503 return 1; |
504 } | |
505 | |
25221 | 506 const vf_info_t vf_info_yadif = { |
18608 | 507 "Yet Another DeInterlacing Filter", |
508 "yadif", | |
509 "Michael Niedermayer", | |
510 "", | |
30638
a7b908875c14
Rename open() vf initialization function to vf_open().
diego
parents:
29087
diff
changeset
|
511 vf_open, |
18608 | 512 NULL |
513 }; |