webrtc代码走读八(h264 rtp打包笔记)

一、Payload Structures

h264rtp打包载荷结构有三种:单一NAL单元模式、组合封包模式、分片封包模式。

1、单一NAL单元模式

即一个RTP包仅由一个完整的NALU组成。这种情况下RTP NAL头类型字段和原始的H.264的NALU头类型字段是一样的。对于NALU的长度小于MTU大小的包,一般采用单一NAL单元模式。对于一个原始的H.264NALU单元常由[StartCode][NALUHeader][NALUPayload]三部分组成,其中StartCode用于标示这是一个NALU单元的开始,必须是"00 00 00 01"或"00 00 01",NALU头仅一个字节,其后都是NALU单元内容。打包时去除"00 00 01"或"00 00 00 01"的开始码,把其他数据封包的RTP包即可。

The single NAL unit packet defined here MUST contain only one NAL unit of the types defined in [1]. This means that neither an aggregation packet nor a fragmentation unit can be used within a single NAL unit packet. A NAL unit stream composed by de-packetizing single NAL unit packets in RTP sequence number order MUST conform to the NAL unit decoding order.

webrtc代码走读八(h264 rtp打包笔记)_第1张图片

PPS、SPS等NAL,每个NAL都单独打包一个RTP报文,很明显这种打包方式比较浪费带宽。

2、组合封包模式

由多个NAL单元组成一个RTP包。组合打包又分STAP(Single-time aggregation packet)、MTAP(Multi-time aggregation packet)两种。

webrtc代码走读八(h264 rtp打包笔记)_第2张图片

  • STAP

单时间聚合包,聚合具有相同NALU时间的NAL单元。定义两种STAPs类型,一个没有DON(STAP-A),另一个包含DON(STAP-B)。

  • MTAP

多时间聚合包,聚合具有潜在不同NALU时间的NAL单元。定义了两个不同的MTAPs,其NAL单元的时间戳偏移的长度不同。

3、分片封包模式。

用于把一个NALU单元封装成多个RTP包。存在两种类型FU-A和FU-B。类型值分别是28和29。而当NALU的长度超过MTU时,就必须对NALU单元进行分片封包。也称为Fragmentation Units(FUs)。将NALU拆分成小于MTU的数据包进行发送。

webrtc代码走读八(h264 rtp打包笔记)_第3张图片

 

webrtc代码走读八(h264 rtp打包笔记)_第4张图片

  • FU indicator定义

F:1个比特.
forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0.

NRI:2个比特.
nal_ref_idc. 取00~11,似乎指示这个NALU的重要性,如00的NALU解码器可以丢弃它而不影响图像的回放,0~3,取值越大,表示当前NAL越重要,需要优先受到保护。如果当前NAL是属于参考帧的片,或是序列参数集,或是图像参数集这些重要的单位时,本句法元素必需大于0。

Type:5个比特
nal_unit_type. 这个NALU单元的类型,1~12由H.264使用,24~31由H.264以外的应用使用,简述如下:
  0     没有定义
  1-23  NAL单元  单个 NAL 单元包
  1     不分区,非IDR图像的片
  2     片分区A
  3     片分区B
  4     片分区C
  5     IDR图像中的片
  6     补充增强信息单元(SEI)
  7     SPS
  8     PPS
  9     序列结束
  10    序列结束
  11    码流借宿
  12    填充
  13-23 保留

  24    STAP-A   单一时间的组合包
  25    STAP-B   单一时间的组合包
  26    MTAP16   多个时间的组合包
  27    MTAP24   多个时间的组合包
  28    FU-A     分片的单元
  29    FU-B     分片的单元
  30-31 没有定义

 

  • FU header定义

S:1 位
当被设置为 1 时,Start 位表示被分片 NAL 单元的开始。当后面的 FU 载荷不是被分片 NAL 单元载荷的开始时,Start 位被设置为 0。
E:1 位
当被设置为 1 时,End 位表示被分片 NAL 单元的结束,比如,载荷的最后一个字节也是被分片的 NAL 单元的最后一个字节。当后面的 FU 载荷不是被分片的 NAL 单元的最后一个片段时,End 位被设置为0。
R:1 位
Reserved 位必须等于 0,且接收者必须忽略它。
Type:5 位
NAL 单元载荷类型,如 ITU-T Recommendation H.264 的表 7-1 所定义的那样。

二、Packetization Modes

h264的rtp打包模式有如下三种:1、Single NAL unit mode;2、Non-interleaved mode;3、Interleaved mode

根据协议,模式1/2,适合低延时的实时会议系统。模式3适合对系统延时要求不高的传输系统。模式1遵守ITU-T Recommendation H.241协议。模式2不按照这个协议来。三种模式下支持的NAL Unit Type类型如下:

webrtc代码走读八(h264 rtp打包笔记)_第5张图片

三、webrtc实现情况

webrtc只支持Single NAL unit mode和Non-interleaved mode两种打包模式。

webrtc通过VideoCodec::SetDefaultParameters函数配置kH264FmtpPacketizationMode参数,配置RTP发包模式。

封包实现函数RtpPacketizerH264::GeneratePackets。

解包实现函数RtpDepacketizerH264::Parse

1)解包函数调用栈

RtpDepacketizerH264::ParseH264PictureID
RtpDepacketizerH264::ParseH264Extension
RtpDepacketizerH264::ProcessStapAOrSingleNalu
RtpDepacketizerH264::Parse
RTPReceiverVideo::ParseRtpPacket
RtpReceiverImpl::IncomingRtpPacket
RtpVideoStreamReceiver::ReceivePacket
RtpVideoStreamReceiver::OnRecoveredPacket
UlpfecReceiverImpl::ProcessReceivedFec
RtpVideoStreamReceiver::ParseAndHandleEncapsulatingHeader
RtpVideoStreamReceiver::ReceivePacket
RtpVideoStreamReceiver::OnRtpPacket
RtpDemuxer::OnRtpPacket
RtpStreamReceiverController::OnRtpPacket
internal::Call::DeliverRtp
internal::Call::DeliverPacket
WebRtcVideoChannel::OnPacketReceived
BaseChannel::ProcessPacket

video_coding::RtpFrameReferenceFinder::ManageFrame
RtpVideoStreamReceiver::OnReceivedFrame
video_coding::PacketBuffer::InsertPacket
RtpVideoStreamReceiver::OnReceivedPayloadData
RTPReceiverVideo::ParseRtpPacket
RtpReceiverImpl::IncomingRtpPacket

 

参考

https://tools.ietf.org/html/rfc6184

https://www.wolfcstech.com/2017/08/18/h264_on_rtp/

你可能感兴趣的:(webrtc,openh264,webrtc代码走读)