xref: /aosp_15_r20/external/libavc/encoder/svc/isvce_deblk.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2022 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  *  isvce_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  *  - isvce_fill_bs_1mv_1ref_non_mbaff
34  *  - isvce_compute_bs
35  *  - isvce_filter_top_edge
36  *  - isvce_filter_left_edge
37  *  - isvce_deblock_mb
38  *
39  * @remarks
40  *  None
41  *
42  *******************************************************************************
43  */
44 #include <stdio.h>
45 #include <string.h>
46 
47 #include "ih264e_config.h"
48 #include "ih264_typedefs.h"
49 #include "iv2.h"
50 #include "ive2.h"
51 #include "isvc_macros.h"
52 #include "isvc_defs.h"
53 #include "isvc_structs.h"
54 #include "ih264_trans_data.h"
55 #include "isvc_trans_quant_itrans_iquant.h"
56 #include "isvc_inter_pred_filters.h"
57 #include "isvc_mem_fns.h"
58 #include "ih264_padding.h"
59 #include "ih264_intra_pred_filters.h"
60 #include "ih264_deblk_edge_filters.h"
61 #include "isvc_cabac_tables.h"
62 #include "ih264_deblk_tables.h"
63 #include "isvce_defs.h"
64 #include "ih264e_error.h"
65 #include "ih264e_bitstream.h"
66 #include "ime_distortion_metrics.h"
67 #include "ime_defs.h"
68 #include "ime_structs.h"
69 #include "irc_cntrl_param.h"
70 #include "irc_frame_info_collector.h"
71 #include "isvce_rate_control.h"
72 #include "isvce_cabac_structs.h"
73 #include "isvce_structs.h"
74 #include "isvce_deblk.h"
75 #include "isvce_globals.h"
76 
77 static const UWORD32 gau4_isvce_packed_bs2[(1 << MAX_TU_IN_MB_COL) * 2] = {
78     /* BS TABLES FOR NORMAL EDGES */
79     0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200,
80     0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202,
81 
82     /* BS TABLES FOR XTRA LEFT MB EDGES IN MBAFF CASE */
83     0x01010101, 0x02010101, 0x01020101, 0x02020101, 0x01010201, 0x02010201, 0x01020201, 0x02020201,
84     0x01010102, 0x02010102, 0x01020102, 0x02020102, 0x01010202, 0x02010202, 0x01020202, 0x02020202};
85 
86 static const UWORD16 gau2_isvce_4x4_v2h_reorder[(1 << MAX_TU_IN_MB_COL)] = {
87     0x0000, 0x0001, 0x0010, 0x0011, 0x0100, 0x0101, 0x0110, 0x0111,
88     0x1000, 0x1001, 0x1010, 0x1011, 0x1100, 0x1101, 0x1110, 0x1111};
89 
isvce_fill_bs1_16x16mb_pslice(isvce_mb_info_t * ps_cur_mb,isvce_mb_info_t * ps_top_mb,isvce_mb_info_t * ps_left_mb,UWORD32 * pu4_bs_table,coordinates_t * ps_mb_pos)90 static void isvce_fill_bs1_16x16mb_pslice(isvce_mb_info_t *ps_cur_mb, isvce_mb_info_t *ps_top_mb,
91                                           isvce_mb_info_t *ps_left_mb, UWORD32 *pu4_bs_table,
92                                           coordinates_t *ps_mb_pos)
93 {
94     WORD16 i2_q_mv0, i2_q_mv1;
95     WORD16 i2_p_mv0, i2_p_mv1;
96     UWORD32 i;
97     UWORD32 u4_bs_horz = pu4_bs_table[0];
98     UWORD32 u4_bs_vert = pu4_bs_table[4];
99 
100     i2_q_mv0 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
101     i2_q_mv1 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
102 
103     if(ps_mb_pos->i4_ordinate)
104     {
105         /* Computing Bs for the top edge */
106         for(i = 0; i < 4; i++)
107         {
108             UWORD32 u4_idx = 24 - (i << 3);
109 
110             /* check if Bs is already set */
111             if(!((u4_bs_horz >> u4_idx) & 0xf))
112             {
113                 /************************************************************/
114                 /* If Bs is not set, use left edge and current edge mvs and */
115                 /* reference pictures addresses to evaluate Bs==1           */
116                 /************************************************************/
117                 UWORD32 u4_bs_temp1;
118                 UWORD32 u4_bs;
119 
120                 /*********************************************************/
121                 /* If any motion vector component differs by more than 1 */
122                 /* integer pel or if reference pictures are different Bs */
123                 /* is set to 1. Note that this condition shall be met for*/
124                 /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
125                 /*********************************************************/
126                 i2_p_mv0 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
127                 i2_p_mv1 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
128 
129                 u4_bs_temp1 =
130                     ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) || (ABS((i2_p_mv1 - i2_q_mv1)) >= 4));
131 
132                 u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
133                           ps_top_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
134                          u4_bs_temp1);
135 
136                 u4_bs_horz |= (u4_bs << u4_idx);
137             }
138         }
139 
140         pu4_bs_table[0] = u4_bs_horz;
141     }
142 
143     if(ps_mb_pos->i4_abscissa)
144     {
145         /* Computing Bs for the left edge */
146         for(i = 0; i < 4; i++)
147         {
148             UWORD32 u4_idx = 24 - (i << 3);
149 
150             /* check if Bs is already set */
151             if(!((u4_bs_vert >> u4_idx) & 0xf))
152             {
153                 /* If Bs is not set, evalaute conditions for Bs=1 */
154                 UWORD32 u4_bs_temp1;
155                 UWORD32 u4_bs;
156                 /*********************************************************/
157                 /* If any motion vector component differs by more than 1 */
158                 /* integer pel or if reference pictures are different Bs */
159                 /* is set to 1. Note that this condition shall be met for*/
160                 /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
161                 /*********************************************************/
162 
163                 i2_p_mv0 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
164                 i2_p_mv1 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
165 
166                 u4_bs_temp1 =
167                     ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv1)) >= 4));
168 
169                 u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
170                           ps_left_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
171                          u4_bs_temp1);
172 
173                 u4_bs_vert |= (u4_bs << u4_idx);
174             }
175         }
176 
177         pu4_bs_table[4] = u4_bs_vert;
178     }
179 }
180 
isvce_fill_bs1_16x16mb_bslice(isvce_mb_info_t * ps_cur_mb,isvce_mb_info_t * ps_top_mb,isvce_mb_info_t * ps_left_mb,UWORD32 * pu4_bs_table,coordinates_t * ps_mb_pos)181 static void isvce_fill_bs1_16x16mb_bslice(isvce_mb_info_t *ps_cur_mb, isvce_mb_info_t *ps_top_mb,
182                                           isvce_mb_info_t *ps_left_mb, UWORD32 *pu4_bs_table,
183                                           coordinates_t *ps_mb_pos)
184 {
185     WORD16 i2_q_mv0, i2_q_mv1, i2_q_mv2, i2_q_mv3;
186     WORD16 i2_p_mv0, i2_p_mv1, i2_p_mv2, i2_p_mv3;
187     UWORD32 i;
188     UWORD32 u4_bs_horz = pu4_bs_table[0];
189     UWORD32 u4_bs_vert = pu4_bs_table[4];
190 
191     i2_q_mv0 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
192     i2_q_mv1 = ps_cur_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
193     i2_q_mv2 = ps_cur_mb->as_pu->as_me_info[L1].s_mv.i2_mvx;
194     i2_q_mv3 = ps_cur_mb->as_pu->as_me_info[L1].s_mv.i2_mvy;
195 
196     /* Computing Bs for the top edge */
197     if(ps_mb_pos->i4_ordinate)
198     {
199         for(i = 0; i < 4; i++)
200         {
201             UWORD32 u4_idx = 24 - (i << 3);
202 
203             /* check if Bs is already set */
204             if(!((u4_bs_horz >> u4_idx) & 0xf))
205             {
206                 /************************************************************/
207                 /* If Bs is not set, use left edge and current edge mvs and */
208                 /* reference pictures addresses to evaluate Bs==1           */
209                 /************************************************************/
210                 UWORD32 u4_bs_temp1, u4_bs_temp2;
211                 UWORD32 u4_bs;
212 
213                 /*********************************************************/
214                 /* If any motion vector component differs by more than 1 */
215                 /* integer pel or if reference pictures are different Bs */
216                 /* is set to 1. Note that this condition shall be met for*/
217                 /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
218                 /*********************************************************/
219                 i2_p_mv0 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
220                 i2_p_mv1 = ps_top_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
221                 i2_p_mv2 = ps_top_mb->as_pu->as_me_info[L1].s_mv.i2_mvx;
222                 i2_p_mv3 = ps_top_mb->as_pu->as_me_info[L1].s_mv.i2_mvy;
223 
224                 u4_bs_temp1 =
225                     ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv1)) >= 4) |
226                      (ABS((i2_p_mv2 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv3)) >= 4));
227 
228                 u4_bs_temp2 =
229                     ((ABS((i2_p_mv0 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv3)) >= 4) |
230                      (ABS((i2_p_mv2 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv1)) >= 4));
231 
232                 u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
233                           ps_top_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
234                          (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
235                           ps_top_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
236                          u4_bs_temp1) &&
237                         ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
238                           ps_top_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
239                          (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
240                           ps_top_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
241                          u4_bs_temp2);
242 
243                 u4_bs_horz |= (u4_bs << u4_idx);
244             }
245         }
246 
247         pu4_bs_table[0] = u4_bs_horz;
248     }
249 
250     /* Computing Bs for the left edge */
251     if(ps_mb_pos->i4_abscissa)
252     {
253         for(i = 0; i < 4; i++)
254         {
255             UWORD32 u4_idx = 24 - (i << 3);
256 
257             /* check if Bs is already set */
258             if(!((u4_bs_vert >> u4_idx) & 0xf))
259             {
260                 /* If Bs is not set, evalaute conditions for Bs=1 */
261                 UWORD32 u4_bs_temp1, u4_bs_temp2;
262                 UWORD32 u4_bs;
263                 /*********************************************************/
264                 /* If any motion vector component differs by more than 1 */
265                 /* integer pel or if reference pictures are different Bs */
266                 /* is set to 1. Note that this condition shall be met for*/
267                 /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/
268                 /*********************************************************/
269 
270                 i2_p_mv0 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvx;
271                 i2_p_mv1 = ps_left_mb->as_pu->as_me_info[L0].s_mv.i2_mvy;
272                 i2_p_mv2 = ps_left_mb->as_pu->as_me_info[L1].s_mv.i2_mvx;
273                 i2_p_mv3 = ps_left_mb->as_pu->as_me_info[L1].s_mv.i2_mvy;
274 
275                 u4_bs_temp1 =
276                     ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv1)) >= 4) |
277                      (ABS((i2_p_mv2 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv3)) >= 4));
278 
279                 u4_bs_temp2 =
280                     ((ABS((i2_p_mv0 - i2_q_mv2)) >= 4) | (ABS((i2_p_mv1 - i2_q_mv3)) >= 4) |
281                      (ABS((i2_p_mv2 - i2_q_mv0)) >= 4) | (ABS((i2_p_mv3 - i2_q_mv1)) >= 4));
282 
283                 u4_bs = ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
284                           ps_left_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
285                          (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
286                           ps_left_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
287                          u4_bs_temp1) &&
288                         ((ps_cur_mb->as_pu->as_me_info[L0].i1_ref_idx !=
289                           ps_left_mb->as_pu->as_me_info[L1].i1_ref_idx) ||
290                          (ps_cur_mb->as_pu->as_me_info[L1].i1_ref_idx !=
291                           ps_left_mb->as_pu->as_me_info[L0].i1_ref_idx) ||
292                          u4_bs_temp2);
293 
294                 u4_bs_vert |= (u4_bs << u4_idx);
295             }
296         }
297 
298         pu4_bs_table[4] = u4_bs_vert;
299     }
300 }
301 
isvce_fill_bs2_horz_vert(UWORD32 * pu4_bs,WORD32 u4_left_mb_csbp,WORD32 u4_top_mb_csbp,WORD32 u4_cur_mb_csbp,coordinates_t * ps_mb_pos,const UWORD32 * pu4_packed_bs2,const UWORD16 * pu2_4x4_v2h_reorder)302 static void isvce_fill_bs2_horz_vert(UWORD32 *pu4_bs, WORD32 u4_left_mb_csbp, WORD32 u4_top_mb_csbp,
303                                      WORD32 u4_cur_mb_csbp, coordinates_t *ps_mb_pos,
304                                      const UWORD32 *pu4_packed_bs2,
305                                      const UWORD16 *pu2_4x4_v2h_reorder)
306 {
307     UWORD32 u4_nbr_horz_csbp, u4_nbr_vert_csbp;
308     UWORD32 u4_horz_bs2_dec, u4_vert_bs2_dec;
309     UWORD32 u4_left_mb_masked_csbp, u4_cur_mb_masked_csbp;
310 
311     UWORD32 u4_reordered_vert_bs2_dec, u4_temp;
312 
313     WORD32 u4_cur_mb_csbp_seq = 0;
314     WORD32 u4_top_mb_csbp_seq = 0;
315     WORD32 u4_left_mb_csbp_seq = 0;
316 
317     /* Convert the csbp packed data in sequential pattern from raster order */
318     u4_cur_mb_csbp_seq |= u4_cur_mb_csbp & 3;  // 0 1
319     u4_cur_mb_csbp >>= 2;
320     u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 4;  // 4 5
321     u4_cur_mb_csbp >>= 2;
322     u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 2;  // 2 3
323     u4_cur_mb_csbp >>= 2;
324     u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 6;  // 6 7
325     u4_cur_mb_csbp >>= 2;
326     u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 8;  // 8 9
327     u4_cur_mb_csbp >>= 2;
328     u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 12;  // 12 13
329     u4_cur_mb_csbp >>= 2;
330     u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 10;  // 10 11
331     u4_cur_mb_csbp >>= 2;
332     u4_cur_mb_csbp_seq |= (u4_cur_mb_csbp & 3) << 14;  // 14 15
333 
334     u4_left_mb_csbp_seq |= u4_left_mb_csbp & 3;  // 0 1
335     u4_left_mb_csbp >>= 2;
336     u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 4;  // 4 5
337     u4_left_mb_csbp >>= 2;
338     u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 2;  // 2 3
339     u4_left_mb_csbp >>= 2;
340     u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 6;  // 6 7
341     u4_left_mb_csbp >>= 2;
342     u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 8;  // 8 9
343     u4_left_mb_csbp >>= 2;
344     u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 12;  // 12 13
345     u4_left_mb_csbp >>= 2;
346     u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 10;  // 10 11
347     u4_left_mb_csbp >>= 2;
348     u4_left_mb_csbp_seq |= (u4_left_mb_csbp & 3) << 14;  // 14 15
349 
350     /* Required only the last row of top MB */
351     u4_top_mb_csbp = u4_top_mb_csbp >> 10;  // 12 13
352     u4_top_mb_csbp_seq |= (u4_top_mb_csbp & 3);
353     u4_top_mb_csbp = u4_top_mb_csbp >> 4;  // 14 15
354     u4_top_mb_csbp_seq |= ((u4_top_mb_csbp & 3) << 2);
355 
356     /* u4_nbr_horz_csbp=11C|10C|9C|8C|7C|6C|5C|4C|3C|2C|1C|0C|15T|14T|13T|12T */
357     u4_nbr_horz_csbp = (u4_cur_mb_csbp_seq << 4) | u4_top_mb_csbp_seq;
358     u4_horz_bs2_dec = u4_cur_mb_csbp_seq | u4_nbr_horz_csbp;
359 
360     /* u4_left_mb_masked_csbp = 15L|0|0|0|11L|0|0|0|7L|0|0|0|3L|0|0|0 */
361     u4_left_mb_masked_csbp = u4_left_mb_csbp_seq & CSBP_RIGHT_BLOCK_MASK;
362 
363     /* u4_cur_mb_masked_csbp =14C|13C|12C|x|10C|9C|8C|x|6C|5C|4C|x|2C|1C|0C|x */
364     u4_cur_mb_masked_csbp = (u4_cur_mb_csbp_seq << 1) & (~CSBP_LEFT_BLOCK_MASK);
365 
366     /* u4_nbr_vert_csbp=14C|13C|12C|15L|10C|9C|8C|11L|6C|5C|4C|7L|2C|1C|0C|3L */
367     u4_nbr_vert_csbp = (u4_cur_mb_masked_csbp) | (u4_left_mb_masked_csbp >> 3);
368 
369     u4_vert_bs2_dec = u4_cur_mb_csbp_seq | u4_nbr_vert_csbp;
370 
371     /* Fill horz edges (0,1,2,3) boundary strengths 2 using look up table */
372     if(ps_mb_pos->i4_ordinate)
373     {
374         pu4_bs[0] = pu4_packed_bs2[u4_horz_bs2_dec & 0xF];
375     }
376 
377     pu4_bs[1] = pu4_packed_bs2[(u4_horz_bs2_dec >> 4) & 0xF];
378     pu4_bs[2] = pu4_packed_bs2[(u4_horz_bs2_dec >> 8) & 0xF];
379     pu4_bs[3] = pu4_packed_bs2[(u4_horz_bs2_dec >> 12) & 0xF];
380 
381     /* Do 4x4 tranpose of u4_vert_bs2_dec by using look up table for reorder */
382     u4_reordered_vert_bs2_dec = pu2_4x4_v2h_reorder[u4_vert_bs2_dec & 0xF];
383     u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 4) & 0xF];
384     u4_reordered_vert_bs2_dec |= (u4_temp << 1);
385     u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 8) & 0xF];
386     u4_reordered_vert_bs2_dec |= (u4_temp << 2);
387     u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 12) & 0xF];
388     u4_reordered_vert_bs2_dec |= (u4_temp << 3);
389 
390     /* Fill vert edges (4,5,6,7) boundary strengths 2 using look up table */
391     if(ps_mb_pos->i4_abscissa)
392     {
393         pu4_bs[4] = pu4_packed_bs2[u4_reordered_vert_bs2_dec & 0xF];
394     }
395 
396     pu4_bs[5] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 4) & 0xF];
397     pu4_bs[6] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 8) & 0xF];
398     pu4_bs[7] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 12) & 0xF];
399 }
400 
401 /* brief Fills the BS for edges falling on a IBL boundary */
isvce_fill_bs_ibl(isvce_mb_info_t * ps_cur_mb,isvce_mb_info_t * ps_top_mb,isvce_mb_info_t * ps_left_mb,UWORD32 * pu4_bs_table)402 static void isvce_fill_bs_ibl(isvce_mb_info_t *ps_cur_mb, isvce_mb_info_t *ps_top_mb,
403                               isvce_mb_info_t *ps_left_mb, UWORD32 *pu4_bs_table)
404 {
405     /*! Flow of the module is as follows                                  */
406     /*! 1. checks if MB edge is falling on IBL boundary                   */
407     /*! 2. if only Mb edge then it fills the BS based on INTRA or INTER
408            stauts                                                         */
409     /*! 3. if the current MB is IBL and neighbours are also neighbours
410            then it uses the current layer t_coeff flag to decide the
411            BS of a particular edge                                        */
412     /*! 4. fills the BS for all the edges in curretn MB if IBL            */
413 
414     UWORD16 u2_top_horz_nnz;
415     UWORD8 u1_top_mb_ibl, u1_left_mb_ibl;
416     UWORD32 i4_i, i4_edge;
417     UWORD8 u1_bs;
418     UWORD8 u1_cnd;
419     UWORD8 u1_top_intra;
420     UWORD8 u1_left_intra;
421     UWORD8 u1_p_nnz, u1_q_nnz;
422     UWORD8 u1_curr_mb_ibl;
423     UWORD16 u2_curr_nnz;
424     UWORD8 u1_left_mb_nnz = 0, u1_left_nnz;
425     WORD32 i4_horz_start = 0;
426     WORD32 i4_vertical_start = 0;
427 
428     u1_top_mb_ibl = ps_top_mb ? (ps_top_mb->u1_base_mode_flag && ps_top_mb->u1_is_intra) : 0;
429     u1_left_mb_ibl = ps_left_mb ? (ps_left_mb->u1_base_mode_flag && ps_left_mb->u1_is_intra) : 0;
430 
431     u1_curr_mb_ibl = ps_cur_mb ? (ps_cur_mb->u1_base_mode_flag && ps_cur_mb->u1_is_intra) : 0;
432 
433     u1_top_intra = ps_top_mb ? ps_top_mb->u1_is_intra : 0;
434     u1_left_intra = ps_left_mb ? ps_left_mb->u1_is_intra : 0;
435 
436     /* return if none of the current top and left is IBL */
437     if((0 == u1_curr_mb_ibl) && (0 == u1_top_mb_ibl) && (0 == u1_left_mb_ibl))
438     {
439         return;
440     }
441 
442     /* set up the vertical and horz MB edge skip flags */
443     if(0 != u1_curr_mb_ibl)
444     {
445         /* if top is not IBL */
446         if(0 == u1_top_mb_ibl)
447         {
448             i4_horz_start = 1;
449         }
450 
451         /* if left in not IBL */
452         if(0 == u1_left_mb_ibl)
453         {
454             i4_vertical_start = 1;
455         }
456     }
457 
458     /* Fill BS for mb egdex assuming non IBL case */
459 
460     /* only the  MB edges fall across IBL boundary */
461     if((0 != u1_curr_mb_ibl) || (0 != u1_top_mb_ibl) || (0 != u1_left_mb_ibl))
462     {
463         UWORD16 u2_temp, u2_i, u1_i;
464         u2_temp = ps_left_mb ? ps_left_mb->u4_res_csbp : 0;
465         for(u2_i = 0; u2_i < MAX_TU_IN_MB_COL; u2_i++)
466         {
467             UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u2_i * 4 + MAX_TU_IN_MB_ROW - 1];
468             u1_left_mb_nnz |= ((u2_temp & (1 << u1_zscan_idx)) ? 1 << u2_i : 0);
469         }
470 
471         u2_curr_nnz = ps_cur_mb->u4_res_csbp;
472 
473         u2_top_horz_nnz = 0;
474         if(ps_top_mb)
475         {
476             /* last row of top MB */
477             for(u1_i = 12; u1_i < 16; u1_i++)
478             {
479                 UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u1_i];
480                 u2_top_horz_nnz |=
481                     ((ps_top_mb->u4_res_csbp & (1 << u1_zscan_idx)) ? 1 << (u1_i - 12) : 0);
482             }
483         }
484         else
485         {
486             u2_top_horz_nnz = 0;
487         }
488 
489         /* top is intra and not ibl */
490         if(0 != u1_top_intra)
491         {
492             pu4_bs_table[0] = 0x04040404;
493         }
494         /* left is intra and not ibl */
495         if(0 != u1_left_intra)
496         {
497             pu4_bs_table[4] = 0x04040404;
498         }
499 
500         /* assume neighbours are inter and update bs */
501         /* Edge = 0 means Vert Edges and Edge = 1 means Horz edges */
502         for(i4_edge = 0; i4_edge < 2; i4_edge++)
503         {
504             UWORD8 u1_p_nnz = 0, u1_q_nnz = 0;
505             UWORD32 u4_bs_edge = 0;
506             WORD32 i4_bit_mask;
507             WORD32 i4_curr_intra_flag;
508             WORD32 i4_neibor_intra_flag;
509 
510             if(((1 == i4_horz_start) && (i4_edge == 1))) continue;
511             if(((1 == i4_vertical_start) && (i4_edge == 0))) continue;
512 
513             i4_curr_intra_flag = (0 != u1_curr_mb_ibl);
514 
515             if(0 != i4_edge)
516             {
517                 /* initialize for the TOP edge */
518                 u1_p_nnz = (UWORD8) u2_top_horz_nnz;
519                 for(i4_i = 0; i4_i < MAX_TU_IN_MB_ROW; i4_i++)
520                 {
521                     UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[i4_i];
522                     u1_q_nnz |= ((u2_curr_nnz & (1 << u1_zscan_idx)) ? (1 << i4_i) : 0);
523                 }
524 
525                 i4_neibor_intra_flag = (u1_top_mb_ibl || u1_top_intra);
526             }
527             else
528             {
529                 u1_p_nnz = u1_left_mb_nnz;
530                 for(u2_i = 0; u2_i < MAX_TU_IN_MB_COL; u2_i++)
531                 {
532                     UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u2_i * 4];
533                     u1_q_nnz |= ((u2_curr_nnz & (1 << u1_zscan_idx)) ? 1 << u2_i : 0);
534                 }
535 
536                 i4_neibor_intra_flag = (u1_left_mb_ibl || u1_left_intra);
537             }
538 
539             i4_bit_mask = 1;
540             /* find bs of 4 edges */
541             for(i4_i = 0; i4_i < 4; i4_i++)
542             {
543                 UWORD8 u1_p_nnz_temp, u1_q_nnz_temp;
544 
545                 u1_p_nnz_temp = (u1_p_nnz & i4_bit_mask);
546                 u1_q_nnz_temp = (u1_q_nnz & i4_bit_mask);
547 
548                 u1_cnd = ((u1_p_nnz_temp && (!i4_neibor_intra_flag)) ||
549                           (u1_q_nnz_temp && (!i4_curr_intra_flag)));
550 
551                 u1_bs = u1_cnd ? 2 : 1;
552 
553                 /* update the bs of the edge */
554                 u4_bs_edge = (u4_bs_edge << 8) + u1_bs;
555                 i4_bit_mask <<= 1;
556 
557             } /* end of loop over blk edges */
558 
559             /* update the bs of edges */
560             if(i4_edge && !u1_top_intra)
561             {
562                 pu4_bs_table[0] = u4_bs_edge;
563             }
564             else if(!i4_edge && !u1_left_intra)
565             {
566                 pu4_bs_table[4] = u4_bs_edge;
567             }
568         } /* end of loop over v1 vetical and horizontal edge */
569     }
570 
571     /* current MB is IBL */
572     if(0 != u1_curr_mb_ibl)
573     {
574         WORD32 i4_bit_mask_edge = 1;
575         UWORD16 u2_temp, u2_i, u1_i;
576 
577         u1_left_mb_nnz = 0;
578         u2_temp = ps_left_mb ? ps_left_mb->u4_csbp : 0;
579         for(u2_i = 0; u2_i < MAX_TU_IN_MB_COL; u2_i++)
580         {
581             UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u2_i * 4 + MAX_TU_IN_MB_ROW - 1];
582             u1_left_mb_nnz |= ((u2_temp & (1 << u1_zscan_idx)) ? 1 << u2_i : 0);
583         }
584 
585         u2_curr_nnz = ps_cur_mb->u4_csbp;
586 
587         u2_top_horz_nnz = 0;
588         if(ps_top_mb)
589         {
590             for(u1_i = 12; u1_i < 16; u1_i++)
591             {
592                 UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[u1_i];
593                 u2_top_horz_nnz |=
594                     ((ps_top_mb->u4_csbp & (1 << u1_zscan_idx)) ? 1 << (u1_i - 12) : 0);
595             }
596         }
597         else
598         {
599             u2_top_horz_nnz = 0;
600         }
601 
602         /* all are IBL edges then use only t_coeff of current layer */
603         /* loop over all edges */
604         for(i4_edge = 0; i4_edge < 4; i4_edge++)
605         {
606             UWORD16 u2_curr_horz_nnz = 0;
607             WORD32 i4_bit_mask = 1;
608 
609             u1_left_nnz = (u1_left_mb_nnz & i4_bit_mask_edge);
610 
611             for(i4_i = 0; i4_i < 4; i4_i++)
612             {
613                 UWORD8 u1_curr_nnz, u1_top_nnz;
614                 UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[(4 * i4_edge) + i4_i];
615 
616                 u2_curr_horz_nnz |= ((ps_cur_mb->u4_csbp & (1 << u1_zscan_idx)) ? (1 << i4_i) : 0);
617                 u1_curr_nnz = (u2_curr_horz_nnz & i4_bit_mask);
618                 u1_top_nnz = (u2_top_horz_nnz & i4_bit_mask);
619 
620                 /* update bs horizontal */
621                 if(!((1 == i4_horz_start) && (0 == i4_edge)))
622                 {
623                     u1_p_nnz = u1_top_nnz;
624                     u1_q_nnz = u1_curr_nnz;
625                     u1_cnd = !(u1_p_nnz || u1_q_nnz);
626                     u1_bs = u1_cnd ? 0 : 1;
627                     pu4_bs_table[i4_edge] = (pu4_bs_table[i4_edge] << 8) + u1_bs;
628                 }
629 
630                 /* update bs vertical */
631                 if(!((1 == i4_vertical_start) && (0 == i4_i)))
632                 {
633                     u1_p_nnz = u1_left_nnz;
634                     u1_q_nnz = u1_curr_nnz;
635                     u1_cnd = !(u1_p_nnz || u1_q_nnz);
636                     u1_bs = u1_cnd ? 0 : 1;
637                     pu4_bs_table[i4_i + 4] = (pu4_bs_table[i4_i + 4] << 8) + u1_bs;
638                 }
639                 /* store the current nnz to left nnz */
640                 u1_left_nnz = u1_curr_nnz;
641                 i4_bit_mask <<= 1;
642             }
643             /* store the current row nnz to top row nnz */
644             u2_top_horz_nnz = u2_curr_horz_nnz;
645             i4_bit_mask_edge <<= 1;
646         }
647     }
648 }
649 
isvce_compute_bs(isvce_process_ctxt_t * ps_proc,UWORD8 u1_inter_layer_deblk_flag)650 void isvce_compute_bs(isvce_process_ctxt_t *ps_proc, UWORD8 u1_inter_layer_deblk_flag)
651 {
652     coordinates_t s_mb_pos;
653 
654     UWORD32 *pu4_pic_vert_bs;
655     UWORD32 *pu4_pic_horz_bs;
656 
657     isvce_bs_ctxt_t *ps_bs = &(ps_proc->s_deblk_ctxt.s_bs_ctxt);
658     block_neighbors_t *ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
659     nbr_info_t *ps_nbr_info = &ps_proc->s_nbr_info;
660     isvce_mb_info_t *ps_left_mb = ps_ngbr_avbl->u1_mb_a ? ps_nbr_info->ps_left_mb_info : NULL;
661     isvce_mb_info_t *ps_top_mb =
662         ps_ngbr_avbl->u1_mb_b ? &ps_nbr_info->ps_top_row_mb_info[ps_bs->i4_mb_x] : NULL;
663     isvce_mb_info_t *ps_cur_mb = ps_proc->ps_mb_info;
664 
665     UWORD32 u1_left_mb_intra, u1_left_mb_ibl;
666 
667     UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp;
668 
669     UWORD32 u4_cur_mb_intra, u1_top_mb_intra, u4_cur_mb_fld;
670     UWORD32 u4_cur_mb_ibl, u1_top_mb_ibl;
671     UWORD32 au4_bs_table[8];
672     UWORD32 *pu4_bs_table;
673 
674     u4_cur_mb_intra = ps_cur_mb->u1_is_intra;
675     u4_cur_mb_ibl = ps_cur_mb->u1_base_mode_flag && ps_cur_mb->u1_is_intra;
676     u4_cur_mb_fld = 0;
677 
678     u1_top_mb_intra = ps_top_mb ? ps_top_mb->u1_is_intra : 0;
679     u1_top_mb_ibl = ps_top_mb ? (ps_top_mb->u1_base_mode_flag && ps_top_mb->u1_is_intra) : 0;
680 
681     u1_left_mb_intra = ps_left_mb ? ps_left_mb->u1_is_intra : 0;
682     u1_left_mb_ibl = ps_left_mb ? (ps_left_mb->u1_base_mode_flag && ps_left_mb->u1_is_intra) : 0;
683 
684     pu4_bs_table = au4_bs_table;
685     memset(pu4_bs_table, 0, sizeof(pu4_bs_table[0]) * NUM_EDGES_IN_MB * 2);
686 
687     s_mb_pos.i4_abscissa = ps_bs->i4_mb_x;
688     s_mb_pos.i4_ordinate = ps_bs->i4_mb_y;
689 
690     if(!u1_inter_layer_deblk_flag)
691     {
692         pu4_pic_vert_bs =
693             ps_bs->pu4_pic_vert_bs +
694             ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
695         pu4_pic_horz_bs =
696             ps_bs->pu4_pic_horz_bs +
697             ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
698     }
699     else
700     {
701         pu4_pic_vert_bs =
702             ps_bs->pu4_intra_base_vert_bs +
703             ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
704         pu4_pic_horz_bs =
705             ps_bs->pu4_intra_base_horz_bs +
706             ((s_mb_pos.i4_ordinate * ps_proc->i4_wd_mbs) + s_mb_pos.i4_abscissa) * NUM_EDGES_IN_MB;
707     }
708 
709     if(u4_cur_mb_intra && !(u4_cur_mb_ibl))
710     {
711         pu4_bs_table[4] = ps_bs->i4_mb_x ? 0x04040404 : 0;
712         pu4_bs_table[0] = ps_bs->i4_mb_y ? 0x04040404 : 0;
713         pu4_bs_table[1] = 0x03030303;
714         pu4_bs_table[2] = 0x03030303;
715         pu4_bs_table[3] = 0x03030303;
716         pu4_bs_table[5] = 0x03030303;
717         pu4_bs_table[6] = 0x03030303;
718         pu4_bs_table[7] = 0x03030303;
719     }
720     else
721     {
722         isvce_fill_bs_ibl(ps_cur_mb, ps_top_mb, ps_left_mb, pu4_bs_table);
723 
724         if(!u4_cur_mb_ibl)
725         {
726             UWORD32 u4_bs_0, u4_bs_4;
727 
728             UWORD32 u4_is_b = (ps_proc->i4_slice_type == BSLICE);
729 
730             u2_cur_csbp = ps_cur_mb->u4_csbp;
731             u2_left_csbp = ps_left_mb ? ps_left_mb->u4_csbp : 0;
732             u2_top_csbp = ps_top_mb ? ps_top_mb->u4_csbp : 0;
733 
734             u2_cur_csbp |= (ps_cur_mb->u4_res_csbp);
735             u2_left_csbp |= ps_left_mb ? ps_left_mb->u4_res_csbp : 0;
736             u2_top_csbp |= ps_top_mb ? ps_top_mb->u4_res_csbp : 0;
737 
738             u4_bs_0 = pu4_bs_table[0];
739             u4_bs_4 = pu4_bs_table[4];
740 
741             isvce_fill_bs2_horz_vert(pu4_bs_table, u2_left_csbp, u2_top_csbp, u2_cur_csbp,
742                                      &s_mb_pos, (gau4_isvce_packed_bs2),
743                                      (gau2_isvce_4x4_v2h_reorder));
744 
745             if(u1_left_mb_intra)
746             {
747                 pu4_bs_table[4] = 0x04040404;
748             }
749             else if(u1_left_mb_ibl)
750             {
751                 pu4_bs_table[4] = u4_bs_4;
752             }
753 
754             if(u1_top_mb_intra)
755             {
756                 pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404;
757             }
758             else if(u1_top_mb_ibl)
759             {
760                 pu4_bs_table[0] = u4_bs_0;
761             }
762 
763             if(!u4_is_b)
764             {
765                 isvce_fill_bs1_16x16mb_pslice(ps_cur_mb, ps_top_mb, ps_left_mb, pu4_bs_table,
766                                               &s_mb_pos);
767             }
768             else
769             {
770                 isvce_fill_bs1_16x16mb_bslice(ps_cur_mb, ps_top_mb, ps_left_mb, pu4_bs_table,
771                                               &s_mb_pos);
772             }
773         }
774     }
775 
776     pu4_pic_horz_bs[0] = pu4_bs_table[0];
777     pu4_pic_horz_bs[1] = pu4_bs_table[1];
778     pu4_pic_horz_bs[2] = pu4_bs_table[2];
779     pu4_pic_horz_bs[3] = pu4_bs_table[3];
780 
781     pu4_pic_vert_bs[0] = pu4_bs_table[4];
782     pu4_pic_vert_bs[1] = pu4_bs_table[5];
783     pu4_pic_vert_bs[2] = pu4_bs_table[6];
784     pu4_pic_vert_bs[3] = pu4_bs_table[7];
785 }
786 
787 /**
788 *******************************************************************************
789 *
790 * @brief This function performs deblocking of top horizontal edge
791 *
792 * @par Description:
793 *  This function performs deblocking of top horizontal edge
794 *
795 * @param[in] ps_codec
796 *  pointer to codec context
797 *
798 * @param[in] ps_proc
799 *  pointer to proc context
800 *
801 * @param[in] pu1_mb_qp
802 *  pointer to mb quantization param
803 *
804 * @param[in] pu1_cur_pic_luma
805 *  pointer to recon buffer luma
806 *
807 * @param[in] pu1_cur_pic_chroma
808 *  pointer to recon buffer chroma
809 *
810 * @param[in] pu4_pic_horz_bs
811 *  pointer to horizontal blocking strength
812 *
813 * @returns  none
814 *
815 * @remarks none
816 *
817 *******************************************************************************
818 */
isvce_filter_top_edge(isvce_codec_t * ps_codec,UWORD8 u1_qp_p,UWORD8 u1_qp_q,UWORD8 * pu1_cur_pic_luma,WORD32 i4_luma_stride,UWORD8 * pu1_cur_pic_chroma,WORD32 i4_chroma_stride,UWORD32 * pu4_pic_horz_bs)819 static void isvce_filter_top_edge(isvce_codec_t *ps_codec, UWORD8 u1_qp_p, UWORD8 u1_qp_q,
820                                   UWORD8 *pu1_cur_pic_luma, WORD32 i4_luma_stride,
821                                   UWORD8 *pu1_cur_pic_chroma, WORD32 i4_chroma_stride,
822                                   UWORD32 *pu4_pic_horz_bs)
823 {
824     UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma;
825     UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;
826 
827     /********/
828     /* luma */
829     /********/
830     u4_qp_luma = (u1_qp_p + u1_qp_q + 1) >> 1;
831 
832     /* filter offset A and filter offset B have to be received from slice header
833      */
834     /* TODO : for now lets set these offsets as zero */
835 
836     u4_idx_A_luma = MIN(51, u4_qp_luma + 0);
837     u4_idx_B_luma = MIN(51, u4_qp_luma + 0);
838 
839     /* alpha, beta computation */
840     u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
841     u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];
842 
843     /**********/
844     /* chroma */
845     /**********/
846     u4_qp_chroma = (gu1_qpc_fqpi[u1_qp_p] + gu1_qpc_fqpi[u1_qp_q] + 1) >> 1;
847 
848     /* filter offset A and filter offset B have to be received from slice header
849      */
850     /* TODO : for now lets set these offsets as zero */
851 
852     u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
853     u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);
854 
855     /* alpha, beta computation */
856     u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
857     u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];
858 
859     /* deblk edge */
860     /* top Horizontal edge - allowed to be deblocked ? */
861     if(pu4_pic_horz_bs[0] == 0x04040404)
862     {
863         /* strong filter */
864         ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
865                                          u4_beta_luma);
866         ps_codec->pf_deblk_chroma_horz_bs4(pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma,
867                                            u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma);
868     }
869     else
870     {
871         /* normal filter */
872         ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
873                                            u4_beta_luma, pu4_pic_horz_bs[0],
874                                            gu1_ih264_clip_table[u4_idx_A_luma]);
875 
876         ps_codec->pf_deblk_chroma_horz_bslt4(
877             pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma,
878             u4_beta_chroma, pu4_pic_horz_bs[0], gu1_ih264_clip_table[u4_idx_A_chroma],
879             gu1_ih264_clip_table[u4_idx_A_chroma]);
880     }
881 }
882 
883 /**
884 *******************************************************************************
885 *
886 * @brief This function performs deblocking of left vertical edge
887 *
888 * @par Description:
889 *  This function performs deblocking of top horizontal edge
890 *
891 * @param[in] ps_codec
892 *  pointer to codec context
893 *
894 * @param[in] ps_proc
895 *  pointer to proc context
896 *
897 * @param[in] pu1_mb_qp
898 *  pointer to mb quantization param
899 *
900 * @param[in] pu1_cur_pic_luma
901 *  pointer to recon buffer luma
902 *
903 * @param[in] pu1_cur_pic_chroma
904 *  pointer to recon buffer chroma
905 *
906 * @param[in] pu4_pic_vert_bs
907 *  pointer to vertical blocking strength
908 *
909 * @returns  none
910 *
911 * @remarks none
912 *
913 *******************************************************************************
914 */
isvce_filter_left_edge(isvce_codec_t * ps_codec,UWORD8 u1_qp_p,UWORD8 u1_qp_q,UWORD8 * pu1_cur_pic_luma,WORD32 i4_luma_stride,UWORD8 * pu1_cur_pic_chroma,WORD32 i4_chroma_stride,UWORD32 * pu4_pic_vert_bs)915 static void isvce_filter_left_edge(isvce_codec_t *ps_codec, UWORD8 u1_qp_p, UWORD8 u1_qp_q,
916                                    UWORD8 *pu1_cur_pic_luma, WORD32 i4_luma_stride,
917                                    UWORD8 *pu1_cur_pic_chroma, WORD32 i4_chroma_stride,
918                                    UWORD32 *pu4_pic_vert_bs)
919 {
920     UWORD32 u4_alpha_luma, u4_beta_luma, u4_qp_luma, u4_idx_A_luma, u4_idx_B_luma;
921     UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;
922 
923     /********/
924     /* luma */
925     /********/
926     u4_qp_luma = (u1_qp_p + u1_qp_q + 1) >> 1;
927 
928     /* filter offset A and filter offset B have to be received from slice header
929      */
930     /* TODO : for now lets set these offsets as zero */
931 
932     u4_idx_A_luma = MIN(51, u4_qp_luma + 0);
933     u4_idx_B_luma = MIN(51, u4_qp_luma + 0);
934 
935     /* alpha, beta computation */
936     u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
937     u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];
938 
939     /**********/
940     /* chroma */
941     /**********/
942     u4_qp_chroma = (gu1_qpc_fqpi[u1_qp_p] + gu1_qpc_fqpi[u1_qp_q] + 1) >> 1;
943 
944     /* filter offset A and filter offset B have to be received from slice header
945      */
946     /* TODO : for now lets set these offsets as zero */
947 
948     u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
949     u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);
950 
951     /* alpha, beta computation */
952     u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
953     u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];
954 
955     /* deblk edge */
956     if(pu4_pic_vert_bs[0] == 0x04040404)
957     {
958         /* strong filter */
959         ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
960                                          u4_beta_luma);
961         ps_codec->pf_deblk_chroma_vert_bs4(pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma,
962                                            u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma);
963     }
964     else
965     {
966         /* normal filter */
967         ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma, i4_luma_stride, u4_alpha_luma,
968                                            u4_beta_luma, pu4_pic_vert_bs[0],
969                                            gu1_ih264_clip_table[u4_idx_A_luma]);
970 
971         ps_codec->pf_deblk_chroma_vert_bslt4(
972             pu1_cur_pic_chroma, i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma,
973             u4_beta_chroma, pu4_pic_vert_bs[0], gu1_ih264_clip_table[u4_idx_A_chroma],
974             gu1_ih264_clip_table[u4_idx_A_chroma]);
975     }
976 }
977 
isvce_get_deblk_mb_qp(isvce_process_ctxt_t * ps_proc,coordinates_t * ps_mb_pos)978 static UWORD8 isvce_get_deblk_mb_qp(isvce_process_ctxt_t *ps_proc, coordinates_t *ps_mb_pos)
979 {
980     UWORD8 u1_mb_qp;
981 
982     isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
983     isvce_bs_ctxt_t *ps_bs_ctxt = &ps_deblk->s_bs_ctxt;
984     coordinates_t s_cur_mb_pos = {ps_deblk->i4_mb_x, ps_deblk->i4_mb_y};
985 
986     UWORD32 u4_mb_idx = ps_mb_pos->i4_abscissa + ps_mb_pos->i4_ordinate * ps_proc->i4_wd_mbs;
987 
988     if((s_cur_mb_pos.i4_abscissa != ps_mb_pos->i4_abscissa) ||
989        (s_cur_mb_pos.i4_ordinate != ps_mb_pos->i4_ordinate))
990     {
991         u1_mb_qp = ps_bs_ctxt->pu1_pic_qp[u4_mb_idx];
992     }
993     else
994     {
995         isvce_mb_info_t *ps_mb_info =
996             ps_proc->ps_cur_mv_buf->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].ps_mb_info +
997             u4_mb_idx;
998 
999         if((0 == ps_mb_pos->i4_abscissa) && (0 == ps_mb_pos->i4_ordinate))
1000         {
1001             u1_mb_qp = ps_mb_info->u1_mb_qp;
1002         }
1003         else
1004         {
1005             if((ps_mb_info->u4_cbp > 0) || (I16x16 == ps_mb_info->u2_mb_type))
1006             {
1007                 u1_mb_qp = ps_mb_info->u1_mb_qp;
1008             }
1009             else
1010             {
1011                 u1_mb_qp = ps_bs_ctxt->pu1_pic_qp[u4_mb_idx - 1];
1012             }
1013         }
1014     }
1015 
1016     return u1_mb_qp;
1017 }
1018 
1019 /**
1020 *******************************************************************************
1021 *
1022 * @brief This function performs deblocking on an mb
1023 *
1024 * @par Description:
1025 *  This function performs deblocking on an mb
1026 *
1027 * @param[in] ps_proc
1028 *  process context corresponding to the job
1029 *
1030 * @param[in] ps_deblk
1031 *  pointer to deblock context
1032 *
1033 * @returns  none
1034 *
1035 * @remarks none
1036 *
1037 *******************************************************************************
1038 */
isvce_deblock_mb(isvce_process_ctxt_t * ps_proc,isvce_deblk_ctxt_t * ps_deblk,UWORD8 u1_inter_layer_deblk_flag)1039 void isvce_deblock_mb(isvce_process_ctxt_t *ps_proc, isvce_deblk_ctxt_t *ps_deblk,
1040                       UWORD8 u1_inter_layer_deblk_flag)
1041 {
1042     UWORD8 u1_mb_a, u1_mb_b;
1043     UWORD32 *pu4_pic_vert_bs;
1044     UWORD32 *pu4_pic_horz_bs;
1045     UWORD8 u1_cur_mb_qp;
1046     UWORD8 u1_left_mb_qp;
1047     UWORD8 u1_top_mb_qp;
1048     UWORD32 u4_alpha_luma, u4_beta_luma, u4_idx_A_luma, u4_idx_B_luma;
1049     UWORD32 u4_alpha_chroma, u4_beta_chroma, u4_qp_chroma, u4_idx_A_chroma, u4_idx_B_chroma;
1050 
1051     isvce_codec_t *ps_codec = ps_proc->ps_codec;
1052     coordinates_t s_cur_mb_pos = {ps_deblk->i4_mb_x, ps_deblk->i4_mb_y};
1053     coordinates_t s_left_mb_pos = {ps_deblk->i4_mb_x - 1, ps_deblk->i4_mb_y};
1054     coordinates_t s_top_mb_pos = {ps_deblk->i4_mb_x, ps_deblk->i4_mb_y - 1};
1055 
1056     WORD32 i4_mb_x = ps_deblk->i4_mb_x, i4_mb_y = ps_deblk->i4_mb_y;
1057     WORD32 i4_luma_stride = ps_deblk->s_rec_pic_buf_props.as_component_bufs[0].i4_data_stride;
1058     UWORD8 *pu1_cur_pic_luma =
1059         (UWORD8 *) (ps_deblk->s_rec_pic_buf_props.as_component_bufs[0].pv_data) +
1060         (i4_mb_x * MB_SIZE) + ((i4_mb_y * MB_SIZE) * i4_luma_stride);
1061     WORD32 i4_chroma_stride = ps_deblk->s_rec_pic_buf_props.as_component_bufs[1].i4_data_stride;
1062     UWORD8 *pu1_cur_pic_chroma =
1063         (UWORD8 *) (ps_deblk->s_rec_pic_buf_props.as_component_bufs[1].pv_data) +
1064         (i4_mb_x * MB_SIZE) + (i4_mb_y * (MB_SIZE / 2) * i4_chroma_stride);
1065     UWORD32 push_ptr = (i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x;
1066 
1067     if(!u1_inter_layer_deblk_flag)
1068     {
1069         pu4_pic_vert_bs = ps_deblk->s_bs_ctxt.pu4_pic_vert_bs;
1070         pu4_pic_horz_bs = ps_deblk->s_bs_ctxt.pu4_pic_horz_bs;
1071     }
1072     else
1073     {
1074         pu4_pic_vert_bs = ps_deblk->s_bs_ctxt.pu4_intra_base_vert_bs;
1075         pu4_pic_horz_bs = ps_deblk->s_bs_ctxt.pu4_intra_base_horz_bs;
1076     }
1077 
1078     /* derive neighbor availability */
1079     /* In slice mode the edges of mbs that lie on the slice boundary are not
1080      * deblocked */
1081     /* deblocking filter idc '2' */
1082     if(ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
1083     {
1084         /* slice index */
1085         UWORD8 *pu1_slice_idx = ps_deblk->pu1_slice_idx;
1086 
1087         pu1_slice_idx += (i4_mb_y * ps_proc->i4_wd_mbs);
1088         /* left macroblock availability */
1089         u1_mb_a = (i4_mb_x == 0 || (pu1_slice_idx[i4_mb_x - 1] != pu1_slice_idx[i4_mb_x])) ? 0 : 1;
1090         /* top macroblock availability */
1091         u1_mb_b = (i4_mb_y == 0 ||
1092                    (pu1_slice_idx[i4_mb_x - ps_proc->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))
1093                       ? 0
1094                       : 1;
1095     }
1096     else
1097     {
1098         /* left macroblock availability */
1099         u1_mb_a = (i4_mb_x == 0) ? 0 : 1;
1100         /* top macroblock availability */
1101         u1_mb_b = (i4_mb_y == 0) ? 0 : 1;
1102     }
1103 
1104     pu4_pic_vert_bs += push_ptr * NUM_EDGES_IN_MB;
1105     pu4_pic_horz_bs += push_ptr * NUM_EDGES_IN_MB;
1106 
1107     /********/
1108     /* luma */
1109     /********/
1110     u1_cur_mb_qp = isvce_get_deblk_mb_qp(ps_proc, &s_cur_mb_pos);
1111     ps_deblk->s_bs_ctxt.pu1_pic_qp[push_ptr] = u1_cur_mb_qp;
1112 
1113     /* filter offset A and filter offset B have to be received from slice header
1114      */
1115     /* TODO : for now lets set these offsets as zero */
1116 
1117     u4_idx_A_luma = MIN(51, u1_cur_mb_qp + 0);
1118     u4_idx_B_luma = MIN(51, u1_cur_mb_qp + 0);
1119 
1120     /* alpha, beta computation */
1121     u4_alpha_luma = gu1_ih264_alpha_table[u4_idx_A_luma];
1122     u4_beta_luma = gu1_ih264_beta_table[u4_idx_B_luma];
1123 
1124     /**********/
1125     /* chroma */
1126     /**********/
1127     u4_qp_chroma = gu1_qpc_fqpi[u1_cur_mb_qp];
1128 
1129     /* filter offset A and filter offset B have to be received from slice header
1130      */
1131     /* TODO : for now lets set these offsets as zero */
1132 
1133     u4_idx_A_chroma = MIN(51, u4_qp_chroma + 0);
1134     u4_idx_B_chroma = MIN(51, u4_qp_chroma + 0);
1135 
1136     /* alpha, beta computation */
1137     u4_alpha_chroma = gu1_ih264_alpha_table[u4_idx_A_chroma];
1138     u4_beta_chroma = gu1_ih264_beta_table[u4_idx_B_chroma];
1139 
1140     /* Deblock vertical edges */
1141     /* left vertical edge 0 - allowed to be deblocked ? */
1142     if(u1_mb_a)
1143     {
1144         u1_left_mb_qp = isvce_get_deblk_mb_qp(ps_proc, &s_left_mb_pos);
1145 
1146         isvce_filter_left_edge(ps_codec, u1_left_mb_qp, u1_cur_mb_qp, pu1_cur_pic_luma,
1147                                i4_luma_stride, pu1_cur_pic_chroma, i4_chroma_stride,
1148                                pu4_pic_vert_bs);
1149     }
1150 
1151     /* vertical edge 1 */
1152     if(pu4_pic_vert_bs[1] == 0x04040404)
1153     {
1154         /* strong filter */
1155         ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 4, i4_luma_stride, u4_alpha_luma,
1156                                          u4_beta_luma);
1157     }
1158     else
1159     {
1160         /* normal filter */
1161         ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 4, i4_luma_stride, u4_alpha_luma,
1162                                            u4_beta_luma, pu4_pic_vert_bs[1],
1163                                            gu1_ih264_clip_table[u4_idx_A_luma]);
1164     }
1165 
1166     /* vertical edge 2 */
1167     if(pu4_pic_vert_bs[2] == 0x04040404)
1168     {
1169         /* strong filter */
1170         ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 8, i4_luma_stride, u4_alpha_luma,
1171                                          u4_beta_luma);
1172         ps_codec->pf_deblk_chroma_vert_bs4(pu1_cur_pic_chroma + 8, i4_chroma_stride,
1173                                            u4_alpha_chroma, u4_beta_chroma, u4_alpha_chroma,
1174                                            u4_beta_chroma);
1175     }
1176     else
1177     {
1178         /* normal filter */
1179         ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 8, i4_luma_stride, u4_alpha_luma,
1180                                            u4_beta_luma, pu4_pic_vert_bs[2],
1181                                            gu1_ih264_clip_table[u4_idx_A_luma]);
1182 
1183         ps_codec->pf_deblk_chroma_vert_bslt4(
1184             pu1_cur_pic_chroma + 8, i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma,
1185             u4_alpha_chroma, u4_beta_chroma, pu4_pic_vert_bs[2],
1186             gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
1187     }
1188 
1189     /* vertical edge 3 */
1190     if(pu4_pic_vert_bs[3] == 0x04040404)
1191     {
1192         /* strong filter */
1193         ps_codec->pf_deblk_luma_vert_bs4(pu1_cur_pic_luma + 12, i4_luma_stride, u4_alpha_luma,
1194                                          u4_beta_luma);
1195     }
1196     else
1197     {
1198         /* normal filter */
1199         ps_codec->pf_deblk_luma_vert_bslt4(pu1_cur_pic_luma + 12, i4_luma_stride, u4_alpha_luma,
1200                                            u4_beta_luma, pu4_pic_vert_bs[3],
1201                                            gu1_ih264_clip_table[u4_idx_A_luma]);
1202     }
1203 
1204     /* Deblock Horizontal edges */
1205     /* Horizontal edge 0 */
1206     if(u1_mb_b)
1207     {
1208         u1_top_mb_qp = isvce_get_deblk_mb_qp(ps_proc, &s_top_mb_pos);
1209 
1210         isvce_filter_top_edge(ps_codec, u1_top_mb_qp, u1_cur_mb_qp, pu1_cur_pic_luma,
1211                               i4_luma_stride, pu1_cur_pic_chroma, i4_chroma_stride,
1212                               pu4_pic_horz_bs);
1213     }
1214 
1215     /* horizontal edge 1 */
1216     if(pu4_pic_horz_bs[1] == 0x04040404)
1217     {
1218         /* strong filter */
1219         ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 4 * i4_luma_stride, i4_luma_stride,
1220                                          u4_alpha_luma, u4_beta_luma);
1221     }
1222     else
1223     {
1224         /* normal filter */
1225         ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 4 * i4_luma_stride, i4_luma_stride,
1226                                            u4_alpha_luma, u4_beta_luma, pu4_pic_horz_bs[1],
1227                                            gu1_ih264_clip_table[u4_idx_A_luma]);
1228     }
1229 
1230     /* horizontal edge 2 */
1231     if(pu4_pic_horz_bs[2] == 0x04040404)
1232     {
1233         /* strong filter */
1234         ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 8 * i4_luma_stride, i4_luma_stride,
1235                                          u4_alpha_luma, u4_beta_luma);
1236         ps_codec->pf_deblk_chroma_horz_bs4(pu1_cur_pic_chroma + 4 * i4_chroma_stride,
1237                                            i4_chroma_stride, u4_alpha_chroma, u4_beta_chroma,
1238                                            u4_alpha_chroma, u4_beta_chroma);
1239     }
1240     else
1241     {
1242         /* normal filter */
1243         ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 8 * i4_luma_stride, i4_luma_stride,
1244                                            u4_alpha_luma, u4_beta_luma, pu4_pic_horz_bs[2],
1245                                            gu1_ih264_clip_table[u4_idx_A_luma]);
1246 
1247         ps_codec->pf_deblk_chroma_horz_bslt4(
1248             pu1_cur_pic_chroma + 4 * i4_chroma_stride, i4_chroma_stride, u4_alpha_chroma,
1249             u4_beta_chroma, u4_alpha_chroma, u4_beta_chroma, pu4_pic_horz_bs[2],
1250             gu1_ih264_clip_table[u4_idx_A_chroma], gu1_ih264_clip_table[u4_idx_A_chroma]);
1251     }
1252 
1253     /* horizontal edge 3 */
1254     if(pu4_pic_horz_bs[3] == 0x04040404)
1255     {
1256         /* strong filter */
1257         ps_codec->pf_deblk_luma_horz_bs4(pu1_cur_pic_luma + 12 * i4_luma_stride, i4_luma_stride,
1258                                          u4_alpha_luma, u4_beta_luma);
1259     }
1260     else
1261     {
1262         /* normal filter */
1263         ps_codec->pf_deblk_luma_horz_bslt4(pu1_cur_pic_luma + 12 * i4_luma_stride, i4_luma_stride,
1264                                            u4_alpha_luma, u4_beta_luma, pu4_pic_horz_bs[3],
1265                                            gu1_ih264_clip_table[u4_idx_A_luma]);
1266     }
1267 }
1268