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 */
ihevcd_nal_search_start_code(UWORD8 * pu1_buf,WORD32 bytes_remaining)96 WORD32 ihevcd_nal_search_start_code(UWORD8 *pu1_buf, WORD32 bytes_remaining)
97 {
98 WORD32 ofst;
99
100 WORD32 zero_byte_cnt;
101 WORD32 start_code_found;
102
103 ofst = -1;
104
105 zero_byte_cnt = 0;
106 start_code_found = 0;
107 while(ofst < (bytes_remaining - 1))
108 {
109 ofst++;
110 if(pu1_buf[ofst] != 0)
111 {
112 zero_byte_cnt = 0;
113 continue;
114 }
115
116 zero_byte_cnt++;
117 if((pu1_buf[ofst + 1] == START_CODE_PREFIX_BYTE) &&
118 (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE))
119 {
120 /* Found the start code */
121 ofst++;
122 start_code_found = 1;
123 break;
124 }
125 }
126 if(0 == start_code_found)
127 {
128 if((START_CODE_PREFIX_BYTE == pu1_buf[ofst]) &&
129 (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE))
130 {
131 /* Found a start code at the end*/
132 ofst++;
133 }
134 }
135 /* Since ofst started at -1, increment it by 1 */
136 ofst++;
137
138 return ofst;
139 }
140
141 /**
142 *******************************************************************************
143 *
144 * @brief
145 * Remove emulation prevention byte present in the bitstream till next start
146 * code is found. Emulation prevention byte removed data is stored in a
147 * different buffer
148 *
149 * @par Description:
150 * Assumption is first start code is already found and pu1_buf is pointing
151 * to a byte after the start code Search for Next NAL's start code Return
152 * if start code is found Remove any emulation prevention byte present Copy
153 * data to new buffer If no start code is found, then treat complete buffer
154 * as one nal.
155 *
156 * @param[in] pu1_src
157 * Pointer to bitstream (excludes the initial the start code)
158 *
159 * @param[in] pu1_dst
160 * Pointer to destination buffer
161 *
162 * @param[in] bytes_remaining
163 * Number of bytes remaining
164 *
165 * @param[out] pi4_nal_len
166 * NAL length (length of bitstream parsed)
167 *
168 * @param[out] pi4_dst_len
169 * Destination bitstream size (length of bitstream parsed with emulation bytes
170 * removed)
171 *
172 * @returns Error code from IHEVCD_ERROR_T
173 *
174 * @remarks
175 * Incomplete start code at the end of input bitstream is not handled. This
176 * has to be taken care outside this func
177 *
178 *******************************************************************************
179 */
ihevcd_nal_remv_emuln_bytes(UWORD8 * pu1_src,UWORD8 * pu1_dst,WORD32 bytes_remaining,WORD32 * pi4_nal_len,WORD32 * pi4_dst_len)180 IHEVCD_ERROR_T ihevcd_nal_remv_emuln_bytes(UWORD8 *pu1_src,
181 UWORD8 *pu1_dst,
182 WORD32 bytes_remaining,
183 WORD32 *pi4_nal_len,
184 WORD32 *pi4_dst_len)
185 {
186 WORD32 src_cnt;
187 WORD32 dst_cnt;
188 WORD32 zero_byte_cnt;
189 WORD32 start_code_found;
190 UWORD8 u1_src;
191 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
192
193 src_cnt = 0;
194 dst_cnt = 0;
195 zero_byte_cnt = 0;
196 start_code_found = 0;
197 while(src_cnt < (bytes_remaining - 1))
198 {
199 u1_src = pu1_src[src_cnt++];
200
201 pu1_dst[dst_cnt++] = u1_src;
202 if(u1_src != 0)
203 {
204 zero_byte_cnt = 0;
205 continue;
206 }
207
208 zero_byte_cnt++;
209 if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)
210 {
211 u1_src = pu1_src[src_cnt];
212 if(START_CODE_PREFIX_BYTE == u1_src)
213 {
214 /* Found the start code */
215 src_cnt -= zero_byte_cnt;
216 dst_cnt -= zero_byte_cnt;
217 start_code_found = 1;
218 break;
219 }
220 else if(EMULATION_PREVENT_BYTE == u1_src)
221 {
222 /* Found the emulation prevention byte */
223 src_cnt++;
224 zero_byte_cnt = 0;
225
226 /* Decrement dst_cnt so that the next byte overwrites
227 * the emulation prevention byte already copied to dst above
228 */
229 }
230 }
231
232 }
233
234 if(0 == start_code_found)
235 {
236 u1_src = pu1_src[src_cnt++];
237 if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)
238 {
239
240 if(START_CODE_PREFIX_BYTE == u1_src)
241 {
242 /* Found a start code at the end*/
243 src_cnt -= zero_byte_cnt;
244 }
245 else if(EMULATION_PREVENT_BYTE == u1_src)
246 {
247 /* Found the emulation prevention byte at the end*/
248 src_cnt++;
249 /* Decrement dst_cnt so that the next byte overwrites
250 * the emulation prevention byte already copied to dst above
251 */
252 dst_cnt--;
253 }
254 }
255 else
256 {
257 pu1_dst[dst_cnt++] = u1_src;
258 }
259
260
261 }
262 *pi4_nal_len = src_cnt;
263 *pi4_dst_len = dst_cnt;
264 return ret;
265 }
266 /**
267 *******************************************************************************
268 *
269 * @brief
270 * Decode given NAL unit's header
271 *
272 * @par Description:
273 * Call NAL unit's header decode Section: 7.3.1.2
274 *
275 * @param[in] ps_bitstrm
276 * Pointer to bitstream context
277 *
278 * @param[out] ps_nal
279 * Pointer to NAL header
280 *
281 * @returns Error code from IHEVCD_ERROR_T
282 *
283 * @remarks
284 *
285 *
286 *******************************************************************************
287 */
ihevcd_nal_unit_header(bitstrm_t * ps_bitstrm,nal_header_t * ps_nal)288 IHEVCD_ERROR_T ihevcd_nal_unit_header(bitstrm_t *ps_bitstrm, nal_header_t *ps_nal)
289 {
290 WORD32 unused;
291 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
292 UNUSED(unused);
293 /* Syntax : forbidden_zero_bit */
294 unused = ihevcd_bits_get(ps_bitstrm, 1);
295
296 /* Syntax : nal_unit_type */
297 ps_nal->i1_nal_unit_type = ihevcd_bits_get(ps_bitstrm, 6);
298
299 /* Syntax : nuh_reserved_zero_6bits */
300 unused = ihevcd_bits_get(ps_bitstrm, 6);
301
302 /* Syntax : nuh_temporal_id_plus1 */
303 ps_nal->i1_nuh_temporal_id = ihevcd_bits_get(ps_bitstrm, 3) - 1;
304
305 return ret;
306
307 }
308
309 /**
310 *******************************************************************************
311 *
312 * @brief
313 * Decode given NAL
314 *
315 * @par Description:
316 * Based on the NAL type call appropriate decode function Section: 7.3.1.1
317 *
318 *
319 * @param[in,out] ps_codec
320 * Pointer to codec context (Functions called within will modify contents of
321 * ps_codec)
322 *
323 * @returns Error code from IHEVCD_ERROR_T
324 *
325 * @remarks
326 *
327 *
328 *******************************************************************************
329 */
ihevcd_nal_unit(codec_t * ps_codec)330 IHEVCD_ERROR_T ihevcd_nal_unit(codec_t *ps_codec)
331 {
332 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
333
334 /* NAL Header */
335 nal_header_t s_nal;
336
337 ret = ihevcd_nal_unit_header(&ps_codec->s_parse.s_bitstrm, &s_nal);
338 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
339
340 if(ps_codec->i4_slice_error)
341 s_nal.i1_nal_unit_type = ps_codec->s_parse.ps_slice_hdr->i1_nal_unit_type;
342
343 /* Setting RASL Output flag */
344 switch(s_nal.i1_nal_unit_type)
345 {
346 case NAL_BLA_W_LP :
347 case NAL_BLA_W_DLP :
348 case NAL_BLA_N_LP :
349 ps_codec->i4_rasl_output_flag = 0;
350 break;
351
352 //TODO: After IDR, there is no case of open GOP
353 //To be fixed appropriately by ignoring RASL only if the
354 // required references are not found
355 case NAL_IDR_W_LP :
356 case NAL_IDR_N_LP :
357 ps_codec->i4_rasl_output_flag = 1;
358 break;
359
360 case NAL_CRA :
361 ps_codec->i4_rasl_output_flag = (0 != ps_codec->i4_cra_as_first_pic) ? 0 : 1;
362 break;
363
364 default:
365 break;
366 }
367
368 switch(s_nal.i1_nal_unit_type)
369 {
370 case NAL_BLA_W_LP :
371 case NAL_BLA_W_DLP :
372 case NAL_BLA_N_LP :
373 case NAL_IDR_W_LP :
374 case NAL_IDR_N_LP :
375 case NAL_CRA :
376 case NAL_TRAIL_N :
377 case NAL_TRAIL_R :
378 case NAL_TSA_N :
379 case NAL_TSA_R :
380 case NAL_STSA_N :
381 case NAL_STSA_R :
382 case NAL_RADL_N :
383 case NAL_RADL_R :
384 case NAL_RASL_N :
385 case NAL_RASL_R :
386 if(ps_codec->i4_header_mode)
387 return IHEVCD_SLICE_IN_HEADER_MODE;
388
389 if((0 == ps_codec->i4_sps_done) ||
390 (0 == ps_codec->i4_pps_done))
391 {
392 return IHEVCD_INVALID_HEADER;
393 }
394
395 ps_codec->i4_header_in_slice_mode = 0;
396 ps_codec->i4_cra_as_first_pic = 0;
397
398 ret = ihevcd_parse_slice_header(ps_codec, &s_nal);
399 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
400 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
401 {
402 if((s_nal.i1_nal_unit_type != NAL_RASL_N && s_nal.i1_nal_unit_type != NAL_RASL_R) ||
403 ps_codec->i4_rasl_output_flag ||
404 ps_codec->i4_slice_error)
405 ret = ihevcd_parse_slice_data(ps_codec);
406 }
407 break;
408
409 case NAL_VPS :
410 // ret = ihevcd_parse_vps(ps_codec);
411 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
412 break;
413
414 case NAL_SPS :
415 if(0 == ps_codec->i4_header_mode)
416 {
417 ps_codec->i4_header_in_slice_mode = 1;
418 if(ps_codec->i4_sps_done &&
419 ps_codec->i4_pic_present)
420 break;
421 }
422
423 ret = ihevcd_parse_sps(ps_codec);
424 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
425 {
426 sps_t *ps_sps = ps_codec->ps_sps_base + MAX_SPS_CNT - 1;
427 ihevcd_copy_sps(ps_codec, ps_sps->i1_sps_id, MAX_SPS_CNT - 1);
428 }
429 ps_codec->i4_error_code = ret;
430
431 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
432 break;
433
434 case NAL_PPS :
435 if(0 == ps_codec->i4_header_mode)
436 {
437 ps_codec->i4_header_in_slice_mode = 1;
438 if(ps_codec->i4_pps_done &&
439 ps_codec->i4_pic_present)
440 break;
441 }
442
443 ret = ihevcd_parse_pps(ps_codec);
444 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
445 {
446 pps_t *ps_pps = ps_codec->ps_pps_base + MAX_PPS_CNT - 1;
447 ihevcd_copy_pps(ps_codec, ps_pps->i1_pps_id, MAX_PPS_CNT - 1);
448 }
449 ps_codec->i4_error_code = ret;
450 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
451 break;
452
453 case NAL_EOS :
454 ps_codec->i4_cra_as_first_pic = 1;
455 break;
456
457 default:
458 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type);
459 break;
460 }
461
462 return ret;
463 }
464
465