Mercurial > mplayer.hg
annotate libmpcodecs/vf_yadif.c @ 32439:2f1ccd169a7f
Improve vd_ffmpeg aspect handling to respect container aspect if possible
(i.e. until the first resolution or aspect change) and to use correct
aspect if only resolution changes but not the pixel aspect.
author | reimar |
---|---|
date | Fri, 22 Oct 2010 17:36:11 +0000 |
parents | 7727a2450505 |
children | b87fb1c5c4e9 |
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" |
18608 | 37 |
38 //===========================================================================// | |
39 | |
40 struct vf_priv_s { | |
41 int mode; | |
42 int parity; | |
18917
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
43 int buffered_i; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
44 int buffered_tff; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
45 double buffered_pts; |
d9a75b26da6c
Add a new video pts tracking mode, enabled by option -correct-pts.
uau
parents:
18657
diff
changeset
|
46 mp_image_t *buffered_mpi; |
18608 | 47 int stride[3]; |
18625 | 48 uint8_t *ref[4][3]; |
21060 | 49 int do_deinterlace; |
18608 | 50 }; |
51 | |
19830 | 52 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); |
53 | |
18608 | 54 static void store_ref(struct vf_priv_s *p, uint8_t *src[3], int src_stride[3], int width, int height){ |
55 int i; | |
56 | |
23458
973e53dc7df5
Do not use fast_memcpy for small size copy, esp. when the size is constant
reimar
parents:
23457
diff
changeset
|
57 memcpy (p->ref[3], p->ref[0], sizeof(uint8_t *)*3); |
18625 | 58 memmove(p->ref[0], p->ref[1], sizeof(uint8_t *)*3*3); |
18608 | 59 |
60 for(i=0; i<3; i++){ | |
61 int is_chroma= !!i; | |
62 | |
18625 | 63 memcpy_pic(p->ref[2][i], src[i], width>>is_chroma, height>>is_chroma, p->stride[i], src_stride[i]); |
18608 | 64 } |
65 } | |
66 | |
28292
d6001126678f
More #ifdef HAVE_MMX etc. missed by earlier search.
reimar
parents:
28174
diff
changeset
|
67 #if HAVE_MMX && defined(NAMED_ASM_ARGS) |
19830 | 68 |
69 #define LOAD4(mem,dst) \ | |
70 "movd "mem", "#dst" \n\t"\ | |
71 "punpcklbw %%mm7, "#dst" \n\t" | |
72 | |
73 #define PABS(tmp,dst) \ | |
74 "pxor "#tmp", "#tmp" \n\t"\ | |
75 "psubw "#dst", "#tmp" \n\t"\ | |
76 "pmaxsw "#tmp", "#dst" \n\t" | |
77 | |
78 #define CHECK(pj,mj) \ | |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
79 "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
|
80 "movq "#mj"(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1-j] */\ |
19830 | 81 "movq %%mm2, %%mm4 \n\t"\ |
82 "movq %%mm2, %%mm5 \n\t"\ | |
83 "pxor %%mm3, %%mm4 \n\t"\ | |
84 "pavgb %%mm3, %%mm5 \n\t"\ | |
85 "pand %[pb1], %%mm4 \n\t"\ | |
86 "psubusb %%mm4, %%mm5 \n\t"\ | |
87 "psrlq $8, %%mm5 \n\t"\ | |
88 "punpcklbw %%mm7, %%mm5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\ | |
89 "movq %%mm2, %%mm4 \n\t"\ | |
90 "psubusb %%mm3, %%mm2 \n\t"\ | |
91 "psubusb %%mm4, %%mm3 \n\t"\ | |
92 "pmaxub %%mm3, %%mm2 \n\t"\ | |
93 "movq %%mm2, %%mm3 \n\t"\ | |
94 "movq %%mm2, %%mm4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\ | |
95 "psrlq $8, %%mm3 \n\t" /* ABS(cur[x-refs +j] - cur[x+refs -j]) */\ | |
96 "psrlq $16, %%mm4 \n\t" /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\ | |
97 "punpcklbw %%mm7, %%mm2 \n\t"\ | |
98 "punpcklbw %%mm7, %%mm3 \n\t"\ | |
99 "punpcklbw %%mm7, %%mm4 \n\t"\ | |
100 "paddw %%mm3, %%mm2 \n\t"\ | |
101 "paddw %%mm4, %%mm2 \n\t" /* score */ | |
102 | |
103 #define CHECK1 \ | |
104 "movq %%mm0, %%mm3 \n\t"\ | |
105 "pcmpgtw %%mm2, %%mm3 \n\t" /* if(score < spatial_score) */\ | |
106 "pminsw %%mm2, %%mm0 \n\t" /* spatial_score= score; */\ | |
107 "movq %%mm3, %%mm6 \n\t"\ | |
108 "pand %%mm3, %%mm5 \n\t"\ | |
109 "pandn %%mm1, %%mm3 \n\t"\ | |
110 "por %%mm5, %%mm3 \n\t"\ | |
111 "movq %%mm3, %%mm1 \n\t" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */ | |
112 | |
113 #define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\ | |
114 hurts both quality and speed, but matches the C version. */\ | |
115 "paddw %[pw1], %%mm6 \n\t"\ | |
116 "psllw $14, %%mm6 \n\t"\ | |
117 "paddsw %%mm6, %%mm2 \n\t"\ | |
118 "movq %%mm0, %%mm3 \n\t"\ | |
119 "pcmpgtw %%mm2, %%mm3 \n\t"\ | |
120 "pminsw %%mm2, %%mm0 \n\t"\ | |
121 "pand %%mm3, %%mm5 \n\t"\ | |
122 "pandn %%mm1, %%mm3 \n\t"\ | |
123 "por %%mm5, %%mm3 \n\t"\ | |
124 "movq %%mm3, %%mm1 \n\t" | |
125 | |
126 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){ | |
127 static const uint64_t pw_1 = 0x0001000100010001ULL; | |
128 static const uint64_t pb_1 = 0x0101010101010101ULL; | |
129 const int mode = p->mode; | |
130 uint64_t tmp0, tmp1, tmp2, tmp3; | |
131 int x; | |
132 | |
133 #define FILTER\ | |
134 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
|
135 __asm__ volatile(\ |
19830 | 136 "pxor %%mm7, %%mm7 \n\t"\ |
137 LOAD4("(%[cur],%[mrefs])", %%mm0) /* c = cur[x-refs] */\ | |
138 LOAD4("(%[cur],%[prefs])", %%mm1) /* e = cur[x+refs] */\ | |
139 LOAD4("(%["prev2"])", %%mm2) /* prev2[x] */\ | |
140 LOAD4("(%["next2"])", %%mm3) /* next2[x] */\ | |
141 "movq %%mm3, %%mm4 \n\t"\ | |
142 "paddw %%mm2, %%mm3 \n\t"\ | |
143 "psraw $1, %%mm3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\ | |
144 "movq %%mm0, %[tmp0] \n\t" /* c */\ | |
145 "movq %%mm3, %[tmp1] \n\t" /* d */\ | |
146 "movq %%mm1, %[tmp2] \n\t" /* e */\ | |
147 "psubw %%mm4, %%mm2 \n\t"\ | |
148 PABS( %%mm4, %%mm2) /* temporal_diff0 */\ | |
149 LOAD4("(%[prev],%[mrefs])", %%mm3) /* prev[x-refs] */\ | |
150 LOAD4("(%[prev],%[prefs])", %%mm4) /* prev[x+refs] */\ | |
151 "psubw %%mm0, %%mm3 \n\t"\ | |
152 "psubw %%mm1, %%mm4 \n\t"\ | |
153 PABS( %%mm5, %%mm3)\ | |
154 PABS( %%mm5, %%mm4)\ | |
155 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff1 */\ | |
156 "psrlw $1, %%mm2 \n\t"\ | |
157 "psrlw $1, %%mm3 \n\t"\ | |
158 "pmaxsw %%mm3, %%mm2 \n\t"\ | |
159 LOAD4("(%[next],%[mrefs])", %%mm3) /* next[x-refs] */\ | |
160 LOAD4("(%[next],%[prefs])", %%mm4) /* next[x+refs] */\ | |
161 "psubw %%mm0, %%mm3 \n\t"\ | |
162 "psubw %%mm1, %%mm4 \n\t"\ | |
163 PABS( %%mm5, %%mm3)\ | |
164 PABS( %%mm5, %%mm4)\ | |
165 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff2 */\ | |
166 "psrlw $1, %%mm3 \n\t"\ | |
167 "pmaxsw %%mm3, %%mm2 \n\t"\ | |
168 "movq %%mm2, %[tmp3] \n\t" /* diff */\ | |
169 \ | |
170 "paddw %%mm0, %%mm1 \n\t"\ | |
171 "paddw %%mm0, %%mm0 \n\t"\ | |
172 "psubw %%mm1, %%mm0 \n\t"\ | |
173 "psrlw $1, %%mm1 \n\t" /* spatial_pred */\ | |
174 PABS( %%mm2, %%mm0) /* ABS(c-e) */\ | |
175 \ | |
176 "movq -1(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1] */\ | |
177 "movq -1(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1] */\ | |
178 "movq %%mm2, %%mm4 \n\t"\ | |
179 "psubusb %%mm3, %%mm2 \n\t"\ | |
180 "psubusb %%mm4, %%mm3 \n\t"\ | |
181 "pmaxub %%mm3, %%mm2 \n\t"\ | |
182 "pshufw $9,%%mm2, %%mm3 \n\t"\ | |
183 "punpcklbw %%mm7, %%mm2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\ | |
184 "punpcklbw %%mm7, %%mm3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\ | |
185 "paddw %%mm2, %%mm0 \n\t"\ | |
186 "paddw %%mm3, %%mm0 \n\t"\ | |
187 "psubw %[pw1], %%mm0 \n\t" /* spatial_score */\ | |
188 \ | |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
189 CHECK(-2,0)\ |
19830 | 190 CHECK1\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
191 CHECK(-3,1)\ |
19830 | 192 CHECK2\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
193 CHECK(0,-2)\ |
19830 | 194 CHECK1\ |
20010
5ae0a24fbed8
Compile fix for odd versions of binutils, namely the ones in Fedora.
gpoirier
parents:
19942
diff
changeset
|
195 CHECK(1,-3)\ |
19830 | 196 CHECK2\ |
197 \ | |
198 /* if(p->mode<2) ... */\ | |
199 "movq %[tmp3], %%mm6 \n\t" /* diff */\ | |
32351
7727a2450505
yadif: Explicit wordlength for compare. Fixes compile with clang.
cehoyos
parents:
31978
diff
changeset
|
200 "cmpl $2, %[mode] \n\t"\ |
19830 | 201 "jge 1f \n\t"\ |
202 LOAD4("(%["prev2"],%[mrefs],2)", %%mm2) /* prev2[x-2*refs] */\ | |
203 LOAD4("(%["next2"],%[mrefs],2)", %%mm4) /* next2[x-2*refs] */\ | |
204 LOAD4("(%["prev2"],%[prefs],2)", %%mm3) /* prev2[x+2*refs] */\ | |
205 LOAD4("(%["next2"],%[prefs],2)", %%mm5) /* next2[x+2*refs] */\ | |
206 "paddw %%mm4, %%mm2 \n\t"\ | |
207 "paddw %%mm5, %%mm3 \n\t"\ | |
208 "psrlw $1, %%mm2 \n\t" /* b */\ | |
209 "psrlw $1, %%mm3 \n\t" /* f */\ | |
210 "movq %[tmp0], %%mm4 \n\t" /* c */\ | |
211 "movq %[tmp1], %%mm5 \n\t" /* d */\ | |
212 "movq %[tmp2], %%mm7 \n\t" /* e */\ | |
213 "psubw %%mm4, %%mm2 \n\t" /* b-c */\ | |
214 "psubw %%mm7, %%mm3 \n\t" /* f-e */\ | |
215 "movq %%mm5, %%mm0 \n\t"\ | |
216 "psubw %%mm4, %%mm5 \n\t" /* d-c */\ | |
217 "psubw %%mm7, %%mm0 \n\t" /* d-e */\ | |
218 "movq %%mm2, %%mm4 \n\t"\ | |
219 "pminsw %%mm3, %%mm2 \n\t"\ | |
220 "pmaxsw %%mm4, %%mm3 \n\t"\ | |
221 "pmaxsw %%mm5, %%mm2 \n\t"\ | |
222 "pminsw %%mm5, %%mm3 \n\t"\ | |
223 "pmaxsw %%mm0, %%mm2 \n\t" /* max */\ | |
224 "pminsw %%mm0, %%mm3 \n\t" /* min */\ | |
225 "pxor %%mm4, %%mm4 \n\t"\ | |
226 "pmaxsw %%mm3, %%mm6 \n\t"\ | |
227 "psubw %%mm2, %%mm4 \n\t" /* -max */\ | |
228 "pmaxsw %%mm4, %%mm6 \n\t" /* diff= MAX3(diff, min, -max); */\ | |
229 "1: \n\t"\ | |
230 \ | |
231 "movq %[tmp1], %%mm2 \n\t" /* d */\ | |
232 "movq %%mm2, %%mm3 \n\t"\ | |
233 "psubw %%mm6, %%mm2 \n\t" /* d-diff */\ | |
234 "paddw %%mm6, %%mm3 \n\t" /* d+diff */\ | |
235 "pmaxsw %%mm2, %%mm1 \n\t"\ | |
236 "pminsw %%mm3, %%mm1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\ | |
237 "packuswb %%mm1, %%mm1 \n\t"\ | |
238 \ | |
239 :[tmp0]"=m"(tmp0),\ | |
240 [tmp1]"=m"(tmp1),\ | |
241 [tmp2]"=m"(tmp2),\ | |
242 [tmp3]"=m"(tmp3)\ | |
243 :[prev] "r"(prev),\ | |
244 [cur] "r"(cur),\ | |
245 [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
|
246 [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
|
247 [mrefs]"r"((x86_reg)-refs),\ |
19830 | 248 [pw1] "m"(pw_1),\ |
249 [pb1] "m"(pb_1),\ | |
250 [mode] "g"(mode)\ | |
251 );\ | |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
26727
diff
changeset
|
252 __asm__ volatile("movd %%mm1, %0" :"=m"(*dst));\ |
19830 | 253 dst += 4;\ |
254 prev+= 4;\ | |
255 cur += 4;\ | |
256 next+= 4;\ | |
257 } | |
258 | |
259 if(parity){ | |
260 #define prev2 "prev" | |
261 #define next2 "cur" | |
262 FILTER | |
263 #undef prev2 | |
264 #undef next2 | |
265 }else{ | |
266 #define prev2 "cur" | |
267 #define next2 "next" | |
268 FILTER | |
269 #undef prev2 | |
270 #undef next2 | |
271 } | |
272 } | |
273 #undef LOAD4 | |
274 #undef PABS | |
275 #undef CHECK | |
276 #undef CHECK1 | |
277 #undef CHECK2 | |
278 #undef FILTER | |
279 | |
28292
d6001126678f
More #ifdef HAVE_MMX etc. missed by earlier search.
reimar
parents:
28174
diff
changeset
|
280 #endif /* HAVE_MMX && defined(NAMED_ASM_ARGS) */ |
19830 | 281 |
282 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 | 283 int x; |
284 uint8_t *prev2= parity ? prev : cur ; | |
285 uint8_t *next2= parity ? cur : next; | |
19829 | 286 for(x=0; x<w; x++){ |
287 int c= cur[-refs]; | |
288 int d= (prev2[0] + next2[0])>>1; | |
289 int e= cur[+refs]; | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
290 int temporal_diff0= FFABS(prev2[0] - next2[0]); |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
291 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
|
292 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
|
293 int diff= FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2); |
19829 | 294 int spatial_pred= (c+e)>>1; |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
295 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
|
296 + FFABS(cur[-refs+1] - cur[+refs+1]) - 1; |
18621 | 297 |
18657 | 298 #define CHECK(j)\ |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
299 { 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
|
300 + FFABS(cur[-refs +j] - cur[+refs -j])\ |
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
301 + FFABS(cur[-refs+1+j] - cur[+refs+1-j]);\ |
18657 | 302 if(score < spatial_score){\ |
303 spatial_score= score;\ | |
304 spatial_pred= (cur[-refs +j] + cur[+refs -j])>>1;\ | |
18608 | 305 |
19829 | 306 CHECK(-1) CHECK(-2) }} }} |
307 CHECK( 1) CHECK( 2) }} }} | |
18657 | 308 |
19829 | 309 if(p->mode<2){ |
310 int b= (prev2[-2*refs] + next2[-2*refs])>>1; | |
311 int f= (prev2[+2*refs] + next2[+2*refs])>>1; | |
18608 | 312 #if 0 |
19829 | 313 int a= cur[-3*refs]; |
314 int g= cur[+3*refs]; | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
315 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
|
316 int min= FFMIN3(d-e, d-c, FFMAX3(FFMIN(b-c,f-e),FFMIN(b-c,b-a),FFMIN(f-g,f-e)) ); |
18608 | 317 #else |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
318 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
|
319 int min= FFMIN3(d-e, d-c, FFMAX(b-c, f-e)); |
18608 | 320 #endif |
321 | |
27844
ad60e4aee053
Use libavutil FFMIN etc. instead of defining our own variants.
reimar
parents:
27754
diff
changeset
|
322 diff= FFMAX3(diff, min, -max); |
19829 | 323 } |
18608 | 324 |
19829 | 325 if(spatial_pred > d + diff) |
326 spatial_pred = d + diff; | |
327 else if(spatial_pred < d - diff) | |
328 spatial_pred = d - diff; | |
19828 | 329 |
19829 | 330 dst[0] = spatial_pred; |
19828 | 331 |
19829 | 332 dst++; |
333 cur++; | |
334 prev++; | |
335 next++; | |
336 prev2++; | |
337 next2++; | |
338 } | |
19828 | 339 } |
18608 | 340 |
19828 | 341 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
|
342 int y, i; |
19828 | 343 |
344 for(i=0; i<3; i++){ | |
345 int is_chroma= !!i; | |
346 int w= width >>is_chroma; | |
347 int h= height>>is_chroma; | |
348 int refs= p->stride[i]; | |
349 | |
350 for(y=0; y<h; y++){ | |
351 if((y ^ parity) & 1){ | |
352 uint8_t *prev= &p->ref[0][i][y*refs]; | |
353 uint8_t *cur = &p->ref[1][i][y*refs]; | |
354 uint8_t *next= &p->ref[2][i][y*refs]; | |
355 uint8_t *dst2= &dst[i][y*dst_stride[i]]; | |
356 filter_line(p, dst2, prev, cur, next, w, refs, parity ^ tff); | |
18608 | 357 }else{ |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23381
diff
changeset
|
358 fast_memcpy(&dst[i][y*dst_stride[i]], &p->ref[1][i][y*refs], w); |
18608 | 359 } |
360 } | |
361 } | |
28292
d6001126678f
More #ifdef HAVE_MMX etc. missed by earlier search.
reimar
parents:
28174
diff
changeset
|
362 #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
|
363 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
|
364 #endif |
18608 | 365 } |
366 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
367 static int config(struct vf_instance *vf, |
18608 | 368 int width, int height, int d_width, int d_height, |
369 unsigned int flags, unsigned int outfmt){ | |
18625 | 370 int i, j; |
18608 | 371 |
372 for(i=0; i<3; i++){ | |
373 int is_chroma= !!i; | |
18625 | 374 int w= ((width + 31) & (~31))>>is_chroma; |
375 int h= ((height+6+ 31) & (~31))>>is_chroma; | |
18608 | 376 |
377 vf->priv->stride[i]= w; | |
18625 | 378 for(j=0; j<3; j++) |
379 vf->priv->ref[j][i]= malloc(w*h*sizeof(uint8_t))+3*w; | |
18608 | 380 } |
381 | |
382 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
383 } | |
384 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
385 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
|
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 }; |