Coverage Report

Created: 2025-12-29 06:18

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
94.5k
{
43
94.5k
    WORD32 i;
44
45
94.5k
    UWORD8 u1_num_valid_subset_sps_found = 0;
46
94.5k
    UWORD16 u2_max_views = 1;
47
48
94.5k
    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.11M
    for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++)
54
3.02M
    {
55
3.02M
        if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
56
3.07k
        {
57
3.07k
            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.07k
            u2_max_views =
63
3.07k
                MAX(u2_max_views, ps_mvcd_ctxt->as_subset_sps[i].s_sps_mvc_ext.u2_num_views);
64
3.07k
            u1_num_valid_subset_sps_found++;
65
3.07k
        }
66
3.02M
    }
67
68
94.5k
    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
94.5k
    if(ps_mvcd_ctxt->u2_num_views > u2_max_views)
74
4
    {
75
4
        return IV_FAIL;
76
4
    }
77
78
94.5k
    if(ps_mvcd_ctxt->u2_num_views_decoded >= u2_max_views)
79
0
    {
80
0
        return IV_FAIL;
81
0
    }
82
83
94.5k
    return IV_SUCCESS;
84
94.5k
}
85
86
static IV_API_CALL_STATUS_T imvcd_check_sps_and_subset_sps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
87
94.5k
{
88
94.5k
    UWORD32 i;
89
94.5k
    UWORD32 u4_cnt;
90
91
94.5k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
92
93
94.5k
    UWORD32 u4_num_sps = ps_mvcd_ctxt->u1_num_sps;
94
94.5k
    UWORD32 u4_num_subset_sps = ps_mvcd_ctxt->u1_num_subset_sps;
95
94.5k
    WORD32 i4_max_mb_addr = INT32_MIN;
96
97
94.5k
    i = 0;
98
94.5k
    u4_cnt = 0;
99
100
300k
    while((u4_cnt < u4_num_sps) && (i < MAX_NUM_SEQ_PARAMS))
101
205k
    {
102
205k
        if(ps_view_ctxt->ps_sps[i].u1_is_valid)
103
101k
        {
104
101k
            u4_cnt++;
105
106
101k
            if(i4_max_mb_addr == INT32_MIN)
107
94.5k
            {
108
94.5k
                i4_max_mb_addr = ps_view_ctxt->ps_sps[i].u4_max_mb_addr;
109
94.5k
            }
110
6.92k
            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
101k
            if(ps_view_ctxt->ps_sps[i].u4_max_mb_addr >
116
101k
               imvcd_get_num_mbs_in_level(ps_view_ctxt->ps_sps[i].u1_level_idc))
117
3
            {
118
3
                return IV_FAIL;
119
3
            }
120
121
101k
            if(ps_view_ctxt->ps_sps[i].u1_mb_aff_flag)
122
4
            {
123
4
                return IV_FAIL;
124
4
            }
125
126
101k
            if(!ps_view_ctxt->ps_sps[i].u1_frame_mbs_only_flag)
127
1
            {
128
1
                return IV_FAIL;
129
1
            }
130
101k
        }
131
132
205k
        i++;
133
205k
    }
134
135
94.5k
    if(u4_cnt != u4_num_sps)
136
0
    {
137
0
        return IV_FAIL;
138
0
    }
139
140
94.5k
    i = 0;
141
94.5k
    u4_cnt = 0;
142
143
102k
    while((u4_cnt < u4_num_subset_sps) && (i < MAX_NUM_SEQ_PARAMS))
144
8.43k
    {
145
8.43k
        if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u1_is_valid)
146
3.07k
        {
147
3.07k
            u4_cnt++;
148
149
3.07k
            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.07k
            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.07k
            if(ps_mvcd_ctxt->as_subset_sps[i].s_sps_data.u4_max_mb_addr >
159
3.07k
               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.07k
            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.07k
            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.07k
        }
174
175
8.43k
        i++;
176
8.43k
    }
177
178
94.5k
    if(u4_cnt != u4_num_subset_sps)
179
0
    {
180
0
        return IV_FAIL;
181
0
    }
182
183
94.5k
    return IV_SUCCESS;
184
94.5k
}
185
186
static IV_API_CALL_STATUS_T imvcd_check_pps(mvc_dec_ctxt_t *ps_mvcd_ctxt)
187
94.5k
{
188
94.5k
    WORD32 i;
189
190
94.5k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
191
192
94.5k
    bool b_is_valid_pps_found = false;
193
194
24.2M
    for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
195
24.1M
    {
196
24.1M
        if(ps_view_ctxt->ps_pps[i].u1_is_valid)
197
99.6k
        {
198
99.6k
            b_is_valid_pps_found = true;
199
200
99.6k
            if(ps_view_ctxt->ps_pps[i].u1_frame_cropping_flag)
201
0
            {
202
0
                return IV_FAIL;
203
0
            }
204
205
99.6k
            if(ps_view_ctxt->ps_pps[i].u1_num_slice_groups != 1)
206
0
            {
207
0
                return IV_FAIL;
208
0
            }
209
99.6k
        }
210
24.1M
    }
211
212
94.5k
    return b_is_valid_pps_found ? IV_SUCCESS : IV_FAIL;
213
94.5k
}
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
94.5k
{
218
94.5k
    AVC_EXT_NALU_ID_T e_nalu_id;
219
220
94.5k
    UWORD16 u2_num_view_slices_in_au = 0;
221
94.5k
    UWORD8 *pu1_input_buffer = (UWORD8 *) ps_ip->s_ivd_ip.pv_stream_buffer;
222
94.5k
    UWORD32 u4_num_bytes_remaining = ps_ip->s_ivd_ip.u4_num_Bytes;
223
224
94.5k
    while(true)
225
129k
    {
226
129k
        UWORD32 u4_length_of_start_code = 0;
227
129k
        UWORD32 u4_next_is_aud = 0;
228
129k
        WORD32 i4_nalu_length = ih264d_find_start_code(pu1_input_buffer, 0, u4_num_bytes_remaining,
229
129k
                                                       &u4_length_of_start_code, &u4_next_is_aud);
230
231
129k
        if(i4_nalu_length <= 0)
232
389
        {
233
389
            break;
234
389
        }
235
236
129k
        if((0 != u4_next_is_aud) && (1 != u4_next_is_aud))
237
0
        {
238
0
            break;
239
0
        }
240
241
129k
        if(u4_length_of_start_code < (NUM_OF_ZERO_BYTES_BEFORE_START_CODE + 1))
242
0
        {
243
0
            break;
244
0
        }
245
246
129k
        e_nalu_id = NAL_UNIT_TYPE(pu1_input_buffer[u4_length_of_start_code]);
247
129k
        u2_num_view_slices_in_au += (SLICE_NON_IDR == e_nalu_id) || (SLICE_IDR == e_nalu_id) ||
248
33.2k
                                    (CODED_SLICE_EXTENSION == e_nalu_id);
249
250
129k
        if(((WORD64) u4_num_bytes_remaining) <=
251
129k
           ((WORD64) (((WORD64) u4_length_of_start_code) + ((WORD64) i4_nalu_length))))
252
2.60k
        {
253
2.60k
            break;
254
2.60k
        }
255
126k
        else
256
126k
        {
257
126k
            pu1_input_buffer += u4_length_of_start_code + i4_nalu_length;
258
126k
            u4_num_bytes_remaining -= u4_length_of_start_code + i4_nalu_length;
259
126k
        }
260
261
126k
        if(u2_num_view_slices_in_au == ps_mvcd_ctxt->u2_num_views)
262
91.5k
        {
263
91.5k
            break;
264
91.5k
        }
265
126k
    }
266
267
94.5k
    return (u2_num_view_slices_in_au != ps_mvcd_ctxt->u2_num_views) ? IV_FAIL : IV_SUCCESS;
268
94.5k
}
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
94.5k
{
273
94.5k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
274
275
94.5k
    if(ps_mvcd_ctxt->b_header_only_decode)
276
0
    {
277
0
        return IV_FAIL;
278
0
    }
279
280
94.5k
    if(!ps_view_ctxt->init_done)
281
0
    {
282
0
        return IV_FAIL;
283
0
    }
284
285
94.5k
    if(IV_FAIL == imvcd_check_invalid_numViews(ps_mvcd_ctxt))
286
4
    {
287
4
        return IV_FAIL;
288
4
    }
289
290
94.5k
    if(IV_FAIL == imvcd_check_sps_and_subset_sps(ps_mvcd_ctxt))
291
8
    {
292
8
        return IV_FAIL;
293
8
    }
294
295
94.5k
    if(IV_FAIL == imvcd_check_pps(ps_mvcd_ctxt))
296
15
    {
297
15
        return IV_FAIL;
298
15
    }
299
300
94.5k
    if(!ps_mvcd_ctxt->b_flush_enabled)
301
94.5k
    {
302
94.5k
        if(IV_FAIL == imvcd_check_num_view_slices_in_au(ps_mvcd_ctxt, ps_ip))
303
463
        {
304
463
            return IV_FAIL;
305
463
        }
306
94.5k
    }
307
308
94.0k
    return IV_SUCCESS;
309
94.5k
}
310
311
IV_API_CALL_STATUS_T imvcd_view_error_checks(mvc_dec_ctxt_t *ps_mvcd_ctxt)
312
95.1k
{
313
95.1k
    WORD32 i;
314
315
95.1k
    nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt);
316
95.1k
    dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt;
317
95.1k
    dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps;
318
319
95.1k
    bool b_is_idr_slice = imvcd_is_idr_au(ps_mvcd_ctxt);
320
321
95.1k
    if(b_is_idr_slice && (ps_view_ctxt->ps_cur_slice->u1_slice_type != ISLICE))
322
3
    {
323
3
        return IV_FAIL;
324
3
    }
325
326
95.1k
    if(ps_view_ctxt->u1_first_slice_in_stream && !b_is_idr_slice)
327
11
    {
328
11
        return IV_FAIL;
329
11
    }
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
95.1k
    if(b_is_idr_slice)
338
26.5k
    {
339
26.5k
        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
26.5k
        else if(MIN(ps_pps->i4_top_field_order_cnt, ps_pps->i4_bottom_field_order_cnt) != 0)
353
8
        {
354
8
            return IV_FAIL;
355
8
        }
356
26.5k
    }
357
358
95.1k
    if(ps_nalu_mvc_ext->u2_view_id != 0)
359
1.78k
    {
360
1.78k
        subset_sps_t *ps_subset_sps =
361
1.78k
            ps_mvcd_ctxt->aps_pps_id_to_subset_sps_map[ps_pps->u1_pic_parameter_set_id];
362
363
1.78k
        if((NULL == ps_subset_sps) || !ps_subset_sps->s_sps_data.u1_is_valid)
364
0
        {
365
0
            return IV_FAIL;
366
0
        }
367
368
1.78k
        if(0 == ps_mvcd_ctxt->u1_num_subset_sps)
369
0
        {
370
0
            return IV_FAIL;
371
0
        }
372
373
1.78k
        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
1.78k
    }
378
93.3k
    else
379
93.3k
    {
380
93.3k
        if(ps_mvcd_ctxt->u2_num_views_decoded > 0)
381
7
        {
382
7
            return IV_FAIL;
383
7
        }
384
93.3k
    }
385
386
95.1k
    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
95.1k
    if(ps_view_ctxt->u4_first_slice_in_pic &&
392
95.1k
       (ps_view_ctxt->ps_cur_slice->u2_first_mb_in_slice != 0))
393
1
    {
394
1
        return IV_FAIL;
395
1
    }
396
397
95.1k
    if(ps_view_ctxt->ps_cur_slice->u1_mmco_equalto5)
398
0
    {
399
0
        return IV_FAIL;
400
0
    }
401
402
96.9k
    for(i = 0; i < ps_mvcd_ctxt->u2_num_views_decoded; i++)
403
1.80k
    {
404
1.80k
        if(ps_mvcd_ctxt->as_slices[i].i4_poc != ps_view_ctxt->ps_cur_slice->i4_poc)
405
1
        {
406
1
            return IV_FAIL;
407
1
        }
408
409
1.80k
        if(ps_mvcd_ctxt->as_slices[i].u2_frame_num != ps_view_ctxt->ps_cur_slice->u2_frame_num)
410
1
        {
411
1
            return IV_FAIL;
412
1
        }
413
1.80k
    }
414
415
95.1k
    if(SKIP_NONE != ps_view_ctxt->u4_skip_frm_mask)
416
0
    {
417
0
        return IV_FAIL;
418
0
    }
419
420
95.1k
    return IV_SUCCESS;
421
95.1k
}