一:YUV的概念
YUV:(也称为YCbCr),是电视系统所采用的一种颜色编码方法
Y:表示亮度,也就是灰阶值,他是基础信号
UV:表示的则是色度,UV的作用是描述影像的色彩及饱和度,它们用于指定像素的颜色
二:YUV常见格式
YUV4:2:0 (YCbCr 4:2:0)--这比RGB少了二分之一
YUV4:2:2 (YCbCr 4:2:2)--YUV4:2:2就是比RGB小三分之一,RGB8:8:8
YUV4:4:4 (YCbCr 4:4:4)--理解为1:1:1,就是4个Y对应4个U和4个V
1:YUV4:2:0
YUV4:2:0并不意味着只有Y,Cb2个分量,而没有Cr分量,他实际指的是每行扫描线来说,只有一种色度分量,它以2:1的抽样率来存储的;
2:YUV存储格式
plannar(平面)
1:I420:YYYYYYYY UU VV -->YUV420P,是PC端用的
2:YV12: YYYYYYYY VV UU --> YUV420P
packed(打包)
1:NV12: YYYYYYYY UVUV --> YUV420SP
2:NV21: YYYYYYYY VUVU --> YUV420SP
有可能开发过程,比如iOS/安卓,在解码视频后发现图像出现倒置或者翻转,有可能是因为他们的YUV格式不一致,因为PC端一般常用与I420,安卓一般默认NV21,iOS一般默认NV12,如果想行为统一,就需要保证一致的存储格式;
三:NALU
NALU = NAL Header + NAL Body
H264码流在网络中传输时实际是以NALU的形式进行传输,每个NALU由一个字节Header和RBSP组成
NAL Header 解析
NAL Header 为一个字节,里面包含什么样的数据呢
第0位:F
第1~2位:NRI
第3~7位:type
F:forbidden_zero_bit,在H264规范中规定了第一位必须为0,记住就行了
NRI:表示重要性,暂时无用处,000最无用,111最有用,用于表示当前NALU的重要性,值越大,越重要,解码器在解码处理不过来的时候丢掉重要性为0的NALU
type:表示这个NAL的类型,一下表示常见的几个
1:5:IDR图像的片(可以理解为I帧,I帧由多个I片组成)
2:7:序列参数集(sps)
3:8:序列参数集(pps)
NAL类型
单一类型:一个RTP包只包含NALU,就是说H264帧里只包含了一个片,例如P帧或者B帧都是单一类型
组合类型:一个RTP包含多个NALU,类型是24-27,像pps或者sps一般都放在一个包里,以为2个数据单元都非常小
分片类型:一个NALU单元分成多个RTP包,类型28-29
第1个字节:FU indicator分片单元指示符
第2个字节:FU Header 分片单元头,有多个片,就有FU Header组合起来
FU Header
S:start bit用于指明分片的开始,在网络传输时,一个个包,我们知道他的分片的包,那么如何区分是开始还是末尾的包呢?如果为1就是分片的开始
E:end bit用于指明分片的结束
R:未使用,设置为0
Type:指明分片NAL类型,网络传输完成后,还是需要将分片组合成NALU单元,这个NAL
单元是关键帧还是非关键帧是sps还是pps,就需要根据Type来判断
在传输过程中将一个帧切割成多个片,如果在传输过程中顺序打乱,或者丢失了其中某个片,我们怎么判断NALU单元传输完整呢?
依据FU Header的S/E位,并借助于RTP包的包头,在RTP的包头包括了每个包的序列号,如果收到的包,收到了S包,也收到了E包,中间的包的序号是连续的,那就说明包是完整的,如果不是连续的就是丢包了,如果没有丢包就可以组合起来