webrtc QOS 优化 (1)慢启动优化

11 篇文章 1 订阅 ¥59.90 ¥99.00

前言

  • 搞webrtc很多年了,钱没赚到,恶心了那么久,现在想想还不如当初不入坑了,webrtc不单单难在某一个算法,而且难在对整个体系的把控,要把每个策略作用都发挥到最大,webrtc源码过于庞大,费力不讨好,建议新手改行。
  • 还不如学学怎么装逼和扯皮,想当年在某cloud搞流媒体,组内一个android毕业生,天天装逼,天天扯皮,从一开始的最低级别,短短两年升到组内最高级别,深深让我体会到靠逼做开发的威力,边装逼边写代码,写代码是为了装逼服务,组内其他成员个个都是影帝,说话又好听,当然,还要遇到一个脑子进水的草包组长。虽然最后小组都搞解散了,但是个个都特别开心,因为有补偿。工作那么久第一次遇到那么奇葩的脑残组

慢启动优化

在webrtc启动阶段,第一个ack时钟的是由探测的策略来产生,这时GCC通过探测来进行码率评估,类型tcp的慢启动:

探测计划启动的滞后

  • 慢启动阶段 视频到达pacer比音频慢了一秒,所以,慢启动阶段探测计划创建后,即便有音频数据传递到pacer了,但是由于音频的编码长度为160个字节,甚至85个字节
    所以 条件不成立:packet_size >= std::min(RecommendedMinProbeSize(), kMinProbePacketSize) 导致探测无法在只有音频数据的情况下启动。

  • 过了一秒后有视频数据后才满足 packet_size 900 >= kMinProbePacketSize 200 才会启动探测计划,导致慢启动阶段的探测滞后,但是没出现探测超时,因为在1秒内会连续创建多个探测计划

  • 系统启动后,探测计划启动的太慢 过了两秒后才启动探测 优化如下:

  • 1.kMinProbePacketSize 改成 100 可以让探测计划在音频数据来到的时候立刻启动:probing_state_ = kActive

  • 2.或者提前启动视频采集,

  • 3.或者改成 OnIncomingPacket(std::unique_ptr packet),把字节长度的判断改成判断音视频帧类型,有音频帧就启动probe模块

remb报文对探测的干扰

  • 慢启动阶段等待探测结果时state_ == State::kWaitingForProbingResult,接收到remb的报文会影响 current_target_ 的大小,从而触发创建新的探测计划

  • bitrate_bps > min_bitrate_to_probe_further_bps_ 当 remb码率大于 min_bitrate_to_probe_further_bps_时会触发重新探测,本来会以上一个探测码率的2倍作为下一个探测码率,结果现在以remb码率作为下一个探测码率

  • 可以禁用 remb的报文 ,或者使能 packet_feedback_only_

rtx 模式的启用 默认使用非rtx模式

  • padding数据生成有两种做法:

    1. rtx 模式:如果启用RTX, WebRTC会从历史发送的packet中取一包数据,把类型改为padding,直到请求的padding_size用尽,并且使用RTX通道专用的序列号序列 问题在于接收端能从这种数据包中恢复媒体数据吗
    1. 非rtx 模式:生成新的RTP Padding包,长度范围:50 - 224字节,超过224分段发,通常224字节满额发送,原因如下
void RtpVideoSender::ConfigureSsrcs() {
  for (const RtpStreamSender& stream : rtp_streams_) {
    stream.rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads);
  }
}

1.stream.rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted | kRtxRedundantPayloads); 现在是非rtx模式,
改成 stream.rtp_rtcp->SetRtxSendStatus(kRtxRedundantPayloads); 就可以启动rtx模式,不知道接收端效果如何

2.启动rtx模式后, packet_history_ 不为空的时候才使用rtx模式,否则使用非rtx模式
std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPayloadPaddingPacket(rtc::FunctionView<std::unique_ptr<RtpPacketToSend>(const RtpPacketToSend&)> encapsulate) {
  StoredPacket* best_packet = nullptr;
  if (enable_padding_prio_ && !padding_priority_.empty()) {
    auto best_packet_it = padding_priority_.begin();
    best_packet = *best_packet_it;
  } else if (!enable_padding_prio_ && !packet_history_.empty()) { // packet_history_ 不为空的时候才使用rtx模式,否则使用非rtx模式
    for (auto it = packet_history_.rbegin(); it != packet_history_.rend();
         ++it) {
      if (it->packet_ != nullptr) {
        best_packet = &(*it);
        break;
      }
    }
  }
}
  • 41
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code&bug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值