xref: /aosp_15_r20/external/libavc/decoder/svc/isvcd_nal.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
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 /*****************************************************************************/
isvcd_nal_buf_reset(void * pv_nal_buf)145 void isvcd_nal_buf_reset(void *pv_nal_buf)
146 {
147     nal_buf_t *ps_nal_buf = pv_nal_buf;
148 
149     ps_nal_buf->i4_valid_flag = SVCD_FALSE;
150     ps_nal_buf->i4_buf_size = 0;
151     ps_nal_buf->u4_max_bits = 0;
152     ps_nal_buf->pu1_buf = NULL;
153 }
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 /*****************************************************************************/
isvcd_nal_find_start_code(UWORD8 * pu1_buf_start,WORD32 i4_cur_pos,WORD32 i4_max_num_bytes,WORD32 * pi4_zero_cnt,UWORD32 * pu4_bytes_consumed)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 {
185     UWORD8 *pu1_buf = pu1_buf_start + i4_cur_pos;
186     WORD32 i4_i;
187 
188     for(i4_i = 0; i4_i < (i4_max_num_bytes - i4_cur_pos); i4_i++)
189     {
190         /*-------------------------------------------------------------------*/
191         /* If zero increment the zero byte counter                           */
192         /*-------------------------------------------------------------------*/
193         if(0 == *pu1_buf)
194         {
195             (*pi4_zero_cnt)++;
196         }
197 
198         /*-------------------------------------------------------------------*/
199         /* If start code found then increment the byte consumed and return   */
200         /*-------------------------------------------------------------------*/
201         else if(0x01 == *pu1_buf && *pi4_zero_cnt >= NUM_OF_ZERO_BYTES_BEFORE_START_CODE)
202         {
203             (*pu4_bytes_consumed)++;
204             return (SC_FOUND);
205         }
206         /*-------------------------------------------------------------------*/
207         /* If non zero byte and value is not equal to 1 a then reset zero    */
208         /* byte counter                                                      */
209         /*-------------------------------------------------------------------*/
210         else
211         {
212             *pi4_zero_cnt = 0;
213         }
214 
215         (*pu4_bytes_consumed)++;
216         pu1_buf++;
217     }
218 
219     return (SC_NOT_FOUND);
220 }
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 
isvcd_get_first_start_code(UWORD8 * pu1_stream_buffer,UWORD32 * pu4_bytes_consumed,UWORD32 * pu4_num_bytes)246 WORD32 isvcd_get_first_start_code(UWORD8 *pu1_stream_buffer, UWORD32 *pu4_bytes_consumed,
247                                   UWORD32 *pu4_num_bytes)
248 {
249     WORD32 i4_zero_cnt = 0, i4_status;
250     UWORD32 u4_bytes_consumed_temp = 0;
251 
252     i4_status = isvcd_nal_find_start_code(pu1_stream_buffer, 0, *pu4_num_bytes, &i4_zero_cnt,
253                                           &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     if(SC_NOT_FOUND == i4_status)
261     {
262         *pu4_bytes_consumed += u4_bytes_consumed_temp;
263         return (i4_status);
264     }
265     else
266     {
267         /*-------------------------------------------------------------------*/
268         /* If start code found then proceed with bitstream extraction        */
269         /*-------------------------------------------------------------------*/
270         *pu4_bytes_consumed += u4_bytes_consumed_temp;
271         return (i4_status);
272     }
273 }
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 
isvcd_get_annex_b_nal_unit(UWORD8 * pu1_buf_start,WORD32 i4_cur_pos,WORD32 i4_max_num_bytes,WORD32 * pi4_state,WORD32 * pi4_zero_byte_cnt,UWORD32 * pu4_bytes_consumed,void * pv_nal_unit,WORD32 * pi4_more_data_flag)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 {
313     nal_unit_t *ps_nal_unit = (nal_unit_t *) pv_nal_unit;
314     WORD32 i4_status, i4_nal_start_flag = SVCD_FALSE;
315 
316     /*-----------------------------------------------------------------------*/
317     /* Initialization                                                        */
318     /*-----------------------------------------------------------------------*/
319     *pu4_bytes_consumed = 0;
320     *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     if(NAL_END == *pi4_state)
328     {
329         return i4_nal_start_flag;
330     }
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     ps_nal_unit->pu1_bufs = pu1_buf_start + i4_cur_pos;
342 
343     if(NAL_START == *pi4_state)
344     {
345         if(0 != *pi4_zero_byte_cnt)
346         {
347             return i4_nal_start_flag;
348         }
349         i4_nal_start_flag = SVCD_TRUE;
350         ps_nal_unit->i4_num_bufs = 1;
351         ps_nal_unit->i4_buf_sizes = 0;
352         *pi4_state = FIND_NAL_END;
353     }
354 
355     i4_status = isvcd_nal_find_start_code(pu1_buf_start, i4_cur_pos, i4_max_num_bytes,
356                                           pi4_zero_byte_cnt, pu4_bytes_consumed);
357 
358     if(SC_NOT_FOUND == i4_status)
359     {
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         ps_nal_unit->i4_buf_sizes = *pu4_bytes_consumed;
370         *pi4_more_data_flag = SVCD_FALSE;
371 
372         return (i4_nal_start_flag);
373     }
374     else
375     {
376         /*-------------------------------------------------------------------*/
377         /* If NAL END is found then increment the bytes consumed appropriatly*/
378         /* reset the zero byte counter                                       */
379         /*-------------------------------------------------------------------*/
380         *pi4_state = NAL_END;
381         ps_nal_unit->i4_buf_sizes = *pu4_bytes_consumed - 1;
382         *pi4_zero_byte_cnt = 0;
383         return (i4_nal_start_flag);
384     }
385 }
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 
isvcd_nal_rbsp_to_sodb(UWORD8 * pu1_buf,WORD32 i4_nal_len_in_bytes,UWORD8 u1_ecd_mode)412 UWORD32 isvcd_nal_rbsp_to_sodb(UWORD8 *pu1_buf, WORD32 i4_nal_len_in_bytes, UWORD8 u1_ecd_mode)
413 {
414     UWORD32 u4_last_word_pos;
415     UWORD32 u4_word, u4_max_bit_offset;
416     UWORD8 i4_num_bits;
417     WORD32 i4_i;
418     WORD64 i8_nal_len;
419     UWORD32 *pu4_buf;
420 
421     if(0 >= i4_nal_len_in_bytes)
422     {
423         return (0);
424     }
425 
426     /* Get offset in bits */
427     i8_nal_len = (WORD64) i4_nal_len_in_bytes << 3;
428     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     if(1 == u1_ecd_mode)
434     {
435         return (u4_max_bit_offset);
436     }
437 
438     /* Calculate the position of last word */
439     u4_last_word_pos = i4_nal_len_in_bytes >> 2;
440 
441     /* Load the last word                 */
442     i4_i = i4_nal_len_in_bytes & 0x03;
443     if(0 != i4_i)
444     {
445         pu4_buf = (UWORD32 *) pu1_buf;
446         pu4_buf += u4_last_word_pos;
447         u4_word = *pu4_buf;
448         i4_num_bits = i4_i << 3;
449         u4_word >>= (32 - i4_num_bits);
450     }
451     else
452     {
453         pu4_buf = (UWORD32 *) pu1_buf;
454         pu4_buf += (u4_last_word_pos - 1);
455         u4_word = *pu4_buf;
456         i4_num_bits = 32;
457     }
458 
459     /* Search for RBSP stop bit          */
460     do
461     {
462         for(i4_i = 0; (i4_i < i4_num_bits) && !CHECKBIT(u4_word, i4_i); i4_i++)
463             ;
464 
465         u4_max_bit_offset -= i4_i;
466 
467         /* RBSP stop bit is found then   */
468         /* come out of the loop          */
469         if(0 != CHECKBIT(u4_word, i4_i))
470         {
471             /* Remove RBSP stop bit */
472             u4_max_bit_offset -= 1;
473             break;
474         }
475 
476         pu4_buf -= 1;
477         u4_word = *pu4_buf;
478         i4_num_bits = 32;
479     } while(u4_max_bit_offset > 0);
480 
481     return (u4_max_bit_offset);
482 }
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 
isvcd_reset_emulation_ctxt(void * pv_emulation_ctxt)509 void isvcd_reset_emulation_ctxt(void *pv_emulation_ctxt)
510 {
511     emulation_prevent_ctxt_t *ps_emulation_ctxt = (emulation_prevent_ctxt_t *) pv_emulation_ctxt;
512 
513     /*! Reset the emulation prevention context */
514     ps_emulation_ctxt->i4_state = NOT_STUFFED_BYTE;
515     ps_emulation_ctxt->i4_zeroes_cnt = 0;
516     ps_emulation_ctxt->u4_bytes_in_word = 0;
517     ps_emulation_ctxt->u4_word = 0;
518 }
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 /****************************************************************************/
isvcd_nal_byte_swap_emulation(UWORD32 * pu4_out_stream,UWORD32 * pu4_out_len,UWORD8 * pu1_in_stream,UWORD32 u4_in_len,WORD32 i4_0s_bfr_sc,void * pv_emulation_ctxt)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 {
565     UWORD32 u4_i, u4_num_bytes, u4_offset;
566     UWORD8 u1_cur_byte;
567     emulation_prevent_ctxt_t *ps_emulation_ctxt = (emulation_prevent_ctxt_t *) pv_emulation_ctxt;
568 
569     u4_offset = ps_emulation_ctxt->u4_bytes_in_word;
570     u4_num_bytes = ps_emulation_ctxt->u4_bytes_in_word;
571 
572     for(u4_i = 0; u4_i < u4_in_len; u4_i++)
573     {
574         UWORD8 u1_cur_byte_emu, u1_cur_byte_sc;
575         UWORD64 u8_sft_word;
576 
577         u1_cur_byte = *pu1_in_stream++;
578         u1_cur_byte_emu = (EMULATION_PREVENTION_BYTE == u1_cur_byte);
579         u1_cur_byte_sc = (START_CODE_BYTE == u1_cur_byte);
580 
581         if((ps_emulation_ctxt->i4_zeroes_cnt >= i4_0s_bfr_sc) & (u1_cur_byte_emu | u1_cur_byte_sc) &
582            (NOT_STUFFED_BYTE == ps_emulation_ctxt->i4_state))
583         {
584             if(u1_cur_byte_sc)
585             {
586                 break;
587             }
588             ps_emulation_ctxt->i4_zeroes_cnt = 0;
589             ps_emulation_ctxt->i4_state = STUFFED_BYTE;
590             continue;
591         }
592 
593         u8_sft_word = (UWORD64) ps_emulation_ctxt->u4_word << 8;
594         ps_emulation_ctxt->u4_word = (UWORD32) (u8_sft_word | u1_cur_byte);
595         ps_emulation_ctxt->u4_bytes_in_word++;
596         u4_num_bytes++;
597         ps_emulation_ctxt->i4_zeroes_cnt++;
598         if(u1_cur_byte != 0x00)
599         {
600             ps_emulation_ctxt->i4_zeroes_cnt = 0;
601         }
602 
603         if((u4_num_bytes & 0x03) == 0x00)
604         {
605             *pu4_out_stream = ps_emulation_ctxt->u4_word;
606             ps_emulation_ctxt->u4_bytes_in_word = 0;
607             pu4_out_stream++;
608         }
609 
610         ps_emulation_ctxt->i4_state = NOT_STUFFED_BYTE;
611     }
612 
613     if(ps_emulation_ctxt->u4_bytes_in_word)
614     {
615         UWORD64 temp_out_stream = (UWORD64) ps_emulation_ctxt->u4_word
616                                   << ((4 - ps_emulation_ctxt->u4_bytes_in_word) << 3);
617         *pu4_out_stream = (UWORD32) temp_out_stream;
618     }
619 
620     *pu4_out_len = (u4_num_bytes - u4_offset);
621     return ((u4_num_bytes & 0xFFFFFFFC));
622 }
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 /*****************************************************************************/
isvcd_set_default_nal_prms(void * pv_nal_prms)649 void isvcd_set_default_nal_prms(void *pv_nal_prms)
650 {
651     nal_prms_t *ps_nal_prms;
652     ps_nal_prms = (nal_prms_t *) pv_nal_prms;
653 
654     /* Set default values */
655     ps_nal_prms->i4_dependency_id = 0;
656     ps_nal_prms->i4_derived_nal_type = 0xFF;
657     ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
658     ps_nal_prms->i4_nal_header_len = 0;
659     ps_nal_prms->i4_nal_ref_idc = 0xFF;
660     ps_nal_prms->i4_nal_unit_type = 0xFF;
661     ps_nal_prms->i4_no_int_lyr_pred = 1;
662     ps_nal_prms->i4_priority_id = 0;
663     ps_nal_prms->i4_quality_id = 0;
664     ps_nal_prms->i4_discard_flag = 0;
665     ps_nal_prms->i4_dqid = 0;
666     ps_nal_prms->i4_use_ref_base_pic_flag = 0;
667     ps_nal_prms->i4_temporal_id = 0;
668     ps_nal_prms->i4_idr_pic_num = 0;
669     ps_nal_prms->u2_frm_num = 0;
670     ps_nal_prms->i4_poc_lsb = 0;
671     ps_nal_prms->i4_delta_poc_bot = 0;
672     ps_nal_prms->ai4_delta_poc[0] = 0;
673     ps_nal_prms->ai4_delta_poc[1] = 0;
674     ps_nal_prms->u1_pps_id = 0;
675 }
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 /*****************************************************************************/
isvcd_dec_nal_hdr(void * pv_buf_ptr,WORD32 i4_buf_size,void * pv_nal_header_buf,void * pv_nal_prms,void * pv_prefix_nal_buf,void * pv_prefix_nal_prms,UWORD32 * pu4_err_code)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 {
706     nal_prms_t *ps_nal_prms;
707     nal_prms_t *ps_prefix_nal_prms;
708     nal_buf_t *ps_prefix_nal_buf;
709     dec_bit_stream_t s_stream_ctxt = {0};
710     WORD32 i4_forbidden_zero_bit;
711 
712     /* byte swapping */
713     UWORD8 *pu1_buf = (UWORD8 *) pv_nal_header_buf;
714     UWORD8 *pu1_src = (UWORD8 *) pv_buf_ptr;
715 
716     ps_nal_prms = (nal_prms_t *) pv_nal_prms;
717     ps_prefix_nal_prms = (nal_prms_t *) pv_prefix_nal_prms;
718     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     s_stream_ctxt.u4_ofst = 0;
726     s_stream_ctxt.pu4_buffer = pv_nal_header_buf;
727     s_stream_ctxt.u4_max_ofst = (i4_buf_size << 3);
728 
729     *pu4_err_code = 0;
730 
731     /* Check the size of bitstream buffer */
732     if(s_stream_ctxt.u4_max_ofst < 8)
733     {
734         *pu4_err_code = (UWORD32) NAL_INSUFFICIENT_DATA;
735         return;
736     }
737 
738     if(s_stream_ctxt.u4_max_ofst >= 32)
739     {
740         *pu1_buf++ = *(pu1_src + 3);
741         *pu1_buf++ = *(pu1_src + 2);
742         *pu1_buf++ = *(pu1_src + 1);
743         *pu1_buf++ = *pu1_src;
744     }
745     else
746     {
747         *pu1_buf++ = *pu1_src;
748     }
749 
750     /*-----------------------------------------------------------------------*/
751     /*! Parse the NAL header and update the NAL header structure members     */
752     /*-----------------------------------------------------------------------*/
753     /* Read forbidden 0 bit */
754     i4_forbidden_zero_bit = ih264d_get_bit_h264(&s_stream_ctxt);
755 
756     if(0 != i4_forbidden_zero_bit)
757     {
758         *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
759         return;
760     }
761 
762     /*---------------- Read NAL ref idc -----------------------------*/
763     ps_nal_prms->i4_nal_ref_idc = ih264d_get_bits_h264(&s_stream_ctxt, 2);
764 
765     /*----------------- Read NAL type -------------------------------*/
766     ps_nal_prms->i4_nal_unit_type = ih264d_get_bits_h264(&s_stream_ctxt, 5);
767     if(ps_nal_prms->i4_nal_unit_type > CODED_SLICE_EXTENSION_NAL)
768     {
769         *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
770         return;
771     }
772     if(ACCESS_UNIT_DELIMITER_RBSP == ps_nal_prms->i4_nal_unit_type)
773     {
774         ps_nal_prms->i4_derived_nal_type = NON_VCL_NAL;
775         return;
776     }
777 
778     /* set idr pic flag */
779     if(IDR_SLICE_NAL == ps_nal_prms->i4_nal_unit_type)
780     {
781         ps_nal_prms->i4_idr_pic_flag = SVCD_TRUE;
782     }
783     else
784     {
785         ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
786     }
787 
788     /*----------------- Read SVC extension NAL header ---------------*/
789     if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type ||
790        PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
791     {
792         WORD32 i4_svc_extension_flag, i4_idr_flag;
793 
794         /* check the size of the buffer */
795         if(s_stream_ctxt.u4_max_ofst < 32)
796         {
797             *pu4_err_code = (UWORD32) NAL_INSUFFICIENT_DATA;
798             return;
799         }
800 
801         i4_svc_extension_flag = ih264d_get_bit_h264(&s_stream_ctxt);
802         UNUSED(i4_svc_extension_flag);
803 
804         i4_idr_flag = ih264d_get_bit_h264(&s_stream_ctxt);
805 
806         /* Set idr pic flag based on idr flag */
807         if(1 == i4_idr_flag)
808         {
809             ps_nal_prms->i4_idr_pic_flag = SVCD_TRUE;
810         }
811         else
812         {
813             ps_nal_prms->i4_idr_pic_flag = SVCD_FALSE;
814         }
815 
816         /* parse priorit id */
817         ps_nal_prms->i4_priority_id = ih264d_get_bits_h264(&s_stream_ctxt, 6);
818 
819         /* parse the no inter layer prediction flag */
820         ps_nal_prms->i4_no_int_lyr_pred = ih264d_get_bit_h264(&s_stream_ctxt);
821 
822         /* parse dependency id */
823         ps_nal_prms->i4_dependency_id = ih264d_get_bits_h264(&s_stream_ctxt, 3);
824 
825         /* parse quality id */
826         ps_nal_prms->i4_quality_id = ih264d_get_bits_h264(&s_stream_ctxt, 4);
827 
828         if((ps_nal_prms->i4_quality_id > 0) || (ps_nal_prms->i4_dependency_id > 2))
829         {
830             *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
831             return;
832         }
833         /* parse temporal id */
834         ps_nal_prms->i4_temporal_id = ih264d_get_bits_h264(&s_stream_ctxt, 3);
835 
836         /* parse use ref base pic flag */
837         ps_nal_prms->i4_use_ref_base_pic_flag = ih264d_get_bit_h264(&s_stream_ctxt);
838 
839         if(0 != ps_nal_prms->i4_use_ref_base_pic_flag)
840         {
841             *pu4_err_code = (UWORD32) NAL_CORRUPT_DATA;
842             return;
843         }
844         /* parse discrad flag */
845         ps_nal_prms->i4_discard_flag = ih264d_get_bit_h264(&s_stream_ctxt);
846 
847         /* parse the reserved bits */
848         ih264d_get_bits_h264(&s_stream_ctxt, 3);
849     }
850 
851     /* update NAL hedaer length in bytes */
852     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     if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type)
861     {
862         isvcd_nal_buf_reset(ps_prefix_nal_buf);
863     }
864 
865     if(SVCD_TRUE == ps_prefix_nal_buf->i4_valid_flag)
866     {
867         /* Copy the required parameters from the prefix NAL unit */
868         ps_nal_prms->i4_dependency_id = ps_prefix_nal_prms->i4_dependency_id;
869         ps_nal_prms->i4_quality_id = ps_prefix_nal_prms->i4_quality_id;
870         ps_nal_prms->i4_priority_id = ps_prefix_nal_prms->i4_priority_id;
871         ps_nal_prms->i4_temporal_id = ps_prefix_nal_prms->i4_temporal_id;
872         ps_nal_prms->i4_no_int_lyr_pred = ps_prefix_nal_prms->i4_no_int_lyr_pred;
873         ps_nal_prms->i4_use_ref_base_pic_flag = ps_prefix_nal_prms->i4_use_ref_base_pic_flag;
874         ps_nal_prms->i4_discard_flag = ps_prefix_nal_prms->i4_discard_flag;
875     }
876 
877     /*-----------------------------------------------------------------------*/
878     /* Set the derived NAL unit type and also update the DQID for VCL NAL    */
879     /*  units                                                                */
880     /*-----------------------------------------------------------------------*/
881     if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type ||
882        SLICE_NAL == ps_nal_prms->i4_nal_unit_type ||
883        IDR_SLICE_NAL == ps_nal_prms->i4_nal_unit_type ||
884        PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
885     {
886         ps_nal_prms->i4_derived_nal_type = VCL_NAL;
887 
888         /* calculate the DQID and modified DQID */
889         ps_nal_prms->i4_dqid = (ps_nal_prms->i4_dependency_id << 4) + ps_nal_prms->i4_quality_id;
890     }
891     else
892     {
893         ps_nal_prms->i4_derived_nal_type = NON_VCL_NAL;
894     }
895 }
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 /*****************************************************************************/
isvcd_parse_part_slice_hdr(UWORD8 * pu1_input_buf,WORD32 i4_input_buf_size,UWORD8 * pu1_temp_buf,void * pv_sps,void * pv_pps,nal_prms_t * ps_nal_prms,UWORD32 * pu4_err_code,WORD32 * pi4_sps_pps_status)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 {
929     UWORD32 u4_slice_type;
930     dec_seq_params_t *ps_sps = (dec_seq_params_t *) pv_sps;
931     dec_pic_params_t *ps_pps = (dec_pic_params_t *) pv_pps;
932     dec_bit_stream_t s_stream_ctxt = {0};
933     dec_bit_stream_t *ps_stream_ctxt;
934     UWORD32 *pu4_bitstrm_buf;
935     UWORD32 *pu4_bitstrm_ofst;
936 
937     *pi4_sps_pps_status = NAL_CORRUPT_DATA;
938     /* Perform the emulation prevention and byte swap */
939     {
940         emulation_prevent_ctxt_t s_emulation_ctxt = {0};
941         WORD32 i4_size, i4_temp;
942 
943         isvcd_reset_emulation_ctxt((void *) &s_emulation_ctxt);
944         i4_size = MIN(i4_input_buf_size, HEADER_BUFFER_LEN_BEFORE_EP);
945 
946         isvcd_nal_byte_swap_emulation((UWORD32 *) pu1_temp_buf, (UWORD32 *) &i4_temp, pu1_input_buf,
947                                       (UWORD32) i4_size, NUM_OF_ZERO_BYTES_BEFORE_START_CODE,
948                                       &s_emulation_ctxt);
949 
950         /* Initialize the stream context structure */
951         s_stream_ctxt.pu4_buffer = (UWORD32 *) pu1_temp_buf;
952         s_stream_ctxt.u4_ofst = 0;
953         s_stream_ctxt.u4_max_ofst = (i4_size << 3);
954     }
955 
956     ps_stream_ctxt = &s_stream_ctxt;
957 
958     /* Parse the first mb address in slice */
959     pu4_bitstrm_buf = ps_stream_ctxt->pu4_buffer;
960     pu4_bitstrm_ofst = &ps_stream_ctxt->u4_ofst;
961     ps_nal_prms->u4_first_mb_addr = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
962     if(ps_nal_prms->u4_first_mb_addr >= (MAX_MBS_LEVEL_51))
963     {
964         return ERROR_CORRUPTED_SLICE;
965     }
966     /* Parse slice type */
967     u4_slice_type = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
968 
969     if(u4_slice_type > 9) return ERROR_INV_SLC_TYPE_T;
970 
971     /* Check the validity of slice prms */
972     switch(u4_slice_type)
973     {
974         case 0:
975         case 5:
976             u4_slice_type = P_SLICE;
977             /* P slice */
978             break;
979         case 1:
980         case 6:
981             u4_slice_type = B_SLICE;
982             /* B slice */
983             break;
984         case 2:
985         case 7:
986             /* I slice */
987             u4_slice_type = I_SLICE;
988             break;
989         default:
990             break;
991     }
992 
993     /* Parse the pps id */
994     ps_nal_prms->u1_pps_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
995     if(ps_nal_prms->u1_pps_id & MASK_ERR_PIC_SET_ID) return ERROR_INV_SLICE_HDR_T;
996 
997     /* validate pps id */
998     ps_pps += ps_nal_prms->u1_pps_id;
999     if(0 == ps_pps->u1_is_valid)
1000     {
1001         return NOT_OK;
1002     }
1003     /* Derive sps id */
1004     ps_sps = ps_pps->ps_sps;
1005 
1006     ps_nal_prms->u1_sps_id = ps_sps->u1_seq_parameter_set_id;
1007     if(CODED_SLICE_EXTENSION_NAL == ps_nal_prms->i4_nal_unit_type)
1008     {
1009         ps_sps += MAX_NUM_SEQ_PARAMS;
1010         ps_nal_prms->u1_sps_id = ps_sps->u1_seq_parameter_set_id;
1011         ps_nal_prms->u1_sps_id += MAX_NUM_SEQ_PARAMS;
1012     }
1013 
1014     if(NULL == ps_sps)
1015     {
1016         return NOT_OK;
1017     }
1018     if(FALSE == ps_sps->u1_is_valid)
1019     {
1020         return ERROR_INV_SLICE_HDR_T;
1021     }
1022     if(ps_nal_prms->u4_first_mb_addr > (ps_sps->u2_frm_ht_in_mbs * ps_sps->u2_frm_wd_in_mbs))
1023     {
1024         return ERROR_CORRUPTED_SLICE;
1025     }
1026     *pi4_sps_pps_status = 0;
1027 
1028     /* Parse frame number */
1029     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     if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
1033     {
1034         ps_nal_prms->i4_idr_pic_num = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1035 
1036         if(ps_nal_prms->i4_idr_pic_num > 65535) return ERROR_INV_SLICE_HDR_T;
1037     }
1038 
1039     /* Poc lsb */
1040     if(0 == ps_sps->u1_pic_order_cnt_type)
1041     {
1042         ps_nal_prms->i4_poc_lsb =
1043             ih264d_get_bits_h264(ps_stream_ctxt, ps_sps->u1_log2_max_pic_order_cnt_lsb_minus);
1044 
1045         if(ps_nal_prms->i4_poc_lsb < 0 ||
1046            ps_nal_prms->i4_poc_lsb >= ps_sps->i4_max_pic_order_cntLsb)
1047             return ERROR_INV_SLICE_HDR_T;
1048         if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
1049         {
1050             ps_nal_prms->i4_delta_poc_bot = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1051         }
1052     }
1053     else if((1 == ps_sps->u1_pic_order_cnt_type) && (!ps_sps->u1_delta_pic_order_always_zero_flag))
1054     {
1055         ps_nal_prms->ai4_delta_poc[0] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1056 
1057         if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
1058         {
1059             ps_nal_prms->ai4_delta_poc[1] = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
1060         }
1061     }
1062 
1063     *pu4_err_code = 0;
1064     return (OK);
1065 }
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 /*****************************************************************************/
isvcd_get_int_tgt_lyr_attr(target_lyr_attr_t * ps_app_attr,target_lyr_attr_t * ps_int_attr,nal_prms_t * ps_nal_prms)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 {
1094     WORD32 i4_dep_id;
1095     WORD32 i4_quality_id;
1096     WORD32 i4_temp_id;
1097     WORD32 i4_prior_id;
1098 
1099     /* sanity checks */
1100     if((NULL == ps_app_attr) || (NULL == ps_int_attr) || (NULL == ps_nal_prms))
1101     {
1102         return NOT_OK;
1103     }
1104 
1105     i4_dep_id = ps_int_attr->i4_dependency_id;
1106     i4_quality_id = ps_int_attr->i4_quality_id;
1107     i4_temp_id = ps_int_attr->i4_temporal_id;
1108     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     if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
1113     {
1114         if(ps_int_attr->i4_dependency_id < ps_app_attr->i4_dependency_id)
1115         {
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             if((ps_nal_prms->i4_dependency_id - 1 == ps_int_attr->i4_dependency_id) &&
1120                (0 == ps_nal_prms->i4_quality_id))
1121             {
1122                 /* Set revised target dependency id */
1123                 i4_dep_id = ps_nal_prms->i4_dependency_id;
1124                 i4_temp_id = ps_app_attr->i4_temporal_id;
1125                 i4_prior_id = ps_app_attr->i4_priority_id;
1126             }
1127         }
1128         else
1129         {
1130             /* cases when the curr dep is greater than or equal to app dep */
1131             i4_dep_id = ps_app_attr->i4_dependency_id;
1132             i4_temp_id = ps_app_attr->i4_temporal_id;
1133             i4_prior_id = ps_app_attr->i4_priority_id;
1134         }
1135     }
1136 
1137     /* Set quality id */
1138     if(i4_dep_id == ps_app_attr->i4_dependency_id)
1139     {
1140         i4_quality_id = ps_app_attr->i4_quality_id;
1141     }
1142     else
1143     {
1144         i4_quality_id = MAX_QUALITY_ID;
1145     }
1146 
1147     /* Update the internal attributes */
1148     ps_int_attr->i4_dependency_id = i4_dep_id;
1149     ps_int_attr->i4_quality_id = i4_quality_id;
1150     ps_int_attr->i4_temporal_id = i4_temp_id;
1151     ps_int_attr->i4_priority_id = i4_prior_id;
1152 
1153     return (OK);
1154 }
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 /*****************************************************************************/
isvcd_discard_nal(void * pv_nal_prms,void * pv_app_attr,void * pv_int_attr,WORD32 i4_update_flag)1186 WORD32 isvcd_discard_nal(void *pv_nal_prms, void *pv_app_attr, void *pv_int_attr,
1187                          WORD32 i4_update_flag)
1188 {
1189     WORD32 i4_discard_nal_flag;
1190     nal_prms_t *ps_nal_prms;
1191     target_lyr_attr_t *ps_app_attr;
1192     target_lyr_attr_t *ps_int_attr;
1193     WORD32 i4_status;
1194 
1195     ps_nal_prms = (nal_prms_t *) pv_nal_prms;
1196     ps_app_attr = (target_lyr_attr_t *) pv_app_attr;
1197     ps_int_attr = (target_lyr_attr_t *) pv_int_attr;
1198 
1199     /* Get the updated target layer attributes */
1200     if(SVCD_TRUE == i4_update_flag)
1201     {
1202         i4_status = isvcd_get_int_tgt_lyr_attr(ps_app_attr, ps_int_attr, ps_nal_prms);
1203         if(OK != i4_status)
1204         {
1205             return NOT_OK;
1206         }
1207     }
1208 
1209     i4_discard_nal_flag = SVCD_FALSE;
1210 
1211     if(VCL_NAL == ps_nal_prms->i4_derived_nal_type)
1212     {
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         if(PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type)
1224         {
1225             if(ps_nal_prms->i4_dependency_id > ps_int_attr->i4_dependency_id)
1226             {
1227                 i4_discard_nal_flag = SVCD_TRUE;
1228             }
1229 
1230             if(ps_nal_prms->i4_dependency_id == ps_int_attr->i4_dependency_id &&
1231                ps_nal_prms->i4_quality_id > ps_int_attr->i4_quality_id)
1232             {
1233                 i4_discard_nal_flag = SVCD_TRUE;
1234             }
1235 
1236             if(ps_nal_prms->i4_temporal_id > ps_int_attr->i4_temporal_id)
1237             {
1238                 i4_discard_nal_flag = SVCD_TRUE;
1239             }
1240 
1241             if(ps_nal_prms->i4_priority_id > ps_int_attr->i4_priority_id)
1242             {
1243                 i4_discard_nal_flag = SVCD_TRUE;
1244             }
1245         }
1246         else
1247         {
1248             if(0 == ps_int_attr->i4_quality_id && 0 == ps_int_attr->i4_dependency_id)
1249             {
1250                 i4_discard_nal_flag = SVCD_TRUE;
1251             }
1252         }
1253     }
1254 
1255     return (i4_discard_nal_flag);
1256 }
1257