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 * @file
23 * isvcd_mb_utils.c
24 *
25 * @brief
26 * Contains utitlity functions needed for Macroblock decoding
27 *
28 * @author
29 * Kishore
30 *
31 * @par List of Functions:
32 * - isvcd_get_mb_info_cabac_nonmbaff()
33 *
34 * @remarks
35 * None
36 *
37 *******************************************************************************
38 */
39
40 #include <string.h>
41 #include <stdlib.h>
42 #include "ih264d_bitstrm.h"
43 #include "ih264d_defs.h"
44 #include "ih264d_debug.h"
45 #include "isvcd_structs.h"
46 #include "ih264d_defs.h"
47 #include "ih264d_mb_utils.h"
48 #include "ih264d_parse_slice.h"
49 #include "ih264d_error_handler.h"
50 #include "ih264d_parse_mb_header.h"
51 #include "ih264d_cabac.h"
52 #include "ih264d_defs.h"
53 #include "ih264d_tables.h"
54
55 /*****************************************************************************/
56 /* */
57 /* Function Name : get_mb_info_cabac */
58 /* */
59 /* Description : This function sets the following information of cur MB */
60 /* (a) mb_x and mb_y */
61 /* (b) Neighbour availablity */
62 /* (c) Macroblock location in the frame buffer */
63 /* (e) leftMb parama and TopMb params of curMB */
64 /* (f) For Mbaff case leftMb params and TopMb params of */
65 /* bottomMb are also set if curMB is top */
66 /* (g) For mbaff predicts field/frame u4_flag for topMb */
67 /* and sets the field/frame for botMb. This is */
68 /* written in ps_dec->u1_cur_mb_fld_dec_flag */
69 /* */
70 /* Inputs : pointer to decstruct */
71 /* pointer to current mb info */
72 /* currentMbaddress */
73 /* */
74 /* Processing : leftMb and TopMb params are used by DecMbskip and */
75 /* DecCtxMbfield modules so that these modules do not */
76 /* check for neigbour availability and then find the */
77 /* neigbours for context increments */
78 /* */
79 /* Returns : OK */
80 /* */
81 /* Issues : <List any issues or problems with this function> */
82 /* */
83 /* Revision History: */
84 /* */
85 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
86 /* 06 09 2021 Kishore Draft */
87 /* */
88 /*****************************************************************************/
isvcd_get_mb_info_cabac_nonmbaff(dec_struct_t * ps_dec,const UWORD16 u2_cur_mb_address,dec_mb_info_t * ps_cur_mb_info,UWORD32 u4_mbskip)89 UWORD32 isvcd_get_mb_info_cabac_nonmbaff(dec_struct_t *ps_dec, const UWORD16 u2_cur_mb_address,
90 dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mbskip)
91 {
92 WORD32 mb_x;
93 WORD32 mb_y;
94 UWORD32 u1_mb_ngbr_avail = 0;
95 UWORD32 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs;
96 UWORD32 u1_top_mb = 1;
97 WORD32 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx;
98 UWORD32 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE;
99 UWORD32 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE;
100 ctxt_inc_mb_info_t *const p_ctx_inc_mb_map = ps_dec->p_ctxt_inc_mb_map;
101
102 /*--------------------------------------------------------------------*/
103 /* Calculate values of mb_x and mb_y */
104 /*--------------------------------------------------------------------*/
105 mb_x = (WORD16) ps_dec->u2_mbx;
106 mb_y = (WORD16) ps_dec->u2_mby;
107 ps_dec->u2_cur_mb_addr = u2_cur_mb_address;
108
109 mb_x++;
110 if((UWORD32) mb_x == u2_frm_width_in_mb)
111 {
112 mb_x = 0;
113 mb_y++;
114 if(mb_y >= ps_dec->u2_frm_ht_in_mbs)
115 {
116 mb_y = ps_dec->u2_frm_ht_in_mbs - 1;
117 }
118 }
119 /*********************************************************************/
120 /* Cabac Context Initialisations */
121 /*********************************************************************/
122 ps_dec->ps_curr_ctxt_mb_info = p_ctx_inc_mb_map + mb_x;
123 ps_dec->p_left_ctxt_mb_info = p_ctx_inc_mb_map - 1;
124 ps_dec->p_top_ctxt_mb_info = p_ctx_inc_mb_map - 1;
125
126 /********************************************************************/
127 /* neighbour availablility */
128 /********************************************************************/
129 if(mb_y > ps_dec->i2_prev_slice_mby)
130 {
131 /* if not in the immemdiate row of prev slice end then top will be available */
132 if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) i2_prev_slice_mbx = -1;
133
134 if(mb_x > i2_prev_slice_mbx)
135 {
136 u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK;
137 u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE;
138 u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE;
139 ps_dec->p_top_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info;
140 }
141 if((mb_x > (i2_prev_slice_mbx - 1)) && ((UWORD32) mb_x != (u2_frm_width_in_mb - 1)))
142 {
143 u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK;
144 u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE;
145 }
146
147 if(mb_x > (i2_prev_slice_mbx + 1))
148 {
149 u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK;
150 u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE;
151 }
152 /* Next row */
153 i2_prev_slice_mbx = -1;
154 }
155 /* Same row */
156 if(mb_x > (i2_prev_slice_mbx + 1))
157 {
158 u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK;
159 u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE;
160 ps_dec->p_left_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info - 1;
161 }
162 {
163 mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row;
164 mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row;
165 /* copy the parameters of topleft Mb */
166 ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype;
167 /* Neighbour pointer assignments*/
168 ps_cur_mb_info->ps_curmb = ps_cur_mb_row + mb_x;
169 ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1;
170 ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x;
171 ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + mb_x + 1;
172
173 /* Update the parameters of topleftmb*/
174 ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type;
175 }
176
177 ps_dec->u2_mby = mb_y;
178 ps_dec->u2_mbx = mb_x;
179 ps_cur_mb_info->u2_mbx = mb_x;
180 ps_cur_mb_info->u2_mby = mb_y;
181 ps_cur_mb_info->u1_topmb = u1_top_mb;
182 ps_dec->i4_submb_ofst += SUB_BLK_SIZE;
183 ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
184 ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
185 ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag;
186 ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag;
187 ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask;
188 ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask;
189
190 /*********************************************************************/
191 /* Assign the neigbours */
192 /*********************************************************************/
193 if(u4_mbskip)
194 {
195 UWORD8 u1_a, u1_b;
196 UWORD32 u4_ctx_inc;
197
198 u1_a = (ps_dec->p_top_ctxt_mb_info->u1_mb_type != CAB_INFERRED)
199 ? (!!(ps_dec->p_top_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK))
200 : 0;
201 u1_b = (ps_dec->p_left_ctxt_mb_info->u1_mb_type != CAB_INFERRED)
202 ? (!!(ps_dec->p_left_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK))
203 : 0;
204 u4_ctx_inc = 2 - (u1_a + u1_b);
205
206 u4_mbskip = ih264d_decode_bin(u4_ctx_inc, ps_dec->p_mb_skip_flag_t, ps_dec->ps_bitstrm,
207 &ps_dec->s_cab_dec_env);
208
209 if(!u4_mbskip)
210 {
211 if(!(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK))
212 {
213 UWORD32 *pu4_buf;
214 UWORD8 *pu1_buf;
215
216 pu1_buf = ps_dec->pu1_left_nnz_y;
217 pu4_buf = (UWORD32 *) pu1_buf;
218 *pu4_buf = 0;
219 pu1_buf = ps_dec->pu1_left_nnz_uv;
220 pu4_buf = (UWORD32 *) pu1_buf;
221 *pu4_buf = 0;
222
223 *(ps_dec->pu1_left_yuv_dc_csbp) = 0;
224 MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0);
225 *(UWORD32 *) ps_dec->pi1_left_ref_idx_ctxt_inc = 0;
226 }
227 if(!(u1_mb_ngbr_avail & TOP_MB_AVAILABLE_MASK))
228 {
229 MEMSET_16BYTES(ps_dec->ps_curr_ctxt_mb_info->u1_mv, 0);
230 memset(ps_dec->ps_curr_ctxt_mb_info->i1_ref_idx, 0, 4);
231 }
232 }
233 }
234 return (u4_mbskip);
235 }
236
237 /*****************************************************************************/
238 /* */
239 /* Function Name : isvcd_get_mb_info_cavlc_nonmbaff */
240 /* */
241 /* Description : This function sets the following information of cur MB */
242 /* (a) mb_x and mb_y */
243 /* (b) Neighbour availablity */
244 /* (c) Macroblock location in the frame buffer */
245 /* (e) For mbaff predicts field/frame u4_flag for topMb */
246 /* and sets the field/frame for botMb. This is */
247 /* written in ps_dec->u1_cur_mb_fld_dec_flag */
248 /* */
249 /* Inputs : pointer to decstruct */
250 /* pointer to current mb info */
251 /* currentMbaddress */
252 /* */
253 /* Processing : leftMb and TopMb params are used by DecMbskip and */
254 /* DecCtxMbfield modules so that these modules do not */
255 /* check for neigbour availability and then find the */
256 /* neigbours for context increments */
257 /* */
258 /* Returns : OK */
259 /* */
260 /* Issues : <List any issues or problems with this function> */
261 /* */
262 /* Revision History: */
263 /* */
264 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
265 /* 24 01 2023 Kishore Draft */
266 /* */
267 /*****************************************************************************/
268
isvcd_get_mb_info_cavlc_nonmbaff(dec_struct_t * ps_dec,const UWORD16 u2_cur_mb_address,dec_mb_info_t * ps_cur_mb_info,UWORD32 u4_mbskip_run)269 UWORD32 isvcd_get_mb_info_cavlc_nonmbaff(dec_struct_t *ps_dec, const UWORD16 u2_cur_mb_address,
270 dec_mb_info_t *ps_cur_mb_info, UWORD32 u4_mbskip_run)
271 {
272 WORD32 mb_x;
273 WORD32 mb_y;
274 UWORD8 u1_mb_ngbr_avail = 0;
275 UWORD16 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs;
276 WORD16 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx;
277 UWORD16 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE;
278 UWORD16 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE;
279 UNUSED(u4_mbskip_run);
280 /*--------------------------------------------------------------------*/
281 /* Calculate values of mb_x and mb_y */
282 /*--------------------------------------------------------------------*/
283 mb_x = (WORD16) ps_dec->u2_mbx;
284 mb_y = (WORD16) ps_dec->u2_mby;
285
286 ps_dec->u2_cur_mb_addr = u2_cur_mb_address;
287
288 mb_x++;
289
290 if(mb_x == u2_frm_width_in_mb)
291 {
292 mb_x = 0;
293 mb_y++;
294 if(mb_y >= ps_dec->u2_frm_ht_in_mbs)
295 {
296 mb_y = ps_dec->u2_frm_ht_in_mbs - 1;
297 }
298 }
299 if(mb_y > ps_dec->i2_prev_slice_mby)
300 {
301 /* if not in the immemdiate row of prev slice end then top
302 will be available */
303 if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) i2_prev_slice_mbx = -1;
304
305 if(mb_x > i2_prev_slice_mbx)
306 {
307 u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK;
308 u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE;
309 u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE;
310 }
311
312 if((mb_x > (i2_prev_slice_mbx - 1)) && (mb_x != (u2_frm_width_in_mb - 1)))
313 {
314 u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK;
315 u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE;
316 }
317
318 if(mb_x > (i2_prev_slice_mbx + 1))
319 {
320 u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK;
321 u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE;
322 }
323
324 /* Next row Left will be available*/
325 i2_prev_slice_mbx = -1;
326 }
327
328 /* Same row */
329 if(mb_x > (i2_prev_slice_mbx + 1))
330 {
331 u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK;
332 u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE;
333 }
334
335 {
336 mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row;
337 mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row;
338
339 /* copy the parameters of topleft Mb */
340 ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype;
341 /* Neighbour pointer assignments*/
342 ps_cur_mb_info->ps_curmb = ps_cur_mb_row + mb_x;
343 ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1;
344 ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x;
345 ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + mb_x + 1;
346
347 /* Update the parameters of topleftmb*/
348 ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type;
349 }
350
351 ps_dec->u2_mby = mb_y;
352 ps_dec->u2_mbx = mb_x;
353 ps_cur_mb_info->u2_mbx = mb_x;
354 ps_cur_mb_info->u2_mby = mb_y;
355 ps_cur_mb_info->u1_topmb = 1;
356 ps_dec->i4_submb_ofst += SUB_BLK_SIZE;
357 ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
358 ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail;
359 ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag;
360 ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag;
361 ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask;
362 ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask;
363 return (OK);
364 }
365