Home | History | Annotate | Download | only in common
      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