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*/ 96WORD32 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*/ 180IHEVCD_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*/ 288IHEVCD_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*/ 330IHEVCD_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->u4_pic_cnt) ? 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 397 ret = ihevcd_parse_slice_header(ps_codec, &s_nal); 398 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 399 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 400 { 401 if((s_nal.i1_nal_unit_type != NAL_RASL_N && s_nal.i1_nal_unit_type != NAL_RASL_R) || 402 ps_codec->i4_rasl_output_flag || 403 ps_codec->i4_slice_error) 404 ret = ihevcd_parse_slice_data(ps_codec); 405 } 406 break; 407 408 case NAL_VPS : 409 // ret = ihevcd_parse_vps(ps_codec); 410 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 411 break; 412 413 case NAL_SPS : 414 if(0 == ps_codec->i4_header_mode) 415 { 416 ps_codec->i4_header_in_slice_mode = 1; 417 if(ps_codec->i4_sps_done && 418 ps_codec->i4_pic_present) 419 break; 420 } 421 422 ret = ihevcd_parse_sps(ps_codec); 423 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 424 { 425 sps_t *ps_sps = ps_codec->ps_sps_base + MAX_SPS_CNT - 1; 426 ihevcd_copy_sps(ps_codec, ps_sps->i1_sps_id, MAX_SPS_CNT - 1); 427 } 428 429 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 430 break; 431 432 case NAL_PPS : 433 if(0 == ps_codec->i4_header_mode) 434 { 435 ps_codec->i4_header_in_slice_mode = 1; 436 if(ps_codec->i4_pps_done && 437 ps_codec->i4_pic_present) 438 break; 439 } 440 441 ret = ihevcd_parse_pps(ps_codec); 442 if(ret == (IHEVCD_ERROR_T)IHEVCD_SUCCESS) 443 { 444 pps_t *ps_pps = ps_codec->ps_pps_base + MAX_PPS_CNT - 1; 445 ihevcd_copy_pps(ps_codec, ps_pps->i1_pps_id, MAX_PPS_CNT - 1); 446 } 447 448 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 449 break; 450 451 default: 452 DEBUG_PRINT_NAL_INFO(ps_codec, s_nal.i1_nal_unit_type); 453 break; 454 } 455 456 return ret; 457} 458 459