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 106 void 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 189 void 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 292 void 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 393 void 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 489 void 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 572 void 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