1 /* 2 * 3 * Copyright 2011 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 color_space_convertor.c 20 * @brief SEC_OMX specific define 21 * @author ShinWon Lee (shinwon.lee (at) samsung.com) 22 * @version 1.0 23 * @history 24 * 2011.7.01 : Create 25 */ 26 27 #include "stdlib.h" 28 #include "color_space_convertor.h" 29 30 #define TILED_SIZE 64*32 31 32 /* 33 * De-interleaves src to dest1, dest2 34 * 35 * @param dest1 36 * Address of de-interleaved data[out] 37 * 38 * @param dest2 39 * Address of de-interleaved data[out] 40 * 41 * @param src 42 * Address of interleaved data[in] 43 * 44 * @param src_size 45 * Size of interleaved data[in] 46 */ 47 void csc_deinterleave_memcpy(char *dest1, char *dest2, char *src, int src_size) 48 { 49 int i = 0; 50 for(i=0; i<src_size/2; i++) { 51 dest1[i] = src[i*2]; 52 dest2[i] = src[i*2+1]; 53 } 54 } 55 56 /* 57 * Interleaves src1, src2 to dest 58 * 59 * @param dest 60 * Address of interleaved data[out] 61 * 62 * @param src1 63 * Address of de-interleaved data[in] 64 * 65 * @param src2 66 * Address of de-interleaved data[in] 67 * 68 * @param src_size 69 * Size of de-interleaved data[in] 70 */ 71 void csc_interleave_memcpy(char *dest, char *src1, char *src2, int src_size) 72 { 73 int i = 0; 74 for(i=0; i<src_size; i++) { 75 dest[i*2] = src1[i]; 76 dest[i*2+1] = src2[i]; 77 } 78 } 79 80 /* 81 * Converts tiled data to linear. 82 * 1. Y of NV12T to Y of YUV420P 83 * 2. Y of NV12T to Y of YUV420S 84 * 3. UV of NV12T to UV of YUV420S 85 * 86 * @param yuv420_dest 87 * Y or UV plane address of YUV420[out] 88 * 89 * @param nv12t_src 90 * Y or UV plane address of NV12T[in] 91 * 92 * @param yuv420_width 93 * Width of YUV420[in] 94 * 95 * @param yuv420_height 96 * Y: Height of YUV420, UV: Height/2 of YUV420[in] 97 */ 98 void csc_tiled_to_linear(char *yuv420_dest, char *nv12t_src, int yuv420_width, int yuv420_height) 99 { 100 unsigned int i, j; 101 unsigned int tiled_x_index = 0, tiled_y_index = 0; 102 unsigned int aligned_x_size = 0; 103 unsigned int tiled_offset = 0, tiled_offset1 = 0, tiled_offset2 = 0, tiled_offset3 = 0; 104 unsigned int temp1 = 0, temp2 = 0; 105 106 if (yuv420_width >= 1024) { 107 for (i=0; i<yuv420_height; i=i+1) { 108 tiled_offset = 0; 109 tiled_y_index = i>>5; 110 if (tiled_y_index & 0x1) { 111 /* odd fomula: 2+x_block_num*(y-1) */ 112 tiled_offset = tiled_y_index-1; 113 temp1 = ((yuv420_width+127)>>7)<<7; 114 tiled_offset = tiled_offset*(temp1>>6); 115 tiled_offset = tiled_offset+2; 116 tiled_offset = tiled_offset<<11; 117 tiled_offset1 = tiled_offset+2048*1; 118 tiled_offset2 = tiled_offset+2048*2; 119 tiled_offset3 = tiled_offset+2048*3; 120 temp2 = 8; 121 } else { 122 temp2 = ((yuv420_height+31)>>5)<<5; 123 /* even fomula: x_block_num*y */ 124 temp1 = ((yuv420_width+127)>>7)<<7; 125 tiled_offset = tiled_y_index*(temp1>>6); 126 tiled_offset = tiled_offset<<11; 127 if ((i+32)<temp2) { 128 tiled_offset1 = tiled_offset+2048*1; 129 tiled_offset2 = tiled_offset+2048*6; 130 tiled_offset3 = tiled_offset+2048*7; 131 temp2 = 8; 132 } else { 133 tiled_offset1 = tiled_offset+2048*1; 134 tiled_offset2 = tiled_offset+2048*2; 135 tiled_offset3 = tiled_offset+2048*3; 136 temp2 = 4; 137 } 138 } 139 temp1 = i&0x1F; 140 memcpy(yuv420_dest+yuv420_width*(i), nv12t_src+tiled_offset+64*(temp1), 64); 141 memcpy(yuv420_dest+yuv420_width*(i)+64*1, nv12t_src+tiled_offset1+64*(temp1), 64); 142 memcpy(yuv420_dest+yuv420_width*(i)+64*2, nv12t_src+tiled_offset2+64*(temp1), 64); 143 memcpy(yuv420_dest+yuv420_width*(i)+64*3, nv12t_src+tiled_offset3+64*(temp1), 64); 144 145 tiled_offset = tiled_offset+temp2*2048; 146 tiled_offset1 = tiled_offset1+temp2*2048; 147 tiled_offset2 = tiled_offset2+temp2*2048; 148 tiled_offset3 = tiled_offset3+temp2*2048; 149 memcpy(yuv420_dest+yuv420_width*(i)+64*4, nv12t_src+tiled_offset+64*(temp1), 64); 150 memcpy(yuv420_dest+yuv420_width*(i)+64*5, nv12t_src+tiled_offset1+64*(temp1), 64); 151 memcpy(yuv420_dest+yuv420_width*(i)+64*6, nv12t_src+tiled_offset2+64*(temp1), 64); 152 memcpy(yuv420_dest+yuv420_width*(i)+64*7, nv12t_src+tiled_offset3+64*(temp1), 64); 153 154 tiled_offset = tiled_offset+temp2*2048; 155 tiled_offset1 = tiled_offset1+temp2*2048; 156 tiled_offset2 = tiled_offset2+temp2*2048; 157 tiled_offset3 = tiled_offset3+temp2*2048; 158 memcpy(yuv420_dest+yuv420_width*(i)+64*8, nv12t_src+tiled_offset+64*(temp1), 64); 159 memcpy(yuv420_dest+yuv420_width*(i)+64*9, nv12t_src+tiled_offset1+64*(temp1), 64); 160 memcpy(yuv420_dest+yuv420_width*(i)+64*10, nv12t_src+tiled_offset2+64*(temp1), 64); 161 memcpy(yuv420_dest+yuv420_width*(i)+64*11, nv12t_src+tiled_offset3+64*(temp1), 64); 162 163 tiled_offset = tiled_offset+temp2*2048; 164 tiled_offset1 = tiled_offset1+temp2*2048; 165 tiled_offset2 = tiled_offset2+temp2*2048; 166 tiled_offset3 = tiled_offset3+temp2*2048; 167 memcpy(yuv420_dest+yuv420_width*(i)+64*12, nv12t_src+tiled_offset+64*(temp1), 64); 168 memcpy(yuv420_dest+yuv420_width*(i)+64*13, nv12t_src+tiled_offset1+64*(temp1), 64); 169 memcpy(yuv420_dest+yuv420_width*(i)+64*14, nv12t_src+tiled_offset2+64*(temp1), 64); 170 memcpy(yuv420_dest+yuv420_width*(i)+64*15, nv12t_src+tiled_offset3+64*(temp1), 64); 171 } 172 aligned_x_size = 1024; 173 } 174 175 if ((yuv420_width-aligned_x_size) >= 512) { 176 for (i=0; i<yuv420_height; i=i+1) { 177 tiled_offset = 0; 178 tiled_y_index = i>>5; 179 if (tiled_y_index & 0x1) { 180 /* odd fomula: 2+x_block_num*(y-1) */ 181 tiled_offset = tiled_y_index-1; 182 temp1 = ((yuv420_width+127)>>7)<<7; 183 tiled_offset = tiled_offset*(temp1>>6); 184 tiled_offset = tiled_offset+2; 185 temp1 = aligned_x_size>>5; 186 tiled_offset = tiled_offset+temp1; 187 tiled_offset = tiled_offset<<11; 188 tiled_offset1 = tiled_offset+2048*1; 189 tiled_offset2 = tiled_offset+2048*2; 190 tiled_offset3 = tiled_offset+2048*3; 191 temp2 = 8; 192 } else { 193 temp2 = ((yuv420_height+31)>>5)<<5; 194 /* even fomula: x_block_num*y */ 195 temp1 = ((yuv420_width+127)>>7)<<7; 196 tiled_offset = tiled_y_index*(temp1>>6); 197 tiled_offset = tiled_offset<<11; 198 if ((i+32)<temp2) { 199 temp1 = aligned_x_size>>5; 200 tiled_offset = tiled_offset+(temp1<<11); 201 tiled_offset1 = tiled_offset+2048*1; 202 tiled_offset2 = tiled_offset+2048*6; 203 tiled_offset3 = tiled_offset+2048*7; 204 temp2 = 8; 205 } else { 206 temp1 = aligned_x_size>>6; 207 tiled_offset = tiled_offset+(temp1<<11); 208 tiled_offset1 = tiled_offset+2048*1; 209 tiled_offset2 = tiled_offset+2048*2; 210 tiled_offset3 = tiled_offset+2048*3; 211 temp2 = 4; 212 } 213 } 214 temp1 = i&0x1F; 215 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i), nv12t_src+tiled_offset+64*(temp1), 64); 216 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*1, nv12t_src+tiled_offset1+64*(temp1), 64); 217 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*2, nv12t_src+tiled_offset2+64*(temp1), 64); 218 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*3, nv12t_src+tiled_offset3+64*(temp1), 64); 219 220 tiled_offset = tiled_offset+temp2*2048; 221 tiled_offset1 = tiled_offset1+temp2*2048; 222 tiled_offset2 = tiled_offset2+temp2*2048; 223 tiled_offset3 = tiled_offset3+temp2*2048; 224 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*4, nv12t_src+tiled_offset+64*(temp1), 64); 225 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*5, nv12t_src+tiled_offset1+64*(temp1), 64); 226 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*6, nv12t_src+tiled_offset2+64*(temp1), 64); 227 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*7, nv12t_src+tiled_offset3+64*(temp1), 64); 228 } 229 aligned_x_size = aligned_x_size+512; 230 } 231 232 if ((yuv420_width-aligned_x_size) >= 256) { 233 for (i=0; i<yuv420_height; i=i+1) { 234 tiled_offset = 0; 235 tiled_y_index = i>>5; 236 if (tiled_y_index & 0x1) { 237 /* odd fomula: 2+x_block_num*(y-1) */ 238 tiled_offset = tiled_y_index-1; 239 temp1 = ((yuv420_width+127)>>7)<<7; 240 tiled_offset = tiled_offset*(temp1>>6); 241 tiled_offset = tiled_offset+2; 242 temp1 = aligned_x_size>>5; 243 tiled_offset = tiled_offset+temp1; 244 tiled_offset = tiled_offset<<11; 245 tiled_offset1 = tiled_offset+2048*1; 246 tiled_offset2 = tiled_offset+2048*2; 247 tiled_offset3 = tiled_offset+2048*3; 248 } else { 249 temp2 = ((yuv420_height+31)>>5)<<5; 250 /* even fomula: x_block_num*y */ 251 temp1 = ((yuv420_width+127)>>7)<<7; 252 tiled_offset = tiled_y_index*(temp1>>6); 253 tiled_offset = tiled_offset<<11; 254 if ((i+32)<temp2) { 255 temp1 = aligned_x_size>>5; 256 tiled_offset = tiled_offset+(temp1<<11); 257 tiled_offset1 = tiled_offset+2048*1; 258 tiled_offset2 = tiled_offset+2048*6; 259 tiled_offset3 = tiled_offset+2048*7; 260 } else { 261 temp1 = aligned_x_size>>6; 262 tiled_offset = tiled_offset+(temp1<<11); 263 tiled_offset1 = tiled_offset+2048*1; 264 tiled_offset2 = tiled_offset+2048*2; 265 tiled_offset3 = tiled_offset+2048*3; 266 } 267 } 268 temp1 = i&0x1F; 269 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i), nv12t_src+tiled_offset+64*(temp1), 64); 270 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*1, nv12t_src+tiled_offset1+64*(temp1), 64); 271 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*2, nv12t_src+tiled_offset2+64*(temp1), 64); 272 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64*3, nv12t_src+tiled_offset3+64*(temp1), 64); 273 } 274 aligned_x_size = aligned_x_size+256; 275 } 276 277 if ((yuv420_width-aligned_x_size) >= 128) { 278 for (i=0; i<yuv420_height; i=i+2) { 279 tiled_offset = 0; 280 tiled_y_index = i>>5; 281 if (tiled_y_index & 0x1) { 282 /* odd fomula: 2+x_block_num*(y-1) */ 283 tiled_offset = tiled_y_index-1; 284 temp1 = ((yuv420_width+127)>>7)<<7; 285 tiled_offset = tiled_offset*(temp1>>6); 286 tiled_offset = tiled_offset+2; 287 temp1 = aligned_x_size>>5; 288 tiled_offset = tiled_offset+temp1; 289 tiled_offset = tiled_offset<<11; 290 tiled_offset1 = tiled_offset+2048*1; 291 } else { 292 temp2 = ((yuv420_height+31)>>5)<<5; 293 /* even fomula: x_block_num*y */ 294 temp1 = ((yuv420_width+127)>>7)<<7; 295 tiled_offset = tiled_y_index*(temp1>>6); 296 tiled_offset = tiled_offset<<11; 297 if ((i+32)<temp2) { 298 temp1 = aligned_x_size>>5; 299 tiled_offset = tiled_offset+(temp1<<11); 300 tiled_offset1 = tiled_offset+2048*1; 301 } else { 302 temp1 = aligned_x_size>>6; 303 tiled_offset = tiled_offset+(temp1<<11); 304 tiled_offset1 = tiled_offset+2048*1; 305 } 306 } 307 temp1 = i&0x1F; 308 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i), nv12t_src+tiled_offset+64*(temp1), 64); 309 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i)+64, nv12t_src+tiled_offset1+64*(temp1), 64); 310 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i+1), nv12t_src+tiled_offset+64*(temp1+1), 64); 311 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i+1)+64, nv12t_src+tiled_offset1+64*(temp1+1), 64); 312 } 313 aligned_x_size = aligned_x_size+128; 314 } 315 316 if ((yuv420_width-aligned_x_size) >= 64) { 317 for (i=0; i<yuv420_height; i=i+4) { 318 tiled_offset = 0; 319 tiled_x_index = aligned_x_size>>6; 320 tiled_y_index = i>>5; 321 if (tiled_y_index & 0x1) { 322 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 323 tiled_offset = tiled_y_index-1; 324 temp1 = ((yuv420_width+127)>>7)<<7; 325 tiled_offset = tiled_offset*(temp1>>6); 326 tiled_offset = tiled_offset+tiled_x_index; 327 tiled_offset = tiled_offset+2; 328 temp1 = (tiled_x_index>>2)<<2; 329 tiled_offset = tiled_offset+temp1; 330 tiled_offset = tiled_offset<<11; 331 } else { 332 temp2 = ((yuv420_height+31)>>5)<<5; 333 if ((i+32)<temp2) { 334 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 335 temp1 = tiled_x_index+2; 336 temp1 = (temp1>>2)<<2; 337 tiled_offset = tiled_x_index+temp1; 338 temp1 = ((yuv420_width+127)>>7)<<7; 339 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 340 tiled_offset = tiled_offset<<11; 341 } else { 342 /* even2 fomula: x+x_block_num*y */ 343 temp1 = ((yuv420_width+127)>>7)<<7; 344 tiled_offset = tiled_y_index*(temp1>>6); 345 tiled_offset = tiled_offset+tiled_x_index; 346 tiled_offset = tiled_offset<<11; 347 } 348 } 349 350 temp1 = i&0x1F; 351 temp2 = aligned_x_size&0x3F; 352 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i), nv12t_src+tiled_offset+temp2+64*(temp1), 64); 353 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i+1), nv12t_src+tiled_offset+temp2+64*(temp1+1), 64); 354 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i+2), nv12t_src+tiled_offset+temp2+64*(temp1+2), 64); 355 memcpy(yuv420_dest+aligned_x_size+yuv420_width*(i+3), nv12t_src+tiled_offset+temp2+64*(temp1+3), 64); 356 } 357 aligned_x_size = aligned_x_size+64; 358 } 359 360 if (yuv420_width != aligned_x_size) { 361 for (i=0; i<yuv420_height; i=i+4) { 362 for (j=aligned_x_size; j<yuv420_width; j=j+4) { 363 tiled_offset = 0; 364 tiled_x_index = j>>6; 365 tiled_y_index = i>>5; 366 if (tiled_y_index & 0x1) { 367 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 368 tiled_offset = tiled_y_index-1; 369 temp1 = ((yuv420_width+127)>>7)<<7; 370 tiled_offset = tiled_offset*(temp1>>6); 371 tiled_offset = tiled_offset+tiled_x_index; 372 tiled_offset = tiled_offset+2; 373 temp1 = (tiled_x_index>>2)<<2; 374 tiled_offset = tiled_offset+temp1; 375 tiled_offset = tiled_offset<<11; 376 } else { 377 temp2 = ((yuv420_height+31)>>5)<<5; 378 if ((i+32)<temp2) { 379 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 380 temp1 = tiled_x_index+2; 381 temp1 = (temp1>>2)<<2; 382 tiled_offset = tiled_x_index+temp1; 383 temp1 = ((yuv420_width+127)>>7)<<7; 384 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 385 tiled_offset = tiled_offset<<11; 386 } else { 387 /* even2 fomula: x+x_block_num*y */ 388 temp1 = ((yuv420_width+127)>>7)<<7; 389 tiled_offset = tiled_y_index*(temp1>>6); 390 tiled_offset = tiled_offset+tiled_x_index; 391 tiled_offset = tiled_offset<<11; 392 } 393 } 394 395 temp1 = i&0x1F; 396 temp2 = j&0x3F; 397 memcpy(yuv420_dest+j+yuv420_width*(i), nv12t_src+tiled_offset+temp2+64*(temp1), 4); 398 memcpy(yuv420_dest+j+yuv420_width*(i+1), nv12t_src+tiled_offset+temp2+64*(temp1+1), 4); 399 memcpy(yuv420_dest+j+yuv420_width*(i+2), nv12t_src+tiled_offset+temp2+64*(temp1+2), 4); 400 memcpy(yuv420_dest+j+yuv420_width*(i+3), nv12t_src+tiled_offset+temp2+64*(temp1+3), 4); 401 } 402 } 403 } 404 } 405 406 /* 407 * Converts and Deinterleaves tiled data to linear 408 * 1. UV of NV12T to UV of YUV420P 409 * 410 * @param yuv420_u_dest 411 * U plane address of YUV420P[out] 412 * 413 * @param yuv420_v_dest 414 * V plane address of YUV420P[out] 415 * 416 * @param nv12t_src 417 * UV plane address of NV12T[in] 418 * 419 * @param yuv420_width 420 * Width of YUV420[in] 421 * 422 * @param yuv420_uv_height 423 * Height/2 of YUV420[in] 424 */ 425 void csc_tiled_to_linear_deinterleave(char *yuv420_u_dest, char *yuv420_v_dest, char *nv12t_uv_src, int yuv420_width, int yuv420_uv_height) 426 { 427 unsigned int i, j; 428 unsigned int tiled_x_index = 0, tiled_y_index = 0; 429 unsigned int aligned_x_size = 0; 430 unsigned int tiled_offset = 0, tiled_offset1 = 0, tiled_offset2 = 0, tiled_offset3 = 0; 431 unsigned int temp1 = 0, temp2 = 0; 432 433 if (yuv420_width >= 1024) { 434 for (i=0; i<yuv420_uv_height; i=i+1) { 435 tiled_offset = 0; 436 tiled_y_index = i>>5; 437 if (tiled_y_index & 0x1) { 438 /* odd fomula: 2+x_block_num*(y-1) */ 439 tiled_offset = tiled_y_index-1; 440 temp1 = ((yuv420_width+127)>>7)<<7; 441 tiled_offset = tiled_offset*(temp1>>6); 442 tiled_offset = tiled_offset+2; 443 tiled_offset = tiled_offset<<11; 444 tiled_offset1 = tiled_offset+2048*1; 445 tiled_offset2 = tiled_offset+2048*2; 446 tiled_offset3 = tiled_offset+2048*3; 447 temp2 = 8; 448 } else { 449 temp2 = ((yuv420_uv_height+31)>>5)<<5; 450 /* even fomula: x_block_num*y */ 451 temp1 = ((yuv420_width+127)>>7)<<7; 452 tiled_offset = tiled_y_index*(temp1>>6); 453 tiled_offset = tiled_offset<<11; 454 if ((i+32)<temp2) { 455 tiled_offset1 = tiled_offset+2048*1; 456 tiled_offset2 = tiled_offset+2048*6; 457 tiled_offset3 = tiled_offset+2048*7; 458 temp2 = 8; 459 } else { 460 tiled_offset1 = tiled_offset+2048*1; 461 tiled_offset2 = tiled_offset+2048*2; 462 tiled_offset3 = tiled_offset+2048*3; 463 temp2 = 4; 464 } 465 } 466 temp1 = i&0x1F; 467 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i), yuv420_v_dest+yuv420_width/2*(i), nv12t_uv_src+tiled_offset+64*(temp1), 64); 468 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*1, yuv420_v_dest+yuv420_width/2*(i)+32*1, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 469 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*2, yuv420_v_dest+yuv420_width/2*(i)+32*2, nv12t_uv_src+tiled_offset2+64*(temp1), 64); 470 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*3, yuv420_v_dest+yuv420_width/2*(i)+32*3, nv12t_uv_src+tiled_offset3+64*(temp1), 64); 471 472 tiled_offset = tiled_offset+temp2*2048; 473 tiled_offset1 = tiled_offset1+temp2*2048; 474 tiled_offset2 = tiled_offset2+temp2*2048; 475 tiled_offset3 = tiled_offset3+temp2*2048; 476 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*4, yuv420_v_dest+yuv420_width/2*(i)+32*4, nv12t_uv_src+tiled_offset+64*(temp1), 64); 477 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*5, yuv420_v_dest+yuv420_width/2*(i)+32*5, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 478 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*6, yuv420_v_dest+yuv420_width/2*(i)+32*6, nv12t_uv_src+tiled_offset2+64*(temp1), 64); 479 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*7, yuv420_v_dest+yuv420_width/2*(i)+32*7, nv12t_uv_src+tiled_offset3+64*(temp1), 64); 480 481 tiled_offset = tiled_offset+temp2*2048; 482 tiled_offset1 = tiled_offset1+temp2*2048; 483 tiled_offset2 = tiled_offset2+temp2*2048; 484 tiled_offset3 = tiled_offset3+temp2*2048; 485 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*8, yuv420_v_dest+yuv420_width/2*(i)+32*8, nv12t_uv_src+tiled_offset+64*(temp1), 64); 486 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*9, yuv420_v_dest+yuv420_width/2*(i)+32*9, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 487 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*10, yuv420_v_dest+yuv420_width/2*(i)+32*10, nv12t_uv_src+tiled_offset2+64*(temp1), 64); 488 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*11, yuv420_v_dest+yuv420_width/2*(i)+32*11, nv12t_uv_src+tiled_offset3+64*(temp1), 64); 489 490 tiled_offset = tiled_offset+temp2*2048; 491 tiled_offset1 = tiled_offset1+temp2*2048; 492 tiled_offset2 = tiled_offset2+temp2*2048; 493 tiled_offset3 = tiled_offset3+temp2*2048; 494 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*12, yuv420_v_dest+yuv420_width/2*(i)+32*12, nv12t_uv_src+tiled_offset+64*(temp1), 64); 495 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*13, yuv420_v_dest+yuv420_width/2*(i)+32*13, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 496 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*14, yuv420_v_dest+yuv420_width/2*(i)+32*14, nv12t_uv_src+tiled_offset2+64*(temp1), 64); 497 csc_deinterleave_memcpy(yuv420_u_dest+yuv420_width/2*(i)+32*15, yuv420_v_dest+yuv420_width/2*(i)+32*15, nv12t_uv_src+tiled_offset3+64*(temp1), 64); 498 } 499 aligned_x_size = 1024; 500 } 501 502 if ((yuv420_width-aligned_x_size) >= 512) { 503 for (i=0; i<yuv420_uv_height; i=i+1) { 504 tiled_offset = 0; 505 tiled_y_index = i>>5; 506 if (tiled_y_index & 0x1) { 507 /* odd fomula: 2+x_block_num*(y-1) */ 508 tiled_offset = tiled_y_index-1; 509 temp1 = ((yuv420_width+127)>>7)<<7; 510 tiled_offset = tiled_offset*(temp1>>6); 511 tiled_offset = tiled_offset+2; 512 temp1 = aligned_x_size>>5; 513 tiled_offset = tiled_offset+temp1; 514 tiled_offset = tiled_offset<<11; 515 tiled_offset1 = tiled_offset+2048*1; 516 tiled_offset2 = tiled_offset+2048*2; 517 tiled_offset3 = tiled_offset+2048*3; 518 temp2 = 8; 519 } else { 520 temp2 = ((yuv420_uv_height+31)>>5)<<5; 521 /* even fomula: x_block_num*y */ 522 temp1 = ((yuv420_width+127)>>7)<<7; 523 tiled_offset = tiled_y_index*(temp1>>6); 524 tiled_offset = tiled_offset<<11; 525 if ((i+32)<temp2) { 526 temp1 = aligned_x_size>>5; 527 tiled_offset = tiled_offset+(temp1<<11); 528 tiled_offset1 = tiled_offset+2048*1; 529 tiled_offset2 = tiled_offset+2048*6; 530 tiled_offset3 = tiled_offset+2048*7; 531 temp2 = 8; 532 } else { 533 temp1 = aligned_x_size>>6; 534 tiled_offset = tiled_offset+(temp1<<11); 535 tiled_offset1 = tiled_offset+2048*1; 536 tiled_offset2 = tiled_offset+2048*2; 537 tiled_offset3 = tiled_offset+2048*3; 538 temp2 = 4; 539 } 540 } 541 temp1 = i&0x1F; 542 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i), yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i), nv12t_uv_src+tiled_offset+64*(temp1), 64); 543 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*1, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*1, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 544 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*2, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*2, nv12t_uv_src+tiled_offset2+64*(temp1), 64); 545 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*3, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*3, nv12t_uv_src+tiled_offset3+64*(temp1), 64); 546 547 tiled_offset = tiled_offset+temp2*2048; 548 tiled_offset1 = tiled_offset1+temp2*2048; 549 tiled_offset2 = tiled_offset2+temp2*2048; 550 tiled_offset3 = tiled_offset3+temp2*2048; 551 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*4, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*4, nv12t_uv_src+tiled_offset+64*(temp1), 64); 552 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*5, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*5, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 553 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*6, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*6, nv12t_uv_src+tiled_offset2+64*(temp1), 64); 554 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*7, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*7, nv12t_uv_src+tiled_offset3+64*(temp1), 64); 555 } 556 aligned_x_size = aligned_x_size+512; 557 } 558 559 if ((yuv420_width-aligned_x_size) >= 256) { 560 for (i=0; i<yuv420_uv_height; i=i+1) { 561 tiled_offset = 0; 562 tiled_y_index = i>>5; 563 if (tiled_y_index & 0x1) { 564 /* odd fomula: 2+x_block_num*(y-1) */ 565 tiled_offset = tiled_y_index-1; 566 temp1 = ((yuv420_width+127)>>7)<<7; 567 tiled_offset = tiled_offset*(temp1>>6); 568 tiled_offset = tiled_offset+2; 569 temp1 = aligned_x_size>>5; 570 tiled_offset = tiled_offset+temp1; 571 tiled_offset = tiled_offset<<11; 572 tiled_offset1 = tiled_offset+2048*1; 573 tiled_offset2 = tiled_offset+2048*2; 574 tiled_offset3 = tiled_offset+2048*3; 575 } else { 576 temp2 = ((yuv420_uv_height+31)>>5)<<5; 577 /* even fomula: x_block_num*y */ 578 temp1 = ((yuv420_width+127)>>7)<<7; 579 tiled_offset = tiled_y_index*(temp1>>6); 580 tiled_offset = tiled_offset<<11; 581 if ((i+32)<temp2) { 582 temp1 = aligned_x_size>>5; 583 tiled_offset = tiled_offset+(temp1<<11); 584 tiled_offset1 = tiled_offset+2048*1; 585 tiled_offset2 = tiled_offset+2048*6; 586 tiled_offset3 = tiled_offset+2048*7; 587 } else { 588 temp1 = aligned_x_size>>6; 589 tiled_offset = tiled_offset+(temp1<<11); 590 tiled_offset1 = tiled_offset+2048*1; 591 tiled_offset2 = tiled_offset+2048*2; 592 tiled_offset3 = tiled_offset+2048*3; 593 } 594 } 595 temp1 = i&0x1F; 596 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i), yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i), nv12t_uv_src+tiled_offset+64*(temp1), 64); 597 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*1, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*1, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 598 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*2, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*2, nv12t_uv_src+tiled_offset2+64*(temp1), 64); 599 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*3, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*3, nv12t_uv_src+tiled_offset3+64*(temp1), 64); 600 } 601 aligned_x_size = aligned_x_size+256; 602 } 603 604 if ((yuv420_width-aligned_x_size) >= 128) { 605 for (i=0; i<yuv420_uv_height; i=i+2) { 606 tiled_offset = 0; 607 tiled_y_index = i>>5; 608 if (tiled_y_index & 0x1) { 609 /* odd fomula: 2+x_block_num*(y-1) */ 610 tiled_offset = tiled_y_index-1; 611 temp1 = ((yuv420_width+127)>>7)<<7; 612 tiled_offset = tiled_offset*(temp1>>6); 613 tiled_offset = tiled_offset+2; 614 temp1 = aligned_x_size>>5; 615 tiled_offset = tiled_offset+temp1; 616 tiled_offset = tiled_offset<<11; 617 tiled_offset1 = tiled_offset+2048*1; 618 } else { 619 temp2 = ((yuv420_uv_height+31)>>5)<<5; 620 /* even fomula: x_block_num*y */ 621 temp1 = ((yuv420_width+127)>>7)<<7; 622 tiled_offset = tiled_y_index*(temp1>>6); 623 tiled_offset = tiled_offset<<11; 624 if ((i+32)<temp2) { 625 temp1 = aligned_x_size>>5; 626 tiled_offset = tiled_offset+(temp1<<11); 627 tiled_offset1 = tiled_offset+2048*1; 628 } else { 629 temp1 = aligned_x_size>>6; 630 tiled_offset = tiled_offset+(temp1<<11); 631 tiled_offset1 = tiled_offset+2048*1; 632 } 633 } 634 temp1 = i&0x1F; 635 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i), yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i), nv12t_uv_src+tiled_offset+64*(temp1), 64); 636 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i)+32*1, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i)+32*1, nv12t_uv_src+tiled_offset1+64*(temp1), 64); 637 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i+1), yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i+1), nv12t_uv_src+tiled_offset+64*(temp1+1), 64); 638 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i+1)+32*1, yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i+1)+32*1, nv12t_uv_src+tiled_offset1+64*(temp1+1), 64); 639 } 640 aligned_x_size = aligned_x_size+128; 641 } 642 643 if ((yuv420_width-aligned_x_size) >= 64) { 644 for (i=0; i<yuv420_uv_height; i=i+2) { 645 tiled_offset = 0; 646 tiled_x_index = aligned_x_size>>6; 647 tiled_y_index = i>>5; 648 if (tiled_y_index & 0x1) { 649 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 650 tiled_offset = tiled_y_index-1; 651 temp1 = ((yuv420_width+127)>>7)<<7; 652 tiled_offset = tiled_offset*(temp1>>6); 653 tiled_offset = tiled_offset+tiled_x_index; 654 tiled_offset = tiled_offset+2; 655 temp1 = (tiled_x_index>>2)<<2; 656 tiled_offset = tiled_offset+temp1; 657 tiled_offset = tiled_offset<<11; 658 } else { 659 temp2 = ((yuv420_uv_height+31)>>5)<<5; 660 if ((i+32)<temp2) { 661 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 662 temp1 = tiled_x_index+2; 663 temp1 = (temp1>>2)<<2; 664 tiled_offset = tiled_x_index+temp1; 665 temp1 = ((yuv420_width+127)>>7)<<7; 666 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 667 tiled_offset = tiled_offset<<11; 668 } else { 669 /* even2 fomula: x+x_block_num*y */ 670 temp1 = ((yuv420_width+127)>>7)<<7; 671 tiled_offset = tiled_y_index*(temp1>>6); 672 tiled_offset = tiled_offset+tiled_x_index; 673 tiled_offset = tiled_offset<<11; 674 } 675 } 676 temp1 = i&0x1F; 677 temp2 = aligned_x_size&0x3F; 678 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i), yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i), nv12t_uv_src+tiled_offset+64*(temp1), 64); 679 csc_deinterleave_memcpy(yuv420_u_dest+aligned_x_size/2+yuv420_width/2*(i+1), yuv420_v_dest+aligned_x_size/2+yuv420_width/2*(i+1), nv12t_uv_src+tiled_offset+64*(temp1+1), 64); 680 } 681 aligned_x_size = aligned_x_size+64; 682 } 683 684 if (yuv420_width != aligned_x_size) { 685 for (i=0; i<yuv420_uv_height; i=i+2) { 686 for (j=aligned_x_size; j<yuv420_width; j=j+4) { 687 tiled_offset = 0; 688 tiled_x_index = j>>6; 689 tiled_y_index = i>>5; 690 if (tiled_y_index & 0x1) { 691 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 692 tiled_offset = tiled_y_index-1; 693 temp1 = ((yuv420_width+127)>>7)<<7; 694 tiled_offset = tiled_offset*(temp1>>6); 695 tiled_offset = tiled_offset+tiled_x_index; 696 tiled_offset = tiled_offset+2; 697 temp1 = (tiled_x_index>>2)<<2; 698 tiled_offset = tiled_offset+temp1; 699 tiled_offset = tiled_offset<<11; 700 } else { 701 temp2 = ((yuv420_uv_height+31)>>5)<<5; 702 if ((i+32)<temp2) { 703 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 704 temp1 = tiled_x_index+2; 705 temp1 = (temp1>>2)<<2; 706 tiled_offset = tiled_x_index+temp1; 707 temp1 = ((yuv420_width+127)>>7)<<7; 708 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 709 tiled_offset = tiled_offset<<11; 710 } else { 711 /* even2 fomula: x+x_block_num*y */ 712 temp1 = ((yuv420_width+127)>>7)<<7; 713 tiled_offset = tiled_y_index*(temp1>>6); 714 tiled_offset = tiled_offset+tiled_x_index; 715 tiled_offset = tiled_offset<<11; 716 } 717 } 718 temp1 = i&0x1F; 719 temp2 = j&0x3F; 720 csc_deinterleave_memcpy(yuv420_u_dest+j/2+yuv420_width/2*(i), yuv420_v_dest+j/2+yuv420_width/2*(i), nv12t_uv_src+tiled_offset+temp2+64*(temp1), 4); 721 csc_deinterleave_memcpy(yuv420_u_dest+j/2+yuv420_width/2*(i+1), yuv420_v_dest+j/2+yuv420_width/2*(i+1), nv12t_uv_src+tiled_offset+temp2+64*(temp1+1), 4); 722 } 723 } 724 } 725 } 726 727 /* 728 * Converts linear data to tiled. 729 * 1. Y of YUV420P to Y of NV12T 730 * 2. Y of YUV420S to Y of NV12T 731 * 3. UV of YUV420S to UV of NV12T 732 * 733 * @param nv12t_dest 734 * Y or UV plane address of NV12T[out] 735 * 736 * @param yuv420_src 737 * Y or UV plane address of YUV420P(S)[in] 738 * 739 * @param yuv420_width 740 * Width of YUV420[in] 741 * 742 * @param yuv420_height 743 * Y: Height of YUV420, UV: Height/2 of YUV420[in] 744 */ 745 void csc_linear_to_tiled(char *nv12t_dest, char *yuv420_src, int yuv420_width, int yuv420_height) 746 { 747 unsigned int i, j; 748 unsigned int tiled_x_index = 0, tiled_y_index = 0; 749 unsigned int aligned_x_size = 0, aligned_y_size = 0; 750 unsigned int tiled_offset = 0; 751 unsigned int temp1 = 0, temp2 = 0; 752 753 aligned_y_size = (yuv420_height>>5)<<5; 754 aligned_x_size = (yuv420_width>>6)<<6; 755 756 for (i=0; i<aligned_y_size; i=i+32) { 757 for (j=0; j<aligned_x_size; j=j+64) { 758 tiled_offset = 0; 759 tiled_x_index = j>>6; 760 tiled_y_index = i>>5; 761 if (tiled_y_index & 0x1) { 762 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 763 tiled_offset = tiled_y_index-1; 764 temp1 = ((yuv420_width+127)>>7)<<7; 765 tiled_offset = tiled_offset*(temp1>>6); 766 tiled_offset = tiled_offset+tiled_x_index; 767 tiled_offset = tiled_offset+2; 768 temp1 = (tiled_x_index>>2)<<2; 769 tiled_offset = tiled_offset+temp1; 770 tiled_offset = tiled_offset<<11; 771 } else { 772 temp2 = ((yuv420_height+31)>>5)<<5; 773 if ((i+32)<temp2) { 774 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 775 temp1 = tiled_x_index+2; 776 temp1 = (temp1>>2)<<2; 777 tiled_offset = tiled_x_index+temp1; 778 temp1 = ((yuv420_width+127)>>7)<<7; 779 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 780 tiled_offset = tiled_offset<<11; 781 } else { 782 /* even2 fomula: x+x_block_num*y */ 783 temp1 = ((yuv420_width+127)>>7)<<7; 784 tiled_offset = tiled_y_index*(temp1>>6); 785 tiled_offset = tiled_offset+tiled_x_index; 786 tiled_offset = tiled_offset<<11; 787 } 788 } 789 790 memcpy(nv12t_dest+tiled_offset, yuv420_src+j+yuv420_width*(i), 64); 791 memcpy(nv12t_dest+tiled_offset+64*1, yuv420_src+j+yuv420_width*(i+1), 64); 792 memcpy(nv12t_dest+tiled_offset+64*2, yuv420_src+j+yuv420_width*(i+2), 64); 793 memcpy(nv12t_dest+tiled_offset+64*3, yuv420_src+j+yuv420_width*(i+3), 64); 794 memcpy(nv12t_dest+tiled_offset+64*4, yuv420_src+j+yuv420_width*(i+4), 64); 795 memcpy(nv12t_dest+tiled_offset+64*5, yuv420_src+j+yuv420_width*(i+5), 64); 796 memcpy(nv12t_dest+tiled_offset+64*6, yuv420_src+j+yuv420_width*(i+6), 64); 797 memcpy(nv12t_dest+tiled_offset+64*7, yuv420_src+j+yuv420_width*(i+7), 64); 798 memcpy(nv12t_dest+tiled_offset+64*8, yuv420_src+j+yuv420_width*(i+8), 64); 799 memcpy(nv12t_dest+tiled_offset+64*9, yuv420_src+j+yuv420_width*(i+9), 64); 800 memcpy(nv12t_dest+tiled_offset+64*10, yuv420_src+j+yuv420_width*(i+10), 64); 801 memcpy(nv12t_dest+tiled_offset+64*11, yuv420_src+j+yuv420_width*(i+11), 64); 802 memcpy(nv12t_dest+tiled_offset+64*12, yuv420_src+j+yuv420_width*(i+12), 64); 803 memcpy(nv12t_dest+tiled_offset+64*13, yuv420_src+j+yuv420_width*(i+13), 64); 804 memcpy(nv12t_dest+tiled_offset+64*14, yuv420_src+j+yuv420_width*(i+14), 64); 805 memcpy(nv12t_dest+tiled_offset+64*15, yuv420_src+j+yuv420_width*(i+15), 64); 806 memcpy(nv12t_dest+tiled_offset+64*16, yuv420_src+j+yuv420_width*(i+16), 64); 807 memcpy(nv12t_dest+tiled_offset+64*17, yuv420_src+j+yuv420_width*(i+17), 64); 808 memcpy(nv12t_dest+tiled_offset+64*18, yuv420_src+j+yuv420_width*(i+18), 64); 809 memcpy(nv12t_dest+tiled_offset+64*19, yuv420_src+j+yuv420_width*(i+19), 64); 810 memcpy(nv12t_dest+tiled_offset+64*20, yuv420_src+j+yuv420_width*(i+20), 64); 811 memcpy(nv12t_dest+tiled_offset+64*21, yuv420_src+j+yuv420_width*(i+21), 64); 812 memcpy(nv12t_dest+tiled_offset+64*22, yuv420_src+j+yuv420_width*(i+22), 64); 813 memcpy(nv12t_dest+tiled_offset+64*23, yuv420_src+j+yuv420_width*(i+23), 64); 814 memcpy(nv12t_dest+tiled_offset+64*24, yuv420_src+j+yuv420_width*(i+24), 64); 815 memcpy(nv12t_dest+tiled_offset+64*25, yuv420_src+j+yuv420_width*(i+25), 64); 816 memcpy(nv12t_dest+tiled_offset+64*26, yuv420_src+j+yuv420_width*(i+26), 64); 817 memcpy(nv12t_dest+tiled_offset+64*27, yuv420_src+j+yuv420_width*(i+27), 64); 818 memcpy(nv12t_dest+tiled_offset+64*28, yuv420_src+j+yuv420_width*(i+28), 64); 819 memcpy(nv12t_dest+tiled_offset+64*29, yuv420_src+j+yuv420_width*(i+29), 64); 820 memcpy(nv12t_dest+tiled_offset+64*30, yuv420_src+j+yuv420_width*(i+30), 64); 821 memcpy(nv12t_dest+tiled_offset+64*31, yuv420_src+j+yuv420_width*(i+31), 64); 822 } 823 } 824 825 for (i=aligned_y_size; i<yuv420_height; i=i+4) { 826 for (j=0; j<aligned_x_size; j=j+64) { 827 tiled_offset = 0; 828 tiled_x_index = j>>6; 829 tiled_y_index = i>>5; 830 if (tiled_y_index & 0x1) { 831 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 832 tiled_offset = tiled_y_index-1; 833 temp1 = ((yuv420_width+127)>>7)<<7; 834 tiled_offset = tiled_offset*(temp1>>6); 835 tiled_offset = tiled_offset+tiled_x_index; 836 tiled_offset = tiled_offset+2; 837 temp1 = (tiled_x_index>>2)<<2; 838 tiled_offset = tiled_offset+temp1; 839 tiled_offset = tiled_offset<<11; 840 } else { 841 temp2 = ((yuv420_height+31)>>5)<<5; 842 if ((i+32)<temp2) { 843 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 844 temp1 = tiled_x_index+2; 845 temp1 = (temp1>>2)<<2; 846 tiled_offset = tiled_x_index+temp1; 847 temp1 = ((yuv420_width+127)>>7)<<7; 848 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 849 tiled_offset = tiled_offset<<11; 850 } else { 851 /* even2 fomula: x+x_block_num*y */ 852 temp1 = ((yuv420_width+127)>>7)<<7; 853 tiled_offset = tiled_y_index*(temp1>>6); 854 tiled_offset = tiled_offset+tiled_x_index; 855 tiled_offset = tiled_offset<<11; 856 } 857 } 858 859 temp1 = i&0x1F; 860 memcpy(nv12t_dest+tiled_offset+64*(temp1), yuv420_src+j+yuv420_width*(i), 64); 861 memcpy(nv12t_dest+tiled_offset+64*(temp1+1), yuv420_src+j+yuv420_width*(i+1), 64); 862 memcpy(nv12t_dest+tiled_offset+64*(temp1+2), yuv420_src+j+yuv420_width*(i+2), 64); 863 memcpy(nv12t_dest+tiled_offset+64*(temp1+3), yuv420_src+j+yuv420_width*(i+3), 64); 864 } 865 } 866 867 for (i=0; i<yuv420_height; i=i+4) { 868 for (j=aligned_x_size; j<yuv420_width; j=j+4) { 869 tiled_offset = 0; 870 tiled_x_index = j>>6; 871 tiled_y_index = i>>5; 872 if (tiled_y_index & 0x1) { 873 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 874 tiled_offset = tiled_y_index-1; 875 temp1 = ((yuv420_width+127)>>7)<<7; 876 tiled_offset = tiled_offset*(temp1>>6); 877 tiled_offset = tiled_offset+tiled_x_index; 878 tiled_offset = tiled_offset+2; 879 temp1 = (tiled_x_index>>2)<<2; 880 tiled_offset = tiled_offset+temp1; 881 tiled_offset = tiled_offset<<11; 882 } else { 883 temp2 = ((yuv420_height+31)>>5)<<5; 884 if ((i+32)<temp2) { 885 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 886 temp1 = tiled_x_index+2; 887 temp1 = (temp1>>2)<<2; 888 tiled_offset = tiled_x_index+temp1; 889 temp1 = ((yuv420_width+127)>>7)<<7; 890 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 891 tiled_offset = tiled_offset<<11; 892 } else { 893 /* even2 fomula: x+x_block_num*y */ 894 temp1 = ((yuv420_width+127)>>7)<<7; 895 tiled_offset = tiled_y_index*(temp1>>6); 896 tiled_offset = tiled_offset+tiled_x_index; 897 tiled_offset = tiled_offset<<11; 898 } 899 } 900 901 temp1 = i&0x1F; 902 temp2 = j&0x3F; 903 memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1), yuv420_src+j+yuv420_width*(i), 4); 904 memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1+1), yuv420_src+j+yuv420_width*(i+1), 4); 905 memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1+2), yuv420_src+j+yuv420_width*(i+2), 4); 906 memcpy(nv12t_dest+tiled_offset+temp2+64*(temp1+3), yuv420_src+j+yuv420_width*(i+3), 4); 907 } 908 } 909 } 910 911 /* 912 * Converts and Interleaves linear to tiled 913 * 1. UV of YUV420P to UV of NV12T 914 * 915 * @param nv12t_uv_dest 916 * UV plane address of NV12T[out] 917 * 918 * @param yuv420p_u_src 919 * U plane address of YUV420P[in] 920 * 921 * @param yuv420p_v_src 922 * V plane address of YUV420P[in] 923 * 924 * @param yuv420_width 925 * Width of YUV420[in] 926 * 927 * @param yuv420_uv_height 928 * Height/2 of YUV420[in] 929 */ 930 void csc_linear_to_tiled_interleave(char *nv12t_uv_dest, char *yuv420p_u_src, char *yuv420p_v_src, int yuv420_width, int yuv420_uv_height) 931 { 932 unsigned int i, j; 933 unsigned int tiled_x_index = 0, tiled_y_index = 0; 934 unsigned int aligned_x_size = 0, aligned_y_size = 0; 935 unsigned int tiled_offset = 0; 936 unsigned int temp1 = 0, temp2 = 0; 937 938 aligned_y_size = (yuv420_uv_height>>5)<<5; 939 aligned_x_size = ((yuv420_width)>>6)<<6; 940 941 for (i=0; i<aligned_y_size; i=i+32) { 942 for (j=0; j<aligned_x_size; j=j+64) { 943 tiled_offset = 0; 944 tiled_x_index = j>>6; 945 tiled_y_index = i>>5; 946 if (tiled_y_index & 0x1) { 947 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 948 tiled_offset = tiled_y_index-1; 949 temp1 = ((yuv420_width+127)>>7)<<7; 950 tiled_offset = tiled_offset*(temp1>>6); 951 tiled_offset = tiled_offset+tiled_x_index; 952 tiled_offset = tiled_offset+2; 953 temp1 = (tiled_x_index>>2)<<2; 954 tiled_offset = tiled_offset+temp1; 955 tiled_offset = tiled_offset<<11; 956 } else { 957 temp2 = ((yuv420_uv_height+31)>>5)<<5; 958 if ((i+32)<temp2) { 959 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 960 temp1 = tiled_x_index+2; 961 temp1 = (temp1>>2)<<2; 962 tiled_offset = tiled_x_index+temp1; 963 temp1 = ((yuv420_width+127)>>7)<<7; 964 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 965 tiled_offset = tiled_offset<<11; 966 } else { 967 /* even2 fomula: x+x_block_num*y */ 968 temp1 = ((yuv420_width+127)>>7)<<7; 969 tiled_offset = tiled_y_index*(temp1>>6); 970 tiled_offset = tiled_offset+tiled_x_index; 971 tiled_offset = tiled_offset<<11; 972 } 973 } 974 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset, yuv420p_u_src+j/2+yuv420_width/2*(i), yuv420p_v_src+j/2+yuv420_width/2*(i), 32); 975 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*1, yuv420p_u_src+j/2+yuv420_width/2*(i+1), yuv420p_v_src+j/2+yuv420_width/2*(i+1), 32); 976 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*2, yuv420p_u_src+j/2+yuv420_width/2*(i+2), yuv420p_v_src+j/2+yuv420_width/2*(i+2), 32); 977 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*3, yuv420p_u_src+j/2+yuv420_width/2*(i+3), yuv420p_v_src+j/2+yuv420_width/2*(i+3), 32); 978 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*4, yuv420p_u_src+j/2+yuv420_width/2*(i+4), yuv420p_v_src+j/2+yuv420_width/2*(i+4), 32); 979 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*5, yuv420p_u_src+j/2+yuv420_width/2*(i+5), yuv420p_v_src+j/2+yuv420_width/2*(i+5), 32); 980 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*6, yuv420p_u_src+j/2+yuv420_width/2*(i+6), yuv420p_v_src+j/2+yuv420_width/2*(i+6), 32); 981 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*7, yuv420p_u_src+j/2+yuv420_width/2*(i+7), yuv420p_v_src+j/2+yuv420_width/2*(i+7), 32); 982 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*8, yuv420p_u_src+j/2+yuv420_width/2*(i+8), yuv420p_v_src+j/2+yuv420_width/2*(i+8), 32); 983 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*9, yuv420p_u_src+j/2+yuv420_width/2*(i+9), yuv420p_v_src+j/2+yuv420_width/2*(i+9), 32); 984 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*10, yuv420p_u_src+j/2+yuv420_width/2*(i+10), yuv420p_v_src+j/2+yuv420_width/2*(i+10), 32); 985 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*11, yuv420p_u_src+j/2+yuv420_width/2*(i+11), yuv420p_v_src+j/2+yuv420_width/2*(i+11), 32); 986 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*12, yuv420p_u_src+j/2+yuv420_width/2*(i+12), yuv420p_v_src+j/2+yuv420_width/2*(i+12), 32); 987 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*13, yuv420p_u_src+j/2+yuv420_width/2*(i+13), yuv420p_v_src+j/2+yuv420_width/2*(i+13), 32); 988 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*14, yuv420p_u_src+j/2+yuv420_width/2*(i+14), yuv420p_v_src+j/2+yuv420_width/2*(i+14), 32); 989 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*15, yuv420p_u_src+j/2+yuv420_width/2*(i+15), yuv420p_v_src+j/2+yuv420_width/2*(i+15), 32); 990 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*16, yuv420p_u_src+j/2+yuv420_width/2*(i+16), yuv420p_v_src+j/2+yuv420_width/2*(i+16), 32); 991 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*17, yuv420p_u_src+j/2+yuv420_width/2*(i+17), yuv420p_v_src+j/2+yuv420_width/2*(i+17), 32); 992 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*18, yuv420p_u_src+j/2+yuv420_width/2*(i+18), yuv420p_v_src+j/2+yuv420_width/2*(i+18), 32); 993 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*19, yuv420p_u_src+j/2+yuv420_width/2*(i+19), yuv420p_v_src+j/2+yuv420_width/2*(i+19), 32); 994 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*20, yuv420p_u_src+j/2+yuv420_width/2*(i+20), yuv420p_v_src+j/2+yuv420_width/2*(i+20), 32); 995 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*21, yuv420p_u_src+j/2+yuv420_width/2*(i+21), yuv420p_v_src+j/2+yuv420_width/2*(i+21), 32); 996 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*22, yuv420p_u_src+j/2+yuv420_width/2*(i+22), yuv420p_v_src+j/2+yuv420_width/2*(i+22), 32); 997 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*23, yuv420p_u_src+j/2+yuv420_width/2*(i+23), yuv420p_v_src+j/2+yuv420_width/2*(i+23), 32); 998 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*24, yuv420p_u_src+j/2+yuv420_width/2*(i+24), yuv420p_v_src+j/2+yuv420_width/2*(i+24), 32); 999 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*25, yuv420p_u_src+j/2+yuv420_width/2*(i+25), yuv420p_v_src+j/2+yuv420_width/2*(i+25), 32); 1000 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*26, yuv420p_u_src+j/2+yuv420_width/2*(i+26), yuv420p_v_src+j/2+yuv420_width/2*(i+26), 32); 1001 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*27, yuv420p_u_src+j/2+yuv420_width/2*(i+27), yuv420p_v_src+j/2+yuv420_width/2*(i+27), 32); 1002 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*28, yuv420p_u_src+j/2+yuv420_width/2*(i+28), yuv420p_v_src+j/2+yuv420_width/2*(i+28), 32); 1003 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*29, yuv420p_u_src+j/2+yuv420_width/2*(i+29), yuv420p_v_src+j/2+yuv420_width/2*(i+29), 32); 1004 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*30, yuv420p_u_src+j/2+yuv420_width/2*(i+30), yuv420p_v_src+j/2+yuv420_width/2*(i+30), 32); 1005 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*31, yuv420p_u_src+j/2+yuv420_width/2*(i+31), yuv420p_v_src+j/2+yuv420_width/2*(i+31), 32); 1006 } 1007 } 1008 1009 for (i=aligned_y_size; i<yuv420_uv_height; i=i+4) { 1010 for (j=0; j<aligned_x_size; j=j+64) { 1011 tiled_offset = 0; 1012 tiled_x_index = j>>6; 1013 tiled_y_index = i>>5; 1014 if (tiled_y_index & 0x1) { 1015 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 1016 tiled_offset = tiled_y_index-1; 1017 temp1 = ((yuv420_width+127)>>7)<<7; 1018 tiled_offset = tiled_offset*(temp1>>6); 1019 tiled_offset = tiled_offset+tiled_x_index; 1020 tiled_offset = tiled_offset+2; 1021 temp1 = (tiled_x_index>>2)<<2; 1022 tiled_offset = tiled_offset+temp1; 1023 tiled_offset = tiled_offset<<11; 1024 } else { 1025 temp2 = ((yuv420_uv_height+31)>>5)<<5; 1026 if ((i+32)<temp2) { 1027 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 1028 temp1 = tiled_x_index+2; 1029 temp1 = (temp1>>2)<<2; 1030 tiled_offset = tiled_x_index+temp1; 1031 temp1 = ((yuv420_width+127)>>7)<<7; 1032 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 1033 tiled_offset = tiled_offset<<11; 1034 } else { 1035 /* even2 fomula: x+x_block_num*y */ 1036 temp1 = ((yuv420_width+127)>>7)<<7; 1037 tiled_offset = tiled_y_index*(temp1>>6); 1038 tiled_offset = tiled_offset+tiled_x_index; 1039 tiled_offset = tiled_offset<<11; 1040 } 1041 } 1042 temp1 = i&0x1F; 1043 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1), yuv420p_u_src+j/2+yuv420_width/2*(i), yuv420p_v_src+j/2+yuv420_width/2*(i), 32); 1044 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1+1), yuv420p_u_src+j/2+yuv420_width/2*(i+1), yuv420p_v_src+j/2+yuv420_width/2*(i+1), 32); 1045 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1+2), yuv420p_u_src+j/2+yuv420_width/2*(i+2), yuv420p_v_src+j/2+yuv420_width/2*(i+2), 32); 1046 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+64*(temp1+3), yuv420p_u_src+j/2+yuv420_width/2*(i+3), yuv420p_v_src+j/2+yuv420_width/2*(i+3), 32); 1047 } 1048 } 1049 1050 for (i=0; i<yuv420_uv_height; i=i+4) { 1051 for (j=aligned_x_size; j<yuv420_width; j=j+4) { 1052 tiled_offset = 0; 1053 tiled_x_index = j>>6; 1054 tiled_y_index = i>>5; 1055 if (tiled_y_index & 0x1) { 1056 /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */ 1057 tiled_offset = tiled_y_index-1; 1058 temp1 = ((yuv420_width+127)>>7)<<7; 1059 tiled_offset = tiled_offset*(temp1>>6); 1060 tiled_offset = tiled_offset+tiled_x_index; 1061 tiled_offset = tiled_offset+2; 1062 temp1 = (tiled_x_index>>2)<<2; 1063 tiled_offset = tiled_offset+temp1; 1064 tiled_offset = tiled_offset<<11; 1065 } else { 1066 temp2 = ((yuv420_uv_height+31)>>5)<<5; 1067 if ((i+32)<temp2) { 1068 /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */ 1069 temp1 = tiled_x_index+2; 1070 temp1 = (temp1>>2)<<2; 1071 tiled_offset = tiled_x_index+temp1; 1072 temp1 = ((yuv420_width+127)>>7)<<7; 1073 tiled_offset = tiled_offset+tiled_y_index*(temp1>>6); 1074 tiled_offset = tiled_offset<<11; 1075 } else { 1076 /* even2 fomula: x+x_block_num*y */ 1077 temp1 = ((yuv420_width+127)>>7)<<7; 1078 tiled_offset = tiled_y_index*(temp1>>6); 1079 tiled_offset = tiled_offset+tiled_x_index; 1080 tiled_offset = tiled_offset<<11; 1081 } 1082 } 1083 temp1 = i&0x1F; 1084 temp2 = j&0x3F; 1085 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1), yuv420p_u_src+j/2+yuv420_width/2*(i), yuv420p_v_src+j/2+yuv420_width/2*(i), 2); 1086 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1+1), yuv420p_u_src+j/2+yuv420_width/2*(i+1), yuv420p_v_src+j/2+yuv420_width/2*(i+1), 2); 1087 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1+2), yuv420p_u_src+j/2+yuv420_width/2*(i+2), yuv420p_v_src+j/2+yuv420_width/2*(i+2), 2); 1088 csc_interleave_memcpy(nv12t_uv_dest+tiled_offset+temp2+64*(temp1+3), yuv420p_u_src+j/2+yuv420_width/2*(i+3), yuv420p_v_src+j/2+yuv420_width/2*(i+3), 2); 1089 } 1090 } 1091 } 1092 1093