Date: 2018.9.10
#include
#include
#include
#include
#include
#include
#include "D264.h"
using namespace std;
int main(int argc, const char *argv[])
{
FILE *BitStream=NULL;
unsigned char *SPS_nalu;
unsigned char sps_profole_idc = 1;
int sps_width = 1;
int sps_height = 1;
size_t len = 24;
BitStream = fopen(argv[1], "rb");
SPS_nalu = (unsigned char*)malloc(len + 256);
fread(SPS_nalu, 1,len, BitStream);
//memcpy(SPS_nalu, BitStream, len);
if (argc < 2 || !BitStream)
{
cout << "error, please check the input!!!!!!!!!!!!!!!!!!!" << endl;
}
if (1/*((BitStream[4])&0x1f) == 0x7*/) //sps
{
cout << "AVC_sps_analysis :" << endl;
int videoW = -1;
int videoH = -1;
unsigned char profile_idc = -1;
cout << "videoH = " << videoH << endl;
cout << "videoW = " << videoW << endl;
cout << "profile_idc = " << profile_idc << endl;
D264_StartSlice(SPS_nalu, len, &videoW, &videoH, &profile_idc);
sps_profole_idc = profile_idc;
sps_width = videoW;
sps_height = videoH;
}
cout << "sps_profile_idc = " << sps_profole_idc << endl;
cout << "sps_width = " << sps_width << endl;
cout << "sps_height = " << sps_height << endl;
free(SPS_nalu);
SPS_nalu = NULL;
fclose(BitStream);
return 0;
}
int D264_BitstreamGetBs(BITSTREAM *bs,unsigned char *nalu_buf, signed int buf_len, NALU *nalu)
{
signed int start_code_len;
signed int nalu_len;
printf("%d %d %d %d \n", nalu_buf[0], nalu_buf[1], nalu_buf[2], nalu_buf[3] );
if(nalu_buf[0] == 0 && nalu_buf[1] == 0 && nalu_buf[2] == 0 && nalu_buf[3] == 1)
{
start_code_len = 4;
}
else if(nalu_buf[0] == 0 && nalu_buf[1] == 0 && nalu_buf[2] == 1)
{
start_code_len = 3;
}
else
{
start_code_len = 0;
}
// printf("start_code_len=%d\n", start_code_len);
nalu->nal_reference_idc = (nalu_buf[start_code_len]>>5) & 3;
nalu->nal_unit_type = (nalu_buf[start_code_len]) & 0x1f;
nalu_len = D264_EBSP_to_RBSP(nalu_buf, (unsigned char *)bs->pStart, buf_len, 1 + start_code_len);
bs->pStart = nalu_buf+1+start_code_len;
}
bs->nBsLength = D264_RBSP_to_SODB((unsigned char *)bs->pStart, nalu_len);
D264_DecBitstreamInit(bs,(unsigned char *)bs->pStart);
return ERR_OK;
}
int D264_StartSlice(uint8_t *nalu_buf,int32_t buf_len,int *pWidth,int *pHeight, uint8_t *pProfile_idc)
{
int ret;
BITSTREAM bs[1];// = &pEnc->m_bs;
NALU nalu;
int CurHdr;
unsigned char *pAlignBs = pBs+((BS_ALIGN_BYTE-((long)pBs)%8)&(BS_ALIGN_BYTE-1));
int bslen = buf_len > 256 ? 256 : buf_len;
memcpy(pAlignBs,nalu_buf,bslen);
if(bslen <= 0)
return ERR_FAIL;
ret = D264_BitstreamGetBs(bs, pAlignBs, bslen, &nalu);
if(ret != ERR_OK)
return ERR_FAIL;
CurHdr = D264_DecSliceHdr(bs, &nalu,pWidth,pHeight,pProfile_idc);
if(CurHdr != PARAM_ERR && CurHdr != NOT_SUPPORTED && CurHdr != ERR_FAIL)
{
if(CurHdr == END_XPS)
return ERR_OK;
}
else
{
return ERR_FAIL;
}
return ERR_OK;
}
int D264_RBSP_to_SODB(unsigned char *pStreamStart, int last_byte_pos)
{
int ctr_bit, bitoffset = 0;
//find trailing 1 bits
ctr_bit = (pStreamStart[last_byte_pos-1] & (0x01 << bitoffset));
while (ctr_bit == 0)
{
bitoffset++;
if(bitoffset == 8)
{
last_byte_pos -= 1;
bitoffset = 0;
}
ctr_bit = pStreamStart[last_byte_pos - 1] & (0x01 << (bitoffset));
}
return(last_byte_pos);
}
int D264_EBSP_to_RBSP(unsigned char *nalu_buf, unsigned char *bs_buffer, int end_bytepos, int begin_bytepos)
{
int i, j, count = 0;
int tmp;
int bFind03 = 0;
int trid;
if(end_bytepos < begin_bytepos)
{
return end_bytepos;
}
for(j = 0, i = begin_bytepos; i < end_bytepos; i++)
{
tmp = nalu_buf[i];
count = (tmp != 0x03 || count != ZEROBYTES_SHORTSTARTCODE) ? bs_buffer[j++] = tmp ,(!tmp ) * (count+1) : 0;
}
return j;
}
#endif
int D264_find_start_code (unsigned char *buf, int zeros_in_startcode)
{
int i;
int info;
info = 1;
for (i = 0; i < zeros_in_startcode; i++)
{
if(buf[i] != 0)
{
info = 0;
}
}
if(buf[i] != 1)
{
info = 0;
}
return info;
}
int D264_more_rbsp_data (unsigned char buffer[],int totbitoffset,int bytecount)
{
int ctr_bit, byteoffset, bitoffset;
// there is more until we're in the last byte
byteoffset = totbitoffset >> 3;
if (byteoffset < (bytecount-1))
{
return TRUE;
}
else if (byteoffset >= (bytecount))
{
return FALSE;
}
else
{
// read one bit
bitoffset = 7 - (totbitoffset & 7);
ctr_bit = (buffer[byteoffset] & (0x01 << bitoffset));
// a stop bit has to be one
if (ctr_bit == 0)
{
return TRUE;
}
else
{
bitoffset--;
while (bitoffset >= 0)
{
ctr_bit = (buffer[byteoffset] & (0x01 << bitoffset)); // set up control bit
if (ctr_bit > 0)
{
return TRUE;
}
bitoffset--;
}
return FALSE;
}
}
}
SPS解析函数:
signed int D264_interpret_SPS (BITSTREAM *bs, SEQ_PARAMETER_SET *sps,int *pWidth,int *pHeight)
{
signed int i;
signed int reserved_zero;
int tmp;
if(bs->pStart == NULL)
return 1;
if(sps == NULL)
return 1;
sps->profile_idc = D264_BitstreamGetBitsNotInline (bs,8);
sps->constrained_set0_flag = D264_BitstreamGetBitsNotInline(bs,1);
sps->constrained_set1_flag = D264_BitstreamGetBitsNotInline(bs,1);
sps->constrained_set2_flag = D264_BitstreamGetBitsNotInline(bs,1);
reserved_zero = D264_BitstreamGetBitsNotInline(bs,5);
// assert (reserved_zero == 0);
if(reserved_zero != 0)
return 1;
sps->level_idc = D264_BitstreamGetBitsNotInline(bs,8);
// if(sps->level_idc != 30)
// {
// printf("sorry! only level 2.0 is supported!\n");
// return 1;
// }
sps->seq_parameter_set_id = D264_ue_v (bs);
if((sps->profile_idc==FREXT_HP ) ||
(sps->profile_idc==FREXT_Hi10P) ||
(sps->profile_idc==FREXT_Hi422) ||
(sps->profile_idc==FREXT_Hi444))
{
sps->chroma_format_idc = D264_ue_v (bs);
// Residue Color Transform
if(sps->chroma_format_idc == 3)
sps->residue_transform_flag = D264_BitstreamGetBitsNotInline(bs,1);
sps->bit_depth_luma_minus8 = D264_ue_v (bs);
sps->bit_depth_chroma_minus8 = D264_ue_v (bs);
sps->lossless_qpprime_flag = D264_BitstreamGetBitsNotInline(bs,1);
sps->seq_scaling_matrix_present_flag = D264_BitstreamGetBitsNotInline(bs,1);
if(sps->seq_scaling_matrix_present_flag)
{
for(i=0; i<8; i++)
{
sps->seq_scaling_list_present_flag[i] = D264_BitstreamGetBitsNotInline(bs,1);
if(sps->seq_scaling_list_present_flag[i])
{
if(i<6)
Scaling_List(sps->ScalingList4x4[i], 16, &sps->UseDefaultScalingMatrix4x4Flag[i], bs);
else
Scaling_List(sps->ScalingList8x8[i-6], 64, &sps->UseDefaultScalingMatrix8x8Flag[i-6], bs);
}
}
}
}
sps->log2_max_frame_num_minus4 = D264_ue_v (bs);
sps->pic_order_cnt_type = D264_ue_v (bs);
if (sps->pic_order_cnt_type == 0)
{
sps->log2_max_pic_order_cnt_lsb_minus4 = D264_ue_v (bs);
}
else if (sps->pic_order_cnt_type == 1)
{
sps->delta_pic_order_always_zero_flag = D264_BitstreamGetBitsNotInline (bs,1);
sps->offset_for_non_ref_pic = D264_se_v (bs);
sps->offset_for_top_to_bottom_field = D264_se_v (bs);
sps->num_ref_frames_in_pic_order_cnt_cycle = D264_ue_v (bs);
for(i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
{
sps->offset_for_ref_frame[i] = D264_se_v (bs);
}
}
tmp = D264_ue_v (bs);
if(sps->num_ref_frames!= tmp)
sps->param_changed_flag = 1;
sps->num_ref_frames = tmp;
sps->gaps_in_frame_num_value_allowed_flag = D264_BitstreamGetBitsNotInline (bs,1);
tmp = D264_ue_v (bs);
if(sps->pic_width_in_mbs_minus1!= tmp)
sps->param_changed_flag = 1;
sps->pic_width_in_mbs_minus1 = tmp;
tmp = D264_ue_v (bs);
if(sps->pic_height_in_map_units_minus1!= tmp)
sps->param_changed_flag = 1;
sps->pic_height_in_map_units_minus1 = tmp;
*pWidth = sps->pic_width_in_mbs_minus1*16+16;
*pHeight = sps->pic_height_in_map_units_minus1*16+16;
if(*pHeight == 1088)
*pHeight = 1080;
sps->frame_mbs_only_flag = D264_BitstreamGetBitsNotInline (bs,1);
if (!sps->frame_mbs_only_flag)
{
sps->mb_adaptive_frame_field_flag = D264_BitstreamGetBitsNotInline (bs,1);
}
sps->direct_8x8_inference_flag = D264_BitstreamGetBitsNotInline (bs,1);
sps->frame_cropping_flag = D264_BitstreamGetBitsNotInline (bs,1);
if (sps->frame_cropping_flag)
{
sps->frame_cropping_rect_left_offset = D264_ue_v (bs);
sps->frame_cropping_rect_right_offset = D264_ue_v (bs);
sps->frame_cropping_rect_top_offset = D264_ue_v (bs);
sps->frame_cropping_rect_bottom_offset = D264_ue_v (bs);
}
sps->vui_parameters_present_flag = D264_BitstreamGetBitsNotInline (bs,1);
#ifdef _PRINT_DEBUG_INFO
if (sps->vui_parameters_present_flag)
{
printf ("VUI sequence parameters present but not supported, ignored\n");
}
#endif
sps->Valid = TRUE;
return 0;
}
/**/
signed int D264_process_SPS (BITSTREAM *bs,SEQ_PARAMETER_SET *tmp_sps,int *pWidth,int *pHeight)
{
if ( D264_interpret_SPS(bs, tmp_sps,pWidth,pHeight) != 0 )
{
return 1;
}
return 0;
}
signed int D264_DecSliceHdr(BITSTREAM *bs, NALU *nalu,int *pWidth,int *pHeight, unsigned char *pProfile_idc)
{
signed int old_max_dpb;
signed int re_status;
signed int current_header = 0;
signed int param_changed_flag = 0;
signed int old_width_in_mb;
signed int old_height_in_mb;
SEQ_PARAMETER_SET m_sps[1];
if(nalu->nal_unit_type == NALU_TYPE_SPS)
{
re_status = D264_process_SPS(bs, m_sps,pWidth,pHeight);
if ( 0 != re_status )
{
return PARAM_ERR;
}
else
{
*pProfile_idc = m_sps[0].profile_idc;
return END_XPS;
}
}
else
{
return PARAM_ERR;
}
}
码流VLC解析:
#include
#include "../inc/E264_vlc.h"
unsigned int bitc(unsigned short src)
{
int i;
int nBit = 0;
for(i=0;i<8;i++)
{
nBit += (((1<0);
}
return nBit;
}
unsigned int _bitc4(unsigned int src)
{
int result;
int i;
for(i=0;i<4;i++)
{
((unsigned char *)(&result))[i] = bitc(((unsigned char *)(&src))[i]);
}
return result;
}
unsigned int _swap4(unsigned int src)
{
int result = 0;
int i;
result = 0;
((unsigned char *)(&result))[0] = ((unsigned char *)(&src))[1];
((unsigned char *)(&result))[1] = ((unsigned char *)(&src))[0];
((unsigned char *)(&result))[2] = ((unsigned char *)(&src))[3];
((unsigned char *)(&result))[3] = ((unsigned char *)(&src))[2];
return result;
}
unsigned int _packlh2 (unsigned int src1, unsigned int src2)
{
unsigned int result;
((unsigned short *)(&result))[0] = ((unsigned short *)(&src2))[1];
((unsigned short *)(&result))[1] = ((unsigned short *)(&src1))[0];
return result;
}
_INLINE_ void D264_GetNal(BITSTREAM *bs,unsigned int iPrevData,unsigned int iData)
{
unsigned char* naluBuffer = bs->pCurrent-4;
int nBsLength = 0;
int i;
int count;
unsigned char *pStart = (unsigned char *)(&iData);
unsigned char data;
count = (!(iPrevData&0x000000ff)+!(iPrevData&0x0000ffff));
// count = (iPrevData&0xff000000) ? 0:count;
for(i=0; i < 4; i++)
{
data = naluBuffer[nBsLength++];
(count == ZEROBYTES_SHORTSTARTCODE && (data == 0x03)) ? nBsLength++ : 0;
count = count == ZEROBYTES_SHORTSTARTCODE ? 0:count;
pStart[i] = naluBuffer[nBsLength-1];
count = data == 0 ? count+1:0;
}
iData = _packlh2(iData,iData);
iData = _swap4(iData);
bs->DataB = iData;
bs->pCurrent+=nBsLength-4;
}
#endif
int _cmpgtu4(int src1,int src2)
{
int result;
int i;
result = 0;
for(i=0;i<4;i++)
{
result |= (((unsigned char *)(&src1))[i]>((unsigned char *)(&src2))[i])<return result;
}
int _norm(unsigned int val)
{
int size = 0;
while(val)
{
val>>=1;
size++;
}
return 31-size;
}
#pragma CODE_SECTION(BitstreamShowBits,".H264Dec_L2_Code_GetMBData")
unsigned int BitstreamShowBits(BITSTREAM * const bs,
const unsigned int bits)
{
int iPos = bs->iPos;
unsigned int DataA = bs->DataA;
unsigned int DataB = bs->DataB;
int rs = 32 - bits;
int nbit = (bits + iPos) - 32;
unsigned int l;
l = nbit <= 0?(DataA << iPos) >> rs
:((DataA << iPos) >> rs) | (DataB >> (32 - nbit));
return l;
}
#pragma CODE_SECTION(D264_BitstreamGetBits,".H264Dec_L2_Code_GetMBData")//Get(0)
static _INLINE_ unsigned int D264_BitstreamGetBits(BITSTREAM * const bs,
const unsigned int bits)
{
int iPos = bs->iPos;
unsigned int DataA = bs->DataA;
unsigned int DataB = bs->DataB;
int nbit = (bits + iPos) - 32;
#if 1
unsigned int l = nbit <= 0?(DataA << iPos) >> (32 - bits)
:((DataA << iPos)>>(32-bits)) | (DataB >> (32 - nbit));
#else
unsigned int l = nbit <= 0?(unsigned __int64)(DataA << iPos) >> (32 - bits)
:((unsigned __int64)(DataA << iPos)>>(32-bits)) | (unsigned __int64)(DataB >> (32 - nbit));
#endif
iPos += bits;
if (iPos >= 32)
{
unsigned int DataA = bs->DataA;
unsigned int DataB = bs->DataB;
int data;// = *(int*)(bs->pCurrent);
memcpy(&data, bs->pCurrent, sizeof(int));
iPos -= 32;
DataA = DataB;
data = _packlh2(data,data);
DataB = _swap4(data);
bs->pCurrent+=sizeof(int);
bs->DataA = DataA;
bs->DataB = DataB;
#ifdef E264_NAL_NEW_003
{
int c0,c1;
c0=_cmpgtu4(0x00000101,DataA);
c1=_cmpgtu4(0x01010100,DataB);
if(_bitc4(c0)+_bitc4(c1)>=2)
{
D264_GetNal(bs,DataA,DataB);
}
}
#endif
}
bs->iPos = iPos;
return l;
}
#pragma CODE_SECTION(D264_BitstreamGetBitsNotInline,".H264Dec_L2_Code")
unsigned int D264_BitstreamGetBitsNotInline(BITSTREAM * const bs,
const unsigned int bits)
{
return D264_BitstreamGetBits(bs,bits);
}
#pragma CODE_SECTION(D264_linfo_ue,".H264Dec_L2_Code_GetMBData")
_INLINE_ signed int D264_linfo_ue(signed int len, signed int info)
{
return ((1 << (len >> 1)) + info - 1);
}
#pragma CODE_SECTION(D264_linfo_se,".H264Dec_L2_Code_GetMBData")
_INLINE_ signed int D264_linfo_se(signed int len, signed int info)
{
signed int n;
signed int value;
n = (1 << (len >> 1)) + info - 1;
value = (n + 1) >> 1;
return ( (n & 0x01) == 0 ? -value : value);// lsb is signed bit
}
#pragma CODE_SECTION(D264_get_VLC_symbol,".H264Dec_L2_Code_GetMBData")
signed int D264_get_VLC_symbol (BITSTREAM *bs, signed int *info)
{
signed int ctr_bit;
unsigned int tmp;
int len = 0;
int a;
// int lennew = 0;
int code = BitstreamShowBits(bs,16);
len = _norm(code) + 1 - (32-16);
#if 0
BitstreamSkip(bs,len+1);
*info = D264_BitstreamGetBitsLenZero(bs,len);
#else
*info = D264_BitstreamGetBits(bs,len*2+1) & ((1<1);
#endif
return ((len<<1) + 1);
}
#pragma CODE_SECTION(D264_ue_v,".H264Dec_L2_Code")
signed int D264_ue_v (BITSTREAM *bs)
{
signed int info;
signed int sym_len;
signed int val;
sym_len = D264_get_VLC_symbol (bs, &info);
val = D264_linfo_ue(sym_len, info);
return val;
}
#pragma CODE_SECTION(D264_se_v,".H264Dec_L2_Code")
signed int D264_se_v (BITSTREAM *bs)
{
signed int info;
signed int sym_len;
signed int val;
sym_len = D264_get_VLC_symbol (bs, &info);
val = D264_linfo_se(sym_len, info);
return val;
}
THE END!