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