/src/libavc/decoder/svc/isvcd_mb_utils.c
Line | Count | Source (jump to first uncovered line) |
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 | | /*****************************************************************************/ |
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 | 1.23M | { |
92 | 1.23M | WORD32 mb_x; |
93 | 1.23M | WORD32 mb_y; |
94 | 1.23M | UWORD32 u1_mb_ngbr_avail = 0; |
95 | 1.23M | UWORD32 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs; |
96 | 1.23M | UWORD32 u1_top_mb = 1; |
97 | 1.23M | WORD32 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx; |
98 | 1.23M | UWORD32 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE; |
99 | 1.23M | UWORD32 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE; |
100 | 1.23M | 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 | 1.23M | mb_x = (WORD16) ps_dec->u2_mbx; |
106 | 1.23M | mb_y = (WORD16) ps_dec->u2_mby; |
107 | 1.23M | ps_dec->u2_cur_mb_addr = u2_cur_mb_address; |
108 | | |
109 | 1.23M | mb_x++; |
110 | 1.23M | if((UWORD32) mb_x == u2_frm_width_in_mb) |
111 | 156k | { |
112 | 156k | mb_x = 0; |
113 | 156k | mb_y++; |
114 | 156k | if(mb_y >= ps_dec->u2_frm_ht_in_mbs) |
115 | 0 | { |
116 | 0 | mb_y = ps_dec->u2_frm_ht_in_mbs - 1; |
117 | 0 | } |
118 | 156k | } |
119 | | /*********************************************************************/ |
120 | | /* Cabac Context Initialisations */ |
121 | | /*********************************************************************/ |
122 | 1.23M | ps_dec->ps_curr_ctxt_mb_info = p_ctx_inc_mb_map + mb_x; |
123 | 1.23M | ps_dec->p_left_ctxt_mb_info = p_ctx_inc_mb_map - 1; |
124 | 1.23M | ps_dec->p_top_ctxt_mb_info = p_ctx_inc_mb_map - 1; |
125 | | |
126 | | /********************************************************************/ |
127 | | /* neighbour availablility */ |
128 | | /********************************************************************/ |
129 | 1.23M | if(mb_y > ps_dec->i2_prev_slice_mby) |
130 | 1.07M | { |
131 | | /* if not in the immemdiate row of prev slice end then top will be available */ |
132 | 1.07M | if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) i2_prev_slice_mbx = -1; |
133 | | |
134 | 1.07M | if(mb_x > i2_prev_slice_mbx) |
135 | 1.06M | { |
136 | 1.06M | u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; |
137 | 1.06M | u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; |
138 | 1.06M | u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; |
139 | 1.06M | ps_dec->p_top_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info; |
140 | 1.06M | } |
141 | 1.07M | if((mb_x > (i2_prev_slice_mbx - 1)) && ((UWORD32) mb_x != (u2_frm_width_in_mb - 1))) |
142 | 915k | { |
143 | 915k | u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK; |
144 | 915k | u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE; |
145 | 915k | } |
146 | | |
147 | 1.07M | if(mb_x > (i2_prev_slice_mbx + 1)) |
148 | 904k | { |
149 | 904k | u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; |
150 | 904k | u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; |
151 | 904k | } |
152 | | /* Next row */ |
153 | 1.07M | i2_prev_slice_mbx = -1; |
154 | 1.07M | } |
155 | | /* Same row */ |
156 | 1.23M | if(mb_x > (i2_prev_slice_mbx + 1)) |
157 | 1.05M | { |
158 | 1.05M | u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK; |
159 | 1.05M | u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; |
160 | 1.05M | ps_dec->p_left_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info - 1; |
161 | 1.05M | } |
162 | 1.23M | { |
163 | 1.23M | mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row; |
164 | 1.23M | mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row; |
165 | | /* copy the parameters of topleft Mb */ |
166 | 1.23M | ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype; |
167 | | /* Neighbour pointer assignments*/ |
168 | 1.23M | ps_cur_mb_info->ps_curmb = ps_cur_mb_row + mb_x; |
169 | 1.23M | ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1; |
170 | 1.23M | ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x; |
171 | 1.23M | ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + mb_x + 1; |
172 | | |
173 | | /* Update the parameters of topleftmb*/ |
174 | 1.23M | ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type; |
175 | 1.23M | } |
176 | | |
177 | 1.23M | ps_dec->u2_mby = mb_y; |
178 | 1.23M | ps_dec->u2_mbx = mb_x; |
179 | 1.23M | ps_cur_mb_info->u2_mbx = mb_x; |
180 | 1.23M | ps_cur_mb_info->u2_mby = mb_y; |
181 | 1.23M | ps_cur_mb_info->u1_topmb = u1_top_mb; |
182 | 1.23M | ps_dec->i4_submb_ofst += SUB_BLK_SIZE; |
183 | 1.23M | ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; |
184 | 1.23M | ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; |
185 | 1.23M | ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag; |
186 | 1.23M | ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag; |
187 | 1.23M | ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask; |
188 | 1.23M | ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask; |
189 | | |
190 | | /*********************************************************************/ |
191 | | /* Assign the neigbours */ |
192 | | /*********************************************************************/ |
193 | 1.23M | if(u4_mbskip) |
194 | 1.13M | { |
195 | 1.13M | UWORD8 u1_a, u1_b; |
196 | 1.13M | UWORD32 u4_ctx_inc; |
197 | | |
198 | 1.13M | u1_a = (ps_dec->p_top_ctxt_mb_info->u1_mb_type != CAB_INFERRED) |
199 | 1.13M | ? (!!(ps_dec->p_top_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK)) |
200 | 1.13M | : 0; |
201 | 1.13M | u1_b = (ps_dec->p_left_ctxt_mb_info->u1_mb_type != CAB_INFERRED) |
202 | 1.13M | ? (!!(ps_dec->p_left_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK)) |
203 | 1.13M | : 0; |
204 | 1.13M | u4_ctx_inc = 2 - (u1_a + u1_b); |
205 | | |
206 | 1.13M | u4_mbskip = ih264d_decode_bin(u4_ctx_inc, ps_dec->p_mb_skip_flag_t, ps_dec->ps_bitstrm, |
207 | 1.13M | &ps_dec->s_cab_dec_env); |
208 | | |
209 | 1.13M | if(!u4_mbskip) |
210 | 291k | { |
211 | 291k | if(!(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK)) |
212 | 69.2k | { |
213 | 69.2k | UWORD32 *pu4_buf; |
214 | 69.2k | UWORD8 *pu1_buf; |
215 | | |
216 | 69.2k | pu1_buf = ps_dec->pu1_left_nnz_y; |
217 | 69.2k | pu4_buf = (UWORD32 *) pu1_buf; |
218 | 69.2k | *pu4_buf = 0; |
219 | 69.2k | pu1_buf = ps_dec->pu1_left_nnz_uv; |
220 | 69.2k | pu4_buf = (UWORD32 *) pu1_buf; |
221 | 69.2k | *pu4_buf = 0; |
222 | | |
223 | 69.2k | *(ps_dec->pu1_left_yuv_dc_csbp) = 0; |
224 | 69.2k | MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0); |
225 | 69.2k | *(UWORD32 *) ps_dec->pi1_left_ref_idx_ctxt_inc = 0; |
226 | 69.2k | } |
227 | 291k | if(!(u1_mb_ngbr_avail & TOP_MB_AVAILABLE_MASK)) |
228 | 43.1k | { |
229 | 43.1k | MEMSET_16BYTES(ps_dec->ps_curr_ctxt_mb_info->u1_mv, 0); |
230 | 43.1k | memset(ps_dec->ps_curr_ctxt_mb_info->i1_ref_idx, 0, 4); |
231 | 43.1k | } |
232 | 291k | } |
233 | 1.13M | } |
234 | 1.23M | return (u4_mbskip); |
235 | 1.23M | } |
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 | | |
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 | 14.3M | { |
272 | 14.3M | WORD32 mb_x; |
273 | 14.3M | WORD32 mb_y; |
274 | 14.3M | UWORD8 u1_mb_ngbr_avail = 0; |
275 | 14.3M | UWORD16 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs; |
276 | 14.3M | WORD16 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx; |
277 | 14.3M | UWORD16 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE; |
278 | 14.3M | UWORD16 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE; |
279 | 14.3M | UNUSED(u4_mbskip_run); |
280 | | /*--------------------------------------------------------------------*/ |
281 | | /* Calculate values of mb_x and mb_y */ |
282 | | /*--------------------------------------------------------------------*/ |
283 | 14.3M | mb_x = (WORD16) ps_dec->u2_mbx; |
284 | 14.3M | mb_y = (WORD16) ps_dec->u2_mby; |
285 | | |
286 | 14.3M | ps_dec->u2_cur_mb_addr = u2_cur_mb_address; |
287 | | |
288 | 14.3M | mb_x++; |
289 | | |
290 | 14.3M | if(mb_x == u2_frm_width_in_mb) |
291 | 2.06M | { |
292 | 2.06M | mb_x = 0; |
293 | 2.06M | mb_y++; |
294 | 2.06M | if(mb_y >= ps_dec->u2_frm_ht_in_mbs) |
295 | 0 | { |
296 | 0 | mb_y = ps_dec->u2_frm_ht_in_mbs - 1; |
297 | 0 | } |
298 | 2.06M | } |
299 | 14.3M | if(mb_y > ps_dec->i2_prev_slice_mby) |
300 | 13.5M | { |
301 | | /* if not in the immemdiate row of prev slice end then top |
302 | | will be available */ |
303 | 13.5M | if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) i2_prev_slice_mbx = -1; |
304 | | |
305 | 13.5M | if(mb_x > i2_prev_slice_mbx) |
306 | 13.4M | { |
307 | 13.4M | u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; |
308 | 13.4M | u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; |
309 | 13.4M | u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; |
310 | 13.4M | } |
311 | | |
312 | 13.5M | if((mb_x > (i2_prev_slice_mbx - 1)) && (mb_x != (u2_frm_width_in_mb - 1))) |
313 | 11.4M | { |
314 | 11.4M | u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK; |
315 | 11.4M | u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE; |
316 | 11.4M | } |
317 | | |
318 | 13.5M | if(mb_x > (i2_prev_slice_mbx + 1)) |
319 | 11.3M | { |
320 | 11.3M | u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; |
321 | 11.3M | u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; |
322 | 11.3M | } |
323 | | |
324 | | /* Next row Left will be available*/ |
325 | 13.5M | i2_prev_slice_mbx = -1; |
326 | 13.5M | } |
327 | | |
328 | | /* Same row */ |
329 | 14.3M | if(mb_x > (i2_prev_slice_mbx + 1)) |
330 | 12.0M | { |
331 | 12.0M | u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK; |
332 | 12.0M | u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; |
333 | 12.0M | } |
334 | | |
335 | 14.3M | { |
336 | 14.3M | mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row; |
337 | 14.3M | mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row; |
338 | | |
339 | | /* copy the parameters of topleft Mb */ |
340 | 14.3M | ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype; |
341 | | /* Neighbour pointer assignments*/ |
342 | 14.3M | ps_cur_mb_info->ps_curmb = ps_cur_mb_row + mb_x; |
343 | 14.3M | ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1; |
344 | 14.3M | ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x; |
345 | 14.3M | ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + mb_x + 1; |
346 | | |
347 | | /* Update the parameters of topleftmb*/ |
348 | 14.3M | ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type; |
349 | 14.3M | } |
350 | | |
351 | 14.3M | ps_dec->u2_mby = mb_y; |
352 | 14.3M | ps_dec->u2_mbx = mb_x; |
353 | 14.3M | ps_cur_mb_info->u2_mbx = mb_x; |
354 | 14.3M | ps_cur_mb_info->u2_mby = mb_y; |
355 | 14.3M | ps_cur_mb_info->u1_topmb = 1; |
356 | 14.3M | ps_dec->i4_submb_ofst += SUB_BLK_SIZE; |
357 | 14.3M | ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; |
358 | 14.3M | ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; |
359 | 14.3M | ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag; |
360 | 14.3M | ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag; |
361 | 14.3M | ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask; |
362 | 14.3M | ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask; |
363 | 14.3M | return (OK); |
364 | 14.3M | } |