C++程序  |  911行  |  30.67 KB

/******************************************************************************
 *
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/

/**
 *******************************************************************************
 * @file
 *  ih264e_deblk.c
 *
 * @brief
 *  This file contains functions that are associated with deblocking
 *
 * @author
 *  ittiam
 *
 * @par List of Functions:
 *  - ih264e_fill_bs_1mv_1ref_non_mbaff
 *  - ih264e_calculate_csbp
 *  - ih264e_compute_bs
 *  - ih264e_filter_top_edge
 *  - ih264e_filter_left_edge
 *  - ih264e_deblock_mb
 *
 * @remarks
 *  None
 *
 *******************************************************************************
 */

/*****************************************************************************/
/* File Includes                                                             */
/*****************************************************************************/

/* System include files */
#include <stdio.h>
#include <string.h>
#include <assert.h>

/* User include files */
#include "ih264e_config.h"
#include "ih264_typedefs.h"
#include "iv2.h"
#include "ive2.h"
#include "ih264_macros.h"
#include "ih264_defs.h"
#include "ih264e_defs.h"
#include "ih264e_error.h"
#include "ih264e_bitstream.h"
#include "ime_distortion_metrics.h"
#include "ime_defs.h"
#include "ime_structs.h"
#include "ih264_structs.h"
#include "ih264_trans_quant_itrans_iquant.h"
#include "ih264_inter_pred_filters.h"
#include "ih264_mem_fns.h"
#include "ih264_padding.h"
#include "ih264_intra_pred_filters.h"
#include "ih264_deblk_edge_filters.h"
#include "ih264_cabac_tables.h"
#include "irc_cntrl_param.h"
#include "irc_frame_info_collector.h"
#include "ih264e_rate_control.h"
#include "ih264e_cabac_structs.h"
#include "ih264e_structs.h"
#include "ih264_trans_data.h"
#include "ih264_deblk_tables.h"
#include "ih264e_deblk.h"


/*****************************************************************************/
/* Extern global definitions                                                 */
/*****************************************************************************/

/**
******************************************************************************
* @brief  BS Table Lookup
* input  :
* output :
* @remarks none
******************************************************************************
*/
static const UWORD32 gu4_bs_table[][16] =
{
    {
        0x00000000, 0x02000000, 0x00020000, 0x02020000,
        0x00000200, 0x02000200, 0x00020200, 0x02020200,
        0x00000002, 0x02000002, 0x00020002, 0x02020002,
        0x00000202, 0x02000202, 0x00020202, 0x02020202
    },
    {
        0x01010101, 0x02010101, 0x01020101, 0x02020101,
        0x01010201, 0x02010201, 0x01020201, 0x02020201,
        0x01010102, 0x02010102, 0x01020102, 0x02020102,
        0x01010202, 0x02010202, 0x01020202, 0x02020202
    }
};

/**
******************************************************************************
* @brief  Transpose Matrix used in BS
* input  :
* output :
* @remarks none
******************************************************************************
*/
static const UWORD16  ih264e_gu2_4x4_v2h_reorder[16] =
{
    0x0000, 0x0001, 0x0010, 0x0011,
    0x0100, 0x0101, 0x0110, 0x0111,
    0x1000, 0x1001, 0x1010, 0x1011,
    0x1100, 0x1101, 0x1110, 0x1111
};


/*****************************************************************************/
/* Function Definitions                                                      */
/*****************************************************************************/

/**
*******************************************************************************
*
* @brief Fill BS value for all the edges of an mb
*
* @par Description:
*  Fill BS value for all the edges of an mb
*
* @param[in] pu4_horz_bs
*  Base pointer of horizontal BS table
*
* @param[in] pu4_vert_bs
*  Base pointer of vertical BS table
*
* @param[in] u4_left_mb_csbp
*  coded sub block pattern of left mb
*
* @param[in] u4_left_mb_csbp
*  coded sub block pattern of top mb
*
* @param[in] ps_left_pu
*  PU for left MB
*
* @param[in] ps_top_pu
*  PU for top MB
*
* @param[in] ps_curr_pu
*  PU for current MB
*
*
* @returns  none
*
* @remarks  none
*
*******************************************************************************
*/
static void ih264e_fill_bs_1mv_1ref_non_mbaff(UWORD32 *pu4_horz_bs,
                                              UWORD32 *pu4_vert_bs,
                                              UWORD32 u4_left_mb_csbp,
                                              UWORD32 u4_top_mb_csbp,
                                              UWORD32 u4_cur_mb_csbp,
                                              enc_pu_t *ps_left_pu,
                                              enc_pu_t *ps_top_pu,
                                              enc_pu_t *ps_curr_pu)
{
    /* motion vectors of blks p & q */
    WORD16 i16_qMvl0_x, i16_qMvl0_y, i16_pMvl0_x, i16_pMvl0_y;
    WORD16 i16_qMvl1_x, i16_qMvl1_y, i16_pMvl1_x, i16_pMvl1_y;

    /* temp var */
    UWORD32 u4_left_flag, u4_top_flag;
    const UWORD32 *bs_map;
    UWORD32 u4_reordered_vert_bs_enc, u4_temp;

    /* Coded Pattern for Horizontal Edge */
    /*-----------------------------------------------------------------------*/
    /*u4_nbr_horz_csbp=11C|10C|9C|8C|7C|6C|5C|4C|3C|2C|1C|0C|15T|14T|13T|12T */
    /*-----------------------------------------------------------------------*/
    UWORD32 u4_nbr_horz_csbp = (u4_cur_mb_csbp << 4) | (u4_top_mb_csbp >> 12);
    UWORD32 u4_horz_bs_enc = u4_cur_mb_csbp | u4_nbr_horz_csbp;

    /* Coded Pattern for Vertical Edge */
    /*-----------------------------------------------------------------------*/
    /*u4_left_mb_masked_csbp = 15L|0|0|0|11L|0|0|0|7L|0|0|0|3L|0|0|0         */
    /*-----------------------------------------------------------------------*/
    UWORD32 u4_left_mb_masked_csbp = u4_left_mb_csbp & CSBP_RIGHT_BLOCK_MASK;

    /*-----------------------------------------------------------------------*/
    /*u4_cur_mb_masked_csbp =14C|13C|12C|x|10C|9C|8C|x|6C|5C|4C|x|2C|1C|0C|x */
    /*-----------------------------------------------------------------------*/
    UWORD32 u4_cur_mb_masked_csbp = (u4_cur_mb_csbp << 1)
                    & (~CSBP_LEFT_BLOCK_MASK);

    /*-----------------------------------------------------------------------*/
    /*u4_nbr_vert_csbp=14C|13C|12C|15L|10C|9C|8C|11L|6C|5C|4C|7L|2C|1C|0C|3L */
    /*-----------------------------------------------------------------------*/
    UWORD32 u4_nbr_vert_csbp = (u4_cur_mb_masked_csbp)
                    | (u4_left_mb_masked_csbp >> 3);
    UWORD32 u4_vert_bs_enc = u4_cur_mb_csbp | u4_nbr_vert_csbp;

    /* BS Calculation for MB Boundary Edges */

    /* BS calculation for 1 2 3 horizontal boundary */
    bs_map = gu4_bs_table[0];
    pu4_horz_bs[1] = bs_map[(u4_horz_bs_enc >> 4) & 0xF];
    pu4_horz_bs[2] = bs_map[(u4_horz_bs_enc >> 8) & 0xF];
    pu4_horz_bs[3] = bs_map[(u4_horz_bs_enc >> 12) & 0xF];

    /* BS calculation for 5 6 7 vertical boundary */
    /* Do 4x4 tranpose of u4_vert_bs_enc by using look up table for reorder */
    u4_reordered_vert_bs_enc = ih264e_gu2_4x4_v2h_reorder[u4_vert_bs_enc & 0xF];

    u4_temp = ih264e_gu2_4x4_v2h_reorder[(u4_vert_bs_enc >> 4) & 0xF];
    u4_reordered_vert_bs_enc |= (u4_temp << 1);

    u4_temp = ih264e_gu2_4x4_v2h_reorder[(u4_vert_bs_enc >> 8) & 0xF];
    u4_reordered_vert_bs_enc |= (u4_temp << 2);

    u4_temp = ih264e_gu2_4x4_v2h_reorder[(u4_vert_bs_enc >> 12) & 0xF];
    u4_reordered_vert_bs_enc |= (u4_temp << 3);

    pu4_vert_bs[1] = bs_map[(u4_reordered_vert_bs_enc >> 4) & 0xF];
    pu4_vert_bs[2] = bs_map[(u4_reordered_vert_bs_enc >> 8) & 0xF];
    pu4_vert_bs[3] = bs_map[(u4_reordered_vert_bs_enc >> 12) & 0xF];


    /* BS Calculation for MB Boundary Edges */
    if (ps_top_pu->b1_intra_flag)
    {
        pu4_horz_bs[0] = 0x04040404;
    }
    else
    {
        if (ps_curr_pu->b2_pred_mode != ps_top_pu->b2_pred_mode)
        {
            u4_top_flag = 1;
        }
        else if(ps_curr_pu->b2_pred_mode != 2)
        {
            i16_pMvl0_x = ps_top_pu->s_me_info[ps_top_pu->b2_pred_mode].s_mv.i2_mvx;
            i16_pMvl0_y = ps_top_pu->s_me_info[ps_top_pu->b2_pred_mode].s_mv.i2_mvy;

            i16_qMvl0_x = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvx;
            i16_qMvl0_y = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvy;


            u4_top_flag =  (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4)
                         | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4);
        }
        else
        {

            i16_pMvl0_x = ps_top_pu->s_me_info[PRED_L0].s_mv.i2_mvx;
            i16_pMvl0_y = ps_top_pu->s_me_info[PRED_L0].s_mv.i2_mvy;
            i16_pMvl1_x = ps_top_pu->s_me_info[PRED_L1].s_mv.i2_mvx;
            i16_pMvl1_y = ps_top_pu->s_me_info[PRED_L1].s_mv.i2_mvy;

            i16_qMvl0_x = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvx;
            i16_qMvl0_y = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvy;
            i16_qMvl1_x = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvx;
            i16_qMvl1_y = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvy;


            u4_top_flag =  (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4)
                         | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4)
                         | (ABS((i16_pMvl1_x - i16_qMvl1_x)) >= 4)
                         | (ABS((i16_pMvl1_y - i16_qMvl1_y)) >= 4);
        }

        bs_map = gu4_bs_table[!!u4_top_flag];
        pu4_horz_bs[0] = bs_map[u4_horz_bs_enc & 0xF];
    }


    if (ps_left_pu->b1_intra_flag)
    {
        pu4_vert_bs[0] = 0x04040404;
    }
    else
    {
        if (ps_curr_pu->b2_pred_mode != ps_left_pu->b2_pred_mode)
        {
            u4_left_flag = 1;
        }
        else if(ps_curr_pu->b2_pred_mode != 2)/* Not bipred */
        {
            i16_pMvl0_x = ps_left_pu->s_me_info[ps_left_pu->b2_pred_mode].s_mv.i2_mvx;
            i16_pMvl0_y = ps_left_pu->s_me_info[ps_left_pu->b2_pred_mode].s_mv.i2_mvy;

            i16_qMvl0_x = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvx;
            i16_qMvl0_y = ps_curr_pu->s_me_info[ps_curr_pu->b2_pred_mode].s_mv.i2_mvy;


            u4_left_flag =  (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4)
                          | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4);
        }
        else
        {

            i16_pMvl0_x = ps_left_pu->s_me_info[PRED_L0].s_mv.i2_mvx;
            i16_pMvl0_y = ps_left_pu->s_me_info[PRED_L0].s_mv.i2_mvy;
            i16_pMvl1_x = ps_left_pu->s_me_info[PRED_L1].s_mv.i2_mvx;
            i16_pMvl1_y = ps_left_pu->s_me_info[PRED_L1].s_mv.i2_mvy;

            i16_qMvl0_x = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvx;
            i16_qMvl0_y = ps_curr_pu->s_me_info[PRED_L0].s_mv.i2_mvy;
            i16_qMvl1_x = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvx;
            i16_qMvl1_y = ps_curr_pu->s_me_info[PRED_L1].s_mv.i2_mvy;


            u4_left_flag =  (ABS((i16_pMvl0_x - i16_qMvl0_x)) >= 4)
                          | (ABS((i16_pMvl0_y - i16_qMvl0_y)) >= 4)
                          | (ABS((i16_pMvl1_x - i16_qMvl1_x)) >= 4)
                          | (ABS((i16_pMvl1_y - i16_qMvl1_y)) >= 4);
        }

        bs_map = gu4_bs_table[!!u4_left_flag];
        pu4_vert_bs[0] = bs_map[u4_reordered_vert_bs_enc & 0xF];
    }
}

/**
*******************************************************************************
*
* @brief calculate coded subblock pattern from nnz
*
* @par Description:
*  calculate coded subblock pattern from nnz
*
* @param[in] ps_proc
*  process context
*
* @returns  csbp
*
* @remarks  none
*
*******************************************************************************
*/
static UWORD32 ih264e_calculate_csbp(process_ctxt_t *ps_proc)
{
    /* number of non zeros for each tx blk */
    UWORD8 *pu1_curr_nnz = (UWORD8 *)ps_proc->au4_nnz;

    /* csbp */
    UWORD32 u4_csbp = 0;

    /* temp var */
    WORD32  i4_i;

    pu1_curr_nnz += 1;

    /* Creating Subblock pattern for current MB */
    /* 15C|14C|13C|12C|11C|10C|9C|8C|7C|6C|5C|4C|3C|2C|1C|0C  */
    for (i4_i = 0; i4_i < 16; i4_i++ )
    {
        u4_csbp |= ((!!*(pu1_curr_nnz + i4_i))<< i4_i);
    }

    return u4_csbp;
}

/**
*******************************************************************************
*
* @brief This function computes blocking strength for an mb
*
* @par Description:
*  This function computes blocking strength for an mb
*
* @param[in] ps_proc
*  process context
*
* @returns  none
*
* @remarks
*
*******************************************************************************
*/
void ih264e_compute_bs(process_ctxt_t * ps_proc)
{
    /* deblk bs context */
    bs_ctxt_t *ps_bs = &(ps_proc->s_deblk_ctxt.s_bs_ctxt);

    /* vertical blocking strength */
    UWORD32 *pu4_pic_vert_bs;

    /* horizontal blocking strength */
    UWORD32 *pu4_pic_horz_bs;

    /* mb indices */
    WORD32 i4_mb_x, i4_mb_y;

    /* is intra */
    WORD32 i4_intra;

    /* temp var */
    WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;

    /* init indices */
    i4_mb_x = ps_bs->i4_mb_x;
    i4_mb_y = ps_bs->i4_mb_y;

    /* init pointers */
    pu4_pic_vert_bs = ps_bs->pu4_pic_vert_bs + ((i4_mb_y * i4_wd_mbs) + i4_mb_x) * 4;
    pu4_pic_horz_bs = ps_bs->pu4_pic_horz_bs + ((i4_mb_y * i4_wd_mbs) + i4_mb_x) * 4;

    /* is intra? */
    i4_intra = ps_proc->u4_is_intra;

    /* compute blocking strength */
    if (i4_intra)
    {
        pu4_pic_vert_bs[0] = 0x04040404;
        pu4_pic_vert_bs[1] = pu4_pic_vert_bs[2] = pu4_pic_vert_bs[3] = 0x03030303;

        pu4_pic_horz_bs[0] = 0x04040404;
        pu4_pic_horz_bs[1] = pu4_pic_horz_bs[2] = pu4_pic_horz_bs[3] = 0x03030303;
    }
    else
    {
        /* left mb syntax info */
        mb_info_t *ps_left_mb_syntax_ele = &ps_proc->s_left_mb_syntax_ele;

        /* top mb syntax info */
        mb_info_t *ps_top_mb_syntax_ele = ps_proc->ps_top_row_mb_syntax_ele + i4_mb_x;

        /* top row motion vector info */
        enc_pu_t *ps_top_row_pu = ps_proc->ps_top_row_pu + i4_mb_x;

        /* csbp for curr mb */
        ps_proc->u4_csbp = ih264e_calculate_csbp(ps_proc);

        /* csbp for ngbrs */
        if (i4_mb_x == 0)
        {
            ps_left_mb_syntax_ele->u4_csbp = 0;
            ps_proc->s_left_mb_pu.b1_intra_flag = 0;
            ps_proc->s_left_mb_pu.b2_pred_mode = ps_proc->ps_pu->b2_pred_mode;
            ps_proc->s_left_mb_pu.s_me_info[0].s_mv = ps_proc->ps_pu->s_me_info[0].s_mv;
            ps_proc->s_left_mb_pu.s_me_info[1].s_mv = ps_proc->ps_pu->s_me_info[1].s_mv;
        }
        if (i4_mb_y == 0)
        {
            ps_top_mb_syntax_ele->u4_csbp = 0;
            ps_top_row_pu->b1_intra_flag = 0;
            ps_top_row_pu->b2_pred_mode = ps_proc->ps_pu->b2_pred_mode;
            ps_top_row_pu->s_me_info[0].s_mv = ps_proc->ps_pu->s_me_info[0].s_mv;
            ps_top_row_pu->s_me_info[1].s_mv = ps_proc->ps_pu->s_me_info[1].s_mv;
        }

        ih264e_fill_bs_1mv_1ref_non_mbaff(pu4_pic_horz_bs,
                                          pu4_pic_vert_bs,
                                          ps_left_mb_syntax_ele->u4_csbp,
                                          ps_top_mb_syntax_ele->u4_csbp,
                                          ps_proc->u4_csbp,
                                          &ps_proc->s_left_mb_pu,
                                          ps_top_row_pu,
                                          ps_proc->ps_pu);
    }

    return ;
}

/**
*******************************************************************************
*
* @brief This function performs deblocking of top horizontal edge
*
* @par Description:
*  This function performs deblocking of top horizontal edge
*
* @param[in] ps_codec
*  pointer to codec context
*
* @param[in] ps_proc
*  pointer to proc context
*
* @param[in] pu1_mb_qp
*  pointer to mb quantization param
*
* @param[in] pu1_cur_pic_luma
*  pointer to recon buffer luma
*
* @param[in] pu1_cur_pic_chroma
*  pointer to recon buffer chroma
*
* @param[in] pu4_pic_horz_bs
*  pointer to horizontal blocking strength
*
* @returns  none
*
* @remarks none
*
*******************************************************************************
*/
static void ih264e_filter_top_edge(codec_t *ps_codec,
                                   process_ctxt_t *ps_proc,
                                   UWORD8 *pu1_mb_qp,
                                   UWORD8 *pu1_cur_pic_luma,
                                   UWORD8 *pu1_cur_pic_chroma,
                                   UWORD32 *pu4_pic_horz_bs)
{
    /* strd */
    WORD32 i4_rec_strd = ps_proc->i4_rec_strd;

    /* deblk params */
    UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma, u4_qp_p, u4_qp_q;
    UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;

    /* collect qp of left & top mb */
    u4_qp_p = pu1_mb_qp[-ps_proc->i4_wd_mbs];
    u4_qp_q = pu1_mb_qp[0];

    /********/
    /* luma */
    /********/
    u4_qp_luma = (u4_qp_p + u4_qp_q + 1) >> 1;

    /* filter offset A and filter offset B have to be received from slice header */
    /* TODO : for now lets set these offsets as zero */


    u4_idx_A_luma = MIN(51, u4_qp_luma + 0);
    u4_idx_B_luma = MIN(51, u4_qp_luma + 0);

    /* alpha, beta computation */
    u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
    u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];

    /**********/
    /* chroma */
    /**********/
    u4_qp_chroma = (gu1_qpc_fqpi[u4_qp_p] + gu1_qpc_fqpi[u4_qp_q] + 1) >> 1;

    /* filter offset A and filter offset B have to be received from slice header */
    /* TODO : for now lets set these offsets as zero */


    u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
    u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);

    /* alpha, beta computation */
    u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
    u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];

    /* deblk edge */
    /* top Horizontal edge - allowed to be deblocked ? */
    if (pu4_pic_horz_bs[0] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
        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);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma, i4_rec_strd, u4_alpha_luma,
                                               u4_beta_luma, pu4_pic_horz_bs[0],
                                               gu1_ih264_clip_table[u4_idx_A_luma]);

        ps_codec->pf_deblk_chroma_horz_bslt4(pu1_cur_pic_chroma, i4_rec_strd, u4_alpha_chroma,
                                             u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_horz_bs[0],
                                             gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
    }
}

/**
*******************************************************************************
*
* @brief This function performs deblocking of left vertical edge
*
* @par Description:
*  This function performs deblocking of top horizontal edge
*
* @param[in] ps_codec
*  pointer to codec context
*
* @param[in] ps_proc
*  pointer to proc context
*
* @param[in] pu1_mb_qp
*  pointer to mb quantization param
*
* @param[in] pu1_cur_pic_luma
*  pointer to recon buffer luma
*
* @param[in] pu1_cur_pic_chroma
*  pointer to recon buffer chroma
*
* @param[in] pu4_pic_vert_bs
*  pointer to vertical blocking strength
*
* @returns  none
*
* @remarks none
*
*******************************************************************************
*/
static void ih264e_filter_left_edge(codec_t *ps_codec,
                                    process_ctxt_t *ps_proc,
                                    UWORD8 *pu1_mb_qp,
                                    UWORD8 *pu1_cur_pic_luma,
                                    UWORD8 *pu1_cur_pic_chroma,
                                    UWORD32 *pu4_pic_vert_bs)
{
    /* strd */
    WORD32 i4_rec_strd = ps_proc->i4_rec_strd;

    /* deblk params */
    UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma, u4_qp_p, u4_qp_q;
    UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;

    /* collect qp of left & curr mb */
    u4_qp_p = pu1_mb_qp[-1];
    u4_qp_q = pu1_mb_qp[0];

    /********/
    /* luma */
    /********/
    u4_qp_luma = (u4_qp_p + u4_qp_q + 1) >> 1;

    /* filter offset A and filter offset B have to be received from slice header */
    /* TODO : for now lets set these offsets as zero */


    u4_idx_A_luma = MIN(51, u4_qp_luma + 0);
    u4_idx_B_luma = MIN(51, u4_qp_luma + 0);

    /* alpha, beta computation */
    u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
    u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];

    /**********/
    /* chroma */
    /**********/
    u4_qp_chroma = (gu1_qpc_fqpi[u4_qp_p] + gu1_qpc_fqpi[u4_qp_q] + 1) >> 1;

    /* filter offset A and filter offset B have to be received from slice header */
    /* TODO : for now lets set these offsets as zero */


    u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
    u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);

    /* alpha, beta computation */
    u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
    u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];

    /* deblk edge */
    if (pu4_pic_vert_bs[0] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
        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);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma, i4_rec_strd,
                                           u4_alpha_luma, u4_beta_luma,
                                           pu4_pic_vert_bs[0],
                                           gu1_ih264_clip_table[u4_idx_A_luma]);

        ps_codec->pf_deblk_chroma_vert_bslt4(pu1_cur_pic_chroma, i4_rec_strd, u4_alpha_chroma,
                                             u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_vert_bs[0],
                                             gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
    }
}

/**
*******************************************************************************
*
* @brief This function performs deblocking on an mb
*
* @par Description:
*  This function performs deblocking on an mb
*
* @param[in] ps_proc
*  process context corresponding to the job
*
* @param[in] ps_deblk
*  pointer to deblock context
*
* @returns  none
*
* @remarks none
*
*******************************************************************************
*/
void ih264e_deblock_mb(process_ctxt_t *ps_proc, deblk_ctxt_t * ps_deblk)
{
    /* codec ctxt */
    codec_t *ps_codec = ps_proc->ps_codec;

    /* ngbr availability */
    UWORD8  u1_mb_a, u1_mb_b;

    /* mb indices */
    WORD32  i4_mb_x = ps_deblk->i4_mb_x, i4_mb_y = ps_deblk->i4_mb_y;

    /* pic qp ptr */
    UWORD8  *pu1_pic_qp = ps_deblk->s_bs_ctxt.pu1_pic_qp;

    /* vertical blocking strength */
    UWORD32 *pu4_pic_vert_bs = ps_deblk->s_bs_ctxt.pu4_pic_vert_bs;

    /* horizontal blocking strength */
    UWORD32 *pu4_pic_horz_bs = ps_deblk->s_bs_ctxt.pu4_pic_horz_bs;

    /* src buffers luma */
    UWORD8  *pu1_cur_pic_luma = ps_deblk->pu1_cur_pic_luma;

    /* src buffers chroma */
    UWORD8  *pu1_cur_pic_chroma = ps_deblk->pu1_cur_pic_chroma;

    /* strd */
    WORD32 i4_rec_strd = ps_proc->i4_rec_strd;

    /* deblk params */
    UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma;
    UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;

    /* temp var */
    UWORD32 push_ptr = (i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x;

    /* derive neighbor availability */
    /* In slice mode the edges of mbs that lie on the slice boundary are not deblocked */
    /* deblocking filter idc '2' */
    if (ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
    {
        /* slice index */
        UWORD8  *pu1_slice_idx = ps_deblk->pu1_slice_idx;

        pu1_slice_idx += (i4_mb_y * ps_proc->i4_wd_mbs);
        /* left macroblock availability */
        u1_mb_a = (i4_mb_x == 0 ||
                        (pu1_slice_idx[i4_mb_x - 1 ] != pu1_slice_idx[i4_mb_x]))? 0 : 1;
        /* top macroblock availability */
        u1_mb_b = (i4_mb_y == 0 ||
                        (pu1_slice_idx[i4_mb_x-ps_proc->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))? 0 : 1;
    }
    else
    {
        /* left macroblock availability */
        u1_mb_a = (i4_mb_x == 0)? 0 : 1;
        /* top macroblock availability */
        u1_mb_b = (i4_mb_y == 0)? 0 : 1;
    }

    pu1_pic_qp += push_ptr;
    pu4_pic_vert_bs += push_ptr * 4;
    pu4_pic_horz_bs += push_ptr * 4;

    /********/
    /* luma */
    /********/
    u4_qp_luma = pu1_pic_qp[0];

    /* filter offset A and filter offset B have to be received from slice header */
    /* TODO : for now lets set these offsets as zero */


    u4_idx_A_luma = MIN(51, u4_qp_luma + 0);
    u4_idx_B_luma = MIN(51, u4_qp_luma + 0);

    /* alpha, beta computation */
    u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
    u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];

    /**********/
    /* chroma */
    /**********/
    u4_qp_chroma = gu1_qpc_fqpi[u4_qp_luma];

    /* filter offset A and filter offset B have to be received from slice header */
    /* TODO : for now lets set these offsets as zero */


    u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
    u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);

    /* alpha, beta computation */
    u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
    u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];

    /* Deblock vertical edges */
    /* left vertical edge 0 - allowed to be deblocked ? */
    if (u1_mb_a)
    {
        ih264e_filter_left_edge(ps_codec, ps_proc, pu1_pic_qp, pu1_cur_pic_luma, pu1_cur_pic_chroma, pu4_pic_vert_bs);
    }

    /* vertical edge 1 */
    if (pu4_pic_vert_bs[1] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 4, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 4, i4_rec_strd,
                                           u4_alpha_luma, u4_beta_luma,
                                           pu4_pic_vert_bs[1],
                                           gu1_ih264_clip_table[u4_idx_A_luma]);
    }

    /* vertical edge 2 */
    if (pu4_pic_vert_bs[2] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 8, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
        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);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 8, i4_rec_strd, u4_alpha_luma,
                                           u4_beta_luma, pu4_pic_vert_bs[2],
                                           gu1_ih264_clip_table[u4_idx_A_luma]);

        ps_codec->pf_deblk_chroma_vert_bslt4(pu1_cur_pic_chroma + 8, i4_rec_strd, u4_alpha_chroma,
                                             u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_vert_bs[2],
                                             gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
    }

    /* vertical edge 3 */
    if (pu4_pic_vert_bs[3] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 12, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 12, i4_rec_strd, u4_alpha_luma,
                                           u4_beta_luma, pu4_pic_vert_bs[3],
                                           gu1_ih264_clip_table[u4_idx_A_luma]);
    }

    /* Deblock Horizontal edges */
    /* Horizontal edge 0 */
    if (u1_mb_b)
    {
        ih264e_filter_top_edge(ps_codec, ps_proc, pu1_pic_qp, pu1_cur_pic_luma, pu1_cur_pic_chroma, pu4_pic_horz_bs);
    }

    /* horizontal edge 1 */
    if (pu4_pic_horz_bs[1] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 4 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 4 * i4_rec_strd, i4_rec_strd, u4_alpha_luma,
                                           u4_beta_luma, pu4_pic_horz_bs[1],
                                           gu1_ih264_clip_table[u4_idx_A_luma]);
    }

    /* horizontal edge 2 */
    if (pu4_pic_horz_bs[2] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 8 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
        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);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 8 * i4_rec_strd, i4_rec_strd, u4_alpha_luma,
                                           u4_beta_luma, pu4_pic_horz_bs[2],
                                           gu1_ih264_clip_table[u4_idx_A_luma]);

        ps_codec->pf_deblk_chroma_horz_bslt4(pu1_cur_pic_chroma + 4 * i4_rec_strd, i4_rec_strd, u4_alpha_chroma,
                                             u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_horz_bs[2],
                                             gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
    }

    /* horizontal edge 3 */
    if (pu4_pic_horz_bs[3] == 0x04040404)
    {
        /* strong filter */
        ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 12 * i4_rec_strd, i4_rec_strd, u4_alpha_luma, u4_beta_luma);
    }
    else
    {
        /* normal filter */
        ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 12 * i4_rec_strd, i4_rec_strd, u4_alpha_luma,
                                           u4_beta_luma, pu4_pic_horz_bs[3],
                                           gu1_ih264_clip_table[u4_idx_A_luma]);
    }

    return ;
}