/src/libhevc/decoder/ihevcd_nal.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore |
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 | | /** |
19 | | ******************************************************************************* |
20 | | * @file |
21 | | * ihevcd_nal.c |
22 | | * |
23 | | * @brief |
24 | | * Contains functions for NAL level such as search start code etc |
25 | | * |
26 | | * @author |
27 | | * Harish |
28 | | * |
29 | | * @par List of Functions: |
30 | | * |
31 | | * @remarks |
32 | | * None |
33 | | * |
34 | | ******************************************************************************* |
35 | | */ |
36 | | /*****************************************************************************/ |
37 | | /* File Includes */ |
38 | | /*****************************************************************************/ |
39 | | #include <stdio.h> |
40 | | #include <stddef.h> |
41 | | #include <stdlib.h> |
42 | | #include <string.h> |
43 | | #include <assert.h> |
44 | | |
45 | | #include "ihevc_typedefs.h" |
46 | | #include "iv.h" |
47 | | #include "ivd.h" |
48 | | #include "ihevcd_cxa.h" |
49 | | |
50 | | #include "ihevc_defs.h" |
51 | | #include "ihevc_debug.h" |
52 | | #include "ihevc_structs.h" |
53 | | #include "ihevc_macros.h" |
54 | | #include "ihevc_platform_macros.h" |
55 | | #include "ihevc_cabac_tables.h" |
56 | | |
57 | | |
58 | | #include "ihevcd_defs.h" |
59 | | #include "ihevcd_function_selector.h" |
60 | | #include "ihevcd_structs.h" |
61 | | #include "ihevcd_error.h" |
62 | | #include "ihevcd_nal.h" |
63 | | #include "ihevcd_bitstream.h" |
64 | | #include "ihevcd_parse_headers.h" |
65 | | #include "ihevcd_parse_slice.h" |
66 | | #include "ihevcd_debug.h" |
67 | | /*****************************************************************************/ |
68 | | /* Function Prototypes */ |
69 | | /*****************************************************************************/ |
70 | | |
71 | | /** |
72 | | ******************************************************************************* |
73 | | * |
74 | | * @brief |
75 | | * Search start code from the given buffer pointer |
76 | | * |
77 | | * @par Description: |
78 | | * Search for start code Return the offset of start code if start code is |
79 | | * found If no start code is found till end of given bitstream then treat |
80 | | * it as invalid NAL and return end of buffer as offset |
81 | | * |
82 | | * @param[in] pu1_buf |
83 | | * Pointer to bitstream |
84 | | * |
85 | | * @param[in] bytes_remaining |
86 | | * Number of bytes remaining in the buffer |
87 | | * |
88 | | * @returns Offset to the first byte in NAL after start code |
89 | | * |
90 | | * @remarks |
91 | | * Incomplete start code at the end of input bitstream is not handled. This |
92 | | * has to be taken care outside this func |
93 | | * |
94 | | ******************************************************************************* |
95 | | */ |
96 | | WORD32 ihevcd_nal_search_start_code(UWORD8 *pu1_buf, WORD32 bytes_remaining) |
97 | 12.8k | { |
98 | 12.8k | WORD32 ofst; |
99 | | |
100 | 12.8k | WORD32 zero_byte_cnt; |
101 | 12.8k | WORD32 start_code_found; |
102 | | |
103 | 12.8k | ofst = -1; |
104 | | |
105 | 12.8k | zero_byte_cnt = 0; |
106 | 12.8k | start_code_found = 0; |
107 | 111M | while(ofst < (bytes_remaining - 1)) |
108 | 111M | { |
109 | 111M | ofst++; |
110 | 111M | if(pu1_buf[ofst] != 0) |
111 | 9.52M | { |
112 | 9.52M | zero_byte_cnt = 0; |
113 | 9.52M | continue; |
114 | 9.52M | } |
115 | | |
116 | 101M | zero_byte_cnt++; |
117 | 101M | if((ofst < (bytes_remaining - 1)) && |
118 | 101M | (pu1_buf[ofst + 1] == START_CODE_PREFIX_BYTE) && |
119 | 101M | (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)) |
120 | 12.8k | { |
121 | | /* Found the start code */ |
122 | 12.8k | ofst++; |
123 | 12.8k | start_code_found = 1; |
124 | 12.8k | break; |
125 | 12.8k | } |
126 | 101M | } |
127 | 12.8k | if((0 == start_code_found) && (ofst < bytes_remaining)) |
128 | 12 | { |
129 | 12 | if((START_CODE_PREFIX_BYTE == pu1_buf[ofst]) && |
130 | 12 | (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)) |
131 | 0 | { |
132 | | /* Found a start code at the end*/ |
133 | 0 | ofst++; |
134 | 0 | } |
135 | 12 | } |
136 | | /* Since ofst started at -1, increment it by 1 */ |
137 | 12.8k | ofst++; |
138 | | |
139 | 12.8k | return ofst; |
140 | 12.8k | } |
141 | | |
142 | | /** |
143 | | ******************************************************************************* |
144 | | * |
145 | | * @brief |
146 | | * Remove emulation prevention byte present in the bitstream till next start |
147 | | * code is found. Emulation prevention byte removed data is stored in a |
148 | | * different buffer |
149 | | * |
150 | | * @par Description: |
151 | | * Assumption is first start code is already found and pu1_buf is pointing |
152 | | * to a byte after the start code Search for Next NAL's start code Return |
153 | | * if start code is found Remove any emulation prevention byte present Copy |
154 | | * data to new buffer If no start code is found, then treat complete buffer |
155 | | * as one nal. |
156 | | * |
157 | | * @param[in] pu1_src |
158 | | * Pointer to bitstream (excludes the initial the start code) |
159 | | * |
160 | | * @param[in] pu1_dst |
161 | | * Pointer to destination buffer |
162 | | * |
163 | | * @param[in] bytes_remaining |
164 | | * Number of bytes remaining |
165 | | * |
166 | | * @param[out] pi4_nal_len |
167 | | * NAL length (length of bitstream parsed) |
168 | | * |
169 | | * @param[out] pi4_dst_len |
170 | | * Destination bitstream size (length of bitstream parsed with emulation bytes |
171 | | * removed) |
172 | | * |
173 | | * @returns Error code from IHEVCD_ERROR_T |
174 | | * |
175 | | * @remarks |
176 | | * Incomplete start code at the end of input bitstream is not handled. This |
177 | | * has to be taken care outside this func |
178 | | * |
179 | | ******************************************************************************* |
180 | | */ |
181 | | IHEVCD_ERROR_T ihevcd_nal_remv_emuln_bytes(UWORD8 *pu1_src, |
182 | | UWORD8 *pu1_dst, |
183 | | WORD32 bytes_remaining, |
184 | | WORD32 *pi4_nal_len, |
185 | | WORD32 *pi4_dst_len) |
186 | 12.8k | { |
187 | 12.8k | WORD32 src_cnt; |
188 | 12.8k | WORD32 dst_cnt; |
189 | 12.8k | WORD32 zero_byte_cnt; |
190 | 12.8k | WORD32 start_code_found; |
191 | 12.8k | UWORD8 u1_src; |
192 | 12.8k | IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; |
193 | | |
194 | 12.8k | src_cnt = 0; |
195 | 12.8k | dst_cnt = 0; |
196 | 12.8k | zero_byte_cnt = 0; |
197 | 12.8k | start_code_found = 0; |
198 | 150M | while(src_cnt < (bytes_remaining - 1)) |
199 | 150M | { |
200 | 150M | u1_src = pu1_src[src_cnt++]; |
201 | | |
202 | 150M | pu1_dst[dst_cnt++] = u1_src; |
203 | 150M | if(u1_src != 0) |
204 | 24.5M | { |
205 | 24.5M | zero_byte_cnt = 0; |
206 | 24.5M | continue; |
207 | 24.5M | } |
208 | | |
209 | 126M | zero_byte_cnt++; |
210 | 126M | if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE) |
211 | 124M | { |
212 | 124M | u1_src = pu1_src[src_cnt]; |
213 | 124M | if(START_CODE_PREFIX_BYTE == u1_src) |
214 | 12.6k | { |
215 | | /* Found the start code */ |
216 | 12.6k | src_cnt -= zero_byte_cnt; |
217 | 12.6k | dst_cnt -= zero_byte_cnt; |
218 | 12.6k | start_code_found = 1; |
219 | 12.6k | break; |
220 | 12.6k | } |
221 | 124M | else if(EMULATION_PREVENT_BYTE == u1_src) |
222 | 1.48k | { |
223 | | /* Found the emulation prevention byte */ |
224 | 1.48k | src_cnt++; |
225 | 1.48k | zero_byte_cnt = 0; |
226 | | |
227 | | /* Decrement dst_cnt so that the next byte overwrites |
228 | | * the emulation prevention byte already copied to dst above |
229 | | */ |
230 | 1.48k | } |
231 | 124M | } |
232 | | |
233 | 126M | } |
234 | | |
235 | 12.8k | if((0 == start_code_found) && (src_cnt < bytes_remaining)) |
236 | 156 | { |
237 | 156 | u1_src = pu1_src[src_cnt++]; |
238 | 156 | if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE) |
239 | 116 | { |
240 | | |
241 | 116 | if(START_CODE_PREFIX_BYTE == u1_src) |
242 | 0 | { |
243 | | /* Found a start code at the end*/ |
244 | 0 | src_cnt -= zero_byte_cnt; |
245 | 0 | } |
246 | 116 | else if(EMULATION_PREVENT_BYTE == u1_src) |
247 | 0 | { |
248 | | /* Found the emulation prevention byte at the end*/ |
249 | 0 | src_cnt++; |
250 | | /* Decrement dst_cnt so that the next byte overwrites |
251 | | * the emulation prevention byte already copied to dst above |
252 | | */ |
253 | 0 | dst_cnt--; |
254 | 0 | } |
255 | 116 | } |
256 | 40 | else |
257 | 40 | { |
258 | 40 | pu1_dst[dst_cnt++] = u1_src; |
259 | 40 | } |
260 | | |
261 | | |
262 | 156 | } |
263 | 12.8k | *pi4_nal_len = src_cnt; |
264 | 12.8k | *pi4_dst_len = dst_cnt; |
265 | 12.8k | return ret; |
266 | 12.8k | } |
267 | | /** |
268 | | ******************************************************************************* |
269 | | * |
270 | | * @brief |
271 | | * Decode given NAL unit's header |
272 | | * |
273 | | * @par Description: |
274 | | * Call NAL unit's header decode Section: 7.3.1.2 |
275 | | * |
276 | | * @param[in] ps_bitstrm |
277 | | * Pointer to bitstream context |
278 | | * |
279 | | * @param[out] ps_nal |
280 | | * Pointer to NAL header |
281 | | * |
282 | | * @returns Error code from IHEVCD_ERROR_T |
283 | | * |
284 | | * @remarks |
285 | | * |
286 | | * |
287 | | ******************************************************************************* |
288 | | */ |
289 | | IHEVCD_ERROR_T ihevcd_nal_unit_header(bitstrm_t *ps_bitstrm, nal_header_t *ps_nal) |
290 | 12.8k | { |
291 | 12.8k | WORD32 unused; |
292 | 12.8k | IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; |
293 | 12.8k | UNUSED(unused); |
294 | | /* Syntax : forbidden_zero_bit */ |
295 | 12.8k | unused = ihevcd_bits_get(ps_bitstrm, 1); |
296 | | |
297 | | /* Syntax : nal_unit_type */ |
298 | 12.8k | ps_nal->i1_nal_unit_type = ihevcd_bits_get(ps_bitstrm, 6); |
299 | | |
300 | | /* Syntax : nuh_reserved_zero_6bits */ |
301 | 12.8k | unused = ihevcd_bits_get(ps_bitstrm, 6); |
302 | | |
303 | | /* Syntax : nuh_temporal_id_plus1 */ |
304 | 12.8k | ps_nal->i1_nuh_temporal_id = (WORD32)ihevcd_bits_get(ps_bitstrm, 3) - 1; |
305 | | |
306 | 12.8k | return ret; |
307 | | |
308 | 12.8k | } |
309 | | |
310 | | /** |
311 | | ******************************************************************************* |
312 | | * |
313 | | * @brief |
314 | | * Decode given NAL |
315 | | * |
316 | | * @par Description: |
317 | | * Based on the NAL type call appropriate decode function Section: 7.3.1.1 |
318 | | * |
319 | | * |
320 | | * @param[in,out] ps_codec |
321 | | * Pointer to codec context (Functions called within will modify contents of |
322 | | * ps_codec) |
323 | | * |
324 | | * @returns Error code from IHEVCD_ERROR_T |
325 | | * |
326 | | * @remarks |
327 | | * |
328 | | * |
329 | | ******************************************************************************* |
330 | | */ |
331 | | IHEVCD_ERROR_T ihevcd_nal_unit(codec_t *ps_codec) |
332 | 12.8k | { |
333 | 12.8k | IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; |
334 | | |
335 | | /* NAL Header */ |
336 | 12.8k | nal_header_t s_nal; |
337 | | |
338 | 12.8k | ret = ihevcd_nal_unit_header(&ps_codec->s_parse.s_bitstrm, &s_nal); |
339 | 12.8k | RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); |
340 | | |
341 | 12.8k | if(ps_codec->i4_slice_error) |
342 | 240 | s_nal.i1_nal_unit_type = ps_codec->s_parse.ps_slice_hdr->i1_nal_unit_type; |
343 | | |
344 | | /* Setting RASL Output flag */ |
345 | 12.8k | switch(s_nal.i1_nal_unit_type) |
346 | 12.8k | { |
347 | 8 | case NAL_BLA_W_LP : |
348 | 161 | case NAL_BLA_W_DLP : |
349 | 781 | case NAL_BLA_N_LP : |
350 | 781 | ps_codec->i4_rasl_output_flag = 0; |
351 | 781 | break; |
352 | | |
353 | | //TODO: After IDR, there is no case of open GOP |
354 | | //To be fixed appropriately by ignoring RASL only if the |
355 | | // required references are not found |
356 | 752 | case NAL_IDR_W_LP : |
357 | 1.21k | case NAL_IDR_N_LP : |
358 | 1.21k | ps_codec->i4_rasl_output_flag = 1; |
359 | 1.21k | break; |
360 | | |
361 | 95 | case NAL_CRA : |
362 | 95 | ps_codec->i4_rasl_output_flag = (0 != ps_codec->i4_cra_as_first_pic) ? 0 : 1; |
363 | 95 | break; |
364 | | |
365 | 10.7k | default: |
366 | 10.7k | break; |
367 | 12.8k | } |
368 | | |
369 | 12.8k | switch(s_nal.i1_nal_unit_type) |
370 | 12.8k | { |
371 | 8 | case NAL_BLA_W_LP : |
372 | 161 | case NAL_BLA_W_DLP : |
373 | 781 | case NAL_BLA_N_LP : |
374 | 1.53k | case NAL_IDR_W_LP : |
375 | 1.99k | case NAL_IDR_N_LP : |
376 | 2.08k | case NAL_CRA : |
377 | 5.72k | case NAL_TRAIL_N : |
378 | 8.01k | case NAL_TRAIL_R : |
379 | 8.77k | case NAL_TSA_N : |
380 | 9.00k | case NAL_TSA_R : |
381 | 9.03k | case NAL_STSA_N : |
382 | 9.25k | case NAL_STSA_R : |
383 | 9.29k | case NAL_RADL_N : |
384 | 9.30k | case NAL_RADL_R : |
385 | 9.54k | case NAL_RASL_N : |
386 | 9.71k | case NAL_RASL_R : |
387 | 9.71k | if(ps_codec->i4_header_mode) |
388 | 1.31k | return IHEVCD_SLICE_IN_HEADER_MODE; |
389 | | |
390 | 8.39k | if((0 == ps_codec->i4_sps_done) || |
391 | 8.39k | (0 == ps_codec->i4_pps_done)) |
392 | 369 | { |
393 | 369 | return IHEVCD_INVALID_HEADER; |
394 | 369 | } |
395 | | |
396 | 8.02k | ps_codec->i4_header_in_slice_mode = 0; |
397 | 8.02k | ps_codec->i4_cra_as_first_pic = 0; |
398 | | |
399 | 8.02k | ret = ihevcd_parse_slice_header(ps_codec, &s_nal); |
400 | 8.02k | DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); |
401 | 8.02k | if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) |
402 | 5.13k | { |
403 | 5.13k | if((s_nal.i1_nal_unit_type != NAL_RASL_N && s_nal.i1_nal_unit_type != NAL_RASL_R) || |
404 | 5.13k | ps_codec->i4_rasl_output_flag || |
405 | 5.13k | ps_codec->i4_slice_error) |
406 | 5.13k | ret = ihevcd_parse_slice_data(ps_codec); |
407 | 5.13k | } |
408 | 8.02k | break; |
409 | | |
410 | 122 | case NAL_VPS : |
411 | | // ret = ihevcd_parse_vps(ps_codec); |
412 | 122 | DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); |
413 | 122 | break; |
414 | | |
415 | 939 | case NAL_SPS : |
416 | 939 | if(0 == ps_codec->i4_header_mode) |
417 | 709 | { |
418 | 709 | ps_codec->i4_header_in_slice_mode = 1; |
419 | 709 | if(ps_codec->i4_sps_done && |
420 | 709 | ps_codec->i4_pic_present) |
421 | 70 | break; |
422 | 709 | } |
423 | | |
424 | 869 | ret = ihevcd_parse_sps(ps_codec); |
425 | 869 | if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) |
426 | 179 | { |
427 | 179 | sps_t *ps_sps = ps_codec->ps_sps_base + MAX_SPS_CNT - 1; |
428 | 179 | ihevcd_copy_sps(ps_codec, ps_sps->i1_sps_id, MAX_SPS_CNT - 1); |
429 | 179 | } |
430 | 869 | ps_codec->i4_error_code = ret; |
431 | | |
432 | 869 | DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); |
433 | 869 | break; |
434 | | |
435 | 756 | case NAL_PPS : |
436 | 756 | if(0 == ps_codec->i4_header_mode) |
437 | 674 | { |
438 | 674 | ps_codec->i4_header_in_slice_mode = 1; |
439 | 674 | if(ps_codec->i4_pps_done && |
440 | 674 | ps_codec->i4_pic_present) |
441 | 58 | break; |
442 | 674 | } |
443 | | |
444 | 698 | ret = ihevcd_parse_pps(ps_codec); |
445 | 698 | if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) |
446 | 372 | { |
447 | 372 | pps_t *ps_pps = ps_codec->ps_pps_base + MAX_PPS_CNT - 1; |
448 | 372 | ihevcd_copy_pps(ps_codec, ps_pps->i1_pps_id, MAX_PPS_CNT - 1); |
449 | 372 | } |
450 | 698 | ps_codec->i4_error_code = ret; |
451 | 698 | DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); |
452 | 698 | break; |
453 | | |
454 | 0 | #ifndef DISABLE_SEI |
455 | 161 | case NAL_PREFIX_SEI: |
456 | 591 | case NAL_SUFFIX_SEI: |
457 | 591 | if(IVD_DECODE_HEADER == ps_codec->i4_header_mode) |
458 | 54 | { |
459 | 54 | return IHEVCD_SLICE_IN_HEADER_MODE; |
460 | 54 | } |
461 | | |
462 | 537 | ret = ihevcd_parse_sei(ps_codec, &s_nal); |
463 | 537 | break; |
464 | | |
465 | 0 | #endif |
466 | 33 | case NAL_EOS : |
467 | 33 | ps_codec->i4_cra_as_first_pic = 1; |
468 | 33 | break; |
469 | | |
470 | 686 | default: |
471 | 686 | DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); |
472 | 686 | break; |
473 | 12.8k | } |
474 | | |
475 | 11.0k | return ret; |
476 | 12.8k | } |
477 | | |