xref: /aosp_15_r20/external/libavc/decoder/svc/isvcd_nal_parse.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_parse.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 /* File Includes                                                             */
38 /*****************************************************************************/
39 
40 /* System include files */
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <limits.h>
45 #include <stddef.h>
46 #include <assert.h>
47 
48 /* standard interface include files */
49 #include "ih264_typedefs.h"
50 #include "ih264_macros.h"
51 #include "ih264_platform_macros.h"
52 #include "ih264d_tables.h"
53 #include "iv.h"
54 #include "ivd.h"
55 #include "ih264d_defs.h"
56 #include "ih264d_debug.h"
57 #include "ih264_debug.h"
58 #include "ih264d_inter_pred.h"
59 #include "isvcd_structs.h"
60 #include "ih264d_nal.h"
61 #include "ih264d_error_handler.h"
62 
63 /*****************************************************************************/
64 /*Extern Variable Declarations                                               */
65 /*****************************************************************************/
66 
67 /*****************************************************************************/
68 /* Global Variable Definitions                                               */
69 /*****************************************************************************/
70 
71 /*****************************************************************************/
72 /* Static Global Variable Definitions                                        */
73 /*****************************************************************************/
74 
75 /*****************************************************************************/
76 /* Static function Definitions                                               */
77 /*****************************************************************************/
78 
79 /*****************************************************************************/
80 /*                                                                           */
81 /*  Function Name : isvcd_get_nal_buf                                         */
82 /*                                                                           */
83 /*  Description   : This routine returns the NAL buffer structure to use for */
84 /*                  current NAL unit. This will also perform the initializa -*/
85 /*                  tion of the structure                                    */
86 /*  Inputs        : 1. NAL parse structure                                   */
87 /*                  2. Place holder for nal buffer structure                 */
88 /*  Globals       : None                                                     */
89 /*  Processing    : If current NAL unit prefix NAL unit then                 */
90 /*                      - Resets the prefix nal buffer structure             */
91 /*                      - Assigns the buffer pointer                         */
92 /*                  Otherwise                                                */
93 /*                      - Assigns the buffer pointer                         */
94 /*  Outputs       :  - Updated NAL buffer strcuture                          */
95 /*                   - Updates the place holder with correct NAL buffer      */
96 /*                  structure                                                */
97 /*  Returns       : None                                                     */
98 /*                                                                           */
99 /*  Issues        : None                                                     */
100 /*                                                                           */
101 /*  Revision History:                                                        */
102 /*                                                                           */
103 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
104 /*         06 09 2021   Vijay      Draft                                     */
105 /*                                                                           */
106 /*****************************************************************************/
isvcd_get_nal_buf(nal_parse_ctxt_t * ps_nal_parse_ctxt,nal_buf_t ** pps_nal_buf)107 void isvcd_get_nal_buf(nal_parse_ctxt_t *ps_nal_parse_ctxt, nal_buf_t **pps_nal_buf)
108 {
109     nal_prms_t *ps_nal_prms;
110     nal_buf_t *ps_nal_buf;
111 
112     ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
113 
114     /* Get the NAL buffer structure */
115     if(PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
116     {
117         ps_nal_buf = &ps_nal_parse_ctxt->s_prefix_nal_buf;
118 
119         /* Note: This reset will cause a prefix NAL unit */
120         /* which is followed by another prefix NAL unit  */
121         /* to be ignored by the module. This is indeed   */
122         /* a desired behaviour                           */
123         isvcd_nal_buf_reset(ps_nal_buf);
124     }
125     else
126     {
127         ps_nal_buf = &ps_nal_parse_ctxt->s_nal_buf;
128     }
129 
130     /* Initialize the buffer structure */
131     ps_nal_buf->i4_valid_flag = SVCD_TRUE;
132     if(VCL_NAL == ps_nal_prms->i4_derived_nal_type)
133     {
134         ps_nal_buf->pu1_buf = ps_nal_parse_ctxt->pu1_vcl_nal_buf;
135     }
136     else if(NON_VCL_NAL == ps_nal_prms->i4_derived_nal_type)
137     {
138         ps_nal_buf->pu1_buf = ps_nal_parse_ctxt->pu1_non_vcl_nal_buf;
139     }
140     else
141     {
142         ps_nal_buf->pu1_buf = NULL;
143         return;
144     }
145 
146     *pps_nal_buf = ps_nal_buf;
147 }
148 
149 /*****************************************************************************/
150 /*                                                                           */
151 /*  Function Name : isvcd_dqid_ctxt_reset                                     */
152 /*                                                                           */
153 /*  Description   : This routine resets the DQID context. This routine shall */
154 /*                  be invoked once in a picture                             */
155 /*                                                                           */
156 /*  Inputs        : DQID context structure                                   */
157 /*  Globals       : None                                                     */
158 /*  Processing    : Invalidates all the DQID nodes                           */
159 /*                                                                           */
160 /*  Outputs       : Updated DQID context                                     */
161 /*  Returns       : status                                                   */
162 /*                                                                           */
163 /*  Issues        : None                                                     */
164 /*                                                                           */
165 /*  Revision History:                                                        */
166 /*                                                                           */
167 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
168 /*         06 09 2021   Vijay      Draft                                     */
169 /*                                                                           */
170 /*****************************************************************************/
isvcd_dqid_ctxt_reset(dqid_ctxt_t * ps_dqid_ctxt)171 WORD32 isvcd_dqid_ctxt_reset(dqid_ctxt_t *ps_dqid_ctxt)
172 {
173     WORD32 i4_lyr_idx;
174     WORD32 i4_max_num_lyrs;
175     dqid_node_t *ps_dqid_node;
176 
177     /* sanity checks */
178     if(NULL == ps_dqid_ctxt)
179     {
180         return NOT_OK;
181     }
182 
183     i4_max_num_lyrs = ps_dqid_ctxt->i4_max_num_lyrs;
184     ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
185 
186     /* Loop over all the layers */
187     for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
188     {
189         /* Reset the valid flag */
190         ps_dqid_node->u1_valid_flag = SVCD_FALSE;
191 
192         /* Loop updates */
193         ps_dqid_node += 1;
194     } /* loop over all the layers */
195 
196     return (OK);
197 }
198 
199 /*****************************************************************************/
200 /*                                                                           */
201 /*  Function Name : isvcd_get_dqid_node                                       */
202 /*                                                                           */
203 /*  Description   : This routine gets a DQID node corresponding to a DQID    */
204 /*                                                                           */
205 /*  Inputs        : 1. DQID context                                          */
206 /*                  2. DQID                                                  */
207 /*                  3. Place holder for DQID node (output)                   */
208 /*  Globals       : None                                                     */
209 /*  Processing    : It performs the following                                */
210 /*                  - Searches for all elements untill it gets element having*/
211 /*                    DQID equal to input DQID.                              */
212 /*                  - If not found it finds a free (un-occupied) node        */
213 /*                                                                           */
214 /*  Outputs       : 1. Updated DQID node                                     */
215 /*  Returns       : status                                                   */
216 /*                                                                           */
217 /*  Issues        : None                                                     */
218 /*                                                                           */
219 /*  Revision History:                                                        */
220 /*                                                                           */
221 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
222 /*         06 09 2021   Vijay      Draft                                     */
223 /*                                                                           */
224 /*****************************************************************************/
isvcd_get_dqid_node(dqid_ctxt_t * ps_dqid_ctxt,UWORD8 u1_dqid,dqid_node_t ** pps_dqid_node)225 WORD32 isvcd_get_dqid_node(dqid_ctxt_t *ps_dqid_ctxt, UWORD8 u1_dqid, dqid_node_t **pps_dqid_node)
226 {
227     WORD32 i4_lyr_idx;
228     WORD32 i4_max_num_lyrs;
229     dqid_node_t *ps_dqid_node;
230     dqid_node_t *ps_rqrd_dqid_node;
231 
232     /* sanity checks */
233     if((NULL == ps_dqid_ctxt) || (NULL == pps_dqid_node))
234     {
235         return NOT_OK;
236     }
237 
238     i4_max_num_lyrs = ps_dqid_ctxt->i4_max_num_lyrs;
239     ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
240 
241     /*Initialization */
242     ps_rqrd_dqid_node = NULL;
243 
244     /* Loop over all the buffer nodes */
245     for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
246     {
247         if((SVCD_TRUE == ps_dqid_node->u1_valid_flag) && (u1_dqid == ps_dqid_node->u1_dqid))
248         {
249             ps_rqrd_dqid_node = ps_dqid_node;
250             break;
251         }
252         /* Loop updates */
253         ps_dqid_node += 1;
254     } /* Loop over all the buffer nodes */
255 
256     if(NULL == ps_rqrd_dqid_node)
257     {
258         /* If vcl node is not allocated for the requested DQID then allocate buffer */
259         ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
260         for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
261         {
262             if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
263             {
264                 break;
265             }
266             /* Loop updates */
267             ps_dqid_node += 1;
268         } /* Loop over all the nodes */
269         /* Update the node structure */
270         ps_rqrd_dqid_node = ps_dqid_node;
271     }
272 
273     /* sanity checks */
274     if(NULL == ps_rqrd_dqid_node)
275     {
276         return NOT_OK;
277     }
278     *pps_dqid_node = ps_rqrd_dqid_node;
279 
280     return (OK);
281 }
282 
283 /*****************************************************************************/
284 /*                                                                           */
285 /*  Function Name : isvcd_nal_reset_ctxt                                     */
286 /*                                                                           */
287 /*  Description   : This routine performs NAL unit level initialization      */
288 /*                  This routine shall be called before parsing a NAL unit   */
289 /*                                                                           */
290 /*  Inputs        : 1. NAL parse context structure                           */
291 /*  Globals       : None                                                     */
292 /*  Processing    : This does initializaiton of NAL unit level tracking      */
293 /*                  varaibles                                                */
294 /*                                                                           */
295 /*  Outputs       : Updated context structure                                */
296 /*  Returns       : status                                                   */
297 /*                                                                           */
298 /*  Issues        : None                                                     */
299 /*                                                                           */
300 /*  Revision History:                                                        */
301 /*                                                                           */
302 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
303 /*         06 09 2021   Vijay      Draft                                     */
304 /*                                                                           */
305 /*****************************************************************************/
isvcd_nal_reset_ctxt(nal_parse_ctxt_t * ps_nal_parse_ctxt)306 WORD32 isvcd_nal_reset_ctxt(nal_parse_ctxt_t *ps_nal_parse_ctxt)
307 {
308     nal_unit_t *ps_nal_unit;
309 
310     if(NULL == ps_nal_parse_ctxt)
311     {
312         return NOT_OK;
313     }
314 
315     /* Reset the NAL boundary detetction */
316     ps_nal_parse_ctxt->i4_find_nal_state = NAL_START;
317     ps_nal_parse_ctxt->i4_zero_byte_cnt = 0;
318     ps_nal_unit = ps_nal_parse_ctxt->pv_nal_unit;
319     ps_nal_unit->i4_num_bufs = 0;
320 
321     /*Reset emulation prevention */
322     isvcd_reset_emulation_ctxt(&ps_nal_parse_ctxt->s_emulation_ctxt);
323 
324     /*Reset the NAL header prms */
325     isvcd_set_default_nal_prms(&ps_nal_parse_ctxt->s_nal_prms);
326 
327     /* Reset other NAL level tracking variables */
328     ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_FALSE;
329 
330     /*Reset NAL buffer structure*/
331     isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_nal_buf);
332 
333     return (OK);
334 }
335 
336 /*****************************************************************************/
337 /*                                                                           */
338 /*  Function Name : isvcd_pic_reset_ctxt                                      */
339 /*                                                                           */
340 /*  Description   : This routine performs the picture level initialization.  */
341 /*                  This routine shall be called before parsing a access unit*/
342 /*                                                                           */
343 /*  Inputs        : pv_nal_parse_ctxt - Pointer to context structure         */
344 /*                                                                           */
345 /*  Globals       : None                                                     */
346 /*                                                                           */
347 /*  Processing    : 1. Resets the varaibles                                  */
348 /*                                                                           */
349 /*  Outputs       : Updated context structure                                */
350 /*                                                                           */
351 /*  Returns       : none                                                     */
352 /*                                                                           */
353 /*  Issues        : None                                                     */
354 /*                                                                           */
355 /*  Revision History:                                                        */
356 /*          DD MM YYYY   Author(s)       Changes                             */
357 /*          06 09 2021   Vijay           Draft                               */
358 /*                                                                           */
359 /*****************************************************************************/
isvcd_pic_reset_ctxt(nal_parse_ctxt_t * ps_nal_parse_ctxt)360 void isvcd_pic_reset_ctxt(nal_parse_ctxt_t *ps_nal_parse_ctxt)
361 {
362     WORD32 i4_status;
363 
364     /*-----------------------------------------------------------------------*/
365     /*! Reset NAL boundary detetction logic                                  */
366     /*-----------------------------------------------------------------------*/
367     i4_status = isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
368 
369     UNUSED(i4_status);
370 
371     /*-----------------------------------------------------------------------*/
372     /*! Reset picture boundary detctetion logic                              */
373     /*-----------------------------------------------------------------------*/
374     ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au = SVCD_TRUE;
375 
376     /*-----------------------------------------------------------------------*/
377     /*! Reset VCL and non VCL NAL buffer tracking variables                  */
378     /*-----------------------------------------------------------------------*/
379     ps_nal_parse_ctxt->pu1_non_vcl_nal_buf = ps_nal_parse_ctxt->pv_non_vcl_nal_buf;
380     ps_nal_parse_ctxt->pu1_vcl_nal_buf = ps_nal_parse_ctxt->pv_vcl_nal_buf;
381 
382     /* reset the bytes left to buffer size */
383     ps_nal_parse_ctxt->u4_bytes_left_vcl = MAX_VCL_NAL_BUFF_SIZE;
384 
385     ps_nal_parse_ctxt->u4_bytes_left_non_vcl = MAX_NON_VCL_NAL_BUFF_SIZE;
386 
387     /* Offset the buffer to start of vcl data */
388     UPDATE_NAL_BUF_PTR(&ps_nal_parse_ctxt->pu1_non_vcl_nal_buf, NON_VCL_NAL,
389                        &ps_nal_parse_ctxt->u4_bytes_left_non_vcl);
390 
391     UPDATE_NAL_BUF_PTR(&ps_nal_parse_ctxt->pu1_vcl_nal_buf, VCL_NAL,
392                        &ps_nal_parse_ctxt->u4_bytes_left_vcl);
393 
394     /* Reset previous field */
395     ps_nal_parse_ctxt->ps_prev_non_vcl_buf = NULL;
396     ps_nal_parse_ctxt->i4_idr_pic_err_flag = 0;
397 
398     /*-----------------------------------------------------------------------*/
399     /*! Reset other NAL related tracking variables                           */
400     /*-----------------------------------------------------------------------*/
401     ps_nal_parse_ctxt->i4_num_non_vcl_nals = 0;
402 
403     /* Reset the vcl nal node buffer context */
404     i4_status = isvcd_dqid_ctxt_reset(&ps_nal_parse_ctxt->s_dqid_ctxt);
405 
406     /* Reset target layer update flag */
407     ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_TRUE;
408 }
409 
410 /*****************************************************************************/
411 /*                                                                           */
412 /*  Function Name : isvcd_get_nal_prms                                        */
413 /*                                                                           */
414 /*  Description   : This routine will update the nal prms                    */
415 /*  Inputs        : 1. Start of bitstream buffer containing NAL header       */
416 /*                  2. Size of the buffer                                    */
417 /*                  3. NAL prms structure                                    */
418 /*                  4. Place holder for error code                           */
419 /*                  5. Place holder for nal discard flag                     */
420 /*                  6. NAL parse context structure                           */
421 /*  Globals       : None                                                     */
422 /*  Processing    : 1. Parses the NAL header                                 */
423 /*                  2. Sets the discard flag                                 */
424 /*                  3. If NAL is not discarded and nal is VCL NAL unit then  */
425 /*                     decodes the slice prms (prefix nal units are excluded)*/
426 /*  Outputs       : Updated NAL prms structure                               */
427 /*                  Updated NAL discrd flag                                  */
428 /*                  Updates the error code if encountered with error         */
429 /*  Returns       : status                                                   */
430 /*                                                                           */
431 /*  Issues        : None                                                     */
432 /*                                                                           */
433 /*  Revision History:                                                        */
434 /*                                                                           */
435 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
436 /*         06 09 2021   Vijay           Draft                                */
437 /*                                                                           */
438 /*****************************************************************************/
isvcd_get_nal_prms(UWORD8 * pu1_buf,WORD32 i4_buf_size,nal_prms_t * ps_nal_prms,nal_prms_t * ps_prefix_nal_prms,nal_buf_t * ps_prefix_nal_buf,UWORD32 * pu4_err_code,WORD32 * pi4_sps_pps_status,WORD32 * pi4_nal_discard_flag,nal_parse_ctxt_t * ps_nal_parse_ctxt)439 WORD32 isvcd_get_nal_prms(UWORD8 *pu1_buf, WORD32 i4_buf_size, nal_prms_t *ps_nal_prms,
440                           nal_prms_t *ps_prefix_nal_prms, nal_buf_t *ps_prefix_nal_buf,
441                           UWORD32 *pu4_err_code, WORD32 *pi4_sps_pps_status,
442                           WORD32 *pi4_nal_discard_flag, nal_parse_ctxt_t *ps_nal_parse_ctxt)
443 {
444     UWORD8 *pu1_input_buf;
445     WORD32 i4_status;
446     dec_seq_params_t *ps_sps;
447     dec_pic_params_t *ps_pps;
448 
449     ps_sps = ps_nal_parse_ctxt->pv_seq_prms;
450     ps_pps = ps_nal_parse_ctxt->pv_pic_prms;
451 
452     *pu4_err_code = 0;
453     *pi4_sps_pps_status = NAL_CORRUPT_DATA;
454 
455     /* Decode the NAL header */
456     isvcd_dec_nal_hdr(pu1_buf, i4_buf_size, ps_nal_parse_ctxt->pv_nal_header_buf, ps_nal_prms,
457                       ps_prefix_nal_buf, ps_prefix_nal_prms, pu4_err_code);
458 
459     /* If encountered with error return fail */
460     if(0 != *pu4_err_code)
461     {
462         return (NOT_OK);
463     }
464 
465     if(ACCESS_UNIT_DELIMITER_RBSP == ps_nal_prms->i4_nal_unit_type)
466     {
467         *pi4_nal_discard_flag = 1;
468         return OK;
469     }
470 
471     /* Set the discard flag */
472     *pi4_nal_discard_flag = isvcd_discard_nal(
473         (void *) ps_nal_prms, (void *) &ps_nal_parse_ctxt->s_app_attr,
474         (void *) &ps_nal_parse_ctxt->s_int_attr, ps_nal_parse_ctxt->i4_tgt_lyr_update);
475 
476     /* Parse the slice header if all the following */
477     /* conditions are true                         */
478     /* 1. NAL is a VCL NAL unit                    */
479     /* 2. NAL is not a prefix NAL unit             */
480     /* 3. NAL is not discarded                     */
481     if((NON_VCL_NAL == ps_nal_prms->i4_derived_nal_type) ||
482        (PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type) || (SVCD_TRUE == *pi4_nal_discard_flag))
483     {
484         return (OK);
485     }
486 
487     pu1_input_buf = pu1_buf;
488     pu1_input_buf += ps_nal_prms->i4_nal_header_len;
489     i4_buf_size -= ps_nal_prms->i4_nal_header_len;
490 
491     i4_status =
492         isvcd_parse_part_slice_hdr(pu1_input_buf, i4_buf_size, ps_nal_parse_ctxt->pv_nal_header_buf,
493                                    ps_sps, ps_pps, ps_nal_prms, pu4_err_code, pi4_sps_pps_status);
494 
495     return (i4_status);
496 }
497 
498 /*****************************************************************************/
499 /*                                                                           */
500 /*  Function Name : isvcd_compare_nal_prms                                    */
501 /*                                                                           */
502 /*  Description   : Detects the picture boundary for annex B based input     */
503 /*                  bitstream                                                */
504 /*                                                                           */
505 /*  Inputs        : 1. Pointer to NAL prms                                   */
506 /*                  2. Pass (first pass or second pass (verification)        */
507 /*                  3. Place holder for picture boundary type                */
508 /*                  4. Place holder for picture boundary status              */
509 /*                  4. pointer to bitstream extract context structure        */
510 /*  Globals       :                                                          */
511 /*  Processing    : Detects the picture bounadry as described in G.7.4.1.2.4 */
512 /*                                                                           */
513 /*  Outputs       : Detects the picture boundary                             */
514 /*                  Updates the first NAL in AU field                        */
515 /*                  Updates the picture boundary type if picture boundary is */
516 /*                      detetcetd otherwise it's value shall be ignored      */
517 /*                  Updates the picture boundary status with either          */
518 /*                  PIC_BOUNDARY_TRUE if picture boundary is detetcted or    */
519 /*                  PIC_BOUNDARY_FALSE otherwise                             */
520 /*                  Updates the error code                                   */
521 /*  Returns       : status                                                   */
522 /*                                                                           */
523 /*  Issues        : None                                                     */
524 /*                                                                           */
525 /*  Revision History:                                                        */
526 /*                                                                           */
527 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
528 /*         06 09 2021   Vijay           Draft                                */
529 /*                                                                           */
530 /*****************************************************************************/
isvcd_compare_nal_prms(nal_prms_t * ps_nal_prms,WORD32 i4_pass,WORD32 i4_prev_dqid,WORD32 * pi4_pic_bound_type,WORD32 * pi4_pic_bound_status,nal_parse_ctxt_t * ps_nal_parse_ctxt)531 WORD32 isvcd_compare_nal_prms(nal_prms_t *ps_nal_prms, WORD32 i4_pass, WORD32 i4_prev_dqid,
532                               WORD32 *pi4_pic_bound_type, WORD32 *pi4_pic_bound_status,
533                               nal_parse_ctxt_t *ps_nal_parse_ctxt)
534 {
535     dqid_node_t *ps_dqid_node;
536     vcl_node_t *ps_vcl_node;
537     WORD32 i4_status;
538 
539     /* If DQID is lesser than the DQID of the previous */
540     /* NAL then declare the picture boundary           */
541     *pi4_pic_bound_type = PIC_BOUND_DQID;
542     if(i4_prev_dqid > ps_nal_prms->i4_dqid)
543     {
544         *pi4_pic_bound_status = PIC_BOUNDARY_TRUE;
545         return (OK);
546     }
547 
548     /* Perform the picture boundary detection only for */
549     /* the layers with quality id equal to 0           */
550     if((FIRST_PASS == i4_pass) && (0 != (ps_nal_prms->i4_dqid & 0x0F)))
551     {
552         *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
553         return (OK);
554     }
555 
556     /* Get the DQID node */
557     i4_status =
558         isvcd_get_dqid_node(&ps_nal_parse_ctxt->s_dqid_ctxt, (UWORD8) i4_prev_dqid, &ps_dqid_node);
559     if((OK != i4_status) || (NULL == ps_dqid_node))
560     {
561         return NOT_OK;
562     }
563     /* If the current slice is first slice in the layer */
564     /* then do not compare                              */
565     if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
566     {
567         *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
568         return (OK);
569     }
570 
571     *pi4_pic_bound_type = PIC_BOUND_SLICE_PRMS;
572     *pi4_pic_bound_status = PIC_BOUNDARY_TRUE;
573     ps_vcl_node = ps_dqid_node->ps_vcl_node;
574 
575     /* Compare NAL ref idc */
576     {
577         WORD32 i4_prev_ref_pic_flag;
578         WORD32 i4_cur_ref_pic_flag;
579 
580         i4_prev_ref_pic_flag = (0 != ps_vcl_node->i4_nal_ref_idc);
581         i4_cur_ref_pic_flag = (0 != ps_nal_prms->i4_nal_ref_idc);
582 
583         if(i4_prev_ref_pic_flag != i4_cur_ref_pic_flag)
584         {
585             return (OK);
586         }
587     }
588 
589     /* Compare IDR picture flag */
590     if(ps_vcl_node->i4_idr_pic_flag != ps_nal_prms->i4_idr_pic_flag)
591     {
592         return (OK);
593     }
594 
595     /* Compare PPS id */
596     if(ps_vcl_node->u1_pps_id != ps_nal_prms->u1_pps_id)
597     {
598         return (OK);
599     }
600 
601     /* Compare idr pic num */
602     if((SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag) &&
603        (ps_vcl_node->i4_idr_pic_num != ps_nal_prms->i4_idr_pic_num))
604     {
605         return (OK);
606     }
607 
608     /* Compare frame number */
609     if(ps_vcl_node->u2_frm_num != ps_nal_prms->u2_frm_num)
610     {
611         return (OK);
612     }
613 
614     /* Compare poc lsb */
615     if(ps_dqid_node->i4_poc_lsb != ps_nal_prms->i4_poc_lsb)
616     {
617         return (OK);
618     }
619 
620     /* Compare delta poc bottom */
621     if(ps_dqid_node->i4_delta_poc_bot != ps_nal_prms->i4_delta_poc_bot)
622     {
623         return (OK);
624     }
625 
626     /* Compare delta poc [0] */
627     if(ps_dqid_node->ai4_delta_poc[0] != ps_nal_prms->ai4_delta_poc[0])
628     {
629         return (OK);
630     }
631 
632     /* Compare delta poc [0] */
633     if(ps_dqid_node->ai4_delta_poc[1] != ps_nal_prms->ai4_delta_poc[1])
634     {
635         return (OK);
636     }
637 
638     *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
639     return (OK);
640 }
641 
642 /*****************************************************************************/
643 /*                                                                           */
644 /*  Function Name : isvcd_detetct_pic_boundary_annex_b                        */
645 /*                                                                           */
646 /*  Description   : Detects the picture boundary for annex B based input     */
647 /*                  bitstream                                                */
648 /*                                                                           */
649 /*                                                                           */
650 /*  Inputs        : 1. Pointer to NAL prms                                   */
651 /*                  2. Input bitstream structure                             */
652 /*                  3. Current position of the bitstream pointer             */
653 /*                  4. Place holder for picture boundary status              */
654 /*                  5. pointer to bitstream extract context structure        */
655 /*  Globals       :                                                          */
656 /*  Processing    : It does the following                                    */
657 /*                  1. Look for next NAL.                                    */
658 /*                      If not found then declare picture boundary           */
659 /*                      Otherwsie goto next step                             */
660 /*                  2. Parse the NAL header                                  */
661 /*                      If encountered with error then declare picture       */
662 /*                      boundary                                             */
663 /*                      Otherwise goto next step                             */
664 /*                  3. If picture boundary type is                           */
665 /*                      DQID change and DQID is not equal previous DQID then */
666 /*                      declare picture boundary. Otherwise, the comapre the */
667 /*                      rest of parameters. If during comparison, if there is*/
668 /*                  4. If picture boundary type is                           */
669 /*                      SLICE PRMS CHANGE and Dependency id is not equal then*/
670 /*                      declare picture boundary. Otherwise compre rest of   */
671 /*                      parameters and goto step 5                           */
672 /*                  5. If during comparison, if there is                     */
673 /*                       * an error - then declare picture boundary          */
674 /*                       * Otherwsie if picture  boundary is not detetcted   */
675 /*                         then discard the second slice and proceed.        */
676 /*                                                                           */
677 /*  Outputs       : Detects the picture boundary                             */
678 /*                  Updates the first NAL in AU field                        */
679 /*                  Updates the picture boundary type if picture boundary is */
680 /*                      detetcetd otherwise it's value shall be ignored      */
681 /*                  Updates the error code                                   */
682 /*  Returns       : status                                                   */
683 /*                                                                           */
684 /*  Issues        : None                                                     */
685 /*                                                                           */
686 /*  Revision History:                                                        */
687 /*                                                                           */
688 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
689 /*         06 09 2021   Vijay           Draft                                */
690 /*                                                                           */
691 /*****************************************************************************/
isvcd_detect_pic_boundary_annex_b(nal_prms_t * ps_nal_prms,UWORD8 * pu1_stream_buffer,WORD32 i4_cur_pos,WORD32 * pi4_pic_bound_status,nal_parse_ctxt_t * ps_nal_parse_ctxt,UWORD32 * pu4_num_bytes)692 WORD32 isvcd_detect_pic_boundary_annex_b(nal_prms_t *ps_nal_prms, UWORD8 *pu1_stream_buffer,
693                                          WORD32 i4_cur_pos, WORD32 *pi4_pic_bound_status,
694                                          nal_parse_ctxt_t *ps_nal_parse_ctxt,
695                                          UWORD32 *pu4_num_bytes)
696 {
697     UWORD32 u4_err_code;
698     WORD32 i4_zero_cnt;
699     WORD32 i4_status;
700     nal_prms_t s_nal_prms = {0};
701     nal_prms_t s_prefix_nal_prms = {0};
702     nal_buf_t s_prefix_nal_buf = {0};
703     WORD32 i4_pic_bound_type;
704     WORD32 i4_pic_bound_status;
705     UWORD8 *pu1_buf;
706     WORD32 i4_buf_size;
707     WORD32 i4_more_data_flag;
708     WORD32 i4_new_lyr_flag;
709     WORD32 i4_prev_dqid;
710     WORD32 i4_nal_discard_flag;
711 
712     /* Initializations */
713     i4_zero_cnt = 0;
714     s_prefix_nal_buf.i4_valid_flag = SVCD_FALSE;
715     *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
716     i4_new_lyr_flag = SVCD_TRUE;
717 
718     /* Get the previous layer's DQID                    */
719     if(SVCD_TRUE == ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au)
720     {
721         ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
722         ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au = SVCD_FALSE;
723     }
724     i4_prev_dqid = ps_nal_parse_ctxt->i4_prev_dq_id;
725     ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
726 
727     /* Detect the picture boundary */
728     if(ps_nal_prms->i4_dqid <= i4_prev_dqid)
729     {
730         i4_status =
731             isvcd_compare_nal_prms(ps_nal_prms, FIRST_PASS, i4_prev_dqid, &i4_pic_bound_type,
732                                    &i4_pic_bound_status, ps_nal_parse_ctxt);
733         if(OK != i4_status)
734         {
735             return NOT_OK;
736         }
737         i4_new_lyr_flag = SVCD_FALSE;
738 
739         /* Check whether the picture boundary is detected */
740         /* or not */
741         if(PIC_BOUNDARY_FALSE == i4_pic_bound_status)
742         {
743             return (OK);
744         }
745 
746         /* Otherwise look for next nal and compare again */
747         *pi4_pic_bound_status = PIC_BOUNDARY_TRUE;
748     }
749 
750     do
751     {
752         WORD32 i4_sps_pps_corrupt_status;
753         WORD32 i4_tgt_lyr_bckup;
754         /* If following conditions are true then there */
755         /* is no data left to decode next NAL and hence*/
756         /* no further processing is required           */
757         if((NAL_END != ps_nal_parse_ctxt->i4_find_nal_state) ||
758            ((WORD64) i4_cur_pos >= (WORD64) *pu4_num_bytes))
759         {
760             return (OK);
761         }
762 
763         /* Otherwise fill the parameters */
764         pu1_buf = pu1_stream_buffer;
765         pu1_buf += i4_cur_pos;
766         i4_buf_size = *pu4_num_bytes - i4_cur_pos;
767 
768         /* Get the NAL prms. This involves the following things*/
769         /* 1. Decode the NAL header                            */
770         /* 2. Set the discard flag                             */
771         /* 3. Decode the slice header if needed                */
772         isvcd_set_default_nal_prms(&s_nal_prms);
773 
774         /* take a back up of tgt lyr update flag */
775         i4_tgt_lyr_bckup = ps_nal_parse_ctxt->i4_tgt_lyr_update;
776 
777         /* the tgt attributes should not be  updaetd while pic boundary det*/
778         ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_FALSE;
779 
780         i4_status = isvcd_get_nal_prms(pu1_buf, i4_buf_size, &s_nal_prms, &s_prefix_nal_prms,
781                                        &s_prefix_nal_buf, &u4_err_code, &i4_sps_pps_corrupt_status,
782                                        &i4_nal_discard_flag, ps_nal_parse_ctxt);
783         /* restore back the tgt lyr update flag */
784         ps_nal_parse_ctxt->i4_tgt_lyr_update = i4_tgt_lyr_bckup;
785         /* If the error code by the nal prms decoder then declare*/
786         /* picture boundary                                     */
787         if(0 != u4_err_code)
788         {
789             return (OK);
790         }
791 
792         i4_more_data_flag = SVCD_FALSE;
793 
794         /* If prefix NAL unit comes then save the nal prms*/
795         if(PREFIX_UNIT_NAL == s_nal_prms.i4_nal_unit_type)
796         {
797             UWORD32 u4_bytes_consumed;
798             WORD32 i4_status;
799 
800             /* If prefix NAL is not discarded then set the varaibles */
801             /* appropriatly */
802             if(SVCD_FALSE == i4_nal_discard_flag)
803             {
804                 s_prefix_nal_buf.i4_valid_flag = SVCD_TRUE;
805                 memcpy(&s_prefix_nal_prms, &s_nal_prms, sizeof(nal_prms_t));
806             }
807 
808             /* Go to next start code */
809             i4_zero_cnt = 0;
810             u4_bytes_consumed = 0;
811             i4_status = isvcd_nal_find_start_code(pu1_stream_buffer, i4_cur_pos, *pu4_num_bytes,
812                                                   &i4_zero_cnt, &u4_bytes_consumed);
813             /* If associated NAL unit is  not present then */
814             if(SC_FOUND != i4_status)
815             {
816                 return (OK);
817             }
818             i4_cur_pos += u4_bytes_consumed;
819             i4_more_data_flag = SVCD_TRUE;
820         }
821     } while(SVCD_TRUE == i4_more_data_flag);
822 
823     /* Do further picture boundary detection only for */
824     /* VCL NAL unit (excliding prefix NAL unit)       */
825     if((NON_VCL_NAL == s_nal_prms.i4_derived_nal_type) ||
826        (PREFIX_UNIT_NAL == s_nal_prms.i4_nal_unit_type) || (SVCD_TRUE == i4_nal_discard_flag))
827     {
828         return (OK);
829     }
830 
831     if(SVCD_FALSE == i4_new_lyr_flag)
832     {
833         if(PIC_BOUND_DQID == i4_pic_bound_type)
834         {
835             /* If picture boundary was detetcted based on change*/
836             /* in DQID then declare picture boundary if DQID of the third slice is different */
837             if(i4_prev_dqid != s_nal_prms.i4_dqid)
838             {
839                 return (OK);
840             }
841         }
842         else
843         {
844             /* If picture boundary was detetcted based on change in DQID */
845             /* then declare picture boundary if dependency id of third slice is different */
846             if(PIC_BOUND_SLICE_PRMS != i4_pic_bound_type)
847             {
848                 return NOT_OK;
849             }
850 
851             if((i4_prev_dqid & 0xF) != (s_nal_prms.i4_dqid & 0xF))
852             {
853                 return (OK);
854             }
855         }
856 
857         isvcd_compare_nal_prms(&s_nal_prms, SECOND_PASS, i4_prev_dqid, &i4_pic_bound_type,
858                                &i4_pic_bound_status, ps_nal_parse_ctxt);
859         *pi4_pic_bound_status = i4_pic_bound_status;
860 
861         if(PIC_BOUNDARY_FALSE == i4_pic_bound_status)
862         {
863             ps_nal_parse_ctxt->i4_prev_dq_id = i4_prev_dqid;
864         }
865     }
866     else
867     {
868         if(SVCD_TRUE != i4_new_lyr_flag)
869         {
870             return NOT_OK;
871         }
872         /* The NAL header is not corrupted only if any of the following conditions are true */
873         /* 1. The DQID of the first slice differs with DQID of the third slice */
874         /* 2. Picture boundary is detected between first slice and third slice */
875         if(i4_prev_dqid == s_nal_prms.i4_dqid)
876         {
877             isvcd_compare_nal_prms(&s_nal_prms, SECOND_PASS, i4_prev_dqid, &i4_pic_bound_type,
878                                    &i4_pic_bound_status, ps_nal_parse_ctxt);
879             /* NAL header is corrupted and hence correct it  */
880             if(PIC_BOUNDARY_FALSE == i4_pic_bound_status)
881             {
882                 ps_nal_prms->i4_dqid = s_nal_prms.i4_dqid;
883                 ps_nal_prms->i4_dependency_id = s_nal_prms.i4_dependency_id;
884                 ps_nal_prms->i4_quality_id = s_nal_prms.i4_quality_id;
885                 ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
886             }
887         }
888         *pi4_pic_bound_status = PIC_BOUNDARY_FALSE;
889     }
890     return (OK);
891 }
892 
893 /*****************************************************************************/
894 /*                                                                           */
895 /*  Function Name : isvcd_insert_vcl_node                                    */
896 /*                                                                           */
897 /*  Description   : This routine inserts a DQID layer into DQID list         */
898 /*                  (this will add a VCL NAL node into VCL NAL structure     */
899 /*                                                                           */
900 /*  Inputs        : 1. vcl nal structure                                     */
901 /*                  2. VCL node to be inserted                               */
902 /*  Globals       : None                                                     */
903 /*  Processing    :                                                          */
904 /*                                                                           */
905 /*  Outputs       : Updated vcl nal structure                                */
906 /*  Returns       : status                                                   */
907 /*                                                                           */
908 /*  Issues        : None                                                     */
909 /*                                                                           */
910 /*  Revision History:                                                        */
911 /*                                                                           */
912 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
913 /*         06 09 2021   Vijay      Draft                                     */
914 /*                                                                           */
915 /*****************************************************************************/
isvcd_insert_vcl_node(vcl_nal_t * ps_vcl_nal,vcl_node_t * ps_vcl_node)916 WORD32 isvcd_insert_vcl_node(vcl_nal_t *ps_vcl_nal, vcl_node_t *ps_vcl_node)
917 {
918     vcl_node_t *ps_bot_node;
919     vcl_node_t *ps_top_node;
920     vcl_node_t *ps_node;
921     WORD32 i4_rqrd_dqid;
922 
923     /* sanity checks */
924     if((NULL == ps_vcl_nal) || (NULL == ps_vcl_node))
925     {
926         return NOT_OK;
927     }
928 
929     i4_rqrd_dqid = (ps_vcl_node->i4_dependency_id << 4);
930     i4_rqrd_dqid += ps_vcl_node->i4_quality_id;
931     ps_node = ps_vcl_nal->ps_bot_node;
932 
933     /* Search for node which has a DQID which is */
934     /* lesser than taht of the node to inserted  */
935     while(NULL != ps_node)
936     {
937         WORD32 i4_dqid;
938 
939         i4_dqid = (ps_node->i4_dependency_id << 4);
940         i4_dqid += ps_node->i4_quality_id;
941 
942         /* If we get a DQID which is greater than*/
943         /* the DQID of the  node to be inserted  */
944         /* then break out of the loop and update */
945         if(i4_dqid > i4_rqrd_dqid)
946         {
947             ps_bot_node = ps_node->ps_bot_node;
948             break;
949         }
950 
951         ps_node = ps_node->ps_top_node;
952     }
953 
954     /* If none of the nodes in the list have DQId */
955     /* greater than the node to be inserted then  */
956     /* bottom node will be top most node          */
957     if(NULL == ps_node)
958     {
959         ps_bot_node = ps_vcl_nal->ps_top_node;
960     }
961 
962     /* Insert the node into DQID list */
963     if(NULL != ps_bot_node)
964     {
965         ps_top_node = ps_bot_node->ps_top_node;
966     }
967     else
968     {
969         ps_top_node = ps_vcl_nal->ps_bot_node;
970     }
971 
972     /* Join previous node and specified node */
973     if(NULL != ps_bot_node)
974     {
975         ps_bot_node->ps_top_node = ps_vcl_node;
976     }
977     else
978     {
979         ps_vcl_nal->ps_bot_node = ps_vcl_node;
980     }
981     ps_vcl_node->ps_bot_node = ps_bot_node;
982 
983     /* Join next node and specified node */
984     if(NULL != ps_top_node)
985     {
986         ps_top_node->ps_bot_node = ps_vcl_node;
987     }
988     else
989     {
990         ps_vcl_nal->ps_top_node = ps_vcl_node;
991     }
992     ps_vcl_node->ps_top_node = ps_top_node;
993 
994     return (OK);
995 }
996 /*****************************************************************************/
997 /*                                                                           */
998 /*  Function Name : isvcd_update_nal_ctxt                                     */
999 /*                                                                           */
1000 /*  Description   : Updates the vcl nal or non vcl structures.               */
1001 /*                                                                           */
1002 /*  Inputs        : ps_nal_parse_ctxt - Bitstream extract context structure  */
1003 /*                  vcl nal structure pointer                                */
1004 /*                  NON vcl nal structure                                    */
1005 /*                                                                           */
1006 /*  Globals       : None                                                     */
1007 /*                                                                           */
1008 /*  Processing    : If VCL NAL then adds a node to DQID list                 */
1009 /*                  otherwise adds information to non vcl structure          */
1010 /*                                                                           */
1011 /*  Outputs       : None                                                     */
1012 /*                                                                           */
1013 /*  Returns       : None                                                     */
1014 /*                                                                           */
1015 /*  Issues        : None                                                     */
1016 /*                                                                           */
1017 /*  Revision History:                                                        */
1018 /*          DD MM YYYY   Author(s)       Changes                             */
1019 /*          06 09 2021   Vijay           Draft                               */
1020 /*                                                                           */
1021 /*****************************************************************************/
isvcd_update_nal_ctxt(nal_parse_ctxt_t * ps_nal_parse_ctxt,vcl_nal_t * ps_vcl_nal,non_vcl_nal_t * ps_non_vcl_nal)1022 void isvcd_update_nal_ctxt(nal_parse_ctxt_t *ps_nal_parse_ctxt, vcl_nal_t *ps_vcl_nal,
1023                            non_vcl_nal_t *ps_non_vcl_nal)
1024 {
1025     /*! If current NAL is VCL NAL then
1026           - Insert a VCL node into DQID list if neccessery
1027           - update the information part of NAL unit */
1028     /*! Otherwise, populate the buffer parameters into non vcl output
1029     structure */
1030     nal_prms_t *ps_nal_prms;
1031     nal_buf_t *ps_nal_buf, *ps_prefix_nal_buf;
1032 
1033     ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
1034     ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
1035     ps_nal_buf = &ps_nal_parse_ctxt->s_nal_buf;
1036     ps_prefix_nal_buf = &ps_nal_parse_ctxt->s_prefix_nal_buf;
1037 
1038     /* If prefix NAL unit then          */
1039     /* - calculate the SODB length      */
1040     if(PREFIX_UNIT_NAL == ps_nal_prms->i4_nal_unit_type)
1041     {
1042         /* Since we consume the zeroes in start code also */
1043         /* size has to reduced                            */
1044         if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
1045         {
1046             ps_prefix_nal_buf->i4_buf_size -= 2;
1047         }
1048 
1049         ps_prefix_nal_buf->u4_max_bits =
1050             isvcd_nal_rbsp_to_sodb(ps_prefix_nal_buf->pu1_buf, ps_prefix_nal_buf->i4_buf_size, 0);
1051         memcpy(&ps_nal_parse_ctxt->s_prefix_nal_prms, &ps_nal_parse_ctxt->s_nal_prms,
1052                sizeof(nal_prms_t));
1053         return;
1054     }
1055 
1056     if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
1057     {
1058         /* Since we consume the zeroes in start code also */
1059         /* size has to reduced                            */
1060         if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
1061         {
1062             ps_nal_buf->i4_buf_size -= 2;
1063         }
1064     }
1065 
1066     if(VCL_NAL == ps_nal_prms->i4_derived_nal_type)
1067     {
1068         dqid_node_t *ps_dqid_node;
1069         vcl_node_t *ps_node;
1070         WORD32 i4_status;
1071         dec_pic_params_t *ps_pps;
1072         dec_seq_params_t *ps_sps;
1073         vcl_buf_hdr_t *ps_vcl_hdr;
1074         vcl_buf_hdr_t *ps_prev_vcl_hdr;
1075         WORD32 i4_slice_offset;
1076 
1077         ps_sps = ps_nal_parse_ctxt->pv_seq_prms;
1078         ps_sps += ps_nal_prms->u1_sps_id;
1079         ps_pps = ps_nal_parse_ctxt->pv_pic_prms;
1080         ps_pps += ps_nal_prms->u1_pps_id;
1081 
1082         /* Get the VCL NAL node */
1083         i4_status = isvcd_get_dqid_node(&ps_nal_parse_ctxt->s_dqid_ctxt,
1084                                         (UWORD8) ps_nal_parse_ctxt->i4_prev_dq_id, &ps_dqid_node);
1085 
1086         ps_node = ps_dqid_node->ps_vcl_node;
1087 
1088         if(NULL == ps_node)
1089         {
1090             /* no active node has been acquired */
1091             return;
1092         }
1093 
1094         /*-------------------------------------------------------------------*/
1095         /* The DQID list updation should happen only once in a               */
1096         /* layer. Hence a flag used to determine whether the                 */
1097         /* layer is already initialized or not.                              */
1098         /*-------------------------------------------------------------------*/
1099         if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
1100         {
1101             /* Update the DQID node */
1102             ps_dqid_node->u1_valid_flag = SVCD_TRUE;
1103             ps_dqid_node->u1_dqid = (ps_nal_prms->i4_dependency_id << 4);
1104             ps_dqid_node->u1_dqid += ps_nal_prms->i4_quality_id;
1105             ps_dqid_node->i4_poc_lsb = ps_nal_prms->i4_poc_lsb;
1106             ps_dqid_node->i4_delta_poc_bot = ps_nal_prms->i4_delta_poc_bot;
1107             ps_dqid_node->ai4_delta_poc[0] = ps_nal_prms->ai4_delta_poc[0];
1108             ps_dqid_node->ai4_delta_poc[1] = ps_nal_prms->ai4_delta_poc[1];
1109 
1110             /* Update the VCL node */
1111             ps_node->i4_quality_id = ps_nal_prms->i4_quality_id;
1112             ps_node->i4_dependency_id = ps_nal_prms->i4_dependency_id;
1113             ps_node->i4_temporal_id = ps_nal_prms->i4_temporal_id;
1114             ps_node->i4_priority_id = ps_nal_prms->i4_priority_id;
1115             ps_node->i4_idr_pic_flag = ps_nal_prms->i4_idr_pic_flag;
1116             ps_node->i4_nal_ref_idc = ps_nal_prms->i4_nal_ref_idc;
1117             ps_node->i4_nal_unit_type = ps_nal_prms->i4_nal_unit_type;
1118             ps_node->i4_use_ref_base = ps_nal_prms->i4_use_ref_base_pic_flag;
1119             ps_node->i4_nal_ref_idc = ps_nal_prms->i4_nal_ref_idc;
1120             ps_node->u1_sps_id = ps_nal_prms->u1_sps_id;
1121             ps_node->u1_pps_id = ps_nal_prms->u1_pps_id;
1122             ps_node->u2_frm_num = ps_nal_prms->u2_frm_num;
1123             ps_node->i4_idr_pic_num = ps_nal_prms->i4_idr_pic_num;
1124             ps_node->i4_num_slices = 0;
1125             ps_node->u1_acc_no_int_pred = 1;
1126             if(0 == ps_sps->u1_pic_order_cnt_type)
1127             {
1128                 ps_node->i4_poc_syntax = ps_nal_prms->i4_poc_lsb;
1129             }
1130             else
1131             {
1132                 ps_node->i4_poc_syntax = ps_nal_prms->ai4_delta_poc[0];
1133             }
1134 
1135             /* Insert the node into DQID list */
1136             i4_status = isvcd_insert_vcl_node(ps_vcl_nal, ps_node);
1137             if(OK != i4_status)
1138             {
1139                 return;
1140             }
1141 
1142             /* Reset the previous field */
1143             ps_nal_parse_ctxt->ps_prev_vcl_buf = NULL;
1144             ps_node->ps_first_vcl_nal = NULL;
1145         }
1146 
1147         /* Update accumulated no inter layer prediction */
1148         ps_node->u1_acc_no_int_pred &= (UWORD8) ps_nal_prms->i4_no_int_lyr_pred;
1149 
1150         /****************** Fill VCL BUF header ************/
1151 
1152         /* If prefix NAL unit is present then update  */
1153         /* the following                              */
1154         /* - Start of buffer header will be present in*/
1155         /*   before the start of prefix NAL unit's SODB*/
1156         /*   data.                                    */
1157         /*   Note: If memeory left for buffer header  */
1158         /*   of the prefix NAL unit will have junk    */
1159         /*   values                                   */
1160 
1161         if(NULL == ps_nal_buf->pu1_buf)
1162         {
1163             /* no nal needs to be added into the list hence return */
1164             return;
1165         }
1166         else
1167         {
1168             ps_vcl_hdr = (vcl_buf_hdr_t *) (ps_nal_buf->pu1_buf - GET_NAL_BUF_INC(VCL_NAL));
1169         }
1170 
1171         i4_slice_offset = 0;
1172         if(SVCD_TRUE == ps_prefix_nal_buf->i4_valid_flag)
1173         {
1174             ps_vcl_hdr = (vcl_buf_hdr_t *) (ps_prefix_nal_buf->pu1_buf - GET_NAL_BUF_INC(VCL_NAL));
1175             i4_slice_offset = ps_nal_buf->pu1_buf - ps_prefix_nal_buf->pu1_buf;
1176         }
1177 
1178         /* Update the next field of the previous nal  */
1179         /* unit or if it is the first NAL then update */
1180         /* VCL node information                       */
1181         ps_prev_vcl_hdr = ps_nal_parse_ctxt->ps_prev_vcl_buf;
1182         if(NULL != ps_prev_vcl_hdr)
1183         {
1184             ps_prev_vcl_hdr->ps_next = ps_vcl_hdr;
1185         }
1186         else
1187         {
1188             ps_node->ps_first_vcl_nal = ps_vcl_hdr;
1189         }
1190 
1191         /* Fill the VCL buffer header */
1192         ps_vcl_hdr->ps_next = NULL;
1193         ps_vcl_hdr->i4_no_int_lyr_pred = ps_nal_prms->i4_no_int_lyr_pred;
1194         ps_vcl_hdr->i4_first_mb_addr = ps_nal_prms->u4_first_mb_addr;
1195         ps_vcl_hdr->u4_prefix_nal_bits = ps_prefix_nal_buf->u4_max_bits;
1196         ps_vcl_hdr->i4_slice_offset = 0;
1197         ps_vcl_hdr->i4_buf_offset = GET_NAL_BUF_INC(VCL_NAL);
1198         ps_vcl_hdr->i4_slice_offset = i4_slice_offset;
1199 
1200         /* Determine max num bits */
1201         ps_nal_buf->u4_max_bits = isvcd_nal_rbsp_to_sodb(
1202             ps_nal_buf->pu1_buf, ps_nal_buf->i4_buf_size, ps_pps->u1_entropy_coding_mode);
1203         ps_vcl_hdr->u4_max_bits = ps_nal_buf->u4_max_bits;
1204 
1205         /* Updates */
1206         ps_nal_parse_ctxt->ps_prev_vcl_buf = ps_vcl_hdr;
1207         ps_node->i4_num_slices += 1;
1208     }
1209     /*-----------------------------------------------------------------------*/
1210     /* If start of NAL and if its a NON VCL NAL then update the              */
1211     /* start address of the NON VCL NAL                                      */
1212     /*-----------------------------------------------------------------------*/
1213     else
1214     {
1215         non_vcl_buf_hdr_t *ps_non_vcl_buf_hdr;
1216         non_vcl_buf_hdr_t *ps_prev_non_vcl_buf_hdr;
1217 
1218         ps_non_vcl_buf_hdr =
1219             (non_vcl_buf_hdr_t *) (ps_nal_buf->pu1_buf - GET_NAL_BUF_INC(NON_VCL_NAL));
1220 
1221         /* Update NON VCL structure */
1222         ps_non_vcl_buf_hdr->i4_nal_unit_type = ps_nal_prms->i4_nal_unit_type;
1223         ps_non_vcl_buf_hdr->ps_next = NULL;
1224         ps_non_vcl_buf_hdr->i4_buf_offset = GET_NAL_BUF_INC(NON_VCL_NAL);
1225         ps_non_vcl_buf_hdr->i4_buf_size = ps_nal_buf->i4_buf_size;
1226 
1227         /* Update the next field and first non vcl fields of */
1228         /* non vcl buffer header structure and non vcl       */
1229         /* structure respectively                            */
1230         ps_prev_non_vcl_buf_hdr = ps_nal_parse_ctxt->ps_prev_non_vcl_buf;
1231         if(NULL != ps_prev_non_vcl_buf_hdr)
1232         {
1233             ps_prev_non_vcl_buf_hdr->ps_next = ps_non_vcl_buf_hdr;
1234         }
1235         else
1236         {
1237             ps_non_vcl_nal->ps_first_non_vcl_nal = ps_non_vcl_buf_hdr;
1238         }
1239 
1240         /* Updates */
1241         ps_nal_parse_ctxt->i4_num_non_vcl_nals += 1;
1242         ps_non_vcl_nal->i4_num_non_vcl_nals = ps_nal_parse_ctxt->i4_num_non_vcl_nals;
1243         ps_nal_parse_ctxt->ps_prev_non_vcl_buf = ps_non_vcl_buf_hdr;
1244     }
1245 }
1246 
1247 /*****************************************************************************/
1248 /*                                                                           */
1249 /*  Function Name : isvcd_idr_err_hdlr                                        */
1250 /*                                                                           */
1251 /*  Description   : This routine shall be invoked to handle a case when a    */
1252 /*                  slice is an IDR picture and it is referring to corrupted */
1253 /*                  SPS or PPS                                               */
1254 /*                                                                           */
1255 /*  Inputs        : 1. VCL NAL structure                                     */
1256 /*                  2. NAL paramters                                         */
1257 /*                  3. NAL parse context structure                           */
1258 /*  Globals       : None                                                     */
1259 /*  Processing    : It will set the highest available dependency id below the*/
1260 /*                  current dependency id as the target layer. Also sets the */
1261 /*                  update target layer flag to FALSE as target layer need not*/
1262 /*                  adopt to the application's target layer in the current   */
1263 /*                  picture                                                  */
1264 /*                                                                           */
1265 /*  Outputs       : Updated vcl nal structure                                */
1266 /*                  Updated internal target layer attributes                 */
1267 /*                  Updated target layer update flag                         */
1268 /*  Returns       : status                                                   */
1269 /*                                                                           */
1270 /*  Issues        : None                                                     */
1271 /*                                                                           */
1272 /*  Revision History:                                                        */
1273 /*                                                                           */
1274 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1275 /*         06 09 2021   Vijay           Draft                                */
1276 /*                                                                           */
1277 /*****************************************************************************/
isvcd_idr_err_hdlr(vcl_nal_t * ps_vcl_nal,nal_prms_t * ps_nal_prms,nal_parse_ctxt_t * ps_nal_parse_ctxt)1278 WORD32 isvcd_idr_err_hdlr(vcl_nal_t *ps_vcl_nal, nal_prms_t *ps_nal_prms,
1279                           nal_parse_ctxt_t *ps_nal_parse_ctxt)
1280 {
1281     vcl_node_t *ps_vcl_node;
1282     target_lyr_attr_t *ps_int_attr;
1283 
1284     /* sanity checks */
1285     if((NULL == ps_vcl_nal) || (NULL == ps_nal_prms) || (NULL == ps_nal_parse_ctxt))
1286     {
1287         return NOT_OK;
1288     }
1289     UNUSED(ps_nal_prms);
1290 
1291     /* Initializations */
1292     ps_vcl_node = ps_vcl_nal->ps_top_node;
1293     ps_int_attr = &ps_nal_parse_ctxt->s_int_attr;
1294 
1295     /* the highest node present in the depedency list will be         */
1296     /* considered as targte layer and appropriate params will be used */
1297 
1298     /* If not found then delete all the layers in the AU */
1299     if(NULL == ps_vcl_node)
1300     {
1301         ps_int_attr->i4_dependency_id = -1;
1302         ps_int_attr->i4_quality_id = MAX_QUALITY_ID;
1303     }
1304     else
1305     {
1306         /* Set the target layer */
1307         ps_int_attr->i4_dependency_id = ps_vcl_node->i4_dependency_id;
1308         ps_int_attr->i4_quality_id = ps_vcl_node->i4_quality_id;
1309     }
1310 
1311     return (OK);
1312 }
1313 /*****************************************************************************/
1314 /*                                                                           */
1315 /*  Function Name :svcd_refine_dqid_list                                     */
1316 /*                                                                           */
1317 /*  Description   : Inserts the dummy nodes for each dependency id which     */
1318 /*                  have not come in the bitstream                           */
1319 /*                                                                           */
1320 /*  Inputs        :VCL NAL structure                                         */
1321 /*                  NAL parse context structure                              */
1322 /*  Globals       : None                                                     */
1323 /*  Processing    : For each dependency id till the target dependency id     */
1324 /*                  - If layer already exists (came in the bitstream) then   */
1325 /*                    do nothing                                             */
1326 /*                  - Otherwsie insert a dummy node                          */
1327 /*                                                                           */
1328 /*  Outputs       : Updated VCL NAL structure                                */
1329 /*  Returns       : None                                                     */
1330 /*                                                                           */
1331 /*  Issues        : None                                                     */
1332 /*                                                                           */
1333 /*  Revision History:                                                        */
1334 /*                                                                           */
1335 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1336 /*         06 09 2021   Vijay           Draft                                */
1337 /*                                                                           */
1338 /*****************************************************************************/
isvcd_refine_dqid_list(vcl_nal_t * ps_vcl_nal,nal_parse_ctxt_t * ps_nal_parse_ctxt)1339 WORD32 isvcd_refine_dqid_list(vcl_nal_t *ps_vcl_nal, nal_parse_ctxt_t *ps_nal_parse_ctxt)
1340 {
1341     vcl_node_t *ps_node;
1342     target_lyr_attr_t *ps_int_attr;
1343     dqid_ctxt_t *ps_dqid_ctxt;
1344     UWORD8 u1_dep_id;
1345     WORD32 i4_status;
1346     WORD32 i4_dep_id;
1347 
1348     ps_int_attr = &ps_nal_parse_ctxt->s_int_attr;
1349     ps_dqid_ctxt = &ps_nal_parse_ctxt->s_dqid_ctxt;
1350     i4_dep_id = -1;
1351 
1352     for(u1_dep_id = 0; u1_dep_id <= ps_int_attr->i4_dependency_id; u1_dep_id++)
1353     {
1354         dqid_node_t *ps_dqid_node;
1355 
1356         /* Get a DQID node */
1357         i4_status = isvcd_get_dqid_node(ps_dqid_ctxt, (UWORD8) (u1_dep_id << 4), &ps_dqid_node);
1358         if(OK != i4_status)
1359         {
1360             return NOT_OK;
1361         }
1362 
1363         /* If node does not exist already then insert a dummy node */
1364         if(SVCD_FALSE == ps_dqid_node->u1_valid_flag)
1365         {
1366             if(1 == ps_nal_parse_ctxt->i4_idr_pic_err_flag)
1367             {
1368                 ps_int_attr->i4_dependency_id = i4_dep_id;
1369                 ps_int_attr->i4_quality_id = MAX_QUALITY_ID;
1370 
1371                 /* remove all the nodes from dependency list */
1372                 /* which are at higher dependency than the   */
1373                 /* value set in init attributes              */
1374                 while(NULL != ps_vcl_nal->ps_top_node)
1375                 {
1376                     /* if higher dependency */
1377                     if(ps_vcl_nal->ps_top_node->i4_dependency_id > i4_dep_id)
1378                     {
1379                         ps_vcl_nal->ps_top_node = ps_vcl_nal->ps_top_node->ps_bot_node;
1380                     }
1381                     else
1382                     {
1383                         break;
1384                     }
1385                 }
1386 
1387                 /* if no node exists in the dependency list */
1388                 if(NULL == ps_vcl_nal->ps_top_node)
1389                 {
1390                     ps_vcl_nal->ps_bot_node = NULL;
1391                 }
1392                 else if(ps_vcl_nal->ps_top_node == ps_vcl_nal->ps_bot_node)
1393                 {
1394                     /* if a single node exists */
1395                     ps_vcl_nal->ps_top_node->ps_bot_node = NULL;
1396                     ps_vcl_nal->ps_bot_node->ps_top_node = NULL;
1397                 }
1398 
1399                 return (NOT_OK);
1400             }
1401             else
1402             {
1403                 ps_dqid_node->u1_valid_flag = SVCD_TRUE;
1404                 ps_dqid_node->u1_dqid = (u1_dep_id << 4);
1405 
1406                 /* Fill VCL node information */
1407                 ps_node = ps_dqid_node->ps_vcl_node;
1408                 ps_node->i4_dependency_id = u1_dep_id;
1409                 ps_node->i4_quality_id = 0;
1410                 ps_node->ps_first_vcl_nal = NULL;
1411             }
1412 
1413             /* Insert node into DQID list */
1414             i4_status = isvcd_insert_vcl_node(ps_vcl_nal, ps_node);
1415             if(OK != i4_status)
1416             {
1417                 return (NOT_OK);
1418             }
1419         }
1420 
1421         i4_dep_id++;
1422     } /* End of loop over all the dependency id */
1423     return (OK);
1424 }
1425 
1426 /*****************************************************************************/
1427 /*                                                                           */
1428 /*  Function Name : isvcd_nal_parse_set_target_attr                          */
1429 /*                                                                           */
1430 /*  Description   : Sets the target layer attributes                         */
1431 /*                                                                           */
1432 /*  Inputs        : i4_target_quality_id - Target layer quality id           */
1433 /*                  i4_target_dependency_id - Target layer dependency id     */
1434 /*                  i4_target_temporal_id - Target layer temporal id         */
1435 /*                  i4_target_priority_id - Target layer priority id         */
1436 /*                  pv_nal_parse_ctxt - Pointer module handle                */
1437 /*                                                                           */
1438 /*  Globals       : None                                                     */
1439 /*                                                                           */
1440 /*  Processing    : None                                                     */
1441 /*                                                                           */
1442 /*  Outputs       : None                                                     */
1443 /*                                                                           */
1444 /*  Returns       : None                                                     */
1445 /*                                                                           */
1446 /*  Issues        : None                                                     */
1447 /*                                                                           */
1448 /*  Revision History:                                                        */
1449 /*          DD MM YYYY   Author(s)       Changes                             */
1450 /*          06 09 2021   Vijay           Draft                               */
1451 /*                                                                           */
1452 /*****************************************************************************/
1453 
isvcd_nal_parse_set_target_attr(WORD32 i4_target_quality_id,WORD32 i4_target_dependency_id,WORD32 i4_target_temporal_id,WORD32 i4_target_priority_id,void * pv_nal_parse_ctxt)1454 WORD32 isvcd_nal_parse_set_target_attr(WORD32 i4_target_quality_id, WORD32 i4_target_dependency_id,
1455                                        WORD32 i4_target_temporal_id, WORD32 i4_target_priority_id,
1456                                        void *pv_nal_parse_ctxt)
1457 {
1458     nal_parse_ctxt_t *ps_nal_parse_ctxt;
1459     target_lyr_attr_t *ps_app_attr;
1460 
1461     if((i4_target_quality_id > MAX_QUALITY_ID) || (i4_target_dependency_id > MAX_DEPENDENCY_ID))
1462     {
1463         return IV_FAIL;
1464     }
1465 
1466     ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
1467     ps_app_attr = &ps_nal_parse_ctxt->s_app_attr;
1468 
1469     /*-----------------------------------------------------------------------*/
1470     /*! Register the target information into context structure               */
1471     /*-----------------------------------------------------------------------*/
1472     ps_app_attr->i4_quality_id = i4_target_quality_id;
1473     ps_app_attr->i4_dependency_id = i4_target_dependency_id;
1474     ps_app_attr->i4_temporal_id = i4_target_temporal_id;
1475     ps_app_attr->i4_priority_id = i4_target_priority_id;
1476     return IV_SUCCESS;
1477 }
1478 
1479 /*****************************************************************************/
1480 /*                                                                           */
1481 /*  Function Name : isvcd_nal_parse_reset_ctxt                               */
1482 /*                                                                           */
1483 /*  Description   : Initializes the bitstream extraction module. Should be   */
1484 /*                  called once in a sequence                                */
1485 /*                                                                           */
1486 /*  Inputs        : i4_input_bitstream_mode - Input bitstream mode RFC or    */
1487 /*                      Annex B                                              */
1488 /*                  i4_input_mode - Input mode - Full input mode or partial  */
1489 /*                      input mode                                           */
1490 /*                  pv_nal_parse_ctxt - Module handle                        */
1491 /*                                                                           */
1492 /*  Globals       : None                                                     */
1493 /*                                                                           */
1494 /*  Processing    : None                                                     */
1495 /*                                                                           */
1496 /*  Outputs       : None                                                     */
1497 /*                                                                           */
1498 /*  Returns       : None                                                     */
1499 /*                                                                           */
1500 /*  Issues        : None                                                     */
1501 /*                                                                           */
1502 /*  Revision History:                                                        */
1503 /*          DD MM YYYY   Author(s)       Changes                             */
1504 /*          06 09 2021   Vijay           Draft                               */
1505 /*                                                                           */
1506 /*****************************************************************************/
1507 
isvcd_nal_parse_reset_ctxt(WORD32 i4_input_bitstream_mode,WORD32 i4_input_mode,void * pv_nal_parse_ctxt)1508 void isvcd_nal_parse_reset_ctxt(WORD32 i4_input_bitstream_mode, WORD32 i4_input_mode,
1509                                 void *pv_nal_parse_ctxt)
1510 {
1511     nal_parse_ctxt_t *ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
1512     UNUSED(i4_input_mode);
1513 
1514     /*-----------------------------------------------------------------------*/
1515     /*! Set the input bitstream mode of context structure                    */
1516     /*-----------------------------------------------------------------------*/
1517     switch(i4_input_bitstream_mode)
1518     {
1519         case ANNEX_B:
1520         case NON_ANNEX_B:
1521             break;
1522         default:
1523             break;
1524     }
1525 
1526     ps_nal_parse_ctxt->i4_input_bitstream_mode = i4_input_bitstream_mode;
1527 
1528     /*-----------------------------------------------------------------------*/
1529     /*! Perform the picture level initialization                             */
1530     /*-----------------------------------------------------------------------*/
1531     isvcd_pic_reset_ctxt(pv_nal_parse_ctxt);
1532 
1533     /* Reset the prefix nal unit buffer structure */
1534     isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_prefix_nal_buf);
1535 
1536     /*-----------------------------------------------------------------------*/
1537     /*! Reset other varaibles                                                */
1538     /*-----------------------------------------------------------------------*/
1539     ps_nal_parse_ctxt->i4_dec_frst_sc_flag = SVCD_TRUE;
1540     ps_nal_parse_ctxt->i4_eos_flag = SVCD_FALSE;
1541     ps_nal_parse_ctxt->u1_pic_boundary_aud_flag = 0;
1542     ps_nal_parse_ctxt->u4_bytes_left = 0;
1543 
1544     /* Reset target layer attributes */
1545     {
1546         target_lyr_attr_t *ps_app_attr;
1547         target_lyr_attr_t *ps_int_attr;
1548 
1549         ps_app_attr = &ps_nal_parse_ctxt->s_app_attr;
1550         ps_int_attr = &ps_nal_parse_ctxt->s_int_attr;
1551 
1552         ps_app_attr->i4_dependency_id = MAX_DEPENDENCY_ID;
1553         ps_app_attr->i4_quality_id = MAX_QUALITY_ID;
1554         ps_app_attr->i4_temporal_id = MAX_TEMPORAL_ID;
1555         ps_app_attr->i4_priority_id = MAX_PRIORITY_ID;
1556 
1557         ps_int_attr->i4_dependency_id = -1;
1558         ps_int_attr->i4_quality_id = MAX_QUALITY_ID;
1559         ps_int_attr->i4_temporal_id = 0;
1560         ps_int_attr->i4_priority_id = MAX_PRIORITY_ID;
1561     }
1562 }
1563 
1564 /*****************************************************************************/
1565 /*                                                                           */
1566 /*  Function Name : isvcd_nal_parse_partial_signal_eos                       */
1567 /*                                                                           */
1568 /*  Description   : Does processing when end of stream occurs for partial    */
1569 /*                  input mode of operation.                                 */
1570 /*                                                                           */
1571 /*  Inputs        : pv_nal_parse_ctxt - bitstream extract context structure  */
1572 /*                  pv_out_vcl_nal - vcl nal structure                       */
1573 /*                  pv_out_non_vcl_nal - non vcl nal structure               */
1574 /*                                                                           */
1575 /*  Globals       : None                                                     */
1576 /*                                                                           */
1577 /*  Processing    : None                                                     */
1578 /*                                                                           */
1579 /*  Outputs       : None                                                     */
1580 /*                                                                           */
1581 /*  Returns       : Picture boundary detetcted or not                        */
1582 /*                                                                           */
1583 /*  Issues        : None                                                     */
1584 /*                                                                           */
1585 /*  Revision History:                                                        */
1586 /*          DD MM YYYY   Author(s)       Changes                             */
1587 /*          06 09 2021   Vijay           Draft                               */
1588 /*                                                                           */
1589 /*****************************************************************************/
1590 
isvcd_nal_parse_partial_signal_eos(void * pv_nal_parse_ctxt,void * pv_out_vcl_nal,void * pv_out_non_vcl_nal)1591 WORD32 isvcd_nal_parse_partial_signal_eos(void *pv_nal_parse_ctxt, void *pv_out_vcl_nal,
1592                                           void *pv_out_non_vcl_nal)
1593 {
1594     nal_parse_ctxt_t *ps_nal_parse_ctxt;
1595     vcl_nal_t *ps_vcl_nal;
1596 
1597     ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
1598     ps_vcl_nal = (vcl_nal_t *) pv_out_vcl_nal;
1599 
1600     /* for RFC mode */
1601     if(NON_ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
1602     {
1603         /* Reset the end of stream flag so that in    */
1604         ps_nal_parse_ctxt->i4_eos_flag = SVCD_TRUE;
1605     }
1606 
1607     if(1 == ps_nal_parse_ctxt->u1_pic_boundary_aud_flag)
1608     {
1609         ps_nal_parse_ctxt->i4_eos_flag = SVCD_TRUE;
1610     }
1611     /* Update VCL node if it is first call in the */
1612     /* flush mode                                 */
1613     if(SVCD_FALSE == ps_nal_parse_ctxt->i4_eos_flag)
1614     {
1615         WORD32 i4_status;
1616 
1617         /* Update the unfinished NAL into VCL node if */
1618         /* all the following conditions are true      */
1619         /* 1. We have not found the start code and    */
1620         /*    NAL boundary is not detected yet        */
1621         /* 2. NAL is not discarded                    */
1622         if((FIND_NAL_END == ps_nal_parse_ctxt->i4_find_nal_state) &&
1623            (SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag))
1624         {
1625             isvcd_update_nal_ctxt(ps_nal_parse_ctxt, pv_out_vcl_nal, pv_out_non_vcl_nal);
1626         }
1627 
1628         ps_nal_parse_ctxt->i4_idr_pic_err_flag = 0;
1629         /* Refine based on the no inter layer pred flag*/
1630         i4_status = isvcd_refine_dqid_list(ps_vcl_nal, ps_nal_parse_ctxt);
1631 
1632         if(!(OK == i4_status))
1633         {
1634             return i4_status;
1635         }
1636         UNUSED(i4_status);
1637 
1638         /* Reset the context structure variables */
1639         isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
1640 
1641         /* Reset the end of stream flag so that in    */
1642         /* the next flush call the above steps need   */
1643         /* not be performed                           */
1644         ps_nal_parse_ctxt->i4_eos_flag = SVCD_TRUE;
1645 
1646         return (PIC_BOUNDARY_TRUE);
1647     }
1648     else
1649     {
1650         return (FLUSH_DECODED_PICTURE);
1651     }
1652 }
1653 /*****************************************************************************/
1654 /*                                                                           */
1655 /*  Function Name : isvcd_nal_parse_pic_bound_proc                           */
1656 /*                                                                           */
1657 /*  Description   : Function does the picture end processign and resets      */
1658 /*                                                                           */
1659 /*                                                                           */
1660 /*  Inputs        : ps_nal_parse_ctxt, ps_vcl_nal                            */
1661 /*  Globals       : none                                                     */
1662 /*  Processing    : DQid list refiniment and resets                          */
1663 /*                                                                           */
1664 /*  Outputs       : none                                                     */
1665 /*  Returns       : none                                                     */
1666 /*                                                                           */
1667 /*  Issues        : none                                                     */
1668 /*                                                                           */
1669 /*  Revision History:                                                        */
1670 /*                                                                           */
1671 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
1672 /*         06 09 2021   vijayakumar          creation                        */
1673 /*                                                                           */
1674 /*****************************************************************************/
isvcd_nal_parse_pic_bound_proc(nal_parse_ctxt_t * ps_nal_parse_ctxt,vcl_nal_t * ps_vcl_nal,nal_prms_t * ps_nal_prms)1675 void isvcd_nal_parse_pic_bound_proc(nal_parse_ctxt_t *ps_nal_parse_ctxt, vcl_nal_t *ps_vcl_nal,
1676                                     nal_prms_t *ps_nal_prms)
1677 {
1678     WORD32 i4_status;
1679 
1680     i4_status = isvcd_refine_dqid_list(ps_vcl_nal, ps_nal_parse_ctxt);
1681 
1682     /* in case of IDR pictures if the node     */
1683     /* which has to be added into dependency   */
1684     /* list is not valied then the layer below */
1685     /* that node is set as target layer        */
1686 
1687     if(NOT_OK == i4_status)
1688     {
1689         ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
1690         ps_vcl_nal->i1_nal_ref_id_next = -1;
1691     }
1692     else
1693     {
1694         /* update the next access unit params */
1695         /* will be used by lower level decoder*/
1696         /* for concealment of frame number    */
1697         /* applicable for single layer cases  */
1698         ps_vcl_nal->i1_nal_ref_id_next = ps_nal_prms->i4_nal_ref_idc;
1699 
1700         ps_vcl_nal->u2_frm_num_next = ps_nal_prms->u2_frm_num;
1701     }
1702 
1703     /* -------- reset few variables in context structure ----*/
1704     isvcd_pic_reset_ctxt(ps_nal_parse_ctxt);
1705 }
1706 /*****************************************************************************/
1707 /*                                                                           */
1708 /*  Function Name : isvcd_nal_parse_vcl_nal_partial                          */
1709 /*                                                                           */
1710 /*  Description   : None                                                     */
1711 /*                                                                           */
1712 /*  Inputs        : pv_nal_parse_ctxt - bitstream extract ctxt               */
1713 /*                      structure                                            */
1714 /*                  pv_input_bitstream_ctxt - bitstream context              */
1715 /*                  pv_out_non_vcl_nal - non vcl nal structure (output)      */
1716 /*                  pv_out_vcl_nal - vcl nal structure (output)              */
1717 /*                  pu4_bytes_consumed - bytes consumed variable(output)     */
1718 /*                  pi4_num_packets_consumed - packets consumed (output/RFC) */
1719 /*                                                                           */
1720 /*  Globals       : None                                                     */
1721 /*                                                                           */
1722 /*  Processing    : None                                                     */
1723 /*                                                                           */
1724 /*  Outputs       : Updates bytes consumed variable, packets consumed,       */
1725 /*                  output structures (vcl nal , non vcl nal)                */
1726 /*                                                                           */
1727 /*  Returns       : If picture bounadry is detetcted then PIC_BOUNDARY_TRUE  */
1728 /*                  otherwise PIC_BOUNDARY_FALSE                             */
1729 /*                                                                           */
1730 /*  Issues        : None                                                     */
1731 /*                                                                           */
1732 /*  Revision History:                                                        */
1733 /*          DD MM YYYY   Author(s)       Changes                             */
1734 /*          06 09 2021   Vijay           Draft                               */
1735 /*                                                                           */
1736 /*****************************************************************************/
1737 
isvcd_nal_parse_vcl_nal_partial(void * pv_nal_parse_ctxt,UWORD8 * pu1_stream_buffer,void * pv_out_non_vcl_nal,void * pv_out_vcl_nal,UWORD32 * pu4_bytes_consumed,UWORD32 * pu4_num_bytes)1738 WORD32 isvcd_nal_parse_vcl_nal_partial(void *pv_nal_parse_ctxt, UWORD8 *pu1_stream_buffer,
1739                                        void *pv_out_non_vcl_nal, void *pv_out_vcl_nal,
1740                                        UWORD32 *pu4_bytes_consumed, UWORD32 *pu4_num_bytes)
1741 {
1742     /*! - Search for the NAL boundary
1743         - If NAL boundary is not found and bytes consumed is lesser than
1744           minimum buffer size then break out of the loop
1745         - if it is start of NAL then read the NAL header
1746         - If it is a VCL NAL then invoke picture boundary detection logic and
1747           picture boundary is detected then break out of the loop without
1748           updating the bytes consumed variable
1749         - NAL discard logic determines whther the current NAL has to be
1750           discarded or not
1751         - If NAL is not discarded then populate the vcl or non vcl output
1752           structures
1753     */
1754     nal_parse_ctxt_t *ps_nal_parse_ctxt;
1755     vcl_nal_t *ps_vcl_nal;
1756     non_vcl_nal_t *ps_non_vcl_nal;
1757     nal_unit_t *ps_nal_unit;
1758     WORD32 i4_nal_start_flag, i4_cur_pos, i4_status;
1759     WORD32 i4_nal_header_len, i4_more_data_flag;
1760     UWORD32 u4_bytes_consumed_temp = 0;
1761     UWORD8 **ppu1_out_buf;
1762     nal_prms_t *ps_nal_prms;
1763     WORD32 i4_pic_bound_status;
1764 
1765     ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
1766     ps_vcl_nal = (vcl_nal_t *) pv_out_vcl_nal;
1767     ps_non_vcl_nal = (non_vcl_nal_t *) pv_out_non_vcl_nal;
1768     ps_nal_unit = (nal_unit_t *) ps_nal_parse_ctxt->pv_nal_unit;
1769     ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
1770 
1771     /* Initialization */
1772     i4_cur_pos = 0;
1773     *pu4_bytes_consumed = 0;
1774     i4_nal_header_len = 0;
1775     i4_nal_start_flag = SVCD_FALSE;
1776     i4_more_data_flag = SVCD_TRUE;
1777     i4_pic_bound_status = PIC_BOUNDARY_FALSE;
1778 
1779     ps_non_vcl_nal->i4_num_non_vcl_nals = ps_nal_parse_ctxt->i4_num_non_vcl_nals;
1780 
1781     /* Since we do not perform the picture boundary detection */
1782     /* on the prefix NAL unit, the current picture's prefix   */
1783     /* NAL unit will be at the bottom of the buffer. Hence    */
1784     /* it should be copied to top of the buffer               */
1785     if(SVCD_TRUE == ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au)
1786     {
1787         nal_buf_t *ps_prefix_nal_buf;
1788 
1789         ps_prefix_nal_buf = &ps_nal_parse_ctxt->s_prefix_nal_buf;
1790         if(SVCD_TRUE == ps_prefix_nal_buf->i4_valid_flag)
1791         {
1792             WORD32 i4_buf_size;
1793             UWORD8 *pu1_vcl_nal;
1794 
1795             if(ps_prefix_nal_buf->i4_buf_size > 0)
1796             {
1797                 i4_buf_size = ps_prefix_nal_buf->i4_buf_size;
1798                 i4_buf_size = UP_ALIGN_8(i4_buf_size + BUFFER_ALIGN_4);
1799             }
1800             else
1801             {
1802                 i4_buf_size = 0;
1803             }
1804 
1805             pu1_vcl_nal = ps_nal_parse_ctxt->pu1_vcl_nal_buf + i4_buf_size;
1806 
1807             memmove(ps_nal_parse_ctxt->pu1_vcl_nal_buf, ps_prefix_nal_buf->pu1_buf, i4_buf_size);
1808             ps_prefix_nal_buf->pu1_buf = ps_nal_parse_ctxt->pu1_vcl_nal_buf;
1809             ps_nal_parse_ctxt->pu1_vcl_nal_buf = pu1_vcl_nal;
1810 
1811             /* subtract the buffer size left */
1812             ps_nal_parse_ctxt->u4_bytes_left_vcl -= i4_buf_size;
1813         }
1814         /* Reset the top and bottom node */
1815         ps_vcl_nal->ps_top_node = NULL;
1816         ps_vcl_nal->ps_bot_node = NULL;
1817         ps_vcl_nal->i1_nal_ref_id_next = -1;
1818         ps_vcl_nal->u2_frm_num_next = 0;
1819     }
1820 
1821     /* If number of bytes left in the previous process call  */
1822     /* is is greater or equal to number of bytes in input    */
1823     /* buffer of the current process call then declare that  */
1824     /* end of bitstream has occurred and consume the bytes   */
1825     /* but do not decode                                     */
1826     if(ps_nal_parse_ctxt->u4_bytes_left >= (UWORD32) *pu4_num_bytes)
1827     {
1828         ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
1829         *pu4_bytes_consumed = *pu4_num_bytes;
1830 
1831         i4_status =
1832             isvcd_nal_parse_partial_signal_eos(ps_nal_parse_ctxt, ps_vcl_nal, ps_non_vcl_nal);
1833         /* set the next AU params to default values */
1834         ps_vcl_nal->i1_nal_ref_id_next = -1;
1835         ps_vcl_nal->u2_frm_num_next = 0;
1836 
1837         return (i4_status);
1838     }
1839     ps_nal_parse_ctxt->u4_bytes_left = 0;
1840 
1841     /*************************************************************************/
1842     /*                      LOOP OVER NALs                                   */
1843     /*************************************************************************/
1844     do
1845     {
1846         nal_buf_t *ps_nal_buf;
1847         UWORD32 *pu4_bytes_left;
1848 
1849         /* Find NAL boundary                */
1850         if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
1851         {
1852             i4_nal_start_flag = isvcd_get_annex_b_nal_unit(
1853                 pu1_stream_buffer, i4_cur_pos, *pu4_num_bytes,
1854                 &ps_nal_parse_ctxt->i4_find_nal_state, &ps_nal_parse_ctxt->i4_zero_byte_cnt,
1855                 &u4_bytes_consumed_temp, ps_nal_parse_ctxt->pv_nal_unit, &i4_more_data_flag);
1856 
1857             i4_cur_pos += u4_bytes_consumed_temp;
1858         }
1859 
1860         /*********************************************************************/
1861         /*          READ NAL HEADER AND NAL DISCARD LOGIC                    */
1862         /*********************************************************************/
1863 
1864         /* If it is the start of NAL header perform the following */
1865         /* 1. Decode NAL header                                   */
1866         /* 2. Determine whether the NAL has to be discarded or not*/
1867         /* 3. Detect the picture boundary                         */
1868         if(SVCD_TRUE == i4_nal_start_flag)
1869         {
1870             UWORD32 u4_err_code;
1871             WORD32 i4_sps_pps_corrupt_status;
1872             WORD32 i4_internal_dep_id_prev;
1873 
1874             /* Get the NAL prms. This involves the following things*/
1875             /* 1. Decode the NAL header                            */
1876             /* 2. Set the discard flag                             */
1877             /* 3. Decode the slice header if needed                */
1878 
1879             /* get the dependency id at which the NAl parse is currently */
1880             /* present */
1881             i4_internal_dep_id_prev = ps_nal_parse_ctxt->s_int_attr.i4_dependency_id;
1882 
1883             i4_status = isvcd_get_nal_prms(
1884                 ps_nal_unit->pu1_bufs, ps_nal_unit->i4_buf_sizes, ps_nal_prms,
1885                 &ps_nal_parse_ctxt->s_prefix_nal_prms, &ps_nal_parse_ctxt->s_prefix_nal_buf,
1886                 &u4_err_code, &i4_sps_pps_corrupt_status, &ps_nal_parse_ctxt->i4_discard_nal_flag,
1887                 ps_nal_parse_ctxt);
1888 
1889             if(NON_ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
1890             {
1891                 ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
1892             }
1893 
1894             /* If the error code returned by the "picture boundary" */
1895             /* detetction is                                        */
1896             /* 1. Insufficient bitstream size: then store the bytes */
1897             /*    left and break out of the loop                    */
1898             /* 2. Corrupted slice: then discard the slice           */
1899             if((NAL_INSUFFICIENT_DATA == (WORD32) u4_err_code) &&
1900                (NAL_END != ps_nal_parse_ctxt->i4_find_nal_state))
1901             {
1902                 ps_nal_parse_ctxt->u4_bytes_left = *pu4_num_bytes - *pu4_bytes_consumed;
1903 
1904                 /* Reset the NAL level tracking variables */
1905                 isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
1906                 break;
1907             }
1908             else if(0 != u4_err_code)
1909             {
1910                 ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
1911 
1912                 if(SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag)
1913                 {
1914                     /* IDR Error handler is called       */
1915                     /* only if for a given layer the NAL */
1916                     /* haeder and partial slice decode   */
1917                     /* routine comes out as no SPS PPS   */
1918                     /* error. But for Lowest layer in    */
1919                     /* access unit it is doen always     */
1920                     if(i4_internal_dep_id_prev != ps_nal_parse_ctxt->s_int_attr.i4_dependency_id)
1921                     {
1922                         /* if the target depedency id has been */
1923                         /* changed while decoding currnet NAL  */
1924 
1925                         if((0 != i4_sps_pps_corrupt_status) ||
1926                            (-1 == ps_nal_parse_ctxt->i4_prev_dq_id))
1927                         {
1928                             i4_status =
1929                                 isvcd_idr_err_hdlr(ps_vcl_nal, ps_nal_prms, ps_nal_parse_ctxt);
1930                             if(OK != i4_status)
1931                             {
1932                                 return i4_status;
1933                             }
1934                             UNUSED(i4_status);
1935 
1936                             ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_FALSE;
1937                         }
1938                         else
1939                         {
1940                             if(0 == ps_nal_prms->i4_quality_id)
1941                             {
1942                                 /* over write the frame number */
1943                                 ps_nal_parse_ctxt->s_nal_prms.u2_frm_num = 0;
1944 
1945                                 /* Get the previous layer's DQID */
1946                                 if(ps_nal_parse_ctxt->i4_prev_dq_id < ps_nal_prms->i4_dqid)
1947                                 {
1948                                     ps_nal_parse_ctxt->i4_prev_dq_id = ps_nal_prms->i4_dqid;
1949                                     ps_nal_parse_ctxt->i4_is_frst_vcl_nal_in_au = SVCD_FALSE;
1950                                 }
1951 
1952                                 /* update the nal context with the nal */
1953                                 /* header params */
1954                                 isvcd_update_nal_ctxt(ps_nal_parse_ctxt, ps_vcl_nal,
1955                                                       ps_non_vcl_nal);
1956                             }
1957                         }
1958                     }
1959                 }
1960             }
1961 
1962             /* Populate the derived nal type into bitstream extract*/
1963             /* context structure                                   */
1964             i4_nal_header_len = ps_nal_prms->i4_nal_header_len;
1965             ps_nal_parse_ctxt->i4_nal_type = ps_nal_prms->i4_derived_nal_type;
1966 
1967             /* get the accumulated idr pic error flag */
1968             ps_nal_parse_ctxt->i4_idr_pic_err_flag |=
1969                 ((SVCD_TRUE == ps_nal_prms->i4_idr_pic_flag) &&
1970                  (SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag) &&
1971                  (i4_internal_dep_id_prev != ps_nal_parse_ctxt->s_int_attr.i4_dependency_id));
1972 
1973             if(ACCESS_UNIT_DELIMITER_RBSP == ps_nal_prms->i4_nal_unit_type)
1974             {
1975                 i4_pic_bound_status = PIC_BOUNDARY_TRUE;
1976                 ps_nal_parse_ctxt->u1_pic_boundary_aud_flag = 1;
1977                 /* If picture boundary is detected then come out of  */
1978                 /* the loop                                          */
1979                 if(PIC_BOUNDARY_TRUE == i4_pic_bound_status)
1980                 {
1981                     isvcd_nal_parse_pic_bound_proc(ps_nal_parse_ctxt, ps_vcl_nal, ps_nal_prms);
1982                     break;
1983                 }
1984             }
1985             /* Perform the picture boundary detetction if all the  */
1986             /* following conditions are TRUE                       */
1987             /*  1. VCL NAL                                         */
1988             /*  2. Not a prefix NAL                                */
1989             /*  3. Not a discardable NAL                           */
1990             if((VCL_NAL == ps_nal_prms->i4_derived_nal_type) &&
1991                (PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type) &&
1992                (SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag))
1993             {
1994                 if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
1995                 {
1996                     ps_nal_parse_ctxt->u1_pic_boundary_aud_flag = 0;
1997 
1998                     i4_status = isvcd_detect_pic_boundary_annex_b(ps_nal_prms, pu1_stream_buffer,
1999                                                                   i4_cur_pos, &i4_pic_bound_status,
2000                                                                   ps_nal_parse_ctxt, pu4_num_bytes);
2001                 }
2002 
2003                 /* If picture boundary is detected then come out of  */
2004                 /* the loop                                          */
2005                 if(PIC_BOUNDARY_TRUE == i4_pic_bound_status)
2006                 {
2007                     isvcd_nal_parse_pic_bound_proc(ps_nal_parse_ctxt, ps_vcl_nal, ps_nal_prms);
2008                     break;
2009                 }
2010             }
2011 
2012             if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
2013             {
2014                 /* Set the active NAL buffer structure and initialize */
2015                 /* the nal buffer structure                           */
2016                 isvcd_get_nal_buf(ps_nal_parse_ctxt, &ps_nal_buf);
2017                 ps_nal_parse_ctxt->ps_nal_buf = ps_nal_buf;
2018             }
2019             else
2020             {
2021                 ps_nal_parse_ctxt->ps_nal_buf = NULL;
2022             }
2023         }
2024 
2025         /*-------------------------------------------------------------------*/
2026         /* In RFC based bitstreams, this is a dummy update (in this mode, the*/
2027         /* bytes consumed updation is done by picture boundary dectection    */
2028         /* But for Annex B based streams this is valid update                */
2029         /*-------------------------------------------------------------------*/
2030         *pu4_bytes_consumed += u4_bytes_consumed_temp;
2031 
2032         /*********************************************************************/
2033         /*          EMULATION PREVENTION AND BYTE SWAPPING                   */
2034         /*********************************************************************/
2035 
2036         /* Determine output buffer */
2037         ps_nal_buf = ps_nal_parse_ctxt->ps_nal_buf;
2038 
2039         if(VCL_NAL == ps_nal_parse_ctxt->i4_nal_type)
2040         {
2041             ppu1_out_buf = &ps_nal_parse_ctxt->pu1_vcl_nal_buf;
2042             pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_vcl;
2043             if(*pu4_bytes_left < (MAX_VCL_NAL_BUFF_SIZE * 0.05))
2044             {
2045                 return (VCL_NAL_FOUND_FALSE);
2046             }
2047         }
2048         else
2049         {
2050             ppu1_out_buf = &ps_nal_parse_ctxt->pu1_non_vcl_nal_buf;
2051             pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_non_vcl;
2052             if(*pu4_bytes_left < (MAX_NON_VCL_NAL_BUFF_SIZE * 0.05))
2053             {
2054                 return (VCL_NAL_FOUND_FALSE);
2055             }
2056         }
2057 
2058         /* if 0 bytes left then discard the current NAL */
2059         if(0 >= (WORD32) *pu4_bytes_left)
2060         {
2061             ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
2062         }
2063 
2064         /* Perform the emulation prevention and byte swap */
2065         if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
2066         {
2067             UWORD32 u4_output_bytes, u4_buf_inc;
2068 
2069             /* Do emulation prevention and byte swapping on all the packets  */
2070             /* of RFC or current partial or full Annex B NAL unit            */
2071             {
2072                 UWORD32 u4_buf_size;
2073 
2074                 /* clip the size before emulation prevention */
2075                 u4_buf_size = (UWORD32) CLIP3(0, (WORD32) *pu4_bytes_left,
2076                                               (ps_nal_unit->i4_buf_sizes - i4_nal_header_len));
2077 
2078                 u4_buf_inc = isvcd_nal_byte_swap_emulation(
2079                     (UWORD32 *) *ppu1_out_buf, &u4_output_bytes,
2080                     ps_nal_unit->pu1_bufs + i4_nal_header_len, u4_buf_size,
2081                     NUM_OF_ZERO_BYTES_BEFORE_START_CODE, &ps_nal_parse_ctxt->s_emulation_ctxt);
2082 
2083                 i4_nal_header_len = 0;
2084                 u4_buf_inc = UP_ALIGN_8(u4_buf_inc);
2085                 *ppu1_out_buf += u4_buf_inc;
2086                 *pu4_bytes_left -= u4_buf_inc;
2087                 ps_nal_buf->i4_buf_size += u4_output_bytes;
2088             }
2089         }
2090 
2091         /*********************************************************************/
2092         /*                UPDATE VARIABLES                                   */
2093         /*********************************************************************/
2094         if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
2095         {
2096             if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
2097             {
2098                 /* This fucntions updates output nal ctxt - vcl nal structure*/
2099                 /* and non vcl nal structure depending upon the current NAL  */
2100                 /* type.                                                     */
2101                 /* This will only update parameters which are available at   */
2102                 /* end of NAL unit like nal unit's total size                */
2103                 isvcd_update_nal_ctxt(ps_nal_parse_ctxt, ps_vcl_nal, ps_non_vcl_nal);
2104 
2105                 UPDATE_NAL_BUF_PTR(ppu1_out_buf, ps_nal_prms->i4_derived_nal_type, pu4_bytes_left);
2106             }
2107 
2108             /* If the prefix NAL unit is not immediatly followed by */
2109             /* a AVC NAL unit it shall be discarded and hence reset */
2110             /* is done                                              */
2111             /* Also if prefix NAL unit is discarded then we should  */
2112             /* not associate the prefix NAL unit with AVC NAL unit  */
2113             /* and hence a reset is required                        */
2114             if((PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type) ||
2115                (SVCD_TRUE == ps_nal_parse_ctxt->i4_discard_nal_flag))
2116             {
2117                 isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_prefix_nal_buf);
2118             }
2119 
2120             /* Reset the nal level tracking variables */
2121             isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
2122         }
2123 
2124         /*------------- while loop ends here --------------------------------*/
2125     } while(SVCD_TRUE == i4_more_data_flag);
2126 
2127     return (i4_pic_bound_status);
2128 }
2129 
2130 /*****************************************************************************/
2131 /*                                                                           */
2132 /*  Function Name : isvcd_nal_parse_non_vcl_nal                              */
2133 /*                                                                           */
2134 /*  Description   : None                                                     */
2135 /*                                                                           */
2136 /*  Inputs        : pv_nal_parse_ctxt - bitstream extract ctxt               */
2137 /*                      structure                                            */
2138 /*                  pv_input_bitstream_ctxt - bitstream context              */
2139 /*                  pv_out_non_vcl_nal - non vcl nal structure (output)      */
2140 /*                  pu4_bytes_consumed - bytes consumed variable(output)     */
2141 /*                  pi4_num_packets_consumed - packets consumed (output/RFC) */
2142 /*                                                                           */
2143 /*  Globals       : None                                                     */
2144 /*                                                                           */
2145 /*  Processing    : None                                                     */
2146 /*                                                                           */
2147 /*  Outputs       : Updates bytes consumed variable, packets consumed,       */
2148 /*                  output structures (non vcl nal)                          */
2149 /*                                                                           */
2150 /*  Returns       : If vcl nal is found then VCL_NAL_FOUND_TRUE otherwise    */
2151 /*                  VCL_NAL_FOUND_FALSE                                      */
2152 /*                                                                           */
2153 /*  Issues        : None                                                     */
2154 /*                                                                           */
2155 /*  Revision History:                                                        */
2156 /*          DD MM YYYY   Author(s)       Changes                             */
2157 /*          06 09 2021   Vijay      Draft                                    */
2158 /*                                                                           */
2159 /*****************************************************************************/
2160 
isvcd_nal_parse_non_vcl_nal(void * pv_nal_parse_ctxt,UWORD8 * pu1_stream_buffer,void * pv_out_non_vcl_nal,UWORD32 * pu4_bytes_consumed,UWORD32 * pu4_num_bytes)2161 WORD32 isvcd_nal_parse_non_vcl_nal(void *pv_nal_parse_ctxt, UWORD8 *pu1_stream_buffer,
2162                                    void *pv_out_non_vcl_nal, UWORD32 *pu4_bytes_consumed,
2163                                    UWORD32 *pu4_num_bytes)
2164 {
2165     /*! - Search for the NAL boundary
2166         - If NAL boundary is not found and bytes consumed is lesser than
2167           minimum buffer size then break out of the loop
2168         - if it is start of NAL then read the NAL header
2169         - If it is a VCL NAL then return from this fucntion saying that
2170           VCL NAL found
2171         - NAL discard logic determines whther the current NAL has to be
2172           discarded or not
2173         - If NAL is not discarded then populate the vcl or non vcl output
2174           structures
2175     */
2176 
2177     nal_parse_ctxt_t *ps_nal_parse_ctxt;
2178     non_vcl_nal_t *ps_non_vcl_nal;
2179     nal_unit_t *ps_nal_unit;
2180     WORD32 i4_nal_start_flag, i4_cur_pos, i4_status;
2181     WORD32 i4_nal_header_len, i4_more_data_flag;
2182     UWORD32 u4_bytes_consumed_temp = 0;
2183     UWORD8 **ppu1_out_buf;
2184     nal_prms_t *ps_nal_prms;
2185 
2186     ps_nal_parse_ctxt = (nal_parse_ctxt_t *) pv_nal_parse_ctxt;
2187     ps_non_vcl_nal = (non_vcl_nal_t *) pv_out_non_vcl_nal;
2188     ps_nal_unit = (nal_unit_t *) ps_nal_parse_ctxt->pv_nal_unit;
2189     ps_nal_prms = &ps_nal_parse_ctxt->s_nal_prms;
2190 
2191     /* Initialization */
2192     i4_cur_pos = 0;
2193     *pu4_bytes_consumed = 0;
2194     i4_nal_header_len = 0;
2195     i4_nal_start_flag = SVCD_FALSE;
2196     i4_more_data_flag = SVCD_TRUE;
2197     i4_status = PIC_BOUNDARY_FALSE;
2198 
2199     /* reset the target layer update flag */
2200     ps_nal_parse_ctxt->i4_tgt_lyr_update = SVCD_FALSE;
2201     /*************************************************************************/
2202     /*              SEARCHING FOR THE START OF BITSTREAM                     */
2203     /*************************************************************************/
2204 
2205     /*-----------------------------------------------------------------------*/
2206     /* For Annex B based bitstreams the first start code has to decoded      */
2207     /* The first start code can come after multiple process call also. This  */
2208     /* has to be carefully handled                                           */
2209     /*-----------------------------------------------------------------------*/
2210 
2211     if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode &&
2212        SVCD_TRUE == ps_nal_parse_ctxt->i4_dec_frst_sc_flag)
2213     {
2214         WORD32 i4_status;
2215 
2216         i4_status =
2217             isvcd_get_first_start_code(pu1_stream_buffer, pu4_bytes_consumed, pu4_num_bytes);
2218 
2219         /*-------------------------------------------------------------------*/
2220         /* If start code found then proceed with bitstream extraction        */
2221         /*-------------------------------------------------------------------*/
2222 
2223         if(i4_status == SC_NOT_FOUND)
2224         {
2225             return (VCL_NAL_FOUND_FALSE);
2226         }
2227 
2228         i4_cur_pos = *pu4_bytes_consumed;
2229         ps_nal_parse_ctxt->i4_dec_frst_sc_flag = SVCD_FALSE;
2230     }
2231 
2232     /* If number of bytes left in the previous process call  */
2233     /* is is greater or equal to number of bytes in input    */
2234     /* buffer of the current process call then declare that  */
2235     /* end of bitstream has occurred and consume the bytes   */
2236     /* but do not decode                                     */
2237     if(ps_nal_parse_ctxt->u4_bytes_left >= (UWORD32) *pu4_num_bytes)
2238     {
2239         ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
2240         *pu4_bytes_consumed = *pu4_num_bytes;
2241 
2242         i4_status = isvcd_nal_parse_partial_signal_eos(ps_nal_parse_ctxt, NULL, ps_non_vcl_nal);
2243         return (i4_status);
2244     }
2245 
2246     do
2247     {
2248         nal_buf_t *ps_nal_buf;
2249         UWORD32 *pu4_bytes_left;
2250 
2251         /*********************************************************************/
2252         /*                  NAL BOUNDARY DETECTION                           */
2253         /*********************************************************************/
2254         /*-------------------------------------------------------------------*/
2255         /* Detect NAL boundary                                               */
2256         /* After return,  this NAL boundary detetction logic might be in     */
2257         /* one of following states:                                          */
2258         /*  - NAL_START                                                      */
2259         /*  - FIND_NAL_END                                                   */
2260         /*  - NAL_END                                                        */
2261         /*-------------------------------------------------------------------*/
2262         if(ANNEX_B == ps_nal_parse_ctxt->i4_input_bitstream_mode)
2263         {
2264             i4_nal_start_flag = isvcd_get_annex_b_nal_unit(
2265                 pu1_stream_buffer, i4_cur_pos, *pu4_num_bytes,
2266                 &ps_nal_parse_ctxt->i4_find_nal_state, &ps_nal_parse_ctxt->i4_zero_byte_cnt,
2267                 &u4_bytes_consumed_temp, ps_nal_parse_ctxt->pv_nal_unit, &i4_more_data_flag);
2268 
2269             i4_cur_pos += u4_bytes_consumed_temp;
2270         }
2271 
2272         /* If current NAL unit is start of new NAL unit then parse the NAL
2273             header. If the current NAL unit type is VCL NAL then return from
2274             this function. otherwise apply NAL discard logic and discard the
2275             NAL if discard NAL flag is true                                  */
2276 
2277         if(SVCD_TRUE == i4_nal_start_flag)
2278         {
2279             UWORD32 u4_err_code;
2280             WORD32 i4_sps_pps_corrupt_status;
2281 
2282             /* Get the NAL prms. This involves the following things*/
2283             /* 1. Decode the NAL header                            */
2284             /* 2. Set the discard flag                             */
2285             /* 3. Decode the slice header if needed                */
2286             isvcd_get_nal_prms(ps_nal_unit->pu1_bufs, ps_nal_unit->i4_buf_sizes, ps_nal_prms,
2287                                &ps_nal_parse_ctxt->s_prefix_nal_prms,
2288                                &ps_nal_parse_ctxt->s_prefix_nal_buf, &u4_err_code,
2289                                &i4_sps_pps_corrupt_status, &ps_nal_parse_ctxt->i4_discard_nal_flag,
2290                                ps_nal_parse_ctxt);
2291             /* If the error code returned by the "picture boundary" */
2292             /* detetction is                                        */
2293             /* 1. Insufficient bitstream size: then store the bytes */
2294             /*    left and break out of the loop                    */
2295             /* 2. Corrupted slice: then discard the slice           */
2296             if((NAL_INSUFFICIENT_DATA == (WORD32) u4_err_code) &&
2297                (NAL_END != ps_nal_parse_ctxt->i4_find_nal_state))
2298             {
2299                 ps_nal_parse_ctxt->u4_bytes_left = *pu4_num_bytes - *pu4_bytes_consumed;
2300 
2301                 /* Reset the NAL level tracking variables */
2302                 isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
2303                 break;
2304             }
2305             else if(0 != u4_err_code)
2306             {
2307                 ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
2308             }
2309 
2310             /* Populate other paramters based on the nal prms */
2311             ps_nal_parse_ctxt->i4_nal_type = ps_nal_prms->i4_derived_nal_type;
2312             i4_nal_header_len = ps_nal_prms->i4_nal_header_len;
2313 
2314             /* If derived NAL unit is VCL_NAL then return from this function */
2315             if(VCL_NAL == ps_nal_prms->i4_derived_nal_type &&
2316                PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type)
2317             {
2318                 isvcd_pic_reset_ctxt(ps_nal_parse_ctxt);
2319 
2320                 return (VCL_NAL_FOUND_TRUE);
2321             }
2322 
2323             /* Set the active NAL buffer structure and initialize */
2324             /* the nal buffer structure                           */
2325             isvcd_get_nal_buf(ps_nal_parse_ctxt, &ps_nal_buf);
2326 
2327             ps_nal_parse_ctxt->ps_nal_buf = ps_nal_buf;
2328         }
2329 
2330         /* Update the bytes consumed variable */
2331 
2332         *pu4_bytes_consumed += u4_bytes_consumed_temp;
2333 
2334         ps_nal_buf = ps_nal_parse_ctxt->ps_nal_buf;
2335         if(VCL_NAL == ps_nal_parse_ctxt->i4_nal_type)
2336         {
2337             ppu1_out_buf = &ps_nal_parse_ctxt->pu1_vcl_nal_buf;
2338             pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_vcl;
2339             if(*pu4_bytes_left < (MAX_VCL_NAL_BUFF_SIZE * 0.05))
2340             {
2341                 return (VCL_NAL_FOUND_FALSE);
2342             }
2343         }
2344         else
2345         {
2346             ppu1_out_buf = &ps_nal_parse_ctxt->pu1_non_vcl_nal_buf;
2347             pu4_bytes_left = &ps_nal_parse_ctxt->u4_bytes_left_non_vcl;
2348             if(*pu4_bytes_left < (MAX_NON_VCL_NAL_BUFF_SIZE * 0.05))
2349             {
2350                 return (VCL_NAL_FOUND_FALSE);
2351             }
2352         }
2353 
2354         /* if 0 bytes left then discard the current NAL */
2355         if(0 >= (WORD32) *pu4_bytes_left)
2356         {
2357             ps_nal_parse_ctxt->i4_discard_nal_flag = SVCD_TRUE;
2358         }
2359 
2360         /* If NAL is not discarded then :
2361             1) Perform emulation prevention and byte swapping on the RBSP data
2362             2) Update the NAL unit ctxt:
2363                 a) If VCL NAL then update DQID list
2364                 b) If NON VCL NAL then update the non vcl output structure   */
2365 
2366         if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
2367         {
2368             UWORD32 u4_output_bytes, u4_buf_inc;
2369 
2370             {
2371                 UWORD32 u4_buf_size;
2372 
2373                 /* clip the size before emulation prevention */
2374                 u4_buf_size = (UWORD32) CLIP3(0, (WORD32) *pu4_bytes_left,
2375                                               (ps_nal_unit->i4_buf_sizes - i4_nal_header_len));
2376 
2377                 u4_buf_inc = isvcd_nal_byte_swap_emulation(
2378                     (UWORD32 *) *ppu1_out_buf, &u4_output_bytes,
2379                     ps_nal_unit->pu1_bufs + i4_nal_header_len, u4_buf_size,
2380                     NUM_OF_ZERO_BYTES_BEFORE_START_CODE, &ps_nal_parse_ctxt->s_emulation_ctxt);
2381                 i4_nal_header_len = 0;
2382 
2383                 u4_buf_inc = UP_ALIGN_8(u4_buf_inc);
2384                 *ppu1_out_buf += u4_buf_inc;
2385                 *pu4_bytes_left -= u4_buf_inc;
2386                 ps_nal_buf->i4_buf_size += u4_output_bytes;
2387             }
2388         }
2389 
2390         /*********************************************************************/
2391         /*                UPDATE VARIABLES                                   */
2392         /*********************************************************************/
2393 
2394         if(NAL_END == ps_nal_parse_ctxt->i4_find_nal_state)
2395         {
2396             /*---------------------------------------------------------------*/
2397             /* - Update the total bits in the NAL. While doing so bits       */
2398             /* calculated so far should be converted to SODB length          */
2399             /*---------------------------------------------------------------*/
2400             if(SVCD_FALSE == ps_nal_parse_ctxt->i4_discard_nal_flag)
2401             {
2402                 isvcd_update_nal_ctxt(ps_nal_parse_ctxt, NULL, ps_non_vcl_nal);
2403 
2404                 UPDATE_NAL_BUF_PTR(ppu1_out_buf, ps_nal_prms->i4_derived_nal_type, pu4_bytes_left);
2405             }
2406 
2407             /* If the prefix NAL unit is not immediatly followed by */
2408             /* a AVC NAL unit it shall be discarded and hence reset */
2409             /* is done                                              */
2410             /* Also if prefix NAL unit is discarded then we should  */
2411             /* not associate the prefix NAL unit with AVC NAL unit  */
2412             /* and hence a reset is required                        */
2413             if((PREFIX_UNIT_NAL != ps_nal_prms->i4_nal_unit_type) ||
2414                (SVCD_TRUE == ps_nal_parse_ctxt->i4_discard_nal_flag))
2415             {
2416                 isvcd_nal_buf_reset(&ps_nal_parse_ctxt->s_prefix_nal_buf);
2417             }
2418 
2419             /* Reset NAL level tracking variables */
2420             isvcd_nal_reset_ctxt(ps_nal_parse_ctxt);
2421         }
2422 
2423         i4_nal_header_len = 0;
2424         /*------------- while loop ends here --------------------------------*/
2425     } while(SVCD_TRUE == i4_more_data_flag);
2426 
2427     if(i4_more_data_flag == 0)
2428     {
2429         isvcd_pic_reset_ctxt(ps_nal_parse_ctxt);
2430         return (VCL_NAL_FOUND_TRUE);
2431     }
2432 
2433     return (VCL_NAL_FOUND_FALSE);
2434 }