Mercurial > mplayer.hg
annotate libmpcodecs/vf_tfields.c @ 10036:1dfe4dab4a42
Implemented some default values. The corresponding Kax elements are not stored if they are set to their default value.
author | mosu |
---|---|
date | Wed, 30 Apr 2003 20:20:51 +0000 |
parents | 9829b7e61b55 |
children | 765c2276aa0c |
rev | line source |
---|---|
9514 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 | |
5 #include "../config.h" | |
6 #include "../mp_msg.h" | |
10020 | 7 #include "../cpudetect.h" |
9514 | 8 |
9 #include "img_format.h" | |
10 #include "mp_image.h" | |
11 #include "vf.h" | |
12 | |
13 #include "../libvo/fastmemcpy.h" | |
14 | |
15 struct vf_priv_s { | |
16 int mode; | |
17 }; | |
18 | |
19 static inline void *my_memcpy_pic(void * dst, void * src, int bytesPerLine, int height, int dstStride, int srcStride) | |
20 { | |
21 int i; | |
22 void *retval=dst; | |
23 | |
24 for(i=0; i<height; i++) | |
25 { | |
26 memcpy(dst, src, bytesPerLine); | |
27 src+= srcStride; | |
28 dst+= dstStride; | |
29 } | |
30 | |
31 return retval; | |
32 } | |
33 | |
34 static void deint(unsigned char *dest, int ds, unsigned char *src, int ss, int w, int h, int field) | |
35 { | |
36 int x, y; | |
37 src += ss; | |
38 dest += ds; | |
39 if (field) { | |
40 src += ss; | |
41 dest += ds; | |
42 h -= 2; | |
43 } | |
44 for (y=h/2; y; y--) { | |
45 for (x=0; x<w; x++) { | |
46 if (((src[x-ss] < src[x]) && (src[x+ss] < src[x])) || | |
47 ((src[x-ss] > src[x]) && (src[x+ss] > src[x]))) { | |
48 //dest[x] = (src[x+ss] + src[x-ss])>>1; | |
49 dest[x] = ((src[x+ss]<<1) + (src[x-ss]<<1) | |
50 + src[x+ss+1] + src[x-ss+1] | |
51 + src[x+ss-1] + src[x-ss-1])>>3; | |
52 } | |
53 else dest[x] = src[x]; | |
54 } | |
55 dest += ds<<1; | |
56 src += ss<<1; | |
57 } | |
58 } | |
59 | |
10020 | 60 #ifdef HAVE_3DNOW |
61 static void qpel_3DNOW(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
62 { |
10020 | 63 int i, j, ssd=ss; |
64 int crap1, crap2; | |
65 if (up) { | |
66 ssd = -ss; | |
67 memcpy(d, s, w); | |
68 d += ds; | |
69 s += ss; | |
70 } | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
71 for (i=h-1; i; i--) { |
10020 | 72 asm( |
73 "pxor %%mm7, %%mm7 \n\t" | |
74 "1: \n\t" | |
75 "movq (%%esi), %%mm0 \n\t" | |
76 "movq (%%esi,%%eax), %%mm1 \n\t" | |
77 "pavgusb %%mm0, %%mm1 \n\t" | |
78 "addl $8, %%esi \n\t" | |
79 "pavgusb %%mm0, %%mm1 \n\t" | |
80 "movq %%mm1, (%%edi) \n\t" | |
81 "addl $8, %%edi \n\t" | |
82 "decl %%ecx \n\t" | |
83 "jnz 1b \n\t" | |
84 : "=S"(crap1), "=D"(crap2) | |
85 : "c"(w>>3), "S"(s), "D"(d), "a"(ssd) | |
86 ); | |
87 for (j=(w&7); j<w; j++) | |
88 d[j] = (s[j+ssd] + 3*s[j])>>2; | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
89 d += ds; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
90 s += ss; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
91 } |
10020 | 92 if (!up) memcpy(d, s, w); |
93 asm volatile("emms \n\t" : : : "memory"); | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
94 } |
10020 | 95 #endif |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
96 |
10020 | 97 #ifdef HAVE_MMX2 |
98 static void qpel_MMX2(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
99 { |
10020 | 100 int i, j, ssd=ss; |
101 int crap1, crap2; | |
102 if (up) { | |
103 ssd = -ss; | |
104 memcpy(d, s, w); | |
105 d += ds; | |
106 s += ss; | |
107 } | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
108 for (i=h-1; i; i--) { |
10020 | 109 asm( |
110 "pxor %%mm7, %%mm7 \n\t" | |
111 "1: \n\t" | |
112 "movq (%%esi), %%mm0 \n\t" | |
113 "movq (%%esi,%%eax), %%mm1 \n\t" | |
114 "pavgb %%mm0, %%mm1 \n\t" | |
115 "addl $8, %%esi \n\t" | |
116 "pavgb %%mm0, %%mm1 \n\t" | |
117 "movq %%mm1, (%%edi) \n\t" | |
118 "addl $8, %%edi \n\t" | |
119 "decl %%ecx \n\t" | |
120 "jnz 1b \n\t" | |
121 : "=S"(crap1), "=D"(crap2) | |
122 : "c"(w>>3), "S"(s), "D"(d), "a"(ssd) | |
123 ); | |
124 for (j=(w&7); j<w; j++) | |
125 d[j] = (s[j+ssd] + 3*s[j])>>2; | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
126 d += ds; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
127 s += ss; |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
128 } |
10020 | 129 if (!up) memcpy(d, s, w); |
130 asm volatile("emms \n\t" : : : "memory"); | |
131 } | |
132 #endif | |
133 | |
134 #ifdef HAVE_MMX | |
135 static void qpel_MMX(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) | |
136 { | |
137 int i, j, ssd=ss; | |
138 int crap1, crap2; | |
139 if (up) { | |
140 ssd = -ss; | |
141 memcpy(d, s, w); | |
142 d += ds; | |
143 s += ss; | |
144 } | |
145 for (i=h-1; i; i--) { | |
146 asm( | |
147 "pxor %%mm7, %%mm7 \n\t" | |
148 "1: \n\t" | |
149 "movq (%%esi), %%mm0 \n\t" | |
150 "movq (%%esi), %%mm1 \n\t" | |
151 "movq (%%esi,%%eax), %%mm2 \n\t" | |
152 "movq (%%esi,%%eax), %%mm3 \n\t" | |
153 "addl $8, %%esi \n\t" | |
154 "punpcklbw %%mm7, %%mm0 \n\t" | |
155 "punpckhbw %%mm7, %%mm1 \n\t" | |
156 "punpcklbw %%mm7, %%mm2 \n\t" | |
157 "punpckhbw %%mm7, %%mm3 \n\t" | |
158 "paddw %%mm0, %%mm2 \n\t" | |
159 "paddw %%mm1, %%mm3 \n\t" | |
160 "paddw %%mm0, %%mm2 \n\t" | |
161 "paddw %%mm1, %%mm3 \n\t" | |
162 "paddw %%mm0, %%mm2 \n\t" | |
163 "paddw %%mm1, %%mm3 \n\t" | |
164 "psrlw $2, %%mm2 \n\t" | |
165 "psrlw $2, %%mm3 \n\t" | |
166 "packsswb %%mm3, %%mm2 \n\t" | |
167 "movq %%mm2, (%%edi) \n\t" | |
168 "addl $8, %%edi \n\t" | |
169 "decl %%ecx \n\t" | |
170 "jnz 1b \n\t" | |
171 : "=S"(crap1), "=D"(crap2) | |
172 : "c"(w>>3), "S"(s), "D"(d), "a"(ssd) | |
173 ); | |
174 for (j=(w&7); j<w; j++) | |
175 d[j] = (s[j+ssd] + 3*s[j])>>2; | |
176 d += ds; | |
177 s += ss; | |
178 } | |
179 if (!up) memcpy(d, s, w); | |
180 asm volatile("emms \n\t" : : : "memory"); | |
181 } | |
182 #endif | |
183 | |
184 static void qpel_C(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up) | |
185 { | |
186 int i, j, ssd=ss; | |
187 if (up) { | |
188 ssd = -ss; | |
189 memcpy(d, s, w); | |
190 d += ds; | |
191 s += ss; | |
192 } | |
193 for (i=h-1; i; i--) { | |
194 for (j=0; j<w; j++) | |
195 d[j] = (s[j+ssd] + 3*s[j])>>2; | |
196 d += ds; | |
197 s += ss; | |
198 } | |
199 if (!up) memcpy(d, s, w); | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
200 } |
9514 | 201 |
10020 | 202 static void (*qpel)(unsigned char *d, unsigned char *s, int w, int h, int ds, int ss, int up); |
9514 | 203 |
204 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi) | |
205 { | |
206 int ret; | |
207 mp_image_t *dmpi; | |
208 | |
209 switch (vf->priv->mode) { | |
210 case 0: | |
211 dmpi = vf_get_image(vf->next, mpi->imgfmt, | |
212 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
213 mpi->width, mpi->height/2); | |
214 memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, | |
215 dmpi->stride[0], mpi->stride[0]*2); | |
216 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
217 memcpy_pic(dmpi->planes[1], mpi->planes[1], | |
218 mpi->chroma_width, mpi->chroma_height/2, | |
219 dmpi->stride[1], mpi->stride[1]*2); | |
220 memcpy_pic(dmpi->planes[2], mpi->planes[2], | |
221 mpi->chroma_width, mpi->chroma_height/2, | |
222 dmpi->stride[2], mpi->stride[2]*2); | |
223 } | |
224 ret = vf_next_put_image(vf, dmpi); | |
225 | |
226 memcpy_pic(dmpi->planes[0], mpi->planes[0] + mpi->stride[0], | |
227 mpi->w, mpi->h/2, dmpi->stride[0], mpi->stride[0]*2); | |
228 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
229 memcpy_pic(dmpi->planes[1], mpi->planes[1] + mpi->stride[1], | |
230 mpi->chroma_width, mpi->chroma_height/2, | |
231 dmpi->stride[1], mpi->stride[1]*2); | |
232 memcpy_pic(dmpi->planes[2], mpi->planes[2] + mpi->stride[2], | |
233 mpi->chroma_width, mpi->chroma_height/2, | |
234 dmpi->stride[2], mpi->stride[2]*2); | |
235 } | |
236 return vf_next_put_image(vf, dmpi) || ret; | |
237 case 1: | |
238 dmpi = vf_get_image(vf->next, mpi->imgfmt, | |
239 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
240 mpi->width, mpi->height); | |
241 my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, | |
242 dmpi->stride[0]*2, mpi->stride[0]*2); | |
243 deint(dmpi->planes[0], dmpi->stride[0], mpi->planes[0], mpi->stride[0], mpi->w, mpi->h, 0); | |
244 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
245 my_memcpy_pic(dmpi->planes[1], mpi->planes[1], | |
246 mpi->chroma_width, mpi->chroma_height/2, | |
247 dmpi->stride[1]*2, mpi->stride[1]*2); | |
248 my_memcpy_pic(dmpi->planes[2], mpi->planes[2], | |
249 mpi->chroma_width, mpi->chroma_height/2, | |
250 dmpi->stride[2]*2, mpi->stride[2]*2); | |
251 deint(dmpi->planes[1], dmpi->stride[1], mpi->planes[1], mpi->stride[1], | |
252 mpi->chroma_width, mpi->chroma_height, 0); | |
253 deint(dmpi->planes[2], dmpi->stride[2], mpi->planes[2], mpi->stride[2], | |
254 mpi->chroma_width, mpi->chroma_height, 0); | |
255 } | |
256 ret = vf_next_put_image(vf, dmpi); | |
257 | |
258 my_memcpy_pic(dmpi->planes[0] + dmpi->stride[0], mpi->planes[0] + mpi->stride[0], | |
259 mpi->w, mpi->h/2, dmpi->stride[0]*2, mpi->stride[0]*2); | |
260 deint(dmpi->planes[0], dmpi->stride[0], mpi->planes[0], mpi->stride[0], mpi->w, mpi->h, 1); | |
261 if (mpi->flags & MP_IMGFLAG_PLANAR) { | |
262 my_memcpy_pic(dmpi->planes[1] + dmpi->stride[1], mpi->planes[1] + mpi->stride[1], | |
263 mpi->chroma_width, mpi->chroma_height/2, | |
264 dmpi->stride[1]*2, mpi->stride[1]*2); | |
265 my_memcpy_pic(dmpi->planes[2] + dmpi->stride[2], mpi->planes[2] + mpi->stride[2], | |
266 mpi->chroma_width, mpi->chroma_height/2, | |
267 dmpi->stride[2]*2, mpi->stride[2]*2); | |
268 deint(dmpi->planes[1], dmpi->stride[1], mpi->planes[1], mpi->stride[1], | |
269 mpi->chroma_width, mpi->chroma_height, 1); | |
270 deint(dmpi->planes[2], dmpi->stride[2], mpi->planes[2], mpi->stride[2], | |
271 mpi->chroma_width, mpi->chroma_height, 1); | |
272 } | |
273 return vf_next_put_image(vf, dmpi) || ret; | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
274 case 2: |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
275 dmpi = vf_get_image(vf->next, mpi->imgfmt, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
276 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
277 mpi->width, mpi->height/2); |
10020 | 278 qpel(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2, |
279 dmpi->stride[0], mpi->stride[0]*2, 0); | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
280 if (mpi->flags & MP_IMGFLAG_PLANAR) { |
10020 | 281 qpel(dmpi->planes[1], mpi->planes[1], |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
282 mpi->chroma_width, mpi->chroma_height/2, |
10020 | 283 dmpi->stride[1], mpi->stride[1]*2, 0); |
284 qpel(dmpi->planes[2], mpi->planes[2], | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
285 mpi->chroma_width, mpi->chroma_height/2, |
10020 | 286 dmpi->stride[2], mpi->stride[2]*2, 0); |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
287 } |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
288 ret = vf_next_put_image(vf, dmpi); |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
289 |
10020 | 290 qpel(dmpi->planes[0], mpi->planes[0] + mpi->stride[0], |
291 mpi->w, mpi->h/2, dmpi->stride[0], mpi->stride[0]*2, 1); | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
292 if (mpi->flags & MP_IMGFLAG_PLANAR) { |
10020 | 293 qpel(dmpi->planes[1], mpi->planes[1] + mpi->stride[1], |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
294 mpi->chroma_width, mpi->chroma_height/2, |
10020 | 295 dmpi->stride[1], mpi->stride[1]*2, 1); |
296 qpel(dmpi->planes[2], mpi->planes[2] + mpi->stride[2], | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
297 mpi->chroma_width, mpi->chroma_height/2, |
10020 | 298 dmpi->stride[2], mpi->stride[2]*2, 1); |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
299 } |
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
300 return vf_next_put_image(vf, dmpi) || ret; |
9514 | 301 } |
302 return 0; | |
303 } | |
304 | |
305 static int query_format(struct vf_instance_s* vf, unsigned int fmt) | |
306 { | |
307 /* FIXME - figure out which other formats work */ | |
308 switch (fmt) { | |
309 case IMGFMT_YV12: | |
310 case IMGFMT_IYUV: | |
311 case IMGFMT_I420: | |
312 return vf_next_query_format(vf, fmt); | |
313 } | |
314 return 0; | |
315 } | |
316 | |
317 static int config(struct vf_instance_s* vf, | |
318 int width, int height, int d_width, int d_height, | |
319 unsigned int flags, unsigned int outfmt) | |
320 { | |
321 switch (vf->priv->mode) { | |
322 case 0: | |
10009
69f10d08c3be
new mode for tfields filter -- shifts fields by a quarter-pixel so the
rfelker
parents:
9593
diff
changeset
|
323 case 2: |
9514 | 324 return vf_next_config(vf,width,height/2,d_width,d_height,flags,outfmt); |
325 case 1: | |
326 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
327 } | |
328 return 0; | |
329 } | |
330 | |
331 static void uninit(struct vf_instance_s* vf) | |
332 { | |
333 free(vf->priv); | |
334 } | |
335 | |
336 static int open(vf_instance_t *vf, char* args) | |
337 { | |
338 struct vf_priv_s *p; | |
339 vf->config = config; | |
340 vf->put_image = put_image; | |
341 vf->query_format = query_format; | |
342 vf->uninit = uninit; | |
343 vf->default_reqs = VFCAP_ACCEPT_STRIDE; | |
344 vf->priv = p = calloc(1, sizeof(struct vf_priv_s)); | |
345 vf->priv->mode = 0; | |
346 if (args) sscanf(args, "%d", &vf->priv->mode); | |
10020 | 347 qpel = qpel_C; |
348 #ifdef HAVE_MMX | |
349 if(gCpuCaps.hasMMX) qpel = qpel_MMX; | |
350 #endif | |
351 #ifdef HAVE_MMX2 | |
352 if(gCpuCaps.hasMMX2) qpel = qpel_MMX2; | |
353 #endif | |
354 #ifdef HAVE_3DNOW | |
355 if(gCpuCaps.has3DNow) qpel = qpel_3DNOW; | |
356 #endif | |
9514 | 357 return 1; |
358 } | |
359 | |
360 vf_info_t vf_info_tfields = { | |
361 "temporal field separation", | |
362 "tfields", | |
363 "Rich Felker", | |
364 "", | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9514
diff
changeset
|
365 open, |
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9514
diff
changeset
|
366 NULL |
9514 | 367 }; |
368 | |
369 |