Coverage Report

Created: 2026-02-14 06:46

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