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