You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
393 lines
11 KiB
393 lines
11 KiB
/****************************************************************************** |
|
* |
|
* Copyright (C) 2015 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at: |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
***************************************************************************** |
|
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
|
*/ |
|
/*! |
|
************************************************************************** |
|
* \file ih264d_nal.c |
|
* |
|
* \brief NAL parsing routines |
|
* |
|
* Detailed_description |
|
* |
|
* \author |
|
* - AI 19 11 2002 Creation |
|
************************************************************************** |
|
*/ |
|
#include "ih264d_bitstrm.h" |
|
#include "ih264d_defs.h" |
|
#include "ih264_typedefs.h" |
|
#include "ih264_macros.h" |
|
#include "ih264_platform_macros.h" |
|
#include "ih264d_defs.h" |
|
#define NUM_OF_ZERO_BYTES_BEFORE_START_CODE 2 |
|
#define EMULATION_PREVENTION_BYTE 0x03 |
|
|
|
#define NAL_FIRST_BYTE_SIZE 1 |
|
|
|
/*! |
|
************************************************************************** |
|
* \if Function name : ih264d_find_start_code \endif |
|
* |
|
* \brief |
|
* This function searches for the Start Code Prefix. |
|
* |
|
* \param pu1_buf : Pointer to char buffer which contains bitstream. |
|
* \param u4_cur_pos : Current position in the buffer. |
|
* \param u4_max_ofst : Number of bytes in Buffer. |
|
* \param pu4_length_of_start_code : Poiter to length of Start Code. |
|
* |
|
* \return |
|
* Returns 0 on success and -1 on error. |
|
* |
|
************************************************************************** |
|
*/ |
|
#define START_CODE_NOT_FOUND -1 |
|
#define END_OF_STREAM_BUFFER -2 |
|
#define END_OF_STREAM -1 |
|
|
|
void ih264d_check_if_aud(UWORD8 *pu1_buf, |
|
UWORD32 u4_cur_pos, |
|
UWORD32 u4_max_ofst, |
|
UWORD32 *pu4_next_is_aud) |
|
{ |
|
UWORD8 u1_first_byte, u1_nal_unit_type; |
|
if(u4_cur_pos + 1 < u4_max_ofst) |
|
{ |
|
u1_first_byte = pu1_buf[u4_cur_pos + 1]; |
|
u1_nal_unit_type = NAL_UNIT_TYPE(u1_first_byte); |
|
|
|
if(u1_nal_unit_type == ACCESS_UNIT_DELIMITER_RBSP) |
|
{ |
|
*pu4_next_is_aud = 1; |
|
} |
|
} |
|
|
|
} |
|
WORD32 ih264d_find_start_code(UWORD8 *pu1_buf, |
|
UWORD32 u4_cur_pos, |
|
UWORD32 u4_max_ofst, |
|
UWORD32 *pu4_length_of_start_code, |
|
UWORD32 *pu4_next_is_aud) |
|
{ |
|
WORD32 zero_byte_cnt = 0; |
|
UWORD32 ui_curPosTemp; |
|
|
|
*pu4_length_of_start_code = 0; |
|
/*Find first start code */ |
|
while(u4_cur_pos < u4_max_ofst) |
|
{ |
|
if(pu1_buf[u4_cur_pos] == 0) |
|
zero_byte_cnt++; |
|
else if(pu1_buf[u4_cur_pos] |
|
== 0x01 && zero_byte_cnt >= NUM_OF_ZERO_BYTES_BEFORE_START_CODE) |
|
{ |
|
/* Found the start code */ |
|
u4_cur_pos++; |
|
break; |
|
} |
|
else |
|
{ |
|
zero_byte_cnt = 0; |
|
} |
|
u4_cur_pos++; |
|
} |
|
/*Find Next Start Code */ |
|
*pu4_length_of_start_code = u4_cur_pos; |
|
zero_byte_cnt = 0; |
|
ui_curPosTemp = u4_cur_pos; |
|
while(u4_cur_pos < u4_max_ofst) |
|
{ |
|
|
|
if(pu1_buf[u4_cur_pos] == 0) |
|
zero_byte_cnt++; |
|
else if(pu1_buf[u4_cur_pos] |
|
== 0x01 && zero_byte_cnt >= NUM_OF_ZERO_BYTES_BEFORE_START_CODE) |
|
{ |
|
/* Found the start code */ |
|
ih264d_check_if_aud(pu1_buf, u4_cur_pos, u4_max_ofst, |
|
pu4_next_is_aud); |
|
return (u4_cur_pos - zero_byte_cnt - ui_curPosTemp); |
|
} |
|
else |
|
{ |
|
zero_byte_cnt = 0; |
|
} |
|
u4_cur_pos++; |
|
} |
|
|
|
return (u4_cur_pos - zero_byte_cnt - ui_curPosTemp); //(START_CODE_NOT_FOUND); |
|
} |
|
|
|
/*! |
|
************************************************************************** |
|
* \if Function name : ih264d_get_next_nal_unit \endif |
|
* |
|
* \brief |
|
* This function reads one NAl unit. |
|
* |
|
* \param ps_nalStream : Poiter to NalUnitStream structure. |
|
* \param ps_nalUnit : Pointer to NalUnit. |
|
* |
|
* \return |
|
* Returns 0 on success and -1 on error. |
|
* |
|
************************************************************************** |
|
*/ |
|
WORD32 ih264d_get_next_nal_unit(UWORD8 *pu1_buf, |
|
UWORD32 u4_cur_pos, |
|
UWORD32 u4_max_ofst, |
|
UWORD32 *pu4_length_of_start_code) |
|
{ |
|
|
|
WORD32 i_length_of_nal_unit = 0; |
|
UWORD32 u4_next_is_aud; |
|
|
|
/* NAL Thread starts */ |
|
|
|
ih264d_find_start_code(pu1_buf, u4_cur_pos, u4_max_ofst, |
|
pu4_length_of_start_code, &u4_next_is_aud); |
|
|
|
return (i_length_of_nal_unit); |
|
} |
|
|
|
/*! |
|
************************************************************************** |
|
* \if Function name : ih264d_process_nal_unit \endif |
|
* |
|
* \brief |
|
* This function removes emulation byte "0x03" from bitstream (EBSP to RBSP). |
|
* It also converts bytestream format into 32 bit little-endian format. |
|
* |
|
* \param ps_bitstrm : Poiter to dec_bit_stream_t structure. |
|
* \param pu1_nal_unit : Pointer to char buffer of NalUnit. |
|
* \param u4_numbytes_in_nal_unit : Number bytes in NalUnit buffer. |
|
* |
|
* \return |
|
* Returns number of bytes in RBSP ps_bitstrm. |
|
* |
|
* \note |
|
* This function is same as nal_unit() of 7.3.1. Apart from nal_unit() |
|
* implementation it converts char buffer into 32 bit Buffer. This |
|
* facilitates efficient access of bitstream. This has been done taking |
|
* into account present processor architectures. |
|
* |
|
************************************************************************** |
|
*/ |
|
WORD32 ih264d_process_nal_unit(dec_bit_stream_t *ps_bitstrm, |
|
UWORD8 *pu1_nal_unit, |
|
UWORD32 u4_numbytes_in_nal_unit) |
|
{ |
|
UWORD32 u4_num_bytes_in_rbsp; |
|
UWORD8 u1_cur_byte; |
|
WORD32 i = 0; |
|
WORD8 c_count; |
|
UWORD32 ui_word; |
|
UWORD32 *puc_bitstream_buffer = (UWORD32*)pu1_nal_unit; |
|
ps_bitstrm->pu4_buffer = puc_bitstream_buffer; |
|
|
|
/*--------------------------------------------------------------------*/ |
|
/* First Byte of the NAL Unit */ |
|
/*--------------------------------------------------------------------*/ |
|
|
|
ui_word = *pu1_nal_unit++; |
|
|
|
/*--------------------------------------------------------------------*/ |
|
/* Convertion of the EBSP to RBSP */ |
|
/* ie Remove the emulation_prevention_byte [equal to 0x03] */ |
|
/*--------------------------------------------------------------------*/ |
|
u4_num_bytes_in_rbsp = 0; |
|
c_count = 0; |
|
|
|
//first iteration |
|
|
|
u1_cur_byte = *pu1_nal_unit++; |
|
|
|
ui_word = ((ui_word << 8) | u1_cur_byte); |
|
|
|
c_count++; |
|
if(u1_cur_byte != 0x00) |
|
c_count = 0; |
|
|
|
//second iteration |
|
|
|
u1_cur_byte = *pu1_nal_unit++; |
|
|
|
ui_word = ((ui_word << 8) | u1_cur_byte); |
|
u4_num_bytes_in_rbsp = 2; |
|
|
|
c_count++; |
|
if(u1_cur_byte != 0x00) |
|
c_count = 0; |
|
|
|
if(u4_numbytes_in_nal_unit > 2) |
|
{ |
|
i = ((u4_numbytes_in_nal_unit - 3)); |
|
} |
|
|
|
for(; i > 8; i -= 4) |
|
{ |
|
|
|
// loop 0 |
|
u1_cur_byte = *pu1_nal_unit++; |
|
|
|
if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE |
|
&& u1_cur_byte == EMULATION_PREVENTION_BYTE) |
|
{ |
|
c_count = 0; |
|
u1_cur_byte = *pu1_nal_unit++; |
|
i--; |
|
} |
|
|
|
ui_word = ((ui_word << 8) | u1_cur_byte); |
|
*puc_bitstream_buffer = ui_word; |
|
puc_bitstream_buffer++; |
|
c_count++; |
|
if(u1_cur_byte != 0x00) |
|
c_count = 0; |
|
|
|
// loop 1 |
|
u1_cur_byte = *pu1_nal_unit++; |
|
|
|
if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE |
|
&& u1_cur_byte == EMULATION_PREVENTION_BYTE) |
|
{ |
|
c_count = 0; |
|
u1_cur_byte = *pu1_nal_unit++; |
|
i--; |
|
} |
|
ui_word = ((ui_word << 8) | u1_cur_byte); |
|
|
|
c_count++; |
|
if(u1_cur_byte != 0x00) |
|
c_count = 0; |
|
|
|
// loop 2 |
|
u1_cur_byte = *pu1_nal_unit++; |
|
|
|
if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE |
|
&& u1_cur_byte == EMULATION_PREVENTION_BYTE) |
|
{ |
|
c_count = 0; |
|
u1_cur_byte = *pu1_nal_unit++; |
|
i--; |
|
} |
|
|
|
ui_word = ((ui_word << 8) | u1_cur_byte); |
|
|
|
c_count++; |
|
if(u1_cur_byte != 0x00) |
|
c_count = 0; |
|
|
|
// loop 3 |
|
u1_cur_byte = *pu1_nal_unit++; |
|
|
|
if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE |
|
&& u1_cur_byte == EMULATION_PREVENTION_BYTE) |
|
{ |
|
c_count = 0; |
|
u1_cur_byte = *pu1_nal_unit++; |
|
i--; |
|
} |
|
|
|
ui_word = ((ui_word << 8) | u1_cur_byte); |
|
|
|
c_count++; |
|
if(u1_cur_byte != 0x00) |
|
c_count = 0; |
|
|
|
u4_num_bytes_in_rbsp += 4; |
|
|
|
} |
|
|
|
for(; i > 0; i--) |
|
{ |
|
u1_cur_byte = *pu1_nal_unit++; |
|
|
|
if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE |
|
&& u1_cur_byte == EMULATION_PREVENTION_BYTE) |
|
{ |
|
c_count = 0; |
|
i--; |
|
u1_cur_byte = *pu1_nal_unit++; |
|
} |
|
|
|
ui_word = ((ui_word << 8) | u1_cur_byte); |
|
u4_num_bytes_in_rbsp++; |
|
|
|
if((u4_num_bytes_in_rbsp & 0x03) == 0x03) |
|
{ |
|
*puc_bitstream_buffer = ui_word; |
|
puc_bitstream_buffer++; |
|
} |
|
c_count++; |
|
if(u1_cur_byte != 0x00) |
|
c_count = 0; |
|
|
|
} |
|
|
|
*puc_bitstream_buffer = (ui_word |
|
<< ((3 - (((u4_num_bytes_in_rbsp << 30) >> 30))) << 3)); |
|
ps_bitstrm->u4_ofst = 0; |
|
ps_bitstrm->u4_max_ofst = ((u4_num_bytes_in_rbsp + NAL_FIRST_BYTE_SIZE) << 3); |
|
|
|
return (u4_num_bytes_in_rbsp); |
|
} |
|
|
|
|
|
/*! |
|
************************************************************************** |
|
* \if Function name : ih264d_rbsp_to_sodb \endif |
|
* |
|
* \brief |
|
* This function converts RBSP to SODB. |
|
* |
|
* \param ps_bitstrm : Poiter to dec_bit_stream_t structure. |
|
* |
|
* \return |
|
* None. |
|
* |
|
************************************************************************** |
|
*/ |
|
void ih264d_rbsp_to_sodb(dec_bit_stream_t *ps_bitstrm) |
|
{ |
|
UWORD32 ui_lastWord; |
|
UWORD32 ui_word; |
|
UWORD8 uc_lastByte; |
|
WORD8 i; |
|
|
|
ui_lastWord = (ps_bitstrm->u4_max_ofst >> 5); |
|
i = (ps_bitstrm->u4_max_ofst >> 3) & 0x03; |
|
|
|
if(i) |
|
{ |
|
ui_word = ps_bitstrm->pu4_buffer[ui_lastWord]; |
|
uc_lastByte = ((ui_word << ((i - 1) << 3)) >> 24); |
|
} |
|
else |
|
{ |
|
ui_word = ps_bitstrm->pu4_buffer[ui_lastWord - 1]; |
|
uc_lastByte = ((ui_word << 24) >> 24); |
|
} |
|
/*--------------------------------------------------------------------*/ |
|
/* Find out the rbsp_stop_bit position in the last byte of rbsp */ |
|
/*--------------------------------------------------------------------*/ |
|
for(i = 0; (i < 8) && !CHECKBIT(uc_lastByte, i); ++i) |
|
; |
|
ps_bitstrm->u4_max_ofst = ps_bitstrm->u4_max_ofst - (i + 1); |
|
}
|
|
|