Mercurial > mplayer.hg
comparison libmpcodecs/vf_ilpack.c @ 9933:3548701a13fe
1. new alternate approach to inverse telecine! much better!
2. interlaced 4:2:0 planar to 4:2:2 packer. makes it possible to watch
interlaced movies without horrible chroma artifacts, provided you have
an interlaced display device.
author | rfelker |
---|---|
date | Sat, 19 Apr 2003 01:39:37 +0000 |
parents | |
children | 3ddfe9316ca9 |
comparison
equal
deleted
inserted
replaced
9932:208fcee0aa2d | 9933:3548701a13fe |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <inttypes.h> | |
5 | |
6 #include "../config.h" | |
7 #include "../mp_msg.h" | |
8 #include "../cpudetect.h" | |
9 | |
10 #include "img_format.h" | |
11 #include "mp_image.h" | |
12 #include "vf.h" | |
13 | |
14 #include "../libvo/fastmemcpy.h" | |
15 #include "../postproc/rgb2rgb.h" | |
16 | |
17 #ifdef HAVE_MMX | |
18 static void pack_MMX(unsigned char *dst, unsigned char *y, | |
19 unsigned char *u, unsigned char *v, int w) | |
20 { | |
21 int j; | |
22 asm ("" | |
23 "pxor %%mm0, %%mm0 \n\t" | |
24 ".balign 16 \n\t" | |
25 "1: \n\t" | |
26 "movq (%0), %%mm1 \n\t" | |
27 "movq (%0), %%mm2 \n\t" | |
28 "punpcklbw %%mm0, %%mm1 \n\t" | |
29 "punpckhbw %%mm0, %%mm2 \n\t" | |
30 | |
31 "movq (%1), %%mm3 \n\t" | |
32 "movq (%2), %%mm5 \n\t" | |
33 "punpcklbw %%mm0, %%mm3 \n\t" | |
34 "punpcklbw %%mm0, %%mm5 \n\t" | |
35 "movq %%mm3, %%mm4 \n\t" | |
36 "movq %%mm5, %%mm6 \n\t" | |
37 "punpcklwd %%mm0, %%mm3 \n\t" | |
38 "punpckhwd %%mm0, %%mm4 \n\t" | |
39 "punpcklwd %%mm0, %%mm5 \n\t" | |
40 "punpckhwd %%mm0, %%mm6 \n\t" | |
41 "pslld $8, %%mm3 \n\t" | |
42 "pslld $8, %%mm4 \n\t" | |
43 "pslld $24, %%mm5 \n\t" | |
44 "pslld $24, %%mm6 \n\t" | |
45 | |
46 "por %%mm3, %%mm1 \n\t" | |
47 "por %%mm4, %%mm2 \n\t" | |
48 "por %%mm5, %%mm1 \n\t" | |
49 "por %%mm6, %%mm2 \n\t" | |
50 | |
51 "addl $8, %0 \n\t" | |
52 "addl $4, %1 \n\t" | |
53 "addl $4, %2 \n\t" | |
54 "movq %%mm1, (%3) \n\t" | |
55 "movq %%mm2, 8(%3) \n\t" | |
56 "addl $16, %3 \n\t" | |
57 "decl %4 \n\t" | |
58 "jnz 1b \n\t" | |
59 : | |
60 : "r" (y), "r" (u), "r" (v), "r" (dst), "r" (w/8) | |
61 : "memory" | |
62 ); | |
63 for (j = (w&7)/2; j; j--) { | |
64 *dst++ = *y++; | |
65 *dst++ = *u++; | |
66 *dst++ = *y++; | |
67 *dst++ = *v++; | |
68 } | |
69 asm volatile ( "emms \n\t" ::: "memory" ); | |
70 } | |
71 #endif | |
72 | |
73 static void pack_C(unsigned char *dst, unsigned char *y, | |
74 unsigned char *u, unsigned char *v, int w) | |
75 { | |
76 int j; | |
77 for (j = w/2; j; j--) { | |
78 *dst++ = *y++; | |
79 *dst++ = *u++; | |
80 *dst++ = *y++; | |
81 *dst++ = *v++; | |
82 } | |
83 } | |
84 | |
85 static void (*pack)(unsigned char *dst, unsigned char *y, | |
86 unsigned char *u, unsigned char *v, int w); | |
87 | |
88 static void ilpack(unsigned char *dst, unsigned char *src[3], | |
89 unsigned int dststride, unsigned int srcstride[3], int w, int h) | |
90 { | |
91 int i; | |
92 unsigned char *y, *u, *v; | |
93 | |
94 y = src[0]; | |
95 u = src[1]; | |
96 v = src[2]; | |
97 | |
98 for (i=0; i<h; i++) { | |
99 pack(dst, y, u, v, w); | |
100 y += srcstride[0]; | |
101 if ((i&3) == 1) { | |
102 u -= srcstride[1]; | |
103 v -= srcstride[2]; | |
104 } else { | |
105 u += srcstride[1]; | |
106 v += srcstride[2]; | |
107 } | |
108 dst += dststride; | |
109 } | |
110 } | |
111 | |
112 | |
113 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi) | |
114 { | |
115 mp_image_t *dmpi; | |
116 | |
117 // hope we'll get DR buffer: | |
118 dmpi=vf_get_image(vf->next, IMGFMT_YUY2, | |
119 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
120 mpi->w, mpi->h); | |
121 | |
122 ilpack(dmpi->planes[0], mpi->planes, dmpi->stride[0], mpi->stride, mpi->w, mpi->h); | |
123 | |
124 return vf_next_put_image(vf,dmpi); | |
125 } | |
126 | |
127 static int config(struct vf_instance_s* vf, | |
128 int width, int height, int d_width, int d_height, | |
129 unsigned int flags, unsigned int outfmt) | |
130 { | |
131 /* FIXME - also support UYVY output? */ | |
132 return vf_next_config(vf, width, height, d_width, d_height, flags, IMGFMT_YUY2); | |
133 } | |
134 | |
135 | |
136 static int query_format(struct vf_instance_s* vf, unsigned int fmt) | |
137 { | |
138 /* FIXME - really any YUV 4:2:0 input format should work */ | |
139 switch (fmt) { | |
140 case IMGFMT_YV12: | |
141 case IMGFMT_IYUV: | |
142 case IMGFMT_I420: | |
143 return vf_next_query_format(vf,IMGFMT_YUY2); | |
144 } | |
145 return 0; | |
146 } | |
147 | |
148 static int open(vf_instance_t *vf, char* args) | |
149 { | |
150 vf->config=config; | |
151 vf->query_format=query_format; | |
152 vf->put_image=put_image; | |
153 | |
154 pack = pack_C; | |
155 #ifdef HAVE_MMX | |
156 if(gCpuCaps.hasMMX) pack = pack_MMX; | |
157 #endif | |
158 return 1; | |
159 } | |
160 | |
161 vf_info_t vf_info_ilpack = { | |
162 "4:2:0 planar -> 4:2:2 packed reinterlacer", | |
163 "ilpack", | |
164 "Richard Felker", | |
165 "", | |
166 open, | |
167 NULL | |
168 }; | |
169 |