Mercurial > sdl-ios-xcode
comparison src/video/ps3/spulibs/yuv2rgb_converter.c @ 3144:0d8d1f870964 gsoc2009_ps3
Moved SPE-functions to SDL_ps3spe.c.
Added ActivateRenderer() and PS3_QueryTexturePixels().
Added yuv2rgb_spu but not yet in use.
author | Martin Lowinski <martin@goldtopf.org> |
---|---|
date | Wed, 10 Jun 2009 09:15:33 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3143:8fdabaa064c3 | 3144:0d8d1f870964 |
---|---|
1 /* | |
2 * SDL - Simple DirectMedia Layer | |
3 * CELL BE Support for PS3 Framebuffer | |
4 * Copyright (C) 2008, 2009 International Business Machines Corporation | |
5 * | |
6 * This library is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU Lesser General Public License as published | |
8 * by the Free Software Foundation; either version 2.1 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with this library; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 | |
19 * USA | |
20 * | |
21 * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com> | |
22 * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com> | |
23 * SPE code based on research by: | |
24 * Rene Becker | |
25 * Thimo Emmerich | |
26 */ | |
27 | |
28 #include "spu_common.h" | |
29 | |
30 #include <spu_intrinsics.h> | |
31 #include <spu_mfcio.h> | |
32 | |
33 // Debugging | |
34 //#define DEBUG | |
35 | |
36 #ifdef DEBUG | |
37 #define deprintf(fmt, args... ) \ | |
38 fprintf( stdout, fmt, ##args ); \ | |
39 fflush( stdout ); | |
40 #else | |
41 #define deprintf( fmt, args... ) | |
42 #endif | |
43 | |
44 struct yuv2rgb_parms_t parms_converter __attribute__((aligned(128))); | |
45 | |
46 /* A maximum of 8 lines Y, therefore 4 lines V, 4 lines U are stored | |
47 * there might be the need to retrieve misaligned data, adjust | |
48 * incoming v and u plane to be able to handle this (add 128) | |
49 */ | |
50 unsigned char y_plane[2][(MAX_HDTV_WIDTH + 128) * 4] __attribute__((aligned(128))); | |
51 unsigned char v_plane[2][(MAX_HDTV_WIDTH + 128) * 2] __attribute__((aligned(128))); | |
52 unsigned char u_plane[2][(MAX_HDTV_WIDTH + 128) * 2] __attribute__((aligned(128))); | |
53 | |
54 /* A maximum of 4 lines BGRA are stored, 4 byte per pixel */ | |
55 unsigned char bgra[4 * MAX_HDTV_WIDTH * 4] __attribute__((aligned(128))); | |
56 | |
57 /* some vectors needed by the float to int conversion */ | |
58 static const vector float vec_255 = { 255.0f, 255.0f, 255.0f, 255.0f }; | |
59 static const vector float vec_0_1 = { 0.1f, 0.1f, 0.1f, 0.1f }; | |
60 | |
61 void yuv_to_rgb_w16(); | |
62 void yuv_to_rgb_w32(); | |
63 | |
64 void yuv_to_rgb_w16_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr, unsigned int width); | |
65 void yuv_to_rgb_w32_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr_, unsigned int width); | |
66 | |
67 | |
68 int main(unsigned long long spe_id __attribute__((unused)), unsigned long long argp __attribute__ ((unused))) | |
69 { | |
70 deprintf("[SPU] yuv2rgb_spu is up... (on SPE #%llu)\n", spe_id); | |
71 uint32_t ea_mfc, mbox; | |
72 // send ready message | |
73 spu_write_out_mbox(SPU_READY); | |
74 | |
75 while (1) { | |
76 /* Check mailbox */ | |
77 mbox = spu_read_in_mbox(); | |
78 deprintf("[SPU] Message is %u\n", mbox); | |
79 switch (mbox) { | |
80 case SPU_EXIT: | |
81 deprintf("[SPU] fb_writer goes down...\n"); | |
82 return 0; | |
83 case SPU_START: | |
84 break; | |
85 default: | |
86 deprintf("[SPU] Cannot handle message\n"); | |
87 continue; | |
88 } | |
89 | |
90 /* Tag Manager setup */ | |
91 unsigned int tag_id; | |
92 tag_id = mfc_multi_tag_reserve(1); | |
93 if (tag_id == MFC_TAG_INVALID) { | |
94 deprintf("[SPU] Failed to reserve mfc tags on yuv2rgb_converter\n"); | |
95 return 0; | |
96 } | |
97 | |
98 /* DMA transfer for the input parameters */ | |
99 ea_mfc = spu_read_in_mbox(); | |
100 deprintf("[SPU] Message on yuv2rgb_converter is %u\n", ea_mfc); | |
101 spu_mfcdma32(&parms_converter, (unsigned int)ea_mfc, sizeof(struct yuv2rgb_parms_t), tag_id, MFC_GET_CMD); | |
102 DMA_WAIT_TAG(tag_id); | |
103 | |
104 /* There are alignment issues that involve handling of special cases | |
105 * a width of 32 results in a width of 16 in the chrominance | |
106 * --> choose the proper handling to optimize the performance | |
107 */ | |
108 deprintf("[SPU] Convert %ix%i from YUV to RGB\n", parms_converter.src_pixel_width, parms_converter.src_pixel_height); | |
109 if (parms_converter.src_pixel_width & 0x1f) { | |
110 deprintf("[SPU] Using yuv_to_rgb_w16\n"); | |
111 yuv_to_rgb_w16(); | |
112 } else { | |
113 deprintf("[SPU] Using yuv_to_rgb_w32\n"); | |
114 yuv_to_rgb_w32(); | |
115 } | |
116 | |
117 mfc_multi_tag_release(tag_id, 1); | |
118 deprintf("[SPU] yuv2rgb_spu... done!\n"); | |
119 /* Send FIN message */ | |
120 spu_write_out_mbox(SPU_FIN); | |
121 } | |
122 | |
123 return 0; | |
124 } | |
125 | |
126 | |
127 /* | |
128 * float_to_char() | |
129 * | |
130 * converts a float to a character using saturated | |
131 * arithmetic | |
132 * | |
133 * @param s float for conversion | |
134 * @returns converted character | |
135 */ | |
136 inline static unsigned char float_to_char(float s) { | |
137 vector float vec_s = spu_splats(s); | |
138 vector unsigned int select_1 = spu_cmpgt(vec_0_1, vec_s); | |
139 vec_s = spu_sel(vec_s, vec_0_1, select_1); | |
140 | |
141 vector unsigned int select_2 = spu_cmpgt(vec_s, vec_255); | |
142 vec_s = spu_sel(vec_s, vec_255, select_2); | |
143 return (unsigned char) spu_extract(vec_s,0); | |
144 } | |
145 | |
146 | |
147 /* | |
148 * vfloat_to_vuint() | |
149 * | |
150 * converts a float vector to an unsinged int vector using saturated | |
151 * arithmetic | |
152 * | |
153 * @param vec_s float vector for conversion | |
154 * @returns converted unsigned int vector | |
155 */ | |
156 inline static vector unsigned int vfloat_to_vuint(vector float vec_s) { | |
157 vector unsigned int select_1 = spu_cmpgt(vec_0_1, vec_s); | |
158 vec_s = spu_sel(vec_s, vec_0_1, select_1); | |
159 | |
160 vector unsigned int select_2 = spu_cmpgt(vec_s, vec_255); | |
161 vec_s = spu_sel(vec_s, vec_255, select_2); | |
162 return spu_convtu(vec_s,0); | |
163 } | |
164 | |
165 | |
166 void yuv_to_rgb_w16() { | |
167 // Pixel dimensions of the picture | |
168 uint32_t width, height; | |
169 | |
170 // Extract parameters | |
171 width = parms_converter.src_pixel_width; | |
172 height = parms_converter.src_pixel_height; | |
173 | |
174 // Plane data management | |
175 // Y | |
176 unsigned char* ram_addr_y = parms_converter.y_plane; | |
177 // V | |
178 unsigned char* ram_addr_v = parms_converter.v_plane; | |
179 // U | |
180 unsigned char* ram_addr_u = parms_converter.u_plane; | |
181 | |
182 // BGRA | |
183 unsigned char* ram_addr_bgra = parms_converter.dstBuffer; | |
184 | |
185 // Strides | |
186 unsigned int stride_y = width; | |
187 unsigned int stride_vu = width>>1; | |
188 | |
189 // Buffer management | |
190 unsigned int buf_idx = 0; | |
191 unsigned int size_4lines_y = stride_y<<2; | |
192 unsigned int size_2lines_y = stride_y<<1; | |
193 unsigned int size_2lines_vu = stride_vu<<1; | |
194 | |
195 // 2*width*4byte_per_pixel | |
196 unsigned int size_2lines_bgra = width<<3; | |
197 | |
198 | |
199 // start double-buffered processing | |
200 // 4 lines y | |
201 spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y, size_4lines_y, RETR_BUF+buf_idx, MFC_GET_CMD); | |
202 | |
203 // 2 lines v | |
204 spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD); | |
205 | |
206 // 2 lines u | |
207 spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD); | |
208 | |
209 // Wait for these transfers to be completed | |
210 DMA_WAIT_TAG((RETR_BUF + buf_idx)); | |
211 | |
212 unsigned int i; | |
213 for(i=0; i<(height>>2)-1; i++) { | |
214 | |
215 buf_idx^=1; | |
216 | |
217 // 4 lines y | |
218 spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y+size_4lines_y, size_4lines_y, RETR_BUF+buf_idx, MFC_GET_CMD); | |
219 | |
220 // 2 lines v | |
221 spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v+size_2lines_vu, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD); | |
222 | |
223 // 2 lines u | |
224 spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u+size_2lines_vu, size_2lines_vu, RETR_BUF+buf_idx, MFC_GET_CMD); | |
225 | |
226 DMA_WAIT_TAG((RETR_BUF + buf_idx)); | |
227 | |
228 buf_idx^=1; | |
229 | |
230 | |
231 // Convert YUV to BGRA, store it back (first two lines) | |
232 yuv_to_rgb_w16_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width); | |
233 | |
234 // Next two lines | |
235 yuv_to_rgb_w16_line(y_plane[buf_idx] + size_2lines_y, | |
236 v_plane[buf_idx] + stride_vu, | |
237 u_plane[buf_idx] + stride_vu, | |
238 bgra + size_2lines_bgra, | |
239 width); | |
240 | |
241 // Wait for previous storing transfer to be completed | |
242 DMA_WAIT_TAG(STR_BUF); | |
243 | |
244 // Store converted lines in two steps->max transfer size 16384 | |
245 spu_mfcdma32(bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
246 ram_addr_bgra += size_2lines_bgra; | |
247 spu_mfcdma32(bgra+size_2lines_bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
248 ram_addr_bgra += size_2lines_bgra; | |
249 | |
250 // Move 4 lines | |
251 ram_addr_y += size_4lines_y; | |
252 ram_addr_v += size_2lines_vu; | |
253 ram_addr_u += size_2lines_vu; | |
254 | |
255 buf_idx^=1; | |
256 } | |
257 | |
258 // Convert YUV to BGRA, store it back (first two lines) | |
259 yuv_to_rgb_w16_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width); | |
260 | |
261 // Next two lines | |
262 yuv_to_rgb_w16_line(y_plane[buf_idx] + size_2lines_y, | |
263 v_plane[buf_idx] + stride_vu, | |
264 u_plane[buf_idx] + stride_vu, | |
265 bgra + size_2lines_bgra, | |
266 width); | |
267 | |
268 // Wait for previous storing transfer to be completed | |
269 DMA_WAIT_TAG(STR_BUF); | |
270 spu_mfcdma32(bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
271 ram_addr_bgra += size_2lines_bgra; | |
272 spu_mfcdma32(bgra+size_2lines_bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
273 | |
274 // wait for previous storing transfer to be completed | |
275 DMA_WAIT_TAG(STR_BUF); | |
276 | |
277 } | |
278 | |
279 | |
280 void yuv_to_rgb_w32() { | |
281 // Pixel dimensions of the picture | |
282 uint32_t width, height; | |
283 | |
284 // Extract parameters | |
285 width = parms_converter.src_pixel_width; | |
286 height = parms_converter.src_pixel_height; | |
287 | |
288 // Plane data management | |
289 // Y | |
290 unsigned char* ram_addr_y = parms_converter.y_plane; | |
291 // V | |
292 unsigned char* ram_addr_v = parms_converter.v_plane; | |
293 // U | |
294 unsigned char* ram_addr_u = parms_converter.u_plane; | |
295 | |
296 // BGRA | |
297 unsigned char* ram_addr_bgra = parms_converter.dstBuffer; | |
298 | |
299 // Strides | |
300 unsigned int stride_y = width; | |
301 unsigned int stride_vu = width>>1; | |
302 | |
303 // Buffer management | |
304 unsigned int buf_idx = 0; | |
305 unsigned int size_4lines_y = stride_y<<2; | |
306 unsigned int size_2lines_y = stride_y<<1; | |
307 unsigned int size_2lines_vu = stride_vu<<1; | |
308 | |
309 // 2*width*4byte_per_pixel | |
310 unsigned int size_2lines_bgra = width<<3; | |
311 | |
312 // start double-buffered processing | |
313 // 4 lines y | |
314 spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y, size_4lines_y, RETR_BUF + buf_idx, MFC_GET_CMD); | |
315 // 2 lines v | |
316 spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD); | |
317 // 2 lines u | |
318 spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD); | |
319 | |
320 // Wait for these transfers to be completed | |
321 DMA_WAIT_TAG((RETR_BUF + buf_idx)); | |
322 | |
323 unsigned int i; | |
324 for(i=0; i < (height>>2)-1; i++) { | |
325 buf_idx^=1; | |
326 // 4 lines y | |
327 spu_mfcdma32(y_plane[buf_idx], (unsigned int) ram_addr_y+size_4lines_y, size_4lines_y, RETR_BUF + buf_idx, MFC_GET_CMD); | |
328 deprintf("4lines = %d\n", size_4lines_y); | |
329 // 2 lines v | |
330 spu_mfcdma32(v_plane[buf_idx], (unsigned int) ram_addr_v+size_2lines_vu, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD); | |
331 deprintf("2lines = %d\n", size_2lines_vu); | |
332 // 2 lines u | |
333 spu_mfcdma32(u_plane[buf_idx], (unsigned int) ram_addr_u+size_2lines_vu, size_2lines_vu, RETR_BUF + buf_idx, MFC_GET_CMD); | |
334 deprintf("2lines = %d\n", size_2lines_vu); | |
335 | |
336 DMA_WAIT_TAG((RETR_BUF + buf_idx)); | |
337 | |
338 buf_idx^=1; | |
339 | |
340 // Convert YUV to BGRA, store it back (first two lines) | |
341 yuv_to_rgb_w32_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width); | |
342 | |
343 // Next two lines | |
344 yuv_to_rgb_w32_line(y_plane[buf_idx] + size_2lines_y, | |
345 v_plane[buf_idx] + stride_vu, | |
346 u_plane[buf_idx] + stride_vu, | |
347 bgra + size_2lines_bgra, | |
348 width); | |
349 | |
350 // Wait for previous storing transfer to be completed | |
351 DMA_WAIT_TAG(STR_BUF); | |
352 | |
353 // Store converted lines in two steps->max transfer size 16384 | |
354 spu_mfcdma32(bgra, (unsigned int)ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
355 ram_addr_bgra += size_2lines_bgra; | |
356 spu_mfcdma32(bgra + size_2lines_bgra, (unsigned int)ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
357 ram_addr_bgra += size_2lines_bgra; | |
358 | |
359 // Move 4 lines | |
360 ram_addr_y += size_4lines_y; | |
361 ram_addr_v += size_2lines_vu; | |
362 ram_addr_u += size_2lines_vu; | |
363 | |
364 buf_idx^=1; | |
365 } | |
366 | |
367 // Convert YUV to BGRA, store it back (first two lines) | |
368 yuv_to_rgb_w32_line(y_plane[buf_idx], v_plane[buf_idx], u_plane[buf_idx], bgra, width); | |
369 | |
370 // Next two lines | |
371 yuv_to_rgb_w32_line(y_plane[buf_idx] + size_2lines_y, | |
372 v_plane[buf_idx] + stride_vu, | |
373 u_plane[buf_idx] + stride_vu, | |
374 bgra + size_2lines_bgra, | |
375 width); | |
376 | |
377 // Wait for previous storing transfer to be completed | |
378 DMA_WAIT_TAG(STR_BUF); | |
379 spu_mfcdma32(bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
380 ram_addr_bgra += size_2lines_bgra; | |
381 spu_mfcdma32(bgra + size_2lines_bgra, (unsigned int) ram_addr_bgra, size_2lines_bgra, STR_BUF, MFC_PUT_CMD); | |
382 | |
383 // Wait for previous storing transfer to be completed | |
384 DMA_WAIT_TAG(STR_BUF); | |
385 } | |
386 | |
387 | |
388 /* Some vectors needed by the yuv 2 rgb conversion algorithm */ | |
389 const vector float vec_minus_128 = { -128.0f, -128.0f, -128.0f, -128.0f }; | |
390 const vector unsigned char vec_null = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | |
391 const vector unsigned char vec_char2int_first = { 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13 }; | |
392 const vector unsigned char vec_char2int_second = { 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17 }; | |
393 const vector unsigned char vec_char2int_third = { 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x1B }; | |
394 const vector unsigned char vec_char2int_fourth = { 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1F }; | |
395 | |
396 const vector float vec_R_precalc_coeff = {1.403f, 1.403f, 1.403f, 1.403f}; | |
397 const vector float vec_Gu_precalc_coeff = {-0.344f, -0.344f, -0.344f, -0.344f}; | |
398 const vector float vec_Gv_precalc_coeff = {-0.714f, -0.714f, -0.714f, -0.714f}; | |
399 const vector float vec_B_precalc_coeff = {1.773f, 1.773f, 1.773f, 1.773f}; | |
400 | |
401 const vector unsigned int vec_alpha = { 255 << 24, 255 << 24, 255 << 24, 255 << 24 }; | |
402 | |
403 const vector unsigned char vec_select_floats_upper = { 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07 }; | |
404 const vector unsigned char vec_select_floats_lower = { 0x08, 0x09, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x0C, 0x0D, 0x0E, 0x0F }; | |
405 | |
406 | |
407 /* | |
408 * yuv_to_rgb_w16() | |
409 * | |
410 * processes to line of yuv-input, width has to be a multiple of 16 | |
411 * two lines of yuv are taken as input | |
412 * | |
413 * @param y_addr address of the y plane in local store | |
414 * @param v_addr address of the v plane in local store | |
415 * @param u_addr address of the u plane in local store | |
416 * @param bgra_addr_ address of the bgra output buffer | |
417 * @param width the width in pixel | |
418 */ | |
419 void yuv_to_rgb_w16_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr_, unsigned int width) { | |
420 // each pixel is stored as an integer | |
421 unsigned int* bgra_addr = (unsigned int*) bgra_addr_; | |
422 | |
423 unsigned int x; | |
424 for(x = 0; x < width; x+=2) { | |
425 // Gehe zweischrittig durch die zeile, da jeder u und v wert fuer 4 pixel(zwei hoch, zwei breit) gilt | |
426 const unsigned char Y_1 = *(y_addr + x); | |
427 const unsigned char Y_2 = *(y_addr + x + 1); | |
428 const unsigned char Y_3 = *(y_addr + x + width); | |
429 const unsigned char Y_4 = *(y_addr + x + width + 1); | |
430 const unsigned char U = *(u_addr + (x >> 1)); | |
431 const unsigned char V = *(v_addr + (x >> 1)); | |
432 | |
433 float V_minus_128 = (float)((float)V - 128.0f); | |
434 float U_minus_128 = (float)((float)U - 128.0f); | |
435 | |
436 float R_precalculate = 1.403f * V_minus_128; | |
437 float G_precalculate = -(0.344f * U_minus_128 + 0.714f * V_minus_128); | |
438 float B_precalculate = 1.773f * U_minus_128; | |
439 | |
440 const unsigned char R_1 = float_to_char((Y_1 + R_precalculate)); | |
441 const unsigned char R_2 = float_to_char((Y_2 + R_precalculate)); | |
442 const unsigned char R_3 = float_to_char((Y_3 + R_precalculate)); | |
443 const unsigned char R_4 = float_to_char((Y_4 + R_precalculate)); | |
444 const unsigned char G_1 = float_to_char((Y_1 + G_precalculate)); | |
445 const unsigned char G_2 = float_to_char((Y_2 + G_precalculate)); | |
446 const unsigned char G_3 = float_to_char((Y_3 + G_precalculate)); | |
447 const unsigned char G_4 = float_to_char((Y_4 + G_precalculate)); | |
448 const unsigned char B_1 = float_to_char((Y_1 + B_precalculate)); | |
449 const unsigned char B_2 = float_to_char((Y_2 + B_precalculate)); | |
450 const unsigned char B_3 = float_to_char((Y_3 + B_precalculate)); | |
451 const unsigned char B_4 = float_to_char((Y_4 + B_precalculate)); | |
452 | |
453 *(bgra_addr + x) = (B_1 << 0)| (G_1 << 8) | (R_1 << 16) | (255 << 24); | |
454 *(bgra_addr + x + 1) = (B_2 << 0)| (G_2 << 8) | (R_2 << 16) | (255 << 24); | |
455 *(bgra_addr + x + width) = (B_3 << 0)| (G_3 << 8) | (R_3 << 16) | (255 << 24); | |
456 *(bgra_addr + x + width + 1) = (B_4 << 0)| (G_4 << 8) | (R_4 << 16) | (255 << 24); | |
457 } | |
458 } | |
459 | |
460 | |
461 /* | |
462 * yuv_to_rgb_w32() | |
463 * | |
464 * processes to line of yuv-input, width has to be a multiple of 32 | |
465 * two lines of yuv are taken as input | |
466 * | |
467 * @param y_addr address of the y plane in local store | |
468 * @param v_addr address of the v plane in local store | |
469 * @param u_addr address of the u plane in local store | |
470 * @param bgra_addr_ address of the bgra output buffer | |
471 * @param width the width in pixel | |
472 */ | |
473 void yuv_to_rgb_w32_line(unsigned char* y_addr, unsigned char* v_addr, unsigned char* u_addr, unsigned char* bgra_addr_, unsigned int width) { | |
474 // each pixel is stored as an integer | |
475 unsigned int* bgra_addr = (unsigned int*) bgra_addr_; | |
476 | |
477 unsigned int x; | |
478 for(x = 0; x < width; x+=32) { | |
479 // Gehe zweischrittig durch die zeile, da jeder u und v wert fuer 4 pixel(zwei hoch, zwei breit) gilt | |
480 | |
481 const vector unsigned char vchar_Y_1 = *((vector unsigned char*)(y_addr + x)); | |
482 const vector unsigned char vchar_Y_2 = *((vector unsigned char*)(y_addr + x + 16)); | |
483 const vector unsigned char vchar_Y_3 = *((vector unsigned char*)(y_addr + x + width)); | |
484 const vector unsigned char vchar_Y_4 = *((vector unsigned char*)(y_addr + x + width + 16)); | |
485 const vector unsigned char vchar_U = *((vector unsigned char*)(u_addr + (x >> 1))); | |
486 const vector unsigned char vchar_V = *((vector unsigned char*)(v_addr + (x >> 1))); | |
487 | |
488 const vector float vfloat_U_1 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_first), 0),vec_minus_128); | |
489 const vector float vfloat_U_2 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_second), 0),vec_minus_128); | |
490 const vector float vfloat_U_3 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_third), 0),vec_minus_128); | |
491 const vector float vfloat_U_4 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_U, vec_char2int_fourth), 0),vec_minus_128); | |
492 | |
493 const vector float vfloat_V_1 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_first), 0),vec_minus_128); | |
494 const vector float vfloat_V_2 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_second), 0),vec_minus_128); | |
495 const vector float vfloat_V_3 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_third), 0),vec_minus_128); | |
496 const vector float vfloat_V_4 = spu_add(spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_V, vec_char2int_fourth), 0),vec_minus_128); | |
497 | |
498 vector float Y_1 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_first), 0); | |
499 vector float Y_2 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_second), 0); | |
500 vector float Y_3 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_third), 0); | |
501 vector float Y_4 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_1, vec_char2int_fourth), 0); | |
502 vector float Y_5 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_first), 0); | |
503 vector float Y_6 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_second), 0); | |
504 vector float Y_7 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_third), 0); | |
505 vector float Y_8 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_2, vec_char2int_fourth), 0); | |
506 vector float Y_9 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_first), 0); | |
507 vector float Y_10 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_second), 0); | |
508 vector float Y_11 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_third), 0); | |
509 vector float Y_12 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_3, vec_char2int_fourth), 0); | |
510 vector float Y_13 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_first), 0); | |
511 vector float Y_14 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_second), 0); | |
512 vector float Y_15 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_third), 0); | |
513 vector float Y_16 = spu_convtf((vector unsigned int)spu_shuffle(vec_null, vchar_Y_4, vec_char2int_fourth), 0); | |
514 | |
515 const vector float R1a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_1); | |
516 const vector float R2a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_2); | |
517 const vector float R3a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_3); | |
518 const vector float R4a_precalculate = spu_mul(vec_R_precalc_coeff, vfloat_V_4); | |
519 | |
520 const vector float R1_precalculate = spu_shuffle(R1a_precalculate, R1a_precalculate, vec_select_floats_upper); | |
521 const vector float R2_precalculate = spu_shuffle(R1a_precalculate, R1a_precalculate, vec_select_floats_lower); | |
522 const vector float R3_precalculate = spu_shuffle(R2a_precalculate, R2a_precalculate, vec_select_floats_upper); | |
523 const vector float R4_precalculate = spu_shuffle(R2a_precalculate, R2a_precalculate, vec_select_floats_lower); | |
524 const vector float R5_precalculate = spu_shuffle(R3a_precalculate, R3a_precalculate, vec_select_floats_upper); | |
525 const vector float R6_precalculate = spu_shuffle(R3a_precalculate, R3a_precalculate, vec_select_floats_lower); | |
526 const vector float R7_precalculate = spu_shuffle(R4a_precalculate, R4a_precalculate, vec_select_floats_upper); | |
527 const vector float R8_precalculate = spu_shuffle(R4a_precalculate, R4a_precalculate, vec_select_floats_lower); | |
528 | |
529 | |
530 const vector float G1a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_1, spu_mul(vfloat_V_1, vec_Gv_precalc_coeff)); | |
531 const vector float G2a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_2, spu_mul(vfloat_V_2, vec_Gv_precalc_coeff)); | |
532 const vector float G3a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_3, spu_mul(vfloat_V_3, vec_Gv_precalc_coeff)); | |
533 const vector float G4a_precalculate = spu_madd(vec_Gu_precalc_coeff, vfloat_U_4, spu_mul(vfloat_V_4, vec_Gv_precalc_coeff)); | |
534 | |
535 const vector float G1_precalculate = spu_shuffle(G1a_precalculate, G1a_precalculate, vec_select_floats_upper); | |
536 const vector float G2_precalculate = spu_shuffle(G1a_precalculate, G1a_precalculate, vec_select_floats_lower); | |
537 const vector float G3_precalculate = spu_shuffle(G2a_precalculate, G2a_precalculate, vec_select_floats_upper); | |
538 const vector float G4_precalculate = spu_shuffle(G2a_precalculate, G2a_precalculate, vec_select_floats_lower); | |
539 const vector float G5_precalculate = spu_shuffle(G3a_precalculate, G3a_precalculate, vec_select_floats_upper); | |
540 const vector float G6_precalculate = spu_shuffle(G3a_precalculate, G3a_precalculate, vec_select_floats_lower); | |
541 const vector float G7_precalculate = spu_shuffle(G4a_precalculate, G4a_precalculate, vec_select_floats_upper); | |
542 const vector float G8_precalculate = spu_shuffle(G4a_precalculate, G4a_precalculate, vec_select_floats_lower); | |
543 | |
544 | |
545 const vector float B1a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_1); | |
546 const vector float B2a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_2); | |
547 const vector float B3a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_3); | |
548 const vector float B4a_precalculate = spu_mul(vec_B_precalc_coeff, vfloat_U_4); | |
549 | |
550 const vector float B1_precalculate = spu_shuffle(B1a_precalculate, B1a_precalculate, vec_select_floats_upper); | |
551 const vector float B2_precalculate = spu_shuffle(B1a_precalculate, B1a_precalculate, vec_select_floats_lower); | |
552 const vector float B3_precalculate = spu_shuffle(B2a_precalculate, B2a_precalculate, vec_select_floats_upper); | |
553 const vector float B4_precalculate = spu_shuffle(B2a_precalculate, B2a_precalculate, vec_select_floats_lower); | |
554 const vector float B5_precalculate = spu_shuffle(B3a_precalculate, B3a_precalculate, vec_select_floats_upper); | |
555 const vector float B6_precalculate = spu_shuffle(B3a_precalculate, B3a_precalculate, vec_select_floats_lower); | |
556 const vector float B7_precalculate = spu_shuffle(B4a_precalculate, B4a_precalculate, vec_select_floats_upper); | |
557 const vector float B8_precalculate = spu_shuffle(B4a_precalculate, B4a_precalculate, vec_select_floats_lower); | |
558 | |
559 | |
560 const vector unsigned int R_1 = vfloat_to_vuint(spu_add( Y_1, R1_precalculate)); | |
561 const vector unsigned int R_2 = vfloat_to_vuint(spu_add( Y_2, R2_precalculate)); | |
562 const vector unsigned int R_3 = vfloat_to_vuint(spu_add( Y_3, R3_precalculate)); | |
563 const vector unsigned int R_4 = vfloat_to_vuint(spu_add( Y_4, R4_precalculate)); | |
564 const vector unsigned int R_5 = vfloat_to_vuint(spu_add( Y_5, R5_precalculate)); | |
565 const vector unsigned int R_6 = vfloat_to_vuint(spu_add( Y_6, R6_precalculate)); | |
566 const vector unsigned int R_7 = vfloat_to_vuint(spu_add( Y_7, R7_precalculate)); | |
567 const vector unsigned int R_8 = vfloat_to_vuint(spu_add( Y_8, R8_precalculate)); | |
568 const vector unsigned int R_9 = vfloat_to_vuint(spu_add( Y_9, R1_precalculate)); | |
569 const vector unsigned int R_10 = vfloat_to_vuint(spu_add(Y_10, R2_precalculate)); | |
570 const vector unsigned int R_11 = vfloat_to_vuint(spu_add(Y_11, R3_precalculate)); | |
571 const vector unsigned int R_12 = vfloat_to_vuint(spu_add(Y_12, R4_precalculate)); | |
572 const vector unsigned int R_13 = vfloat_to_vuint(spu_add(Y_13, R5_precalculate)); | |
573 const vector unsigned int R_14 = vfloat_to_vuint(spu_add(Y_14, R6_precalculate)); | |
574 const vector unsigned int R_15 = vfloat_to_vuint(spu_add(Y_15, R7_precalculate)); | |
575 const vector unsigned int R_16 = vfloat_to_vuint(spu_add(Y_16, R8_precalculate)); | |
576 | |
577 const vector unsigned int G_1 = vfloat_to_vuint(spu_add( Y_1, G1_precalculate)); | |
578 const vector unsigned int G_2 = vfloat_to_vuint(spu_add( Y_2, G2_precalculate)); | |
579 const vector unsigned int G_3 = vfloat_to_vuint(spu_add( Y_3, G3_precalculate)); | |
580 const vector unsigned int G_4 = vfloat_to_vuint(spu_add( Y_4, G4_precalculate)); | |
581 const vector unsigned int G_5 = vfloat_to_vuint(spu_add( Y_5, G5_precalculate)); | |
582 const vector unsigned int G_6 = vfloat_to_vuint(spu_add( Y_6, G6_precalculate)); | |
583 const vector unsigned int G_7 = vfloat_to_vuint(spu_add( Y_7, G7_precalculate)); | |
584 const vector unsigned int G_8 = vfloat_to_vuint(spu_add( Y_8, G8_precalculate)); | |
585 const vector unsigned int G_9 = vfloat_to_vuint(spu_add( Y_9, G1_precalculate)); | |
586 const vector unsigned int G_10 = vfloat_to_vuint(spu_add(Y_10, G2_precalculate)); | |
587 const vector unsigned int G_11 = vfloat_to_vuint(spu_add(Y_11, G3_precalculate)); | |
588 const vector unsigned int G_12 = vfloat_to_vuint(spu_add(Y_12, G4_precalculate)); | |
589 const vector unsigned int G_13 = vfloat_to_vuint(spu_add(Y_13, G5_precalculate)); | |
590 const vector unsigned int G_14 = vfloat_to_vuint(spu_add(Y_14, G6_precalculate)); | |
591 const vector unsigned int G_15 = vfloat_to_vuint(spu_add(Y_15, G7_precalculate)); | |
592 const vector unsigned int G_16 = vfloat_to_vuint(spu_add(Y_16, G8_precalculate)); | |
593 | |
594 const vector unsigned int B_1 = vfloat_to_vuint(spu_add( Y_1, B1_precalculate)); | |
595 const vector unsigned int B_2 = vfloat_to_vuint(spu_add( Y_2, B2_precalculate)); | |
596 const vector unsigned int B_3 = vfloat_to_vuint(spu_add( Y_3, B3_precalculate)); | |
597 const vector unsigned int B_4 = vfloat_to_vuint(spu_add( Y_4, B4_precalculate)); | |
598 const vector unsigned int B_5 = vfloat_to_vuint(spu_add( Y_5, B5_precalculate)); | |
599 const vector unsigned int B_6 = vfloat_to_vuint(spu_add( Y_6, B6_precalculate)); | |
600 const vector unsigned int B_7 = vfloat_to_vuint(spu_add( Y_7, B7_precalculate)); | |
601 const vector unsigned int B_8 = vfloat_to_vuint(spu_add( Y_8, B8_precalculate)); | |
602 const vector unsigned int B_9 = vfloat_to_vuint(spu_add( Y_9, B1_precalculate)); | |
603 const vector unsigned int B_10 = vfloat_to_vuint(spu_add(Y_10, B2_precalculate)); | |
604 const vector unsigned int B_11 = vfloat_to_vuint(spu_add(Y_11, B3_precalculate)); | |
605 const vector unsigned int B_12 = vfloat_to_vuint(spu_add(Y_12, B4_precalculate)); | |
606 const vector unsigned int B_13 = vfloat_to_vuint(spu_add(Y_13, B5_precalculate)); | |
607 const vector unsigned int B_14 = vfloat_to_vuint(spu_add(Y_14, B6_precalculate)); | |
608 const vector unsigned int B_15 = vfloat_to_vuint(spu_add(Y_15, B7_precalculate)); | |
609 const vector unsigned int B_16 = vfloat_to_vuint(spu_add(Y_16, B8_precalculate)); | |
610 | |
611 *((vector unsigned int*)(bgra_addr + x)) = spu_or(spu_or(vec_alpha, B_1), spu_or(spu_slqwbyte( R_1, 2),spu_slqwbyte(G_1, 1))); | |
612 *((vector unsigned int*)(bgra_addr + x + 4)) = spu_or(spu_or(vec_alpha, B_2), spu_or(spu_slqwbyte( R_2, 2),spu_slqwbyte(G_2, 1))); | |
613 *((vector unsigned int*)(bgra_addr + x + 8)) = spu_or(spu_or(vec_alpha, B_3), spu_or(spu_slqwbyte( R_3, 2),spu_slqwbyte(G_3, 1))); | |
614 *((vector unsigned int*)(bgra_addr + x + 12)) = spu_or(spu_or(vec_alpha, B_4), spu_or(spu_slqwbyte( R_4, 2),spu_slqwbyte(G_4, 1))); | |
615 *((vector unsigned int*)(bgra_addr + x + 16)) = spu_or(spu_or(vec_alpha, B_5), spu_or(spu_slqwbyte( R_5, 2),spu_slqwbyte(G_5, 1))); | |
616 *((vector unsigned int*)(bgra_addr + x + 20)) = spu_or(spu_or(vec_alpha, B_6), spu_or(spu_slqwbyte( R_6, 2),spu_slqwbyte(G_6, 1))); | |
617 *((vector unsigned int*)(bgra_addr + x + 24)) = spu_or(spu_or(vec_alpha, B_7), spu_or(spu_slqwbyte( R_7, 2),spu_slqwbyte(G_7, 1))); | |
618 *((vector unsigned int*)(bgra_addr + x + 28)) = spu_or(spu_or(vec_alpha, B_8), spu_or(spu_slqwbyte( R_8, 2),spu_slqwbyte(G_8, 1))); | |
619 *((vector unsigned int*)(bgra_addr + x + width)) = spu_or(spu_or(vec_alpha, B_9), spu_or(spu_slqwbyte( R_9, 2),spu_slqwbyte(G_9, 1))); | |
620 *((vector unsigned int*)(bgra_addr + x + width + 4)) = spu_or(spu_or(vec_alpha, B_10), spu_or(spu_slqwbyte(R_10, 2),spu_slqwbyte(G_10, 1))); | |
621 *((vector unsigned int*)(bgra_addr + x + width + 8)) = spu_or(spu_or(vec_alpha, B_11), spu_or(spu_slqwbyte(R_11, 2),spu_slqwbyte(G_11, 1))); | |
622 *((vector unsigned int*)(bgra_addr + x + width + 12)) = spu_or(spu_or(vec_alpha, B_12), spu_or(spu_slqwbyte(R_12, 2),spu_slqwbyte(G_12, 1))); | |
623 *((vector unsigned int*)(bgra_addr + x + width + 16)) = spu_or(spu_or(vec_alpha, B_13), spu_or(spu_slqwbyte(R_13, 2),spu_slqwbyte(G_13, 1))); | |
624 *((vector unsigned int*)(bgra_addr + x + width + 20)) = spu_or(spu_or(vec_alpha, B_14), spu_or(spu_slqwbyte(R_14, 2),spu_slqwbyte(G_14, 1))); | |
625 *((vector unsigned int*)(bgra_addr + x + width + 24)) = spu_or(spu_or(vec_alpha, B_15), spu_or(spu_slqwbyte(R_15, 2),spu_slqwbyte(G_15, 1))); | |
626 *((vector unsigned int*)(bgra_addr + x + width + 28)) = spu_or(spu_or(vec_alpha, B_16), spu_or(spu_slqwbyte(R_16, 2),spu_slqwbyte(G_16, 1))); | |
627 } | |
628 } | |
629 |