h264 ES流文件通过计算first_mb_in_slice区分帧边界

本人由于最近在读取h264文件的时候,遇到如何读取完整一帧数据的问题,通过使用elecard stream analyzer工具,以及结合《新一代视频压缩编码标准--H264/AVC》(第二版)书,并在网上查找总结如下:

首先NAL句法,片头句法以及nal_unit_type语义必须知道:



以上两图截自《新一代视频压缩编码标准--H264/AVC》(第二版)

        简单的区分帧的方法就是读取文件的时候与0x00 0x00 0x00 0x01比较,如果相等认为是一个片,再读取一个字节就对应表6.1的forbidden_zero_bit(1bit),nal_ref_idc(2bit),nal_unit_type(5bit),nal_unit_type值根据表6.20可以确定该帧类型,对于7,8是没有first_mb_in_slice,可以一直读到下一个0x00 0x00 0x00 0x01这之间的数据都是参数集数据。对于1,5都是有first_mb_in_slice并且每一帧第一片的first_mb_in_slice都是0,这对于分成多片的一帧数据的获取是很有用的。

下面是指数哥伦布码的解析:来自http://blog.csdn.net/simongyley/article/details/8517817

     解析k阶指数哥伦布码时,首先从比特流的当前位置开始寻找第一个非零比特,并将找到的零比特个数记为leadingZeroBits,然后根据leadingZeroBits计算CodeNum。用伪代码描述如下:

    

指数哥伦布编码(to be continued..) - lhzsolomon@126 - Truemens world

    

        first_mb_in_slice是需要对h264通过ExpGolomb编码过的一串2进制数进行ExpGolomb解码得到,通过在网上多方查找并结合h264的文件分析,终于找到了计算方法,现在跟大家分享一下,有不对的地方欢迎指正。

I帧情况:

如下图所示:


        88 80 = 1000 1000 1000 0000      假设阶数为0,那么leadingZeroBits=0, CodeNum(first_mb_in_slice) = 1-1+0=0

        06 62 = 0000 0110 0110 0010      假设阶数为0,那么LeadingZeroBits=5, CodeNum(first_mb_in_slice)=2EXP(5)-2EXP(0)+10011(2进制)=32-1+19=50

p帧情况:

如下图所示:


       9A 00 = 1001 1010 0000 0000      假设阶数为0,那么leadingZeroBits=0, CodeNum(first_mb_in_slice) = 1-1+0=0

       03 29 = 0000 0011 0010 1001      假设阶数为0,那么LeadingZeroBits=6, CodeNum(first_mb_in_slice)=2EXP(6)-2EXP(0)+100101(2进制)=64-1+37=100

其实对于0阶而言,最简单的方法就是判断该字节第一个bit是否为1,如果是1,CodeNum(first_mb_in_slice),肯定为0,就是一帧的第一片。

原理解说完毕,希望对大家有所帮助。具体计算first_mb_in_slice的代码网上应该比较多,也可以参考ffmpeg的。


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值