Mercurial > mplayer.hg
annotate libmpcodecs/vf_2xsai.c @ 29491:99eda963d27a
Fix incorrect channel ordering for lavc audio codecs (specifically ffac3,
ffdca, ffflac, ffaac, fftruehd). In the process, adds support for 32-bit
samples.
author | tack |
---|---|
date | Tue, 18 Aug 2009 22:24:36 +0000 |
parents | 0f1b5b68af32 |
children | bbb6ebec87a0 |
rev | line source |
---|---|
7919 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <inttypes.h> | |
5 | |
17012 | 6 #include "config.h" |
7 #include "mp_msg.h" | |
7919 | 8 |
9 #include "img_format.h" | |
10 #include "mp_image.h" | |
11 #include "vf.h" | |
12 | |
13 //===========================================================================// | |
14 | |
24785 | 15 /* FIXME: these all belong in the context, not as globals! */ |
16 | |
25003
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
17 static uint32_t colorMask = 0xF7DEF7DE; |
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
18 static uint32_t lowPixelMask = 0x08210821; |
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
19 static uint32_t qcolorMask = 0xE79CE79C; |
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
20 static uint32_t qlowpixelMask = 0x18631863; |
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
21 static uint32_t redblueMask = 0xF81F; |
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
22 static uint32_t greenMask = 0x7E0; |
7919 | 23 static int PixelsPerMask = 2; |
24 | |
25 #define makecol(r,g,b) (r+(g<<8)+(b<<16)) | |
26 #define makecol_depth(d,r,g,b) (r+(g<<8)+(b<<16)) | |
27 | |
28 int Init_2xSaI(int d) | |
29 { | |
30 | |
31 int minr = 0, ming = 0, minb = 0; | |
32 int i; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
33 |
7919 | 34 // if (d != 15 && d != 16 && d != 24 && d != 32) |
35 // return -1; | |
36 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
37 /* Get lowest color bit */ |
7919 | 38 for (i = 0; i < 255; i++) { |
39 if (!minr) | |
40 minr = makecol(i, 0, 0); | |
41 if (!ming) | |
42 ming = makecol(0, i, 0); | |
43 if (!minb) | |
44 minb = makecol(0, 0, i); | |
45 } | |
46 | |
47 colorMask = (makecol_depth(d, 255, 0, 0) - minr) | (makecol_depth(d, 0, 255, 0) - ming) | (makecol_depth(d, 0, 0, 255) - minb); | |
48 lowPixelMask = minr | ming | minb; | |
49 qcolorMask = (makecol_depth(d, 255, 0, 0) - 3 * minr) | (makecol_depth(d, 0, 255, 0) - 3 * ming) | (makecol_depth(d, 0, 0, 255) - 3 * minb); | |
50 qlowpixelMask = (minr * 3) | (ming * 3) | (minb * 3); | |
51 redblueMask = makecol_depth(d, 255, 0, 255); | |
52 greenMask = makecol_depth(d, 0, 255, 0); | |
53 | |
54 PixelsPerMask = (d <= 16) ? 2 : 1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
55 |
7919 | 56 if (PixelsPerMask == 2) { |
57 colorMask |= (colorMask << 16); | |
58 qcolorMask |= (qcolorMask << 16); | |
59 lowPixelMask |= (lowPixelMask << 16); | |
60 qlowpixelMask |= (qlowpixelMask << 16); | |
61 } | |
62 | |
63 // TRACE("Color Mask: 0x%lX\n", colorMask); | |
64 // TRACE("Low Pixel Mask: 0x%lX\n", lowPixelMask); | |
65 // TRACE("QColor Mask: 0x%lX\n", qcolorMask); | |
66 // TRACE("QLow Pixel Mask: 0x%lX\n", qlowpixelMask); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
67 |
7919 | 68 return 0; |
69 } | |
70 | |
71 | |
72 #define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) | |
73 | |
74 #define INTERPOLATE(A, B) (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask)) | |
75 | |
76 #define Q_INTERPOLATE(A, B, C, D) ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2) \ | |
77 + ((((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2) & qlowpixelMask) | |
78 | |
79 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
80 void Super2xSaI_ex(uint8_t *src, uint32_t src_pitch, |
25003
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
81 uint8_t *dst, uint32_t dst_pitch, |
c79fa5c75d4e
Use proper inttypes.h types instead of broken uint32 etc. defines
reimar
parents:
24863
diff
changeset
|
82 uint32_t width, uint32_t height, int sbpp) { |
7919 | 83 |
84 unsigned int x, y; | |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
85 uint32_t color[16]; |
25669 | 86 unsigned char *src_line[4]; |
7919 | 87 |
88 /* Point to the first 3 lines. */ | |
89 src_line[0] = src; | |
90 src_line[1] = src; | |
91 src_line[2] = src + src_pitch; | |
92 src_line[3] = src + src_pitch * 2; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
93 |
7919 | 94 x = 0, y = 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
95 |
7919 | 96 if (PixelsPerMask == 2) { |
97 unsigned short *sbp; | |
98 sbp = (unsigned short*)src_line[0]; | |
99 color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; | |
100 color[4] = color[0]; color[5] = color[0]; color[6] = *(sbp + 1); color[7] = *(sbp + 2); | |
101 sbp = (unsigned short*)src_line[2]; | |
102 color[8] = *sbp; color[9] = color[8]; color[10] = *(sbp + 1); color[11] = *(sbp + 2); | |
103 sbp = (unsigned short*)src_line[3]; | |
104 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2); | |
105 } | |
106 else { | |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
107 uint32_t *lbp; |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
108 lbp = (uint32_t*)src_line[0]; |
7919 | 109 color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; |
110 color[4] = color[0]; color[5] = color[0]; color[6] = *(lbp + 1); color[7] = *(lbp + 2); | |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
111 lbp = (uint32_t*)src_line[2]; |
7919 | 112 color[8] = *lbp; color[9] = color[8]; color[10] = *(lbp + 1); color[11] = *(lbp + 2); |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
113 lbp = (uint32_t*)src_line[3]; |
7919 | 114 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2); |
115 } | |
116 | |
117 for (y = 0; y < height; y++) { | |
25669 | 118 unsigned char *dst_line[2]; |
7919 | 119 |
120 dst_line[0] = dst + dst_pitch*2*y; | |
121 dst_line[1] = dst + dst_pitch*(2*y+1); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
122 |
7919 | 123 /* Todo: x = width - 2, x = width - 1 */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
124 |
7919 | 125 for (x = 0; x < width; x++) { |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
126 uint32_t product1a, product1b, product2a, product2b; |
7919 | 127 |
128 //--------------------------------------- B0 B1 B2 B3 0 1 2 3 | |
129 // 4 5* 6 S2 -> 4 5* 6 7 | |
130 // 1 2 3 S1 8 9 10 11 | |
131 // A0 A1 A2 A3 12 13 14 15 | |
132 //-------------------------------------- | |
133 if (color[9] == color[6] && color[5] != color[10]) { | |
134 product2b = color[9]; | |
135 product1b = product2b; | |
136 } | |
137 else if (color[5] == color[10] && color[9] != color[6]) { | |
138 product2b = color[5]; | |
139 product1b = product2b; | |
140 } | |
141 else if (color[5] == color[10] && color[9] == color[6]) { | |
142 int r = 0; | |
143 | |
144 r += GET_RESULT(color[6], color[5], color[8], color[13]); | |
145 r += GET_RESULT(color[6], color[5], color[4], color[1]); | |
146 r += GET_RESULT(color[6], color[5], color[14], color[11]); | |
147 r += GET_RESULT(color[6], color[5], color[2], color[7]); | |
148 | |
149 if (r > 0) | |
150 product1b = color[6]; | |
151 else if (r < 0) | |
152 product1b = color[5]; | |
153 else | |
154 product1b = INTERPOLATE(color[5], color[6]); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
155 |
7919 | 156 product2b = product1b; |
157 | |
158 } | |
159 else { | |
160 if (color[6] == color[10] && color[10] == color[13] && color[9] != color[14] && color[10] != color[12]) | |
161 product2b = Q_INTERPOLATE(color[10], color[10], color[10], color[9]); | |
162 else if (color[5] == color[9] && color[9] == color[14] && color[13] != color[10] && color[9] != color[15]) | |
163 product2b = Q_INTERPOLATE(color[9], color[9], color[9], color[10]); | |
164 else | |
165 product2b = INTERPOLATE(color[9], color[10]); | |
166 | |
167 if (color[6] == color[10] && color[6] == color[1] && color[5] != color[2] && color[6] != color[0]) | |
168 product1b = Q_INTERPOLATE(color[6], color[6], color[6], color[5]); | |
169 else if (color[5] == color[9] && color[5] == color[2] && color[1] != color[6] && color[5] != color[3]) | |
170 product1b = Q_INTERPOLATE(color[6], color[5], color[5], color[5]); | |
171 else | |
172 product1b = INTERPOLATE(color[5], color[6]); | |
173 } | |
174 | |
175 if (color[5] == color[10] && color[9] != color[6] && color[4] == color[5] && color[5] != color[14]) | |
176 product2a = INTERPOLATE(color[9], color[5]); | |
177 else if (color[5] == color[8] && color[6] == color[5] && color[4] != color[9] && color[5] != color[12]) | |
178 product2a = INTERPOLATE(color[9], color[5]); | |
179 else | |
180 product2a = color[9]; | |
181 | |
182 if (color[9] == color[6] && color[5] != color[10] && color[8] == color[9] && color[9] != color[2]) | |
183 product1a = INTERPOLATE(color[9], color[5]); | |
184 else if (color[4] == color[9] && color[10] == color[9] && color[8] != color[5] && color[9] != color[0]) | |
185 product1a = INTERPOLATE(color[9], color[5]); | |
186 else | |
187 product1a = color[5]; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
188 |
7919 | 189 if (PixelsPerMask == 2) { |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
190 *((uint32_t *) (&dst_line[0][x * 4])) = product1a | (product1b << 16); |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
191 *((uint32_t *) (&dst_line[1][x * 4])) = product2a | (product2b << 16); |
7919 | 192 } |
193 else { | |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
194 *((uint32_t *) (&dst_line[0][x * 8])) = product1a; |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
195 *((uint32_t *) (&dst_line[0][x * 8 + 4])) = product1b; |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
196 *((uint32_t *) (&dst_line[1][x * 8])) = product2a; |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
197 *((uint32_t *) (&dst_line[1][x * 8 + 4])) = product2b; |
7919 | 198 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
199 |
7919 | 200 /* Move color matrix forward */ |
201 color[0] = color[1]; color[4] = color[5]; color[8] = color[9]; color[12] = color[13]; | |
202 color[1] = color[2]; color[5] = color[6]; color[9] = color[10]; color[13] = color[14]; | |
203 color[2] = color[3]; color[6] = color[7]; color[10] = color[11]; color[14] = color[15]; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
204 |
7919 | 205 if (x < width - 3) { |
206 x += 3; | |
207 if (PixelsPerMask == 2) { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
208 color[3] = *(((unsigned short*)src_line[0]) + x); |
7919 | 209 color[7] = *(((unsigned short*)src_line[1]) + x); |
210 color[11] = *(((unsigned short*)src_line[2]) + x); | |
211 color[15] = *(((unsigned short*)src_line[3]) + x); | |
212 } | |
213 else { | |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
214 color[3] = *(((uint32_t*)src_line[0]) + x); |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
215 color[7] = *(((uint32_t*)src_line[1]) + x); |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
216 color[11] = *(((uint32_t*)src_line[2]) + x); |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
217 color[15] = *(((uint32_t*)src_line[3]) + x); |
7919 | 218 } |
219 x -= 3; | |
220 } | |
221 } | |
222 | |
223 /* We're done with one line, so we shift the source lines up */ | |
224 src_line[0] = src_line[1]; | |
225 src_line[1] = src_line[2]; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
226 src_line[2] = src_line[3]; |
7919 | 227 |
228 /* Read next line */ | |
229 if (y + 3 >= height) | |
230 src_line[3] = src_line[2]; | |
231 else | |
232 src_line[3] = src_line[2] + src_pitch; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
233 |
7919 | 234 /* Then shift the color matrix up */ |
235 if (PixelsPerMask == 2) { | |
236 unsigned short *sbp; | |
237 sbp = (unsigned short*)src_line[0]; | |
238 color[0] = *sbp; color[1] = color[0]; color[2] = *(sbp + 1); color[3] = *(sbp + 2); | |
239 sbp = (unsigned short*)src_line[1]; | |
240 color[4] = *sbp; color[5] = color[4]; color[6] = *(sbp + 1); color[7] = *(sbp + 2); | |
241 sbp = (unsigned short*)src_line[2]; | |
242 color[8] = *sbp; color[9] = color[9]; color[10] = *(sbp + 1); color[11] = *(sbp + 2); | |
243 sbp = (unsigned short*)src_line[3]; | |
244 color[12] = *sbp; color[13] = color[12]; color[14] = *(sbp + 1); color[15] = *(sbp + 2); | |
245 } | |
246 else { | |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
247 uint32_t *lbp; |
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
248 lbp = (uint32_t*)src_line[0]; |
7919 | 249 color[0] = *lbp; color[1] = color[0]; color[2] = *(lbp + 1); color[3] = *(lbp + 2); |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
250 lbp = (uint32_t*)src_line[1]; |
7919 | 251 color[4] = *lbp; color[5] = color[4]; color[6] = *(lbp + 1); color[7] = *(lbp + 2); |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
252 lbp = (uint32_t*)src_line[2]; |
7919 | 253 color[8] = *lbp; color[9] = color[9]; color[10] = *(lbp + 1); color[11] = *(lbp + 2); |
25004
98ca15113cc6
Replace stupid "unsigned long" by the correct uint32_t.
reimar
parents:
25003
diff
changeset
|
254 lbp = (uint32_t*)src_line[3]; |
7919 | 255 color[12] = *lbp; color[13] = color[12]; color[14] = *(lbp + 1); color[15] = *(lbp + 2); |
256 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
257 |
7919 | 258 } // y loop |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
259 |
7919 | 260 } |
261 | |
262 | |
263 //===========================================================================// | |
264 | |
265 static int config(struct vf_instance_s* vf, | |
266 int width, int height, int d_width, int d_height, | |
267 unsigned int flags, unsigned int outfmt){ | |
268 | |
269 Init_2xSaI(outfmt&255); | |
270 | |
271 return vf_next_config(vf,2*width,2*height,2*d_width,2*d_height,flags,outfmt); | |
272 } | |
273 | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17012
diff
changeset
|
274 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ |
7919 | 275 mp_image_t *dmpi; |
276 | |
277 // hope we'll get DR buffer: | |
278 dmpi=vf_get_image(vf->next,mpi->imgfmt, | |
279 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
280 2*mpi->w, 2*mpi->h); | |
281 | |
282 Super2xSaI_ex(mpi->planes[0], mpi->stride[0], | |
283 dmpi->planes[0], dmpi->stride[0], | |
284 mpi->w, mpi->h, mpi->bpp/8); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
25670
diff
changeset
|
285 |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17012
diff
changeset
|
286 return vf_next_put_image(vf,dmpi, pts); |
7919 | 287 } |
288 | |
289 //===========================================================================// | |
290 | |
291 static int query_format(struct vf_instance_s* vf, unsigned int fmt){ | |
292 switch(fmt){ | |
293 // case IMGFMT_BGR15: | |
294 // case IMGFMT_BGR16: | |
295 case IMGFMT_BGR32: | |
296 return vf_next_query_format(vf,fmt); | |
297 } | |
298 return 0; | |
299 } | |
300 | |
301 static int open(vf_instance_t *vf, char* args){ | |
302 vf->config=config; | |
303 vf->put_image=put_image; | |
304 vf->query_format=query_format; | |
305 return 1; | |
306 } | |
307 | |
25221 | 308 const vf_info_t vf_info_2xsai = { |
7919 | 309 "2xSai BGR bitmap 2x scaler", |
310 "2xsai", | |
311 "A'rpi", | |
312 "http://elektron.its.tudelft.nl/~dalikifa/", | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
8123
diff
changeset
|
313 open, |
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
8123
diff
changeset
|
314 NULL |
7919 | 315 }; |
316 | |
317 //===========================================================================// |