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((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 */ 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 */ 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 */ 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