1 /****************************************************************************** 2 * 3 * Copyright (C) 2015 The Android Open Source Project 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 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore 19 */ 20 21 /** 22 ******************************************************************************* 23 * @file 24 * ih264e_fmt_conv.c 25 * 26 * @brief 27 * Contains functions for format conversion or frame copy of output buffer 28 * 29 * @author 30 * ittiam 31 * 32 * @par List of Functions: 33 * - ih264e_fmt_conv_420sp_to_rgb565() 34 * - ih264e_fmt_conv_420sp_to_rgba8888() 35 * - ih264e_fmt_conv_420sp_to_420sp() 36 * - ih264e_fmt_conv_420sp_to_420sp_swap_uv() 37 * - ih264e_fmt_conv_420sp_to_420p() 38 * - ih264e_fmt_conv_420p_to_420sp() 39 * - ih264e_fmt_conv_422i_to_420sp() 40 * - ih264e_fmt_conv() 41 * 42 * @remarks 43 * None 44 * 45 ******************************************************************************* 46 */ 47 48 /*****************************************************************************/ 49 /* File Includes */ 50 /*****************************************************************************/ 51 52 /* System Include files */ 53 #include <stdio.h> 54 #include <stddef.h> 55 #include <stdlib.h> 56 #include <string.h> 57 #include <assert.h> 58 59 /* User Include files */ 60 #include "ih264_typedefs.h" 61 #include "iv2.h" 62 #include "ive2.h" 63 #include "ih264e.h" 64 #include "ithread.h" 65 #include "ih264_defs.h" 66 #include "ih264_debug.h" 67 #include "ime_distortion_metrics.h" 68 #include "ime_defs.h" 69 #include "ime_structs.h" 70 #include "ih264_error.h" 71 #include "ih264_structs.h" 72 #include "ih264_trans_quant_itrans_iquant.h" 73 #include "ih264_inter_pred_filters.h" 74 #include "ih264_mem_fns.h" 75 #include "ih264_padding.h" 76 #include "ih264_intra_pred_filters.h" 77 #include "ih264_deblk_edge_filters.h" 78 #include "ih264_cabac_tables.h" 79 #include "ih264_macros.h" 80 #include "ih264_platform_macros.h" 81 #include "ih264_buf_mgr.h" 82 #include "ih264e_defs.h" 83 #include "ih264e_error.h" 84 #include "ih264e_bitstream.h" 85 #include "irc_cntrl_param.h" 86 #include "irc_frame_info_collector.h" 87 #include "ih264e_rate_control.h" 88 #include "ih264e_cabac_structs.h" 89 #include "ih264e_structs.h" 90 #include "ih264e_fmt_conv.h" 91 92 93 /*****************************************************************************/ 94 /* Function Definitions */ 95 /*****************************************************************************/ 96 97 void ih264e_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src, 98 UWORD8 *pu1_uv_src, 99 UWORD16 *pu2_rgb_dst, 100 WORD32 wd, 101 WORD32 ht, 102 WORD32 src_y_strd, 103 WORD32 src_uv_strd, 104 WORD32 dst_strd, 105 WORD32 is_u_first) 106 { 107 WORD16 i2_r, i2_g, i2_b; 108 UWORD32 u4_r, u4_g, u4_b; 109 WORD16 i2_i, i2_j; 110 UWORD8 *pu1_y_src_nxt; 111 UWORD16 *pu2_rgb_dst_NextRow; 112 113 UWORD8 *pu1_u_src, *pu1_v_src; 114 115 if (is_u_first) 116 { 117 pu1_u_src = (UWORD8 *) pu1_uv_src; 118 pu1_v_src = (UWORD8 *) pu1_uv_src + 1; 119 } 120 else 121 { 122 pu1_u_src = (UWORD8 *) pu1_uv_src + 1; 123 pu1_v_src = (UWORD8 *) pu1_uv_src; 124 } 125 126 pu1_y_src_nxt = pu1_y_src + src_y_strd; 127 pu2_rgb_dst_NextRow = pu2_rgb_dst + dst_strd; 128 129 for (i2_i = 0; i2_i < (ht >> 1); i2_i++) 130 { 131 for (i2_j = (wd >> 1); i2_j > 0; i2_j--) 132 { 133 i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13); 134 i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3) 135 >> 13; 136 i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13; 137 138 pu1_u_src += 2; 139 pu1_v_src += 2; 140 /* pixel 0 */ 141 /* B */ 142 u4_b = CLIP_U8(*pu1_y_src + i2_b); 143 u4_b >>= 3; 144 /* G */ 145 u4_g = CLIP_U8(*pu1_y_src + i2_g); 146 u4_g >>= 2; 147 /* R */ 148 u4_r = CLIP_U8(*pu1_y_src + i2_r); 149 u4_r >>= 3; 150 151 pu1_y_src++; 152 *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b); 153 154 /* pixel 1 */ 155 /* B */ 156 u4_b = CLIP_U8(*pu1_y_src + i2_b); 157 u4_b >>= 3; 158 /* G */ 159 u4_g = CLIP_U8(*pu1_y_src + i2_g); 160 u4_g >>= 2; 161 /* R */ 162 u4_r = CLIP_U8(*pu1_y_src + i2_r); 163 u4_r >>= 3; 164 165 pu1_y_src++; 166 *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b); 167 168 /* pixel 2 */ 169 /* B */ 170 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); 171 u4_b >>= 3; 172 /* G */ 173 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); 174 u4_g >>= 2; 175 /* R */ 176 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); 177 u4_r >>= 3; 178 179 pu1_y_src_nxt++; 180 *pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b); 181 182 /* pixel 3 */ 183 /* B */ 184 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); 185 u4_b >>= 3; 186 /* G */ 187 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); 188 u4_g >>= 2; 189 /* R */ 190 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); 191 u4_r >>= 3; 192 193 pu1_y_src_nxt++; 194 *pu2_rgb_dst_NextRow++ = ((u4_r << 11) | (u4_g << 5) | u4_b); 195 196 } 197 198 pu1_u_src = pu1_u_src + src_uv_strd - wd; 199 pu1_v_src = pu1_v_src + src_uv_strd - wd; 200 201 pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd; 202 pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd; 203 204 pu2_rgb_dst = pu2_rgb_dst_NextRow - wd + dst_strd; 205 pu2_rgb_dst_NextRow = pu2_rgb_dst_NextRow + (dst_strd << 1) - wd; 206 } 207 208 } 209 210 void ih264e_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src, 211 UWORD8 *pu1_uv_src, 212 UWORD32 *pu4_rgba_dst, 213 WORD32 wd, 214 WORD32 ht, 215 WORD32 src_y_strd, 216 WORD32 src_uv_strd, 217 WORD32 dst_strd, 218 WORD32 is_u_first) 219 { 220 WORD16 i2_r, i2_g, i2_b; 221 UWORD32 u4_r, u4_g, u4_b; 222 WORD16 i2_i, i2_j; 223 UWORD8 *pu1_y_src_nxt; 224 UWORD32 *pu4_rgba_dst_NextRow; 225 UWORD8 *pu1_u_src, *pu1_v_src; 226 227 if (is_u_first) 228 { 229 pu1_u_src = (UWORD8 *) pu1_uv_src; 230 pu1_v_src = (UWORD8 *) pu1_uv_src + 1; 231 } 232 else 233 { 234 pu1_u_src = (UWORD8 *) pu1_uv_src + 1; 235 pu1_v_src = (UWORD8 *) pu1_uv_src; 236 } 237 238 pu1_y_src_nxt = pu1_y_src + src_y_strd; 239 240 pu4_rgba_dst_NextRow = pu4_rgba_dst + dst_strd; 241 242 for (i2_i = 0; i2_i < (ht >> 1); i2_i++) 243 { 244 for (i2_j = (wd >> 1); i2_j > 0; i2_j--) 245 { 246 i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13); 247 i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3) 248 >> 13; 249 i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13; 250 251 pu1_u_src += 2; 252 pu1_v_src += 2; 253 /* pixel 0 */ 254 /* B */ 255 u4_b = CLIP_U8(*pu1_y_src + i2_b); 256 /* G */ 257 u4_g = CLIP_U8(*pu1_y_src + i2_g); 258 /* R */ 259 u4_r = CLIP_U8(*pu1_y_src + i2_r); 260 261 pu1_y_src++; 262 *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); 263 264 /* pixel 1 */ 265 /* B */ 266 u4_b = CLIP_U8(*pu1_y_src + i2_b); 267 /* G */ 268 u4_g = CLIP_U8(*pu1_y_src + i2_g); 269 /* R */ 270 u4_r = CLIP_U8(*pu1_y_src + i2_r); 271 272 pu1_y_src++; 273 *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); 274 275 /* pixel 2 */ 276 /* B */ 277 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); 278 /* G */ 279 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); 280 /* R */ 281 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); 282 283 pu1_y_src_nxt++; 284 *pu4_rgba_dst_NextRow++ = 285 ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); 286 287 /* pixel 3 */ 288 /* B */ 289 u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); 290 /* G */ 291 u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); 292 /* R */ 293 u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); 294 295 pu1_y_src_nxt++; 296 *pu4_rgba_dst_NextRow++ = 297 ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); 298 299 } 300 301 pu1_u_src = pu1_u_src + src_uv_strd - wd; 302 pu1_v_src = pu1_v_src + src_uv_strd - wd; 303 304 pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd; 305 pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd; 306 307 pu4_rgba_dst = pu4_rgba_dst_NextRow - wd + dst_strd; 308 pu4_rgba_dst_NextRow = pu4_rgba_dst_NextRow + (dst_strd << 1) - wd; 309 } 310 311 } 312 313 /** 314 ******************************************************************************* 315 * 316 * @brief Function used for copying a 420SP buffer 317 * 318 * @par Description 319 * Function used for copying a 420SP buffer 320 * 321 * @param[in] pu1_y_src 322 * Input Y pointer 323 * 324 * @param[in] pu1_uv_src 325 * Input UV pointer (UV is interleaved either in UV or VU format) 326 * 327 * @param[in] pu1_y_dst 328 * Output Y pointer 329 * 330 * @param[in] pu1_uv_dst 331 * Output UV pointer (UV is interleaved in the same format as that of input) 332 * 333 * @param[in] wd 334 * Width 335 * 336 * @param[in] ht 337 * Height 338 * 339 * @param[in] src_y_strd 340 * Input Y Stride 341 * 342 * @param[in] src_uv_strd 343 * Input UV stride 344 * 345 * @param[in] dst_y_strd 346 * Output Y stride 347 * 348 * @param[in] dst_uv_strd 349 * Output UV stride 350 * 351 * @returns None 352 * 353 * @remarks In case there is a need to perform partial frame copy then 354 * by passion appropriate source and destination pointers and appropriate 355 * values for wd and ht it can be done 356 * 357 ******************************************************************************* 358 */ 359 void ih264e_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src, 360 UWORD8 *pu1_uv_src, 361 UWORD8 *pu1_y_dst, 362 UWORD8 *pu1_uv_dst, 363 WORD32 wd, 364 WORD32 ht, 365 WORD32 src_y_strd, 366 WORD32 src_uv_strd, 367 WORD32 dst_y_strd, 368 WORD32 dst_uv_strd) 369 { 370 UWORD8 *pu1_src, *pu1_dst; 371 WORD32 num_rows, num_cols, src_strd, dst_strd; 372 WORD32 i; 373 374 /* copy luma */ 375 pu1_src = (UWORD8 *) pu1_y_src; 376 pu1_dst = (UWORD8 *) pu1_y_dst; 377 378 num_rows = ht; 379 num_cols = wd; 380 381 src_strd = src_y_strd; 382 dst_strd = dst_y_strd; 383 384 for (i = 0; i < num_rows; i++) 385 { 386 memcpy(pu1_dst, pu1_src, num_cols); 387 pu1_dst += dst_strd; 388 pu1_src += src_strd; 389 } 390 391 /* copy U and V */ 392 pu1_src = (UWORD8 *) pu1_uv_src; 393 pu1_dst = (UWORD8 *) pu1_uv_dst; 394 395 num_rows = ht >> 1; 396 num_cols = wd; 397 398 src_strd = src_uv_strd; 399 dst_strd = dst_uv_strd; 400 401 for (i = 0; i < num_rows; i++) 402 { 403 memcpy(pu1_dst, pu1_src, num_cols); 404 pu1_dst += dst_strd; 405 pu1_src += src_strd; 406 } 407 return; 408 } 409 410 411 void ih264e_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src, 412 UWORD8 *pu1_uv_src, 413 UWORD8 *pu1_y_dst, 414 UWORD8 *pu1_uv_dst, 415 WORD32 wd, 416 WORD32 ht, 417 WORD32 src_y_strd, 418 WORD32 src_uv_strd, 419 WORD32 dst_y_strd, 420 WORD32 dst_uv_strd) 421 { 422 UWORD8 *pu1_src, *pu1_dst; 423 WORD32 num_rows, num_cols, src_strd, dst_strd; 424 WORD32 i; 425 426 /* copy luma */ 427 pu1_src = (UWORD8 *) pu1_y_src; 428 pu1_dst = (UWORD8 *) pu1_y_dst; 429 430 num_rows = ht; 431 num_cols = wd; 432 433 src_strd = src_y_strd; 434 dst_strd = dst_y_strd; 435 436 for (i = 0; i < num_rows; i++) 437 { 438 memcpy(pu1_dst, pu1_src, num_cols); 439 pu1_dst += dst_strd; 440 pu1_src += src_strd; 441 } 442 443 /* copy U and V */ 444 pu1_src = (UWORD8 *) pu1_uv_src; 445 pu1_dst = (UWORD8 *) pu1_uv_dst; 446 447 num_rows = ht >> 1; 448 num_cols = wd; 449 450 src_strd = src_uv_strd; 451 dst_strd = dst_uv_strd; 452 453 for (i = 0; i < num_rows; i++) 454 { 455 WORD32 j; 456 for (j = 0; j < num_cols; j += 2) 457 { 458 pu1_dst[j + 0] = pu1_src[j + 1]; 459 pu1_dst[j + 1] = pu1_src[j + 0]; 460 } 461 pu1_dst += dst_strd; 462 pu1_src += src_strd; 463 } 464 return; 465 } 466 467 void ih264e_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src, 468 UWORD8 *pu1_uv_src, 469 UWORD8 *pu1_y_dst, 470 UWORD8 *pu1_u_dst, 471 UWORD8 *pu1_v_dst, 472 WORD32 wd, 473 WORD32 ht, 474 WORD32 src_y_strd, 475 WORD32 src_uv_strd, 476 WORD32 dst_y_strd, 477 WORD32 dst_uv_strd, 478 WORD32 is_u_first, 479 WORD32 disable_luma_copy) 480 { 481 UWORD8 *pu1_src, *pu1_dst; 482 UWORD8 *pu1_u_src, *pu1_v_src; 483 WORD32 num_rows, num_cols, src_strd, dst_strd; 484 WORD32 i, j; 485 486 if (0 == disable_luma_copy) 487 { 488 /* copy luma */ 489 pu1_src = (UWORD8 *) pu1_y_src; 490 pu1_dst = (UWORD8 *) pu1_y_dst; 491 492 num_rows = ht; 493 num_cols = wd; 494 495 src_strd = src_y_strd; 496 dst_strd = dst_y_strd; 497 498 for (i = 0; i < num_rows; i++) 499 { 500 memcpy(pu1_dst, pu1_src, num_cols); 501 pu1_dst += dst_strd; 502 pu1_src += src_strd; 503 } 504 } 505 /* de-interleave U and V and copy to destination */ 506 if (is_u_first) 507 { 508 pu1_u_src = (UWORD8 *) pu1_uv_src; 509 pu1_v_src = (UWORD8 *) pu1_uv_src + 1; 510 } 511 else 512 { 513 pu1_u_src = (UWORD8 *) pu1_uv_src + 1; 514 pu1_v_src = (UWORD8 *) pu1_uv_src; 515 } 516 517 num_rows = ht >> 1; 518 num_cols = wd >> 1; 519 520 src_strd = src_uv_strd; 521 dst_strd = dst_uv_strd; 522 523 for (i = 0; i < num_rows; i++) 524 { 525 for (j = 0; j < num_cols; j++) 526 { 527 pu1_u_dst[j] = pu1_u_src[j * 2]; 528 pu1_v_dst[j] = pu1_v_src[j * 2]; 529 } 530 531 pu1_u_dst += dst_strd; 532 pu1_v_dst += dst_strd; 533 pu1_u_src += src_strd; 534 pu1_v_src += src_strd; 535 } 536 return; 537 } 538 539 /** 540 ******************************************************************************* 541 * 542 * @brief Function used to perform color space conversion from 420P to 420SP 543 * 544 * @par Description 545 * Function used to perform color space conversion from 420P to 420SP 546 * 547 * @param[in] pu1_y_src 548 * Input Y pointer 549 * 550 * @param[in] pu1_u_src 551 * Input U pointer 552 * 553 * @param[in] pu1_v_dst 554 * Input V pointer 555 * 556 * @param[in] pu1_y_dst 557 * Output Y pointer 558 * 559 * @param[in] pu1_uv_dst 560 * Output UV pointer 561 * 562 * @param[in] u4_width 563 * Width 564 * 565 * @param[in] u4_height 566 * Height 567 * 568 * @param[in] src_y_strd 569 * Input Y Stride 570 * 571 * @param[in] src_u_strd 572 * Input U stride 573 * 574 * @param[in] src_v_strd 575 * Input V stride 576 * 577 * @param[in] dst_y_strd 578 * Output Y stride 579 * 580 * @param[in] dst_uv_strd 581 * Output UV stride 582 * 583 * @param[in] convert_uv_only 584 * Flag to indicate if only UV copy needs to be done 585 * 586 * @returns none 587 * 588 * @remarks In case there is a need to perform partial frame copy then 589 * by passion appropriate source and destination pointers and appropriate 590 * values for wd and ht it can be done 591 * 592 ******************************************************************************* 593 */ 594 void ih264e_fmt_conv_420p_to_420sp(UWORD8 *pu1_y_src, 595 UWORD8 *pu1_u_src, 596 UWORD8 *pu1_v_src, 597 UWORD8 *pu1_y_dst, 598 UWORD8 *pu1_uv_dst, 599 UWORD16 u2_height, 600 UWORD16 u2_width, 601 UWORD16 src_y_strd, 602 UWORD16 src_u_strd, 603 UWORD16 src_v_strd, 604 UWORD16 dst_y_strd, 605 UWORD16 dst_uv_strd, 606 UWORD32 convert_uv_only) 607 { 608 UWORD8 *pu1_src, *pu1_dst; 609 UWORD8 *pu1_src_u, *pu1_src_v; 610 UWORD16 i; 611 UWORD32 u2_width_uv; 612 UWORD32 dest_inc_Y = 0, dest_inc_UV = 0; 613 614 dest_inc_UV = dst_uv_strd; 615 616 if (0 == convert_uv_only) 617 { 618 619 /* Copy Y buffer */ 620 pu1_dst = (UWORD8 *) pu1_y_dst; 621 pu1_src = (UWORD8 *) pu1_y_src; 622 623 dest_inc_Y = dst_y_strd; 624 625 for (i = 0; i < u2_height; i++) 626 { 627 memcpy((void *) pu1_dst, (void *) pu1_src, u2_width); 628 pu1_dst += dest_inc_Y; 629 pu1_src += src_y_strd; 630 } 631 } 632 633 /* Interleave Cb and Cr buffers */ 634 pu1_src_u = pu1_u_src; 635 pu1_src_v = pu1_v_src; 636 pu1_dst = pu1_uv_dst; 637 638 u2_height = (u2_height + 1) >> 1; 639 u2_width_uv = (u2_width + 1) >> 1; 640 for (i = 0; i < u2_height; i++) 641 { 642 UWORD32 j; 643 for (j = 0; j < u2_width_uv; j++) 644 { 645 *pu1_dst++ = *pu1_src_u++; 646 *pu1_dst++ = *pu1_src_v++; 647 } 648 649 pu1_dst += dest_inc_UV - u2_width; 650 pu1_src_u += src_u_strd - u2_width_uv; 651 pu1_src_v += src_v_strd - u2_width_uv; 652 } 653 } 654 655 /** 656 ******************************************************************************* 657 * 658 * @brief Function used to convert 422 interleaved to 420sp 659 * 660 * @par Description 661 * Function used to convert 422 interleaved to 420sp 662 * 663 * @param[in] pu1_y_buf 664 * Output Y pointer 665 * 666 * @param[in] pu1_u_buf 667 * Output u pointer 668 * 669 * @param[in[ pu1_v_buf 670 * Output V pointer 671 * 672 * @param[in] pu1_422i_buf 673 * Input 422i pointer 674 * 675 * @param[in] u4_y_width 676 * Width of Y component 677 * 678 * @param[in] u4_y_height 679 * Height of Y component 680 * 681 * @param[in] u4_y_stride 682 * Stride of pu1_y_buf 683 * 684 * @param[in] u4_u_stride 685 * Stride of pu1_u_buf 686 * 687 * @param[in] u4_v_stride 688 * Stride of pu1_v_buf 689 * 690 * @param[in] u4_422i_stride 691 * Stride of pu1_422i_buf 692 * 693 * @returns None 694 * 695 * @remarks For conversion 696 * pu1_v_buf = pu1_u_buf+1 697 * u4_u_stride = u4_v_stride 698 * 699 * The extra parameters are for maintaining API with assembly function 700 * 701 ******************************************************************************* 702 */ 703 void ih264e_fmt_conv_422i_to_420sp(UWORD8 *pu1_y_buf, 704 UWORD8 *pu1_u_buf, 705 UWORD8 *pu1_v_buf, 706 UWORD8 *pu1_422i_buf, 707 WORD32 u4_y_width, 708 WORD32 u4_y_height, 709 WORD32 u4_y_stride, 710 WORD32 u4_u_stride, 711 WORD32 u4_v_stride, 712 WORD32 u4_422i_stride) 713 { 714 WORD32 row, col; 715 UWORD8 *row_even_422 = pu1_422i_buf; 716 UWORD8 *row_odd_422 = row_even_422 + (u4_422i_stride << 1); 717 UWORD8 *row_even_luma = pu1_y_buf; 718 /* Since at the end of loop, we have row_even_luma += (luma_width << 1), 719 * it should be same here right? */ 720 UWORD8 *row_odd_luma = row_even_luma + u4_y_stride; 721 UWORD8 *row_cb = pu1_u_buf; 722 UWORD8 *row_cr = pu1_v_buf; 723 724 for (row = 0; row < u4_y_height; row = row + 2) 725 { 726 for (col = 0; col < (u4_y_width << 1); col = col + 4) 727 { 728 UWORD8 cb_even = row_even_422[col]; 729 UWORD8 cr_even = row_even_422[col + 2]; 730 731 row_cb[col >> 1] = cb_even; 732 row_cr[col >> 1] = cr_even; 733 734 row_even_luma[col >> 1] = row_even_422[col + 1]; 735 row_even_luma[(col >> 1) + 1] = row_even_422[col + 3]; 736 737 row_odd_luma[col >> 1] = row_odd_422[col + 1]; 738 row_odd_luma[(col >> 1) + 1] = row_odd_422[col + 3]; 739 } 740 741 row_even_422 += (u4_422i_stride << 2); 742 row_odd_422 += (u4_422i_stride << 2); 743 744 row_even_luma += (u4_y_stride << 1); 745 row_odd_luma += (u4_y_stride << 1); 746 747 row_cb += u4_u_stride; 748 row_cr += u4_v_stride; 749 } 750 } 751 752 /** 753 ******************************************************************************* 754 * 755 * @brief Function used from format conversion or frame copy 756 * 757 * @par Description 758 * Function used from copying or converting a reference frame to display buffer 759 * in non shared mode 760 * 761 * @param[in] pu1_y_dst 762 * Output Y pointer 763 * 764 * @param[in] pu1_u_dst 765 * Output U/UV pointer ( UV is interleaved in the same format as that of input) 766 * 767 * @param[in] pu1_v_dst 768 * Output V pointer ( used in 420P output case) 769 * 770 * @param[in] u4_dst_y_strd 771 * Stride of destination Y buffer 772 * 773 * @param[in] u4_dst_u_strd 774 * Stride of destination U/V buffer 775 * 776 * @param[in] blocking 777 * To indicate whether format conversion should wait till frame is reconstructed 778 * and then return after complete copy is done. To be set to 1 when called at the 779 * end of frame processing and set to 0 when called between frame processing modules 780 * in order to utilize available MCPS 781 * 782 * @returns error status 783 * 784 * @remarks 785 * Assumes that the stride of U and V buffers are same. 786 * This is correct in most cases 787 * If a case comes where this is not true we need to modify the fmt conversion 788 * functions called inside also 789 * 790 ******************************************************************************* 791 */ 792 IH264E_ERROR_T ih264e_fmt_conv(codec_t *ps_codec, 793 pic_buf_t *ps_pic, 794 UWORD8 *pu1_y_dst, 795 UWORD8 *pu1_u_dst, 796 UWORD8 *pu1_v_dst, 797 UWORD32 u4_dst_y_strd, 798 UWORD32 u4_dst_uv_strd, 799 WORD32 cur_row, 800 WORD32 num_rows) 801 { 802 IH264E_ERROR_T ret = IH264E_SUCCESS; 803 UWORD8 *pu1_y_src, *pu1_uv_src; 804 UWORD8 *pu1_y_dst_tmp, *pu1_uv_dst_tmp; 805 UWORD8 *pu1_u_dst_tmp, *pu1_v_dst_tmp; 806 UWORD16 *pu2_rgb_dst_tmp; 807 UWORD32 *pu4_rgb_dst_tmp; 808 WORD32 is_u_first; 809 UWORD8 *pu1_luma; 810 UWORD8 *pu1_chroma; 811 WORD32 dst_stride, wd; 812 813 814 if (0 == num_rows) 815 return ret; 816 817 pu1_luma = ps_pic->pu1_luma; 818 pu1_chroma = ps_pic->pu1_chroma; 819 820 821 dst_stride = ps_codec->s_cfg.u4_wd; 822 wd = ps_codec->s_cfg.u4_disp_wd; 823 is_u_first = (IV_YUV_420SP_UV == ps_codec->e_codec_color_format) ? 1 : 0; 824 825 /* In case of 420P output luma copy is disabled for shared mode */ 826 { 827 pu1_y_src = pu1_luma + cur_row * ps_codec->i4_rec_strd; 828 pu1_uv_src = pu1_chroma + (cur_row / 2) * ps_codec->i4_rec_strd; 829 830 pu2_rgb_dst_tmp = (UWORD16 *) pu1_y_dst; 831 pu2_rgb_dst_tmp += cur_row * dst_stride; 832 pu4_rgb_dst_tmp = (UWORD32 *) pu1_y_dst; 833 pu4_rgb_dst_tmp += cur_row * dst_stride; 834 835 pu1_y_dst_tmp = pu1_y_dst + cur_row * u4_dst_y_strd; 836 pu1_uv_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd; 837 pu1_u_dst_tmp = pu1_u_dst + (cur_row / 2) * u4_dst_uv_strd; 838 pu1_v_dst_tmp = pu1_v_dst + (cur_row / 2) * u4_dst_uv_strd; 839 840 /* If the call is non-blocking and there are no rows to be copied then return */ 841 /* In non-shared mode, reference buffers are in 420SP UV format, 842 * if output also is in 420SP_UV, then just copy 843 * if output is in 420SP_VU then swap UV values 844 */ 845 if ((IV_YUV_420SP_UV == ps_codec->s_cfg.e_recon_color_fmt) || 846 (IV_YUV_420SP_VU == ps_codec->s_cfg.e_recon_color_fmt)) 847 { 848 ih264e_fmt_conv_420sp_to_420sp(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp, 849 pu1_uv_dst_tmp, wd, num_rows, 850 ps_codec->i4_rec_strd, 851 ps_codec->i4_rec_strd, u4_dst_y_strd, 852 u4_dst_uv_strd); 853 } 854 else if (IV_YUV_420P == ps_codec->s_cfg.e_recon_color_fmt) 855 { 856 ih264e_fmt_conv_420sp_to_420p(pu1_y_src, pu1_uv_src, pu1_y_dst_tmp, 857 pu1_u_dst_tmp, pu1_v_dst_tmp, wd, 858 num_rows, ps_codec->i4_rec_strd, 859 ps_codec->i4_rec_strd, u4_dst_y_strd, 860 u4_dst_uv_strd, is_u_first, 0); 861 } 862 } 863 return(ret); 864 } 865 866