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_weighted_pred.c 22* 23* @brief 24* Contains function definitions for weighted prediction used in inter 25* prediction 26* 27* @author 28* Srinivas T 29* 30* @par List of Functions: 31* - ihevc_weighted_pred_uni() 32* - ihevc_weighted_pred_bi() 33* - ihevc_weighted_pred_bi_default() 34* - ihevc_weighted_pred_chroma_uni() 35* - ihevc_weighted_pred_chroma_bi() 36* - ihevc_weighted_pred_chroma_bi_default() 37* 38* @remarks 39* None 40* 41******************************************************************************* 42*/ 43/*****************************************************************************/ 44/* File Includes */ 45/*****************************************************************************/ 46#include "ihevc_typedefs.h" 47#include "ihevc_defs.h" 48#include "ihevc_macros.h" 49#include "ihevc_platform_macros.h" 50#include "ihevc_func_selector.h" 51 52#include "ihevc_inter_pred.h" 53 54/** 55******************************************************************************* 56* 57* @brief 58* Does uni-weighted prediction on the array pointed by pi2_src and stores 59* it at the location pointed by pi2_dst 60* 61* @par Description: 62* dst = ( (src + lvl_shift) * wgt0 + (1 << (shift - 1)) ) >> shift + 63* offset 64* 65* @param[in] pi2_src 66* Pointer to the source 67* 68* @param[out] pu1_dst 69* Pointer to the destination 70* 71* @param[in] src_strd 72* Source stride 73* 74* @param[in] dst_strd 75* Destination stride 76* 77* @param[in] wgt0 78* weight to be multiplied to the source 79* 80* @param[in] off0 81* offset to be added after rounding and 82* 83* @param[in] shifting 84* 85* 86* @param[in] shift 87* (14 Bit depth) + log2_weight_denominator 88* 89* @param[in] lvl_shift 90* added before shift and offset 91* 92* @param[in] ht 93* height of the source 94* 95* @param[in] wd 96* width of the source 97* 98* @returns 99* 100* @remarks 101* None 102* 103******************************************************************************* 104*/ 105 106void ihevc_weighted_pred_uni(WORD16 *pi2_src, 107 UWORD8 *pu1_dst, 108 WORD32 src_strd, 109 WORD32 dst_strd, 110 WORD32 wgt0, 111 WORD32 off0, 112 WORD32 shift, 113 WORD32 lvl_shift, 114 WORD32 ht, 115 WORD32 wd) 116{ 117 WORD32 row, col; 118 WORD32 i4_tmp; 119 120 for(row = 0; row < ht; row++) 121 { 122 for(col = 0; col < wd; col++) 123 { 124 i4_tmp = (pi2_src[col] + lvl_shift) * wgt0; 125 i4_tmp += 1 << (shift - 1); 126 i4_tmp = (i4_tmp >> shift) + off0; 127 128 pu1_dst[col] = CLIP_U8(i4_tmp); 129 } 130 131 pi2_src += src_strd; 132 pu1_dst += dst_strd; 133 } 134} 135//WEIGHTED_PRED_UNI 136 137/** 138******************************************************************************* 139* 140* @brief 141* Does chroma uni-weighted prediction on array pointed by pi2_src and stores 142* it at the location pointed by pi2_dst 143* 144* @par Description: 145* dst = ( (src + lvl_shift) * wgt0 + (1 << (shift - 1)) ) >> shift + 146* offset 147* 148* @param[in] pi2_src 149* Pointer to the source 150* 151* @param[out] pu1_dst 152* Pointer to the destination 153* 154* @param[in] src_strd 155* Source stride 156* 157* @param[in] dst_strd 158* Destination stride 159* 160* @param[in] wgt0 161* weight to be multiplied to the source 162* 163* @param[in] off0 164* offset to be added after rounding and 165* 166* @param[in] shifting 167* 168* 169* @param[in] shift 170* (14 Bit depth) + log2_weight_denominator 171* 172* @param[in] lvl_shift 173* added before shift and offset 174* 175* @param[in] ht 176* height of the source 177* 178* @param[in] wd 179* width of the source (each colour component) 180* 181* @returns 182* 183* @remarks 184* None 185* 186******************************************************************************* 187*/ 188 189void ihevc_weighted_pred_chroma_uni(WORD16 *pi2_src, 190 UWORD8 *pu1_dst, 191 WORD32 src_strd, 192 WORD32 dst_strd, 193 WORD32 wgt0_cb, 194 WORD32 wgt0_cr, 195 WORD32 off0_cb, 196 WORD32 off0_cr, 197 WORD32 shift, 198 WORD32 lvl_shift, 199 WORD32 ht, 200 WORD32 wd) 201{ 202 WORD32 row, col; 203 WORD32 i4_tmp; 204 205 for(row = 0; row < ht; row++) 206 { 207 for(col = 0; col < 2 * wd; col += 2) 208 { 209 i4_tmp = (pi2_src[col] + lvl_shift) * wgt0_cb; 210 i4_tmp += 1 << (shift - 1); 211 i4_tmp = (i4_tmp >> shift) + off0_cb; 212 213 pu1_dst[col] = CLIP_U8(i4_tmp); 214 215 i4_tmp = (pi2_src[col + 1] + lvl_shift) * wgt0_cr; 216 i4_tmp += 1 << (shift - 1); 217 i4_tmp = (i4_tmp >> shift) + off0_cr; 218 219 pu1_dst[col + 1] = CLIP_U8(i4_tmp); 220 } 221 222 pi2_src += src_strd; 223 pu1_dst += dst_strd; 224 } 225} 226//WEIGHTED_PRED_CHROMA_UNI 227 228/** 229******************************************************************************* 230* 231* @brief 232* Does bi-weighted prediction on the arrays pointed by pi2_src1 and 233* pi2_src2 and stores it at location pointed by pi2_dst 234* 235* @par Description: 236* dst = ( (src1 + lvl_shift1)*wgt0 + (src2 + lvl_shift2)*wgt1 + (off0 + 237* off1 + 1) << (shift - 1) ) >> shift 238* 239* @param[in] pi2_src1 240* Pointer to source 1 241* 242* @param[in] pi2_src2 243* Pointer to source 2 244* 245* @param[out] pu1_dst 246* Pointer to destination 247* 248* @param[in] src_strd1 249* Source stride 1 250* 251* @param[in] src_strd2 252* Source stride 2 253* 254* @param[in] dst_strd 255* Destination stride 256* 257* @param[in] wgt0 258* weight to be multiplied to source 1 259* 260* @param[in] off0 261* offset 0 262* 263* @param[in] wgt1 264* weight to be multiplied to source 2 265* 266* @param[in] off1 267* offset 1 268* 269* @param[in] shift 270* (14 Bit depth) + log2_weight_denominator 271* 272* @param[in] lvl_shift1 273* added before shift and offset 274* 275* @param[in] lvl_shift2 276* added before shift and offset 277* 278* @param[in] ht 279* height of the source 280* 281* @param[in] wd 282* width of the source 283* 284* @returns 285* 286* @remarks 287* None 288* 289******************************************************************************* 290*/ 291 292void ihevc_weighted_pred_bi(WORD16 *pi2_src1, 293 WORD16 *pi2_src2, 294 UWORD8 *pu1_dst, 295 WORD32 src_strd1, 296 WORD32 src_strd2, 297 WORD32 dst_strd, 298 WORD32 wgt0, 299 WORD32 off0, 300 WORD32 wgt1, 301 WORD32 off1, 302 WORD32 shift, 303 WORD32 lvl_shift1, 304 WORD32 lvl_shift2, 305 WORD32 ht, 306 WORD32 wd) 307{ 308 WORD32 row, col; 309 WORD32 i4_tmp; 310 311 for(row = 0; row < ht; row++) 312 { 313 for(col = 0; col < wd; col++) 314 { 315 i4_tmp = (pi2_src1[col] + lvl_shift1) * wgt0; 316 i4_tmp += (pi2_src2[col] + lvl_shift2) * wgt1; 317 i4_tmp += (off0 + off1 + 1) << (shift - 1); 318 319 pu1_dst[col] = CLIP_U8(i4_tmp >> shift); 320 } 321 322 pi2_src1 += src_strd1; 323 pi2_src2 += src_strd2; 324 pu1_dst += dst_strd; 325 } 326} 327//WEIGHTED_PRED_BI 328 329/** 330******************************************************************************* 331* 332* @brief 333* Does chroma bi-weighted prediction on the arrays pointed by pi2_src1 and 334* pi2_src2 and stores it at location pointed by pi2_dst 335* 336* @par Description: 337* dst = ( (src1 + lvl_shift1)*wgt0 + (src2 + lvl_shift2)*wgt1 + (off0 + 338* off1 + 1) << (shift - 1) ) >> shift 339* 340* @param[in] pi2_src1 341* Pointer to source 1 342* 343* @param[in] pi2_src2 344* Pointer to source 2 345* 346* @param[out] pu1_dst 347* Pointer to destination 348* 349* @param[in] src_strd1 350* Source stride 1 351* 352* @param[in] src_strd2 353* Source stride 2 354* 355* @param[in] dst_strd 356* Destination stride 357* 358* @param[in] wgt0 359* weight to be multiplied to source 1 360* 361* @param[in] off0 362* offset 0 363* 364* @param[in] wgt1 365* weight to be multiplied to source 2 366* 367* @param[in] off1 368* offset 1 369* 370* @param[in] shift 371* (14 Bit depth) + log2_weight_denominator 372* 373* @param[in] lvl_shift1 374* added before shift and offset 375* 376* @param[in] lvl_shift2 377* added before shift and offset 378* 379* @param[in] ht 380* height of the source 381* 382* @param[in] wd 383* width of the source (each colour component) 384* 385* @returns 386* 387* @remarks 388* None 389* 390******************************************************************************* 391*/ 392 393void ihevc_weighted_pred_chroma_bi(WORD16 *pi2_src1, 394 WORD16 *pi2_src2, 395 UWORD8 *pu1_dst, 396 WORD32 src_strd1, 397 WORD32 src_strd2, 398 WORD32 dst_strd, 399 WORD32 wgt0_cb, 400 WORD32 wgt0_cr, 401 WORD32 off0_cb, 402 WORD32 off0_cr, 403 WORD32 wgt1_cb, 404 WORD32 wgt1_cr, 405 WORD32 off1_cb, 406 WORD32 off1_cr, 407 WORD32 shift, 408 WORD32 lvl_shift1, 409 WORD32 lvl_shift2, 410 WORD32 ht, 411 WORD32 wd) 412{ 413 WORD32 row, col; 414 WORD32 i4_tmp; 415 416 for(row = 0; row < ht; row++) 417 { 418 for(col = 0; col < 2 * wd; col += 2) 419 { 420 i4_tmp = (pi2_src1[col] + lvl_shift1) * wgt0_cb; 421 i4_tmp += (pi2_src2[col] + lvl_shift2) * wgt1_cb; 422 i4_tmp += (off0_cb + off1_cb + 1) << (shift - 1); 423 424 pu1_dst[col] = CLIP_U8(i4_tmp >> shift); 425 426 i4_tmp = (pi2_src1[col + 1] + lvl_shift1) * wgt0_cr; 427 i4_tmp += (pi2_src2[col + 1] + lvl_shift2) * wgt1_cr; 428 i4_tmp += (off0_cr + off1_cr + 1) << (shift - 1); 429 430 pu1_dst[col + 1] = CLIP_U8(i4_tmp >> shift); 431 } 432 433 pi2_src1 += src_strd1; 434 pi2_src2 += src_strd2; 435 pu1_dst += dst_strd; 436 } 437} 438//WEIGHTED_PRED_CHROMA_BI 439 440/** 441******************************************************************************* 442* 443* @brief 444* Does default bi-weighted prediction on the arrays pointed by pi2_src1 and 445* pi2_src2 and stores it at location pointed by pi2_dst 446* 447* @par Description: 448* dst = ( (src1 + lvl_shift1) + (src2 + lvl_shift2) + 1 << (shift - 1) ) 449* >> shift where shift = 15 - BitDepth 450* 451* @param[in] pi2_src1 452* Pointer to source 1 453* 454* @param[in] pi2_src2 455* Pointer to source 2 456* 457* @param[out] pu1_dst 458* Pointer to destination 459* 460* @param[in] src_strd1 461* Source stride 1 462* 463* @param[in] src_strd2 464* Source stride 2 465* 466* @param[in] dst_strd 467* Destination stride 468* 469* @param[in] lvl_shift1 470* added before shift and offset 471* 472* @param[in] lvl_shift2 473* added before shift and offset 474* 475* @param[in] ht 476* height of the source 477* 478* @param[in] wd 479* width of the source 480* 481* @returns 482* 483* @remarks 484* None 485* 486******************************************************************************* 487*/ 488 489void ihevc_weighted_pred_bi_default(WORD16 *pi2_src1, 490 WORD16 *pi2_src2, 491 UWORD8 *pu1_dst, 492 WORD32 src_strd1, 493 WORD32 src_strd2, 494 WORD32 dst_strd, 495 WORD32 lvl_shift1, 496 WORD32 lvl_shift2, 497 WORD32 ht, 498 WORD32 wd) 499{ 500 WORD32 row, col; 501 WORD32 i4_tmp; 502 WORD32 shift; 503 504 shift = SHIFT_14_MINUS_BIT_DEPTH + 1; 505 for(row = 0; row < ht; row++) 506 { 507 for(col = 0; col < wd; col++) 508 { 509 i4_tmp = pi2_src1[col] + lvl_shift1; 510 i4_tmp += pi2_src2[col] + lvl_shift2; 511 i4_tmp += 1 << (shift - 1); 512 513 pu1_dst[col] = CLIP_U8(i4_tmp >> shift); 514 } 515 516 pi2_src1 += src_strd1; 517 pi2_src2 += src_strd2; 518 pu1_dst += dst_strd; 519 } 520} 521//WEIGHTED_PRED_BI_DEFAULT 522 523/** 524******************************************************************************* 525* 526* @brief 527* Does chroma default bi-weighted prediction on arrays pointed by pi2_src1 and 528* pi2_src2 and stores it at location pointed by pi2_dst 529* 530* @par Description: 531* dst = ( (src1 + lvl_shift1) + (src2 + lvl_shift2) + 1 << (shift - 1) ) 532* >> shift where shift = 15 - BitDepth 533* 534* @param[in] pi2_src1 535* Pointer to source 1 536* 537* @param[in] pi2_src2 538* Pointer to source 2 539* 540* @param[out] pu1_dst 541* Pointer to destination 542* 543* @param[in] src_strd1 544* Source stride 1 545* 546* @param[in] src_strd2 547* Source stride 2 548* 549* @param[in] dst_strd 550* Destination stride 551* 552* @param[in] lvl_shift1 553* added before shift and offset 554* 555* @param[in] lvl_shift2 556* added before shift and offset 557* 558* @param[in] ht 559* height of the source 560* 561* @param[in] wd 562* width of the source (each colour component) 563* 564* @returns 565* 566* @remarks 567* None 568* 569******************************************************************************* 570*/ 571 572void ihevc_weighted_pred_chroma_bi_default(WORD16 *pi2_src1, 573 WORD16 *pi2_src2, 574 UWORD8 *pu1_dst, 575 WORD32 src_strd1, 576 WORD32 src_strd2, 577 WORD32 dst_strd, 578 WORD32 lvl_shift1, 579 WORD32 lvl_shift2, 580 WORD32 ht, 581 WORD32 wd) 582{ 583 WORD32 row, col; 584 WORD32 i4_tmp; 585 WORD32 shift; 586 587 shift = SHIFT_14_MINUS_BIT_DEPTH + 1; 588 for(row = 0; row < ht; row++) 589 { 590 for(col = 0; col < 2 * wd; col++) 591 { 592 i4_tmp = pi2_src1[col] + lvl_shift1; 593 i4_tmp += pi2_src2[col] + lvl_shift2; 594 i4_tmp += 1 << (shift - 1); 595 596 pu1_dst[col] = CLIP_U8(i4_tmp >> shift); 597 } 598 599 pi2_src1 += src_strd1; 600 pi2_src2 += src_strd2; 601 pu1_dst += dst_strd; 602 } 603} 604//WEIGHTED_PRED_CHROMA_BI_DEFAULT 605