获取.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. Manually enable Appear Offline in Lync 2013 Preview via Registry

    refer to http://www.shudnow.net/2012/09/18/manually-enable-appear-offline-in-lync-2013-preview-via-r ...

  2. openlayers中实现自定冒泡的效果

    自定义的Openlayers.Popup.FreshCloud继承自Openlayers.Popup.Framed,实现了比较简洁的冒泡效果,详细代码如下 /** * Class: OpenLayer ...

  3. python 中变量的命名方法

    从网上找到django中python的命名规范 Python  规范 代码的布局  编码 所有的Python脚本文件都应在文件头标上“# -*- coding:utf-8 -*-”.  缩进 4个空格 ...

  4. windows Service 创建部署

    Windows Service简介: 一个Windows服务程序是在Windows操作系统下能完成特定功能的可执行的应用程序.Windows服务程序虽然是可执行的,但是它不像一般的可执行文件通过双击就 ...

  5. Macbook下virtualenv无法使用解决办法

    Mac下删除自己安装的Python 删除Python框架sudo rm -rf /Library/Frameworks/Python.framework/Versions 删除Python程序sudo ...

  6. 100怎么变成100.00 || undefined在数字环境下是:NaN || null在数字环境下是0 || 数组的toString()方法把每个元素变成字符串,拼在一起以逗号隔开 || 空数组转换成字符串后是什么?

    100怎么变成100.00?

  7. VBS实现定时发送邮件

    原理:建立CDO.Message对象,设置好参数后直接Send就可以了 代码如下: NameSpace = "http://schemas.microsoft.com/cdo/configu ...

  8. SqlLocalDB使用笔记

    一.介绍 SqlLocalDB是VS安装时附带的数据库软件,相当于精简版的SQL Express. 二.使用 VS版本为2015,默认安装位置为:C:\Program Files\Microsoft ...

  9. 6.openssl rsautl和openssl pkeyutl

    rsautl是rsa的工具,相当于rsa.dgst的部分功能集合.可用于签名.验证.加密和解密文件.非对称密钥的密钥是随机生成的,因此不需要也无法指定salt参与加密. pkeyutl是非对称加密的通 ...

  10. Haproxy ssl 配置方式

    通过haproxy redirect请求重定向的方法实现HTTP跳转HTTPS 配置实现http跳转到https,采用redirect重定向的做法,只需在frontend端添加: frontend h ...