Mercurial > mplayer.hg
annotate libmpcodecs/vf_yadif.c @ 34757:da38eb1e2069
subassconvert: handle "\r\n" line ends
Previously the code converting text subtitles to ASS format converted newline
characters, and only those, to ASS "new line" markup. If the subtitles
contained "\r\n", the "\r" was thus left in the text. In previous libass
versions the "\r" was not visible, but in the current one it produces an empty
box. Improve the conversion to remove the "\r" in that case. Also treat a lone
"\r" as a newline.
Picked from mplayer2/3e0a2705
author | cboesch |
---|---|
date | Sat, 07 Apr 2012 11:17:09 +0000 |
parents | d0135e230f3d |
children | b4ce15212bfc |
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" | |
31978
3525dc14e3dc
Add the proper include instead of declaring the correct_pts variable extern.
diego
parents:
30642
diff
changeset
|
34 #include "libmpdemux/demuxer.h" |
18608 | 35 #include "libvo/fastmemcpy.h" |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
36 #include "libavutil/common.h" |
34198 | 37 #include "libavutil/x86_cpu.h" |
18608 | 38 |
39 //===========================================================================// | |
40 | |
41 struct vf_priv_s { | |
42 int mode; | |
43 int parity; | |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
44 int buffered_i; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
45 int buffered_tff; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
46 double buffered_pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
47 mp_image_t *buffered_mpi; |
18608 | 48 int stride[3]; |
18625 | 49 uint8_t *ref[4][3]; |
21060 | 50 int do_deinterlace; |
18608 | 51 }; |
52 | |
19830 | 53 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); |
54 | |
18608 | 55 static void store_ref(struct vf_priv_s *p, uint8_t *src[3], int src_stride[3], int width, int height){ |
56 int i; | |
57 | |
23458
973e53dc7df5
Do not use fast_memcpy for small size copy, esp. when the size is constant
reimar
parents:
23457
diff
changeset
|
58 memcpy (p->ref[3], p->ref[0], sizeof(uint8_t *)*3); |
18625 | 59 memmove(p->ref[0], p->ref[1], sizeof(uint8_t *)*3*3); |
18608 | 60 |
61 for(i=0; i<3; i++){ | |
62 int is_chroma= !!i; | |
34603 | 63 int pn_width = width >>is_chroma; |
64 int pn_height = height>>is_chroma; | |
18608 | 65 |
34603 | 66 |
67 memcpy_pic(p->ref[2][i], src[i], pn_width, pn_height, p->stride[i], src_stride[i]); | |
68 | |
69 fast_memcpy(p->ref[2][i] + pn_height * p->stride[i], | |
70 src[i] + (pn_height-1)*src_stride[i], pn_width); | |
71 fast_memcpy(p->ref[2][i] + (pn_height+1)* p->stride[i], | |
72 src[i] + (pn_height-1)*src_stride[i], pn_width); | |
73 | |
74 fast_memcpy(p->ref[2][i] - p->stride[i], src[i], pn_width); | |
75 fast_memcpy(p->ref[2][i] - 2*p->stride[i], src[i], pn_width); | |
18608 | 76 } |
77 } | |
78 | |
33702
772268824c8a
configure: Drop check for compiler support of named assembler arguments.
diego
parents:
33333
diff
changeset
|
79 #if HAVE_MMX |
19830 | 80 |
81 #define LOAD4(mem,dst) \ | |
82 "movd "mem", "#dst" \n\t"\ | |
83 "punpcklbw %%mm7, "#dst" \n\t" | |
84 | |
85 #define PABS(tmp,dst) \ | |
86 "pxor "#tmp", "#tmp" \n\t"\ | |
87 "psubw "#dst", "#tmp" \n\t"\ | |
88 "pmaxsw "#tmp", "#dst" \n\t" | |
89 | |
90 #define CHECK(pj,mj) \ | |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
91 "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
|
92 "movq "#mj"(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1-j] */\ |
19830 | 93 "movq %%mm2, %%mm4 \n\t"\ |
94 "movq %%mm2, %%mm5 \n\t"\ | |
95 "pxor %%mm3, %%mm4 \n\t"\ | |
96 "pavgb %%mm3, %%mm5 \n\t"\ | |
97 "pand %[pb1], %%mm4 \n\t"\ | |
98 "psubusb %%mm4, %%mm5 \n\t"\ | |
99 "psrlq $8, %%mm5 \n\t"\ | |
100 "punpcklbw %%mm7, %%mm5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\ | |
101 "movq %%mm2, %%mm4 \n\t"\ | |
102 "psubusb %%mm3, %%mm2 \n\t"\ | |
103 "psubusb %%mm4, %%mm3 \n\t"\ | |
104 "pmaxub %%mm3, %%mm2 \n\t"\ | |
105 "movq %%mm2, %%mm3 \n\t"\ | |
106 "movq %%mm2, %%mm4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\ | |
107 "psrlq $8, %%mm3 \n\t" /* ABS(cur[x-refs +j] - cur[x+refs -j]) */\ | |
108 "psrlq $16, %%mm4 \n\t" /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\ | |
109 "punpcklbw %%mm7, %%mm2 \n\t"\ | |
110 "punpcklbw %%mm7, %%mm3 \n\t"\ | |
111 "punpcklbw %%mm7, %%mm4 \n\t"\ | |
112 "paddw %%mm3, %%mm2 \n\t"\ | |
113 "paddw %%mm4, %%mm2 \n\t" /* score */ | |
114 | |
115 #define CHECK1 \ | |
116 "movq %%mm0, %%mm3 \n\t"\ | |
117 "pcmpgtw %%mm2, %%mm3 \n\t" /* if(score < spatial_score) */\ | |
118 "pminsw %%mm2, %%mm0 \n\t" /* spatial_score= score; */\ | |
119 "movq %%mm3, %%mm6 \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" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */ | |
124 | |
125 #define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\ | |
126 hurts both quality and speed, but matches the C version. */\ | |
127 "paddw %[pw1], %%mm6 \n\t"\ | |
128 "psllw $14, %%mm6 \n\t"\ | |
129 "paddsw %%mm6, %%mm2 \n\t"\ | |
130 "movq %%mm0, %%mm3 \n\t"\ | |
131 "pcmpgtw %%mm2, %%mm3 \n\t"\ | |
132 "pminsw %%mm2, %%mm0 \n\t"\ | |
133 "pand %%mm3, %%mm5 \n\t"\ | |
134 "pandn %%mm1, %%mm3 \n\t"\ | |
135 "por %%mm5, %%mm3 \n\t"\ | |
136 "movq %%mm3, %%mm1 \n\t" | |
137 | |
138 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){ | |
139 static const uint64_t pw_1 = 0x0001000100010001ULL; | |
140 static const uint64_t pb_1 = 0x0101010101010101ULL; | |
141 const int mode = p->mode; | |
142 uint64_t tmp0, tmp1, tmp2, tmp3; | |
143 int x; | |
144 | |
145 #define FILTER\ | |
146 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
|
147 __asm__ volatile(\ |
19830 | 148 "pxor %%mm7, %%mm7 \n\t"\ |
149 LOAD4("(%[cur],%[mrefs])", %%mm0) /* c = cur[x-refs] */\ | |
150 LOAD4("(%[cur],%[prefs])", %%mm1) /* e = cur[x+refs] */\ | |
151 LOAD4("(%["prev2"])", %%mm2) /* prev2[x] */\ | |
152 LOAD4("(%["next2"])", %%mm3) /* next2[x] */\ | |
153 "movq %%mm3, %%mm4 \n\t"\ | |
154 "paddw %%mm2, %%mm3 \n\t"\ | |
155 "psraw $1, %%mm3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\ | |
156 "movq %%mm0, %[tmp0] \n\t" /* c */\ | |
157 "movq %%mm3, %[tmp1] \n\t" /* d */\ | |
158 "movq %%mm1, %[tmp2] \n\t" /* e */\ | |
159 "psubw %%mm4, %%mm2 \n\t"\ | |
160 PABS( %%mm4, %%mm2) /* temporal_diff0 */\ | |
161 LOAD4("(%[prev],%[mrefs])", %%mm3) /* prev[x-refs] */\ | |
162 LOAD4("(%[prev],%[prefs])", %%mm4) /* prev[x+refs] */\ | |
163 "psubw %%mm0, %%mm3 \n\t"\ | |
164 "psubw %%mm1, %%mm4 \n\t"\ | |
165 PABS( %%mm5, %%mm3)\ | |
166 PABS( %%mm5, %%mm4)\ | |
167 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff1 */\ | |
168 "psrlw $1, %%mm2 \n\t"\ | |
169 "psrlw $1, %%mm3 \n\t"\ | |
170 "pmaxsw %%mm3, %%mm2 \n\t"\ | |
171 LOAD4("(%[next],%[mrefs])", %%mm3) /* next[x-refs] */\ | |
172 LOAD4("(%[next],%[prefs])", %%mm4) /* next[x+refs] */\ | |
173 "psubw %%mm0, %%mm3 \n\t"\ | |
174 "psubw %%mm1, %%mm4 \n\t"\ | |
175 PABS( %%mm5, %%mm3)\ | |
176 PABS( %%mm5, %%mm4)\ | |
177 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff2 */\ | |
178 "psrlw $1, %%mm3 \n\t"\ | |
179 "pmaxsw %%mm3, %%mm2 \n\t"\ | |
180 "movq %%mm2, %[tmp3] \n\t" /* diff */\ | |
181 \ | |
182 "paddw %%mm0, %%mm1 \n\t"\ | |
183 "paddw %%mm0, %%mm0 \n\t"\ | |
184 "psubw %%mm1, %%mm0 \n\t"\ | |
185 "psrlw $1, %%mm1 \n\t" /* spatial_pred */\ | |
186 PABS( %%mm2, %%mm0) /* ABS(c-e) */\ | |
187 \ | |
188 "movq -1(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1] */\ | |
189 "movq -1(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1] */\ | |
190 "movq %%mm2, %%mm4 \n\t"\ | |
191 "psubusb %%mm3, %%mm2 \n\t"\ | |
192 "psubusb %%mm4, %%mm3 \n\t"\ | |
193 "pmaxub %%mm3, %%mm2 \n\t"\ | |
194 "pshufw $9,%%mm2, %%mm3 \n\t"\ | |
195 "punpcklbw %%mm7, %%mm2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\ | |
196 "punpcklbw %%mm7, %%mm3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\ | |
197 "paddw %%mm2, %%mm0 \n\t"\ | |
198 "paddw %%mm3, %%mm0 \n\t"\ | |
199 "psubw %[pw1], %%mm0 \n\t" /* spatial_score */\ | |
200 \ | |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
201 CHECK(-2,0)\ |
19830 | 202 CHECK1\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
203 CHECK(-3,1)\ |
19830 | 204 CHECK2\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
205 CHECK(0,-2)\ |
19830 | 206 CHECK1\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
207 CHECK(1,-3)\ |
19830 | 208 CHECK2\ |
209 \ | |
210 /* if(p->mode<2) ... */\ | |
211 "movq %[tmp3], %%mm6 \n\t" /* diff */\ | |
32351
7727a2450505
yadif: Explicit wordlength for compare. Fixes compile with clang.
cehoyos
parents:
31978
diff
changeset
|
212 "cmpl $2, %[mode] \n\t"\ |
19830 | 213 "jge 1f \n\t"\ |
214 LOAD4("(%["prev2"],%[mrefs],2)", %%mm2) /* prev2[x-2*refs] */\ | |
215 LOAD4("(%["next2"],%[mrefs],2)", %%mm4) /* next2[x-2*refs] */\ | |
216 LOAD4("(%["prev2"],%[prefs],2)", %%mm3) /* prev2[x+2*refs] */\ | |
217 LOAD4("(%["next2"],%[prefs],2)", %%mm5) /* next2[x+2*refs] */\ | |
218 "paddw %%mm4, %%mm2 \n\t"\ | |
219 "paddw %%mm5, %%mm3 \n\t"\ | |
220 "psrlw $1, %%mm2 \n\t" /* b */\ | |
221 "psrlw $1, %%mm3 \n\t" /* f */\ | |
222 "movq %[tmp0], %%mm4 \n\t" /* c */\ | |
223 "movq %[tmp1], %%mm5 \n\t" /* d */\ | |
224 "movq %[tmp2], %%mm7 \n\t" /* e */\ | |
225 "psubw %%mm4, %%mm2 \n\t" /* b-c */\ | |
226 "psubw %%mm7, %%mm3 \n\t" /* f-e */\ | |
227 "movq %%mm5, %%mm0 \n\t"\ | |
228 "psubw %%mm4, %%mm5 \n\t" /* d-c */\ | |
229 "psubw %%mm7, %%mm0 \n\t" /* d-e */\ | |
230 "movq %%mm2, %%mm4 \n\t"\ | |
231 "pminsw %%mm3, %%mm2 \n\t"\ | |
232 "pmaxsw %%mm4, %%mm3 \n\t"\ | |
233 "pmaxsw %%mm5, %%mm2 \n\t"\ | |
234 "pminsw %%mm5, %%mm3 \n\t"\ | |
235 "pmaxsw %%mm0, %%mm2 \n\t" /* max */\ | |
236 "pminsw %%mm0, %%mm3 \n\t" /* min */\ | |
237 "pxor %%mm4, %%mm4 \n\t"\ | |
238 "pmaxsw %%mm3, %%mm6 \n\t"\ | |
239 "psubw %%mm2, %%mm4 \n\t" /* -max */\ | |
240 "pmaxsw %%mm4, %%mm6 \n\t" /* diff= MAX3(diff, min, -max); */\ | |
241 "1: \n\t"\ | |
242 \ | |
243 "movq %[tmp1], %%mm2 \n\t" /* d */\ | |
244 "movq %%mm2, %%mm3 \n\t"\ | |
245 "psubw %%mm6, %%mm2 \n\t" /* d-diff */\ | |
246 "paddw %%mm6, %%mm3 \n\t" /* d+diff */\ | |
247 "pmaxsw %%mm2, %%mm1 \n\t"\ | |
248 "pminsw %%mm3, %%mm1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\ | |
249 "packuswb %%mm1, %%mm1 \n\t"\ | |
250 \ | |
251 :[tmp0]"=m"(tmp0),\ | |
252 [tmp1]"=m"(tmp1),\ | |
253 [tmp2]"=m"(tmp2),\ | |
254 [tmp3]"=m"(tmp3)\ | |
255 :[prev] "r"(prev),\ | |
256 [cur] "r"(cur),\ | |
257 [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
|
258 [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
|
259 [mrefs]"r"((x86_reg)-refs),\ |
19830 | 260 [pw1] "m"(pw_1),\ |
261 [pb1] "m"(pb_1),\ | |
262 [mode] "g"(mode)\ | |
263 );\ | |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
26727
diff
changeset
|
264 __asm__ volatile("movd %%mm1, %0" :"=m"(*dst));\ |
19830 | 265 dst += 4;\ |
266 prev+= 4;\ | |
267 cur += 4;\ | |
268 next+= 4;\ | |
269 } | |
270 | |
271 if(parity){ | |
272 #define prev2 "prev" | |
273 #define next2 "cur" | |
274 FILTER | |
275 #undef prev2 | |
276 #undef next2 | |
277 }else{ | |
278 #define prev2 "cur" | |
279 #define next2 "next" | |
280 FILTER | |
281 #undef prev2 | |
282 #undef next2 | |
283 } | |
284 } | |
285 #undef LOAD4 | |
286 #undef PABS | |
287 #undef CHECK | |
288 #undef CHECK1 | |
289 #undef CHECK2 | |
290 #undef FILTER | |
291 | |
33702
772268824c8a
configure: Drop check for compiler support of named assembler arguments.
diego
parents:
33333
diff
changeset
|
292 #endif /* HAVE_MMX */ |
19830 | 293 |
294 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 | 295 int x; |
296 uint8_t *prev2= parity ? prev : cur ; | |
297 uint8_t *next2= parity ? cur : next; | |
19829 | 298 for(x=0; x<w; x++){ |
299 int c= cur[-refs]; | |
300 int d= (prev2[0] + next2[0])>>1; | |
301 int e= cur[+refs]; | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
302 int temporal_diff0= FFABS(prev2[0] - next2[0]); |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
303 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
|
304 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
|
305 int diff= FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); |
19829 | 306 int spatial_pred= (c+e)>>1; |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
307 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
|
308 + FFABS(cur[-refs+1] - cur[+refs+1]) - 1; |
18621 | 309 |
18657 | 310 #define CHECK(j)\ |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
311 { 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
|
312 + FFABS(cur[-refs +j] - cur[+refs -j])\ |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
313 + FFABS(cur[-refs+1+j] - cur[+refs+1-j]);\ |
18657 | 314 if(score < spatial_score){\ |
315 spatial_score= score;\ | |
316 spatial_pred= (cur[-refs +j] + cur[+refs -j])>>1;\ | |
18608 | 317 |
19829 | 318 CHECK(-1) CHECK(-2) }} }} |
319 CHECK( 1) CHECK( 2) }} }} | |
18657 | 320 |
19829 | 321 if(p->mode<2){ |
322 int b= (prev2[-2*refs] + next2[-2*refs])>>1; | |
323 int f= (prev2[+2*refs] + next2[+2*refs])>>1; | |
18608 | 324 #if 0 |
19829 | 325 int a= cur[-3*refs]; |
326 int g= cur[+3*refs]; | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
327 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
|
328 int min= FFMIN3(d-e, d-c, FFMAX3(FFMIN(b-c,f-e),FFMIN(b-c,b-a),FFMIN(f-g,f-e)) ); |
18608 | 329 #else |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
330 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
|
331 int min= FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); |
18608 | 332 #endif |
333 | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
334 diff= FFMAX3(diff, min, -max); |
19829 | 335 } |
18608 | 336 |
19829 | 337 if(spatial_pred > d + diff) |
338 spatial_pred = d + diff; | |
339 else if(spatial_pred < d - diff) | |
340 spatial_pred = d - diff; | |
19828 | 341 |
19829 | 342 dst[0] = spatial_pred; |
19828 | 343 |
19829 | 344 dst++; |
345 cur++; | |
346 prev++; | |
347 next++; | |
348 prev2++; | |
349 next2++; | |
350 } | |
19828 | 351 } |
18608 | 352 |
19828 | 353 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
|
354 int y, i; |
19828 | 355 |
356 for(i=0; i<3; i++){ | |
357 int is_chroma= !!i; | |
358 int w= width >>is_chroma; | |
359 int h= height>>is_chroma; | |
360 int refs= p->stride[i]; | |
361 | |
362 for(y=0; y<h; y++){ | |
363 if((y ^ parity) & 1){ | |
364 uint8_t *prev= &p->ref[0][i][y*refs]; | |
365 uint8_t *cur = &p->ref[1][i][y*refs]; | |
366 uint8_t *next= &p->ref[2][i][y*refs]; | |
367 uint8_t *dst2= &dst[i][y*dst_stride[i]]; | |
368 filter_line(p, dst2, prev, cur, next, w, refs, parity ^ tff); | |
18608 | 369 }else{ |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23381
diff
changeset
|
370 fast_memcpy(&dst[i][y*dst_stride[i]], &p->ref[1][i][y*refs], w); |
18608 | 371 } |
372 } | |
373 } | |
33702
772268824c8a
configure: Drop check for compiler support of named assembler arguments.
diego
parents:
33333
diff
changeset
|
374 #if HAVE_MMX |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
26727
diff
changeset
|
375 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
|
376 #endif |
18608 | 377 } |
378 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
379 static int config(struct vf_instance *vf, |
18608 | 380 int width, int height, int d_width, int d_height, |
381 unsigned int flags, unsigned int outfmt){ | |
18625 | 382 int i, j; |
18608 | 383 |
384 for(i=0; i<3; i++){ | |
385 int is_chroma= !!i; | |
18625 | 386 int w= ((width + 31) & (~31))>>is_chroma; |
34603 | 387 int h=(((height + 1) & ( ~1))>>is_chroma) + 6; |
18608 | 388 |
389 vf->priv->stride[i]= w; | |
18625 | 390 for(j=0; j<3; j++) |
33333
b87fb1c5c4e9
Fix "warning: pointer of type 'void *' used in arithmetic".
reimar
parents:
32351
diff
changeset
|
391 vf->priv->ref[j][i]= (uint8_t *)malloc(w*h*sizeof(uint8_t))+3*w; |
18608 | 392 } |
393 | |
394 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
395 } | |
396 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
397 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
|
398 |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
399 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
|
400 int tff; |
18608 | 401 |
402 if(vf->priv->parity < 0) { | |
403 if (mpi->fields & MP_IMGFIELD_ORDERED) | |
404 tff = !!(mpi->fields & MP_IMGFIELD_TOP_FIRST); | |
405 else | |
406 tff = 1; | |
407 } | |
408 else tff = (vf->priv->parity&1)^1; | |
409 | |
18625 | 410 store_ref(vf->priv, mpi->planes, mpi->stride, mpi->w, mpi->h); |
411 | |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
412 vf->priv->buffered_mpi = mpi; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
413 vf->priv->buffered_tff = tff; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
414 vf->priv->buffered_i = 0; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
415 vf->priv->buffered_pts = pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
416 |
22116 | 417 if(vf->priv->do_deinterlace == 0) |
418 return vf_next_put_image(vf, mpi, pts); | |
419 else if(vf->priv->do_deinterlace == 1){ | |
420 vf->priv->do_deinterlace= 2; | |
421 return 0; | |
422 }else | |
22117 | 423 return continue_buffered_image(vf); |
18917
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 |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
426 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
|
427 { |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
428 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
|
429 int tff = vf->priv->buffered_tff; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
430 double pts = vf->priv->buffered_pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
431 int i; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
432 int ret=0; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
433 mp_image_t *dmpi; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
434 |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
435 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
|
436 |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
437 for(i = vf->priv->buffered_i; i<=(vf->priv->mode&1); i++){ |
18608 | 438 dmpi=vf_get_image(vf->next,mpi->imgfmt, |
439 MP_IMGTYPE_TEMP, | |
440 MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE, | |
441 mpi->width,mpi->height); | |
442 vf_clone_mpi_attributes(dmpi, mpi); | |
18625 | 443 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
|
444 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
|
445 vf_queue_frame(vf, continue_buffered_image); |
18608 | 446 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
|
447 if (correct_pts) |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
448 break; |
18626 | 449 if(i<(vf->priv->mode&1)) |
28174 | 450 vf_extra_flip(vf); |
18608 | 451 } |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
452 vf->priv->buffered_i = 1; |
18608 | 453 return ret; |
454 } | |
455 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
456 static void uninit(struct vf_instance *vf){ |
18608 | 457 int i; |
458 if(!vf->priv) return; | |
459 | |
18625 | 460 for(i=0; i<3*3; i++){ |
461 uint8_t **p= &vf->priv->ref[i%3][i/3]; | |
462 if(*p) free(*p - 3*vf->priv->stride[i/3]); | |
463 *p= NULL; | |
18608 | 464 } |
465 free(vf->priv); | |
466 vf->priv=NULL; | |
467 } | |
468 | |
469 //===========================================================================// | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
470 static int query_format(struct vf_instance *vf, unsigned int fmt){ |
18608 | 471 switch(fmt){ |
472 case IMGFMT_YV12: | |
473 case IMGFMT_I420: | |
474 case IMGFMT_IYUV: | |
475 case IMGFMT_Y800: | |
476 case IMGFMT_Y8: | |
477 return vf_next_query_format(vf,fmt); | |
478 } | |
479 return 0; | |
480 } | |
481 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
482 static int control(struct vf_instance *vf, int request, void* data){ |
21060 | 483 switch (request){ |
484 case VFCTRL_GET_DEINTERLACE: | |
485 *(int*)data = vf->priv->do_deinterlace; | |
486 return CONTROL_OK; | |
487 case VFCTRL_SET_DEINTERLACE: | |
22116 | 488 vf->priv->do_deinterlace = 2*!!*(int*)data; |
21060 | 489 return CONTROL_OK; |
490 } | |
491 return vf_next_control (vf, request, data); | |
492 } | |
493 | |
30638
a7b908875c14
Rename open() vf initialization function to vf_open().
diego
parents:
29087
diff
changeset
|
494 static int vf_open(vf_instance_t *vf, char *args){ |
18608 | 495 |
496 vf->config=config; | |
497 vf->put_image=put_image; | |
498 vf->query_format=query_format; | |
499 vf->uninit=uninit; | |
500 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
21060 | 501 vf->control=control; |
18608 | 502 memset(vf->priv, 0, sizeof(struct vf_priv_s)); |
503 | |
504 vf->priv->mode=0; | |
505 vf->priv->parity= -1; | |
21060 | 506 vf->priv->do_deinterlace=1; |
18608 | 507 |
508 if (args) sscanf(args, "%d:%d", &vf->priv->mode, &vf->priv->parity); | |
509 | |
19830 | 510 filter_line = filter_line_c; |
33702
772268824c8a
configure: Drop check for compiler support of named assembler arguments.
diego
parents:
33333
diff
changeset
|
511 #if HAVE_MMX |
19830 | 512 if(gCpuCaps.hasMMX2) filter_line = filter_line_mmx2; |
513 #endif | |
514 | |
18608 | 515 return 1; |
516 } | |
517 | |
25221 | 518 const vf_info_t vf_info_yadif = { |
18608 | 519 "Yet Another DeInterlacing Filter", |
520 "yadif", | |
521 "Michael Niedermayer", | |
522 "", | |
30638
a7b908875c14
Rename open() vf initialization function to vf_open().
diego
parents:
29087
diff
changeset
|
523 vf_open, |
18608 | 524 NULL |
525 }; |