H264属于一种编码格式,使用很多非常牛逼的算法。最终实现了视频数据量的压缩。
打个比方 1920*1080的nv21数据,一帧就有
差不多3M的数据量,那么假设视频传输的FPS是30,这已经很低了吧,那也达到了接近100M/S的数量流量。这谁顶的住啊。
以上只是吹个牛逼,介绍一下视频编码的重要性。
我们如果做相应的开发,一般来说不需要知道它用了多么牛逼的算法,只要知道大致的码流结构,然后呢,取出符合解码器规范的原始数据,送进去解析。如果成功了,就可以关机下班了。
一 框架
H264码流分为两层
1、VCL(Video Coding Layer 视频编码层):我的理解也就是原始数据呗
2、NAL(Network Abstraction Layer 网络提取层): 在网络传输,或者存储在本地存储器上面,还是需要一个结构来打包的,这个就是包裹在VCL外面的NAL层
二 原理
大致就是一些什么关键帧压缩啊,帧间预测啊,什么量化、变换、滤波啊这些,反正就是牛逼
三 编码格式
这个和第一节联合起来看
VCL数据在传输或者存储之前要被封装进NAL单元中,每个NAL单元包括了一个原始字节序列负载(RBSP Raw Byte Sequence Payload)和NAL头,这个RBSP的最后还有一个0x01 还有若干个0x00,用于字节对齐,如下图
可以看到结构还是比较简单基本就是一个NAL头带着一些RBSP数据
四 NAL Header
这个header还是比较重要的,因为在报文解析的时候需要对NAL头进行分析才能正确的取出SPS、PPS还有原始帧数据。
NAL Header只有一个字节
语法: 禁止位(1位)、重要性指示位(2位)、NALU类型(5位)
禁止位(0): 如果这个位为1,那么说明这个NAL单元数据错误,应该丢弃
重要性指示位(1~2): 表示该NAL单元用于重建的重要性,值越大,越重要,取值0-11
NALU类型(3~7):具体定义如下,参见官方文档
值得注意的是解码中我们通常要识别红框标出来的NAL单元类型,分别是I帧、SPS和PPS。
通过以上的总结我们知道了H.264码流结构就是 一个字节的NAL头拼上RBSP组成一个NAL单元,许多个NAL单元就组成了H.264码流。可以说通往解析H.264文件大门的钥匙我们还差最后一把,也就是NAL单元直接是如何分割的。很简单在每个NAL单元之前还有一段Start Code
参考官方文档
实际使用中也就是发现一组 0x00 0x00 0x00 0x01 或者 0x00 0x00 0x01 那么说明是StartCode 那么就进行NAL单元分割
知道这么多就知道如何分析NAL码流了,那么我们实际的来分析一个H.264文件看看
文件可以看到红框框出来三个NAL单元
NAL头分别是 0x67、0x68还有0x06
0x67:根据NAL头定义分析 0x67 & 0x1F = 7,查表得出其类型是7,也就是SPS
0x68: 同上推导出类型是8 PPS
0x06推导出类型是6 SEI
那么问题来了SPS PPS SEI究竟是什么呢
这里还是比较复杂的总结来说就是一些码流的信息,比如宽高 FPS等
这里我贴出几个写的不错的博客可以参考
https://blog.csdn.net/lizhijian21/article/details/80982403
https://blog.csdn.net/y601500359/article/details/80943990
https://blog.csdn.net/nihaoshamozhiying/article/details/79555612