Coverage Report

Created: 2024-07-27 06:35

/src/libavc/decoder/svc/isvcd_nal.c
Line
Count
Source (jump to first uncovered line)
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 isvcd_nal.c
23
 *
24
 * \brief
25
 *    Contains routines that resample for SVC resampling
26
 *
27
 * Detailed_description
28
 *
29
 * \date
30
 *
31
 *
32
 * \author : Kishore
33
 **************************************************************************
34
 */
35
36
/******************************************************************************
37
 *
38
 * Copyright (C) 2022 The Android Open Source Project
39
 *
40
 * Licensed under the Apache License, Version 2.0 (the "License");
41
 * you may not use this file except in compliance with the License.
42
 * You may obtain a copy of the License at:
43
 *
44
 * http://www.apache.org/licenses/LICENSE-2.0
45
 *
46
 * Unless required by applicable law or agreed to in writing, software
47
 * distributed under the License is distributed on an "AS IS" BASIS,
48
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49
 * See the License for the specific language governing permissions and
50
 * limitations under the License.
51
 *
52
 *****************************************************************************
53
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
54
 */
55
/*****************************************************************************/
56
/*                                                                           */
57
/*  File Name         : isvcd_nal.c                                          */
58
/*                                                                           */
59
/*  Description       : Contains fucntions which help in NAL extraction from */
60
/*                      the bitstream                                        */
61
/*                                                                           */
62
/*  List of Functions : isvcd_nal_find_start_code,                           */
63
/*                      isvcd_get_annex_b_nal_unit,                          */
64
/*                      isvcd_get_rfc_nal_unit,                              */
65
/*                      isvcd_nal_rbsp_to_sodb,                              */
66
/*                      isvcd_reset_emulation_ctxt,                          */
67
/*                      isvcd_nal_byte_swap_emulation,                       */
68
/*                      isvcd_set_default_nal_header_prms,                   */
69
/*                      isvcd_dec_nal_hdr,                                   */
70
/*                      isvcd_parse_part_slice_hdr,                          */
71
/*                      isvcd_get_int_tgt_lyr_attr,                          */
72
/*                      isvcd_discard_nal                                    */
73
/*                                                                           */
74
/*  Issues / Problems : None                                                 */
75
/*                                                                           */
76
/*  Revision History:                                                        */
77
/*          DD MM YYYY   Author(s)       Changes                             */
78
/*          14 09 2021   Kishore         Draft                               */
79
/*                                                                           */
80
/*****************************************************************************/
81
/*****************************************************************************/
82
/* File Includes                                                             */
83
/*****************************************************************************/
84
85
/* System include files */
86
87
#include <stdio.h>
88
#include <stdlib.h>
89
#include <string.h>
90
#include <limits.h>
91
#include <stddef.h>
92
#include <assert.h>
93
94
/* standard interface include files */
95
#include "ih264_typedefs.h"
96
#include "ih264_macros.h"
97
#include "ih264_platform_macros.h"
98
#include "ih264d_tables.h"
99
#include "iv.h"
100
#include "ivd.h"
101
#include "ih264d_defs.h"
102
#include "ih264_debug.h"
103
#include "ih264d_parse_cavlc.h"
104
#include "ih264d_inter_pred.h"
105
#include "isvcd_structs.h"
106
#include "ih264d_nal.h"
107
#include "ih264d_error_handler.h"
108
#include "ih264d_defs.h"
109
110
/*****************************************************************************/
111
/*Extern Variable Declarations                                               */
112
/*****************************************************************************/
113
114
/*****************************************************************************/
115
/* Global Variable Definitions                                               */
116
/*****************************************************************************/
117
118
/*****************************************************************************/
119
/* Static Global Variable Definitions                                        */
120
/*****************************************************************************/
121
122
/*****************************************************************************/
123
/* Static function Definitions                                               */
124
/*****************************************************************************/
125
126
/*****************************************************************************/
127
/*                                                                           */
128
/*  Function Name : isvcd_reset_nal_buf                                      */
129
/*                                                                           */
130
/*  Description   : Performs the reset of NAL buffer structure               */
131
/*  Inputs        : 1. Pointer to NAL buffer structure                       */
132
/*  Globals       : None                                                     */
133
/*  Processing    : Updates different fields of the structure                */
134
/*  Outputs       : None                                                     */
135
/*  Returns       :                                                          */
136
/*                                                                           */
137
/*  Issues        : None                                                     */
138
/*                                                                           */
139
/*  Revision History:                                                        */
140
/*                                                                           */
141
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
142
/*         06 09 2021   Vijay      Draft                                     */
143
/*                                                                           */
144
/*****************************************************************************/
145
void isvcd_nal_buf_reset(void *pv_nal_buf)
146
2.91M
{
147
2.91M
    nal_buf_t *ps_nal_buf = pv_nal_buf;
148
149
2.91M
    ps_nal_buf->i4_valid_flag = SVCD_FALSE;
150
2.91M
    ps_nal_buf->i4_buf_size = 0;
151
2.91M
    ps_nal_buf->u4_max_bits = 0;
152
2.91M
    ps_nal_buf->pu1_buf = NULL;
153
2.91M
}
154
/*****************************************************************************/
155
/*                                                                           */
156
/*  Function Name :svcd_nal_find_start_code                                  */
157
/*                                                                           */
158
/*  Description   : Finds the position of the start code in the stream       */
159
/*                                                                           */
160
/*                                                                           */
161
/*  Inputs        : 1. Pointer to buffer start                               */
162
/*                  2. start position                                        */
163
/*                  3. Maximum number of bytes in the buffer                 */
164
/*                  4. pointer to zero byte count                            */
165
/*                  5. pointer to bytes consumed variable                    */
166
/*  Globals       :                                                          */
167
/*  Processing    : Searches for the start code in the bitstream and updates */
168
/*                  consumed variable                                        */
169
/*                                                                           */
170
/*  Outputs       : Bytes consumed variable                                  */
171
/*  Returns       : If start code is found then it returns SC_FOUND otherwise*/
172
/*                  it returns SC_NOT_FOUND                                  */
173
/*                                                                           */
174
/*  Issues        : None                                                     */
175
/*                                                                           */
176
/*  Revision History:                                                        */
177
/*                                                                           */
178
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
179
/*         06 09 2021   Vijay      Draft                                     */
180
/*                                                                           */
181
/*****************************************************************************/
182
WORD32 isvcd_nal_find_start_code(UWORD8 *pu1_buf_start, WORD32 i4_cur_pos, WORD32 i4_max_num_bytes,
183
                                 WORD32 *pi4_zero_cnt, UWORD32 *pu4_bytes_consumed)
184
1.54M
{
185
1.54M
    UWORD8 *pu1_buf = pu1_buf_start + i4_cur_pos;
186
1.54M
    WORD32 i4_i;
187
188
161M
    for(i4_i = 0; i4_i < (i4_max_num_bytes - i4_cur_pos); i4_i++)
189
161M
    {
190
        /*-------------------------------------------------------------------*/
191
        /* If zero increment the zero byte counter                           */
192
        /*-------------------------------------------------------------------*/
193
161M
        if(0 == *pu1_buf)
194
25.9M
        {
195
25.9M
            (*pi4_zero_cnt)++;
196
25.9M
        }
197
198
        /*-------------------------------------------------------------------*/
199
        /* If start code found then increment the byte consumed and return   */
200
        /*-------------------------------------------------------------------*/
201
135M
        else if(0x01 == *pu1_buf && *pi4_zero_cnt >= NUM_OF_ZERO_BYTES_BEFORE_START_CODE)
202
1.50M
        {
203
1.50M
            (*pu4_bytes_consumed)++;
204
1.50M
            return (SC_FOUND);
205
1.50M
        }
206
        /*-------------------------------------------------------------------*/
207
        /* If non zero byte and value is not equal to 1 a then reset zero    */
208
        /* byte counter                                                      */
209
        /*-------------------------------------------------------------------*/
210
134M
        else
211
134M
        {
212
134M
            *pi4_zero_cnt = 0;
213
134M
        }
214
215
160M
        (*pu4_bytes_consumed)++;
216
160M
        pu1_buf++;
217
160M
    }
218
219
36.9k
    return (SC_NOT_FOUND);
220
1.54M
}
221
222
/*****************************************************************************/
223
/*                                                                           */
224
/*  Function Name : isvcd_get_first_start_code                               */
225
/*                                                                           */
226
/*  Description   : Searches for the first start code in the bitstream       */
227
/*                                                                           */
228
/*                                                                           */
229
/*  Inputs        : 1. input buffer structure                                */
230
/*                  2. Bytes consumed variable                               */
231
/*  Globals       : None                                                     */
232
/*  Processing    : None                                                     */
233
/*                                                                           */
234
/*  Outputs       : Updates bytes consumed variable                          */
235
/*  Returns       : Start code is found or not                               */
236
/*                                                                           */
237
/*  Issues        : None                                                     */
238
/*                                                                           */
239
/*  Revision History:                                                        */
240
/*                                                                           */
241
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
242
/*         06 09 2021   Vijay      Draft                                     */
243
/*                                                                           */
244
/*****************************************************************************/
245
246
WORD32 isvcd_get_first_start_code(UWORD8 *pu1_stream_buffer, UWORD32 *pu4_bytes_consumed,
247
                                  UWORD32 *pu4_num_bytes)
248
23.8k
{
249
23.8k
    WORD32 i4_zero_cnt = 0, i4_status;
250
23.8k
    UWORD32 u4_bytes_consumed_temp = 0;
251
252
23.8k
    i4_status = isvcd_nal_find_start_code(pu1_stream_buffer, 0, *pu4_num_bytes, &i4_zero_cnt,
253
23.8k
                                          &u4_bytes_consumed_temp);
254
255
    /*-----------------------------------------------------------------------*/
256
    /* If start code is not found then return and start searching for it     */
257
    /* again in the next process call. This process is repeated till we      */
258
    /* get a start code                                                      */
259
    /*-----------------------------------------------------------------------*/
260
23.8k
    if(SC_NOT_FOUND == i4_status)
261
30
    {
262
30
        *pu4_bytes_consumed += u4_bytes_consumed_temp;
263
30
        return (i4_status);
264
30
    }
265
23.7k
    else
266
23.7k
    {
267
        /*-------------------------------------------------------------------*/
268
        /* If start code found then proceed with bitstream extraction        */
269
        /*-------------------------------------------------------------------*/
270
23.7k
        *pu4_bytes_consumed += u4_bytes_consumed_temp;
271
23.7k
        return (i4_status);
272
23.7k
    }
273
23.8k
}
274
275
/*****************************************************************************/
276
/*                                                                           */
277
/*  Function Name : isvcd_get_annex_b_nal_unit                               */
278
/*                                                                           */
279
/*  Description   : This function gets one NAL unit from the Annex B based   */
280
/*                  input bitstream                                          */
281
/*                                                                           */
282
/*                                                                           */
283
/*  Inputs        : 1. Input buffer pointer                                  */
284
/*                  2. Current position in the input buffer                  */
285
/*                  3. Input buffer size                                     */
286
/*                  4. Pointer to state of NAL boundary detection variable   */
287
/*                  5. Pointer to bytes consumed variable                    */
288
/*                  6. pointer to nal structure                              */
289
/*  Globals       :                                                          */
290
/*  Processing    : This fucntion searches for start code from the current   */
291
/*                  position and once gets one start code it searches for    */
292
/*                  another start code to get a NAL unit.                    */
293
/*                                                                           */
294
/*  Outputs       : Updates the state of NAL boundary detection logic        */
295
/*                  Updates the bytes consumed variable from 0 to bytes      */
296
/*                  consumed in this call                                    */
297
/*  Returns       : start of nal flag                                        */
298
/*                                                                           */
299
/*  Issues        : None                                                     */
300
/*                                                                           */
301
/*  Revision History:                                                        */
302
/*                                                                           */
303
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
304
/*         06 09 2021   Vijay      Draft                                     */
305
/*                                                                           */
306
/*****************************************************************************/
307
308
WORD32 isvcd_get_annex_b_nal_unit(UWORD8 *pu1_buf_start, WORD32 i4_cur_pos, WORD32 i4_max_num_bytes,
309
                                  WORD32 *pi4_state, WORD32 *pi4_zero_byte_cnt,
310
                                  UWORD32 *pu4_bytes_consumed, void *pv_nal_unit,
311
                                  WORD32 *pi4_more_data_flag)
312
1.51M
{
313
1.51M
    nal_unit_t *ps_nal_unit = (nal_unit_t *) pv_nal_unit;
314
1.51M
    WORD32 i4_status, i4_nal_start_flag = SVCD_FALSE;
315
316
    /*-----------------------------------------------------------------------*/
317
    /* Initialization                                                        */
318
    /*-----------------------------------------------------------------------*/
319
1.51M
    *pu4_bytes_consumed = 0;
320
1.51M
    *pi4_more_data_flag = SVCD_TRUE;
321
322
    /*------------------------ check ----------------------------------------*/
323
    /* Assumptions is that this fucntion should not be called with this state*/
324
    /* hence it is responsibility of the caller to reset the state after the */
325
    /* NAL_END.                                                              */
326
    /*-----------------------------------------------------------------------*/
327
1.51M
    if(NAL_END == *pi4_state)
328
941
    {
329
941
        return i4_nal_start_flag;
330
941
    }
331
332
    /*-----------------------------------------------------------------------*/
333
    /* ps_nal_unit->apu1_bufs[0] is expected to point to start of buffer of  */
334
    /* current NAL unit of the current process call. If a NAL unit is frag-  */
335
    /* -mented across multiple process call then this buffer should point to */
336
    /* start address of buffers. But when start of NAL is present in the     */
337
    /* buffer of current process call then ps_nal_unit->apu1_bufs[0] is      */
338
    /* expected to point to start adress of NAL unit (should be pointing to) */
339
    /* NAL header)                                                           */
340
    /*-----------------------------------------------------------------------*/
341
1.51M
    ps_nal_unit->pu1_bufs = pu1_buf_start + i4_cur_pos;
342
343
1.51M
    if(NAL_START == *pi4_state)
344
1.51M
    {
345
1.51M
        if(0 != *pi4_zero_byte_cnt)
346
0
        {
347
0
            return i4_nal_start_flag;
348
0
        }
349
1.51M
        i4_nal_start_flag = SVCD_TRUE;
350
1.51M
        ps_nal_unit->i4_num_bufs = 1;
351
1.51M
        ps_nal_unit->i4_buf_sizes = 0;
352
1.51M
        *pi4_state = FIND_NAL_END;
353
1.51M
    }
354
355
1.51M
    i4_status = isvcd_nal_find_start_code(pu1_buf_start, i4_cur_pos, i4_max_num_bytes,
356
1.51M
                                          pi4_zero_byte_cnt, pu4_bytes_consumed);
357
358
1.51M
    if(SC_NOT_FOUND == i4_status)
359
36.8k
    {
360
        /*-------------------------------------------------------------------*/
361
        /* If start code is not found then there are 2 possibilities         */
362
        /* 1. We are in the middle of decoding the start code. This means    */
363
        /*    that we might have decoded the one or 2 zeroes of the start    */
364
        /*    code. In such cases, we should not consume these bytes. Though */
365
        /*    doing so we might encounter spurious cases where 0's are not   */
366
        /*    actually corresponds to start code but these will not harm us  */
367
        /* 2. Not of above case. Straightforward one                         */
368
        /*-------------------------------------------------------------------*/
369
36.8k
        ps_nal_unit->i4_buf_sizes = *pu4_bytes_consumed;
370
36.8k
        *pi4_more_data_flag = SVCD_FALSE;
371
372
36.8k
        return (i4_nal_start_flag);
373
36.8k
    }
374
1.48M
    else
375
1.48M
    {
376
        /*-------------------------------------------------------------------*/
377
        /* If NAL END is found then increment the bytes consumed appropriatly*/
378
        /* reset the zero byte counter                                       */
379
        /*-------------------------------------------------------------------*/
380
1.48M
        *pi4_state = NAL_END;
381
1.48M
        ps_nal_unit->i4_buf_sizes = *pu4_bytes_consumed - 1;
382
1.48M
        *pi4_zero_byte_cnt = 0;
383
1.48M
        return (i4_nal_start_flag);
384
1.48M
    }
385
1.51M
}
386
387
/*****************************************************************************/
388
/*                                                                           */
389
/*  Function Name : isvcd_nal_rbsp_to_sodb                                   */
390
/*                                                                           */
391
/*  Description   : Converts the RBSP data to SODB data                      */
392
/*                                                                           */
393
/*                                                                           */
394
/*  Inputs        : 1. Input buffer containing the NAL unit                  */
395
/*                  2. Length of NAL unit (in bytes)                         */
396
/*  Globals       : None                                                     */
397
/*  Processing    : Finds the RBSP stop bit, if present then finds the length*/
398
/*                  of SODB data                                             */
399
/*                                                                           */
400
/*  Outputs       :                                                          */
401
/*  Returns       : Number of bits in the SODB data                          */
402
/*                                                                           */
403
/*  Issues        :                                                          */
404
/*                                                                           */
405
/*  Revision History:                                                        */
406
/*                                                                           */
407
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
408
/*         06 09 2021   Vijay      Draft                                     */
409
/*                                                                           */
410
/*****************************************************************************/
411
412
UWORD32 isvcd_nal_rbsp_to_sodb(UWORD8 *pu1_buf, WORD32 i4_nal_len_in_bytes, UWORD8 u1_ecd_mode)
413
498k
{
414
498k
    UWORD32 u4_last_word_pos;
415
498k
    UWORD32 u4_word, u4_max_bit_offset;
416
498k
    UWORD8 i4_num_bits;
417
498k
    WORD32 i4_i;
418
498k
    WORD64 i8_nal_len;
419
498k
    UWORD32 *pu4_buf;
420
421
498k
    if(0 >= i4_nal_len_in_bytes)
422
14.2k
    {
423
14.2k
        return (0);
424
14.2k
    }
425
426
    /* Get offset in bits */
427
484k
    i8_nal_len = (WORD64) i4_nal_len_in_bytes << 3;
428
484k
    u4_max_bit_offset = (UWORD32) i8_nal_len;
429
430
    /* If NAL is coded in CABAC then SODB */
431
    /* length has to account for CABAC    */
432
    /* ZERO WORDS also                    */
433
484k
    if(1 == u1_ecd_mode)
434
76.6k
    {
435
76.6k
        return (u4_max_bit_offset);
436
76.6k
    }
437
438
    /* Calculate the position of last word */
439
408k
    u4_last_word_pos = i4_nal_len_in_bytes >> 2;
440
441
    /* Load the last word                 */
442
408k
    i4_i = i4_nal_len_in_bytes & 0x03;
443
408k
    if(0 != i4_i)
444
320k
    {
445
320k
        pu4_buf = (UWORD32 *) pu1_buf;
446
320k
        pu4_buf += u4_last_word_pos;
447
320k
        u4_word = *pu4_buf;
448
320k
        i4_num_bits = i4_i << 3;
449
320k
        u4_word >>= (32 - i4_num_bits);
450
320k
    }
451
87.9k
    else
452
87.9k
    {
453
87.9k
        pu4_buf = (UWORD32 *) pu1_buf;
454
87.9k
        pu4_buf += (u4_last_word_pos - 1);
455
87.9k
        u4_word = *pu4_buf;
456
87.9k
        i4_num_bits = 32;
457
87.9k
    }
458
459
    /* Search for RBSP stop bit          */
460
408k
    do
461
714k
    {
462
11.0M
        for(i4_i = 0; (i4_i < i4_num_bits) && !CHECKBIT(u4_word, i4_i); i4_i++)
463
10.3M
            ;
464
465
714k
        u4_max_bit_offset -= i4_i;
466
467
        /* RBSP stop bit is found then   */
468
        /* come out of the loop          */
469
714k
        if(0 != CHECKBIT(u4_word, i4_i))
470
405k
        {
471
            /* Remove RBSP stop bit */
472
405k
            u4_max_bit_offset -= 1;
473
405k
            break;
474
405k
        }
475
476
309k
        pu4_buf -= 1;
477
309k
        u4_word = *pu4_buf;
478
309k
        i4_num_bits = 32;
479
309k
    } while(u4_max_bit_offset > 0);
480
481
0
    return (u4_max_bit_offset);
482
484k
}
483
484
/*****************************************************************************/
485
/*                                                                           */
486
/*  Function Name : isvcd_reset_emulation_ctxt                               */
487
/*                                                                           */
488
/*  Description   : Resets the emulation prevention context structure        */
489
/*                                                                           */
490
/*  Inputs        : pv_emulation_ctxt - pointer to emulation prevention      */
491
/*                      context structure                                    */
492
/*                                                                           */
493
/*  Globals       : None                                                     */
494
/*                                                                           */
495
/*  Processing    : None                                                     */
496
/*                                                                           */
497
/*  Outputs       : None                                                     */
498
/*                                                                           */
499
/*  Returns       : None                                                     */
500
/*                                                                           */
501
/*  Issues        : None                                                     */
502
/*                                                                           */
503
/*  Revision History:                                                        */
504
/*          DD MM YYYY   Author(s)       Changes                             */
505
/*          06 09 2021   Vijay      Draft                                    */
506
/*                                                                           */
507
/*****************************************************************************/
508
509
void isvcd_reset_emulation_ctxt(void *pv_emulation_ctxt)
510
2.16M
{
511
2.16M
    emulation_prevent_ctxt_t *ps_emulation_ctxt = (emulation_prevent_ctxt_t *) pv_emulation_ctxt;
512
513
    /*! Reset the emulation prevention context */
514
2.16M
    ps_emulation_ctxt->i4_state = NOT_STUFFED_BYTE;
515
2.16M
    ps_emulation_ctxt->i4_zeroes_cnt = 0;
516
2.16M
    ps_emulation_ctxt->u4_bytes_in_word = 0;
517
2.16M
    ps_emulation_ctxt->u4_word = 0;
518
2.16M
}
519
520
/****************************************************************************/
521
/*                                                                          */
522
/* Function Name  : isvcd_nal_byte_swap_emulation                           */
523
/*                                                                          */
524
/* Description    : This function is does byte swap or emulation or both    */
525
/*                  in the stream.                                          */
526
/*                                                                          */
527
/* Inputs         :  pu4_out_stream : Pointer to bitstream out buffer       */
528
/*                   pu4_out_len    : Pointer to variable for out len       */
529
/*                   pu1_in_stream  : Pointer to bitstream in buffer        */
530
/*                   u4_in_len      : Input bitstream buffer length         */
531
/*                   u4_prev_0s     : In case of fragemented NAL 0s in last */
532
/*                                    fragmented unit                       */
533
/*                   u4_0s_bfr_sc   : Number of zeros before start code     */
534
/*                   u4_bytes       : Number of bytes in last fragmented    */
535
/*                                    word                                  */
536
/*                   u4_word        : Last fragmented word                  */
537
/*                                                                          */
538
/* Globals        :  None                                                   */
539
/*                                                                          */
540
/* Processing     :  It has three mode of operations                        */
541
/*                   1. Byte Swap and Emulation for H.264 WMV9 AP DEC       */
542
/*                      supports both fragmented and non fragmented packets */
543
/*                      set u4_prev_0s = last valid zeros for this operation*/
544
/*                   2. Byte Swap only for MPEG2 and MPEG4 WMV9 MP DEC      */
545
/*                      supports both fragmented and non fragmented packets */
546
/*                      set u4_prev_0s = 0 and  u4_0s_bfr_sc = u4_in_len    */
547
/*                   3. Annex B stream                                      */
548
/*                      only non fragmented                                 */
549
/*                      set u4_prev_0s = 0 for this operation               */
550
/* Outputs        :  pu4_out_len output length of the bit stream            */
551
/*                                                                          */
552
/* Returns        :  Number of zeros in case of framented start code        */
553
/*                                                                          */
554
/* Known Issues   :                                                         */
555
/*                                                                          */
556
/* Revision History                                                         */
557
/*                                                                          */
558
/*      DD MM YY            Author        Changes                           */
559
/*      06 09 2021          Vijay                                           */
560
/****************************************************************************/
561
UWORD32 isvcd_nal_byte_swap_emulation(UWORD32 *pu4_out_stream, UWORD32 *pu4_out_len,
562
                                      UWORD8 *pu1_in_stream, UWORD32 u4_in_len, WORD32 i4_0s_bfr_sc,
563
                                      void *pv_emulation_ctxt)
564
1.80M
{
565
1.80M
    UWORD32 u4_i, u4_num_bytes, u4_offset;
566
1.80M
    UWORD8 u1_cur_byte;
567
1.80M
    emulation_prevent_ctxt_t *ps_emulation_ctxt = (emulation_prevent_ctxt_t *) pv_emulation_ctxt;
568
569
1.80M
    u4_offset = ps_emulation_ctxt->u4_bytes_in_word;
570
1.80M
    u4_num_bytes = ps_emulation_ctxt->u4_bytes_in_word;
571
572
80.0M
    for(u4_i = 0; u4_i < u4_in_len; u4_i++)
573
78.4M
    {
574
78.4M
        UWORD8 u1_cur_byte_emu, u1_cur_byte_sc;
575
78.4M
        UWORD64 u8_sft_word;
576
577
78.4M
        u1_cur_byte = *pu1_in_stream++;
578
78.4M
        u1_cur_byte_emu = (EMULATION_PREVENTION_BYTE == u1_cur_byte);
579
78.4M
        u1_cur_byte_sc = (START_CODE_BYTE == u1_cur_byte);
580
581
78.4M
        if((ps_emulation_ctxt->i4_zeroes_cnt >= i4_0s_bfr_sc) & (u1_cur_byte_emu | u1_cur_byte_sc) &
582
78.4M
           (NOT_STUFFED_BYTE == ps_emulation_ctxt->i4_state))
583
161k
        {
584
161k
            if(u1_cur_byte_sc)
585
148k
            {
586
148k
                break;
587
148k
            }
588
12.5k
            ps_emulation_ctxt->i4_zeroes_cnt = 0;
589
12.5k
            ps_emulation_ctxt->i4_state = STUFFED_BYTE;
590
12.5k
            continue;
591
161k
        }
592
593
78.2M
        u8_sft_word = (UWORD64) ps_emulation_ctxt->u4_word << 8;
594
78.2M
        ps_emulation_ctxt->u4_word = (UWORD32) (u8_sft_word | u1_cur_byte);
595
78.2M
        ps_emulation_ctxt->u4_bytes_in_word++;
596
78.2M
        u4_num_bytes++;
597
78.2M
        ps_emulation_ctxt->i4_zeroes_cnt++;
598
78.2M
        if(u1_cur_byte != 0x00)
599
57.4M
        {
600
57.4M
            ps_emulation_ctxt->i4_zeroes_cnt = 0;
601
57.4M
        }
602
603
78.2M
        if((u4_num_bytes & 0x03) == 0x00)
604
18.6M
        {
605
18.6M
            *pu4_out_stream = ps_emulation_ctxt->u4_word;
606
18.6M
            ps_emulation_ctxt->u4_bytes_in_word = 0;
607
18.6M
            pu4_out_stream++;
608
18.6M
        }
609
610
78.2M
        ps_emulation_ctxt->i4_state = NOT_STUFFED_BYTE;
611
78.2M
    }
612
613
1.80M
    if(ps_emulation_ctxt->u4_bytes_in_word)
614
1.45M
    {
615
1.45M
        UWORD64 temp_out_stream = (UWORD64) ps_emulation_ctxt->u4_word
616
1.45M
                                  << ((4 - ps_emulation_ctxt->u4_bytes_in_word) << 3);
617
1.45M
        *pu4_out_stream = (UWORD32) temp_out_stream;
618
1.45M
    }
619
620
1.80M
    *pu4_out_len = (u4_num_bytes - u4_offset);
621
1.80M
    return ((u4_num_bytes & 0xFFFFFFFC));
622
1.80M
}
623
624
/*****************************************************************************/
625
/*                                                                           */
626
/*  Function Name : isvcd_set_default_nal_header_prms                        */
627
/*                                                                           */
628
/*  Description   : Sets the members of NAL header structures to default     */
629
/*                  values                                                   */
630
/*                                                                           */
631
/*  Inputs        : pv_nal_prms - pointer nal header prms structure          */
632
/*                  i4_temp_id - default value of temporal id                */
633
/*                                                                           */
634
/*  Globals       : None                                                     */
635
/*                                                                           */
636
/*  Processing    : None                                                     */
637
/*                                                                           */
638
/*  Outputs       : None                                                     */
639
/*                                                                           */
640
/*  Returns       : None                                                     */
641
/*                                                                           */
642
/*  Issues        : None                                                     */
643
/*                                                                           */
644
/*  Revision History:                                                        */
645
/*          DD MM YYYY   Author(s)       Changes                             */
646
/*          06 09 2021   Vijay      Draft                                    */
647
/*                                                                           */
648
/*****************************************************************************/
649
void isvcd_set_default_nal_prms(void *pv_nal_prms)
650
1.75M
{
651
1.75M
    nal_prms_t *ps_nal_prms;
652
1.75M
    ps_nal_prms = (nal_prms_t *) pv_nal_prms;
653
654
    /* Set default values */
655
1.75M
    ps_nal_prms->i4_dependency_id = 0;
656
1.75M
    ps_nal_prms->i4_derived_nal_type = 0xFF;
657
1.75M
    ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
658
1.75M
    ps_nal_prms->i4_nal_header_len = 0;
659
1.75M
    ps_nal_prms->i4_nal_ref_idc = 0xFF;
660
1.75M
    ps_nal_prms->i4_nal_unit_type = 0xFF;
661
1.75M
    ps_nal_prms->i4_no_int_lyr_pred = 1;
662
1.75M
    ps_nal_prms->i4_priority_id = 0;
663
1.75M
    ps_nal_prms->i4_quality_id = 0;
664
1.75M
    ps_nal_prms->i4_discard_flag = 0;
665
1.75M
    ps_nal_prms->i4_dqid = 0;
666
1.75M
    ps_nal_prms->i4_use_ref_base_pic_flag = 0;
667
1.75M
    ps_nal_prms->i4_temporal_id = 0;
668
1.75M
    ps_nal_prms->i4_idr_pic_num = 0;
669
1.75M
    ps_nal_prms->u2_frm_num = 0;
670
1.75M
    ps_nal_prms->i4_poc_lsb = 0;
671
1.75M
    ps_nal_prms->i4_delta_poc_bot = 0;
672
1.75M
    ps_nal_prms->ai4_delta_poc[0] = 0;
673
1.75M
    ps_nal_prms->ai4_delta_poc[1] = 0;
674
1.75M
    ps_nal_prms->u1_pps_id = 0;
675
1.75M
}
676
/*****************************************************************************/
677
/*                                                                           */
678
/*  Function Name : isvcd_dec_nal_hdr                                        */
679
/*                                                                           */
680
/*  Description   : None                                                     */
681
/*                                                                           */
682
/*  Inputs        : pv_buf_ptr - Pointer to buffer constaining start of NAL  */
683
/*                  pv_nal_header_buf - Temporray working buffer             */
684
/*                  pv_nal_prms - Pointer to nal header prms                 */
685
/*                      structure                                            */
686
/*                                                                           */
687
/*  Globals       : None                                                     */
688
/*                                                                           */
689
/*  Processing    : None                                                     */
690
/*                                                                           */
691
/*  Outputs       : None                                                     */
692
/*                                                                           */
693
/*  Returns       : None                                                     */
694
/*                                                                           */
695
/*  Issues        : None                                                     */
696
/*                                                                           */
697
/*  Revision History:                                                        */
698
/*          DD MM YYYY   Author(s)       Changes                             */
699
/*          06 09 2021   Vijay      Draft                                    */
700
/*                                                                           */
701
/*****************************************************************************/
702
void isvcd_dec_nal_hdr(void *pv_buf_ptr, WORD32 i4_buf_size, void *pv_nal_header_buf,
703
                       void *pv_nal_prms, void *pv_prefix_nal_buf, void *pv_prefix_nal_prms,
704
                       UWORD32 *pu4_err_code)
705
1.73M
{
706
1.73M
    nal_prms_t *ps_nal_prms;
707
1.73M
    nal_prms_t *ps_prefix_nal_prms;
708
1.73M
    nal_buf_t *ps_prefix_nal_buf;
709
1.73M
    dec_bit_stream_t s_stream_ctxt = {0};
710
1.73M
    WORD32 i4_forbidden_zero_bit;
711
712
    /* byte swapping */
713
1.73M
    UWORD8 *pu1_buf = (UWORD8 *) pv_nal_header_buf;
714
1.73M
    UWORD8 *pu1_src = (UWORD8 *) pv_buf_ptr;
715
716
1.73M
    ps_nal_prms = (nal_prms_t *) pv_nal_prms;
717
1.73M
    ps_prefix_nal_prms = (nal_prms_t *) pv_prefix_nal_prms;
718
1.73M
    ps_prefix_nal_buf = (nal_buf_t *) pv_prefix_nal_buf;
719
720
    /* The NAL header syntax elements are read through bitstream fucntions.  */
721
    /* Hence bitstream context structure initializaton is needed before      */
722
    /* parsing from the bitstream                                            */
723
    /* Also bitstream fucntions assume the buffer is byteswapped. Hence the  */
724
    /* byte swapping is also done for 4 bytes                                */
725
1.73M
    s_stream_ctxt.u4_ofst = 0;
726
1.73M
    s_stream_ctxt.pu4_buffer = pv_nal_header_buf;
727
1.73M
    s_stream_ctxt.u4_max_ofst = (i4_buf_size << 3);
728
729
1.73M
    *pu4_err_code = 0;
730
731
    /* Check the size of bitstream buffer */
732
1.73M
    if(s_stream_ctxt.u4_max_ofst < 8)
733
7.79k
    {
734
7.79k
        *pu4_err_code = (UWORD32) NAL_INSUFFICIENT_DATA;
735
7.79k
        return;
736
7.79k
    }
737
738
1.72M
    if(s_stream_ctxt.u4_max_ofst >= 32)
739
1.69M
    {
740
1.69M
        *pu1_buf++ = *(pu1_src + 3);
741
1.69M
        *pu1_buf++ = *(pu1_src + 2);
742
1.69M
        *pu1_buf++ = *(pu1_src + 1);
743
1.69M
        *pu1_buf++ = *pu1_src;
744
1.69M
    }
745
29.6k
    else
746
29.6k
    {
747
29.6k
        *pu1_buf++ = *pu1_src;
748
29.6k
    }
749
750
    /*-----------------------------------------------------------------------*/
751
    /*! Parse the NAL header and update the NAL header structure members     */
752
    /*-----------------------------------------------------------------------*/
753
    /* Read forbidden 0 bit */
754
1.72M
    i4_forbidden_zero_bit = ih264d_get_bit_h264(&s_stream_ctxt);
755
756
1.72M
    if(0 != i4_forbidden_zero_bit)
757
30.5k
    {
758
30.5k
        *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
759
30.5k
        return;
760
30.5k
    }
761
762
    /*---------------- Read NAL ref idc -----------------------------*/
763
1.69M
    ps_nal_prms->i4_nal_ref_idc = ih264d_get_bits_h264(&s_stream_ctxt, 2);
764
765
    /*----------------- Read NAL type -------------------------------*/
766
1.69M
    ps_nal_prms->i4_nal_unit_type = ih264d_get_bits_h264(&s_stream_ctxt, 5);
767
1.69M
    if(ps_nal_prms->i4_nal_unit_type > CODED_SLICE_EXTENSION_NAL)
768
5.83k
    {
769
5.83k
        *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
770
5.83k
        return;
771
5.83k
    }
772
1.68M
    if(ACCESS_UNIT_DELIMITER_RBSP == ps_nal_prms->i4_nal_unit_type)
773
8.41k
    {
774
8.41k
        ps_nal_prms->i4_derived_nal_type = NON_VCL_NAL;
775
8.41k
        return;
776
8.41k
    }
777
778
    /* set idr pic flag */
779
1.67M
    if(IDR_SLICE_NAL == ps_nal_prms->i4_nal_unit_type)
780
462k
    {
781
462k
        ps_nal_prms->i4_idr_pic_flag = SVCD_TRUE;
782
462k
    }
783
1.21M
    else
784
1.21M
    {
785
1.21M
        ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
786
1.21M
    }
787
788
    /*----------------- Read SVC extension NAL header ---------------*/
789
1.67M
    if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type ||
790
1.67M
       PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
791
152k
    {
792
152k
        WORD32 i4_svc_extension_flag, i4_idr_flag;
793
794
        /* check the size of the buffer */
795
152k
        if(s_stream_ctxt.u4_max_ofst < 32)
796
2.45k
        {
797
2.45k
            *pu4_err_code = (UWORD32) NAL_INSUFFICIENT_DATA;
798
2.45k
            return;
799
2.45k
        }
800
801
149k
        i4_svc_extension_flag = ih264d_get_bit_h264(&s_stream_ctxt);
802
149k
        UNUSED(i4_svc_extension_flag);
803
804
149k
        i4_idr_flag = ih264d_get_bit_h264(&s_stream_ctxt);
805
806
        /* Set idr pic flag based on idr flag */
807
149k
        if(1 == i4_idr_flag)
808
114k
        {
809
114k
            ps_nal_prms->i4_idr_pic_flag = SVCD_TRUE;
810
114k
        }
811
34.6k
        else
812
34.6k
        {
813
34.6k
            ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
814
34.6k
        }
815
816
        /* parse priorit id */
817
149k
        ps_nal_prms->i4_priority_id = ih264d_get_bits_h264(&s_stream_ctxt, 6);
818
819
        /* parse the no inter layer prediction flag */
820
149k
        ps_nal_prms->i4_no_int_lyr_pred = ih264d_get_bit_h264(&s_stream_ctxt);
821
822
        /* parse dependency id */
823
149k
        ps_nal_prms->i4_dependency_id = ih264d_get_bits_h264(&s_stream_ctxt, 3);
824
825
        /* parse quality id */
826
149k
        ps_nal_prms->i4_quality_id = ih264d_get_bits_h264(&s_stream_ctxt, 4);
827
828
149k
        if((ps_nal_prms->i4_quality_id > 0) || (ps_nal_prms->i4_dependency_id > 2))
829
7.03k
        {
830
7.03k
            *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
831
7.03k
            return;
832
7.03k
        }
833
        /* parse temporal id */
834
142k
        ps_nal_prms->i4_temporal_id = ih264d_get_bits_h264(&s_stream_ctxt, 3);
835
836
        /* parse use ref base pic flag */
837
142k
        ps_nal_prms->i4_use_ref_base_pic_flag = ih264d_get_bit_h264(&s_stream_ctxt);
838
839
142k
        if(0 != ps_nal_prms->i4_use_ref_base_pic_flag)
840
2.20k
        {
841
2.20k
            *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
842
2.20k
            return;
843
2.20k
        }
844
        /* parse discrad flag */
845
140k
        ps_nal_prms->i4_discard_flag = ih264d_get_bit_h264(&s_stream_ctxt);
846
847
        /* parse the reserved bits */
848
140k
        ih264d_get_bits_h264(&s_stream_ctxt, 3);
849
140k
    }
850
851
    /* update NAL hedaer length in bytes */
852
1.66M
    ps_nal_prms->i4_nal_header_len = s_stream_ctxt.u4_ofst >> 3;
853
854
    /*************************************************************************/
855
    /* PREFIX NAL UNIT ASSOCIATION WITH ASSOCIATED NAL UNIT                  */
856
    /*************************************************************************/
857
858
    /* if current NAL is not a AVC NAL unit then */
859
    /* discard the prefix NAL unit if present    */
860
1.66M
    if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type)
861
135k
    {
862
135k
        isvcd_nal_buf_reset(ps_prefix_nal_buf);
863
135k
    }
864
865
1.66M
    if(SVCD_TRUE == ps_prefix_nal_buf->i4_valid_flag)
866
2.52k
    {
867
        /* Copy the required parameters from the prefix NAL unit */
868
2.52k
        ps_nal_prms->i4_dependency_id = ps_prefix_nal_prms->i4_dependency_id;
869
2.52k
        ps_nal_prms->i4_quality_id = ps_prefix_nal_prms->i4_quality_id;
870
2.52k
        ps_nal_prms->i4_priority_id = ps_prefix_nal_prms->i4_priority_id;
871
2.52k
        ps_nal_prms->i4_temporal_id = ps_prefix_nal_prms->i4_temporal_id;
872
2.52k
        ps_nal_prms->i4_no_int_lyr_pred = ps_prefix_nal_prms->i4_no_int_lyr_pred;
873
2.52k
        ps_nal_prms->i4_use_ref_base_pic_flag = ps_prefix_nal_prms->i4_use_ref_base_pic_flag;
874
2.52k
        ps_nal_prms->i4_discard_flag = ps_prefix_nal_prms->i4_discard_flag;
875
2.52k
    }
876
877
    /*-----------------------------------------------------------------------*/
878
    /* Set the derived NAL unit type and also update the DQID for VCL NAL    */
879
    /*  units                                                                */
880
    /*-----------------------------------------------------------------------*/
881
1.66M
    if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type ||
882
1.66M
       SLICE_NAL == ps_nal_prms->i4_nal_unit_type ||
883
1.66M
       IDR_SLICE_NAL == ps_nal_prms->i4_nal_unit_type ||
884
1.66M
       PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
885
748k
    {
886
748k
        ps_nal_prms->i4_derived_nal_type = VCL_NAL;
887
888
        /* calculate the DQID and modified DQID */
889
748k
        ps_nal_prms->i4_dqid = (ps_nal_prms->i4_dependency_id << 4) + ps_nal_prms->i4_quality_id;
890
748k
    }
891
919k
    else
892
919k
    {
893
919k
        ps_nal_prms->i4_derived_nal_type = NON_VCL_NAL;
894
919k
    }
895
1.66M
}
896
897
/*****************************************************************************/
898
/*                                                                           */
899
/*  Function Name : isvcd_parse_part_slice_hdr                                */
900
/*                                                                           */
901
/*  Description   : This routine parses the slice till POC parameters        */
902
/*                                                                           */
903
/*  Inputs        : 1. Pointer to input bitstream                            */
904
/*                  2. Temporary input buffer                                */
905
/*                  3. PPS start buffer                                      */
906
/*                  4. SPS start buffer                                      */
907
/*                  5. Pointer to NAL paramter structure                     */
908
/*                  6. Place holder for error code                           */
909
/*  Globals       : None                                                     */
910
/*  Processing    : Parses the slice header                                  */
911
/*                                                                           */
912
/*  Outputs       : Updated NAL prms structure                               */
913
/*                  Updated error code                                       */
914
/*  Returns       : status                                                   */
915
/*                                                                           */
916
/*  Issues        : Does not support interlaced content                      */
917
/*                                                                           */
918
/*  Revision History:                                                        */
919
/*                                                                           */
920
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
921
/*         06 09 2021   Vijay           Draft                                */
922
/*                                                                           */
923
/*****************************************************************************/
924
WORD32 isvcd_parse_part_slice_hdr(UWORD8 *pu1_input_buf, WORD32 i4_input_buf_size,
925
                                  UWORD8 *pu1_temp_buf, void *pv_sps, void *pv_pps,
926
                                  nal_prms_t *ps_nal_prms, UWORD32 *pu4_err_code,
927
                                  WORD32 *pi4_sps_pps_status)
928
625k
{
929
625k
    UWORD32 u4_slice_type;
930
625k
    dec_seq_params_t *ps_sps = (dec_seq_params_t *) pv_sps;
931
625k
    dec_pic_params_t *ps_pps = (dec_pic_params_t *) pv_pps;
932
625k
    dec_bit_stream_t s_stream_ctxt = {0};
933
625k
    dec_bit_stream_t *ps_stream_ctxt;
934
625k
    UWORD32 *pu4_bitstrm_buf;
935
625k
    UWORD32 *pu4_bitstrm_ofst;
936
937
625k
    *pi4_sps_pps_status = NAL_CORRUPT_DATA;
938
    /* Perform the emulation prevention and byte swap */
939
625k
    {
940
625k
        emulation_prevent_ctxt_t s_emulation_ctxt = {0};
941
625k
        WORD32 i4_size, i4_temp;
942
943
625k
        isvcd_reset_emulation_ctxt((void *) &s_emulation_ctxt);
944
625k
        i4_size = MIN(i4_input_buf_size, HEADER_BUFFER_LEN_BEFORE_EP);
945
946
625k
        isvcd_nal_byte_swap_emulation((UWORD32 *) pu1_temp_buf, (UWORD32 *) &i4_temp, pu1_input_buf,
947
625k
                                      (UWORD32) i4_size, NUM_OF_ZERO_BYTES_BEFORE_START_CODE,
948
625k
                                      &s_emulation_ctxt);
949
950
        /* Initialize the stream context structure */
951
625k
        s_stream_ctxt.pu4_buffer = (UWORD32 *) pu1_temp_buf;
952
625k
        s_stream_ctxt.u4_ofst = 0;
953
625k
        s_stream_ctxt.u4_max_ofst = (i4_size << 3);
954
625k
    }
955
956
625k
    ps_stream_ctxt = &s_stream_ctxt;
957
958
    /* Parse the first mb address in slice */
959
625k
    pu4_bitstrm_buf = ps_stream_ctxt->pu4_buffer;
960
625k
    pu4_bitstrm_ofst = &ps_stream_ctxt->u4_ofst;
961
625k
    ps_nal_prms->u4_first_mb_addr = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
962
625k
    if(ps_nal_prms->u4_first_mb_addr >= (MAX_MBS_LEVEL_51))
963
23.4k
    {
964
23.4k
        return ERROR_CORRUPTED_SLICE;
965
23.4k
    }
966
    /* Parse slice type */
967
602k
    u4_slice_type = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
968
969
602k
    if(u4_slice_type > 9) return ERROR_INV_SLC_TYPE_T;
970
971
    /* Check the validity of slice prms */
972
562k
    switch(u4_slice_type)
973
562k
    {
974
326k
        case 0:
975
351k
        case 5:
976
351k
            u4_slice_type = P_SLICE;
977
            /* P slice */
978
351k
            break;
979
133k
        case 1:
980
143k
        case 6:
981
143k
            u4_slice_type = B_SLICE;
982
            /* B slice */
983
143k
            break;
984
51.2k
        case 2:
985
55.5k
        case 7:
986
            /* I slice */
987
55.5k
            u4_slice_type = I_SLICE;
988
55.5k
            break;
989
12.4k
        default:
990
12.4k
            break;
991
562k
    }
992
993
    /* Parse the pps id */
994
562k
    ps_nal_prms->u1_pps_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
995
562k
    if(ps_nal_prms->u1_pps_id & MASK_ERR_PIC_SET_ID) return ERROR_INV_SLICE_HDR_T;
996
997
    /* validate pps id */
998
562k
    ps_pps += ps_nal_prms->u1_pps_id;
999
562k
    if(0 == ps_pps->u1_is_valid)
1000
69.6k
    {
1001
69.6k
        return NOT_OK;
1002
69.6k
    }
1003
    /* Derive sps id */
1004
493k
    ps_sps = ps_pps->ps_sps;
1005
1006
493k
    ps_nal_prms->u1_sps_id = ps_sps->u1_seq_parameter_set_id;
1007
493k
    if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type)
1008
100k
    {
1009
100k
        ps_sps += MAX_NUM_SEQ_PARAMS;
1010
100k
        ps_nal_prms->u1_sps_id = ps_sps->u1_seq_parameter_set_id;
1011
100k
        ps_nal_prms->u1_sps_id += MAX_NUM_SEQ_PARAMS;
1012
100k
    }
1013
1014
493k
    if(NULL == ps_sps)
1015
0
    {
1016
0
        return NOT_OK;
1017
0
    }
1018
493k
    if(FALSE == ps_sps->u1_is_valid)
1019
7.93k
    {
1020
7.93k
        return ERROR_INV_SLICE_HDR_T;
1021
7.93k
    }
1022
485k
    if(ps_nal_prms->u4_first_mb_addr > (ps_sps->u2_frm_ht_in_mbs * ps_sps->u2_frm_wd_in_mbs))
1023
35.1k
    {
1024
35.1k
        return ERROR_CORRUPTED_SLICE;
1025
35.1k
    }
1026
450k
    *pi4_sps_pps_status = 0;
1027
1028
    /* Parse frame number */
1029
450k
    ps_nal_prms->u2_frm_num = ih264d_get_bits_h264(ps_stream_ctxt, ps_sps->u1_bits_in_frm_num);
1030
1031
    /* IDR picture number */
1032
450k
    if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
1033
362k
    {
1034
362k
        ps_nal_prms->i4_idr_pic_num = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1035
1036
362k
        if(ps_nal_prms->i4_idr_pic_num > 65535) return ERROR_INV_SLICE_HDR_T;
1037
362k
    }
1038
1039
    /* Poc lsb */
1040
440k
    if(0 == ps_sps->u1_pic_order_cnt_type)
1041
331k
    {
1042
331k
        ps_nal_prms->i4_poc_lsb =
1043
331k
            ih264d_get_bits_h264(ps_stream_ctxt, ps_sps->u1_log2_max_pic_order_cnt_lsb_minus);
1044
1045
331k
        if(ps_nal_prms->i4_poc_lsb < 0 ||
1046
331k
           ps_nal_prms->i4_poc_lsb >= ps_sps->i4_max_pic_order_cntLsb)
1047
0
            return ERROR_INV_SLICE_HDR_T;
1048
331k
        if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
1049
112k
        {
1050
112k
            ps_nal_prms->i4_delta_poc_bot = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1051
112k
        }
1052
331k
    }
1053
109k
    else if((1 == ps_sps->u1_pic_order_cnt_type) && (!ps_sps->u1_delta_pic_order_always_zero_flag))
1054
84.5k
    {
1055
84.5k
        ps_nal_prms->ai4_delta_poc[0] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1056
1057
84.5k
        if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
1058
73.8k
        {
1059
73.8k
            ps_nal_prms->ai4_delta_poc[1] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1060
73.8k
        }
1061
84.5k
    }
1062
1063
440k
    *pu4_err_code = 0;
1064
440k
    return (OK);
1065
440k
}
1066
1067
/*****************************************************************************/
1068
/*                                                                           */
1069
/*  Function Name : isvcd_get_int_tgt_lyr_attr                                */
1070
/*                                                                           */
1071
/*  Description   : This routine returns the target layer attributes         */
1072
/*                  (dependency id, temporal id and quality id)              */
1073
/*                                                                           */
1074
/*  Inputs        : 1. Application attributes                                */
1075
/*                  2. Internal attributes (input and output)                */
1076
/*                  3. Nal prms structure                                    */
1077
/*  Globals       : None                                                     */
1078
/*  Processing    :                                                          */
1079
/*                                                                           */
1080
/*  Outputs       : Updated internal target layer attributes                 */
1081
/*  Returns       : status                                                   */
1082
/*                                                                           */
1083
/*  Issues        : None                                                     */
1084
/*                                                                           */
1085
/*  Revision History:                                                        */
1086
/*                                                                           */
1087
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1088
/*         06 09 2021   Vijay           Draft                                */
1089
/*                                                                           */
1090
/*****************************************************************************/
1091
WORD32 isvcd_get_int_tgt_lyr_attr(target_lyr_attr_t *ps_app_attr, target_lyr_attr_t *ps_int_attr,
1092
                                  nal_prms_t *ps_nal_prms)
1093
1.03M
{
1094
1.03M
    WORD32 i4_dep_id;
1095
1.03M
    WORD32 i4_quality_id;
1096
1.03M
    WORD32 i4_temp_id;
1097
1.03M
    WORD32 i4_prior_id;
1098
1099
    /* sanity checks */
1100
1.03M
    if((NULL == ps_app_attr) || (NULL == ps_int_attr) || (NULL == ps_nal_prms))
1101
0
    {
1102
0
        return NOT_OK;
1103
0
    }
1104
1105
1.03M
    i4_dep_id = ps_int_attr->i4_dependency_id;
1106
1.03M
    i4_quality_id = ps_int_attr->i4_quality_id;
1107
1.03M
    i4_temp_id = ps_int_attr->i4_temporal_id;
1108
1.03M
    i4_prior_id = ps_int_attr->i4_priority_id;
1109
1110
    /* check for idr pic flag                                  */
1111
    /* dependency & temporal id is updated only for IDR picture */
1112
1.03M
    if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
1113
359k
    {
1114
359k
        if(ps_int_attr->i4_dependency_id < ps_app_attr->i4_dependency_id)
1115
113k
        {
1116
            /* update the internal attributes only if             */
1117
            /* current dep_id -1 == highest dep id decoded so far */
1118
            /* and quality id is equal to 0                       */
1119
113k
            if((ps_nal_prms->i4_dependency_id - 1 == ps_int_attr->i4_dependency_id) &&
1120
113k
               (0 == ps_nal_prms->i4_quality_id))
1121
27.7k
            {
1122
                /* Set revised target dependency id */
1123
27.7k
                i4_dep_id = ps_nal_prms->i4_dependency_id;
1124
27.7k
                i4_temp_id = ps_app_attr->i4_temporal_id;
1125
27.7k
                i4_prior_id = ps_app_attr->i4_priority_id;
1126
27.7k
            }
1127
113k
        }
1128
246k
        else
1129
246k
        {
1130
            /* cases when the curr dep is greater than or equal to app dep */
1131
246k
            i4_dep_id = ps_app_attr->i4_dependency_id;
1132
246k
            i4_temp_id = ps_app_attr->i4_temporal_id;
1133
246k
            i4_prior_id = ps_app_attr->i4_priority_id;
1134
246k
        }
1135
359k
    }
1136
1137
    /* Set quality id */
1138
1.03M
    if(i4_dep_id == ps_app_attr->i4_dependency_id)
1139
471k
    {
1140
471k
        i4_quality_id = ps_app_attr->i4_quality_id;
1141
471k
    }
1142
563k
    else
1143
563k
    {
1144
563k
        i4_quality_id = MAX_QUALITY_ID;
1145
563k
    }
1146
1147
    /* Update the internal attributes */
1148
1.03M
    ps_int_attr->i4_dependency_id = i4_dep_id;
1149
1.03M
    ps_int_attr->i4_quality_id = i4_quality_id;
1150
1.03M
    ps_int_attr->i4_temporal_id = i4_temp_id;
1151
1.03M
    ps_int_attr->i4_priority_id = i4_prior_id;
1152
1153
1.03M
    return (OK);
1154
1.03M
}
1155
1156
/*****************************************************************************/
1157
/*                                                                           */
1158
/*  Function Name : isvcd_discard_nal                                         */
1159
/*                                                                           */
1160
/*  Description   : Determines whether current NAL unit has to be discarded  */
1161
/*                  or not                                                   */
1162
/*                                                                           */
1163
/*  Inputs        : pv_nal_prms - Pointer to NAL header prms                 */
1164
/*                      structure                                            */
1165
/*                  pv_app_lyr_attr - Pointer to application target layer    */
1166
/*                      attributes  structure                                */
1167
/*                  pv_app_lyr_attr - Pointer to internal target layer       */
1168
/*                      attributes  structure                                */
1169
/*                  i4_update_flag - This flag indicates whether the internal*/
1170
/*                      target attrbutes should be updated or not            */
1171
/*  Globals       : None                                                     */
1172
/*                                                                           */
1173
/*  Processing    : None                                                     */
1174
/*                                                                           */
1175
/*  Outputs       : None                                                     */
1176
/*                                                                           */
1177
/*  Returns       : None                                                     */
1178
/*                                                                           */
1179
/*  Issues        : None                                                     */
1180
/*                                                                           */
1181
/*  Revision History:                                                        */
1182
/*          DD MM YYYY   Author(s)       Changes                             */
1183
/*          06 09 2021   Vijay           Draft                               */
1184
/*                                                                           */
1185
/*****************************************************************************/
1186
WORD32 isvcd_discard_nal(void *pv_nal_prms, void *pv_app_attr, void *pv_int_attr,
1187
                         WORD32 i4_update_flag)
1188
1.66M
{
1189
1.66M
    WORD32 i4_discard_nal_flag;
1190
1.66M
    nal_prms_t *ps_nal_prms;
1191
1.66M
    target_lyr_attr_t *ps_app_attr;
1192
1.66M
    target_lyr_attr_t *ps_int_attr;
1193
1.66M
    WORD32 i4_status;
1194
1195
1.66M
    ps_nal_prms = (nal_prms_t *) pv_nal_prms;
1196
1.66M
    ps_app_attr = (target_lyr_attr_t *) pv_app_attr;
1197
1.66M
    ps_int_attr = (target_lyr_attr_t *) pv_int_attr;
1198
1199
    /* Get the updated target layer attributes */
1200
1.66M
    if(SVCD_TRUE == i4_update_flag)
1201
1.03M
    {
1202
1.03M
        i4_status = isvcd_get_int_tgt_lyr_attr(ps_app_attr, ps_int_attr, ps_nal_prms);
1203
1.03M
        if(OK != i4_status)
1204
0
        {
1205
0
            return NOT_OK;
1206
0
        }
1207
1.03M
    }
1208
1209
1.66M
    i4_discard_nal_flag = SVCD_FALSE;
1210
1211
1.66M
    if(VCL_NAL == ps_nal_prms->i4_derived_nal_type)
1212
748k
    {
1213
        /*-------------------------------------------------------------------*/
1214
        /*!Discard VCL NAL if any of following is true                       */
1215
        /*! - Dependency id is greater than target dependency id             */
1216
        /*! - Dependency id is equal to target dependency id but quality id  */
1217
        /*!   is greater than target quality id                              */
1218
        /*! - priority id is greater than target priority id                 */
1219
        /*! - Temporal id is greater than target temporal id                 */
1220
        /*! - If dependency id is greater than a NAL unit for which discard  */
1221
        /*!   flag of the NAL header is set                                  */
1222
        /*-------------------------------------------------------------------*/
1223
748k
        if(PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type)
1224
743k
        {
1225
743k
            if(ps_nal_prms->i4_dependency_id > ps_int_attr->i4_dependency_id)
1226
118k
            {
1227
118k
                i4_discard_nal_flag = SVCD_TRUE;
1228
118k
            }
1229
1230
743k
            if(ps_nal_prms->i4_dependency_id == ps_int_attr->i4_dependency_id &&
1231
743k
               ps_nal_prms->i4_quality_id > ps_int_attr->i4_quality_id)
1232
0
            {
1233
0
                i4_discard_nal_flag = SVCD_TRUE;
1234
0
            }
1235
1236
743k
            if(ps_nal_prms->i4_temporal_id > ps_int_attr->i4_temporal_id)
1237
3.18k
            {
1238
3.18k
                i4_discard_nal_flag = SVCD_TRUE;
1239
3.18k
            }
1240
1241
743k
            if(ps_nal_prms->i4_priority_id > ps_int_attr->i4_priority_id)
1242
0
            {
1243
0
                i4_discard_nal_flag = SVCD_TRUE;
1244
0
            }
1245
743k
        }
1246
4.71k
        else
1247
4.71k
        {
1248
4.71k
            if(0 == ps_int_attr->i4_quality_id && 0 == ps_int_attr->i4_dependency_id)
1249
2.29k
            {
1250
2.29k
                i4_discard_nal_flag = SVCD_TRUE;
1251
2.29k
            }
1252
4.71k
        }
1253
748k
    }
1254
1255
1.66M
    return (i4_discard_nal_flag);
1256
1.66M
}