1 /****************************************************************************** 2 * 3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore 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 ******************************************************************************* 20 * @file 21 * ihevc_intra_pred_filters.c 22 * 23 * @brief 24 * Contains function Definition for intra prediction interpolation filters 25 * 26 * 27 * @author 28 * Srinivas T 29 * 30 * @par List of Functions: 31 * - ihevc_intra_pred_luma_planar() 32 * - ihevc_intra_pred_luma_dc() 33 * - ihevc_intra_pred_luma_horz() 34 * - ihevc_intra_pred_luma_ver() 35 * - ihevc_intra_pred_luma_mode2() 36 * - ihevc_intra_pred_luma_mode_18_34() 37 * - ihevc_intra_pred_luma_mode_3_to_9() 38 * - ihevc_intra_pred_luma_mode_11_to_17() 39 * - ihevc_intra_pred_luma_mode_19_to_25() 40 * - ihevc_intra_pred_luma_mode_27_to_33() 41 * - ihevc_intra_pred_luma_ref_substitution() 42 * 43 * @remarks 44 * None 45 * 46 ******************************************************************************* 47 */ 48 49 50 /*****************************************************************************/ 51 /* File Includes */ 52 /*****************************************************************************/ 53 54 #include <assert.h> 55 #include "ihevc_typedefs.h" 56 #include "ihevc_intra_pred.h" 57 #include "ihevc_macros.h" 58 #include "ihevc_func_selector.h" 59 #include "ihevc_platform_macros.h" 60 #include "ihevc_common_tables.h" 61 #include "ihevc_defs.h" 62 #include "ihevc_mem_fns.h" 63 #include "ihevc_debug.h" 64 65 /****************************************************************************/ 66 /* Constant Macros */ 67 /****************************************************************************/ 68 #define MAX_CU_SIZE 64 69 #define BIT_DEPTH 8 70 #define T32_4NT 128 71 #define T16_4NT 64 72 73 74 /****************************************************************************/ 75 /* Function Macros */ 76 /****************************************************************************/ 77 #define GET_BITS(y,x) ((y) & (1 << x)) && (1 << x) 78 79 /*****************************************************************************/ 80 /* global tables Definition */ 81 /*****************************************************************************/ 82 83 84 /*****************************************************************************/ 85 /* Function Definition */ 86 /*****************************************************************************/ 87 88 /** 89 ******************************************************************************* 90 * 91 * @brief 92 * Intra prediction interpolation filter for pu1_ref substitution 93 * 94 * 95 * @par Description: 96 * Reference substitution process for samples unavailable for prediction 97 * Refer to section 8.4.4.2.2 98 * 99 * @param[in] pu1_top_left 100 * UWORD8 pointer to the top-left 101 * 102 * @param[in] pu1_top 103 * UWORD8 pointer to the top 104 * 105 * @param[in] pu1_left 106 * UWORD8 pointer to the left 107 * 108 * @param[in] src_strd 109 * WORD32 Source stride 110 * 111 * @param[in] nbr_flags 112 * WORD32 neighbor availability flags 113 * 114 * @param[in] nt 115 * WORD32 transform Block size 116 * 117 * @param[in] dst_strd 118 * WORD32 Destination stride 119 * 120 * @returns 121 * 122 * @remarks 123 * None 124 * 125 ******************************************************************************* 126 */ 127 void ihevc_intra_pred_luma_ref_subst_all_avlble(UWORD8 *pu1_top_left, 128 UWORD8 *pu1_top, 129 UWORD8 *pu1_left, 130 WORD32 src_strd, 131 WORD32 nt, 132 WORD32 nbr_flags, 133 UWORD8 *pu1_dst, 134 WORD32 dst_strd) 135 { 136 137 WORD32 i; 138 WORD32 two_nt = 2 * nt; 139 UNUSED(nbr_flags); 140 UNUSED(dst_strd); 141 142 /* Neighbor Flag Structure*/ 143 /* MSB ---> LSB */ 144 /* Top-Left | Top-Right | Top | Left | Bottom-Left 145 1 4 4 4 4 146 */ 147 ASSERT((nbr_flags == 0x11188) || (nbr_flags == 0x133CC) || (nbr_flags == 0x1FFFF)); 148 { 149 150 if(nt == 4) 151 { 152 /* 1 bit extraction for all the neighboring blocks */ 153 154 155 /* Else fill the corresponding samples */ 156 pu1_dst[two_nt] = *pu1_top_left; 157 //if(left) 158 { 159 for(i = 0; i < nt; i++) 160 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 161 } 162 // if(bot_left) 163 { 164 for(i = nt; i < two_nt; i++) 165 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 166 } 167 // if(top) 168 { 169 ihevc_memcpy(&pu1_dst[two_nt + 1], pu1_top, nt); 170 } 171 // if(tp_right) 172 { 173 ihevc_memcpy(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt); 174 } 175 176 177 } 178 else 179 180 { 181 182 /* Else fill the corresponding samples */ 183 ASSERT((nt == 8) || (nt == 16) || (nt == 32)); 184 pu1_dst[two_nt] = *pu1_top_left; 185 186 for(i = 0; i < nt; i++) 187 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 188 189 for(i = nt; i < two_nt; i++) 190 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 191 192 ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1], pu1_top, nt); 193 194 ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt); 195 } 196 197 } 198 } 199 200 201 void ihevc_intra_pred_luma_ref_substitution(UWORD8 *pu1_top_left, 202 UWORD8 *pu1_top, 203 UWORD8 *pu1_left, 204 WORD32 src_strd, 205 WORD32 nt, 206 WORD32 nbr_flags, 207 UWORD8 *pu1_dst, 208 WORD32 dst_strd) 209 { 210 UWORD8 pu1_ref; 211 WORD32 dc_val, i; 212 WORD32 total_samples = (4 * nt) + 1; 213 WORD32 two_nt = 2 * nt; 214 215 WORD32 three_nt = 3 * nt; 216 WORD32 get_bits; 217 WORD32 next; 218 WORD32 bot_left, left, top, tp_right, tp_left; 219 220 WORD32 idx, nbr_id_from_bl, frwd_nbr_flag; 221 UNUSED(dst_strd); 222 /*dc_val = 1 << (BIT_DEPTH - 1);*/ 223 dc_val = 1 << (8 - 1); 224 225 226 /* Neighbor Flag Structure*/ 227 /* MSB ---> LSB */ 228 /* Top-Left | Top-Right | Top | Left | Bottom-Left 229 1 4 4 4 4 230 */ 231 /* If no neighbor flags are present, fill the neighbor samples with DC value */ 232 if(nbr_flags == 0) 233 { 234 for(i = 0; i < total_samples; i++) 235 { 236 pu1_dst[i] = dc_val; 237 } 238 } 239 else 240 { 241 if(nt <= 8) 242 { 243 /* 1 bit extraction for all the neighboring blocks */ 244 tp_left = (nbr_flags & 0x10000) >> 16; 245 bot_left = (nbr_flags & 0x8) >> 3; 246 left = (nbr_flags & 0x80) >> 7; 247 top = (nbr_flags & 0x100) >> 8; 248 tp_right = (nbr_flags & 0x1000) >> 12; 249 250 /* Else fill the corresponding samples */ 251 if(tp_left) 252 pu1_dst[two_nt] = *pu1_top_left; 253 else 254 pu1_dst[two_nt] = 0; 255 256 257 if(left) 258 { 259 for(i = 0; i < nt; i++) 260 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 261 } 262 else 263 { 264 ihevc_memset(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt); 265 } 266 267 268 if(bot_left) 269 { 270 for(i = nt; i < two_nt; i++) 271 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 272 } 273 else 274 { 275 ihevc_memset(&pu1_dst[two_nt - 1 - (two_nt - 1)], 0, nt); 276 } 277 278 279 if(top) 280 { 281 ihevc_memcpy(&pu1_dst[two_nt + 1], pu1_top, nt); 282 } 283 else 284 { 285 ihevc_memset(&pu1_dst[two_nt + 1], 0, nt); 286 } 287 288 if(tp_right) 289 { 290 ihevc_memcpy(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt); 291 } 292 else 293 { 294 ihevc_memset(&pu1_dst[two_nt + 1 + nt], 0, nt); 295 } 296 next = 1; 297 298 /* If bottom -left is not available, reverse substitution process*/ 299 if(bot_left == 0) 300 { 301 WORD32 a_nbr_flag[5]; 302 a_nbr_flag[0] = bot_left; 303 a_nbr_flag[1] = left; 304 a_nbr_flag[2] = tp_left; 305 a_nbr_flag[3] = top; 306 a_nbr_flag[4] = tp_right; 307 308 /* Check for the 1st available sample from bottom-left*/ 309 while(!a_nbr_flag[next]) 310 next++; 311 312 /* If Left, top-left are available*/ 313 if(next <= 2) 314 { 315 idx = nt * next; 316 pu1_ref = pu1_dst[idx]; 317 for(i = 0; i < idx; i++) 318 pu1_dst[i] = pu1_ref; 319 } 320 else /* If top, top-right are available */ 321 { 322 /* Idx is changed to copy 1 pixel value for top-left ,if top-left is not available*/ 323 idx = (nt * (next - 1)) + 1; 324 pu1_ref = pu1_dst[idx]; 325 for(i = 0; i < idx; i++) 326 pu1_dst[i] = pu1_ref; 327 } 328 } 329 330 /* Forward Substitution Process */ 331 /* If left is Unavailable, copy the last bottom-left value */ 332 if(left == 0) 333 { 334 ihevc_memset(&pu1_dst[nt], pu1_dst[nt - 1], nt); 335 336 } 337 /* If top-left is Unavailable, copy the last left value */ 338 if(tp_left == 0) 339 pu1_dst[two_nt] = pu1_dst[two_nt - 1]; 340 /* If top is Unavailable, copy the last top-left value */ 341 if(top == 0) 342 { 343 ihevc_memset(&pu1_dst[two_nt + 1], pu1_dst[two_nt], nt); 344 } 345 /* If to right is Unavailable, copy the last top value */ 346 if(tp_right == 0) 347 { 348 ihevc_memset(&pu1_dst[three_nt + 1], pu1_dst[three_nt], nt); 349 350 } 351 } 352 353 if(nt == 16) 354 { 355 WORD32 nbr_flags_temp = 0; 356 nbr_flags_temp = ((nbr_flags & 0xC) >> 2) + ((nbr_flags & 0xC0) >> 4) 357 + ((nbr_flags & 0x300) >> 4) 358 + ((nbr_flags & 0x3000) >> 6) 359 + ((nbr_flags & 0x10000) >> 8); 360 361 /* Else fill the corresponding samples */ 362 if(nbr_flags & 0x10000) 363 pu1_dst[two_nt] = *pu1_top_left; 364 else 365 pu1_dst[two_nt] = 0; 366 367 if(nbr_flags & 0xC0) 368 { 369 for(i = 0; i < nt; i++) 370 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 371 } 372 else 373 { 374 ihevc_memset_mul_8(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt); 375 } 376 377 /* Bottom - left availability is checked for every 8x8 TU position and set accordingly */ 378 { 379 if(nbr_flags & 0x8) 380 { 381 for(i = nt; i < (nt + 8); i++) 382 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 383 } 384 else 385 { 386 ihevc_memset_mul_8(&pu1_dst[nt - 8], 0, 8); 387 } 388 389 if(nbr_flags & 0x4) 390 { 391 for(i = (nt + 8); i < two_nt; i++) 392 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 393 } 394 else 395 { 396 ihevc_memset_mul_8(&pu1_dst[0], 0, 8); 397 } 398 } 399 400 if(nbr_flags & 0x300) 401 { 402 ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1], pu1_top, nt); 403 } 404 else 405 { 406 ihevc_memset_mul_8(&pu1_dst[two_nt + 1], 0, nt); 407 } 408 409 if(nbr_flags & 0x3000) 410 { 411 ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt); 412 } 413 else 414 { 415 ihevc_memset_mul_8(&pu1_dst[two_nt + 1 + nt], 0, nt); 416 } 417 /* compute trailing zeors based on nbr_flag for substitution process of below left see section .*/ 418 /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */ 419 { 420 nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * 8; /* for below left and left */ 421 422 if(nbr_id_from_bl == 64) 423 nbr_id_from_bl = 32; 424 425 if(nbr_id_from_bl == 32) 426 { 427 /* for top left : 1 pel per nbr bit */ 428 if(!((nbr_flags_temp >> 8) & 0x1)) 429 { 430 nbr_id_from_bl++; 431 nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * 8; /* top and top right; 8 pels per nbr bit */ 432 //nbr_id_from_bl += idx * 8; 433 } 434 } 435 /* Reverse Substitution Process*/ 436 if(nbr_id_from_bl) 437 { 438 /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */ 439 pu1_ref = pu1_dst[nbr_id_from_bl]; 440 for(i = (nbr_id_from_bl - 1); i >= 0; i--) 441 { 442 pu1_dst[i] = pu1_ref; 443 } 444 } 445 } 446 447 /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */ 448 while(nbr_id_from_bl < ((T16_4NT)+1)) 449 { 450 /* To Obtain the next unavailable idx flag after reverse neighbor substitution */ 451 /* Devide by 8 to obtain the original index */ 452 frwd_nbr_flag = (nbr_id_from_bl >> 3); /*+ (nbr_id_from_bl & 0x1);*/ 453 454 /* The Top-left flag is at the last bit location of nbr_flags*/ 455 if(nbr_id_from_bl == (T16_4NT / 2)) 456 { 457 get_bits = GET_BITS(nbr_flags_temp, 8); 458 459 /* only pel substitution for TL */ 460 if(!get_bits) 461 pu1_dst[nbr_id_from_bl] = pu1_dst[nbr_id_from_bl - 1]; 462 } 463 else 464 { 465 get_bits = GET_BITS(nbr_flags_temp, frwd_nbr_flag); 466 if(!get_bits) 467 { 468 /* 8 pel substitution (other than TL) */ 469 pu1_ref = pu1_dst[nbr_id_from_bl - 1]; 470 ihevc_memset_mul_8(pu1_dst + nbr_id_from_bl, pu1_ref, 8); 471 472 473 } 474 475 } 476 nbr_id_from_bl += (nbr_id_from_bl == (T16_4NT / 2)) ? 1 : 8; 477 } 478 479 480 } 481 482 if(nt == 32) 483 { 484 /* Else fill the corresponding samples */ 485 if(nbr_flags & 0x10000) 486 pu1_dst[two_nt] = *pu1_top_left; 487 else 488 pu1_dst[two_nt] = 0; 489 490 if(nbr_flags & 0xF0) 491 { 492 for(i = 0; i < nt; i++) 493 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 494 } 495 else 496 { 497 ihevc_memset_mul_8(&pu1_dst[two_nt - 1 - (nt - 1)], 0, nt); 498 } 499 500 /* Bottom - left availability is checked for every 8x8 TU position and set accordingly */ 501 { 502 if(nbr_flags & 0x8) 503 { 504 for(i = nt; i < (nt + 8); i++) 505 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 506 } 507 else 508 { 509 ihevc_memset_mul_8(&pu1_dst[24], 0, 8); 510 } 511 512 if(nbr_flags & 0x4) 513 { 514 for(i = (nt + 8); i < (nt + 16); i++) 515 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 516 } 517 else 518 { 519 ihevc_memset_mul_8(&pu1_dst[16], 0, 8); 520 } 521 522 if(nbr_flags & 0x2) 523 { 524 for(i = (nt + 16); i < (nt + 24); i++) 525 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 526 } 527 else 528 { 529 ihevc_memset_mul_8(&pu1_dst[8], 0, 8); 530 } 531 532 if(nbr_flags & 0x1) 533 { 534 for(i = (nt + 24); i < (two_nt); i++) 535 pu1_dst[two_nt - 1 - i] = pu1_left[i * src_strd]; 536 } 537 else 538 { 539 ihevc_memset_mul_8(&pu1_dst[0], 0, 8); 540 } 541 } 542 543 544 if(nbr_flags & 0xF00) 545 { 546 ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1], pu1_top, nt); 547 } 548 else 549 { 550 ihevc_memset_mul_8(&pu1_dst[two_nt + 1], 0, nt); 551 } 552 553 if(nbr_flags & 0xF000) 554 { 555 ihevc_memcpy_mul_8(&pu1_dst[two_nt + 1 + nt], pu1_top + nt, nt); 556 } 557 else 558 { 559 ihevc_memset_mul_8(&pu1_dst[two_nt + 1 + nt], 0, nt); 560 } 561 /* compute trailing ones based on mbr_flag for substitution process of below left see section .*/ 562 /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */ 563 { 564 nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 8; /* for below left and left */ 565 566 if(nbr_id_from_bl == 64) 567 { 568 /* for top left : 1 pel per nbr bit */ 569 if(!((nbr_flags >> 16) & 0x1)) 570 { 571 /* top left not available */ 572 nbr_id_from_bl++; 573 /* top and top right; 8 pels per nbr bit */ 574 nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 8; 575 } 576 } 577 /* Reverse Substitution Process*/ 578 if(nbr_id_from_bl) 579 { 580 /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */ 581 pu1_ref = pu1_dst[nbr_id_from_bl]; 582 for(i = (nbr_id_from_bl - 1); i >= 0; i--) 583 pu1_dst[i] = pu1_ref; 584 } 585 } 586 587 /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */ 588 while(nbr_id_from_bl < ((T32_4NT)+1)) 589 { 590 /* To Obtain the next unavailable idx flag after reverse neighbor substitution */ 591 /* Devide by 8 to obtain the original index */ 592 frwd_nbr_flag = (nbr_id_from_bl >> 3); /*+ (nbr_id_from_bl & 0x1);*/ 593 594 /* The Top-left flag is at the last bit location of nbr_flags*/ 595 if(nbr_id_from_bl == (T32_4NT / 2)) 596 { 597 get_bits = GET_BITS(nbr_flags, 16); 598 /* only pel substitution for TL */ 599 if(!get_bits) 600 pu1_dst[nbr_id_from_bl] = pu1_dst[nbr_id_from_bl - 1]; 601 } 602 else 603 { 604 get_bits = GET_BITS(nbr_flags, frwd_nbr_flag); 605 if(!get_bits) 606 { 607 /* 8 pel substitution (other than TL) */ 608 pu1_ref = pu1_dst[nbr_id_from_bl - 1]; 609 ihevc_memset_mul_8(&pu1_dst[nbr_id_from_bl], pu1_ref, 8); 610 611 } 612 613 } 614 nbr_id_from_bl += (nbr_id_from_bl == (T32_4NT / 2)) ? 1 : 8; 615 } 616 } 617 618 } 619 } 620 621 622 /** 623 ******************************************************************************* 624 * 625 * @brief 626 * Intra prediction interpolation filter for ref_filtering 627 * 628 * 629 * @par Description: 630 * Reference DC filtering for neighboring samples dependent on TU size and 631 * mode Refer to section 8.4.4.2.3 in the standard 632 * 633 * @param[in] pu1_src 634 * UWORD8 pointer to the source 635 * 636 * @param[out] pu1_dst 637 * UWORD8 pointer to the destination 638 * 639 * @param[in] nt 640 * integer Transform Block size 641 * 642 * @param[in] mode 643 * integer intraprediction mode 644 * 645 * @returns 646 * 647 * @remarks 648 * None 649 * 650 ******************************************************************************* 651 */ 652 653 654 void ihevc_intra_pred_ref_filtering(UWORD8 *pu1_src, 655 WORD32 nt, 656 UWORD8 *pu1_dst, 657 WORD32 mode, 658 WORD32 strong_intra_smoothing_enable_flag) 659 { 660 WORD32 filter_flag; 661 WORD32 i; /* Generic indexing variable */ 662 WORD32 four_nt = 4 * nt; 663 UWORD8 au1_flt[(4 * MAX_CU_SIZE) + 1]; 664 WORD32 bi_linear_int_flag = 0; 665 WORD32 abs_cond_left_flag = 0; 666 WORD32 abs_cond_top_flag = 0; 667 /*WORD32 dc_val = 1 << (BIT_DEPTH - 5);*/ 668 WORD32 dc_val = 1 << (8 - 5); 669 //WORD32 strong_intra_smoothing_enable_flag = 1; 670 671 filter_flag = gau1_intra_pred_ref_filter[mode] & (1 << (CTZ(nt) - 2)); 672 if(0 == filter_flag) 673 { 674 if(pu1_src == pu1_dst) 675 { 676 return; 677 } 678 else 679 { 680 for(i = 0; i < (four_nt + 1); i++) 681 pu1_dst[i] = pu1_src[i]; 682 } 683 } 684 685 else 686 { 687 /* If strong intra smoothin is enabled and transform size is 32 */ 688 if((1 == strong_intra_smoothing_enable_flag) && (32 == nt)) 689 { 690 /* Strong Intra Filtering */ 691 abs_cond_top_flag = (ABS(pu1_src[2 * nt] + pu1_src[4 * nt] 692 - (2 * pu1_src[3 * nt]))) < dc_val; 693 abs_cond_left_flag = (ABS(pu1_src[2 * nt] + pu1_src[0] 694 - (2 * pu1_src[nt]))) < dc_val; 695 696 bi_linear_int_flag = ((1 == abs_cond_left_flag) 697 && (1 == abs_cond_top_flag)); 698 } 699 /* Extremities Untouched*/ 700 au1_flt[0] = pu1_src[0]; 701 au1_flt[4 * nt] = pu1_src[4 * nt]; 702 703 /* Strong filtering of reference samples */ 704 if(1 == bi_linear_int_flag) 705 { 706 au1_flt[2 * nt] = pu1_src[2 * nt]; 707 708 for(i = 1; i < (2 * nt); i++) 709 au1_flt[i] = (((2 * nt) - i) * pu1_src[0] + i * pu1_src[2 * nt] + 32) >> 6; 710 711 for(i = 1; i < (2 * nt); i++) 712 au1_flt[i + (2 * nt)] = (((2 * nt) - i) * pu1_src[2 * nt] + i * pu1_src[4 * nt] + 32) >> 6; 713 714 } 715 else 716 { 717 /* Perform bilinear filtering of Reference Samples */ 718 for(i = 0; i < (four_nt - 1); i++) 719 { 720 au1_flt[i + 1] = (pu1_src[i] + 2 * pu1_src[i + 1] 721 + pu1_src[i + 2] + 2) >> 2; 722 } 723 } 724 725 726 for(i = 0; i < (four_nt + 1); i++) 727 pu1_dst[i] = au1_flt[i]; 728 } 729 730 } 731 732 733 /** 734 ******************************************************************************* 735 * 736 * @brief 737 * Intra prediction interpolation filter for luma planar 738 * 739 * @par Description: 740 * Planar Intraprediction with reference neighboring samples location 741 * pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 742 * to section 8.4.4.2.4 in the standard 743 * 744 * @param[in] pu1_src 745 * UWORD8 pointer to the source 746 * 747 * @param[out] pu1_dst 748 * UWORD8 pointer to the destination 749 * 750 * @param[in] src_strd 751 * integer source stride 752 * 753 * @param[in] dst_strd 754 * integer destination stride 755 * 756 * @param[in] nt 757 * integer Transform Block size 758 * 759 * @param[in] mode 760 * integer intraprediction mode 761 * 762 * @returns 763 * 764 * @remarks 765 * None 766 * 767 ******************************************************************************* 768 */ 769 770 771 void ihevc_intra_pred_luma_planar(UWORD8 *pu1_ref, 772 WORD32 src_strd, 773 UWORD8 *pu1_dst, 774 WORD32 dst_strd, 775 WORD32 nt, 776 WORD32 mode) 777 { 778 779 780 WORD32 row, col; 781 WORD32 log2nt = 5; 782 WORD32 two_nt, three_nt; 783 UNUSED(src_strd); 784 UNUSED(mode); 785 switch(nt) 786 { 787 case 32: 788 log2nt = 5; 789 break; 790 case 16: 791 log2nt = 4; 792 break; 793 case 8: 794 log2nt = 3; 795 break; 796 case 4: 797 log2nt = 2; 798 break; 799 default: 800 break; 801 } 802 two_nt = 2 * nt; 803 three_nt = 3 * nt; 804 /* Planar filtering */ 805 for(row = 0; row < nt; row++) 806 { 807 for(col = 0; col < nt; col++) 808 { 809 pu1_dst[row * dst_strd + col] = ((nt - 1 - col) 810 * pu1_ref[two_nt - 1 - row] 811 + (col + 1) * pu1_ref[three_nt + 1] 812 + (nt - 1 - row) * pu1_ref[two_nt + 1 + col] 813 + (row + 1) * pu1_ref[nt - 1] + nt) >> (log2nt + 1); 814 } 815 } 816 } 817 818 819 /** 820 ******************************************************************************* 821 * 822 * @brief 823 * Intra prediction interpolation filter for luma dc 824 * 825 * @par Description: 826 * Intraprediction for DC mode with reference neighboring samples location 827 * pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 828 * to section 8.4.4.2.5 in the standard 829 * 830 * @param[in] pu1_src 831 * UWORD8 pointer to the source 832 * 833 * @param[out] pu1_dst 834 * UWORD8 pointer to the destination 835 * 836 * @param[in] src_strd 837 * integer source stride 838 * 839 * @param[in] dst_strd 840 * integer destination stride 841 * 842 * @param[in] nt 843 * integer Transform Block size 844 * 845 * @param[in] mode 846 * integer intraprediction mode 847 * 848 * @returns 849 * 850 * @remarks 851 * None 852 * 853 ******************************************************************************* 854 */ 855 856 857 void ihevc_intra_pred_luma_dc(UWORD8 *pu1_ref, 858 WORD32 src_strd, 859 UWORD8 *pu1_dst, 860 WORD32 dst_strd, 861 WORD32 nt, 862 WORD32 mode) 863 { 864 865 WORD32 acc_dc; 866 WORD32 dc_val, two_dc_val, three_dc_val; 867 WORD32 i; 868 WORD32 row, col; 869 WORD32 log2nt = 5; 870 WORD32 two_nt, three_nt; 871 UNUSED(mode); 872 UNUSED(src_strd); 873 switch(nt) 874 { 875 case 32: 876 log2nt = 5; 877 break; 878 case 16: 879 log2nt = 4; 880 break; 881 case 8: 882 log2nt = 3; 883 break; 884 case 4: 885 log2nt = 2; 886 break; 887 default: 888 break; 889 } 890 two_nt = 2 * nt; 891 three_nt = 3 * nt; 892 893 acc_dc = 0; 894 /* Calculate DC value for the transform block */ 895 for(i = nt; i < two_nt; i++) 896 acc_dc += pu1_ref[i]; 897 898 for(i = (two_nt + 1); i <= three_nt; i++) 899 acc_dc += pu1_ref[i]; 900 901 dc_val = (acc_dc + nt) >> (log2nt + 1); 902 903 two_dc_val = 2 * dc_val; 904 three_dc_val = 3 * dc_val; 905 906 907 if(nt == 32) 908 { 909 for(row = 0; row < nt; row++) 910 for(col = 0; col < nt; col++) 911 pu1_dst[(row * dst_strd) + col] = dc_val; 912 } 913 else 914 { 915 /* DC filtering for the first top row and first left column */ 916 pu1_dst[0] = ((pu1_ref[two_nt - 1] + two_dc_val + pu1_ref[two_nt + 1] + 2) 917 >> 2); 918 919 for(col = 1; col < nt; col++) 920 pu1_dst[col] = (pu1_ref[two_nt + 1 + col] + three_dc_val + 2) >> 2; 921 922 for(row = 1; row < nt; row++) 923 pu1_dst[row * dst_strd] = (pu1_ref[two_nt - 1 - row] + three_dc_val + 2) 924 >> 2; 925 926 /* Fill the remaining rows with DC value*/ 927 for(row = 1; row < nt; row++) 928 for(col = 1; col < nt; col++) 929 pu1_dst[(row * dst_strd) + col] = dc_val; 930 } 931 } 932 933 934 935 /** 936 ******************************************************************************* 937 * 938 * @brief 939 * Intra prediction interpolation filter for horizontal luma variable. 940 * 941 * @par Description: 942 * Horizontal intraprediction(mode 10) with reference samples location 943 * pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 944 * to section 8.4.4.2.6 in the standard (Special case) 945 * 946 * @param[in] pu1_src 947 * UWORD8 pointer to the source 948 * 949 * @param[out] pu1_dst 950 * UWORD8 pointer to the destination 951 * 952 * @param[in] src_strd 953 * integer source stride 954 * 955 * @param[in] dst_strd 956 * integer destination stride 957 * 958 * @param[in] nt 959 * integer Transform Block size 960 * 961 * @param[in] mode 962 * integer intraprediction mode 963 * 964 * @returns 965 * 966 * @remarks 967 * None 968 * 969 ******************************************************************************* 970 */ 971 972 973 void ihevc_intra_pred_luma_horz(UWORD8 *pu1_ref, 974 WORD32 src_strd, 975 UWORD8 *pu1_dst, 976 WORD32 dst_strd, 977 WORD32 nt, 978 WORD32 mode) 979 { 980 981 WORD32 row, col; 982 WORD32 two_nt; 983 WORD16 s2_predpixel; 984 UNUSED(mode); 985 UNUSED(src_strd); 986 two_nt = 2 * nt; 987 988 if(nt == 32) 989 { 990 for(row = 0; row < nt; row++) 991 for(col = 0; col < nt; col++) 992 pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt - 1 - row]; 993 } 994 else 995 { 996 /*Filtering done for the 1st row */ 997 for(col = 0; col < nt; col++) 998 { 999 s2_predpixel = pu1_ref[two_nt - 1] 1000 + ((pu1_ref[two_nt + 1 + col] - pu1_ref[two_nt]) >> 1); 1001 pu1_dst[col] = CLIP_U8(s2_predpixel); 1002 } 1003 1004 /* Replication to next rows*/ 1005 for(row = 1; row < nt; row++) 1006 for(col = 0; col < nt; col++) 1007 pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt - 1 - row]; 1008 } 1009 } 1010 1011 1012 1013 1014 1015 /** 1016 ******************************************************************************* 1017 * 1018 * @brief 1019 * Intra prediction interpolation filter for vertical luma variable. 1020 * 1021 * @par Description: 1022 * Horizontal intraprediction with reference neighboring samples location 1023 * pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 1024 * to section 8.4.4.2.6 in the standard (Special case) 1025 * 1026 * @param[in] pu1_src 1027 * UWORD8 pointer to the source 1028 * 1029 * @param[out] pu1_dst 1030 * UWORD8 pointer to the destination 1031 * 1032 * @param[in] src_strd 1033 * integer source stride 1034 * 1035 * @param[in] dst_strd 1036 * integer destination stride 1037 * 1038 * @param[in] nt 1039 * integer Transform Block size 1040 * 1041 * @param[in] mode 1042 * integer intraprediction mode 1043 * 1044 * @returns 1045 * 1046 * @remarks 1047 * None 1048 * 1049 ******************************************************************************* 1050 */ 1051 1052 1053 void ihevc_intra_pred_luma_ver(UWORD8 *pu1_ref, 1054 WORD32 src_strd, 1055 UWORD8 *pu1_dst, 1056 WORD32 dst_strd, 1057 WORD32 nt, 1058 WORD32 mode) 1059 { 1060 WORD32 row, col; 1061 WORD16 s2_predpixel; 1062 WORD32 two_nt = 2 * nt; 1063 UNUSED(mode); 1064 UNUSED(src_strd); 1065 1066 if(nt == 32) 1067 { 1068 /* Replication to next columns*/ 1069 for(row = 0; row < nt; row++) 1070 for(col = 0; col < nt; col++) 1071 pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt + 1 + col]; 1072 } 1073 else 1074 { 1075 /*Filtering done for the 1st column */ 1076 for(row = 0; row < nt; row++) 1077 { 1078 s2_predpixel = pu1_ref[two_nt + 1] 1079 + ((pu1_ref[two_nt - 1 - row] - pu1_ref[two_nt]) >> 1); 1080 pu1_dst[row * dst_strd] = CLIP_U8(s2_predpixel); 1081 } 1082 1083 /* Replication to next columns*/ 1084 for(row = 0; row < nt; row++) 1085 for(col = 1; col < nt; col++) 1086 pu1_dst[(row * dst_strd) + col] = pu1_ref[two_nt + 1 + col]; 1087 } 1088 } 1089 1090 1091 1092 1093 /** 1094 ******************************************************************************* 1095 * 1096 * @brief 1097 * Intra prediction interpolation filter for luma mode2. 1098 * 1099 * @par Description: 1100 * Intraprediction for mode 2 (sw angle) with reference neighboring samples 1101 * location pointed by 'pu1_ref' to the TU block location pointed by 1102 * 'pu1_dst' Refer to section 8.4.4.2.6 in the standard 1103 * 1104 * @param[in] pu1_src 1105 * UWORD8 pointer to the source 1106 * 1107 * @param[out] pu1_dst 1108 * UWORD8 pointer to the destination 1109 * 1110 * @param[in] src_strd 1111 * integer source stride 1112 * 1113 * @param[in] dst_strd 1114 * integer destination stride 1115 * 1116 * @param[in] nt 1117 * integer Transform Block size 1118 * 1119 * @param[in] mode 1120 * integer intraprediction mode 1121 * 1122 * @returns 1123 * 1124 * @remarks 1125 * None 1126 * 1127 ******************************************************************************* 1128 */ 1129 1130 1131 void ihevc_intra_pred_luma_mode2(UWORD8 *pu1_ref, 1132 WORD32 src_strd, 1133 UWORD8 *pu1_dst, 1134 WORD32 dst_strd, 1135 WORD32 nt, 1136 WORD32 mode) 1137 { 1138 WORD32 row, col; 1139 WORD32 two_nt = 2 * nt; 1140 WORD32 intra_pred_ang = 32; 1141 WORD32 idx = 0; 1142 UNUSED(mode); 1143 UNUSED(src_strd); 1144 /* For the angle 45, replication is done from the corresponding angle */ 1145 /* intra_pred_ang = tan(angle) in q5 format */ 1146 for(col = 0; col < nt; col++) 1147 { 1148 idx = ((col + 1) * intra_pred_ang) >> 5; /* Use idx++ */ 1149 1150 for(row = 0; row < nt; row++) 1151 pu1_dst[col + (row * dst_strd)] = pu1_ref[two_nt - row - idx - 1]; 1152 } 1153 1154 } 1155 1156 1157 /** 1158 ******************************************************************************* 1159 * 1160 * @brief 1161 * Intra prediction interpolation filter for luma mode 18 & mode 34. 1162 * 1163 * @par Description: 1164 * Intraprediction for mode 34 (ne angle) and mode 18 (nw angle) with 1165 * reference neighboring samples location pointed by 'pu1_ref' to the TU 1166 * block location pointed by 'pu1_dst' 1167 * 1168 * @param[in] pu1_src 1169 * UWORD8 pointer to the source 1170 * 1171 * @param[out] pu1_dst 1172 * UWORD8 pointer to the destination 1173 * 1174 * @param[in] src_strd 1175 * integer source stride 1176 * 1177 * @param[in] dst_strd 1178 * integer destination stride 1179 * 1180 * @param[in] nt 1181 * integer Transform Block size 1182 * 1183 * @param[in] mode 1184 * integer intraprediction mode 1185 * 1186 * @returns 1187 * 1188 * @remarks 1189 * None 1190 * 1191 ******************************************************************************* 1192 */ 1193 1194 1195 void ihevc_intra_pred_luma_mode_18_34(UWORD8 *pu1_ref, 1196 WORD32 src_strd, 1197 UWORD8 *pu1_dst, 1198 WORD32 dst_strd, 1199 WORD32 nt, 1200 WORD32 mode) 1201 { 1202 WORD32 row, col; 1203 WORD32 intra_pred_ang; 1204 WORD32 idx = 0; 1205 WORD32 two_nt = 2 * nt; 1206 UNUSED(src_strd); 1207 intra_pred_ang = 32; /*Default value*/ 1208 1209 /* For mode 18, angle is -45degree */ 1210 if(mode == 18) 1211 intra_pred_ang = -32; 1212 /* For mode 34, angle is 45degree */ 1213 else if(mode == 34) 1214 intra_pred_ang = 32; 1215 /* For the angle 45 and -45, replication is done from the corresponding angle */ 1216 /* No interpolation is done for 45 degree*/ 1217 for(row = 0; row < nt; row++) 1218 { 1219 idx = ((row + 1) * intra_pred_ang) >> 5; 1220 #if OPT 1221 if(mode == 18) 1222 idx--; 1223 if(mode == 34) 1224 idx++; 1225 #endif 1226 for(col = 0; col < nt; col++) 1227 pu1_dst[col + (row * dst_strd)] = pu1_ref[two_nt + col + idx + 1]; 1228 1229 } 1230 1231 } 1232 1233 1234 /** 1235 ******************************************************************************* 1236 * 1237 * @brief 1238 * Intra prediction interpolation filter for luma mode 3 to mode 9 1239 * 1240 * @par Description: 1241 * Intraprediction for mode 3 to 9 (positive angle, horizontal mode ) with 1242 * reference neighboring samples location pointed by 'pu1_ref' to the TU 1243 * block location pointed by 'pu1_dst' 1244 * 1245 * @param[in] pu1_src 1246 * UWORD8 pointer to the source 1247 * 1248 * @param[out] pu1_dst 1249 * UWORD8 pointer to the destination 1250 * 1251 * @param[in] src_strd 1252 * integer source stride 1253 * 1254 * @param[in] dst_strd 1255 * integer destination stride 1256 * 1257 * @param[in] nt 1258 * integer Transform Block size 1259 * 1260 * @param[in] mode 1261 * integer intraprediction mode 1262 * 1263 * @returns 1264 * 1265 * @remarks 1266 * None 1267 * 1268 ******************************************************************************* 1269 */ 1270 1271 1272 void ihevc_intra_pred_luma_mode_3_to_9(UWORD8 *pu1_ref, 1273 WORD32 src_strd, 1274 UWORD8 *pu1_dst, 1275 WORD32 dst_strd, 1276 WORD32 nt, 1277 WORD32 mode) 1278 { 1279 WORD32 row, col; 1280 WORD32 two_nt = 2 * nt; 1281 WORD32 intra_pred_ang; 1282 WORD32 idx, ref_main_idx; 1283 WORD32 pos, fract; 1284 UNUSED(src_strd); 1285 /* Intra Pred Angle according to the mode */ 1286 intra_pred_ang = gai4_ihevc_ang_table[mode]; 1287 1288 /* For the angles other then 45 degree, interpolation btw 2 neighboring */ 1289 /* samples dependent on distance to obtain destination sample */ 1290 1291 for(col = 0; col < nt; col++) 1292 { 1293 pos = ((col + 1) * intra_pred_ang); 1294 idx = pos >> 5; 1295 fract = pos & (31); 1296 1297 // Do linear filtering 1298 for(row = 0; row < nt; row++) 1299 { 1300 ref_main_idx = two_nt - row - idx - 1; 1301 pu1_dst[col + (row * dst_strd)] = (((32 - fract) 1302 * pu1_ref[ref_main_idx] 1303 + fract * pu1_ref[ref_main_idx - 1] + 16) >> 5); 1304 } 1305 1306 } 1307 1308 } 1309 1310 1311 /** 1312 ******************************************************************************* 1313 * 1314 * @brief 1315 * Intra prediction interpolation filter for luma mode 11 to mode 17 1316 * 1317 * @par Description: 1318 * Intraprediction for mode 11 to 17 (negative angle, horizontal mode ) 1319 * with reference neighboring samples location pointed by 'pu1_ref' to the 1320 * TU block location pointed by 'pu1_dst' 1321 * 1322 * @param[in] pu1_src 1323 * UWORD8 pointer to the source 1324 * 1325 * @param[out] pu1_dst 1326 * UWORD8 pointer to the destination 1327 * 1328 * @param[in] src_strd 1329 * integer source stride 1330 * 1331 * @param[in] dst_strd 1332 * integer destination stride 1333 * 1334 * @param[in] nt 1335 * integer Transform Block size 1336 * 1337 * @param[in] mode 1338 * integer intraprediction mode 1339 * 1340 * @returns 1341 * 1342 * @remarks 1343 * None 1344 * 1345 ******************************************************************************* 1346 */ 1347 1348 1349 void ihevc_intra_pred_luma_mode_11_to_17(UWORD8 *pu1_ref, 1350 WORD32 src_strd, 1351 UWORD8 *pu1_dst, 1352 WORD32 dst_strd, 1353 WORD32 nt, 1354 WORD32 mode) 1355 { 1356 /* This function and ihevc_intra_pred_luma_mode_19_to_25 are same except*/ 1357 /* for ref main & side samples assignment,can be combined for */ 1358 /* optimzation*/ 1359 1360 WORD32 row, col, k; 1361 WORD32 two_nt; 1362 WORD32 intra_pred_ang, inv_ang, inv_ang_sum; 1363 WORD32 idx, ref_main_idx, ref_idx; 1364 WORD32 pos, fract; 1365 1366 UWORD8 ref_temp[2 * MAX_CU_SIZE + 1]; 1367 UWORD8 *ref_main; 1368 UNUSED(src_strd); 1369 inv_ang_sum = 128; 1370 two_nt = 2 * nt; 1371 1372 intra_pred_ang = gai4_ihevc_ang_table[mode]; 1373 1374 inv_ang = gai4_ihevc_inv_ang_table[mode - 11]; 1375 /* Intermediate reference samples for negative angle modes */ 1376 /* This have to be removed during optimization*/ 1377 /* For horizontal modes, (ref main = ref left) (ref side = ref above) */ 1378 1379 ref_main = ref_temp + nt - 1; 1380 for(k = 0; k < nt + 1; k++) 1381 ref_temp[k + nt - 1] = pu1_ref[two_nt - k]; 1382 1383 ref_main = ref_temp + nt - 1; 1384 ref_idx = (nt * intra_pred_ang) >> 5; 1385 1386 /* SIMD Optimization can be done using look-up table for the loop */ 1387 /* For negative angled derive the main reference samples from side */ 1388 /* reference samples refer to section 8.4.4.2.6 */ 1389 for(k = -1; k > ref_idx; k--) 1390 { 1391 inv_ang_sum += inv_ang; 1392 ref_main[k] = pu1_ref[two_nt + (inv_ang_sum >> 8)]; 1393 } 1394 1395 /* For the angles other then 45 degree, interpolation btw 2 neighboring */ 1396 /* samples dependent on distance to obtain destination sample */ 1397 for(col = 0; col < nt; col++) 1398 { 1399 pos = ((col + 1) * intra_pred_ang); 1400 idx = pos >> 5; 1401 fract = pos & (31); 1402 1403 // Do linear filtering 1404 for(row = 0; row < nt; row++) 1405 { 1406 ref_main_idx = row + idx + 1; 1407 pu1_dst[col + (dst_strd * row)] = (UWORD8)(((32 - fract) 1408 * ref_main[ref_main_idx] 1409 + fract * ref_main[ref_main_idx + 1] + 16) >> 5); 1410 1411 } 1412 1413 } 1414 1415 } 1416 1417 1418 1419 /** 1420 ******************************************************************************* 1421 * 1422 * @brief 1423 * Intra prediction interpolation filter for luma mode 19 to mode 25 1424 * 1425 * @par Description: 1426 * Intraprediction for mode 19 to 25 (negative angle, vertical mode ) with 1427 * reference neighboring samples location pointed by 'pu1_ref' to the TU 1428 * block location pointed by 'pu1_dst' 1429 * 1430 * @param[in] pu1_src 1431 * UWORD8 pointer to the source 1432 * 1433 * @param[out] pu1_dst 1434 * UWORD8 pointer to the destination 1435 * 1436 * @param[in] src_strd 1437 * integer source stride 1438 * 1439 * @param[in] dst_strd 1440 * integer destination stride 1441 * 1442 * @param[in] nt 1443 * integer Transform Block size 1444 * 1445 * @param[in] mode 1446 * integer intraprediction mode 1447 * 1448 * @returns 1449 * 1450 * @remarks 1451 * None 1452 * 1453 ******************************************************************************* 1454 */ 1455 1456 1457 void ihevc_intra_pred_luma_mode_19_to_25(UWORD8 *pu1_ref, 1458 WORD32 src_strd, 1459 UWORD8 *pu1_dst, 1460 WORD32 dst_strd, 1461 WORD32 nt, 1462 WORD32 mode) 1463 { 1464 1465 WORD32 row, col, k; 1466 WORD32 two_nt, intra_pred_ang, idx; 1467 WORD32 inv_ang, inv_ang_sum, pos, fract; 1468 WORD32 ref_main_idx, ref_idx; 1469 UWORD8 ref_temp[(2 * MAX_CU_SIZE) + 1]; 1470 UWORD8 *ref_main; 1471 UNUSED(src_strd); 1472 two_nt = 2 * nt; 1473 intra_pred_ang = gai4_ihevc_ang_table[mode]; 1474 inv_ang = gai4_ihevc_inv_ang_table[mode - 12]; 1475 1476 /* Intermediate reference samples for negative angle modes */ 1477 /* This have to be removed during optimization*/ 1478 /* For horizontal modes, (ref main = ref above) (ref side = ref left) */ 1479 ref_main = ref_temp + nt - 1; 1480 for(k = 0; k < (nt + 1); k++) 1481 ref_temp[k + nt - 1] = pu1_ref[two_nt + k]; 1482 1483 ref_idx = (nt * intra_pred_ang) >> 5; 1484 inv_ang_sum = 128; 1485 1486 /* SIMD Optimization can be done using look-up table for the loop */ 1487 /* For negative angled derive the main reference samples from side */ 1488 /* reference samples refer to section 8.4.4.2.6 */ 1489 for(k = -1; k > ref_idx; k--) 1490 { 1491 inv_ang_sum += inv_ang; 1492 ref_main[k] = pu1_ref[two_nt - (inv_ang_sum >> 8)]; 1493 } 1494 1495 for(row = 0; row < nt; row++) 1496 { 1497 pos = ((row + 1) * intra_pred_ang); 1498 idx = pos >> 5; 1499 fract = pos & (31); 1500 1501 // Do linear filtering 1502 for(col = 0; col < nt; col++) 1503 { 1504 ref_main_idx = col + idx + 1; 1505 pu1_dst[(row * dst_strd) + col] = (UWORD8)(((32 - fract) 1506 * ref_main[ref_main_idx] 1507 + fract * ref_main[ref_main_idx + 1] + 16) >> 5); 1508 1509 } 1510 1511 } 1512 1513 } 1514 1515 1516 1517 /** 1518 ******************************************************************************* 1519 * 1520 * @brief 1521 * Intra prediction interpolation filter for luma mode 27 to mode 33 1522 * 1523 * @par Description: 1524 * Intraprediction for mode 27 to 33 (positive angle, vertical mode ) with 1525 * reference neighboring samples location pointed by 'pu1_ref' to the TU 1526 * block location pointed by 'pu1_dst' 1527 * 1528 * @param[in] pu1_src 1529 * UWORD8 pointer to the source 1530 * 1531 * @param[out] pu1_dst 1532 * UWORD8 pointer to the destination 1533 * 1534 * @param[in] src_strd 1535 * integer source stride 1536 * 1537 * @param[in] dst_strd 1538 * integer destination stride 1539 * 1540 * @param[in] nt 1541 * integer Transform Block size 1542 * 1543 * @param[in] mode 1544 * integer intraprediction mode 1545 * 1546 * @returns 1547 * 1548 * @remarks 1549 * None 1550 * 1551 ******************************************************************************* 1552 */ 1553 1554 1555 void ihevc_intra_pred_luma_mode_27_to_33(UWORD8 *pu1_ref, 1556 WORD32 src_strd, 1557 UWORD8 *pu1_dst, 1558 WORD32 dst_strd, 1559 WORD32 nt, 1560 WORD32 mode) 1561 { 1562 WORD32 row, col; 1563 WORD32 two_nt, pos, fract; 1564 WORD32 intra_pred_ang; 1565 WORD32 idx, ref_main_idx; 1566 UNUSED(src_strd); 1567 two_nt = 2 * nt; 1568 intra_pred_ang = gai4_ihevc_ang_table[mode]; 1569 1570 for(row = 0; row < nt; row++) 1571 { 1572 pos = ((row + 1) * intra_pred_ang); 1573 idx = pos >> 5; 1574 fract = pos & (31); 1575 1576 // Do linear filtering 1577 for(col = 0; col < nt; col++) 1578 { 1579 ref_main_idx = two_nt + col + idx + 1; 1580 pu1_dst[col + (row * dst_strd)] = (((32 - fract) 1581 * pu1_ref[ref_main_idx] 1582 + fract * pu1_ref[ref_main_idx + 1] + 16) >> 5); 1583 } 1584 1585 } 1586 1587 } 1588 1589