NAL协议格式
NAL全称Network Abstract Layer, 即网络抽象层.
https://www.itu.int/rec/T-REC-H.264-201906-I/en
SPS vs. PPS
H.264 comes in a variety of stream formats. One variation is called “Annex B”.
(AUD)(SPS)(PPS)(I-Slice)(PPS)(P-Slice)(PPS)(P-Slice) … (AUD)(SPS)(PPS)(I-Slice).
AUD
总的来说H264的码流的打包方式有两种:
- annex-b byte stream format 的格式,这个是绝大部分编码器的默认输出格式,就是每个帧的开头的3~4个字节是H264的start_code,0x00000001或者0x000001。
- 原始的NAL打包格式,就是开始的若干字节(1,2,4字节)是NAL的长度,而不是start_code,此时必须借助某个全局的数据来获得编 码器的profile,level,PPS,SPS等信息才可以解码。
紧随AUD,一般是SPS/PPS/SEI/IDR的组合或者简单就是一个SLICE,也就是一个帧的开始。
SPS(Sequence Parameter Set)
所谓的编码视频序列即原始视频的一帧一帧的像素数据经过编码之后的结构组成的序列。而每一帧的编码后数据所依赖的参数保存于图像参数集中。一般情况SPS和PPS的NAL Unit通常位于整个码流的起始位置。但在某些特殊情况下,在码流中间也可能出现这两种结构,主要原因可能为:
解码器需要在码流中间开始解码;
编码器在编码的过程中改变了码流的参数(如图像分辨率等);
在做视频播放器时,为了让后续的解码过程可以使用SPS中包含的参数,必须对其中的数据进行解析。
PPS(Picture Parameter Set)
图像参数集
File Video:一般只有文件Header里面有SPS、PPS里面有信息
Live Video:为防止丢失SPS/PPS包或者中途播放、每个IFrame/IDR 前面都有SPS、PPS
An IDR frame, or an I-slice can not be decoded without a SPS and PPS.
IDR vs. I-Frame
Every IDR frame is an I-frame, but not vice versa; so there can be I-frames that aren’t IDR frames.
IDR 后面的帧不会参考之前的帧,I-Frame后面的帧还会参考之前的帧。
An IDR frame is a special type of I-frame in H.264. An IDR frame specifies that no frame after the IDR frame can reference any frame before it. This makes seeking the H.264 file easier and more responsive to the player.
NAL、Frame、SPS、PPS、SLICE关系
- NAL可以是:一帧视频数据(IDR,I-SLICE,P-SLICE)、SPS、PPS
- 一个video frame可能包含多个NAL ?参考VLC
- 一个NAL可能会分成多个RTP数据包(STAP聚合包),多个RTP包聚合成一个NAL
STAP可以分为两种类型STAP-A,STAP-B:
1 | Payload Packet Single NAL Non-Interleaved Interleaved |
SPS + PPS + IDR = I frame VLC的定义是不是有误?IDR就可以认为是I-Frame
(15+4)+(4+4)+(46960+4)= 46991
P-SLICE = p frame
1562+4=1566
IDR = I frame
61779 + 4 = 61783
实验
linux send h264 rtp stream:
1 | 录屏 |
receive h264 rtp stream:
1 | gst-launch-1.0 -v udpsrc port=5000 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96" ! rtph264depay ! decodebin ! videoconvert ! autovideosink |
Wireshark设置:
- 右击Decode As …,Current设置成RTP
- Edit -> Preferences…,Protocols->h264,DynamicRTP Type :96
RTP承载H264数据需要将大的NAL帧分包
1 | 1.如何通过RTP承载H264数据 |