Index: webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc b/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc |
index 713fba87707c1a22b041aab31202b574482659eb..0a152092713a00cd9590bdb16708a8cbce938cb5 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc |
@@ -10,31 +10,26 @@ |
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h" |
-#include <assert.h> |
-#include <stdlib.h> |
-#include <string.h> // memset |
- |
#include <algorithm> |
#include <limits> |
-#include <set> |
#include "webrtc/base/checks.h" |
#include "webrtc/base/logging.h" |
-#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
+#include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" |
+#include "webrtc/system_wrappers/include/clock.h" |
namespace webrtc { |
+namespace { |
+constexpr size_t kMinPacketRequestBytes = 50; |
+} // namespace |
+constexpr size_t RtpPacketHistory::kMaxCapacity; |
-static const int kMinPacketRequestBytes = 50; |
- |
-RTPPacketHistory::RTPPacketHistory(Clock* clock) |
- : clock_(clock), |
- store_(false), |
- prev_index_(0) {} |
+RtpPacketHistory::RtpPacketHistory(Clock* clock) |
+ : clock_(clock), store_(false), prev_index_(0) {} |
-RTPPacketHistory::~RTPPacketHistory() { |
-} |
+RtpPacketHistory::~RtpPacketHistory() {} |
-void RTPPacketHistory::SetStorePacketsStatus(bool enable, |
+void RtpPacketHistory::SetStorePacketsStatus(bool enable, |
uint16_t number_to_store) { |
rtc::CritScope cs(&critsect_); |
if (enable) { |
@@ -42,21 +37,21 @@ void RTPPacketHistory::SetStorePacketsStatus(bool enable, |
LOG(LS_WARNING) << "Purging packet history in order to re-set status."; |
Free(); |
} |
- assert(!store_); |
+ RTC_DCHECK(!store_); |
Allocate(number_to_store); |
} else { |
Free(); |
} |
} |
-void RTPPacketHistory::Allocate(size_t number_to_store) { |
- assert(number_to_store > 0); |
- assert(number_to_store <= kMaxHistoryCapacity); |
+void RtpPacketHistory::Allocate(size_t number_to_store) { |
+ RTC_DCHECK_GT(number_to_store, 0u); |
+ RTC_DCHECK_LE(number_to_store, kMaxCapacity); |
store_ = true; |
stored_packets_.resize(number_to_store); |
} |
-void RTPPacketHistory::Free() { |
+void RtpPacketHistory::Free() { |
if (!store_) { |
return; |
} |
@@ -67,40 +62,29 @@ void RTPPacketHistory::Free() { |
prev_index_ = 0; |
} |
-bool RTPPacketHistory::StorePackets() const { |
+bool RtpPacketHistory::StorePackets() const { |
rtc::CritScope cs(&critsect_); |
return store_; |
} |
-int32_t RTPPacketHistory::PutRTPPacket(const uint8_t* packet, |
- size_t packet_length, |
- int64_t capture_time_ms, |
- StorageType type) { |
+void RtpPacketHistory::PutRtpPacket(std::unique_ptr<RtpPacketToSend> packet, |
+ StorageType type, |
+ bool sent) { |
+ RTC_DCHECK(packet); |
rtc::CritScope cs(&critsect_); |
if (!store_) { |
- return 0; |
- } |
- |
- assert(packet); |
- assert(packet_length > 3); |
- |
- if (packet_length > IP_PACKET_SIZE) { |
- LOG(LS_WARNING) << "Failed to store RTP packet with length: " |
- << packet_length; |
- return -1; |
+ return; |
} |
- const uint16_t seq_num = (packet[2] << 8) + packet[3]; |
- |
// 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_].length > 0 && |
+ if (stored_packets_[prev_index_].packet && |
stored_packets_[prev_index_].send_time == 0) { |
size_t current_size = static_cast<uint16_t>(stored_packets_.size()); |
- if (current_size < kMaxHistoryCapacity) { |
+ if (current_size < kMaxCapacity) { |
size_t expanded_size = std::max(current_size * 3 / 2, current_size + 1); |
- expanded_size = std::min(expanded_size, kMaxHistoryCapacity); |
+ 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. |
@@ -108,91 +92,48 @@ int32_t RTPPacketHistory::PutRTPPacket(const uint8_t* packet, |
} |
} |
- // Store packet |
- // TODO(sprang): Overhaul this class and get rid of this copy step. |
- // (Finally introduce the RtpPacket class?) |
- memcpy(stored_packets_[prev_index_].data, packet, packet_length); |
- stored_packets_[prev_index_].length = packet_length; |
- |
- stored_packets_[prev_index_].sequence_number = seq_num; |
- stored_packets_[prev_index_].time_ms = |
- (capture_time_ms > 0) ? capture_time_ms : clock_->TimeInMilliseconds(); |
- stored_packets_[prev_index_].send_time = 0; // Packet not sent. |
+ // Store packet. |
+ if (packet->capture_time_ms() <= 0) |
+ packet->set_capture_time_ms(clock_->TimeInMilliseconds()); |
+ stored_packets_[prev_index_].sequence_number = packet->SequenceNumber(); |
+ stored_packets_[prev_index_].send_time = |
+ (sent ? clock_->TimeInMilliseconds() : 0); |
stored_packets_[prev_index_].storage_type = type; |
stored_packets_[prev_index_].has_been_retransmitted = false; |
+ stored_packets_[prev_index_].packet = std::move(packet); |
++prev_index_; |
if (prev_index_ >= stored_packets_.size()) { |
prev_index_ = 0; |
} |
- return 0; |
} |
-bool RTPPacketHistory::HasRTPPacket(uint16_t sequence_number) const { |
+bool RtpPacketHistory::HasRtpPacket(uint16_t sequence_number) const { |
rtc::CritScope cs(&critsect_); |
if (!store_) { |
return false; |
} |
- int32_t index = 0; |
- bool found = FindSeqNum(sequence_number, &index); |
- if (!found) { |
- return false; |
- } |
- |
- if (stored_packets_[index].length == 0) { |
- // Invalid length. |
- return false; |
- } |
- return true; |
+ int unused_index = 0; |
+ return FindSeqNum(sequence_number, &unused_index); |
} |
-bool RTPPacketHistory::SetSent(uint16_t sequence_number) { |
+std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndSetSendTime( |
+ uint16_t sequence_number, |
+ int64_t min_elapsed_time_ms, |
+ bool retransmit) { |
rtc::CritScope cs(&critsect_); |
if (!store_) { |
- return false; |
+ return nullptr; |
} |
- int32_t index = 0; |
- bool found = FindSeqNum(sequence_number, &index); |
- if (!found) { |
- return false; |
- } |
- |
- // Send time already set. |
- if (stored_packets_[index].send_time != 0) { |
- return false; |
- } |
- |
- stored_packets_[index].send_time = clock_->TimeInMilliseconds(); |
- return true; |
-} |
- |
-bool RTPPacketHistory::GetPacketAndSetSendTime(uint16_t sequence_number, |
- int64_t min_elapsed_time_ms, |
- bool retransmit, |
- uint8_t* packet, |
- size_t* packet_length, |
- int64_t* stored_time_ms) { |
- rtc::CritScope cs(&critsect_); |
- RTC_CHECK_GE(*packet_length, static_cast<size_t>(IP_PACKET_SIZE)); |
- if (!store_) |
- return false; |
- |
- int32_t index = 0; |
- bool found = FindSeqNum(sequence_number, &index); |
- if (!found) { |
+ int index = 0; |
+ if (!FindSeqNum(sequence_number, &index)) { |
LOG(LS_WARNING) << "No match for getting seqNum " << sequence_number; |
- return false; |
- } |
- |
- size_t length = stored_packets_[index].length; |
- assert(length <= IP_PACKET_SIZE); |
- if (length == 0) { |
- LOG(LS_WARNING) << "No match for getting seqNum " << sequence_number |
- << ", len " << length; |
- return false; |
+ return nullptr; |
} |
+ RTC_DCHECK_EQ(sequence_number, |
+ stored_packets_[index].packet->SequenceNumber()); |
// Verify elapsed time since last retrieve, but only for retransmissions and |
// always send packet upon first retransmission request. |
@@ -200,59 +141,45 @@ bool RTPPacketHistory::GetPacketAndSetSendTime(uint16_t sequence_number, |
if (min_elapsed_time_ms > 0 && retransmit && |
stored_packets_[index].has_been_retransmitted && |
((now - stored_packets_[index].send_time) < min_elapsed_time_ms)) { |
- return false; |
+ return nullptr; |
} |
if (retransmit) { |
if (stored_packets_[index].storage_type == kDontRetransmit) { |
- // No bytes copied since this packet shouldn't be retransmitted or is |
- // of zero size. |
- return false; |
+ // No bytes copied since this packet shouldn't be retransmitted. |
+ return nullptr; |
} |
stored_packets_[index].has_been_retransmitted = true; |
} |
stored_packets_[index].send_time = clock_->TimeInMilliseconds(); |
- GetPacket(index, packet, packet_length, stored_time_ms); |
- return true; |
+ return GetPacket(index); |
} |
-void RTPPacketHistory::GetPacket(int index, |
- uint8_t* packet, |
- size_t* packet_length, |
- int64_t* stored_time_ms) const { |
- // Get packet. |
- size_t length = stored_packets_[index].length; |
- memcpy(packet, stored_packets_[index].data, length); |
- *packet_length = length; |
- *stored_time_ms = stored_packets_[index].time_ms; |
+std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacket(int index) const { |
+ const RtpPacketToSend& stored = *stored_packets_[index].packet; |
+ return std::unique_ptr<RtpPacketToSend>(new RtpPacketToSend(stored)); |
} |
-bool RTPPacketHistory::GetBestFittingPacket(uint8_t* packet, |
- size_t* packet_length, |
- int64_t* stored_time_ms) { |
+std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetBestFittingPacket( |
+ size_t packet_length) const { |
rtc::CritScope cs(&critsect_); |
if (!store_) |
- return false; |
- int index = FindBestFittingPacket(*packet_length); |
+ return nullptr; |
+ int index = FindBestFittingPacket(packet_length); |
if (index < 0) |
- return false; |
- GetPacket(index, packet, packet_length, stored_time_ms); |
- return true; |
+ return nullptr; |
+ return GetPacket(index); |
} |
-// private, lock should already be taken |
-bool RTPPacketHistory::FindSeqNum(uint16_t sequence_number, |
- int32_t* index) const { |
- uint16_t temp_sequence_number = 0; |
+bool RtpPacketHistory::FindSeqNum(uint16_t sequence_number, int* index) const { |
if (prev_index_ > 0) { |
*index = prev_index_ - 1; |
- temp_sequence_number = stored_packets_[*index].sequence_number; |
} else { |
- *index = stored_packets_.size() - 1; |
- temp_sequence_number = stored_packets_[*index].sequence_number; // wrap |
+ *index = stored_packets_.size() - 1; // Wrap. |
} |
+ uint16_t temp_sequence_number = stored_packets_[*index].sequence_number; |
- int32_t idx = (prev_index_ - 1) - (temp_sequence_number - sequence_number); |
+ int idx = *index - (temp_sequence_number - sequence_number); |
if (idx >= 0 && idx < static_cast<int>(stored_packets_.size())) { |
*index = idx; |
temp_sequence_number = stored_packets_[*index].sequence_number; |
@@ -268,24 +195,21 @@ bool RTPPacketHistory::FindSeqNum(uint16_t sequence_number, |
} |
} |
} |
- if (temp_sequence_number == sequence_number) { |
- // We found a match. |
- return true; |
- } |
- return false; |
+ return temp_sequence_number == sequence_number && |
+ stored_packets_[*index].packet; |
} |
-int RTPPacketHistory::FindBestFittingPacket(size_t size) const { |
+int RtpPacketHistory::FindBestFittingPacket(size_t size) const { |
if (size < kMinPacketRequestBytes || stored_packets_.empty()) |
return -1; |
size_t min_diff = std::numeric_limits<size_t>::max(); |
int best_index = -1; // Returned unchanged if we don't find anything. |
for (size_t i = 0; i < stored_packets_.size(); ++i) { |
- if (stored_packets_[i].length == 0) |
+ if (!stored_packets_[i].packet) |
continue; |
- size_t diff = (stored_packets_[i].length > size) |
- ? (stored_packets_[i].length - size) |
- : (size - stored_packets_[i].length); |
+ size_t stored_size = stored_packets_[i].packet->size(); |
+ size_t diff = |
+ (stored_size > size) ? (stored_size - size) : (size - stored_size); |
if (diff < min_diff) { |
min_diff = diff; |
best_index = static_cast<int>(i); |
@@ -294,6 +218,4 @@ int RTPPacketHistory::FindBestFittingPacket(size_t size) const { |
return best_index; |
} |
-RTPPacketHistory::StoredPacket::StoredPacket() {} |
- |
} // namespace webrtc |