WebRTC之RTP包

扩展阅读WebRTC之RTCP

RTP固定头部

RTP的固定头部,详情可以阅读rfc文档5.1 RTP Fixed Header Fields

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • V版本号位,必须等于2
  • P填充位
  • X扩展位,标志是否存在扩展
  • CC CSRC个数
  • M Mark标志位,标志是否是一帧的结束,音频帧几乎每个包都是一个完整的帧,所以M一般情况都等于1,视频包因为一帧比较大,会被分为几个包发送,最后一个包标志需要Mark一下
  • PT负载类型,不同的负载类型对应不同的编解码类型(音频根据采样率和通道不同都要对应不同的负载类型),FEC类型等。
  • sequence number,包序号,发送端指定一个起始序号(如果不指定则随机一个),然后每个包的序号依次递增;如果存在RTX,重发是此序号是rtx的序号,详情请看RTPSender::SendPadData的实现
  • timestamp,包的时间戳,如果一个视频帧被分为几个包,则这个帧对应的几个包的时间戳是一样的;发送端可以指定一个起始时间戳timestamp_offset_(如果不指定则随机一个),然后每个帧的时间戳等于起始时间戳加上采集时间戳timestamp_offset_ + capture_timestamp,详情可以看RTPSender::SendOutgoingData的实现。那么这个capture_timestamp是什么呢,它实际上就是一个单调递增时间戳的低32位,详情可以看VideoStreamEncoder::OnFrame
  • SSRC,同步源的唯一标识,每一个源(音频或者视频,文件)都必须要有一个唯一的标识码,用于区分不同的流
  • CSRC,贡献源,列举此SSRC的资源是由多少个其他的资源(其他资源的SSRC)混合而来的。例如MCU混音之后就需要修改这个;最多只能表示15源

RTP扩展

如果存在RTP扩展则标志位X必须置为1,除了标准扩展外,WebRTC还有自己的扩展,所以服务端如果使用标准rtp解析库需要添加一下WebRTC的RTP扩展。
扩展相关的几个文件rtp_header_extensions.hrtp_utility.cc可以阅读一下

  • kRtpExtensionTransmissionTimeOffset,一个包相对于采集时间的偏移的滴答数
# rtp_sender.cc +569
if (capture_time_ms > 0) {
  padding_packet.SetExtension<TransmissionOffset>(
      (now_ms - capture_time_ms) * kTimestampTicksPerMs);
}
  • kRtpExtensionAudioLevel,一帧音频数据的分贝值
# rtp_sender_audio.cc +226
packet->SetExtension<AudioLevel>(frame_type == kAudioFrameSpeech, audio_level_dbov);
  • kRtpExtensionAbsoluteSendTime,一个包的绝对发送时间
# rtp_sender.cc +572
padding_packet.SetExtension<AbsoluteSendTime>(AbsoluteSendTime::MsTo24Bits(now_ms));
  • kRtpExtensionVideoRotation,帧视频帧的方向
# rtp_sender_video.cc +331
last_packet->SetExtension<VideoOrientation>(current_rotation);
  • kRtpExtensionTransportSequenceNumber,扩展序号,不管是第一次发送还是重发的包,此需要都会递增
# rtp_sender.cc +1066
*packet_id = transport_sequence_number_allocator_->AllocateSequenceNumber();
 if (!packet->SetExtension<TransportSequenceNumber>(*packet_id))
  • kRtpExtensionPlayoutDelay

  • kRtpExtensionVideoContentType,视频源是否是屏幕资源

# rtp_sender_video.cc +336
last_packet->SetExtension<VideoContentTypeExtension>(video_header->content_type);
  • kRtpExtensionVideoTiming,记录视频编码开始,编码结束,打包完成,平滑发送等时间戳,不过这几个时间戳都是相对时间
# 填充此结构体 frame_object.cc +121
timing_.encode_start_ms = ntp_time_ms_ + last_packet->video_header.video_timing.encode_start_delta_ms;
timing_.encode_finish_ms = ntp_time_ms_ + last_packet->video_header.video_timing.encode_finish_delta_ms;
timing_.packetization_finish_ms = ntp_time_ms_ + last_packet->video_header.video_timing.packetization_finish_delta_ms;
timing_.pacer_exit_ms = ntp_time_ms_ + last_packet->video_header.video_timing.pacer_exit_delta_ms;
timing_.network_timestamp_ms = ntp_time_ms_ + last_packet->video_header.video_timing.network_timstamp_delta_ms;
timing_.network2_timestamp_ms = ntp_time_ms_ + last_packet->video_header.video_timing.network2_timstamp_delta_ms;

# 打包到rtp包中 rtp_sender_video.cc +340
last_packet->SetExtension<VideoTimingExtension>(video_header->video_timing);
  • 这几个扩展kRtpExtensionRtpStreamId,kRtpExtensionRepairedRtpStreamId,kRtpExtensionMid,WebRTC都没有使用

RTP填充

探测带宽的时候为了达到一定时间内必须要达到一定的码率,这样的情况下就需要填充一些无意义的内容到rtp包中,填充信息放在负载最后面,在包的最后用一个8位保存填充信息的长度。

// 通用头部 | 扩展 | 负载信息 | 填充信息 | 填充长度
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|One-byte eXtensions id = 0xbede|       length in 32bits        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Extensions                           |
|                             ....                              |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|                          Payload                              |
|         ....               : padding...                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        padding             | padding size   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值