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