(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的包,还有因为缓存不够,扩容导致的不连续的包。