目录
帧类型
GOP
Slice
宏块
码流格式
NALU
帧类型
帧类型 | 预测方式 | 参考帧 | 特点 | |
I帧 | 帧内编码帧 | 帧内预测 | 无 | 能独立编解码,压缩率小 |
P帧 | 前向编码帧 | 帧间/帧内预测 | 参考前面已经编码的帧和P帧 | 压缩率比I帧高,必要参考帧才能解码 |
B帧 | 双向编码帧 | 帧间/帧内预测 | 参考前面或者后面已经编码的I帧和P帧 | 压缩率最好,需要存储帧,延时高 |
IDR帧,立即刷新帧,
IDR帧之后的帧不参考IDR帧之前的帧,避免错误帧传递。
IDR帧是特殊的I帧。普通的I帧就是指当前帧只使用帧内预测编码,但是后面的P帧和B帧还是可以参考普通的I帧之前的帧。一般情况下不太使用这种普通I帧,大多数情况下还是直接使用IDR帧。
GOP
从一个IDR帧开始,到下一个IDR帧的前一帧为止。称为一个GOP(图像组)
IDR帧间隔越大,两个IDR相隔就会越远
GOP越大,编码的I帧就会越少,相对而言P帧,B帧压缩率就越高。
但GOP太大,点播场景进行视频的seek操作就会不方便。
RTC和直播场景中,网络丢包,引起长时间的花屏和卡顿
Slice
为了并行编码设计的,一帧图像可以划分几个Slice,之间相互独立,互不依赖,独立编码
可以使用多线程对多个Slice进行编码,提高编码速度。
slice相互独立,帧内预测,不能跨Slice进行,因此编码性能差一些。
宏块
H264中编码的基本单元
一个Slice包含整数个宏块
宏块MB大小是16x16
在做帧内预测和帧间预测时,宏块又可以划分为不同大小的子块
以上概念之间的关系如下
码流格式
1、Annexb格式:
使用起始码表示一个编码数据的开始,起始码不是图像编码的内容,只是用来分割。
两种起始码
4字节的 00 00 00 01
3字节的 00 00 01
如果编码图像中出现00 00 00 01 ;00 00 01;h264图像编码时做以下处理
00 00 00 修改为 00 00 03 00
00 00 01 修改为 00 00 03 01
2、MP4格式:
没有起始码,在图像编码数据的开始使用了4字节作为长度标识,用来表示编码数据的长度。
NALU
H264两个重要的参数集
SPS 序列参数集:主要包含图像的宽、高、YUV格式和位深等信息
PPS 图像参数集:主要包含熵编码类型,基础QP和最大参考帧数量等基本编码信息;
H264码流结构组成如下
如何在码流中找到相应的帧内容 ?
H264设计了NALU 网络抽象层单元
NALU Header + NALU Data
- Header 头里有相应的位表示NALU类型,对于非I帧,还要继续解析 Slice Header。
- Slice header 中有 first_mb_in_slice字段,表示当前Slice的第一个宏块MB在当前编码图像中的序号。用来区分当前Slice 是否是一帧的第一个Slice,等于0代表是。
实战分析
1)一段h264码流分析
红色为起始码,后面跟的是帧类型。
67为SPS帧 68为PPS帧 65为IDR帧。
2)使用Elecard Stream Analyzer工具分析
参考
https://ke.qq.com/course/3202131?flowToken=1040744