1 /****************************************************************************** 2 * 3 * Copyright (C) 2015 The Android Open Source Project 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 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore 19 */ 20 21 /** 22 ******************************************************************************* 23 * @file 24 * ih264e_deblk.c 25 * 26 * @brief 27 * This file contains functions that are associated with deblocking 28 * 29 * @author 30 * ittiam 31 * 32 * @par List of Functions: 33 * - ih264e_fill_bs_1mv_1ref_non_mbaff 34 * - ih264e_calculate_csbp 35 * - ih264e_compute_bs 36 * - ih264e_filter_top_edge 37 * - ih264e_filter_left_edge 38 * - ih264e_deblock_mb 39 * 40 * @remarks 41 * None 42 * 43 ******************************************************************************* 44 */ 45 46 /*****************************************************************************/ 47 /* File Includes */ 48 /*****************************************************************************/ 49 50 /* System include files */ 51 #include <stdio.h> 52 #include <string.h> 53 #include <assert.h> 54 55 /* User include files */ 56 #include "ih264e_config.h" 57 #include "ih264_typedefs.h" 58 #include "iv2.h" 59 #include "ive2.h" 60 #include "ih264_macros.h" 61 #include "ih264_defs.h" 62 #include "ih264e_defs.h" 63 #include "ih264e_error.h" 64 #include "ih264e_bitstream.h" 65 #include "ime_distortion_metrics.h" 66 #include "ime_defs.h" 67 #include "ime_structs.h" 68 #include "ih264_structs.h" 69 #include "ih264_trans_quant_itrans_iquant.h" 70 #include "ih264_inter_pred_filters.h" 71 #include "ih264_mem_fns.h" 72 #include "ih264_padding.h" 73 #include "ih264_intra_pred_filters.h" 74 #include "ih264_deblk_edge_filters.h" 75 #include "ih264_cabac_tables.h" 76 #include "irc_cntrl_param.h" 77 #include "irc_frame_info_collector.h" 78 #include "ih264e_rate_control.h" 79 #include "ih264e_cabac_structs.h" 80 #include "ih264e_structs.h" 81 #include "ih264_trans_data.h" 82 #include "ih264_deblk_tables.h" 83 #include "ih264e_deblk.h" 84 85 86 /*****************************************************************************/ 87 /* Extern global definitions */ 88 /*****************************************************************************/ 89 90 /** 91 ****************************************************************************** 92 * @brief BS Table Lookup 93 * input : 94 * output : 95 * @remarks none 96 ****************************************************************************** 97 */ 98 static const UWORD32 gu4_bs_table[][16] = 99 { 100 { 101 0x00000000, 0x02000000, 0x00020000, 0x02020000, 102 0x00000200, 0x02000200, 0x00020200, 0x02020200, 103 0x00000002, 0x02000002, 0x00020002, 0x02020002, 104 0x00000202, 0x02000202, 0x00020202, 0x02020202 105 }, 106 { 107 0x01010101, 0x02010101, 0x01020101, 0x02020101, 108 0x01010201, 0x02010201, 0x01020201, 0x02020201, 109 0x01010102, 0x02010102, 0x01020102, 0x02020102, 110 0x01010202, 0x02010202, 0x01020202, 0x02020202 111 } 112 }; 113 114 /** 115 ****************************************************************************** 116 * @brief Transpose Matrix used in BS 117 * input : 118 * output : 119 * @remarks none 120 ****************************************************************************** 121 */ 122 static const UWORD16 ih264e_gu2_4x4_v2h_reorder[16] = 123 { 124 0x0000, 0x0001, 0x0010, 0x0011, 125 0x0100, 0x0101, 0x0110, 0x0111, 126 0x1000, 0x1001, 0x1010, 0x1011, 127 0x1100, 0x1101, 0x1110, 0x1111 128 }; 129 130 131 /*****************************************************************************/ 132 /* Function Definitions */ 133 /*****************************************************************************/ 134 135 /** 136 ******************************************************************************* 137 * 138 * @brief Fill BS value for all the edges of an mb 139 * 140 * @par Description: 141 * Fill BS value for all the edges of an mb 142 * 143 * @param[in] pu4_horz_bs 144 * Base pointer of horizontal BS table 145 * 146 * @param[in] pu4_vert_bs 147 * Base pointer of vertical BS table 148 * 149 * @param[in] u4_left_mb_csbp 150 * coded sub block pattern of left mb 151 * 152 * @param[in] u4_left_mb_csbp 153 * coded sub block pattern of top mb 154 * 155 * @param[in] ps_left_pu 156 * PU for left MB 157 * 158 * @param[in] ps_top_pu 159 * PU for top MB 160 * 161 * @param[in] ps_curr_pu 162 * PU for current MB 163 * 164 * 165 * @returns none 166 * 167 * @remarks none 168 * 169 ******************************************************************************* 170 */ 171 static void ih264e_fill_bs_1mv_1ref_non_mbaff(UWORD32 *pu4_horz_bs, 172 UWORD32 *pu4_vert_bs, 173 UWORD32 u4_left_mb_csbp, 174 UWORD32 u4_top_mb_csbp, 175 UWORD32 u4_cur_mb_csbp, 176 enc_pu_t *ps_left_pu, 177 enc_pu_t *ps_top_pu, 178 enc_pu_t *ps_curr_pu) 179 { 180 /* motion vectors of blks p & q */ 181 WORD16 i16_qMvl0_x, i16_qMvl0_y, i16_pMvl0_x, i16_pMvl0_y; 182 WORD16 i16_qMvl1_x, i16_qMvl1_y, i16_pMvl1_x, i16_pMvl1_y; 183 184 /* temp var */ 185 UWORD32 u4_left_flag, u4_top_flag; 186 const UWORD32 *bs_map; 187 UWORD32 u4_reordered_vert_bs_enc, u4_temp; 188 189 /* Coded Pattern for Horizontal Edge */ 190 /*-----------------------------------------------------------------------*/ 191 /*u4_nbr_horz_csbp=11C|10C|9C|8C|7C|6C|5C|4C|3C|2C|1C|0C|15T|14T|13T|12T */ 192 /*-----------------------------------------------------------------------*/ 193 UWORD32 u4_nbr_horz_csbp = (u4_cur_mb_csbp << 4) | (u4_top_mb_csbp >> 12); 194 UWORD32 u4_horz_bs_enc = u4_cur_mb_csbp | u4_nbr_horz_csbp; 195 196 /* Coded Pattern for Vertical Edge */ 197 /*-----------------------------------------------------------------------*/ 198 /*u4_left_mb_masked_csbp = 15L|0|0|0|11L|0|0|0|7L|0|0|0|3L|0|0|0 */ 199 /*-----------------------------------------------------------------------*/ 200 UWORD32 u4_left_mb_masked_csbp = u4_left_mb_csbp & CSBP_RIGHT_BLOCK_MASK; 201 202 /*-----------------------------------------------------------------------*/ 203 /*u4_cur_mb_masked_csbp =14C|13C|12C|x|10C|9C|8C|x|6C|5C|4C|x|2C|1C|0C|x */ 204 /*-----------------------------------------------------------------------*/ 205 UWORD32 u4_cur_mb_masked_csbp = (u4_cur_mb_csbp << 1) 206 & (~CSBP_LEFT_BLOCK_MASK); 207 208 /*-----------------------------------------------------------------------*/ 209 /*u4_nbr_vert_csbp=14C|13C|12C|15L|10C|9C|8C|11L|6C|5C|4C|7L|2C|1C|0C|3L */ 210 /*-----------------------------------------------------------------------*/ 211 UWORD32 u4_nbr_vert_csbp = (u4_cur_mb_masked_csbp) 212 | (u4_left_mb_masked_csbp >> 3); 213 UWORD32 u4_vert_bs_enc = u4_cur_mb_csbp | u4_nbr_vert_csbp; 214 215 /* BS Calculation for MB Boundary Edges */ 216 217 /* BS calculation for 1 2 3 horizontal boundary */ 218 bs_map = gu4_bs_table[0]; 219 pu4_horz_bs[1] = bs_map[(u4_horz_bs_enc >> 4) & 0xF]; 220 pu4_horz_bs[2] = bs_map[(u4_horz_bs_enc >> 8) & 0xF]; 221 pu4_horz_bs[3] = bs_map[(u4_horz_bs_enc >> 12) & 0xF]; 222 223 /* BS calculation for 5 6 7 vertical boundary */ 224 /* Do 4x4 tranpose of u4_vert_bs_enc by using look up table for reorder */ 225 u4_reordered_vert_bs_enc = ih264e_gu2_4x4_v2h_reorder[u4_vert_bs_enc & 0xF]; 226 227 u4_temp = ih264e_gu2_4x4_v2h_reorder[(u4_vert_bs_enc >> 4) & 0xF]; 228 u4_reordered_vert_bs_enc |= (u4_temp << 1); 229 230 u4_temp = ih264e_gu2_4x4_v2h_reorder[(u4_vert_bs_enc >> 8) & 0xF]; 231 u4_reordered_vert_bs_enc |= (u4_temp << 2); 232 233 u4_temp = ih264e_gu2_4x4_v2h_reorder[(u4_vert_bs_enc >> 12) & 0xF]; 234 u4_reordered_vert_bs_enc |= (u4_temp << 3); 235 236 pu4_vert_bs[1] = bs_map[(u4_reordered_vert_bs_enc >> 4) & 0xF]; 237 pu4_vert_bs[2] = bs_map[(u4_reordered_vert_bs_enc >> 8) & 0xF]; 238 pu4_vert_bs[3] = bs_map[(u4_reordered_vert_bs_enc >> 12) & 0xF]; 239 240 241 /* BS Calculation for MB Boundary Edges */ 242 if (ps_top_pu->b1_intra_flag) 243 { 244 pu4_horz_bs[0] = 0x04040404; 245 } 246 else 247 { 248 if (ps_curr_pu->b2_pred_mode != ps_top_pu->b2_pred_mode) 249 { 250 u4_top_flag = 1; 251 } 252 else if(ps_curr_pu->b2_pred_mode != 2) 253 { 254 i16_pMvl0_x = ps_top_pu->s_me_info[ps_top_pu->b2_pred_mode].s_mv.i2_mvx; 255 i16_pMvl0_y = ps_top_pu->s_me_info[ps_top_pu->b2_pred_mode].s_mv.i2_mvy; 256 257 i16_qMvl0_x = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvx; 258 i16_qMvl0_y = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvy; 259 260 261 u4_top_flag = (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4) 262 | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4); 263 } 264 else 265 { 266 267 i16_pMvl0_x = ps_top_pu->s_me_info[PRED_L0].s_mv.i2_mvx; 268 i16_pMvl0_y = ps_top_pu->s_me_info[PRED_L0].s_mv.i2_mvy; 269 i16_pMvl1_x = ps_top_pu->s_me_info[PRED_L1].s_mv.i2_mvx; 270 i16_pMvl1_y = ps_top_pu->s_me_info[PRED_L1].s_mv.i2_mvy; 271 272 i16_qMvl0_x = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvx; 273 i16_qMvl0_y = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvy; 274 i16_qMvl1_x = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvx; 275 i16_qMvl1_y = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvy; 276 277 278 u4_top_flag = (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4) 279 | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4) 280 | (ABS((i16_pMvl1_x - i16_qMvl1_x)) >= 4) 281 | (ABS((i16_pMvl1_y - i16_qMvl1_y)) >= 4); 282 } 283 284 bs_map = gu4_bs_table[!!u4_top_flag]; 285 pu4_horz_bs[0] = bs_map[u4_horz_bs_enc & 0xF]; 286 } 287 288 289 if (ps_left_pu->b1_intra_flag) 290 { 291 pu4_vert_bs[0] = 0x04040404; 292 } 293 else 294 { 295 if (ps_curr_pu->b2_pred_mode != ps_left_pu->b2_pred_mode) 296 { 297 u4_left_flag = 1; 298 } 299 else if(ps_curr_pu->b2_pred_mode != 2)/* Not bipred */ 300 { 301 i16_pMvl0_x = ps_left_pu->s_me_info[ps_left_pu->b2_pred_mode].s_mv.i2_mvx; 302 i16_pMvl0_y = ps_left_pu->s_me_info[ps_left_pu->b2_pred_mode].s_mv.i2_mvy; 303 304 i16_qMvl0_x = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvx; 305 i16_qMvl0_y = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvy; 306 307 308 u4_left_flag = (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4) 309 | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4); 310 } 311 else 312 { 313 314 i16_pMvl0_x = ps_left_pu->s_me_info[PRED_L0].s_mv.i2_mvx; 315 i16_pMvl0_y = ps_left_pu->s_me_info[PRED_L0].s_mv.i2_mvy; 316 i16_pMvl1_x = ps_left_pu->s_me_info[PRED_L1].s_mv.i2_mvx; 317 i16_pMvl1_y = ps_left_pu->s_me_info[PRED_L1].s_mv.i2_mvy; 318 319 i16_qMvl0_x = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvx; 320 i16_qMvl0_y = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvy; 321 i16_qMvl1_x = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvx; 322 i16_qMvl1_y = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvy; 323 324 325 u4_left_flag = (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4) 326 | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4) 327 | (ABS((i16_pMvl1_x - i16_qMvl1_x)) >= 4) 328 | (ABS((i16_pMvl1_y - i16_qMvl1_y)) >= 4); 329 } 330 331 bs_map = gu4_bs_table[!!u4_left_flag]; 332 pu4_vert_bs[0] = bs_map[u4_reordered_vert_bs_enc & 0xF]; 333 } 334 } 335 336 /** 337 ******************************************************************************* 338 * 339 * @brief calculate coded subblock pattern from nnz 340 * 341 * @par Description: 342 * calculate coded subblock pattern from nnz 343 * 344 * @param[in] ps_proc 345 * process context 346 * 347 * @returns csbp 348 * 349 * @remarks none 350 * 351 ******************************************************************************* 352 */ 353 static UWORD32 ih264e_calculate_csbp(process_ctxt_t *ps_proc) 354 { 355 /* number of non zeros for each tx blk */ 356 UWORD8 *pu1_curr_nnz = (UWORD8 *)ps_proc->au4_nnz; 357 358 /* csbp */ 359 UWORD32 u4_csbp = 0; 360 361 /* temp var */ 362 WORD32 i4_i; 363 364 pu1_curr_nnz += 1; 365 366 /* Creating Subblock pattern for current MB */ 367 /* 15C|14C|13C|12C|11C|10C|9C|8C|7C|6C|5C|4C|3C|2C|1C|0C */ 368 for (i4_i = 0; i4_i < 16; i4_i++ ) 369 { 370 u4_csbp |= ((!!*(pu1_curr_nnz + i4_i))<< i4_i); 371 } 372 373 return u4_csbp; 374 } 375 376 /** 377 ******************************************************************************* 378 * 379 * @brief This function computes blocking strength for an mb 380 * 381 * @par Description: 382 * This function computes blocking strength for an mb 383 * 384 * @param[in] ps_proc 385 * process context 386 * 387 * @returns none 388 * 389 * @remarks 390 * 391 ******************************************************************************* 392 */ 393 void ih264e_compute_bs(process_ctxt_t * ps_proc) 394 { 395 /* deblk bs context */ 396 bs_ctxt_t *ps_bs = &(ps_proc->s_deblk_ctxt.s_bs_ctxt); 397 398 /* vertical blocking strength */ 399 UWORD32 *pu4_pic_vert_bs; 400 401 /* horizontal blocking strength */ 402 UWORD32 *pu4_pic_horz_bs; 403 404 /* mb indices */ 405 WORD32 i4_mb_x, i4_mb_y; 406 407 /* is intra */ 408 WORD32 i4_intra; 409 410 /* temp var */ 411 WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs; 412 413 /* init indices */ 414 i4_mb_x = ps_bs->i4_mb_x; 415 i4_mb_y = ps_bs->i4_mb_y; 416 417 /* init pointers */ 418 pu4_pic_vert_bs = ps_bs->pu4_pic_vert_bs + ((i4_mb_y * i4_wd_mbs) + i4_mb_x) * 4; 419 pu4_pic_horz_bs = ps_bs->pu4_pic_horz_bs + ((i4_mb_y * i4_wd_mbs) + i4_mb_x) * 4; 420 421 /* is intra? */ 422 i4_intra = ps_proc->u4_is_intra; 423 424 /* compute blocking strength */ 425 if (i4_intra) 426 { 427 pu4_pic_vert_bs[0] = 0x04040404; 428 pu4_pic_vert_bs[1] = pu4_pic_vert_bs[2] = pu4_pic_vert_bs[3] = 0x03030303; 429 430 pu4_pic_horz_bs[0] = 0x04040404; 431 pu4_pic_horz_bs[1] = pu4_pic_horz_bs[2] = pu4_pic_horz_bs[3] = 0x03030303; 432 } 433 else 434 { 435 /* left mb syntax info */ 436 mb_info_t *ps_left_mb_syntax_ele = &ps_proc->s_left_mb_syntax_ele; 437 438 /* top mb syntax info */ 439 mb_info_t *ps_top_mb_syntax_ele = ps_proc->ps_top_row_mb_syntax_ele + i4_mb_x; 440 441 /* top row motion vector info */ 442 enc_pu_t *ps_top_row_pu = ps_proc->ps_top_row_pu + i4_mb_x; 443 444 /* csbp for curr mb */ 445 ps_proc->u4_csbp = ih264e_calculate_csbp(ps_proc); 446 447 /* csbp for ngbrs */ 448 if (i4_mb_x == 0) 449 { 450 ps_left_mb_syntax_ele->u4_csbp = 0; 451 ps_proc->s_left_mb_pu.b1_intra_flag = 0; 452 ps_proc->s_left_mb_pu.b2_pred_mode = ps_proc->ps_pu->b2_pred_mode; 453 ps_proc->s_left_mb_pu.s_me_info[0].s_mv = ps_proc->ps_pu->s_me_info[0].s_mv; 454 ps_proc->s_left_mb_pu.s_me_info[1].s_mv = ps_proc->ps_pu->s_me_info[1].s_mv; 455 } 456 if (i4_mb_y == 0) 457 { 458 ps_top_mb_syntax_ele->u4_csbp = 0; 459 ps_top_row_pu->b1_intra_flag = 0; 460 ps_top_row_pu->b2_pred_mode = ps_proc->ps_pu->b2_pred_mode; 461 ps_top_row_pu->s_me_info[0].s_mv = ps_proc->ps_pu->s_me_info[0].s_mv; 462 ps_top_row_pu->s_me_info[1].s_mv = ps_proc->ps_pu->s_me_info[1].s_mv; 463 } 464 465 ih264e_fill_bs_1mv_1ref_non_mbaff(pu4_pic_horz_bs, 466 pu4_pic_vert_bs, 467 ps_left_mb_syntax_ele->u4_csbp, 468 ps_top_mb_syntax_ele->u4_csbp, 469 ps_proc->u4_csbp, 470 &ps_proc->s_left_mb_pu, 471 ps_top_row_pu, 472 ps_proc->ps_pu); 473 } 474 475 return ; 476 } 477 478 /** 479 ******************************************************************************* 480 * 481 * @brief This function performs deblocking of top horizontal edge 482 * 483 * @par Description: 484 * This function performs deblocking of top horizontal edge 485 * 486 * @param[in] ps_codec 487 * pointer to codec context 488 * 489 * @param[in] ps_proc 490 * pointer to proc context 491 * 492 * @param[in] pu1_mb_qp 493 * pointer to mb quantization param 494 * 495 * @param[in] pu1_cur_pic_luma 496 * pointer to recon buffer luma 497 * 498 * @param[in] pu1_cur_pic_chroma 499 * pointer to recon buffer chroma 500 * 501 * @param[in] pu4_pic_horz_bs 502 * pointer to horizontal blocking strength 503 * 504 * @returns none 505 * 506 * @remarks none 507 * 508 ******************************************************************************* 509 */ 510 static void ih264e_filter_top_edge(codec_t *ps_codec, 511 process_ctxt_t *ps_proc, 512 UWORD8 *pu1_mb_qp, 513 UWORD8 *pu1_cur_pic_luma, 514 UWORD8 *pu1_cur_pic_chroma, 515 UWORD32 *pu4_pic_horz_bs) 516 { 517 /* strd */ 518 WORD32 i4_rec_strd = ps_proc->i4_rec_strd; 519 520 /* deblk params */ 521 UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma, u4_qp_p, u4_qp_q; 522 UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma; 523 524 /* collect qp of left & top mb */ 525 u4_qp_p = pu1_mb_qp[-ps_proc->i4_wd_mbs]; 526 u4_qp_q = pu1_mb_qp[0]; 527 528 /********/ 529 /* luma */ 530 /********/ 531 u4_qp_luma = (u4_qp_p + u4_qp_q + 1) >> 1; 532 533 /* filter offset A and filter offset B have to be received from slice header */ 534 /* TODO : for now lets set these offsets as zero */ 535 536 537 u4_idx_A_luma = MIN(51, u4_qp_luma + 0); 538 u4_idx_B_luma = MIN(51, u4_qp_luma + 0); 539 540 /* alpha, beta computation */ 541 u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma]; 542 u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma]; 543 544 /**********/ 545 /* chroma */ 546 /**********/ 547 u4_qp_chroma = (gu1_qpc_fqpi[u4_qp_p] + gu1_qpc_fqpi[u4_qp_q] + 1) >> 1; 548 549 /* filter offset A and filter offset B have to be received from slice header */ 550 /* TODO : for now lets set these offsets as zero */ 551 552 553 u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0); 554 u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0); 555 556 /* alpha, beta computation */ 557 u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma]; 558 u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma]; 559 560 /* deblk edge */ 561 /* top Horizontal edge - allowed to be deblocked ? */ 562 if (pu4_pic_horz_bs[0] == 0x04040404) 563 { 564 /* strong filter */ 565 ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 566 ps_codec->pf_deblk_chroma_horz_bs4(pu1_cur_pic_chroma, i4_rec_strd, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma); 567 } 568 else 569 { 570 /* normal filter */ 571 ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma, i4_rec_strd, u4_alpha_luma, 572 u4_beta_luma, pu4_pic_horz_bs[0], 573 gu1_ih264_clip_table[u4_idx_A_luma]); 574 575 ps_codec->pf_deblk_chroma_horz_bslt4(pu1_cur_pic_chroma, i4_rec_strd, u4_alpha_chroma, 576 u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_horz_bs[0], 577 gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]); 578 } 579 } 580 581 /** 582 ******************************************************************************* 583 * 584 * @brief This function performs deblocking of left vertical edge 585 * 586 * @par Description: 587 * This function performs deblocking of top horizontal edge 588 * 589 * @param[in] ps_codec 590 * pointer to codec context 591 * 592 * @param[in] ps_proc 593 * pointer to proc context 594 * 595 * @param[in] pu1_mb_qp 596 * pointer to mb quantization param 597 * 598 * @param[in] pu1_cur_pic_luma 599 * pointer to recon buffer luma 600 * 601 * @param[in] pu1_cur_pic_chroma 602 * pointer to recon buffer chroma 603 * 604 * @param[in] pu4_pic_vert_bs 605 * pointer to vertical blocking strength 606 * 607 * @returns none 608 * 609 * @remarks none 610 * 611 ******************************************************************************* 612 */ 613 static void ih264e_filter_left_edge(codec_t *ps_codec, 614 process_ctxt_t *ps_proc, 615 UWORD8 *pu1_mb_qp, 616 UWORD8 *pu1_cur_pic_luma, 617 UWORD8 *pu1_cur_pic_chroma, 618 UWORD32 *pu4_pic_vert_bs) 619 { 620 /* strd */ 621 WORD32 i4_rec_strd = ps_proc->i4_rec_strd; 622 623 /* deblk params */ 624 UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma, u4_qp_p, u4_qp_q; 625 UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma; 626 627 /* collect qp of left & curr mb */ 628 u4_qp_p = pu1_mb_qp[-1]; 629 u4_qp_q = pu1_mb_qp[0]; 630 631 /********/ 632 /* luma */ 633 /********/ 634 u4_qp_luma = (u4_qp_p + u4_qp_q + 1) >> 1; 635 636 /* filter offset A and filter offset B have to be received from slice header */ 637 /* TODO : for now lets set these offsets as zero */ 638 639 640 u4_idx_A_luma = MIN(51, u4_qp_luma + 0); 641 u4_idx_B_luma = MIN(51, u4_qp_luma + 0); 642 643 /* alpha, beta computation */ 644 u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma]; 645 u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma]; 646 647 /**********/ 648 /* chroma */ 649 /**********/ 650 u4_qp_chroma = (gu1_qpc_fqpi[u4_qp_p] + gu1_qpc_fqpi[u4_qp_q] + 1) >> 1; 651 652 /* filter offset A and filter offset B have to be received from slice header */ 653 /* TODO : for now lets set these offsets as zero */ 654 655 656 u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0); 657 u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0); 658 659 /* alpha, beta computation */ 660 u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma]; 661 u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma]; 662 663 /* deblk edge */ 664 if (pu4_pic_vert_bs[0] == 0x04040404) 665 { 666 /* strong filter */ 667 ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 668 ps_codec->pf_deblk_chroma_vert_bs4(pu1_cur_pic_chroma, i4_rec_strd, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma); 669 } 670 else 671 { 672 /* normal filter */ 673 ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma, i4_rec_strd, 674 u4_alpha_luma, u4_beta_luma, 675 pu4_pic_vert_bs[0], 676 gu1_ih264_clip_table[u4_idx_A_luma]); 677 678 ps_codec->pf_deblk_chroma_vert_bslt4(pu1_cur_pic_chroma, i4_rec_strd, u4_alpha_chroma, 679 u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_vert_bs[0], 680 gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]); 681 } 682 } 683 684 /** 685 ******************************************************************************* 686 * 687 * @brief This function performs deblocking on an mb 688 * 689 * @par Description: 690 * This function performs deblocking on an mb 691 * 692 * @param[in] ps_proc 693 * process context corresponding to the job 694 * 695 * @param[in] ps_deblk 696 * pointer to deblock context 697 * 698 * @returns none 699 * 700 * @remarks none 701 * 702 ******************************************************************************* 703 */ 704 void ih264e_deblock_mb(process_ctxt_t *ps_proc, deblk_ctxt_t * ps_deblk) 705 { 706 /* codec ctxt */ 707 codec_t *ps_codec = ps_proc->ps_codec; 708 709 /* ngbr availability */ 710 UWORD8 u1_mb_a, u1_mb_b; 711 712 /* mb indices */ 713 WORD32 i4_mb_x = ps_deblk->i4_mb_x, i4_mb_y = ps_deblk->i4_mb_y; 714 715 /* pic qp ptr */ 716 UWORD8 *pu1_pic_qp = ps_deblk->s_bs_ctxt.pu1_pic_qp; 717 718 /* vertical blocking strength */ 719 UWORD32 *pu4_pic_vert_bs = ps_deblk->s_bs_ctxt.pu4_pic_vert_bs; 720 721 /* horizontal blocking strength */ 722 UWORD32 *pu4_pic_horz_bs = ps_deblk->s_bs_ctxt.pu4_pic_horz_bs; 723 724 /* src buffers luma */ 725 UWORD8 *pu1_cur_pic_luma = ps_deblk->pu1_cur_pic_luma; 726 727 /* src buffers chroma */ 728 UWORD8 *pu1_cur_pic_chroma = ps_deblk->pu1_cur_pic_chroma; 729 730 /* strd */ 731 WORD32 i4_rec_strd = ps_proc->i4_rec_strd; 732 733 /* deblk params */ 734 UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma; 735 UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma; 736 737 /* temp var */ 738 UWORD32 push_ptr = (i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x; 739 740 /* derive neighbor availability */ 741 /* In slice mode the edges of mbs that lie on the slice boundary are not deblocked */ 742 /* deblocking filter idc '2' */ 743 if (ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE) 744 { 745 /* slice index */ 746 UWORD8 *pu1_slice_idx = ps_deblk->pu1_slice_idx; 747 748 pu1_slice_idx += (i4_mb_y * ps_proc->i4_wd_mbs); 749 /* left macroblock availability */ 750 u1_mb_a = (i4_mb_x == 0 || 751 (pu1_slice_idx[i4_mb_x - 1 ] != pu1_slice_idx[i4_mb_x]))? 0 : 1; 752 /* top macroblock availability */ 753 u1_mb_b = (i4_mb_y == 0 || 754 (pu1_slice_idx[i4_mb_x-ps_proc->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))? 0 : 1; 755 } 756 else 757 { 758 /* left macroblock availability */ 759 u1_mb_a = (i4_mb_x == 0)? 0 : 1; 760 /* top macroblock availability */ 761 u1_mb_b = (i4_mb_y == 0)? 0 : 1; 762 } 763 764 pu1_pic_qp += push_ptr; 765 pu4_pic_vert_bs += push_ptr * 4; 766 pu4_pic_horz_bs += push_ptr * 4; 767 768 /********/ 769 /* luma */ 770 /********/ 771 u4_qp_luma = pu1_pic_qp[0]; 772 773 /* filter offset A and filter offset B have to be received from slice header */ 774 /* TODO : for now lets set these offsets as zero */ 775 776 777 u4_idx_A_luma = MIN(51, u4_qp_luma + 0); 778 u4_idx_B_luma = MIN(51, u4_qp_luma + 0); 779 780 /* alpha, beta computation */ 781 u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma]; 782 u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma]; 783 784 /**********/ 785 /* chroma */ 786 /**********/ 787 u4_qp_chroma = gu1_qpc_fqpi[u4_qp_luma]; 788 789 /* filter offset A and filter offset B have to be received from slice header */ 790 /* TODO : for now lets set these offsets as zero */ 791 792 793 u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0); 794 u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0); 795 796 /* alpha, beta computation */ 797 u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma]; 798 u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma]; 799 800 /* Deblock vertical edges */ 801 /* left vertical edge 0 - allowed to be deblocked ? */ 802 if (u1_mb_a) 803 { 804 ih264e_filter_left_edge(ps_codec, ps_proc, pu1_pic_qp, pu1_cur_pic_luma, pu1_cur_pic_chroma, pu4_pic_vert_bs); 805 } 806 807 /* vertical edge 1 */ 808 if (pu4_pic_vert_bs[1] == 0x04040404) 809 { 810 /* strong filter */ 811 ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 4, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 812 } 813 else 814 { 815 /* normal filter */ 816 ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 4, i4_rec_strd, 817 u4_alpha_luma, u4_beta_luma, 818 pu4_pic_vert_bs[1], 819 gu1_ih264_clip_table[u4_idx_A_luma]); 820 } 821 822 /* vertical edge 2 */ 823 if (pu4_pic_vert_bs[2] == 0x04040404) 824 { 825 /* strong filter */ 826 ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 8, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 827 ps_codec->pf_deblk_chroma_vert_bs4(pu1_cur_pic_chroma + 8, i4_rec_strd, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma); 828 } 829 else 830 { 831 /* normal filter */ 832 ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 8, i4_rec_strd, u4_alpha_luma, 833 u4_beta_luma, pu4_pic_vert_bs[2], 834 gu1_ih264_clip_table[u4_idx_A_luma]); 835 836 ps_codec->pf_deblk_chroma_vert_bslt4(pu1_cur_pic_chroma + 8, i4_rec_strd, u4_alpha_chroma, 837 u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_vert_bs[2], 838 gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]); 839 } 840 841 /* vertical edge 3 */ 842 if (pu4_pic_vert_bs[3] == 0x04040404) 843 { 844 /* strong filter */ 845 ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 12, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 846 } 847 else 848 { 849 /* normal filter */ 850 ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 12, i4_rec_strd, u4_alpha_luma, 851 u4_beta_luma, pu4_pic_vert_bs[3], 852 gu1_ih264_clip_table[u4_idx_A_luma]); 853 } 854 855 /* Deblock Horizontal edges */ 856 /* Horizontal edge 0 */ 857 if (u1_mb_b) 858 { 859 ih264e_filter_top_edge(ps_codec, ps_proc, pu1_pic_qp, pu1_cur_pic_luma, pu1_cur_pic_chroma, pu4_pic_horz_bs); 860 } 861 862 /* horizontal edge 1 */ 863 if (pu4_pic_horz_bs[1] == 0x04040404) 864 { 865 /* strong filter */ 866 ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 4 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 867 } 868 else 869 { 870 /* normal filter */ 871 ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 4 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, 872 u4_beta_luma, pu4_pic_horz_bs[1], 873 gu1_ih264_clip_table[u4_idx_A_luma]); 874 } 875 876 /* horizontal edge 2 */ 877 if (pu4_pic_horz_bs[2] == 0x04040404) 878 { 879 /* strong filter */ 880 ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 8 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 881 ps_codec->pf_deblk_chroma_horz_bs4(pu1_cur_pic_chroma + 4 * i4_rec_strd, i4_rec_strd, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma); 882 } 883 else 884 { 885 /* normal filter */ 886 ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 8 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, 887 u4_beta_luma, pu4_pic_horz_bs[2], 888 gu1_ih264_clip_table[u4_idx_A_luma]); 889 890 ps_codec->pf_deblk_chroma_horz_bslt4(pu1_cur_pic_chroma + 4 * i4_rec_strd, i4_rec_strd, u4_alpha_chroma, 891 u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_horz_bs[2], 892 gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]); 893 } 894 895 /* horizontal edge 3 */ 896 if (pu4_pic_horz_bs[3] == 0x04040404) 897 { 898 /* strong filter */ 899 ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 12 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, u4_beta_luma); 900 } 901 else 902 { 903 /* normal filter */ 904 ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 12 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, 905 u4_beta_luma, pu4_pic_horz_bs[3], 906 gu1_ih264_clip_table[u4_idx_A_luma]); 907 } 908 909 return ; 910 } 911