xref: /aosp_15_r20/external/libavc/decoder/svc/isvcd_mb_utils.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  * @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