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_deblk_edge_filter.c 22 * 23 * @brief 24 * Contains function definitions for deblocking filters 25 * 26 * @author 27 * Srinivas T 28 * 29 * @par List of Functions: 30 * - ihevc_deblk_luma_vert() 31 * - ihevc_deblk_luma_horz() 32 * - ihevc_deblk_chroma_vert() 33 * - ihevc_deblk_chroma_horz() 34 * @remarks 35 * None 36 * 37 ******************************************************************************* 38 */ 39 #include <stdlib.h> 40 #include <stdio.h> 41 #include <assert.h> 42 #include "ihevc_typedefs.h" 43 #include "ihevc_macros.h" 44 #include "ihevc_platform_macros.h" 45 #include "ihevc_func_selector.h" 46 #include "ihevc_deblk.h" 47 #include "ihevc_deblk_tables.h" 48 #include "ihevc_debug.h" 49 50 51 /** 52 ******************************************************************************* 53 * 54 * @brief 55 * Decision process and filtering for the luma block vertical edge. 56 * 57 * @par Description: 58 * The decision process for the luma block vertical edge is carried out and 59 * an appropriate filter is applied. The boundary filter strength, bs should 60 * be greater than 0. The pcm flags and the transquant bypass flags should 61 * be taken care of by the calling function. 62 * 63 * @param[in] pu1_src 64 * Pointer to the src sample q(0,0) 65 * 66 * @param[in] src_strd 67 * Source stride 68 * 69 * @param[in] bs 70 * Boundary filter strength of q(0,0) 71 * 72 * @param[in] quant_param_p 73 * quantization parameter of p block 74 * 75 * @param[in] quant_param_q 76 * quantization parameter of p block 77 * 78 * @param[in] beta_offset_div2 79 * 80 * 81 * @param[in] tc_offset_div2 82 * 83 * 84 * @param[in] filter_flag_p 85 * flag whether to filter the p block 86 * 87 * @param[in] filter_flag_q 88 * flag whether to filter the q block 89 * 90 * @returns 91 * 92 * @remarks 93 * None 94 * 95 ******************************************************************************* 96 */ 97 98 void ihevc_deblk_luma_vert(UWORD8 *pu1_src, 99 WORD32 src_strd, 100 WORD32 bs, 101 WORD32 quant_param_p, 102 WORD32 quant_param_q, 103 WORD32 beta_offset_div2, 104 WORD32 tc_offset_div2, 105 WORD32 filter_flag_p, 106 WORD32 filter_flag_q) 107 { 108 WORD32 qp_luma, beta_indx, tc_indx; 109 WORD32 beta, tc; 110 WORD32 dp0, dp3, dq0, dq3, d0, d3, dp, dq, d; 111 WORD32 d_sam0, d_sam3; 112 WORD32 de, dep, deq; 113 WORD32 row; 114 WORD32 tmp_p0, tmp_p1, tmp_p2, tmp_q0, tmp_q1, tmp_q2; 115 WORD32 delta, delta_p, delta_q; 116 117 ASSERT((bs > 0) && (bs <= 3)); 118 ASSERT(filter_flag_p || filter_flag_q); 119 120 qp_luma = (quant_param_p + quant_param_q + 1) >> 1; 121 beta_indx = CLIP3(qp_luma + (beta_offset_div2 << 1), 0, 51); 122 123 /* BS based on implementation can take value 3 if it is intra/inter egde */ 124 /* based on BS, tc index is calcuated by adding 2 * ( bs - 1) to QP and tc_offset */ 125 /* for BS = 1 adding factor is (0*2), BS = 2 or 3 adding factor is (1*2) */ 126 /* the above desired functionallity is achieved by doing (2*(bs>>1)) */ 127 128 tc_indx = CLIP3(qp_luma + (2 * (bs >> 1)) + (tc_offset_div2 << 1), 0, 53); 129 130 beta = gai4_ihevc_beta_table[beta_indx]; 131 tc = gai4_ihevc_tc_table[tc_indx]; 132 if(0 == tc) 133 { 134 return; 135 } 136 137 dq0 = ABS(pu1_src[2] - 2 * pu1_src[1] + pu1_src[0]); 138 dq3 = ABS(pu1_src[3 * src_strd + 2] - 2 * pu1_src[3 * src_strd + 1] 139 + pu1_src[3 * src_strd + 0]); 140 dp0 = ABS(pu1_src[-3] - 2 * pu1_src[-2] + pu1_src[-1]); 141 dp3 = ABS(pu1_src[3 * src_strd - 3] - 2 * pu1_src[3 * src_strd - 2] 142 + pu1_src[3 * src_strd - 1]); 143 144 d0 = dp0 + dq0; 145 d3 = dp3 + dq3; 146 147 dp = dp0 + dp3; 148 dq = dq0 + dq3; 149 150 d = d0 + d3; 151 152 de = 0; 153 dep = 0; 154 deq = 0; 155 156 if(d < beta) 157 { 158 d_sam0 = 0; 159 if((2 * d0 < (beta >> 2)) 160 && (ABS(pu1_src[3] - pu1_src[0]) + ABS(pu1_src[-1] - pu1_src[-4]) 161 < (beta >> 3)) 162 && ABS(pu1_src[0] - pu1_src[-1]) < ((5 * tc + 1) >> 1)) 163 { 164 d_sam0 = 1; 165 } 166 167 pu1_src += 3 * src_strd; 168 d_sam3 = 0; 169 if((2 * d3 < (beta >> 2)) 170 && (ABS(pu1_src[3] - pu1_src[0]) + ABS(pu1_src[-1] - pu1_src[-4]) 171 < (beta >> 3)) 172 && ABS(pu1_src[0] - pu1_src[-1]) < ((5 * tc + 1) >> 1)) 173 { 174 d_sam3 = 1; 175 } 176 pu1_src -= 3 * src_strd; 177 178 de = (d_sam0 == 1 && d_sam3 == 1) ? 2 : 1; 179 dep = (dp < (beta + (beta >> 1)) >> 3) ? 1 : 0; 180 deq = (dq < (beta + (beta >> 1)) >> 3) ? 1 : 0; 181 if(tc <= 1) 182 { 183 dep = 0; 184 deq = 0; 185 } 186 } 187 188 if(de != 0) 189 { 190 for(row = 0; row < 4; row++) 191 { 192 tmp_p0 = pu1_src[-1]; 193 tmp_p1 = pu1_src[-2]; 194 tmp_p2 = pu1_src[-3]; 195 196 tmp_q0 = pu1_src[0]; 197 tmp_q1 = pu1_src[1]; 198 tmp_q2 = pu1_src[2]; 199 200 if(de == 2) 201 { 202 tmp_q0 = CLIP3((pu1_src[2] + 2 * pu1_src[1] + 203 2 * pu1_src[0] + 2 * pu1_src[-1] + 204 pu1_src[-2] + 4) >> 3, 205 pu1_src[0] - 2 * tc, 206 pu1_src[0] + 2 * tc); 207 208 tmp_q1 = CLIP3((pu1_src[2] + pu1_src[1] + pu1_src[0] + 209 pu1_src[-1] + 2) >> 2, 210 pu1_src[1] - 2 * tc, 211 pu1_src[1] + 2 * tc); 212 213 tmp_q2 = CLIP3((2 * pu1_src[3] + 3 * pu1_src[2] + 214 pu1_src[1] + pu1_src[0] + 215 pu1_src[-1] + 4) >> 3, 216 pu1_src[2] - 2 * tc, 217 pu1_src[2] + 2 * tc); 218 219 tmp_p0 = CLIP3((pu1_src[1] + 2 * pu1_src[0] + 220 2 * pu1_src[-1] + 2 * pu1_src[-2] + 221 pu1_src[-3] + 4) >> 3, 222 pu1_src[-1] - 2 * tc, 223 pu1_src[-1] + 2 * tc); 224 225 tmp_p1 = CLIP3((pu1_src[0] + pu1_src[-1] + 226 pu1_src[-2] + pu1_src[-3] + 2) >> 2, 227 pu1_src[-2] - 2 * tc, 228 pu1_src[-2] + 2 * tc); 229 230 tmp_p2 = CLIP3((pu1_src[0] + pu1_src[-1] + 231 pu1_src[-2] + 3 * pu1_src[-3] + 232 2 * pu1_src[-4] + 4) >> 3, 233 pu1_src[-3] - 2 * tc, 234 pu1_src[-3] + 2 * tc); 235 } 236 else 237 { 238 delta = (9 * (pu1_src[0] - pu1_src[-1]) - 239 3 * (pu1_src[1] - pu1_src[-2]) + 8) >> 4; 240 if(ABS(delta) < 10 * tc) 241 { 242 delta = CLIP3(delta, -tc, tc); 243 244 tmp_p0 = CLIP_U8(pu1_src[-1] + delta); 245 tmp_q0 = CLIP_U8(pu1_src[0] - delta); 246 247 if(dep == 1) 248 { 249 delta_p = CLIP3((((pu1_src[-3] + pu1_src[-1] + 1) >> 1) 250 - pu1_src[-2] + delta) >> 1, 251 -(tc >> 1), 252 (tc >> 1)); 253 tmp_p1 = CLIP_U8(pu1_src[-2] + delta_p); 254 } 255 256 if(deq == 1) 257 { 258 delta_q = CLIP3((((pu1_src[2] + pu1_src[0] + 1) >> 1) 259 - pu1_src[1] - delta) >> 1, 260 -(tc >> 1), 261 (tc >> 1)); 262 tmp_q1 = CLIP_U8(pu1_src[1] + delta_q); 263 } 264 } 265 } 266 267 if(filter_flag_p != 0) 268 { 269 pu1_src[-3] = tmp_p2; 270 pu1_src[-2] = tmp_p1; 271 pu1_src[-1] = tmp_p0; 272 } 273 274 if(filter_flag_q != 0) 275 { 276 pu1_src[0] = tmp_q0; 277 pu1_src[1] = tmp_q1; 278 pu1_src[2] = tmp_q2; 279 } 280 281 pu1_src += src_strd; 282 } 283 } 284 285 } 286 287 /** 288 ******************************************************************************* 289 * 290 * @brief 291 * 292 * Decision process and filtering for the luma block horizontal edge 293 * 294 * @par Description: 295 * The decision process for the luma block horizontal edge is carried out 296 * and an appropriate filter is applied. The boundary filter strength, bs 297 * should be greater than 0. The pcm flags and the transquant bypass flags 298 * should be taken care of by the calling function. 299 * 300 * @param[in] pu1_src 301 * Pointer to the src sample q(0,0) 302 * 303 * @param[in] src_strd 304 * Source stride 305 * 306 * @param[in] bs 307 * Boundary filter strength of q(0,0) 308 * 309 * @param[in] quant_param_p 310 * quantization parameter of p block 311 * 312 * @param[in] quant_param_q 313 * quantization parameter of p block 314 * 315 * @param[in] beta_offset_div2 316 * 317 * 318 * @param[in] tc_offset_div2 319 * 320 * 321 * @param[in] filter_flag_p 322 * flag whether to filter the p block 323 * 324 * @param[in] filter_flag_q 325 * flag whether to filter the q block 326 * 327 * @returns 328 * 329 * @remarks 330 * None 331 * 332 ******************************************************************************* 333 */ 334 335 void ihevc_deblk_luma_horz(UWORD8 *pu1_src, 336 WORD32 src_strd, 337 WORD32 bs, 338 WORD32 quant_param_p, 339 WORD32 quant_param_q, 340 WORD32 beta_offset_div2, 341 WORD32 tc_offset_div2, 342 WORD32 filter_flag_p, 343 WORD32 filter_flag_q) 344 { 345 WORD32 qp_luma, beta_indx, tc_indx; 346 WORD32 beta, tc; 347 WORD32 dp0, dp3, dq0, dq3, d0, d3, dp, dq, d; 348 WORD32 d_sam0, d_sam3; 349 WORD32 de, dep, deq; 350 WORD32 col; 351 WORD32 tmp_p0, tmp_p1, tmp_p2, tmp_q0, tmp_q1, tmp_q2; 352 WORD32 delta, delta_p, delta_q; 353 354 ASSERT((bs > 0)); 355 ASSERT(filter_flag_p || filter_flag_q); 356 357 qp_luma = (quant_param_p + quant_param_q + 1) >> 1; 358 beta_indx = CLIP3(qp_luma + (beta_offset_div2 << 1), 0, 51); 359 360 /* BS based on implementation can take value 3 if it is intra/inter egde */ 361 /* based on BS, tc index is calcuated by adding 2 * ( bs - 1) to QP and tc_offset */ 362 /* for BS = 1 adding factor is (0*2), BS = 2 or 3 adding factor is (1*2) */ 363 /* the above desired functionallity is achieved by doing (2*(bs>>1)) */ 364 365 tc_indx = CLIP3(qp_luma + 2 * (bs >> 1) + (tc_offset_div2 << 1), 0, 53); 366 367 beta = gai4_ihevc_beta_table[beta_indx]; 368 tc = gai4_ihevc_tc_table[tc_indx]; 369 if(0 == tc) 370 { 371 return; 372 } 373 374 dq0 = ABS(pu1_src[2 * src_strd] - 2 * pu1_src[1 * src_strd] + 375 pu1_src[0 * src_strd]); 376 377 dq3 = ABS(pu1_src[3 + 2 * src_strd] - 2 * pu1_src[3 + 1 * src_strd] + 378 pu1_src[3 + 0 * src_strd]); 379 380 dp0 = ABS(pu1_src[-3 * src_strd] - 2 * pu1_src[-2 * src_strd] + 381 pu1_src[-1 * src_strd]); 382 383 dp3 = ABS(pu1_src[3 - 3 * src_strd] - 2 * pu1_src[3 - 2 * src_strd] + 384 pu1_src[3 - 1 * src_strd]); 385 386 d0 = dp0 + dq0; 387 d3 = dp3 + dq3; 388 389 dp = dp0 + dp3; 390 dq = dq0 + dq3; 391 392 d = d0 + d3; 393 394 de = 0; 395 dep = 0; 396 deq = 0; 397 398 if(d < beta) 399 { 400 d_sam0 = 0; 401 if((2 * d0 < (beta >> 2)) 402 && (ABS(pu1_src[3 * src_strd] - pu1_src[0 * src_strd]) + 403 ABS(pu1_src[-1 * src_strd] - pu1_src[-4 * src_strd]) 404 < (beta >> 3)) 405 && ABS(pu1_src[0 * src_strd] - pu1_src[-1 * src_strd]) 406 < ((5 * tc + 1) >> 1)) 407 { 408 d_sam0 = 1; 409 } 410 411 pu1_src += 3; 412 d_sam3 = 0; 413 if((2 * d3 < (beta >> 2)) 414 && (ABS(pu1_src[3 * src_strd] - pu1_src[0 * src_strd]) + 415 ABS(pu1_src[-1 * src_strd] - pu1_src[-4 * src_strd]) 416 < (beta >> 3)) 417 && ABS(pu1_src[0 * src_strd] - pu1_src[-1 * src_strd]) 418 < ((5 * tc + 1) >> 1)) 419 { 420 d_sam3 = 1; 421 } 422 pu1_src -= 3; 423 424 de = (d_sam0 == 1 && d_sam3 == 1) ? 2 : 1; 425 dep = (dp < ((beta + (beta >> 1)) >> 3)) ? 1 : 0; 426 deq = (dq < ((beta + (beta >> 1)) >> 3)) ? 1 : 0; 427 if(tc <= 1) 428 { 429 dep = 0; 430 deq = 0; 431 } 432 } 433 434 if(de != 0) 435 { 436 for(col = 0; col < 4; col++) 437 { 438 tmp_p0 = pu1_src[-1 * src_strd]; 439 tmp_p1 = pu1_src[-2 * src_strd]; 440 tmp_p2 = pu1_src[-3 * src_strd]; 441 442 tmp_q0 = pu1_src[0 * src_strd]; 443 tmp_q1 = pu1_src[1 * src_strd]; 444 tmp_q2 = pu1_src[2 * src_strd]; 445 if(de == 2) 446 { 447 tmp_q0 = CLIP3((pu1_src[2 * src_strd] + 448 2 * pu1_src[1 * src_strd] + 449 2 * pu1_src[0 * src_strd] + 450 2 * pu1_src[-1 * src_strd] + 451 pu1_src[-2 * src_strd] + 4) >> 3, 452 pu1_src[0 * src_strd] - 2 * tc, 453 pu1_src[0 * src_strd] + 2 * tc); 454 455 tmp_q1 = CLIP3((pu1_src[2 * src_strd] + 456 pu1_src[1 * src_strd] + 457 pu1_src[0 * src_strd] + 458 pu1_src[-1 * src_strd] + 2) >> 2, 459 pu1_src[1 * src_strd] - 2 * tc, 460 pu1_src[1 * src_strd] + 2 * tc); 461 462 tmp_q2 = CLIP3((2 * pu1_src[3 * src_strd] + 463 3 * pu1_src[2 * src_strd] + 464 pu1_src[1 * src_strd] + 465 pu1_src[0 * src_strd] + 466 pu1_src[-1 * src_strd] + 4) >> 3, 467 pu1_src[2 * src_strd] - 2 * tc, 468 pu1_src[2 * src_strd] + 2 * tc); 469 470 tmp_p0 = CLIP3((pu1_src[1 * src_strd] + 471 2 * pu1_src[0 * src_strd] + 472 2 * pu1_src[-1 * src_strd] + 473 2 * pu1_src[-2 * src_strd] + 474 pu1_src[-3 * src_strd] + 4) >> 3, 475 pu1_src[-1 * src_strd] - 2 * tc, 476 pu1_src[-1 * src_strd] + 2 * tc); 477 478 tmp_p1 = CLIP3((pu1_src[0 * src_strd] + 479 pu1_src[-1 * src_strd] + 480 pu1_src[-2 * src_strd] + 481 pu1_src[-3 * src_strd] + 2) >> 2, 482 pu1_src[-2 * src_strd] - 2 * tc, 483 pu1_src[-2 * src_strd] + 2 * tc); 484 485 tmp_p2 = CLIP3((pu1_src[0 * src_strd] + 486 pu1_src[-1 * src_strd] + 487 pu1_src[-2 * src_strd] + 488 3 * pu1_src[-3 * src_strd] + 489 2 * pu1_src[-4 * src_strd] + 4) >> 3, 490 pu1_src[-3 * src_strd] - 2 * tc, 491 pu1_src[-3 * src_strd] + 2 * tc); 492 } 493 else 494 { 495 delta = (9 * (pu1_src[0 * src_strd] - pu1_src[-1 * src_strd]) - 496 3 * (pu1_src[1 * src_strd] - pu1_src[-2 * src_strd]) + 497 8) >> 4; 498 if(ABS(delta) < 10 * tc) 499 { 500 delta = CLIP3(delta, -tc, tc); 501 502 tmp_p0 = CLIP_U8(pu1_src[-1 * src_strd] + delta); 503 tmp_q0 = CLIP_U8(pu1_src[0 * src_strd] - delta); 504 505 if(dep == 1) 506 { 507 delta_p = CLIP3((((pu1_src[-3 * src_strd] + 508 pu1_src[-1 * src_strd] + 1) >> 1) - 509 pu1_src[-2 * src_strd] + delta) >> 1, 510 -(tc >> 1), 511 (tc >> 1)); 512 tmp_p1 = CLIP_U8(pu1_src[-2 * src_strd] + delta_p); 513 } 514 515 if(deq == 1) 516 { 517 delta_q = CLIP3((((pu1_src[2 * src_strd] + 518 pu1_src[0 * src_strd] + 1) >> 1) - 519 pu1_src[1 * src_strd] - delta) >> 1, 520 -(tc >> 1), 521 (tc >> 1)); 522 tmp_q1 = CLIP_U8(pu1_src[1 * src_strd] + delta_q); 523 } 524 } 525 } 526 527 if(filter_flag_p != 0) 528 { 529 pu1_src[-3 * src_strd] = tmp_p2; 530 pu1_src[-2 * src_strd] = tmp_p1; 531 pu1_src[-1 * src_strd] = tmp_p0; 532 } 533 534 if(filter_flag_q != 0) 535 { 536 pu1_src[0 * src_strd] = tmp_q0; 537 pu1_src[1 * src_strd] = tmp_q1; 538 pu1_src[2 * src_strd] = tmp_q2; 539 } 540 541 pu1_src += 1; 542 } 543 } 544 545 } 546 547 /** 548 ******************************************************************************* 549 * 550 * @brief 551 * Filtering for the chroma block vertical edge. 552 * 553 * @par Description: 554 * Filter for chroma vertical edge. The boundary filter strength, bs 555 * should be greater than 1. The pcm flags and the transquant bypass flags 556 * should be taken care of by the calling function. 557 * 558 * @param[in] pu1_src 559 * Pointer to the src sample q(0,0) 560 * 561 * @param[in] src_strd 562 * Source stride 563 * 564 * @param[in] bs 565 * Boundary filter strength of q(0,0) 566 * 567 * @param[in] quant_param_p 568 * quantization parameter of p block 569 * 570 * @param[in] quant_param_q 571 * quantization parameter of p block 572 * 573 * @param[in] beta_offset_div2 574 * 575 * 576 * @param[in] tc_offset_div2 577 * 578 * 579 * @param[in] filter_flag_p 580 * flag whether to filter the p block 581 * 582 * @param[in] filter_flag_q 583 * flag whether to filter the q block 584 * 585 * @returns 586 * 587 * @remarks 588 * None 589 * 590 ******************************************************************************* 591 */ 592 593 void ihevc_deblk_chroma_vert(UWORD8 *pu1_src, 594 WORD32 src_strd, 595 WORD32 quant_param_p, 596 WORD32 quant_param_q, 597 WORD32 qp_offset_u, 598 WORD32 qp_offset_v, 599 WORD32 tc_offset_div2, 600 WORD32 filter_flag_p, 601 WORD32 filter_flag_q) 602 { 603 WORD32 qp_indx_u, qp_chroma_u; 604 WORD32 qp_indx_v, qp_chroma_v; 605 WORD32 tc_indx_u, tc_u; 606 WORD32 tc_indx_v, tc_v; 607 WORD32 delta_u, tmp_p0_u, tmp_q0_u; 608 WORD32 delta_v, tmp_p0_v, tmp_q0_v; 609 WORD32 row; 610 611 ASSERT(filter_flag_p || filter_flag_q); 612 613 /* chroma processing is done only if BS is 2 */ 614 /* this function is assumed to be called only if BS is 2 */ 615 qp_indx_u = qp_offset_u + ((quant_param_p + quant_param_q + 1) >> 1); 616 qp_chroma_u = qp_indx_u < 0 ? qp_indx_u : (qp_indx_u > 57 ? qp_indx_u - 6 : gai4_ihevc_qp_table[qp_indx_u]); 617 618 qp_indx_v = qp_offset_v + ((quant_param_p + quant_param_q + 1) >> 1); 619 qp_chroma_v = qp_indx_v < 0 ? qp_indx_v : (qp_indx_v > 57 ? qp_indx_v - 6 : gai4_ihevc_qp_table[qp_indx_v]); 620 621 tc_indx_u = CLIP3(qp_chroma_u + 2 + (tc_offset_div2 << 1), 0, 53); 622 tc_u = gai4_ihevc_tc_table[tc_indx_u]; 623 624 tc_indx_v = CLIP3(qp_chroma_v + 2 + (tc_offset_div2 << 1), 0, 53); 625 tc_v = gai4_ihevc_tc_table[tc_indx_v]; 626 627 if(0 == tc_u && 0 == tc_v) 628 { 629 return; 630 } 631 632 for(row = 0; row < 4; row++) 633 { 634 delta_u = CLIP3((((pu1_src[0] - pu1_src[-2]) << 2) + 635 pu1_src[-4] - pu1_src[2] + 4) >> 3, 636 -tc_u, tc_u); 637 638 tmp_p0_u = CLIP_U8(pu1_src[-2] + delta_u); 639 tmp_q0_u = CLIP_U8(pu1_src[0] - delta_u); 640 641 delta_v = CLIP3((((pu1_src[1] - pu1_src[-1]) << 2) + 642 pu1_src[-3] - pu1_src[3] + 4) >> 3, 643 -tc_v, tc_v); 644 645 tmp_p0_v = CLIP_U8(pu1_src[-1] + delta_v); 646 tmp_q0_v = CLIP_U8(pu1_src[1] - delta_v); 647 648 if(filter_flag_p != 0) 649 { 650 pu1_src[-2] = tmp_p0_u; 651 pu1_src[-1] = tmp_p0_v; 652 } 653 654 if(filter_flag_q != 0) 655 { 656 pu1_src[0] = tmp_q0_u; 657 pu1_src[1] = tmp_q0_v; 658 } 659 660 pu1_src += src_strd; 661 } 662 663 } 664 665 666 667 /** 668 ******************************************************************************* 669 * 670 * @brief 671 * Filtering for the chroma block horizontal edge. 672 * 673 * @par Description: 674 * Filter for chroma horizontal edge. The boundary filter strength, bs 675 * should be greater than 1. The pcm flags and the transquant bypass flags 676 * should be taken care of by the calling function. 677 * 678 * @param[in] pu1_src 679 * Pointer to the src sample q(0,0) 680 * 681 * @param[in] src_strd 682 * Source stride 683 * 684 * @param[in] bs 685 * Boundary filter strength of q(0,0) 686 * 687 * @param[in] quant_param_p 688 * quantization parameter of p block 689 * 690 * @param[in] quant_param_q 691 * quantization parameter of p block 692 * 693 * @param[in] beta_offset_div2 694 * 695 * 696 * @param[in] tc_offset_div2 697 * 698 * 699 * @param[in] filter_flag_p 700 * flag whether to filter the p block 701 * 702 * @param[in] filter_flag_q 703 * flag whether to filter the q block 704 * 705 * @returns 706 * 707 * @remarks 708 * None 709 * 710 ******************************************************************************* 711 */ 712 713 void ihevc_deblk_chroma_horz(UWORD8 *pu1_src, 714 WORD32 src_strd, 715 WORD32 quant_param_p, 716 WORD32 quant_param_q, 717 WORD32 qp_offset_u, 718 WORD32 qp_offset_v, 719 WORD32 tc_offset_div2, 720 WORD32 filter_flag_p, 721 WORD32 filter_flag_q) 722 { 723 WORD32 qp_indx_u, qp_chroma_u; 724 WORD32 qp_indx_v, qp_chroma_v; 725 WORD32 tc_indx_u, tc_u; 726 WORD32 tc_indx_v, tc_v; 727 WORD32 tc; 728 729 WORD32 delta, tmp_p0, tmp_q0; 730 WORD32 col; 731 732 ASSERT(filter_flag_p || filter_flag_q); 733 734 /* chroma processing is done only if BS is 2 */ 735 /* this function is assumed to be called only if BS is 2 */ 736 qp_indx_u = qp_offset_u + ((quant_param_p + quant_param_q + 1) >> 1); 737 qp_chroma_u = qp_indx_u < 0 ? qp_indx_u : (qp_indx_u > 57 ? qp_indx_u - 6 : gai4_ihevc_qp_table[qp_indx_u]); 738 739 qp_indx_v = qp_offset_v + ((quant_param_p + quant_param_q + 1) >> 1); 740 qp_chroma_v = qp_indx_v < 0 ? qp_indx_v : (qp_indx_v > 57 ? qp_indx_v - 6 : gai4_ihevc_qp_table[qp_indx_v]); 741 742 tc_indx_u = CLIP3(qp_chroma_u + 2 + (tc_offset_div2 << 1), 0, 53); 743 tc_u = gai4_ihevc_tc_table[tc_indx_u]; 744 745 tc_indx_v = CLIP3(qp_chroma_v + 2 + (tc_offset_div2 << 1), 0, 53); 746 tc_v = gai4_ihevc_tc_table[tc_indx_v]; 747 748 if(0 == tc_u && 0 == tc_v) 749 { 750 return; 751 } 752 753 for(col = 0; col < 8; col++) 754 { 755 tc = (col & 1) ? tc_v : tc_u; 756 delta = CLIP3((((pu1_src[0 * src_strd] - 757 pu1_src[-1 * src_strd]) << 2) + 758 pu1_src[-2 * src_strd] - 759 pu1_src[1 * src_strd] + 4) >> 3, 760 -tc, tc); 761 762 tmp_p0 = CLIP_U8(pu1_src[-1 * src_strd] + delta); 763 tmp_q0 = CLIP_U8(pu1_src[0 * src_strd] - delta); 764 765 if(filter_flag_p != 0) 766 { 767 pu1_src[-1 * src_strd] = tmp_p0; 768 } 769 770 if(filter_flag_q != 0) 771 { 772 pu1_src[0 * src_strd] = tmp_q0; 773 } 774 775 pu1_src += 1; 776 } 777 778 } 779 780