Coverage Report

Created: 2026-08-13 07:21

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