流媒体学习之路(WebRTC)——音频NackTracker优化思路(8)

流媒体学习之路(WebRTC)——音频NackTracker优化思路(8)

——
我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost

目标:可以让大家熟悉各类Qos能力、带宽估计能力,提供每个环节关键参数调节接口并实现一个json全配置,提供全面的可视化算法观察能力。

欢迎大家使用
——


  在讲具体内容之前插一句嘴,从GCC分析(3)开始,我们将针对GCC的实现细节去分析它设计的原理,让我们理解这些类存在的意义,不再带大家去串具体的流程了。

一、NackTracker逻辑分析

1.1 设计思路

  NackTracker是WebRTC根据NetEq逻辑设计的Nack逻辑,相比于视频的重传,音频考虑的问题相对更多一些。(本文的音频NackTracker逻辑来源于WebRTC105版本)

//
// The NackTracker class keeps track of the lost packets, an estimate of
// time-to-play for each packet is also given.
//
// Every time a packet is pushed into NetEq, LastReceivedPacket() has to be
// called to update the NACK list.
//
// Every time 10ms audio is pulled from NetEq LastDecodedPacket() should be
// called, and time-to-play is updated at that moment.
//
// If packet N is received, any packet prior to N which has not arrived is
// considered lost, and should be labeled as "missing" (the size of
// the list might be limited and older packet eliminated from the list).
//
// The NackTracker class has to know about the sample rate of the packets to
// compute time-to-play. So sample rate should be set as soon as the first
// packet is received. If there is a change in the receive codec (sender changes
// codec) then NackTracker should be reset. This is because NetEQ would flush
// its buffer and re-transmission is meaning less for old packet. Therefore, in
// that case, after reset the sampling rate has to be updated.
//
// Thread Safety
// =============
// Please note that this class in not thread safe. The class must be protected
// if different APIs are called from different threads.
//

  上面是NackTracker注释的设计思路,意思是:
  1.统计丢失的数据包,并给出每个数据包播放的估计时间;
  2.每次数据进入NetEq时,都会调用 LastReceivedPacket() 更新 NackList;
  3.每次从NetEq队列提取10ms的音频,都需要调用LastDecodedPacket(),更新播放时间记录;
  4.如果接收到数据包N,则在N之前尚未到达的任何数据包都被视为丢失,并应标记为“丢失”(列表的大小可能受到限制,旧的数据包将从列表中删除——这里记录的默认值是500)。
  5.NackTracker类必须知道数据包的采样率才能计算播放时间。因此,一旦接收到第一个数据包,就应该设置采样率。如果接收编解码器发生变化(发送方更改编解码器),则应重置NackTracker。这是因为NetEQ会清空其缓冲区,而重新传输对旧数据包来说意义不大。因此,在这种情况下,在重置之后,必须更新采样率。

1.2 代码

void NackTracker::UpdateLastReceivedPacket(uint16_t sequence_number,
                                           uint32_t timestamp) {
   
  // Just record the value of sequence number and timestamp if this is the
  // first packet.
  // 记录第一个数据包接收信息
  if (!any_rtp_received_) {
   
    sequence_num_last_received_rtp_ = sequence_number;
    timestamp_last_received_rtp_ = timestamp;
    any_rtp_received_ = true;
    // If no packet is decoded, to have a reasonable estimate of time-to-play
    // use the given values.
    if (!any_rtp_decoded_) {
   
      sequence_num_last_decoded_rtp_ = sequence_number;
      timestamp_last_decoded_rtp_ = timestamp;
    }
    return;
  }

  // 序号已接到直接返回
  if (sequence_number == sequence_num_last_received_rtp_)
    return;

  // Received RTP should not be in the list.
  nack_list_.erase(sequence_number);

  // If this is an old sequence number, no more action is required, return.
  // 如果是旧数据直接返回
  if (IsNewerSequenceNumber(sequence_num_last_received_rtp_, sequence_number))
    return;

  // 更新丢包率估计
  UpdatePacketLossRate(sequence_number - sequence_num_last_received_rtp_ - 1);

  // 更新nack列表
  UpdateList(sequence_number, timestamp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值