blob: 043add23b88886a35ab9f0d4a77d29a333c9d976 [file] [log] [blame]
codeworkxf1be2fe2012-03-24 17:38:29 +01001/*
2 *
3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * @file swconvertor.c
20 *
21 * @brief SEC_OMX specific define
22 *
23 * @author ShinWon Lee (shinwon.lee@samsung.com)
24 *
25 * @version 1.0
26 *
27 * @history
28 * 2012.02.01 : Create
29 */
30
31#include "stdio.h"
32#include "stdlib.h"
33#include "swconverter.h"
34
35/*
36 * Get tiled address of position(x,y)
37 *
38 * @param x_size
39 * width of tiled[in]
40 *
41 * @param y_size
42 * height of tiled[in]
43 *
44 * @param x_pos
45 * x position of tield[in]
46 *
47 * @param src_size
48 * y position of tield[in]
49 *
50 * @return
51 * address of tiled data
52 */
53static int tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
54{
55 int pixel_x_m1, pixel_y_m1;
56 int roundup_x, roundup_y;
57 int linear_addr0, linear_addr1, bank_addr ;
58 int x_addr;
59 int trans_addr;
60
61 pixel_x_m1 = x_size -1;
62 pixel_y_m1 = y_size -1;
63
64 roundup_x = ((pixel_x_m1 >> 7) + 1);
65 roundup_y = ((pixel_x_m1 >> 6) + 1);
66
67 x_addr = x_pos >> 2;
68
69 if ((y_size <= y_pos+32) && ( y_pos < y_size) &&
70 (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
71 linear_addr0 = (((y_pos & 0x1f) <<4) | (x_addr & 0xf));
72 linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
73
74 if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
75 bank_addr = ((x_addr >> 4) & 0x1);
76 else
77 bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
78 } else {
79 linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
80 linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
81
82 if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
83 bank_addr = ((x_addr >> 4) & 0x1);
84 else
85 bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
86 }
87
88 linear_addr0 = linear_addr0 << 2;
89 trans_addr = (linear_addr1 <<13) | (bank_addr << 11) | linear_addr0;
90
91 return trans_addr;
92}
93
94/*
95 * De-interleaves src to dest1, dest2
96 *
97 * @param dest1
98 * Address of de-interleaved data[out]
99 *
100 * @param dest2
101 * Address of de-interleaved data[out]
102 *
103 * @param src
104 * Address of interleaved data[in]
105 *
106 * @param src_size
107 * Size of interleaved data[in]
108 */
109void csc_deinterleave_memcpy(
110 unsigned char *dest1,
111 unsigned char *dest2,
112 unsigned char *src,
113 unsigned int src_size)
114{
115 unsigned int i = 0;
116 for(i=0; i<src_size/2; i++) {
117 dest1[i] = src[i*2];
118 dest2[i] = src[i*2+1];
119 }
120}
121
122/*
123 * Interleaves src1, src2 to dest
124 *
125 * @param dest
126 * Address of interleaved data[out]
127 *
128 * @param src1
129 * Address of de-interleaved data[in]
130 *
131 * @param src2
132 * Address of de-interleaved data[in]
133 *
134 * @param src_size
135 * Size of de-interleaved data[in]
136 */
137void csc_interleave_memcpy(
138 unsigned char *dest,
139 unsigned char *src1,
140 unsigned char *src2,
141 unsigned int src_size)
142{
143 unsigned int i = 0;
144 for(i=0; i<src_size; i++) {
145 dest[i * 2] = src1[i];
146 dest[i * 2 + 1] = src2[i];
147 }
148}
149
150/*
151 * Converts tiled data to linear
152 * Crops left, top, right, buttom
153 * 1. Y of NV12T to Y of YUV420P
154 * 2. Y of NV12T to Y of YUV420S
155 * 3. UV of NV12T to UV of YUV420S
156 *
157 * @param yuv420_dest
158 * Y or UV plane address of YUV420[out]
159 *
160 * @param nv12t_src
161 * Y or UV plane address of NV12T[in]
162 *
163 * @param yuv420_width
164 * Width of YUV420[in]
165 *
166 * @param yuv420_height
167 * Y: Height of YUV420, UV: Height/2 of YUV420[in]
168 *
169 * @param left
170 * Crop size of left
171 *
172 * @param top
173 * Crop size of top
174 *
175 * @param right
176 * Crop size of right
177 *
178 * @param buttom
179 * Crop size of buttom
180 */
181static void csc_tiled_to_linear_crop(
182 unsigned char *yuv420_dest,
183 unsigned char *nv12t_src,
184 unsigned int yuv420_width,
185 unsigned int yuv420_height,
186 unsigned int left,
187 unsigned int top,
188 unsigned int right,
189 unsigned int buttom)
190{
191 unsigned int i, j;
192 unsigned int tiled_offset = 0, tiled_offset1 = 0;
193 unsigned int linear_offset = 0;
194 unsigned int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
195
196 temp3 = yuv420_width-right;
197 temp1 = temp3-left;
198 /* real width is greater than or equal 256 */
199 if (temp1 >= 256) {
200 for (i=top; i<yuv420_height-buttom; i=i+1) {
201 j = left;
202 temp3 = (j>>8)<<8;
203 temp3 = temp3>>6;
204 temp4 = i>>5;
205 if (temp4 & 0x1) {
206 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
207 tiled_offset = temp4-1;
208 temp1 = ((yuv420_width+127)>>7)<<7;
209 tiled_offset = tiled_offset*(temp1>>6);
210 tiled_offset = tiled_offset+temp3;
211 tiled_offset = tiled_offset+2;
212 temp1 = (temp3>>2)<<2;
213 tiled_offset = tiled_offset+temp1;
214 tiled_offset = tiled_offset<<11;
215 tiled_offset1 = tiled_offset+2048*2;
216 temp4 = 8;
217 } else {
218 temp2 = ((yuv420_height+31)>>5)<<5;
219 if ((i+32)<temp2) {
220 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
221 temp1 = temp3+2;
222 temp1 = (temp1>>2)<<2;
223 tiled_offset = temp3+temp1;
224 temp1 = ((yuv420_width+127)>>7)<<7;
225 tiled_offset = tiled_offset+temp4*(temp1>>6);
226 tiled_offset = tiled_offset<<11;
227 tiled_offset1 = tiled_offset+2048*6;
228 temp4 = 8;
229 } else {
230 /* even2 fomula: x+x_block_num*y */
231 temp1 = ((yuv420_width+127)>>7)<<7;
232 tiled_offset = temp4*(temp1>>6);
233 tiled_offset = tiled_offset+temp3;
234 tiled_offset = tiled_offset<<11;
235 tiled_offset1 = tiled_offset+2048*2;
236 temp4 = 4;
237 }
238 }
239
240 temp1 = i&0x1F;
241 tiled_offset = tiled_offset+64*(temp1);
242 tiled_offset1 = tiled_offset1+64*(temp1);
243 temp2 = yuv420_width-left-right;
244 linear_offset = temp2*(i-top);
245 temp3 = ((j+256)>>8)<<8;
246 temp3 = temp3-j;
247 temp1 = left&0x3F;
248 if (temp3 > 192) {
249 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);
250 temp2 = ((left+63)>>6)<<6;
251 temp3 = ((yuv420_width-right)>>6)<<6;
252 if (temp2 == temp3) {
253 temp2 = yuv420_width-right-(64-temp1);
254 }
255 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);
256 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);
257 memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);
258 linear_offset = linear_offset+256-temp1;
259 } else if (temp3 > 128) {
260 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);
261 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);
262 memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);
263 linear_offset = linear_offset+192-temp1;
264 } else if (temp3 > 64) {
265 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);
266 memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);
267 linear_offset = linear_offset+128-temp1;
268 } else if (temp3 > 0) {
269 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);
270 linear_offset = linear_offset+64-temp1;
271 }
272
273 tiled_offset = tiled_offset+temp4*2048;
274 j = (left>>8)<<8;
275 j = j + 256;
276 temp2 = yuv420_width-right-256;
277 for (; j<=temp2; j=j+256) {
278 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
279 tiled_offset1 = tiled_offset1+temp4*2048;
280 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
281 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
282 tiled_offset = tiled_offset+temp4*2048;
283 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);
284 linear_offset = linear_offset+256;
285 }
286
287 tiled_offset1 = tiled_offset1+temp4*2048;
288 temp2 = yuv420_width-right-j;
289 if (temp2 > 192) {
290 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
291 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
292 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
293 memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);
294 } else if (temp2 > 128) {
295 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
296 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
297 memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);
298 } else if (temp2 > 64) {
299 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
300 memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);
301 } else {
302 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
303 }
304 }
305 } else if (temp1 >= 64) {
306 for (i=top; i<(yuv420_height-buttom); i=i+1) {
307 j = left;
308 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
309 temp2 = ((j+64)>>6)<<6;
310 temp2 = temp2-j;
311 linear_offset = temp1*(i-top);
312 temp4 = j&0x3;
313 tiled_offset = tiled_offset+temp4;
314 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
315 linear_offset = linear_offset+temp2;
316 j = j+temp2;
317 if ((j+64) <= temp3) {
318 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
319 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
320 linear_offset = linear_offset+64;
321 j = j+64;
322 }
323 if ((j+64) <= temp3) {
324 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
325 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
326 linear_offset = linear_offset+64;
327 j = j+64;
328 }
329 if (j < temp3) {
330 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
331 temp2 = temp3-j;
332 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
333 }
334 }
335 } else {
336 for (i=top; i<(yuv420_height-buttom); i=i+1) {
337 linear_offset = temp1*(i-top);
338 for (j=left; j<(yuv420_width-right); j=j+2) {
339 tiled_offset = tile_4x2_read(yuv420_width, yuv420_height, j, i);
340 temp4 = j&0x3;
341 tiled_offset = tiled_offset+temp4;
342 memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);
343 linear_offset = linear_offset+2;
344 }
345 }
346 }
347}
348
349/*
350 * Converts and Deinterleaves tiled data to linear
351 * Crops left, top, right, buttom
352 * 1. UV of NV12T to UV of YUV420P
353 *
354 * @param yuv420_u_dest
355 * U plane address of YUV420P[out]
356 *
357 * @param yuv420_v_dest
358 * V plane address of YUV420P[out]
359 *
360 * @param nv12t_src
361 * UV plane address of NV12T[in]
362 *
363 * @param yuv420_width
364 * Width of YUV420[in]
365 *
366 * @param yuv420_uv_height
367 * Height/2 of YUV420[in]
368 *
369 * @param left
370 * Crop size of left
371 *
372 * @param top
373 * Crop size of top
374 *
375 * @param right
376 * Crop size of right
377 *
378 * @param buttom
379 * Crop size of buttom
380 */
381static void csc_tiled_to_linear_deinterleave_crop(
382 unsigned char *yuv420_u_dest,
383 unsigned char *yuv420_v_dest,
384 unsigned char *nv12t_uv_src,
385 unsigned int yuv420_width,
386 unsigned int yuv420_uv_height,
387 unsigned int left,
388 unsigned int top,
389 unsigned int right,
390 unsigned int buttom)
391{
392 unsigned int i, j;
393 unsigned int tiled_offset = 0, tiled_offset1 = 0;
394 unsigned int linear_offset = 0;
395 unsigned int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
396
397 temp3 = yuv420_width-right;
398 temp1 = temp3-left;
399 /* real width is greater than or equal 256 */
400 if (temp1 >= 256) {
401 for (i=top; i<yuv420_uv_height-buttom; i=i+1) {
402 j = left;
403 temp3 = (j>>8)<<8;
404 temp3 = temp3>>6;
405 temp4 = i>>5;
406 if (temp4 & 0x1) {
407 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
408 tiled_offset = temp4-1;
409 temp1 = ((yuv420_width+127)>>7)<<7;
410 tiled_offset = tiled_offset*(temp1>>6);
411 tiled_offset = tiled_offset+temp3;
412 tiled_offset = tiled_offset+2;
413 temp1 = (temp3>>2)<<2;
414 tiled_offset = tiled_offset+temp1;
415 tiled_offset = tiled_offset<<11;
416 tiled_offset1 = tiled_offset+2048*2;
417 temp4 = 8;
418 } else {
419 temp2 = ((yuv420_uv_height+31)>>5)<<5;
420 if ((i+32)<temp2) {
421 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
422 temp1 = temp3+2;
423 temp1 = (temp1>>2)<<2;
424 tiled_offset = temp3+temp1;
425 temp1 = ((yuv420_width+127)>>7)<<7;
426 tiled_offset = tiled_offset+temp4*(temp1>>6);
427 tiled_offset = tiled_offset<<11;
428 tiled_offset1 = tiled_offset+2048*6;
429 temp4 = 8;
430 } else {
431 /* even2 fomula: x+x_block_num*y */
432 temp1 = ((yuv420_width+127)>>7)<<7;
433 tiled_offset = temp4*(temp1>>6);
434 tiled_offset = tiled_offset+temp3;
435 tiled_offset = tiled_offset<<11;
436 tiled_offset1 = tiled_offset+2048*2;
437 temp4 = 4;
438 }
439 }
440
441 temp1 = i&0x1F;
442 tiled_offset = tiled_offset+64*(temp1);
443 tiled_offset1 = tiled_offset1+64*(temp1);
444 temp2 = yuv420_width-left-right;
445 linear_offset = temp2*(i-top)/2;
446 temp3 = ((j+256)>>8)<<8;
447 temp3 = temp3-j;
448 temp1 = left&0x3F;
449 if (temp3 > 192) {
450 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset, yuv420_v_dest+linear_offset, nv12t_uv_src+tiled_offset+temp1, 64-temp1);
451 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
452 yuv420_v_dest+linear_offset+(32-temp1/2),
453 nv12t_uv_src+tiled_offset+2048, 64);
454 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2),
455 yuv420_v_dest+linear_offset+(64-temp1/2),
456 nv12t_uv_src+tiled_offset1, 64);
457 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(96-temp1/2),
458 yuv420_v_dest+linear_offset+(96-temp1/2),
459 nv12t_uv_src+tiled_offset1+2048, 64);
460 linear_offset = linear_offset+128-temp1/2;
461 } else if (temp3 > 128) {
462 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
463 yuv420_v_dest+linear_offset,
464 nv12t_uv_src+tiled_offset+2048+temp1, 64-temp1);
465 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
466 yuv420_v_dest+linear_offset+(32-temp1/2),
467 nv12t_uv_src+tiled_offset1, 64);
468 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(64-temp1/2),
469 yuv420_v_dest+linear_offset+(64-temp1/2),
470 nv12t_uv_src+tiled_offset1+2048, 64);
471 linear_offset = linear_offset+96-temp1/2;
472 } else if (temp3 > 64) {
473 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
474 yuv420_v_dest+linear_offset,
475 nv12t_uv_src+tiled_offset1+temp1, 64-temp1);
476 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+(32-temp1/2),
477 yuv420_v_dest+linear_offset+(32-temp1/2),
478 nv12t_uv_src+tiled_offset1+2048, 64);
479 linear_offset = linear_offset+64-temp1/2;
480 } else if (temp3 > 0) {
481 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
482 yuv420_v_dest+linear_offset,
483 nv12t_uv_src+tiled_offset1+2048+temp1, 64-temp1);
484 linear_offset = linear_offset+32-temp1/2;
485 }
486
487 tiled_offset = tiled_offset+temp4*2048;
488 j = (left>>8)<<8;
489 j = j + 256;
490 temp2 = yuv420_width-right-256;
491 for (; j<=temp2; j=j+256) {
492 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
493 yuv420_v_dest+linear_offset,
494 nv12t_uv_src+tiled_offset, 64);
495 tiled_offset1 = tiled_offset1+temp4*2048;
496 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
497 yuv420_v_dest+linear_offset+32,
498 nv12t_uv_src+tiled_offset+2048, 64);
499 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
500 yuv420_v_dest+linear_offset+64,
501 nv12t_uv_src+tiled_offset1, 64);
502 tiled_offset = tiled_offset+temp4*2048;
503 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96,
504 yuv420_v_dest+linear_offset+96,
505 nv12t_uv_src+tiled_offset1+2048, 64);
506 linear_offset = linear_offset+128;
507 }
508
509 tiled_offset1 = tiled_offset1+temp4*2048;
510 temp2 = yuv420_width-right-j;
511 if (temp2 > 192) {
512 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
513 yuv420_v_dest+linear_offset,
514 nv12t_uv_src+tiled_offset, 64);
515 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
516 yuv420_v_dest+linear_offset+32,
517 nv12t_uv_src+tiled_offset+2048, 64);
518 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
519 yuv420_v_dest+linear_offset+64,
520 nv12t_uv_src+tiled_offset1, 64);
521 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+96,
522 yuv420_v_dest+linear_offset+96,
523 nv12t_uv_src+tiled_offset1+2048, temp2-192);
524 } else if (temp2 > 128) {
525 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
526 yuv420_v_dest+linear_offset,
527 nv12t_uv_src+tiled_offset, 64);
528 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
529 yuv420_v_dest+linear_offset+32,
530 nv12t_uv_src+tiled_offset+2048, 64);
531 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+64,
532 yuv420_v_dest+linear_offset+64,
533 nv12t_uv_src+tiled_offset1, temp2-128);
534 } else if (temp2 > 64) {
535 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
536 yuv420_v_dest+linear_offset,
537 nv12t_uv_src+tiled_offset, 64);
538 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset+32,
539 yuv420_v_dest+linear_offset+32,
540 nv12t_uv_src+tiled_offset+2048, temp2-64);
541 } else {
542 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
543 yuv420_v_dest+linear_offset,
544 nv12t_uv_src+tiled_offset, temp2);
545 }
546 }
547 } else if (temp1 >= 64) {
548 for (i=top; i<(yuv420_uv_height-buttom); i=i+1) {
549 j = left;
550 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
551 temp2 = ((j+64)>>6)<<6;
552 temp2 = temp2-j;
553 temp3 = yuv420_width-right;
554 temp4 = temp3-left;
555 linear_offset = temp4*(i-top)/2;
556 temp4 = j&0x3;
557 tiled_offset = tiled_offset+temp4;
558 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
559 yuv420_v_dest+linear_offset,
560 nv12t_uv_src+tiled_offset, temp2);
561 linear_offset = linear_offset+temp2/2;
562 j = j+temp2;
563 if ((j+64) <= temp3) {
564 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
565 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
566 yuv420_v_dest+linear_offset,
567 nv12t_uv_src+tiled_offset, 64);
568 linear_offset = linear_offset+32;
569 j = j+64;
570 }
571 if ((j+64) <= temp3) {
572 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
573 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
574 yuv420_v_dest+linear_offset,
575 nv12t_uv_src+tiled_offset, 64);
576 linear_offset = linear_offset+32;
577 j = j+64;
578 }
579 if (j < temp3) {
580 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
581 temp1 = temp3-j;
582 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
583 yuv420_v_dest+linear_offset,
584 nv12t_uv_src+tiled_offset, temp1);
585 }
586 }
587 } else {
588 for (i=top; i<(yuv420_uv_height-buttom); i=i+1) {
589 temp3 = yuv420_width-right;
590 temp4 = temp3-left;
591 linear_offset = temp4*(i-top)/2;
592 for (j=left; j<(yuv420_width-right); j=j+2) {
593 tiled_offset = tile_4x2_read(yuv420_width, yuv420_uv_height, j, i);
594 temp3 = j&0x3;
595 tiled_offset = tiled_offset+temp3;
596 csc_deinterleave_memcpy(yuv420_u_dest+linear_offset,
597 yuv420_v_dest+linear_offset,
598 nv12t_uv_src+tiled_offset, 2);
599 linear_offset = linear_offset+1;
600 }
601 }
602 }
603}
604
605/*
606 * Converts linear data to tiled
607 * Crops left, top, right, buttom
608 * 1. Y of YUV420P to Y of NV12T
609 * 2. Y of YUV420S to Y of NV12T
610 * 3. UV of YUV420S to UV of NV12T
611 *
612 * @param nv12t_dest
613 * Y or UV plane address of NV12T[out]
614 *
615 * @param yuv420_src
616 * Y or UV plane address of YUV420P(S)[in]
617 *
618 * @param yuv420_width
619 * Width of YUV420[in]
620 *
621 * @param yuv420_height
622 * Y: Height of YUV420, UV: Height/2 of YUV420[in]
623 *
624 * @param left
625 * Crop size of left
626 *
627 * @param top
628 * Crop size of top
629 *
630 * @param right
631 * Crop size of right
632 *
633 * @param buttom
634 * Crop size of buttom
635 */
636static void csc_linear_to_tiled_crop(
637 unsigned char *nv12t_dest,
638 unsigned char *yuv420_src,
639 unsigned int yuv420_width,
640 unsigned int yuv420_height,
641 unsigned int left,
642 unsigned int top,
643 unsigned int right,
644 unsigned int buttom)
645{
646 unsigned int i, j;
647 unsigned int tiled_x_index = 0, tiled_y_index = 0;
648 unsigned int aligned_x_size = 0, aligned_y_size = 0;
649 unsigned int tiled_offset = 0;
650 unsigned int temp1 = 0, temp2 = 0;
651
652 aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5;
653 aligned_x_size = ((yuv420_width-left-right)>>6)<<6;
654
655 for (i=0; i<aligned_y_size; i=i+32) {
656 for (j=0; j<aligned_x_size; j=j+64) {
657 tiled_offset = 0;
658 tiled_x_index = j>>6;
659 tiled_y_index = i>>5;
660 if (tiled_y_index & 0x1) {
661 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
662 tiled_offset = tiled_y_index-1;
663 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
664 tiled_offset = tiled_offset*(temp1>>6);
665 tiled_offset = tiled_offset+tiled_x_index;
666 tiled_offset = tiled_offset+2;
667 temp1 = (tiled_x_index>>2)<<2;
668 tiled_offset = tiled_offset+temp1;
669 tiled_offset = tiled_offset<<11;
670 } else {
671 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
672 if ((i+32)<temp2) {
673 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
674 temp1 = tiled_x_index+2;
675 temp1 = (temp1>>2)<<2;
676 tiled_offset = tiled_x_index+temp1;
677 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
678 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
679 tiled_offset = tiled_offset<<11;
680 } else {
681 /* even2 fomula: x+x_block_num*y */
682 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
683 tiled_offset = tiled_y_index*(temp1>>6);
684 tiled_offset = tiled_offset+tiled_x_index;
685 tiled_offset = tiled_offset<<11;
686 }
687 }
688
689 memcpy(nv12t_dest+tiled_offset, yuv420_src+left+j+yuv420_width*(i+top), 64);
690 memcpy(nv12t_dest+tiled_offset+64*1, yuv420_src+left+j+yuv420_width*(i+top+1), 64);
691 memcpy(nv12t_dest+tiled_offset+64*2, yuv420_src+left+j+yuv420_width*(i+top+2), 64);
692 memcpy(nv12t_dest+tiled_offset+64*3, yuv420_src+left+j+yuv420_width*(i+top+3), 64);
693 memcpy(nv12t_dest+tiled_offset+64*4, yuv420_src+left+j+yuv420_width*(i+top+4), 64);
694 memcpy(nv12t_dest+tiled_offset+64*5, yuv420_src+left+j+yuv420_width*(i+top+5), 64);
695 memcpy(nv12t_dest+tiled_offset+64*6, yuv420_src+left+j+yuv420_width*(i+top+6), 64);
696 memcpy(nv12t_dest+tiled_offset+64*7, yuv420_src+left+j+yuv420_width*(i+top+7), 64);
697 memcpy(nv12t_dest+tiled_offset+64*8, yuv420_src+left+j+yuv420_width*(i+top+8), 64);
698 memcpy(nv12t_dest+tiled_offset+64*9, yuv420_src+left+j+yuv420_width*(i+top+9), 64);
699 memcpy(nv12t_dest+tiled_offset+64*10, yuv420_src+left+j+yuv420_width*(i+top+10), 64);
700 memcpy(nv12t_dest+tiled_offset+64*11, yuv420_src+left+j+yuv420_width*(i+top+11), 64);
701 memcpy(nv12t_dest+tiled_offset+64*12, yuv420_src+left+j+yuv420_width*(i+top+12), 64);
702 memcpy(nv12t_dest+tiled_offset+64*13, yuv420_src+left+j+yuv420_width*(i+top+13), 64);
703 memcpy(nv12t_dest+tiled_offset+64*14, yuv420_src+left+j+yuv420_width*(i+top+14), 64);
704 memcpy(nv12t_dest+tiled_offset+64*15, yuv420_src+left+j+yuv420_width*(i+top+15), 64);
705 memcpy(nv12t_dest+tiled_offset+64*16, yuv420_src+left+j+yuv420_width*(i+top+16), 64);
706 memcpy(nv12t_dest+tiled_offset+64*17, yuv420_src+left+j+yuv420_width*(i+top+17), 64);
707 memcpy(nv12t_dest+tiled_offset+64*18, yuv420_src+left+j+yuv420_width*(i+top+18), 64);
708 memcpy(nv12t_dest+tiled_offset+64*19, yuv420_src+left+j+yuv420_width*(i+top+19), 64);
709 memcpy(nv12t_dest+tiled_offset+64*20, yuv420_src+left+j+yuv420_width*(i+top+20), 64);
710 memcpy(nv12t_dest+tiled_offset+64*21, yuv420_src+left+j+yuv420_width*(i+top+21), 64);
711 memcpy(nv12t_dest+tiled_offset+64*22, yuv420_src+left+j+yuv420_width*(i+top+22), 64);
712 memcpy(nv12t_dest+tiled_offset+64*23, yuv420_src+left+j+yuv420_width*(i+top+23), 64);
713 memcpy(nv12t_dest+tiled_offset+64*24, yuv420_src+left+j+yuv420_width*(i+top+24), 64);
714 memcpy(nv12t_dest+tiled_offset+64*25, yuv420_src+left+j+yuv420_width*(i+top+25), 64);
715 memcpy(nv12t_dest+tiled_offset+64*26, yuv420_src+left+j+yuv420_width*(i+top+26), 64);
716 memcpy(nv12t_dest+tiled_offset+64*27, yuv420_src+left+j+yuv420_width*(i+top+27), 64);
717 memcpy(nv12t_dest+tiled_offset+64*28, yuv420_src+left+j+yuv420_width*(i+top+28), 64);
718 memcpy(nv12t_dest+tiled_offset+64*29, yuv420_src+left+j+yuv420_width*(i+top+29), 64);
719 memcpy(nv12t_dest+tiled_offset+64*30, yuv420_src+left+j+yuv420_width*(i+top+30), 64);
720 memcpy(nv12t_dest+tiled_offset+64*31, yuv420_src+left+j+yuv420_width*(i+top+31), 64);
721 }
722 }
723
724 for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+2) {
725 for (j=0; j<aligned_x_size; j=j+64) {
726 tiled_offset = 0;
727 tiled_x_index = j>>6;
728 tiled_y_index = i>>5;
729 if (tiled_y_index & 0x1) {
730 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
731 tiled_offset = tiled_y_index-1;
732 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
733 tiled_offset = tiled_offset*(temp1>>6);
734 tiled_offset = tiled_offset+tiled_x_index;
735 tiled_offset = tiled_offset+2;
736 temp1 = (tiled_x_index>>2)<<2;
737 tiled_offset = tiled_offset+temp1;
738 tiled_offset = tiled_offset<<11;
739 } else {
740 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
741 if ((i+32)<temp2) {
742 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
743 temp1 = tiled_x_index+2;
744 temp1 = (temp1>>2)<<2;
745 tiled_offset = tiled_x_index+temp1;
746 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
747 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
748 tiled_offset = tiled_offset<<11;
749 } else {
750 /* even2 fomula: x+x_block_num*y */
751 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
752 tiled_offset = tiled_y_index*(temp1>>6);
753 tiled_offset = tiled_offset+tiled_x_index;
754 tiled_offset = tiled_offset<<11;
755 }
756 }
757
758 temp1 = i&0x1F;
759 memcpy(nv12t_dest+tiled_offset+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 64);
760 memcpy(nv12t_dest+tiled_offset+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 64);
761 }
762 }
763
764 for (i=0; i<(yuv420_height-top-buttom); i=i+2) {
765 for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) {
766 tiled_offset = 0;
767 tiled_x_index = j>>6;
768 tiled_y_index = i>>5;
769 if (tiled_y_index & 0x1) {
770 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
771 tiled_offset = tiled_y_index-1;
772 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
773 tiled_offset = tiled_offset*(temp1>>6);
774 tiled_offset = tiled_offset+tiled_x_index;
775 tiled_offset = tiled_offset+2;
776 temp1 = (tiled_x_index>>2)<<2;
777 tiled_offset = tiled_offset+temp1;
778 tiled_offset = tiled_offset<<11;
779 } else {
780 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
781 if ((i+32)<temp2) {
782 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
783 temp1 = tiled_x_index+2;
784 temp1 = (temp1>>2)<<2;
785 tiled_offset = tiled_x_index+temp1;
786 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
787 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
788 tiled_offset = tiled_offset<<11;
789 } else {
790 /* even2 fomula: x+x_block_num*y */
791 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
792 tiled_offset = tiled_y_index*(temp1>>6);
793 tiled_offset = tiled_offset+tiled_x_index;
794 tiled_offset = tiled_offset<<11;
795 }
796 }
797
798 temp1 = i&0x1F;
799 temp2 = j&0x3F;
800 memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1), yuv420_src+left+j+yuv420_width*(i+top), 2);
801 memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1+1), yuv420_src+left+j+yuv420_width*(i+top+1), 2);
802 }
803 }
804
805}
806
807/*
808 * Converts and Interleaves linear to tiled
809 * Crops left, top, right, buttom
810 * 1. UV of YUV420P to UV of NV12T
811 *
812 * @param nv12t_uv_dest
813 * UV plane address of NV12T[out]
814 *
815 * @param yuv420p_u_src
816 * U plane address of YUV420P[in]
817 *
818 * @param yuv420p_v_src
819 * V plane address of YUV420P[in]
820 *
821 * @param yuv420_width
822 * Width of YUV420[in]
823 *
824 * @param yuv420_uv_height
825 * Height/2 of YUV420[in]
826 *
827 * @param left
828 * Crop size of left
829 *
830 * @param top
831 * Crop size of top
832 *
833 * @param right
834 * Crop size of right
835 *
836 * @param buttom
837 * Crop size of buttom
838 */
839static void csc_linear_to_tiled_interleave_crop(
840 unsigned char *nv12t_uv_dest,
841 unsigned char *yuv420_u_src,
842 unsigned char *yuv420_v_src,
843 unsigned int yuv420_width,
844 unsigned int yuv420_height,
845 unsigned int left,
846 unsigned int top,
847 unsigned int right,
848 unsigned int buttom)
849{
850 unsigned int i, j;
851 unsigned int tiled_x_index = 0, tiled_y_index = 0;
852 unsigned int aligned_x_size = 0, aligned_y_size = 0;
853 unsigned int tiled_offset = 0;
854 unsigned int temp1 = 0, temp2 = 0;
855
856 aligned_y_size = ((yuv420_height-top-buttom)>>5)<<5;
857 aligned_x_size = ((yuv420_width-left-right)>>6)<<6;
858
859 for (i=0; i<aligned_y_size; i=i+32) {
860 for (j=0; j<aligned_x_size; j=j+64) {
861 tiled_offset = 0;
862 tiled_x_index = j>>6;
863 tiled_y_index = i>>5;
864 if (tiled_y_index & 0x1) {
865 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
866 tiled_offset = tiled_y_index-1;
867 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
868 tiled_offset = tiled_offset*(temp1>>6);
869 tiled_offset = tiled_offset+tiled_x_index;
870 tiled_offset = tiled_offset+2;
871 temp1 = (tiled_x_index>>2)<<2;
872 tiled_offset = tiled_offset+temp1;
873 tiled_offset = tiled_offset<<11;
874 } else {
875 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
876 if ((i+32)<temp2) {
877 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
878 temp1 = tiled_x_index+2;
879 temp1 = (temp1>>2)<<2;
880 tiled_offset = tiled_x_index+temp1;
881 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
882 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
883 tiled_offset = tiled_offset<<11;
884 } else {
885 /* even2 fomula: x+x_block_num*y */
886 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
887 tiled_offset = tiled_y_index*(temp1>>6);
888 tiled_offset = tiled_offset+tiled_x_index;
889 tiled_offset = tiled_offset<<11;
890 }
891 }
892
893 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset,
894 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
895 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32);
896 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*1,
897 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+1),
898 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+1), 32);
899 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*2,
900 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+2),
901 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+2), 32);
902 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*3,
903 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+3),
904 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+3), 32);
905 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*4,
906 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+4),
907 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+4), 32);
908 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*5,
909 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+5),
910 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+5), 32);
911 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*6,
912 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+6),
913 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+6), 32);
914 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*7,
915 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+7),
916 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+7), 32);
917 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*8,
918 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+8),
919 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+8), 32);
920 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*9,
921 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+9),
922 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+9), 32);
923 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*10,
924 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+10),
925 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+10), 32);
926 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*11,
927 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+11),
928 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+11), 32);
929 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*12,
930 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+12),
931 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+12), 32);
932 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*13,
933 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+13),
934 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+13), 32);
935 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*14,
936 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+14),
937 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+14), 32);
938 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*15,
939 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+15),
940 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+15), 32);
941 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*16,
942 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+16),
943 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+16), 32);
944 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*17,
945 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+17),
946 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+17), 32);
947 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*18,
948 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+18),
949 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+18), 32);
950 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*19,
951 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+19),
952 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+19), 32);
953 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*20,
954 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+20),
955 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+20), 32);
956 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*21,
957 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+21),
958 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+21), 32);
959 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*22,
960 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+22),
961 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+22), 32);
962 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*23,
963 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+23),
964 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+23), 32);
965 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*24,
966 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+24),
967 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+24), 32);
968 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*25,
969 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+25),
970 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+25), 32);
971 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*26,
972 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+26),
973 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+26), 32);
974 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*27,
975 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+27),
976 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+27), 32);
977 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*28,
978 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+28),
979 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+28), 32);
980 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*29,
981 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+29),
982 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+29), 32);
983 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*30,
984 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+30),
985 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+30), 32);
986 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*31,
987 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top+31),
988 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top+31), 32);
989
990 }
991 }
992
993 for (i=aligned_y_size; i<(yuv420_height-top-buttom); i=i+1) {
994 for (j=0; j<aligned_x_size; j=j+64) {
995 tiled_offset = 0;
996 tiled_x_index = j>>6;
997 tiled_y_index = i>>5;
998 if (tiled_y_index & 0x1) {
999 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
1000 tiled_offset = tiled_y_index-1;
1001 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1002 tiled_offset = tiled_offset*(temp1>>6);
1003 tiled_offset = tiled_offset+tiled_x_index;
1004 tiled_offset = tiled_offset+2;
1005 temp1 = (tiled_x_index>>2)<<2;
1006 tiled_offset = tiled_offset+temp1;
1007 tiled_offset = tiled_offset<<11;
1008 } else {
1009 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
1010 if ((i+32)<temp2) {
1011 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
1012 temp1 = tiled_x_index+2;
1013 temp1 = (temp1>>2)<<2;
1014 tiled_offset = tiled_x_index+temp1;
1015 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1016 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
1017 tiled_offset = tiled_offset<<11;
1018 } else {
1019 /* even2 fomula: x+x_block_num*y */
1020 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1021 tiled_offset = tiled_y_index*(temp1>>6);
1022 tiled_offset = tiled_offset+tiled_x_index;
1023 tiled_offset = tiled_offset<<11;
1024 }
1025 }
1026 temp1 = i&0x1F;
1027 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1),
1028 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
1029 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 32);
1030 }
1031 }
1032
1033 for (i=0; i<(yuv420_height-top-buttom); i=i+1) {
1034 for (j=aligned_x_size; j<(yuv420_width-left-right); j=j+2) {
1035 tiled_offset = 0;
1036 tiled_x_index = j>>6;
1037 tiled_y_index = i>>5;
1038 if (tiled_y_index & 0x1) {
1039 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
1040 tiled_offset = tiled_y_index-1;
1041 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1042 tiled_offset = tiled_offset*(temp1>>6);
1043 tiled_offset = tiled_offset+tiled_x_index;
1044 tiled_offset = tiled_offset+2;
1045 temp1 = (tiled_x_index>>2)<<2;
1046 tiled_offset = tiled_offset+temp1;
1047 tiled_offset = tiled_offset<<11;
1048 } else {
1049 temp2 = (((yuv420_height-top-buttom)+31)>>5)<<5;
1050 if ((i+32)<temp2) {
1051 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
1052 temp1 = tiled_x_index+2;
1053 temp1 = (temp1>>2)<<2;
1054 tiled_offset = tiled_x_index+temp1;
1055 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1056 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6);
1057 tiled_offset = tiled_offset<<11;
1058 } else {
1059 /* even2 fomula: x+x_block_num*y */
1060 temp1 = (((yuv420_width-left-right)+127)>>7)<<7;
1061 tiled_offset = tiled_y_index*(temp1>>6);
1062 tiled_offset = tiled_offset+tiled_x_index;
1063 tiled_offset = tiled_offset<<11;
1064 }
1065 }
1066 temp1 = i&0x1F;
1067 temp2 = j&0x3F;
1068 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1),
1069 yuv420_u_src+left/2+j/2+yuv420_width/2*(i+top),
1070 yuv420_v_src+left/2+j/2+yuv420_width/2*(i+top), 1);
1071 }
1072 }
1073
1074}
1075
1076
1077/*
1078 * Converts tiled data to linear
1079 * Crops left, top, right, buttom
1080 * 1. Y of NV12T to Y of YUV420P
1081 * 2. Y of NV12T to Y of YUV420S
1082 * 3. UV of NV12T to UV of YUV420S
1083 *
1084 * @param yuv420_dest
1085 * Y or UV plane address of YUV420[out]
1086 *
1087 * @param nv12t_src
1088 * Y or UV plane address of NV12T[in]
1089 *
1090 * @param yuv420_width
1091 * Width of YUV420[in]
1092 *
1093 * @param yuv420_height
1094 * Y: Height of YUV420, UV: Height/2 of YUV420[in]
1095 *
1096 * @param left
1097 * Crop size of left
1098 *
1099 * @param top
1100 * Crop size of top
1101 *
1102 * @param right
1103 * Crop size of right
1104 *
1105 * @param buttom
1106 * Crop size of buttom
1107 */
1108void csc_tiled_to_linear_crop_neon(
1109 unsigned char *yuv420_dest,
1110 unsigned char *nv12t_src,
1111 unsigned int yuv420_width,
1112 unsigned int yuv420_height,
1113 unsigned int left,
1114 unsigned int top,
1115 unsigned int right,
1116 unsigned int buttom);
1117
1118/*
1119 * Converts and Deinterleaves tiled data to linear
1120 * Crops left, top, right, buttom
1121 * 1. UV of NV12T to UV of YUV420P
1122 *
1123 * @param yuv420_u_dest
1124 * U plane address of YUV420P[out]
1125 *
1126 * @param yuv420_v_dest
1127 * V plane address of YUV420P[out]
1128 *
1129 * @param nv12t_src
1130 * UV plane address of NV12T[in]
1131 *
1132 * @param yuv420_width
1133 * Width of YUV420[in]
1134 *
1135 * @param yuv420_uv_height
1136 * Height/2 of YUV420[in]
1137 *
1138 * @param left
1139 * Crop size of left
1140 *
1141 * @param top
1142 * Crop size of top
1143 *
1144 * @param right
1145 * Crop size of right
1146 *
1147 * @param buttom
1148 * Crop size of buttom
1149 */
1150void csc_tiled_to_linear_deinterleave_crop_neon(
1151 unsigned char *yuv420_u_dest,
1152 unsigned char *yuv420_v_dest,
1153 unsigned char *nv12t_uv_src,
1154 unsigned int yuv420_width,
1155 unsigned int yuv420_uv_height,
1156 unsigned int left,
1157 unsigned int top,
1158 unsigned int right,
1159 unsigned int buttom);
1160
1161/*
1162 * Converts linear data to tiled
1163 * Crops left, top, right, buttom
1164 * 1. Y of YUV420P to Y of NV12T
1165 * 2. Y of YUV420S to Y of NV12T
1166 * 3. UV of YUV420S to UV of NV12T
1167 *
1168 * @param nv12t_dest
1169 * Y or UV plane address of NV12T[out]
1170 *
1171 * @param yuv420_src
1172 * Y or UV plane address of YUV420P(S)[in]
1173 *
1174 * @param yuv420_width
1175 * Width of YUV420[in]
1176 *
1177 * @param yuv420_height
1178 * Y: Height of YUV420, UV: Height/2 of YUV420[in]
1179 *
1180 * @param left
1181 * Crop size of left
1182 *
1183 * @param top
1184 * Crop size of top
1185 *
1186 * @param right
1187 * Crop size of right
1188 *
1189 * @param buttom
1190 * Crop size of buttom
1191 */
1192void csc_linear_to_tiled_crop_neon(
1193 unsigned char *nv12t_dest,
1194 unsigned char *yuv420_src,
1195 unsigned int yuv420_width,
1196 unsigned int yuv420_height,
1197 unsigned int left,
1198 unsigned int top,
1199 unsigned int right,
1200 unsigned int buttom);
1201
1202/*
1203 * Converts and Interleaves linear to tiled
1204 * Crops left, top, right, buttom
1205 * 1. UV of YUV420P to UV of NV12T
1206 *
1207 * @param nv12t_uv_dest
1208 * UV plane address of NV12T[out]
1209 *
1210 * @param yuv420p_u_src
1211 * U plane address of YUV420P[in]
1212 *
1213 * @param yuv420p_v_src
1214 * V plane address of YUV420P[in]
1215 *
1216 * @param yuv420_width
1217 * Width of YUV420[in]
1218 *
1219 * @param yuv420_uv_height
1220 * Height/2 of YUV420[in]
1221 *
1222 * @param left
1223 * Crop size of left
1224 *
1225 * @param top
1226 * Crop size of top
1227 *
1228 * @param right
1229 * Crop size of right
1230 *
1231 * @param buttom
1232 * Crop size of buttom
1233 */
1234void csc_linear_to_tiled_interleave_crop_neon(
1235 unsigned char *nv12t_uv_dest,
1236 unsigned char *yuv420_u_src,
1237 unsigned char *yuv420_v_src,
1238 unsigned int yuv420_width,
1239 unsigned int yuv420_height,
1240 unsigned int left,
1241 unsigned int top,
1242 unsigned int right,
1243 unsigned int buttom);
1244
1245/*
1246 * Converts tiled data to linear.
1247 * 1. y of nv12t to y of yuv420p
1248 * 2. y of nv12t to y of yuv420s
1249 *
1250 * @param dst
1251 * y address of yuv420[out]
1252 *
1253 * @param src
1254 * y address of nv12t[in]
1255 *
1256 * @param yuv420_width
1257 * real width of yuv420[in]
1258 * it should be even
1259 *
1260 * @param yuv420_height
1261 * real height of yuv420[in]
1262 * it should be even.
1263 *
1264 */
1265void csc_tiled_to_linear_y(
1266 unsigned char *y_dst,
1267 unsigned char *y_src,
1268 unsigned int width,
1269 unsigned int height)
1270{
1271 csc_tiled_to_linear_crop(y_dst, y_src, width, height, 0, 0, 0, 0);
1272}
1273
1274/*
1275 * Converts tiled data to linear
1276 * 1. uv of nv12t to y of yuv420s
1277 *
1278 * @param dst
1279 * uv address of yuv420s[out]
1280 *
1281 * @param src
1282 * uv address of nv12t[in]
1283 *
1284 * @param yuv420_width
1285 * real width of yuv420s[in]
1286 *
1287 * @param yuv420_height
1288 * real height of yuv420s[in]
1289 *
1290 */
1291void csc_tiled_to_linear_uv(
1292 unsigned char *uv_dst,
1293 unsigned char *uv_src,
1294 unsigned int width,
1295 unsigned int height)
1296{
1297 csc_tiled_to_linear_crop(uv_dst, uv_src, width, height, 0, 0, 0, 0);
1298}
1299
1300/*
1301 * Converts tiled data to linear
1302 * 1. uv of nt12t to uv of yuv420p
1303 *
1304 * @param u_dst
1305 * u address of yuv420p[out]
1306 *
1307 * @param v_dst
1308 * v address of yuv420p[out]
1309 *
1310 * @param uv_src
1311 * uv address of nt12t[in]
1312 *
1313 * @param yuv420_width
1314 * real width of yuv420p[in]
1315 *
1316 * @param yuv420_height
1317 * real height of yuv420p[in]
1318 */
1319void csc_tiled_to_linear_uv_deinterleave(
1320 unsigned char *u_dst,
1321 unsigned char *v_dst,
1322 unsigned char *uv_src,
1323 unsigned int width,
1324 unsigned int height)
1325{
1326 csc_tiled_to_linear_deinterleave_crop(u_dst, v_dst, uv_src, width, height,
1327 0, 0, 0, 0);
1328}
1329
1330/*
1331 * Converts linear data to tiled
1332 * 1. y of yuv420 to y of nv12t
1333 *
1334 * @param dst
1335 * y address of nv12t[out]
1336 *
1337 * @param src
1338 * y address of yuv420[in]
1339 *
1340 * @param yuv420_width
1341 * real width of yuv420[in]
1342 * it should be even
1343 *
1344 * @param yuv420_height
1345 * real height of yuv420[in]
1346 * it should be even.
1347 *
1348 */
1349void csc_linear_to_tiled_y(
1350 unsigned char *y_dst,
1351 unsigned char *y_src,
1352 unsigned int width,
1353 unsigned int height)
1354{
1355 csc_linear_to_tiled_crop(y_dst, y_src, width, height, 0, 0, 0, 0);
1356}
1357
1358/*
1359 * Converts and interleaves linear data to tiled
1360 * 1. uv of nv12t to uv of yuv420
1361 *
1362 * @param dst
1363 * uv address of nv12t[out]
1364 *
1365 * @param src
1366 * u address of yuv420[in]
1367 *
1368 * @param src
1369 * v address of yuv420[in]
1370 *
1371 * @param yuv420_width
1372 * real width of yuv420[in]
1373 *
1374 * @param yuv420_height
1375 * real height of yuv420[in]
1376 *
1377 */
1378void csc_linear_to_tiled_uv(
1379 unsigned char *uv_dst,
1380 unsigned char *u_src,
1381 unsigned char *v_src,
1382 unsigned int width,
1383 unsigned int height)
1384{
1385 csc_linear_to_tiled_interleave_crop(uv_dst, u_src, v_src, width, height,
1386 0, 0, 0, 0);
1387}
1388
1389/*
1390 * Converts tiled data to linear for mfc 6.x
1391 * 1. Y of NV12T to Y of YUV420P
1392 * 2. Y of NV12T to Y of YUV420S
1393 *
1394 * @param dst
1395 * Y address of YUV420[out]
1396 *
1397 * @param src
1398 * Y address of NV12T[in]
1399 *
1400 * @param yuv420_width
1401 * real width of YUV420[in]
1402 *
1403 * @param yuv420_height
1404 * Y: real height of YUV420[in]
1405 *
1406 */
1407void csc_tiled_to_linear_y_neon(
1408 unsigned char *y_dst,
1409 unsigned char *y_src,
1410 unsigned int width,
1411 unsigned int height)
1412{
1413 csc_tiled_to_linear_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0);
1414}
1415
1416/*
1417 * Converts tiled data to linear for mfc 6.x
1418 * 1. UV of NV12T to Y of YUV420S
1419 *
1420 * @param u_dst
1421 * UV plane address of YUV420P[out]
1422 *
1423 * @param nv12t_src
1424 * Y or UV plane address of NV12T[in]
1425 *
1426 * @param yuv420_width
1427 * real width of YUV420[in]
1428 *
1429 * @param yuv420_height
1430 * (real height)/2 of YUV420[in]
1431 */
1432void csc_tiled_to_linear_uv_neon(
1433 unsigned char *uv_dst,
1434 unsigned char *uv_src,
1435 unsigned int width,
1436 unsigned int height)
1437{
1438 csc_tiled_to_linear_crop_neon(uv_dst, uv_src, width, height, 0, 0, 0, 0);
1439}
1440
1441/*
1442 * Converts tiled data to linear for mfc 6.x
1443 * Deinterleave src to u_dst, v_dst
1444 * 1. UV of NV12T to Y of YUV420P
1445 *
1446 * @param u_dst
1447 * U plane address of YUV420P[out]
1448 *
1449 * @param v_dst
1450 * V plane address of YUV420P[out]
1451 *
1452 * @param nv12t_src
1453 * Y or UV plane address of NV12T[in]
1454 *
1455 * @param yuv420_width
1456 * real width of YUV420[in]
1457 *
1458 * @param yuv420_height
1459 * (real height)/2 of YUV420[in]
1460 */
1461void csc_tiled_to_linear_uv_deinterleave_neon(
1462 unsigned char *u_dst,
1463 unsigned char *v_dst,
1464 unsigned char *uv_src,
1465 unsigned int width,
1466 unsigned int height)
1467{
1468 csc_tiled_to_linear_deinterleave_crop_neon(u_dst, v_dst, uv_src, width, height,
1469 0, 0, 0, 0);
1470}
1471
1472/*
1473 * Converts linear data to tiled
1474 * 1. y of yuv420 to y of nv12t
1475 *
1476 * @param dst
1477 * y address of nv12t[out]
1478 *
1479 * @param src
1480 * y address of yuv420[in]
1481 *
1482 * @param yuv420_width
1483 * real width of yuv420[in]
1484 * it should be even
1485 *
1486 * @param yuv420_height
1487 * real height of yuv420[in]
1488 * it should be even.
1489 *
1490 */
1491void csc_linear_to_tiled_y_neon(
1492 unsigned char *y_dst,
1493 unsigned char *y_src,
1494 unsigned int width,
1495 unsigned int height)
1496{
1497 csc_linear_to_tiled_crop_neon(y_dst, y_src, width, height, 0, 0, 0, 0);
1498}
1499
1500/*
1501 * Converts and interleaves linear data to tiled
1502 * 1. uv of nv12t to uv of yuv420
1503 *
1504 * @param dst
1505 * uv address of nv12t[out]
1506 *
1507 * @param src
1508 * u address of yuv420[in]
1509 *
1510 * @param src
1511 * v address of yuv420[in]
1512 *
1513 * @param yuv420_width
1514 * real width of yuv420[in]
1515 *
1516 * @param yuv420_height
1517 * real height of yuv420[in]
1518 *
1519 */
1520void csc_linear_to_tiled_uv_neon(
1521 unsigned char *uv_dst,
1522 unsigned char *u_src,
1523 unsigned char *v_src,
1524 unsigned int width,
1525 unsigned int height)
1526{
1527 csc_linear_to_tiled_interleave_crop_neon(uv_dst, u_src, v_src,
1528 width, height, 0, 0, 0, 0);
1529}
1530
1531/*
1532 * Converts RGB565 to YUV420P
1533 *
1534 * @param y_dst
1535 * Y plane address of YUV420P[out]
1536 *
1537 * @param u_dst
1538 * U plane address of YUV420P[out]
1539 *
1540 * @param v_dst
1541 * V plane address of YUV420P[out]
1542 *
1543 * @param rgb_src
1544 * Address of RGB565[in]
1545 *
1546 * @param width
1547 * Width of RGB565[in]
1548 *
1549 * @param height
1550 * Height of RGB565[in]
1551 */
1552void csc_RGB565_to_YUV420P(
1553 unsigned char *y_dst,
1554 unsigned char *u_dst,
1555 unsigned char *v_dst,
1556 unsigned char *rgb_src,
1557 unsigned int width,
1558 unsigned int height)
1559{
1560 unsigned int i, j;
1561 unsigned int tmp;
1562
1563 unsigned int R, G, B;
1564 unsigned int Y, U, V;
1565
1566 unsigned int offset1 = width * height;
1567 unsigned int offset2 = width/2 * height/2;
1568
1569 unsigned short int *pSrc = (unsigned short int *)rgb_src;
1570
1571 unsigned char *pDstY = (unsigned char *)y_dst;
1572 unsigned char *pDstU = (unsigned char *)u_dst;
1573 unsigned char *pDstV = (unsigned char *)v_dst;
1574
1575 unsigned int yIndex = 0;
1576 unsigned int uIndex = 0;
1577 unsigned int vIndex = 0;
1578
1579 for (j = 0; j < height; j++) {
1580 for (i = 0; i < width; i++) {
1581 tmp = pSrc[j * width + i];
1582
1583 R = (tmp & 0x0000F800) >> 8;
1584 G = (tmp & 0x000007E0) >> 3;
1585 B = (tmp & 0x0000001F);
1586 B = B << 3;
1587
1588 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1589 Y = Y >> 8;
1590 Y += 16;
1591
1592 pDstY[yIndex++] = (unsigned char)Y;
1593
1594 if ((j % 2) == 0 && (i % 2) == 0) {
1595 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1596 U = U >> 8;
1597 U += 128;
1598 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1599 V = V >> 8;
1600 V += 128;
1601
1602 pDstU[uIndex++] = (unsigned char)U;
1603 pDstV[vIndex++] = (unsigned char)V;
1604 }
1605 }
1606 }
1607}
1608
1609/*
1610 * Converts RGB565 to YUV420SP
1611 *
1612 * @param y_dst
1613 * Y plane address of YUV420SP[out]
1614 *
1615 * @param uv_dst
1616 * UV plane address of YUV420SP[out]
1617 *
1618 * @param rgb_src
1619 * Address of RGB565[in]
1620 *
1621 * @param width
1622 * Width of RGB565[in]
1623 *
1624 * @param height
1625 * Height of RGB565[in]
1626 */
1627void csc_RGB565_to_YUV420SP(
1628 unsigned char *y_dst,
1629 unsigned char *uv_dst,
1630 unsigned char *rgb_src,
1631 unsigned int width,
1632 unsigned int height)
1633{
1634 unsigned int i, j;
1635 unsigned int tmp;
1636
1637 unsigned int R, G, B;
1638 unsigned int Y, U, V;
1639
1640 unsigned int offset = width * height;
1641
1642 unsigned short int *pSrc = (unsigned short int *)rgb_src;
1643
1644 unsigned char *pDstY = (unsigned char *)y_dst;
1645 unsigned char *pDstUV = (unsigned char *)uv_dst;
1646
1647 unsigned int yIndex = 0;
1648 unsigned int uvIndex = 0;
1649
1650 for (j = 0; j < height; j++) {
1651 for (i = 0; i < width; i++) {
1652 tmp = pSrc[j * width + i];
1653
1654 R = (tmp & 0x0000F800) >> 11;
1655 R = R * 8;
1656 G = (tmp & 0x000007E0) >> 5;
1657 G = G * 4;
1658 B = (tmp & 0x0000001F);
1659 B = B * 8;
1660
1661 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1662 Y = Y >> 8;
1663 Y += 16;
1664
1665 pDstY[yIndex++] = (unsigned char)Y;
1666
1667 if ((j % 2) == 0 && (i % 2) == 0) {
1668 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1669 U = U >> 8;
1670 U += 128;
1671 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1672 V = V >> 8;
1673 V += 128;
1674
1675 pDstUV[uvIndex++] = (unsigned char)U;
1676 pDstUV[uvIndex++] = (unsigned char)V;
1677 }
1678 }
1679 }
1680}
1681
1682/*
1683 * Converts ARGB8888 to YUV420P
1684 *
1685 * @param y_dst
1686 * Y plane address of YUV420P[out]
1687 *
1688 * @param u_dst
1689 * U plane address of YUV420P[out]
1690 *
1691 * @param v_dst
1692 * V plane address of YUV420P[out]
1693 *
1694 * @param rgb_src
1695 * Address of ARGB8888[in]
1696 *
1697 * @param width
1698 * Width of ARGB8888[in]
1699 *
1700 * @param height
1701 * Height of ARGB8888[in]
1702 */
1703void csc_ARGB8888_to_YUV420P(
1704 unsigned char *y_dst,
1705 unsigned char *u_dst,
1706 unsigned char *v_dst,
1707 unsigned char *rgb_src,
1708 unsigned int width,
1709 unsigned int height)
1710{
1711 unsigned int i, j;
1712 unsigned int tmp;
1713
1714 unsigned int R, G, B;
1715 unsigned int Y, U, V;
1716
1717 unsigned int offset1 = width * height;
1718 unsigned int offset2 = width/2 * height/2;
1719
1720 unsigned int *pSrc = (unsigned int *)rgb_src;
1721
1722 unsigned char *pDstY = (unsigned char *)y_dst;
1723 unsigned char *pDstU = (unsigned char *)u_dst;
1724 unsigned char *pDstV = (unsigned char *)v_dst;
1725
1726 unsigned int yIndex = 0;
1727 unsigned int uIndex = 0;
1728 unsigned int vIndex = 0;
1729
1730 for (j = 0; j < height; j++) {
1731 for (i = 0; i < width; i++) {
1732 tmp = pSrc[j * width + i];
1733
1734 R = (tmp & 0x00FF0000) >> 16;
1735 G = (tmp & 0x0000FF00) >> 8;
1736 B = (tmp & 0x000000FF);
1737
1738 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1739 Y = Y >> 8;
1740 Y += 16;
1741
1742 pDstY[yIndex++] = (unsigned char)Y;
1743
1744 if ((j % 2) == 0 && (i % 2) == 0) {
1745 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1746 U = U >> 8;
1747 U += 128;
1748 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1749 V = V >> 8;
1750 V += 128;
1751
1752 pDstU[uIndex++] = (unsigned char)U;
1753 pDstV[vIndex++] = (unsigned char)V;
1754 }
1755 }
1756 }
1757}
1758
1759
1760/*
1761 * Converts ARGB8888 to YUV420SP
1762 *
1763 * @param y_dst
1764 * Y plane address of YUV420SP[out]
1765 *
1766 * @param uv_dst
1767 * UV plane address of YUV420SP[out]
1768 *
1769 * @param rgb_src
1770 * Address of ARGB8888[in]
1771 *
1772 * @param width
1773 * Width of ARGB8888[in]
1774 *
1775 * @param height
1776 * Height of ARGB8888[in]
1777 */
1778void csc_ARGB8888_to_YUV420SP(
1779 unsigned char *y_dst,
1780 unsigned char *uv_dst,
1781 unsigned char *rgb_src,
1782 unsigned int width,
1783 unsigned int height)
1784{
1785 unsigned int i, j;
1786 unsigned int tmp;
1787
1788 unsigned int R, G, B;
1789 unsigned int Y, U, V;
1790
1791 unsigned int offset = width * height;
1792
1793 unsigned int *pSrc = (unsigned int *)rgb_src;
1794
1795 unsigned char *pDstY = (unsigned char *)y_dst;
1796 unsigned char *pDstUV = (unsigned char *)uv_dst;
1797
1798 unsigned int yIndex = 0;
1799 unsigned int uvIndex = 0;
1800
1801 for (j = 0; j < height; j++) {
1802 for (i = 0; i < width; i++) {
1803 tmp = pSrc[j * width + i];
1804
1805 R = (tmp & 0x00FF0000) >> 16;
1806 G = (tmp & 0x0000FF00) >> 8;
1807 B = (tmp & 0x000000FF);
1808
1809 Y = ((66 * R) + (129 * G) + (25 * B) + 128);
1810 Y = Y >> 8;
1811 Y += 16;
1812
1813 pDstY[yIndex++] = (unsigned char)Y;
1814
1815 if ((j % 2) == 0 && (i % 2) == 0) {
1816 U = ((-38 * R) - (74 * G) + (112 * B) + 128);
1817 U = U >> 8;
1818 U += 128;
1819 V = ((112 * R) - (94 * G) - (18 * B) + 128);
1820 V = V >> 8;
1821 V += 128;
1822
1823 pDstUV[uvIndex++] = (unsigned char)U;
1824 pDstUV[uvIndex++] = (unsigned char)V;
1825 }
1826 }
1827 }
1828}