获取.h264视频宽高的方法

花了2个通宵终于搞定。(后面附上完整代码)

http://write.blog.csdn.net/postedit/7852406

图像的高和宽在H264的SPS帧中。
在H264码流中,都是以"0x00 0x00 0x01"或者"0x00 0x00 0x00 0x01"为开始码的,找到开始码之后,使用开始码之后的第一个字节的低5位判断是否为7(sps),等于7表示该帧就是SPS帧,从该帧就可以解析出高和宽,SPS是个结构体,里面有两个成员:pic_width_in_mbs_minus1,pic_height_in_map_units_minus_1,分别表示图像的宽和高,以宏块(16x16)为单位的值减1,因此,实际的宽为 (pic_width_in_mbs_minus1+1)*16,高为 (pic_height_in_map_units_minus_1+1)*16

http://write.blog.csdn.net/postedit/7852406

 UINT Ue(BYTE *pBuff, UINT nLen, UINT &nStartBit)
{
//计算0bit的个数
UINT nZeroNum = ;
while (nStartBit < nLen * )
{
if (pBuff[nStartBit / ] & (0x80 >> (nStartBit % ))) //&:按位与,%取余
{
break;
}
nZeroNum++;
nStartBit++;
}
nStartBit ++; //计算结果
DWORD dwRet = ;
for (UINT i=; i<nZeroNum; i++)
{
dwRet <<= ;
if (pBuff[nStartBit / ] & (0x80 >> (nStartBit % )))
{
dwRet += ;
}
nStartBit++;
}
return ( << nZeroNum) - + dwRet;
} int Se(BYTE *pBuff, UINT nLen, UINT &nStartBit)
{ int UeVal=Ue(pBuff,nLen,nStartBit);
double k=UeVal;
int nValue=ceil(k/);//ceil函数:ceil函数的作用是求不小于给定实数的最小整数。ceil(2)=ceil(1.2)=cei(1.5)=2.00
if (UeVal % ==)
nValue=-nValue;
return nValue; } DWORD u(UINT BitCount,BYTE * buf,UINT &nStartBit)
{
DWORD dwRet = ;
for (UINT i=; i<BitCount; i++)
{
dwRet <<= ;
if (buf[nStartBit / ] & (0x80 >> (nStartBit % )))
{
dwRet += ;
}
nStartBit++;
}
return dwRet;
} bool h264_decode_seq_parameter_set(BYTE * buf,UINT nLen,int &Width,int &Height)
{
UINT StartBit=;
int forbidden_zero_bit=u(,buf,StartBit);
int nal_ref_idc=u(,buf,StartBit);
int nal_unit_type=u(,buf,StartBit);
if(nal_unit_type==)
{
int profile_idc=u(,buf,StartBit);
int constraint_set0_flag=u(,buf,StartBit);//(buf[1] & 0x80)>>7;
int constraint_set1_flag=u(,buf,StartBit);//(buf[1] & 0x40)>>6;
int constraint_set2_flag=u(,buf,StartBit);//(buf[1] & 0x20)>>5;
int constraint_set3_flag=u(,buf,StartBit);//(buf[1] & 0x10)>>4;
int reserved_zero_4bits=u(,buf,StartBit);
int level_idc=u(,buf,StartBit); int seq_parameter_set_id=Ue(buf,nLen,StartBit); if( profile_idc == || profile_idc == ||
profile_idc == || profile_idc == )
{
int chroma_format_idc=Ue(buf,nLen,StartBit);
if( chroma_format_idc == )
int residual_colour_transform_flag=u(,buf,StartBit);
int bit_depth_luma_minus8=Ue(buf,nLen,StartBit);
int bit_depth_chroma_minus8=Ue(buf,nLen,StartBit);
int qpprime_y_zero_transform_bypass_flag=u(,buf,StartBit);
int seq_scaling_matrix_present_flag=u(,buf,StartBit); int seq_scaling_list_present_flag[];
if( seq_scaling_matrix_present_flag )
{
for( int i = ; i < ; i++ ) {
seq_scaling_list_present_flag[i]=u(,buf,StartBit);
}
}
}
int log2_max_frame_num_minus4=Ue(buf,nLen,StartBit);
int pic_order_cnt_type=Ue(buf,nLen,StartBit);
if( pic_order_cnt_type == )
int log2_max_pic_order_cnt_lsb_minus4=Ue(buf,nLen,StartBit);
else if( pic_order_cnt_type == )
{
int delta_pic_order_always_zero_flag=u(,buf,StartBit);
int offset_for_non_ref_pic=Se(buf,nLen,StartBit);
int offset_for_top_to_bottom_field=Se(buf,nLen,StartBit);
int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf,nLen,StartBit); int *offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle];
for( int i = ; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )
offset_for_ref_frame[i]=Se(buf,nLen,StartBit);
delete [] offset_for_ref_frame;
}
int num_ref_frames=Ue(buf,nLen,StartBit);
int gaps_in_frame_num_value_allowed_flag=u(,buf,StartBit);
int pic_width_in_mbs_minus1=Ue(buf,nLen,StartBit);
int pic_height_in_map_units_minus1=Ue(buf,nLen,StartBit); Width=(pic_width_in_mbs_minus1+)*;
Height=(pic_height_in_map_units_minus1+)*; return true;
}
else
return false;
} void CCommDlg::OnOK()
{
CString str;
//数据必须把H264的头0x000001去掉
BYTE bytes[]={0x67,0x64,0x08,0x1F,0xAC,0x34,0xC1,0x08,0x28,0x0F,0x64};
UINT startbit=;
int Width,Height;
if (h264_decode_seq_parameter_set(bytes,,Width,Height))
{
str.Format("%d-%d",Width,Height); AfxMessageBox(str);
}
}

从H264码流中获取视频宽高 (SPS帧)的更多相关文章

  1. 从H264码流中获取视频宽高 (SPS帧) 升级篇

    之前写过 <从H264码流中获取视频宽高 (SPS帧)> . 但发现很多局限性,而且有时解出来是错误的. 所以重新去研究了. 用了 官方提供的代码库来解析. 花了点时间,从代码库里单独把解 ...

  2. H264码流中SPS PPS详解<转>

    转载地址:https://zhuanlan.zhihu.com/p/27896239 1 SPS和PPS从何处而来? 2 SPS和PPS中的每个参数起什么作用? 3 如何解析SDP中包含的H.264的 ...

  3. Activity启动过程中获取组件宽高的五种方式

    第一种:(重写Activity的onWindowFocusChanged方法) /** * 重写Acitivty的onWindowFocusChanged方法 */ @Override public ...

  4. H.264从SPS中提取视频宽高

    H.264有两种封装模式: (1)annexb模式:传统模式,使用start code来分隔NAL, SPS和PPS是在ES流的头部: (2)mp4模式:没有start code,使用NALU长度(固 ...

  5. Vue中获取元素宽高

    <div ref="init"></div> 写在 页面 方法 部分 这里的 offsetHeight 是返回元素的宽度(包括元素宽度.内边距和边框,不包括 ...

  6. android onCreate中获取view宽高为0的解决方法

    view.post(runnable) 通过post可以将一个runnable投递到消息队列的尾部,然后等待UI线程Looper调用此runnable的时候,view也已经初始化好了. view.po ...

  7. ffmpeg 获取视频宽高

    int main(int argc, char *argv[]) { const char* file_name = "video.mp4"; int ret; unsigned ...

  8. Activity正确获取View宽高

    在View的measure完成后,一般可以通过getMeasureWidth/getMeasureWidth方法可以正确的获取View的宽高,而在特殊情况下,可能需要多次measure才能确定最终的测 ...

  9. H264码流打包分析

    转自:http://www.360doc.com/content/13/0124/08/9008018_262076786.shtml   SODB 数据比特串-->最原始的编码数据 RBSP ...

随机推荐

  1. c++学习--继承与派生

    继承和派生 1 含有对象成员(子对象)的派生类的构造函数,定义派生类对象成员时,构造函数的执行顺序如下: 1 调用基类的构造函数,对基类数据成员初始化: 2 调用对象成员的构造函数,对对象成员的数据成 ...

  2. Jmeter组件7. JDBC Connection Configuration & JDBC Request

    Jmeter同样可以测试数据库的性能,通过执行增删改查的语句,以下举的是oracle的例子 Step 1: 下载ojdbc14.jar包放到Jmeter lib包中,在test plan中配置,并且重 ...

  3. .net 制作二维码

    首先  要下载  ThoughtWorks.QRCode.dll 下载地址:http://download.csdn.net/detail/lybwwp/6861821 然后新建项目 把Thought ...

  4. MacOS changed System Integrity Protection status

    禁止 System Integrity Protection 按住 command + R 重启系统 进入单用户模式 启动bash工具: 输入: csrutil disable 输入:reboot 启 ...

  5. Java中serialVersionUID

    报错信息如下: Adds a default serial version ID to the selected type. Use this option to add a user-defined ...

  6. 有WebService的项目中写applicationContex.xml文件时应注意!!!

    这是一个简单的WebService实例,来看下如下的applicationContex.xml文件: 1.有XFire的配置 <bean id="baseWebService" ...

  7. Android 5.0属性

    //水波纹效果//v 指定控件 x屏幕的 x轴 y轴 endRadio 起始位置 水波半径Animator circularReveal = ViewAnimationUtils.createCirc ...

  8. redis python-redis 安装详细步骤

    安装redis 把redis安装到 /opt/redis-2.8目录中 wget http://download.redis.io/releases/redis-2.8.1.tar.gz tar -z ...

  9. iOS图片模糊效果与阴影效果

    /** 添加图片模糊效果 @parms  要添加模糊效果的view @return */ + (UIVisualEffectView *)addVisualEffectViewWithView:(UI ...

  10. Nginx开启GZIP来压缩网页

    HTTP协议上的GZIP编码是一种用来改进web应 用程序性能的技术.大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度.这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中 ...