github项目地址:https://github.com/VioletDream-SXZ/H.264AnalysisProject
最好使用linux的,我不知道window那个能不能用。
我们先看一下《新一代视频压缩编码标准–H.264/AVC》第七章里面句法表。(虽然我表示这个表并不全)
先理解一下后面那个u,ue,se是什么意思先。
u(v) 读进连续的v个比特,并将它们解释为无符号整数
ue(v) 无符号指数哥伦布熵编码。
se(v) 有符号指数哥伦布熵编码。
其实就算这个说你们也可能是一脸蒙逼。之后再来介绍一下哥伦布编码,你们记住这个东西怎么运算就可以了。
uint32_t x264_analysis_t::Ue(uint8_t * pBuff, uint32_t nLen, uint32_t & nStartBit)
{
uint32_t nZeroNum = 0;
while (nStartBit < nLen * 8)
{
if(pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8)))
{
break;
}
nZeroNum ++;
nStartBit ++;
}
nStartBit++;
uint64_t dwRet = 0;
for(uint32_t i=0; i<nZeroNum; ++i)
{
dwRet <<= 1;
if(pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8)))
{
dwRet += 1;
}
nStartBit ++;
}
return (1 << nZeroNum) - 1 + dwRet;
}
int x264_analysis_t::Se(uint8_t * pBuff, uint32_t nLen, uint32_t & nStartBit)
{
int UeVal = Ue(pBuff, nLen,nStartBit);
double k = UeVal;
int nValue = ceil(k / 2);
if(UeVal % 2 == 0)
nValue = -nValue;
return nValue;
}
uint64_t x264_analysis_t::U(uint8_t * pBuff, uint32_t BitCount, uint32_t & nStartBit)
{
uint64_t dwRet = 0;
for(uint32_t i=0; i<BitCount; ++i)
{
dwRet <<= 1;
if(pBuff[nStartBit / 8] & (0x80 >> (nStartBit % 8)))
{
dwRet += 1;
}
nStartBit++;
}
return dwRet;
}
先给你们一组数据,这是在吃鸡游戏直播里面抓出来的sps数据:
uint8_t buff[] = {
0x67, 0x64, 0x00, 0x1f, 0xac, 0xd9, 0x40, 0x50,
0x05, 0xba, 0x10, 0x00, 0x00, 0x03, 0x00, 0x10,
0x00, 0x00, 0x03, 0x03, 0x20, 0xf1, 0x83, 0x19,
0x60
};
源码里面都有,可以参考一下。
然后就是对这个表里面的元素一一解析,解析…然后就出错了,这个表其实还缺少一些东西,需要加上的数据位于seq_parameter_set_id之后,需要加入以下东西:
seq_parameter_set_rbsp() | C | Descriptor |
---|---|---|
if(sps_data->profile_idc == 100 or sps_data->profile_idc == 110 or sps_data->profile_idc == 122 or sps_data->profile_idc == 144) | ||
chroma_format_idc | 0 | Ue(v) |
if( sps_data->chroma_format_idc == 3 ) | ||
residual_colour_transform_flag | 0 | U(1) |
bit_depth_luma_minus8 | 0 | Ue(v) |
bit_depth_chroma_minus8 | 0 | Ue(v) |
qpprime_y_zero_transform_bypass_flag | 0 | U(1) |
seq_scaling_matrix_present_flag | 0 | U(1) |
if(sps_data->seq_scaling_matrix_present_flag) | ||
for(int i& |