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 { 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((ofst < (bytes_remaining - 1)) && 118 (pu1_buf[ofst + 1] == START_CODE_PREFIX_BYTE) && 119 (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)) 120 { 121 /* Found the start code */ 122 ofst++; 123 start_code_found = 1; 124 break; 125 } 126 } 127 if((0 == start_code_found) && (ofst < bytes_remaining)) 128 { 129 if((START_CODE_PREFIX_BYTE == pu1_buf[ofst]) && 130 (zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE)) 131 { 132 /* Found a start code at the end*/ 133 ofst++; 134 } 135 } 136 /* Since ofst started at -1, increment it by 1 */ 137 ofst++; 138 139 return ofst; 140 } 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 { 187 WORD32 src_cnt; 188 WORD32 dst_cnt; 189 WORD32 zero_byte_cnt; 190 WORD32 start_code_found; 191 UWORD8 u1_src; 192 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 193 194 src_cnt = 0; 195 dst_cnt = 0; 196 zero_byte_cnt = 0; 197 start_code_found = 0; 198 while(src_cnt < (bytes_remaining - 1)) 199 { 200 u1_src = pu1_src[src_cnt++]; 201 202 pu1_dst[dst_cnt++] = u1_src; 203 if(u1_src != 0) 204 { 205 zero_byte_cnt = 0; 206 continue; 207 } 208 209 zero_byte_cnt++; 210 if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE) 211 { 212 u1_src = pu1_src[src_cnt]; 213 if(START_CODE_PREFIX_BYTE == u1_src) 214 { 215 /* Found the start code */ 216 src_cnt -= zero_byte_cnt; 217 dst_cnt -= zero_byte_cnt; 218 start_code_found = 1; 219 break; 220 } 221 else if(EMULATION_PREVENT_BYTE == u1_src) 222 { 223 /* Found the emulation prevention byte */ 224 src_cnt++; 225 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 } 231 } 232 233 } 234 235 if((0 == start_code_found) && (src_cnt < bytes_remaining)) 236 { 237 u1_src = pu1_src[src_cnt++]; 238 if(zero_byte_cnt >= NUM_ZEROS_BEFORE_START_CODE) 239 { 240 241 if(START_CODE_PREFIX_BYTE == u1_src) 242 { 243 /* Found a start code at the end*/ 244 src_cnt -= zero_byte_cnt; 245 } 246 else if(EMULATION_PREVENT_BYTE == u1_src) 247 { 248 /* Found the emulation prevention byte at the end*/ 249 src_cnt++; 250 /* Decrement dst_cnt so that the next byte overwrites 251 * the emulation prevention byte already copied to dst above 252 */ 253 dst_cnt--; 254 } 255 } 256 else 257 { 258 pu1_dst[dst_cnt++] = u1_src; 259 } 260 261 262 } 263 *pi4_nal_len = src_cnt; 264 *pi4_dst_len = dst_cnt; 265 return ret; 266 } 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 { 291 WORD32 unused; 292 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 293 UNUSED(unused); 294 /* Syntax : forbidden_zero_bit */ 295 unused = ihevcd_bits_get(ps_bitstrm, 1); 296 297 /* Syntax : nal_unit_type */ 298 ps_nal->i1_nal_unit_type = ihevcd_bits_get(ps_bitstrm, 6); 299 300 /* Syntax : nuh_reserved_zero_6bits */ 301 unused = ihevcd_bits_get(ps_bitstrm, 6); 302 303 /* Syntax : nuh_temporal_id_plus1 */ 304 ps_nal->i1_nuh_temporal_id = ihevcd_bits_get(ps_bitstrm, 3) - 1; 305 306 return ret; 307 308 } 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 { 333 IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS; 334 335 /* NAL Header */ 336 nal_header_t s_nal; 337 338 ret = ihevcd_nal_unit_header(&ps_codec->s_parse.s_bitstrm, &s_nal); 339 RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret); 340 341 if(ps_codec->i4_slice_error) 342 s_nal.i1_nal_unit_type = ps_codec->s_parse.ps_slice_hdr->i1_nal_unit_type; 343 344 /* Setting RASL Output flag */ 345 switch(s_nal.i1_nal_unit_type) 346 { 347 case NAL_BLA_W_LP : 348 case NAL_BLA_W_DLP : 349 case NAL_BLA_N_LP : 350 ps_codec->i4_rasl_output_flag = 0; 351 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 case NAL_IDR_W_LP : 357 case NAL_IDR_N_LP : 358 ps_codec->i4_rasl_output_flag = 1; 359 break; 360 361 case NAL_CRA : 362 ps_codec->i4_rasl_output_flag = (0 != ps_codec->i4_cra_as_first_pic) ? 0 : 1; 363 break; 364 365 default: 366 break; 367 } 368 369 switch(s_nal.i1_nal_unit_type) 370 { 371 case NAL_BLA_W_LP : 372 case NAL_BLA_W_DLP : 373 case NAL_BLA_N_LP : 374 case NAL_IDR_W_LP : 375 case NAL_IDR_N_LP : 376 case NAL_CRA : 377 case NAL_TRAIL_N : 378 case NAL_TRAIL_R : 379 case NAL_TSA_N : 380 case NAL_TSA_R : 381 case NAL_STSA_N : 382 case NAL_STSA_R : 383 case NAL_RADL_N : 384 case NAL_RADL_R : 385 case NAL_RASL_N : 386 case NAL_RASL_R : 387 if(ps_codec->i4_header_mode) 388 return IHEVCD_SLICE_IN_HEADER_MODE; 389 390 if((0 == ps_codec->i4_sps_done) || 391 (0 == ps_codec->i4_pps_done)) 392 { 393 return IHEVCD_INVALID_HEADER; 394 } 395 396 ps_codec->i4_header_in_slice_mode = 0; 397 ps_codec->i4_cra_as_first_pic = 0; 398 399 ret = ihevcd_parse_slice_header(ps_codec, &s_nal); 400 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 401 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 402 { 403 if((s_nal.i1_nal_unit_type != NAL_RASL_N && s_nal.i1_nal_unit_type != NAL_RASL_R) || 404 ps_codec->i4_rasl_output_flag || 405 ps_codec->i4_slice_error) 406 ret = ihevcd_parse_slice_data(ps_codec); 407 } 408 break; 409 410 case NAL_VPS : 411 // ret = ihevcd_parse_vps(ps_codec); 412 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 413 break; 414 415 case NAL_SPS : 416 if(0 == ps_codec->i4_header_mode) 417 { 418 ps_codec->i4_header_in_slice_mode = 1; 419 if(ps_codec->i4_sps_done && 420 ps_codec->i4_pic_present) 421 break; 422 } 423 424 ret = ihevcd_parse_sps(ps_codec); 425 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 426 { 427 sps_t *ps_sps = ps_codec->ps_sps_base + MAX_SPS_CNT - 1; 428 ihevcd_copy_sps(ps_codec, ps_sps->i1_sps_id, MAX_SPS_CNT - 1); 429 } 430 ps_codec->i4_error_code = ret; 431 432 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 433 break; 434 435 case NAL_PPS : 436 if(0 == ps_codec->i4_header_mode) 437 { 438 ps_codec->i4_header_in_slice_mode = 1; 439 if(ps_codec->i4_pps_done && 440 ps_codec->i4_pic_present) 441 break; 442 } 443 444 ret = ihevcd_parse_pps(ps_codec); 445 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 446 { 447 pps_t *ps_pps = ps_codec->ps_pps_base + MAX_PPS_CNT - 1; 448 ihevcd_copy_pps(ps_codec, ps_pps->i1_pps_id, MAX_PPS_CNT - 1); 449 } 450 ps_codec->i4_error_code = ret; 451 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 452 break; 453 454 case NAL_PREFIX_SEI: 455 case NAL_SUFFIX_SEI: 456 if(IVD_DECODE_HEADER == ps_codec->i4_header_mode) 457 { 458 return IHEVCD_SLICE_IN_HEADER_MODE; 459 } 460 461 ret = ihevcd_parse_sei(ps_codec, &s_nal); 462 break; 463 464 case NAL_EOS : 465 ps_codec->i4_cra_as_first_pic = 1; 466 break; 467 468 default: 469 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 470 break; 471 } 472 473 return ret; 474 } 475 476