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 98void 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 335void 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 593void 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 713void 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