webrtc在发送端缓存RTP包的方法

(1)rtp包的发送:

 在rtp_sender.cc中,SendToNetwork方法中,每次发包前,都在packet_history_中进行备份,代码如下:

bool RTPSender::SendToNetwork(std::unique_ptr packet,
                              StorageType storage,
                              RtpPacketSender::Priority priority) {
 ...
    if (ssrc == flexfec_ssrc) {
      // Store FlexFEC packets in the history here, so they can be found
      // when the pacer calls TimeToSendPacket.
      flexfec_packet_history_.PutRtpPacket(std::move(packet), storage, false);
    } else {
      packet_history_.PutRtpPacket(std::move(packet), storage, false);
    }

    paced_sender_->InsertPacket(priority, ssrc, seq_no, corrected_time_ms,
                                payload_length, false);
...
}

(2)rtp包的存储:

packet_history_的实现在rtp_packet_history.cc中,这里用一个vector 是stored_packets_完成rtp包存储,vector stored_packets_长度固定为600,最大可以扩大到9600

static const int kMinSendSidePacketHistorySize = 600;
static constexpr size_t kMaxCapacity = 9600;

分配空间的方法是:

void RtpPacketHistory::Allocate(size_t number_to_store) {
...
  stored_packets_.resize(number_to_store);
}
void RtpPacketHistory::PutRtpPacket(std::unique_ptr packet,
                                    StorageType type,
                                    bool sent) {
  
...
  // If index we're about to overwrite contains a packet that has not
  // yet been sent (probably pending in paced sender), we need to expand
  // the buffer.
  if (stored_packets_[prev_index_].packet &&
      stored_packets_[prev_index_].send_time == 0) {
    size_t current_size = static_cast(stored_packets_.size());
    if (current_size < kMaxCapacity) {
      size_t expanded_size = std::max(current_size * 3 / 2, current_size + 1);
      expanded_size = std::min(expanded_size, kMaxCapacity);
      Allocate(expanded_size);
      // Causes discontinuity, but that's OK-ish. FindSeqNum() will still work,
      // but may be slower - at least until buffer has wrapped around once.
      prev_index_ = current_size;
    }
  }
....
}

每次向stored_packets_里放入rtp包的时候,都会检查stored_packets_的容量,如注释所示,如果要放的包的位置里还有包,那么扩容,不过这样会破坏缓存的连续性,在查找的时候,需要遍历了。

(3)rtp包的查找获取:

核心代码是rtp_packet_history.cc的FindSeqNum方法

ool RtpPacketHistory::FindSeqNum(uint16_t sequence_number, int* index) const {
  if (prev_index_ > 0) {
    *index = prev_index_ - 1;
  } else {
    *index = stored_packets_.size() - 1;  // Wrap.
  }
  uint16_t temp_sequence_number = stored_packets_[*index].sequence_number;

  int idx = *index - (temp_sequence_number - sequence_number);
  if (idx >= 0 && idx < static_cast(stored_packets_.size())) {
    *index = idx;
    temp_sequence_number = stored_packets_[*index].sequence_number;
  }

  if (temp_sequence_number != sequence_number) {
    // We did not found a match, search all.
    for (uint16_t m = 0; m < stored_packets_.size(); m++) {
      if (stored_packets_[m].sequence_number == sequence_number) {
        *index = m;
        temp_sequence_number = stored_packets_[*index].sequence_number;
        break;
      }
    }
  }
  return temp_sequence_number == sequence_number &&
         stored_packets_[*index].packet;
}

分两部分,第一部分是通过prev_index来连续获取seq号,这里根据prev_index>0处理了stored_packets_的循环问题。

                   第二部分是通过遍历处理不连续的包,包括seq超过65535的包,还有因为缓存不够,扩容导致的不连续的包。

你可能感兴趣的:(c++)