Coverage Report

Created: 2025-11-12 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavc/decoder/mvc/imvcd_error_handler.c
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Copyright (C) 2021 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
/*                                                                           */
23
/*  File Name         : imvcd_error_handler.c                                */
24
/*                                                                           */
25
/*  Description       : Functions for error handling                         */
26
/*                                                                           */
27
/*****************************************************************************/
28
29
#include "ih264_typedefs.h"
30
#include "iv.h"
31
#include "imvcd.h"
32
#include "ih264_macros.h"
33
#include "imvc_defs.h"
34
#include "ih264d_defs.h"
35
#include "ih264d_error_handler.h"
36
#include "ih264d_nal.h"
37
#include "ih264d_structs.h"
38
#include "imvcd_structs.h"
39
#include "imvcd_utils.h"
40
41
static IV_API_CALL_STATUS_T imvcd_check_invalid_numViews(mvc_dec_ctxt_t *ps_mvcd_ctxt)
42
117k
{
43
117k
    WORD32 i;
44
45
117k
    UWORD8 u1_num_valid_subset_sps_found = 0;
46
117k
    UWORD16 u2_max_views = 1;
47
48
117k
    if((ps_mvcd_ctxt->u1_num_subset_sps == 0) && (ps_mvcd_ctxt->u2_num_views_decoded > 0))
49
0
    {
50
0
        return IV_FAIL;
51
0
    }
52
53
3.88M
    for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
54
3.77M
    {
55
3.77M
        if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
56
3.89k
        {
57
3.89k
            if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_mvc_ext.u2_num_views > MAX_NUM_VIEWS)
58
0
            {
59
0
                return IV_FAIL;
60
0
            }
61
62
3.89k
            u2_max_views =
63
3.89k
                MAX(u2_max_views, ps_mvcd_ctxt->as_subset_sps[i].s_sps_mvc_ext.u2_num_views);
64
3.89k
            u1_num_valid_subset_sps_found++;
65
3.89k
        }
66
3.77M
    }
67
68
117k
    if(u1_num_valid_subset_sps_found > ps_mvcd_ctxt->u1_num_subset_sps)
69
0
    {
70
0
        return IV_FAIL;
71
0
    }
72
73
117k
    if(ps_mvcd_ctxt->u2_num_views > u2_max_views)
74
3
    {
75
3
        return IV_FAIL;
76
3
    }
77
78
117k
    if(ps_mvcd_ctxt->u2_num_views_decoded >= u2_max_views)
79
0
    {
80
0
        return IV_FAIL;
81
0
    }
82
83
117k
    return IV_SUCCESS;
84
117k
}
85
86
static IV_API_CALL_STATUS_T imvcd_check_sps_and_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
87
117k
{
88
117k
    UWORD32 i;
89
117k
    UWORD32 u4_cnt;
90
91
117k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
92
93
117k
    UWORD32 u4_num_sps = ps_mvcd_ctxt->u1_num_sps;
94
117k
    UWORD32 u4_num_subset_sps = ps_mvcd_ctxt->u1_num_subset_sps;
95
117k
    WORD32 i4_max_mb_addr = INT32_MIN;
96
97
117k
    i = 0;
98
117k
    u4_cnt = 0;
99
100
358k
    while((u4_cnt < u4_num_sps) && (i < MAX_NUM_SEQ_PARAMS))
101
241k
    {
102
241k
        if(ps_view_ctxt->ps_sps[i].u1_is_valid)
103
127k
        {
104
127k
            u4_cnt++;
105
106
127k
            if(i4_max_mb_addr == INT32_MIN)
107
117k
            {
108
117k
                i4_max_mb_addr = ps_view_ctxt->ps_sps[i].u4_max_mb_addr;
109
117k
            }
110
9.78k
            else if(i4_max_mb_addr != ps_view_ctxt->ps_sps[i].u4_max_mb_addr)
111
0
            {
112
0
                return IV_FAIL;
113
0
            }
114
115
127k
            if(ps_view_ctxt->ps_sps[i].u4_max_mb_addr >
116
127k
               imvcd_get_num_mbs_in_level(ps_view_ctxt->ps_sps[i].u1_level_idc))
117
18
            {
118
18
                return IV_FAIL;
119
18
            }
120
121
127k
            if(ps_view_ctxt->ps_sps[i].u1_mb_aff_flag)
122
12
            {
123
12
                return IV_FAIL;
124
12
            }
125
126
127k
            if(!ps_view_ctxt->ps_sps[i].u1_frame_mbs_only_flag)
127
35
            {
128
35
                return IV_FAIL;
129
35
            }
130
127k
        }
131
132
241k
        i++;
133
241k
    }
134
135
117k
    if(u4_cnt != u4_num_sps)
136
0
    {
137
0
        return IV_FAIL;
138
0
    }
139
140
117k
    i = 0;
141
117k
    u4_cnt = 0;
142
143
129k
    while((u4_cnt < u4_num_subset_sps) && (i < MAX_NUM_SEQ_PARAMS))
144
11.6k
    {
145
11.6k
        if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
146
3.89k
        {
147
3.89k
            u4_cnt++;
148
149
3.89k
            if(i4_max_mb_addr == INT32_MIN)
150
0
            {
151
0
                i4_max_mb_addr = ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u4_max_mb_addr;
152
0
            }
153
3.89k
            else if(i4_max_mb_addr != ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u4_max_mb_addr)
154
0
            {
155
0
                return IV_FAIL;
156
0
            }
157
158
3.89k
            if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u4_max_mb_addr >
159
3.89k
               imvcd_get_num_mbs_in_level(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_level_idc))
160
0
            {
161
0
                return IV_FAIL;
162
0
            }
163
164
3.89k
            if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_mb_aff_flag)
165
0
            {
166
0
                return IV_FAIL;
167
0
            }
168
169
3.89k
            if(!ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_frame_mbs_only_flag)
170
0
            {
171
0
                return IV_FAIL;
172
0
            }
173
3.89k
        }
174
175
11.6k
        i++;
176
11.6k
    }
177
178
117k
    if(u4_cnt != u4_num_subset_sps)
179
0
    {
180
0
        return IV_FAIL;
181
0
    }
182
183
117k
    return IV_SUCCESS;
184
117k
}
185
186
static IV_API_CALL_STATUS_T imvcd_check_pps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
187
117k
{
188
117k
    WORD32 i;
189
190
117k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
191
192
117k
    bool b_is_valid_pps_found = false;
193
194
30.2M
    for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
195
30.1M
    {
196
30.1M
        if(ps_view_ctxt->ps_pps[i].u1_is_valid)
197
125k
        {
198
125k
            b_is_valid_pps_found = true;
199
200
125k
            if(ps_view_ctxt->ps_pps[i].u1_frame_cropping_flag)
201
0
            {
202
0
                return IV_FAIL;
203
0
            }
204
205
125k
            if(ps_view_ctxt->ps_pps[i].u1_num_slice_groups != 1)
206
0
            {
207
0
                return IV_FAIL;
208
0
            }
209
125k
        }
210
30.1M
    }
211
212
117k
    return b_is_valid_pps_found ? IV_SUCCESS : IV_FAIL;
213
117k
}
214
215
static IV_API_CALL_STATUS_T imvcd_check_num_view_slices_in_au(mvc_dec_ctxt_t *ps_mvcd_ctxt,
216
                                                              imvcd_video_decode_ip_t *ps_ip)
217
117k
{
218
117k
    AVC_EXT_NALU_ID_T e_nalu_id;
219
220
117k
    UWORD16 u2_num_view_slices_in_au = 0;
221
117k
    UWORD8 *pu1_input_buffer = (UWORD8 *) ps_ip->s_ivd_ip.pv_stream_buffer;
222
117k
    UWORD32 u4_num_bytes_remaining = ps_ip->s_ivd_ip.u4_num_Bytes;
223
224
117k
    while(true)
225
193k
    {
226
193k
        UWORD32 u4_length_of_start_code = 0;
227
193k
        UWORD32 u4_next_is_aud = 0;
228
193k
        WORD32 i4_nalu_length = ih264d_find_start_code(pu1_input_buffer, 0, u4_num_bytes_remaining,
229
193k
                                                       &u4_length_of_start_code, &u4_next_is_aud);
230
231
193k
        if(i4_nalu_length <= 0)
232
837
        {
233
837
            break;
234
837
        }
235
236
192k
        if((0 != u4_next_is_aud) && (1 != u4_next_is_aud))
237
0
        {
238
0
            break;
239
0
        }
240
241
192k
        if(u4_length_of_start_code < (NUM_OF_ZERO_BYTES_BEFORE_START_CODE + 1))
242
0
        {
243
0
            break;
244
0
        }
245
246
192k
        e_nalu_id = NAL_UNIT_TYPE(pu1_input_buffer[u4_length_of_start_code]);
247
192k
        u2_num_view_slices_in_au += (SLICE_NON_IDR == e_nalu_id) || (SLICE_IDR == e_nalu_id) ||
248
73.4k
                                    (CODED_SLICE_EXTENSION == e_nalu_id);
249
250
192k
        if(((WORD64) u4_num_bytes_remaining) <=
251
192k
           ((WORD64) (((WORD64) u4_length_of_start_code) + ((WORD64) i4_nalu_length))))
252
12.6k
        {
253
12.6k
            break;
254
12.6k
        }
255
179k
        else
256
179k
        {
257
179k
            pu1_input_buffer += u4_length_of_start_code + i4_nalu_length;
258
179k
            u4_num_bytes_remaining -= u4_length_of_start_code + i4_nalu_length;
259
179k
        }
260
261
179k
        if(u2_num_view_slices_in_au == ps_mvcd_ctxt->u2_num_views)
262
104k
        {
263
104k
            break;
264
104k
        }
265
179k
    }
266
267
117k
    return (u2_num_view_slices_in_au != ps_mvcd_ctxt->u2_num_views) ? IV_FAIL : IV_SUCCESS;
268
117k
}
269
270
IV_API_CALL_STATUS_T imvcd_au_error_checks(mvc_dec_ctxt_t *ps_mvcd_ctxt,
271
                                           imvcd_video_decode_ip_t *ps_ip)
272
117k
{
273
117k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
274
275
117k
    if(ps_mvcd_ctxt->b_header_only_decode)
276
0
    {
277
0
        return IV_FAIL;
278
0
    }
279
280
117k
    if(!ps_view_ctxt->init_done)
281
0
    {
282
0
        return IV_FAIL;
283
0
    }
284
285
117k
    if(IV_FAIL == imvcd_check_invalid_numViews(ps_mvcd_ctxt))
286
3
    {
287
3
        return IV_FAIL;
288
3
    }
289
290
117k
    if(IV_FAIL == imvcd_check_sps_and_subset_sps(ps_mvcd_ctxt))
291
65
    {
292
65
        return IV_FAIL;
293
65
    }
294
295
117k
    if(IV_FAIL == imvcd_check_pps(ps_mvcd_ctxt))
296
139
    {
297
139
        return IV_FAIL;
298
139
    }
299
300
117k
    if(!ps_mvcd_ctxt->b_flush_enabled)
301
117k
    {
302
117k
        if(IV_FAIL == imvcd_check_num_view_slices_in_au(ps_mvcd_ctxt, ps_ip))
303
989
        {
304
989
            return IV_FAIL;
305
989
        }
306
117k
    }
307
308
116k
    return IV_SUCCESS;
309
117k
}
310
311
IV_API_CALL_STATUS_T imvcd_view_error_checks(mvc_dec_ctxt_t *ps_mvcd_ctxt)
312
116k
{
313
116k
    WORD32 i;
314
315
116k
    nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
316
116k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
317
116k
    dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps;
318
319
116k
    bool b_is_idr_slice = imvcd_is_idr_au(ps_mvcd_ctxt);
320
321
116k
    if(b_is_idr_slice && (ps_view_ctxt->ps_cur_slice->u1_slice_type != ISLICE))
322
27
    {
323
27
        return IV_FAIL;
324
27
    }
325
326
116k
    if(ps_view_ctxt->u1_first_slice_in_stream && !b_is_idr_slice)
327
253
    {
328
253
        return IV_FAIL;
329
253
    }
330
331
    /* In accordance with section 8.2.1 from spec. It is reproduced below - */
332
    /* The bitstream shall not contain data that result in Min( TopFieldOrderCnt,
333
       BottomFieldOrderCnt ) not equal to 0 for a coded IDR frame, TopFieldOrderCnt not equal to
334
       0 for a coded IDR top field, or BottomFieldOrderCnt not equal to 0 for a coded IDR bottom
335
       field. Thus, at least one of TopFieldOrderCnt and BottomFieldOrderCnt shall be equal to 0
336
       for the fields of a coded IDR frame. */
337
116k
    if(b_is_idr_slice)
338
37.3k
    {
339
37.3k
        if(ps_view_ctxt->ps_cur_slice->u1_field_pic_flag)
340
0
        {
341
0
            if(ps_view_ctxt->ps_cur_slice->u1_bottom_field_flag &&
342
0
               (ps_pps->i4_bottom_field_order_cnt != 0))
343
0
            {
344
0
                return IV_FAIL;
345
0
            }
346
0
            else if(!ps_view_ctxt->ps_cur_slice->u1_bottom_field_flag &&
347
0
                    (ps_pps->i4_top_field_order_cnt != 0))
348
0
            {
349
0
                return IV_FAIL;
350
0
            }
351
0
        }
352
37.3k
        else if(MIN(ps_pps->i4_top_field_order_cnt, ps_pps->i4_bottom_field_order_cnt) != 0)
353
68
        {
354
68
            return IV_FAIL;
355
68
        }
356
37.3k
    }
357
358
116k
    if(ps_nalu_mvc_ext->u2_view_id != 0)
359
2.12k
    {
360
2.12k
        subset_sps_t *ps_subset_sps =
361
2.12k
            ps_mvcd_ctxt->aps_pps_id_to_subset_sps_map[ps_pps->u1_pic_parameter_set_id];
362
363
2.12k
        if((NULL == ps_subset_sps) || !ps_subset_sps->s_sps_data.u1_is_valid)
364
1
        {
365
1
            return IV_FAIL;
366
1
        }
367
368
2.12k
        if(0 == ps_mvcd_ctxt->u1_num_subset_sps)
369
0
        {
370
0
            return IV_FAIL;
371
0
        }
372
373
2.12k
        if(ps_nalu_mvc_ext->u2_view_id >= ps_subset_sps->s_sps_mvc_ext.u2_num_views)
374
0
        {
375
0
            return IV_FAIL;
376
0
        }
377
2.12k
    }
378
114k
    else
379
114k
    {
380
114k
        if(ps_mvcd_ctxt->u2_num_views_decoded > 0)
381
14
        {
382
14
            return IV_FAIL;
383
14
        }
384
114k
    }
385
386
116k
    if(!ps_view_ctxt->u4_first_slice_in_pic || (ps_view_ctxt->u2_cur_slice_num > 0))
387
0
    {
388
0
        return IV_FAIL;
389
0
    }
390
391
116k
    if(ps_view_ctxt->u4_first_slice_in_pic &&
392
116k
       (ps_view_ctxt->ps_cur_slice->u2_first_mb_in_slice != 0))
393
4
    {
394
4
        return IV_FAIL;
395
4
    }
396
397
116k
    if(ps_view_ctxt->ps_cur_slice->u1_mmco_equalto5)
398
4
    {
399
4
        return IV_FAIL;
400
4
    }
401
402
118k
    for(i = 0; i < ps_mvcd_ctxt->u2_num_views_decoded; i++)
403
2.15k
    {
404
2.15k
        if(ps_mvcd_ctxt->as_slices[i].i4_poc != ps_view_ctxt->ps_cur_slice->i4_poc)
405
47
        {
406
47
            return IV_FAIL;
407
47
        }
408
409
2.10k
        if(ps_mvcd_ctxt->as_slices[i].u2_frame_num != ps_view_ctxt->ps_cur_slice->u2_frame_num)
410
3
        {
411
3
            return IV_FAIL;
412
3
        }
413
2.10k
    }
414
415
116k
    if(SKIP_NONE != ps_view_ctxt->u4_skip_frm_mask)
416
0
    {
417
0
        return IV_FAIL;
418
0
    }
419
420
116k
    return IV_SUCCESS;
421
116k
}