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*/
98static 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*/
122static 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*/
171static 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*/
353static 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*/
393void 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*/
510static 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*/
613static 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*/
704void 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