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*/ 127void 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 201void 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 654void 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 771void 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 857void 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 973void 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 1053void 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 1131void 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 1195void 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 1272void 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 1349void 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 1457void 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 1555void 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