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_chroma_intra_pred_filters.c 22* 23* @brief 24* Contains function Definition for intra prediction interpolation filters 25* 26* 27* @author 28* Ittiam 29* 30* @par List of Functions: 31* ihevc_intra_pred_chroma_planar() 32* 33* ihevc_intra_pred_chroma_dc() 34* 35* ihevc_intra_pred_chroma_horz() 36* 37* ihevc_intra_pred_chroma_ver() 38* 39* ihevc_intra_pred_chroma_mode2() 40* 41* ihevc_intra_pred_chroma_mode_18_34() 42* 43* ihevc_intra_pred_chroma_mode_3_to_9() 44* 45* ihevc_intra_pred_chroma_mode_11_to_17() 46* 47* ihevc_intra_pred_chroma_mode_19_to_25() 48* 49* ihevc_intra_pred_chroma_mode_27_to_33() 50* 51* ihevc_intra_pred_chroma_ref_substitution() 52* 53* 54* @remarks 55* None 56* 57******************************************************************************* 58*/ 59 60 61/*****************************************************************************/ 62/* File Includes */ 63/*****************************************************************************/ 64 65#include "ihevc_typedefs.h" 66#include "ihevc_macros.h" 67#include "ihevc_func_selector.h" 68#include "ihevc_platform_macros.h" 69#include "ihevc_intra_pred.h" 70#include "ihevc_mem_fns.h" 71#include "ihevc_chroma_intra_pred.h" 72#include "ihevc_common_tables.h" 73 74 75/****************************************************************************/ 76/* Constant Macros */ 77/****************************************************************************/ 78#define MAX_CU_SIZE 64 79#define BIT_DEPTH 8 80#define T32_4NT 128 81#define T16_4NT 64 82#define T16C_4NT 64 83#define T8C_4NT 32 84/****************************************************************************/ 85/* Function Macros */ 86/****************************************************************************/ 87 88#define GET_BIT(y,x) ((y) & (1 << x)) && (1 << x) 89 90 91/*****************************************************************************/ 92/* Function Definition */ 93/*****************************************************************************/ 94 95/** 96******************************************************************************* 97* 98* @brief 99* Reference substitution process for samples unavailable for prediction 100* Refer to section 8.4.4.2.2 101* 102* @par Description: 103* 104* 105* @param[in] pu1_top_left 106* UWORD8 pointer to the top-left 107* 108* @param[in] pu1_top 109* UWORD8 pointer to the top 110* 111* @param[in] pu1_left 112* UWORD8 pointer to the left 113* 114* @param[in] src_strd 115* WORD32 Source stride 116* 117* @param[in] nbr_flags 118* WORD32 neighbor availability flags 119* 120* @param[in] nt 121* WORD32 transform Block size 122* 123* @param[in] dst_strd 124* WORD32 Destination stride 125* 126* @returns 127* 128* @remarks 129* None 130* 131******************************************************************************* 132*/ 133 134 135void ihevc_intra_pred_chroma_ref_substitution(UWORD8 *pu1_top_left, 136 UWORD8 *pu1_top, 137 UWORD8 *pu1_left, 138 WORD32 src_strd, 139 WORD32 nt, 140 WORD32 nbr_flags, 141 UWORD8 *pu1_dst, 142 WORD32 dst_strd) 143{ 144 UWORD8 pu1_ref_u, pu1_ref_v; 145 WORD32 dc_val, i, j; 146 WORD32 total_samples = (4 * nt) + 1; 147 WORD32 get_bits; 148 WORD32 next; 149 WORD32 bot_left, left, top, tp_right, tp_left; 150 WORD32 idx, nbr_id_from_bl, frwd_nbr_flag; 151 WORD32 a_nbr_flag[5]; 152 UNUSED(dst_strd); 153 /* Neighbor Flag Structure*/ 154 /* WORD32 nbr_flags MSB-->LSB TOP LEFT | TOP-RIGHT | TOP | LEFT | BOTTOM LEFT*/ 155 /* (1 bit) (4 bits) (4 bits) (4 bits) (4 bits) */ 156 157 if(nbr_flags == 0) 158 { 159/* If no neighbor flags are present, fill the neighbor samples with DC value */ 160 /*dc_val = 1 << (BIT_DEPTH - 1);*/ 161 dc_val = 1 << (8 - 1); 162 for(i = 0; i < (2 * total_samples); i++) 163 { 164 pu1_dst[i] = dc_val; 165 } 166 } 167 else 168 { 169 /* Else fill the corresponding samples */ 170 171 /* Check for the neighbors availibility */ 172 tp_left = (nbr_flags & 0x10000); 173 tp_right = (nbr_flags & 0x0f000); 174 top = (nbr_flags & 0x00f00); 175 left = (nbr_flags & 0x000f0); 176 bot_left = (nbr_flags & 0x0000f); 177 178 /* Fill nbrs depending on avalibility */ 179 /* Top -Left nbrs */ 180 if(0 != tp_left) 181 { 182 pu1_dst[(4 * nt)] = *pu1_top_left; // U top-left sample 183 pu1_dst[(4 * nt) + 1] = *(pu1_top_left + 1); // V top-left sample 184 } 185 /* Left nbrs */ 186 if(0 != left) 187 { 188 for(i = 0, j = 0; i < (2 * nt); i += 2) 189 { 190 pu1_dst[(4 * nt) - 2 - i] = pu1_left[j * src_strd]; // U left samples 191 pu1_dst[(4 * nt) - 1 - i] = pu1_left[(j * src_strd) + 1]; // V left samples 192 j++; 193 } 194 } 195 /* Bottom - Left nbrs */ 196 if(0 != bot_left) 197 { 198 for(i = (2 * nt), j = nt; i < (4 * nt); i += 2) 199 { 200 pu1_dst[(4 * nt) - 2 - i] = pu1_left[j * src_strd]; // U left samples 201 pu1_dst[(4 * nt) - 1 - i] = pu1_left[(j * src_strd) + 1]; // V left samples 202 j++; 203 } 204 } 205 /* Top nbrs */ 206 if(0 != top) 207 { 208 ihevc_memcpy_mul_8(&pu1_dst[(4 * nt) + 2], pu1_top, 2 * nt); 209 // U-V interleaved Top-top right samples 210 } 211 212 /* Top - Right nbrs */ 213 if(0 != tp_right) 214 { 215 ihevc_memcpy_mul_8(&pu1_dst[(4 * nt) + 2 + 2 * nt], pu1_top + 2 * nt, 2 * nt); 216 // U-V interleaved Top-top right samples 217 } 218 219 if(nt == 4) 220 { 221 /* 1 bit extraction for all the neighboring blocks */ 222 tp_left = (nbr_flags & 0x10000) >> 16; 223 bot_left = (nbr_flags & 0x8) >> 3; 224 left = (nbr_flags & 0x80) >> 7; 225 top = (nbr_flags & 0x100) >> 8; 226 tp_right = (nbr_flags & 0x1000) >> 12; 227 228 next = 1; 229 a_nbr_flag[0] = bot_left; 230 a_nbr_flag[1] = left; 231 a_nbr_flag[2] = tp_left; 232 a_nbr_flag[3] = top; 233 a_nbr_flag[4] = tp_right; 234 235 /* If bottom -left is not available, reverse substitution process*/ 236 if(bot_left == 0) 237 { 238 /* Check for the 1st available sample from bottom-left*/ 239 while(!a_nbr_flag[next]) 240 next++; 241 242 /* If Left, top-left are available*/ 243 if(next <= 2) 244 { 245 UWORD16 *pu2_dst; 246 idx = (nt * next); 247 pu2_dst = (UWORD16 *)&pu1_dst[2 * idx]; 248 ihevc_memset_16bit((UWORD16 *)pu1_dst, pu2_dst[0], idx); 249 } 250 else /* If top, top-right are available */ 251 { 252 UWORD16 *pu2_dst; 253 /* Idx is changed to copy 1 pixel value for top-left ,if top-left is not available*/ 254 idx = (nt * (next - 1)) + 1; 255 pu2_dst = (UWORD16 *)&pu1_dst[2 * idx]; 256 ihevc_memset_16bit((UWORD16 *)pu1_dst, pu2_dst[0], idx); 257 } 258 } 259 260 if(left == 0) 261 { 262 UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(2 * nt) - 2]; 263 ihevc_memset_16bit((UWORD16 *)&pu1_dst[(2 * nt)], pu2_dst[0], nt); 264 265 266 } 267 if(tp_left == 0) 268 { 269 pu1_dst[4 * nt] = pu1_dst[(4 * nt) - 2]; 270 pu1_dst[(4 * nt) + 1] = pu1_dst[(4 * nt) - 1]; 271 } 272 if(top == 0) 273 { 274 UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(4 * nt)]; 275 ihevc_memset_16bit((UWORD16 *)&pu1_dst[(4 * nt) + 2], pu2_dst[0], nt); 276 277 278 } 279 if(tp_right == 0) 280 { 281 UWORD16 *pu2_dst = (UWORD16 *)&pu1_dst[(6 * nt)]; 282 ihevc_memset_16bit((UWORD16 *)&pu1_dst[(6 * nt) + 2], pu2_dst[0], nt); 283 284 285 } 286 } 287 else if(nt == 8) 288 { 289 WORD32 nbr_flags_temp = 0; 290 nbr_flags_temp = ((nbr_flags & 0xC) >> 2) + ((nbr_flags & 0xC0) >> 4) 291 + ((nbr_flags & 0x300) >> 4) 292 + ((nbr_flags & 0x3000) >> 6) 293 + ((nbr_flags & 0x10000) >> 8); 294 295 /* compute trailing zeors based on nbr_flag for substitution process of below left see section .*/ 296 /* as each bit in nbr flags corresponds to 8 pels for bot_left, left, top and topright but 1 pel for topleft */ 297 { 298 nbr_id_from_bl = look_up_trailing_zeros(nbr_flags_temp & 0XF) * 4; /* for bottom left and left */ 299 if(nbr_id_from_bl == 32) 300 nbr_id_from_bl = 16; 301 if(nbr_id_from_bl == 16) 302 { 303 /* for top left : 1 pel per nbr bit */ 304 if(!((nbr_flags_temp >> 8) & 0x1)) 305 { 306 nbr_id_from_bl++; 307 nbr_id_from_bl += look_up_trailing_zeros((nbr_flags_temp >> 4) & 0xF) * 4; /* top and top right; 8 pels per nbr bit */ 308 309 } 310 } 311 /* Reverse Substitution Process*/ 312 if(nbr_id_from_bl) 313 { 314 /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */ 315 pu1_ref_u = pu1_dst[2 * nbr_id_from_bl]; 316 pu1_ref_v = pu1_dst[(2 * nbr_id_from_bl) + 1]; 317 for(i = 2 * (nbr_id_from_bl - 1); i >= 0; i -= 2) 318 { 319 pu1_dst[i] = pu1_ref_u; 320 pu1_dst[i + 1] = pu1_ref_v; 321 } 322 } 323 } 324 325 /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */ 326 while(nbr_id_from_bl < ((T8C_4NT)+1)) 327 { 328 /* To Obtain the next unavailable idx flag after reverse neighbor substitution */ 329 /* Divide by 8 to obtain the original index */ 330 frwd_nbr_flag = (nbr_id_from_bl >> 2); /*+ (nbr_id_from_bl & 0x1);*/ 331 332 /* The Top-left flag is at the last bit location of nbr_flags*/ 333 if(nbr_id_from_bl == (T8C_4NT / 2)) 334 { 335 get_bits = GET_BIT(nbr_flags_temp, 8); 336 337 /* only pel substitution for TL */ 338 if(!get_bits) 339 { 340 pu1_dst[2 * nbr_id_from_bl] = pu1_dst[(2 * nbr_id_from_bl) - 2]; 341 pu1_dst[(2 * nbr_id_from_bl) + 1] = pu1_dst[(2 * nbr_id_from_bl) - 1]; 342 } 343 } 344 else 345 { 346 get_bits = GET_BIT(nbr_flags_temp, frwd_nbr_flag); 347 if(!get_bits) 348 { 349 UWORD16 *pu2_dst; 350 /* 8 pel substitution (other than TL) */ 351 pu2_dst = (UWORD16 *)&pu1_dst[(2 * nbr_id_from_bl) - 2]; 352 ihevc_memset_16bit((UWORD16 *)(pu1_dst + (2 * nbr_id_from_bl)), pu2_dst[0], 4); 353 } 354 355 } 356 nbr_id_from_bl += (nbr_id_from_bl == (T8C_4NT / 2)) ? 1 : 4; 357 } 358 359 } 360 else if(nt == 16) 361 { 362 /* compute trailing ones based on mbr_flag for substitution process of below left see section .*/ 363 /* as each bit in nbr flags corresponds to 4 pels for bot_left, left, top and topright but 1 pel for topleft */ 364 { 365 nbr_id_from_bl = look_up_trailing_zeros((nbr_flags & 0XFF)) * 4; /* for bottom left and left */ 366 367 if(nbr_id_from_bl == 32) 368 { 369 /* for top left : 1 pel per nbr bit */ 370 if(!((nbr_flags >> 16) & 0x1)) 371 { 372 /* top left not available */ 373 nbr_id_from_bl++; 374 /* top and top right; 4 pels per nbr bit */ 375 nbr_id_from_bl += look_up_trailing_zeros((nbr_flags >> 8) & 0xFF) * 4; 376 } 377 } 378 /* Reverse Substitution Process*/ 379 if(nbr_id_from_bl) 380 { 381 /* Replicate the bottom-left and subsequent unavailable pixels with the 1st available pixel above */ 382 pu1_ref_u = pu1_dst[2 * nbr_id_from_bl]; 383 pu1_ref_v = pu1_dst[2 * nbr_id_from_bl + 1]; 384 for(i = (2 * (nbr_id_from_bl - 1)); i >= 0; i -= 2) 385 { 386 pu1_dst[i] = pu1_ref_u; 387 pu1_dst[i + 1] = pu1_ref_v; 388 } 389 } 390 } 391 392 /* for the loop of 4*Nt+1 pixels (excluding pixels computed from reverse substitution) */ 393 while(nbr_id_from_bl < ((T16C_4NT)+1)) 394 { 395 /* To Obtain the next unavailable idx flag after reverse neighbor substitution */ 396 /* Devide by 4 to obtain the original index */ 397 frwd_nbr_flag = (nbr_id_from_bl >> 2); /*+ (nbr_id_from_bl & 0x1);*/ 398 399 /* The Top-left flag is at the last bit location of nbr_flags*/ 400 if(nbr_id_from_bl == (T16C_4NT / 2)) 401 { 402 get_bits = GET_BIT(nbr_flags, 16); 403 /* only pel substitution for TL */ 404 if(!get_bits) 405 { 406 pu1_dst[2 * nbr_id_from_bl] = pu1_dst[(2 * nbr_id_from_bl) - 2]; 407 pu1_dst[(2 * nbr_id_from_bl) + 1] = pu1_dst[(2 * nbr_id_from_bl) - 1]; 408 } 409 } 410 else 411 { 412 get_bits = GET_BIT(nbr_flags, frwd_nbr_flag); 413 if(!get_bits) 414 { 415 UWORD16 *pu2_dst; 416 /* 4 pel substitution (other than TL) */ 417 pu2_dst = (UWORD16 *)&pu1_dst[(2 * nbr_id_from_bl) - 2]; 418 ihevc_memset_16bit((UWORD16 *)(pu1_dst + (2 * nbr_id_from_bl)), pu2_dst[0], 4); 419 } 420 421 } 422 nbr_id_from_bl += (nbr_id_from_bl == (T16C_4NT / 2)) ? 1 : 4; 423 } 424 } 425 } 426} 427 428 429/** 430******************************************************************************* 431* 432* @brief 433* Planar Intraprediction with reference neighboring samples location 434* pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 435* to section 8.4.4.2.4 in the standard 436* 437* @par Description: 438* 439* 440* @param[in] pu1_src 441* UWORD8 pointer to the source 442* 443* @param[in] pu1_dst 444* UWORD8 pointer to the destination 445* 446* @param[in] src_strd 447* integer source stride 448* 449* @param[in] dst_strd 450* integer destination stride 451* 452* @param[in] nt 453* integer Transform Block size 454* 455* @param[in] mode 456* integer intraprediction mode 457* 458* @returns 459* 460* @remarks 461* None 462* 463******************************************************************************* 464*/ 465 466 467void ihevc_intra_pred_chroma_planar(UWORD8 *pu1_ref, 468 WORD32 src_strd, 469 UWORD8 *pu1_dst, 470 WORD32 dst_strd, 471 WORD32 nt, 472 WORD32 mode) 473{ 474 475 WORD32 row, col; 476 WORD32 log2nt = 5; 477 WORD32 two_nt, three_nt; 478 UNUSED(src_strd); 479 UNUSED(mode); 480 switch(nt) 481 { 482 case 16: 483 log2nt = 4; 484 break; 485 case 8: 486 log2nt = 3; 487 break; 488 case 4: 489 log2nt = 2; 490 break; 491 default: 492 break; 493 } 494 two_nt = 2 * nt; 495 three_nt = 3 * nt; 496 /* Planar filtering */ 497 for(row = 0; row < nt; row++) 498 { 499 for(col = 0; col < (2 * nt); col += 2) 500 { 501 pu1_dst[row * dst_strd + col] = ((nt - 1 - col / 2) 502 * pu1_ref[2 * (two_nt - 1 - row)] 503 + (col / 2 + 1) * pu1_ref[2 * (three_nt + 1)] 504 + (nt - 1 - row) * pu1_ref[2 * (two_nt + 1) + col] 505 + (row + 1) * pu1_ref[2 * (nt - 1)] + nt) >> (log2nt + 1); 506 507 pu1_dst[row * dst_strd + col + 1] = ((nt - 1 - col / 2) 508 * pu1_ref[2 * (two_nt - 1 - row) + 1] 509 + (col / 2 + 1) * pu1_ref[2 * (three_nt + 1) + 1] 510 + (nt - 1 - row) * pu1_ref[2 * (two_nt + 1) + col + 1] 511 + (row + 1) * pu1_ref[2 * (nt - 1) + 1] + nt) >> (log2nt + 1); 512 } 513 } 514} 515 516 517/** 518******************************************************************************* 519* 520* @brief 521* Intraprediction for DC mode with reference neighboring samples location 522* pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 523* to section 8.4.4.2.5 in the standard 524* 525* @par Description: 526* 527* 528* @param[in] pu1_src 529* UWORD8 pointer to the source 530* 531* @param[in] pu1_dst 532* UWORD8 pointer to the destination 533* 534* @param[in] src_strd 535* integer source stride 536* 537* @param[in] dst_strd 538* integer destination stride 539* 540* @param[in] nt 541* integer Transform Block size (Chroma) 542* 543* @param[in] mode 544* integer intraprediction mode 545* 546* @returns 547* 548* @remarks 549* None 550* 551******************************************************************************* 552*/ 553 554 555void ihevc_intra_pred_chroma_dc(UWORD8 *pu1_ref, 556 WORD32 src_strd, 557 UWORD8 *pu1_dst, 558 WORD32 dst_strd, 559 WORD32 nt, 560 WORD32 mode) 561{ 562 563 WORD32 acc_dc_u, acc_dc_v; 564 WORD32 dc_val_u, dc_val_v; 565 WORD32 i; 566 WORD32 row, col; 567 WORD32 log2nt = 5; 568 UNUSED(mode); 569 UNUSED(src_strd); 570 switch(nt) 571 { 572 case 32: 573 log2nt = 5; 574 break; 575 case 16: 576 log2nt = 4; 577 break; 578 case 8: 579 log2nt = 3; 580 break; 581 case 4: 582 log2nt = 2; 583 break; 584 default: 585 break; 586 } 587 588 589 acc_dc_u = 0; 590 acc_dc_v = 0; 591 /* Calculate DC value for the transform block */ 592 for(i = (2 * nt); i < (4 * nt); i += 2) 593 { 594 acc_dc_u += pu1_ref[i]; 595 acc_dc_v += pu1_ref[i + 1]; 596 } 597 for(i = ((4 * nt) + 2); i < ((6 * nt) + 2); i += 2) 598 { 599 acc_dc_u += pu1_ref[i]; 600 acc_dc_v += pu1_ref[i + 1]; 601 } 602 603 604 dc_val_u = (acc_dc_u + nt) >> (log2nt + 1); 605 dc_val_v = (acc_dc_v + nt) >> (log2nt + 1); 606 607 608 /* Fill the remaining rows with DC value*/ 609 for(row = 0; row < nt; row++) 610 { 611 for(col = 0; col < (2 * nt); col += 2) 612 { 613 pu1_dst[(row * dst_strd) + col] = dc_val_u; 614 pu1_dst[(row * dst_strd) + col + 1] = dc_val_v; 615 } 616 } 617 618} 619 620 621/** 622******************************************************************************* 623* 624* @brief 625* Horizontal intraprediction(mode 10) with reference samples location 626* pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 627* to section 8.4.4.2.6 in the standard (Special case) 628* 629* @par Description: 630* 631* 632* @param[in] pu1_src 633* UWORD8 pointer to the source 634* 635* @param[in] pu1_dst 636* UWORD8 pointer to the destination 637* 638* @param[in] src_strd 639* integer source stride 640* 641* @param[in] dst_strd 642* integer destination stride 643* 644* @param[in] nt 645* integer Transform Block size 646* 647* @param[in] mode 648* integer intraprediction mode 649* 650* @returns 651* 652* @remarks 653* None 654* 655******************************************************************************* 656*/ 657 658 659void ihevc_intra_pred_chroma_horz(UWORD8 *pu1_ref, 660 WORD32 src_strd, 661 UWORD8 *pu1_dst, 662 WORD32 dst_strd, 663 WORD32 nt, 664 WORD32 mode) 665{ 666 667 WORD32 row, col; 668 UNUSED(mode); 669 UNUSED(src_strd); 670 /* Replication to next rows*/ 671 for(row = 0; row < nt; row++) 672 { 673 for(col = 0; col < (2 * nt); col += 2) 674 { 675 pu1_dst[(row * dst_strd) + col] = pu1_ref[(4 * nt) - 2 - 2 * row]; 676 pu1_dst[(row * dst_strd) + col + 1] = pu1_ref[(4 * nt) - 1 - 2 * row]; 677 } 678 } 679} 680 681 682 683/** 684******************************************************************************* 685* 686* @brief 687* Horizontal intraprediction with reference neighboring samples location 688* pointed by 'pu1_ref' to the TU block location pointed by 'pu1_dst' Refer 689* to section 8.4.4.2.6 in the standard (Special case) 690* 691* @par Description: 692* 693* 694* @param[in] pu1_src 695* UWORD8 pointer to the source 696* 697* @param[in] pu1_dst 698* UWORD8 pointer to the destination 699* 700* @param[in] src_strd 701* integer source stride 702* 703* @param[in] dst_strd 704* integer destination stride 705* 706* @param[in] nt 707* integer Transform Block size 708* 709* @param[in] mode 710* integer intraprediction mode 711* 712* @returns 713* 714* @remarks 715* None 716* 717******************************************************************************* 718*/ 719 720 721void ihevc_intra_pred_chroma_ver(UWORD8 *pu1_ref, 722 WORD32 src_strd, 723 UWORD8 *pu1_dst, 724 WORD32 dst_strd, 725 WORD32 nt, 726 WORD32 mode) 727{ 728 WORD32 row, col; 729 UNUSED(mode); 730 UNUSED(src_strd); 731 /* Replication to next columns*/ 732 for(row = 0; row < nt; row++) 733 { 734 for(col = 0; col < (2 * nt); col += 2) 735 { 736 pu1_dst[(row * dst_strd) + col] = pu1_ref[(4 * nt) + 2 + col]; 737 pu1_dst[(row * dst_strd) + col + 1] = pu1_ref[(4 * nt) + 3 + col]; 738 } 739 } 740} 741 742 743/** 744******************************************************************************* 745* 746* @brief 747* Intraprediction for mode 2 (sw angle) with reference neighboring samples 748* location pointed by 'pu1_ref' to the TU block location pointed by 749* 'pu1_dst' Refer to section 8.4.4.2.6 in the standard 750* 751* @par Description: 752* 753* 754* @param[in] pu1_src 755* UWORD8 pointer to the source 756* 757* @param[in] pu1_dst 758* UWORD8 pointer to the destination 759* 760* @param[in] src_strd 761* integer source stride 762* 763* @param[in] dst_strd 764* integer destination stride 765* 766* @param[in] nt 767* integer Transform Block size 768* 769* @param[in] mode 770* integer intraprediction mode 771* 772* @returns 773* 774* @remarks 775* None 776* 777******************************************************************************* 778*/ 779 780 781void ihevc_intra_pred_chroma_mode2(UWORD8 *pu1_ref, 782 WORD32 src_strd, 783 UWORD8 *pu1_dst, 784 WORD32 dst_strd, 785 WORD32 nt, 786 WORD32 mode) 787{ 788 WORD32 row, col; 789 790 WORD32 intra_pred_ang = 32; 791 WORD32 idx_u, idx_v; 792 UNUSED(src_strd); 793 UNUSED(mode); 794 /* For the angle 45, replication is done from the corresponding angle */ 795 /* intra_pred_ang = tan(angle) in q5 format */ 796 for(col = 0; col < (2 * nt); col += 2) 797 { 798 idx_u = ((col + 1) * intra_pred_ang) >> 5; /* Use idx++ */ 799 idx_v = (((col + 1) + 1) * intra_pred_ang) >> 5; /* Use idx++ */ 800 for(row = 0; row < nt; row++) 801 { 802 pu1_dst[col + (row * dst_strd)] = pu1_ref[(4 * nt) - 2 * row - idx_u - 3]; 803 pu1_dst[(col + 1) + (row * dst_strd)] = pu1_ref[(4 * nt) - 2 * row - idx_v - 1]; 804 } 805 } 806 807} 808 809 810/** 811******************************************************************************* 812* 813* @brief 814* Intraprediction for mode 34 (ne angle) and mode 18 (nw angle) with 815* reference neighboring samples location pointed by 'pu1_ref' to the TU 816* block location pointed by 'pu1_dst' 817* 818* @par Description: 819* 820* 821* @param[in] pu1_src 822* UWORD8 pointer to the source 823* 824* @param[in] pu1_dst 825* UWORD8 pointer to the destination 826* 827* @param[in] src_strd 828* integer source stride 829* 830* @param[in] dst_strd 831* integer destination stride 832* 833* @param[in] nt 834* integer Transform Block size 835* 836* @param[in] mode 837* integer intraprediction mode 838* 839* @returns 840* 841* @remarks 842* None 843* 844******************************************************************************* 845*/ 846 847 848void ihevc_intra_pred_chroma_mode_18_34(UWORD8 *pu1_ref, 849 WORD32 src_strd, 850 UWORD8 *pu1_dst, 851 WORD32 dst_strd, 852 WORD32 nt, 853 WORD32 mode) 854{ 855 WORD32 row, col; 856 WORD32 intra_pred_ang; 857 WORD32 idx = 0; 858 UNUSED(src_strd); 859 intra_pred_ang = 32; /*Default value*/ 860 /* For mode 18, angle is -45degree */ 861 if(mode == 18) 862 intra_pred_ang = -32; 863 /* For mode 34, angle is 45degree */ 864 else if(mode == 34) 865 intra_pred_ang = 32; 866 /* For the angle 45 and -45, replication is done from the corresponding angle */ 867 /* No interpolation is done for 45 degree*/ 868 for(row = 0; row < nt; row++) 869 { 870 idx = ((row + 1) * intra_pred_ang) >> 5; 871 872 for(col = 0; col < (2 * nt); col += 2) 873 { 874 pu1_dst[col + (row * dst_strd)] = pu1_ref[(4 * nt) + col + 2 * idx + 2]; 875 pu1_dst[(col + 1) + (row * dst_strd)] = pu1_ref[(4 * nt) + (col + 1) + 2 * idx + 2]; 876 } 877 878 } 879 880} 881 882 883/** 884******************************************************************************* 885* 886* @brief 887* Intraprediction for mode 3 to 9 (positive angle, horizontal mode ) with 888* reference neighboring samples location pointed by 'pu1_ref' to the TU 889* block location pointed by 'pu1_dst' 890* 891* @par Description: 892* 893* 894* @param[in] pu1_src 895* UWORD8 pointer to the source 896* 897* @param[in] pu1_dst 898* UWORD8 pointer to the destination 899* 900* @param[in] src_strd 901* integer source stride 902* 903* @param[in] dst_strd 904* integer destination stride 905* 906* @param[in] nt 907* integer Transform Block size 908* 909* @param[in] mode 910* integer intraprediction mode 911* 912* @returns 913* 914* @remarks 915* None 916* 917******************************************************************************* 918*/ 919 920 921void ihevc_intra_pred_chroma_mode_3_to_9(UWORD8 *pu1_ref, 922 WORD32 src_strd, 923 UWORD8 *pu1_dst, 924 WORD32 dst_strd, 925 WORD32 nt, 926 WORD32 mode) 927{ 928 WORD32 row, col; 929 930 WORD32 intra_pred_ang; 931 WORD32 idx_u, ref_main_idx_u; 932 WORD32 idx_v, ref_main_idx_v; 933 WORD32 pos_u, fract_u; 934 WORD32 pos_v, fract_v; 935 UNUSED(src_strd); 936 /* Intra Pred Angle according to the mode */ 937 intra_pred_ang = gai4_ihevc_ang_table[mode]; 938 939 /* For the angles other then 45 degree, interpolation btw 2 neighboring */ 940 /* samples dependent on distance to obtain destination sample */ 941 942 for(col = 0; col < (2 * nt); col += 2) 943 { 944 pos_u = ((col / 2 + 1) * intra_pred_ang); 945 pos_v = ((col / 2 + 1) * intra_pred_ang); 946 947 idx_u = pos_u >> 5; 948 fract_u = pos_u & (31); 949 950 idx_v = pos_v >> 5; 951 fract_v = pos_v & (31); 952 // Do linear filtering 953 for(row = 0; row < nt; row++) 954 { 955 ref_main_idx_u = (4 * nt) - 2 * row - 2 * idx_u - 2; 956 ref_main_idx_v = (4 * nt) - 2 * row - 2 * idx_v - 1; 957 958 pu1_dst[col + (row * dst_strd)] = (((32 - fract_u) 959 * pu1_ref[ref_main_idx_u] 960 + fract_u * pu1_ref[ref_main_idx_u - 2] + 16) >> 5); 961 962 pu1_dst[(col + 1) + (row * dst_strd)] = (((32 - fract_v) 963 * pu1_ref[ref_main_idx_v] 964 + fract_v * pu1_ref[ref_main_idx_v - 2] + 16) >> 5); 965 } 966 967 } 968 969} 970 971 972/** 973******************************************************************************* 974* 975* @brief 976* Intraprediction for mode 11 to 17 (negative angle, horizontal mode ) 977* with reference neighboring samples location pointed by 'pu1_ref' to the 978* TU block location pointed by 'pu1_dst' 979* 980* @par Description: 981* 982* 983* @param[in] pu1_src 984* UWORD8 pointer to the source 985* 986* @param[in] pu1_dst 987* UWORD8 pointer to the destination 988* 989* @param[in] src_strd 990* integer source stride 991* 992* @param[in] dst_strd 993* integer destination stride 994* 995* @param[in] nt 996* integer Transform Block size 997* 998* @param[in] mode 999* integer intraprediction mode 1000* 1001* @returns 1002* 1003* @remarks 1004* None 1005* 1006******************************************************************************* 1007*/ 1008 1009 1010void ihevc_intra_pred_chroma_mode_11_to_17(UWORD8 *pu1_ref, 1011 WORD32 src_strd, 1012 UWORD8 *pu1_dst, 1013 WORD32 dst_strd, 1014 WORD32 nt, 1015 WORD32 mode) 1016{ 1017 /* This function and ihevc_intra_pred_CHROMA_mode_19_to_25 are same except*/ 1018 /* for ref main & side samples assignment,can be combined for */ 1019 /* optimzation*/ 1020 1021 WORD32 row, col, k; 1022 WORD32 intra_pred_ang, inv_ang, inv_ang_sum; 1023 WORD32 idx_u, idx_v, ref_main_idx_u, ref_main_idx_v, ref_idx; 1024 WORD32 pos_u, pos_v, fract_u, fract_v; 1025 1026 UWORD8 ref_temp[2 * MAX_CU_SIZE + 2]; 1027 UWORD8 *ref_main; 1028 UNUSED(src_strd); 1029 inv_ang_sum = 128; 1030 1031 intra_pred_ang = gai4_ihevc_ang_table[mode]; 1032 1033 inv_ang = gai4_ihevc_inv_ang_table[mode - 11]; 1034 /* Intermediate reference samples for negative angle modes */ 1035 /* This have to be removed during optimization*/ 1036 1037 /* For horizontal modes, (ref main = ref left) (ref side = ref above) */ 1038 1039 1040 ref_main = ref_temp + 2 * nt; 1041 for(k = 0; k < (2 * (nt + 1)); k += 2) 1042 { 1043 ref_temp[k + (2 * (nt - 1))] = pu1_ref[(4 * nt) - k]; 1044 ref_temp[k + 1 + (2 * (nt - 1))] = pu1_ref[(4 * nt) - k + 1]; 1045 } 1046 1047 ref_main = ref_temp + (2 * (nt - 1)); 1048 ref_idx = (nt * intra_pred_ang) >> 5; 1049 1050 /* SIMD Optimization can be done using look-up table for the loop */ 1051 /* For negative angled derive the main reference samples from side */ 1052 /* reference samples refer to section 8.4.4.2.6 */ 1053 for(k = -2; k > (2 * ref_idx); k -= 2) 1054 { 1055 inv_ang_sum += inv_ang; 1056 ref_main[k] = pu1_ref[(4 * nt) + ((inv_ang_sum >> 8) << 1)]; 1057 ref_main[k + 1] = pu1_ref[((4 * nt) + 1) + ((inv_ang_sum >> 8) << 1)]; 1058 } 1059 1060 /* For the angles other then 45 degree, interpolation btw 2 neighboring */ 1061 /* samples dependent on distance to obtain destination sample */ 1062 for(col = 0; col < (2 * nt); col += 2) 1063 { 1064 pos_u = ((col / 2 + 1) * intra_pred_ang); 1065 pos_v = ((col / 2 + 1) * intra_pred_ang); 1066 idx_u = pos_u >> 5; 1067 idx_v = pos_v >> 5; 1068 fract_u = pos_u & (31); 1069 fract_v = pos_v & (31); 1070 1071 // Do linear filtering 1072 for(row = 0; row < nt; row++) 1073 { 1074 ref_main_idx_u = 2 * (row + idx_u + 1); 1075 ref_main_idx_v = 2 * (row + idx_v + 1) + 1; 1076 1077 pu1_dst[col + (dst_strd * row)] = (UWORD8)(((32 - fract_u) 1078 * ref_main[ref_main_idx_u] 1079 + fract_u * ref_main[ref_main_idx_u + 2] + 16) >> 5); 1080 pu1_dst[(col + 1) + (dst_strd * row)] = (UWORD8)(((32 - fract_v) 1081 * ref_main[ref_main_idx_v] 1082 + fract_v * ref_main[ref_main_idx_v + 2] + 16) >> 5); 1083 1084 } 1085 1086 } 1087 1088} 1089 1090 1091 1092/** 1093******************************************************************************* 1094* 1095* @brief 1096* Intraprediction for mode 19 to 25 (negative angle, vertical mode ) with 1097* reference neighboring samples location pointed by 'pu1_ref' to the TU 1098* block location pointed by 'pu1_dst' 1099* 1100* @par Description: 1101* 1102* 1103* @param[in] pu1_src 1104* UWORD8 pointer to the source 1105* 1106* @param[in] pu1_dst 1107* UWORD8 pointer to the destination 1108* 1109* @param[in] src_strd 1110* integer source stride 1111* 1112* @param[in] dst_strd 1113* integer destination stride 1114* 1115* @param[in] nt 1116* integer Transform Block size 1117* 1118* @param[in] mode 1119* integer intraprediction mode 1120* 1121* @returns 1122* 1123* @remarks 1124* None 1125* 1126******************************************************************************* 1127*/ 1128 1129 1130void ihevc_intra_pred_chroma_mode_19_to_25(UWORD8 *pu1_ref, 1131 WORD32 src_strd, 1132 UWORD8 *pu1_dst, 1133 WORD32 dst_strd, 1134 WORD32 nt, 1135 WORD32 mode) 1136{ 1137 1138 WORD32 row, col, k; 1139 WORD32 intra_pred_ang, idx; 1140 WORD32 inv_ang, inv_ang_sum, pos, fract; 1141 WORD32 ref_main_idx_u, ref_main_idx_v, ref_idx; 1142 UWORD8 ref_temp[(2 * MAX_CU_SIZE) + 2]; 1143 UWORD8 *ref_main; 1144 UNUSED(src_strd); 1145 1146 1147 intra_pred_ang = gai4_ihevc_ang_table_chroma[mode]; 1148 inv_ang = gai4_ihevc_inv_ang_table_chroma[mode - 12]; 1149 1150 /* Intermediate reference samples for negative angle modes */ 1151 /* This have to be removed during optimization*/ 1152 /* For horizontal modes, (ref main = ref above) (ref side = ref left) */ 1153 ref_main = ref_temp + 2 * nt; 1154 for(k = 0; k < (2 * (nt + 1)); k += 2) 1155 { 1156 ref_temp[k + (2 * (nt - 1))] = pu1_ref[(4 * nt) + k]; 1157 ref_temp[k + 1 + (2 * (nt - 1))] = pu1_ref[(4 * nt) + k + 1]; 1158 } 1159 1160 1161 ref_idx = (nt * intra_pred_ang) >> 5; 1162 inv_ang_sum = 128; 1163 ref_main = ref_temp + (2 * (nt - 1)); 1164 /* SIMD Optimization can be done using look-up table for the loop */ 1165 /* For negative angled derive the main reference samples from side */ 1166 /* reference samples refer to section 8.4.4.2.6 */ 1167 for(k = -2; k > (2 * ref_idx); k -= 2) 1168 { 1169 inv_ang_sum += inv_ang; 1170 ref_main[k] = pu1_ref[(4 * nt) - (inv_ang_sum >> 8) * 2]; 1171 ref_main[k + 1] = pu1_ref[((4 * nt) + 1) - (inv_ang_sum >> 8) * 2]; 1172 } 1173 1174 for(row = 0; row < nt; row++) 1175 { 1176 pos = ((row + 1) * intra_pred_ang); 1177 idx = pos >> 5; 1178 fract = pos & (31); 1179 1180 // Do linear filtering 1181 for(col = 0; col < (2 * nt); col += 2) 1182 { 1183 ref_main_idx_u = col + 2 * idx + 2; 1184 ref_main_idx_v = (col + 1) + 2 * idx + 2; 1185 pu1_dst[(row * dst_strd) + col] = (UWORD8)(((32 - fract) 1186 * ref_main[ref_main_idx_u] 1187 + fract * ref_main[ref_main_idx_u + 2] + 16) >> 5); 1188 pu1_dst[(row * dst_strd) + (col + 1)] = (UWORD8)(((32 - fract) 1189 * ref_main[ref_main_idx_v] 1190 + fract * ref_main[ref_main_idx_v + 2] + 16) >> 5); 1191 1192 } 1193 1194 } 1195 1196} 1197 1198 1199 1200/** 1201******************************************************************************* 1202* 1203* @brief 1204* Intraprediction for mode 27 to 33 (positive angle, vertical mode ) with 1205* reference neighboring samples location pointed by 'pu1_ref' to the TU 1206* block location pointed by 'pu1_dst' 1207* 1208* @par Description: 1209* 1210* 1211* @param[in] pu1_src 1212* UWORD8 pointer to the source 1213* 1214* @param[in] pu1_dst 1215* UWORD8 pointer to the destination 1216* 1217* @param[in] src_strd 1218* integer source stride 1219* 1220* @param[in] dst_strd 1221* integer destination stride 1222* 1223* @param[in] nt 1224* integer Transform Block size 1225* 1226* @param[in] mode 1227* integer intraprediction mode 1228* 1229* @returns 1230* 1231* @remarks 1232* None 1233* 1234******************************************************************************* 1235*/ 1236 1237 1238void ihevc_intra_pred_chroma_mode_27_to_33(UWORD8 *pu1_ref, 1239 WORD32 src_strd, 1240 UWORD8 *pu1_dst, 1241 WORD32 dst_strd, 1242 WORD32 nt, 1243 WORD32 mode) 1244{ 1245 WORD32 row, col; 1246 WORD32 pos, fract; 1247 WORD32 intra_pred_ang; 1248 WORD32 idx, ref_main_idx_u, ref_main_idx_v; 1249 UNUSED(src_strd); 1250 1251 1252 intra_pred_ang = gai4_ihevc_ang_table_chroma[mode]; 1253 1254 for(row = 0; row < nt; row++) 1255 { 1256 pos = ((row + 1) * intra_pred_ang); 1257 idx = pos >> 5; 1258 fract = pos & (31); 1259 1260 1261 // Do linear filtering 1262 for(col = 0; col < (2 * nt); col += 2) 1263 { 1264 ref_main_idx_u = (4 * nt) + col + 2 * idx + 2; 1265 ref_main_idx_v = (4 * nt) + (col + 1) + 2 * idx + 2; 1266 pu1_dst[col + (row * dst_strd)] = (((32 - fract) 1267 * pu1_ref[ref_main_idx_u] 1268 + fract * pu1_ref[ref_main_idx_u + 2] + 16) >> 5); 1269 pu1_dst[(col + 1) + (row * dst_strd)] = (((32 - fract) 1270 * pu1_ref[ref_main_idx_v] 1271 + fract * pu1_ref[ref_main_idx_v + 2] + 16) >> 5); 1272 1273 } 1274 } 1275 1276} 1277 1278