📄 umc_h264_dec_bitstream.cpp
字号:
{
m_pbs = (Ipp32u*)pb;
m_pbsBase = (Ipp32u*)pb;
m_bitOffset = offset;
m_maxBsSize = maxsize;
} // void H264Bitstream::Reset(Ipp8u * const pb, Ipp32s offset, const Ipp32u maxsize)
void H264Bitstream::RollbackCurrentNALU()
{
ippiUngetBits32(m_pbs,m_bitOffset);
}
// ---------------------------------------------------------------------------
// H264Bitstream::GetSCP()
// Determine if next bistream symbol is a start code. If not,
// do not change bitstream position and return false. If yes, advance
// bitstream position to first symbol following SCP and return true.
//
// A start code is:
// * next 2 bytes are zero
// * next non-zero byte is '01'
// * may include extra stuffing zero bytes
// ---------------------------------------------------------------------------
Ipp32s H264Bitstream::GetSCP()
{
Ipp32s code, code1,tmp;
Ipp32u* ptr_state = m_pbs;
Ipp32s bit_state = m_bitOffset;
VM_ASSERT(m_bitOffset >= 0 && m_bitOffset <= 31);
tmp = (m_bitOffset+1)%8;
if(tmp)
{
ippiGetNBits(m_pbs, m_bitOffset, tmp ,code);
if ((code << (8 - tmp)) & 0x7f) // most sig bit could be rbsp stop bit
{
m_pbs = ptr_state;
m_bitOffset = bit_state;
return 0; // not rbsp if following non-zero bits
}
}
else
{
Ipp32s remaining_bytes = (Ipp32s)m_maxBsSize - (Ipp32s) BytesDecoded();
if (remaining_bytes<1)
return -1; //signilizes end of buffer
ippiNextBits(m_pbs, m_bitOffset,8, code);
if (code == 0x80)
{
// skip past trailing RBSP stop bit
ippiGetBits8(m_pbs, m_bitOffset, code);
}
}
Ipp32s remaining_bytes = (Ipp32s)BytesLeft();
if (remaining_bytes<1)
return -1; //signilizes end of buffer
//ippiNextBits(m_pbs, m_bitOffset,8, code);
ippiGetBits8(m_pbs, m_bitOffset, code);
if(code != 0) {
m_pbs = ptr_state;
m_bitOffset = bit_state;
return 0;
}
if(remaining_bytes<2) {
return(-1);
}
ippiGetBits8(m_pbs, m_bitOffset, code1);
if (code1 != 0)
{
m_pbs = ptr_state;
m_bitOffset = bit_state;
return 0;
}
ippiGetBits8(m_pbs, m_bitOffset, code);
Ipp32s max_search_length = (Ipp32s)BytesLeft();
while (code == 0 && max_search_length-->0)
{
ippiGetBits8(m_pbs, m_bitOffset, code);
}
if (max_search_length<1)
return -1;
if (code != 1)
{
m_pbs = ptr_state;
m_bitOffset = bit_state;
return 0;
}
return 1;
} // H264Bitstream::GetSCP()
Status H264Bitstream::AdvanceToNextSCP()
{
// Search bitstream for next start code:
// 3 bytes: 0 0 1
Ipp32s max_search_length = (Ipp32s)(m_maxBsSize - (Ipp32u)(((Ipp8u *) m_pbs) - ((Ipp8u *) m_pbsBase)));
Ipp32u t1,t2,t3;
Ipp32s p;
if((m_bitOffset+1) % 8)
AlignPointerRight();
ippiGetBits8(m_pbs, m_bitOffset, t1);
ippiGetBits8(m_pbs, m_bitOffset, t2);
ippiGetBits8(m_pbs, m_bitOffset, t3);
for (p = 0; p < max_search_length - 2; p++)
{
if (t1==0 && t2==0 && t3==1)
{
ippiUngetNBits(m_pbs,m_bitOffset,24);
return UMC_OK;
}
t1=t2;
t2=t3;
ippiGetBits8(m_pbs, m_bitOffset, t3);
}
return UMC_ERR_INVALID_STREAM;
} // Status H264Bitstream::AdvanceToNextSCP()
bool H264Bitstream::More_RBSP_Data()
{
Ipp32s code, tmp;
Ipp32u* ptr_state = m_pbs;
Ipp32s bit_state = m_bitOffset;
VM_ASSERT(m_bitOffset >= 0 && m_bitOffset <= 31);
Ipp32s remaining_bytes = (Ipp32s)BytesLeft();
if (remaining_bytes <= 0)
return false;
// get top bit, it can be "rbsp stop" bit
ippiGetNBits(m_pbs, m_bitOffset, 1, code);
// get remain bits, which is less then byte
tmp = (m_bitOffset + 1) % 8;
if(tmp)
{
ippiGetNBits(m_pbs, m_bitOffset, tmp, code);
if ((code << (8 - tmp)) & 0x7f) // most sig bit could be rbsp stop bit
{
m_pbs = ptr_state;
m_bitOffset = bit_state;
// there are more data
return true;
}
}
remaining_bytes = (Ipp32s)BytesLeft();
// run through remain bytes
while (0 < remaining_bytes)
{
ippiGetBits8(m_pbs, m_bitOffset, code);
if (code)
{
m_pbs = ptr_state;
m_bitOffset = bit_state;
// there are more data
return true;
}
remaining_bytes -= 1;
}
return false;
}
// ---------------------------------------------------------------------------
// H264Bitstream::GetNALUnitType()
// Bitstream position is expected to be at the start of a NAL unit.
// Read and return NAL unit type and NAL storage idc.
// ---------------------------------------------------------------------------
Status H264Bitstream::GetNALUnitType( NAL_Unit_Type &uNALUnitType,Ipp8u &uNALStorageIDC)
{
Ipp32u code;
ippiGetBits8(m_pbs, m_bitOffset, code);
uNALStorageIDC = (Ipp8u)((code & NAL_STORAGE_IDC_BITS)>>5);
uNALUnitType = (NAL_Unit_Type)(code & NAL_UNITTYPE_BITS);
return UMC_OK;
} // GetNALUnitType
void H264Bitstream::GetScalingList4x4(H264ScalingList4x4 *scl, Ipp8u *def, Ipp8u *scl_type)
{
Ipp32u lastScale = 8;
Ipp32u nextScale = 8;
bool DefaultMatrix = false;
Ipp32s j;
for (j = 0; j < 16; j++ )
{
if (nextScale != 0)
{
Ipp32s delta_scale = GetVLCElement(true);
nextScale = ( lastScale + delta_scale + 256 ) & 0xff;
DefaultMatrix = ( j == 0 && nextScale == 0 );
}
scl->ScalingListCoeffs[ mp_scan4x4[0][j] ] = ( nextScale == 0 ) ? (Ipp8u)lastScale : (Ipp8u)nextScale;
lastScale = scl->ScalingListCoeffs[ mp_scan4x4[0][j] ];
}
if (!DefaultMatrix)
{
*scl_type=SCLREDEFINED;
return;
}
*scl_type= SCLDEFAULT;
FillScalingList4x4(scl,def);
return;
}
void H264Bitstream::GetScalingList8x8(H264ScalingList8x8 *scl, Ipp8u *def, Ipp8u *scl_type)
{
Ipp32u lastScale = 8;
Ipp32u nextScale = 8;
bool DefaultMatrix=false;
Ipp32s j;
for (j = 0; j < 64; j++ )
{
if (nextScale != 0)
{
Ipp32s delta_scale = GetVLCElement(true);
nextScale = ( lastScale + delta_scale + 256 ) & 0xff;
DefaultMatrix = ( j == 0 && nextScale == 0 );
}
scl->ScalingListCoeffs[ hp_scan8x8[0][j] ] = ( nextScale == 0 ) ? (Ipp8u)lastScale : (Ipp8u)nextScale;
lastScale = scl->ScalingListCoeffs[ hp_scan8x8[0][j] ];
}
if (!DefaultMatrix)
{
*scl_type=SCLREDEFINED;
return;
}
*scl_type= SCLDEFAULT;
FillScalingList8x8(scl,def);
return;
}
// ---------------------------------------------------------------------------
// H264Bitstream::GetSequenceParamSet()
// Read sequence parameter set data from bitstream.
// ---------------------------------------------------------------------------
Status H264Bitstream::GetSequenceParamSet(H264SeqParamSet *sps)
{
// Not all members of the seq param set structure are contained in all
// seq param sets. So start by init all to zero.
Status ps = UMC_OK;
ippsZero_8u((Ipp8u*)sps, sizeof (H264SeqParamSet));
// profile
// TBD: add rejection of unsupported profile
sps->profile_idc = (Ipp8u)GetBits(8);
switch (sps->profile_idc)
{
case H264VideoDecoderParams::H264_PROFILE_BASELINE:
case H264VideoDecoderParams::H264_PROFILE_MAIN:
case H264VideoDecoderParams::H264_PROFILE_EXTENDED:
case H264VideoDecoderParams::H264_PROFILE_HIGH:
case H264VideoDecoderParams::H264_PROFILE_HIGH10:
case H264VideoDecoderParams::H264_PROFILE_HIGH422:
case H264VideoDecoderParams::H264_PROFILE_HIGH444:
case H264VideoDecoderParams::H264_PROFILE_ADVANCED444_INTRA:
case H264VideoDecoderParams::H264_PROFILE_ADVANCED444:
break;
default:
return UMC_ERR_INVALID_STREAM;
}
sps->constrained_set0_flag = (Ipp8u)Get1Bit();
sps->constrained_set1_flag = (Ipp8u)Get1Bit();
sps->constrained_set2_flag = (Ipp8u)Get1Bit();
sps->constrained_set3_flag = (Ipp8u)Get1Bit();
// skip 4 zero bits
GetBits(4);
sps->level_idc = (Ipp8u)GetBits(8);
switch(sps->level_idc)
{
case H264VideoDecoderParams::H264_LEVEL_1:
case H264VideoDecoderParams::H264_LEVEL_11:
case H264VideoDecoderParams::H264_LEVEL_12:
case H264VideoDecoderParams::H264_LEVEL_13:
case H264VideoDecoderParams::H264_LEVEL_2:
case H264VideoDecoderParams::H264_LEVEL_21:
case H264VideoDecoderParams::H264_LEVEL_22:
case H264VideoDecoderParams::H264_LEVEL_3:
case H264VideoDecoderParams::H264_LEVEL_31:
case H264VideoDecoderParams::H264_LEVEL_32:
case H264VideoDecoderParams::H264_LEVEL_4:
case H264VideoDecoderParams::H264_LEVEL_41:
case H264VideoDecoderParams::H264_LEVEL_42:
case H264VideoDecoderParams::H264_LEVEL_5:
case H264VideoDecoderParams::H264_LEVEL_51:
break;
default:
return UMC_ERR_INVALID_STREAM;
}
// id
sps->seq_parameter_set_id = (Ipp8u)GetVLCElement(false);
if (sps->seq_parameter_set_id > MAX_NUM_SEQ_PARAM_SETS-1)
{
ps = UMC_ERR_INVALID_STREAM;
}
if((sps->profile_idc==100) || (sps->profile_idc==110) ||(sps->profile_idc==122) ||(sps->profile_idc==144))
{
sps->chroma_format_idc = (Ipp8u)GetVLCElement(false);
if (sps->chroma_format_idc==3)
{
sps->residual_colour_transform_flag = (Ipp8u) Get1Bit();
}
sps->bit_depth_luma = (Ipp8u)(GetVLCElement(false)+8);
sps->bit_depth_chroma = (Ipp8u)(GetVLCElement(false)+8);
VM_ASSERT(!sps->residual_colour_transform_flag);
if (sps->residual_colour_transform_flag == 1)
{
ps = UMC_ERR_UNSUPPORTED;
}
sps->qpprime_y_zero_transform_bypass_flag = (Ipp8u)Get1Bit();
sps->seq_scaling_matrix_present_flag = (Ipp8u)Get1Bit();
if(sps->seq_scaling_matrix_present_flag)
{
// 0
if(Get1Bit())
{
GetScalingList4x4(&sps->ScalingLists4x4[0],(Ipp8u*)default_intra_scaling_list4x4,&sps->type_of_scaling_list_used[0]);
}
else
{
FillScalingList4x4(&sps->ScalingLists4x4[0],(Ipp8u*) default_intra_scaling_list4x4);
sps->type_of_scaling_list_used[0] = SCLDEFAULT;
}
// 1
if(Get1Bit())
{
GetScalingList4x4(&sps->ScalingLists4x4[1],(Ipp8u*) default_intra_scaling_list4x4,&sps->type_of_scaling_list_used[1]);
}
else
{
FillScalingList4x4(&sps->ScalingLists4x4[1],(Ipp8u*) sps->ScalingLists4x4[0].ScalingListCoeffs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -