H264的ES原始数据一般是以NAL(Network Abstract Layer)的格式存在。可以直接用于文件存储和网络传输。每一个NALU(Network Abstract Layer Unit)数据,是由数据头+RBSP数据组成。 首先需要将数据流,分割成一个一个独立的NALU数据。 接着获取NALU的nal_type,i_nal_type的值等于0x7表示这个nalu是个sps数据包。找到并解析这个sps数据包,里面包含有非常重要的帧率信息 然后根据nal_type判断slice(H264中的slice类似一个视频帧FRAME的概念)。其中nal_type值小于0x1,或大于0x5,表示这个NALU属于一个slice。
在找到slice的NALU后,可以逐字节将NALU的数据与0x80进行与运算,结果为真表示这个slice(视频帧FRAME)的结束位置。
上面的这个代码是摘抄自FFMPEG。他实际作用是判断slice里面的first_mb_in_slice,即第1个宏块在slice中的位置, 如果是一帧开始,这个字段的值肯定是标识第1个宏块。因此,也可以完整解析slice的头部信息,解析出first_mb_in_slice,如果是 0(注意:这是1个哥伦布数值),即这个NALU是一帧的开始。
从现在开始,就有两种办法来计算PTS了。 方法一、根据前后帧的IPB类型,可以得知帧的实际显示顺序,使用前面获取的sps信息中的帧率,以及帧计数frame_count即可计算出PTS。此方法需要做几帧缓存(一般缓存一个group的长度)。 I P B B I P B B I P B ... 帧类型 一个I帧与下一个I帧之间,是一个group。 第8帧的pts=1000(毫秒)*7(帧显示顺序)*帧率 方法二、每一个slice的信息里面,都记录有pic_order_cnt_lsb,当前帧在这个group中的显示顺序。通过这个pic_order_cnt_lsb,可以直接计算出当前帧的PTS。此方法不需要做帧缓存。 计算公式: pts=1000*(i_frame_counter + pic_order_cnt_lsb)*(time_scale/num_units_in_tick) i_frame_counter是最近一次I帧位置的帧序,通过I帧计数+当前group中的帧序,得到帧实际显示序列位置,乘上帧率,再乘上1000(毫秒)的base_clock(基本时钟频率),得到PTS。 I P B B I P B B I P B ... 帧类型 所以,第11帧的pts应该是这么计算 结束语: 如果您对此文章有任何疑问,欢迎到流媒体开发论坛提问。 本站遵循Creative Commons Attribution 3.0 License,所有文章欢迎任何形式的转载,但请注明作者及出处,尊重他人劳动成果! 文章转载自:罗索工作室 [http://www.] 本文标题:流媒体基本要点简述:如何在H264数据中获取PTS? 本文作者:zorru 本文来源:hi.baidu.com/zorru 本文地址:http://www./a/201110/15088.html |