webrtc 代码学习(二十九)初步解决 video 在丢包环境下的卡顿问题,优化待续

初步解决 video 在丢包环境下的卡顿问题
作者:LanPZzzz

文章目录

          • 1. 实验测试,在持续的丢包20% 基础上,视频在前几分钟内画面流畅,但是随着时间越来越多,画面最终卡住
          • 2. 为什么会出现这种现象,分析如下:
          • 3. 初步怎么解决,在接收到 nack 数据的时候,直接就发送数据包到socket,保证 nack 包能够最先发送,当然这样是有代价的,就是你不知道什么时候会crash(T_T........),初步修改如下:
          • 4.优化

1. 实验测试,在持续的丢包20% 基础上,视频在前几分钟内画面流畅,但是随着时间越来越多,画面最终卡住
2. 为什么会出现这种现象,分析如下:
  1. 没有接收到 video 数据包,发送 nack rtcp 数据到sender
  2. sender 在接收到 nack 数据包情况下,从历史数据中找到丢失包,放入到 video pace 中
  3. 同时 video pace 还接收 encoder 的数据包
  4. 使用线程去 从 video pace 中读取数据包发送到socket 中
  5. 经过上面的就导致发送nack 包不及时,接收端又会重新发送nack 请求,导致堆积nack 数据发送不及时,对方丢帧,直至不能解码为止
3. 初步怎么解决,在接收到 nack 数据的时候,直接就发送数据包到socket,保证 nack 包能够最先发送,当然这样是有代价的,就是你不知道什么时候会crash(T_T…),初步修改如下:

RTPSender::ReSendPacket (\modules\rtp_rtcp\source\rtp_sender.cc)

  RTC_DCHECK(retransmission_rate_limiter_);
  // Check if we're overusing retransmission bitrate.
  // TODO(sprang): Add histograms for nack success or failure reasons.
  这里把返回去掉,保证nack 包可以发送
  if (!retransmission_rate_limiter_->TryUseRate(packet_size)) {
    //return -1;
  }

  // by LanPZzzz
  if (video_) {
    这个是用于日志的,打印时间,可以不要的
    std::string strTime = GetLogTime();
    RTC_LOG(LS_ERROR) << strTime  << ", ReSendPacket send [seq:"
                      << stored_packet->rtp_sequence_number << "]"; 
	
  std::unique_ptr packet =
        packet_history_.GetPacketAndSetSendTime(packet_id, true);
    if (!packet) {
      // Packet could theoretically time out between the first check and this
      // one.
      RTC_LOG(LS_ERROR) << strTime  << ", ReSendPacket send [seq:"
                        << stored_packet->rtp_sequence_number << "] no packet"; 
      return 0;
    }

    //const bool rtx = (RtxStatus() & kRtxRetransmitted) > 0;
	// by LanPZzzz, when resend, PrepareAndSendPacket second param must false
    重传时候,PrepareAndSendPacket 的第二个参数 false,保证可能发送nack 包
    if (!PrepareAndSendPacket(std::move(packet), false, true, PacedPacketInfo()))
      return -1;

    return packet_size;
  }

AudioSendStream::OnPacketAdded (\audio\audio_send_stream.cc)

void AudioSendStream::OnPacketAdded(uint32_t ssrc, uint16_t seq_num) {
  //RTC_DCHECK(pacer_thread_checker_.CalledOnValidThread());  这里要注释掉

当然这样修改后,nack 包可以及时到达,未知错误就不知道了

4.优化

你可能感兴趣的:(webrtc学习)