/* /////////////////////////////////////////////////////////////////////// | |
// | |
// INTEL CORPORATION PROPRIETARY INFORMATION | |
// This software is supplied under the terms of a license agreement or | |
// nondisclosure agreement with Intel Corporation and may not be copied | |
// or disclosed except in accordance with the terms of that agreement. | |
// Copyright (c) 2001-2006 Intel Corporation. All Rights Reserved. | |
// | |
// Description: h264 bistream decoding | |
// | |
///////////////////////////////////////////////////////////////////////*/ | |
#include "h264.h" | |
#include "h264parse.h" | |
#include "viddec_parser_ops.h" | |
/** | |
get_codeNum :Get codenum based on sec 9.1 of H264 spec. | |
@param cxt : Buffer adress & size are part inputs, the cxt is updated | |
with codeNum & sign on sucess. | |
Assumption: codeNum is a max of 32 bits | |
@retval 1 : Sucessfuly found a code num, cxt is updated with codeNum, sign, and size of code. | |
@retval 0 : Couldn't find a code in the current buffer. | |
be freed. | |
*/ | |
uint32_t h264_get_codeNum(void *parent, h264_Info* pInfo) | |
{ | |
int32_t leadingZeroBits= 0; | |
uint32_t temp = 0, match = 0, noOfBits = 0, count = 0; | |
uint32_t codeNum =0; | |
uint32_t bits_offset =0, byte_offset =0; | |
uint8_t is_emul =0; | |
uint8_t is_first_byte = 1; | |
uint32_t length =0; | |
uint32_t bits_need_add_in_first_byte =0; | |
int32_t bits_operation_result=0; | |
//remove warning | |
pInfo = pInfo; | |
////// Step 1: parse through zero bits until we find a bit with value 1. | |
viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul); | |
while(!match) | |
{ | |
if ((bits_offset != 0) && ( is_first_byte == 1)) | |
{ | |
//we handle byte at a time, if we have offset then for first | |
// byte handle only 8 - offset bits | |
noOfBits = (uint8_t)(8 - bits_offset); | |
bits_operation_result = viddec_pm_peek_bits(parent, &temp, noOfBits); | |
temp = (temp << bits_offset); | |
if(temp!=0) | |
{ | |
bits_need_add_in_first_byte = bits_offset; | |
} | |
is_first_byte =0; | |
} | |
else | |
{ | |
noOfBits = 8;/* always 8 bits as we read a byte at a time */ | |
bits_operation_result = viddec_pm_peek_bits(parent, &temp, 8); | |
} | |
if(-1==bits_operation_result) | |
{ | |
return MAX_INT32_VALUE; | |
} | |
if(temp != 0) | |
{ | |
// if byte!=0 we have at least one bit with value 1. | |
count=1; | |
while(((temp & 0x80) != 0x80) && (count <= noOfBits)) | |
{ | |
count++; | |
temp = temp <<1; | |
} | |
//At this point we get the bit position of 1 in current byte(count). | |
match = 1; | |
leadingZeroBits += count; | |
} | |
else | |
{ | |
// we don't have a 1 in current byte | |
leadingZeroBits += noOfBits; | |
} | |
if(!match) | |
{ | |
//actually move the bitoff by viddec_pm_get_bits | |
viddec_pm_get_bits(parent, &temp, noOfBits); | |
} | |
else | |
{ | |
//actually move the bitoff by viddec_pm_get_bits | |
viddec_pm_get_bits(parent, &temp, count); | |
} | |
} | |
////// step 2: Now read the next (leadingZeroBits-1) bits to get the encoded value. | |
if(match) | |
{ | |
viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul); | |
/* bit position in current byte */ | |
//count = (uint8_t)((leadingZeroBits + bits_offset)& 0x7); | |
count = ((count + bits_need_add_in_first_byte)& 0x7); | |
leadingZeroBits --; | |
length = leadingZeroBits; | |
codeNum = 0; | |
noOfBits = 8 - count; | |
while(leadingZeroBits > 0) | |
{ | |
if(noOfBits < (uint32_t)leadingZeroBits) | |
{ | |
viddec_pm_get_bits(parent, &temp, noOfBits); | |
codeNum = (codeNum << noOfBits) | temp; | |
leadingZeroBits -= noOfBits; | |
} | |
else | |
{ | |
viddec_pm_get_bits(parent, &temp, leadingZeroBits); | |
codeNum = (codeNum << leadingZeroBits) | temp; | |
leadingZeroBits = 0; | |
} | |
noOfBits = 8; | |
} | |
// update codeNum = 2 ** (leadingZeroBits) -1 + read_bits(leadingZeroBits). | |
codeNum = codeNum + (1 << length) -1; | |
} | |
viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul); | |
if(bits_offset!=0) | |
{ | |
viddec_pm_peek_bits(parent, &temp, 8-bits_offset); | |
} | |
return codeNum; | |
} | |
/*---------------------------------------*/ | |
/*---------------------------------------*/ | |
int32_t h264_GetVLCElement(void *parent, h264_Info* pInfo, uint8_t bIsSigned) | |
{ | |
int32_t sval = 0; | |
signed char sign; | |
sval = h264_get_codeNum(parent , pInfo); | |
if(bIsSigned) //get signed integer golomb code else the value is unsigned | |
{ | |
sign = (sval & 0x1)?1:-1; | |
sval = (sval +1) >> 1; | |
sval = sval * sign; | |
} | |
return sval; | |
} // Ipp32s H264Bitstream::GetVLCElement(bool bIsSigned) | |
/// | |
/// Check whether more RBSP data left in current NAL | |
/// | |
uint8_t h264_More_RBSP_Data(void *parent, h264_Info * pInfo) | |
{ | |
uint8_t cnt = 0; | |
uint8_t is_emul =0; | |
uint8_t cur_byte = 0; | |
int32_t shift_bits =0; | |
uint32_t ctr_bit = 0; | |
uint32_t bits_offset =0, byte_offset =0; | |
//remove warning | |
pInfo = pInfo; | |
if (!viddec_pm_is_nomoredata(parent)) | |
return 1; | |
viddec_pm_get_au_pos(parent, &bits_offset, &byte_offset, &is_emul); | |
shift_bits = 7-bits_offset; | |
// read one byte | |
viddec_pm_get_cur_byte(parent, &cur_byte); | |
ctr_bit = ((cur_byte)>> (shift_bits--)) & 0x01; | |
// a stop bit has to be one | |
if (ctr_bit==0) | |
return 1; | |
while (shift_bits>=0 && !cnt) | |
{ | |
cnt |= (((cur_byte)>> (shift_bits--)) & 0x01); // set up control bit | |
} | |
return (cnt); | |
} | |
///////////// EOF///////////////////// | |