本篇文章主要从自己前几个月遇到的一个小问题引出。
问题背景
之前使用Web浏览器播放做测试,发现升级Chrome 87后播放视频会卡,排查服务端下行处理日志发现,带宽估计模块异常,如下是部分异常日志:
1 2 3 4 5 |
(transport_feedback_adapter.cc): Failed to lookup send time for 394 packets. Send time history too small? (transport_feedback_adapter.cc): Failed to lookup send time for 402 packets. Send time history too small? (transport_feedback_adapter.cc): Failed to lookup send time for 412 packets. Send time history too small? (transport_feedback_adapter.cc): Failed to lookup send time for 431 packets. Send time history too small? (inter_arrival.cc): Packets are being reordered on the path from the socket to the bandwidth estimator. Ignoring this packet for bandwidth estimation, resetting. |
由于下行带宽估计会作用到Pacing模块,带宽估计的异常触发Pacing模块发送异常,从而导致视频卡顿。明明最近没有优化服务端带宽估计处理,哪里出错了呢?
通过异常日志可以很容易发现是反馈的Transport Feecback报文异常,Transport Feecback报文记录的部分RTP包在发送端没有发送时间记录,所以导致“Failed to lookup send time for”错误。进一步分析发现是Chrome 87音频也有带宽估计RTCP反馈,Transport Feedback报文中同时记录着音视频的信息。由于我们服务端目前只支持视频的带宽估计处理,带宽估计模块没有记录音频的发送时间信息,所以导致报错。
源码分析
接收端
在RemoteEstimatorProxy
中,如果收到的RTP包有TransportSequenceNumber
报头扩展,就会将该RTP包信息记录到Transport Feecback报文中。Transport Feecback报文中记录着音频信息,说明发送端音频注册了TransportSequenceNumber
报头扩展。
我们服务端在处理Web浏览器间的音频数据转发时,没做太多处理,毕竟浏览器上优化空间不大,除了重新构建序列号等报头信息,RTP报头扩展维持不动。所以问题出在上行的浏览器发送端。
发送端
M86及以前版本
AudioSendStream::AudioSendStream
中:
1 |
audio_send_side_bwe_(field_trial::IsEnabled("WebRTC-Audio-SendSideBwe")) |
默认没启用音频带宽估计特性。
在AudioSendStream::ConfigureStream
中:
1 2 3 4 5 6 7 |
if (audio_send_side_bwe_ && !allocate_audio_without_feedback_ && new_ids.transport_sequence_number != 0) { // new_ids由SDP获取,通过a=extmap中是否含有 // transport-wide-cc-extensions获取对应extension ID channel_send_->EnableSendTransportSequenceNumber( new_ids.transport_sequence_number); } |
所以旧版WebRTC中音频默认没有注册TransportSequenceNumber
扩展。
M87及以后版本
AudioSendStream::AudioSendStream
中:
1 2 |
allocate_audio_without_feedback_( field_trial::IsEnabled("WebRTC-Audio-ABWENoTWCC")) |
allocate_audio_without_feedback_
默认为false。
AudioSendStream::ConfigureStream
中:
1 2 3 4 5 |
if (!allocate_audio_without_feedback_ && new_ids.transport_sequence_number != 0) { rtp_rtcp_module_->RegisterRtpHeaderExtension( TransportSequenceNumber::kUri, new_ids.transport_sequence_number); } |
可知新版WebRTC中音频默认注册TransportSequenceNumber
报头扩展,也就是开启带宽估计特性。
了解了区别后,问题修复就简单了。后面我们服务端增加了对音频带宽估计的兼容处理修复了该问题。
总结
本文在分析相关问题基础上,介绍了新旧WebRTC版本在音频带宽估计处理上的一个小区别。新版WebRTC默认启用音频带宽估计也是为了提高带宽估计准确性。
文章评论
学习了。
怎么解决的来着