| 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..d96785d94c7040abc1a4065b02a32127b285ffd6 100644
|
| --- a/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc
|
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc
|
| @@ -10,17 +10,11 @@
|
|
|
| #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"
|
|
|
| namespace webrtc {
|
|
|
| @@ -28,76 +22,62 @@ static const int kMinPacketRequestBytes = 50;
|
|
|
| RTPPacketHistory::RTPPacketHistory(Clock* clock)
|
| : clock_(clock),
|
| - store_(false),
|
| prev_index_(0) {}
|
|
|
| RTPPacketHistory::~RTPPacketHistory() {
|
| }
|
|
|
| -void RTPPacketHistory::SetStorePacketsStatus(bool enable,
|
| - uint16_t number_to_store) {
|
| - rtc::CritScope cs(&critsect_);
|
| - if (enable) {
|
| - if (store_) {
|
| +void RTPPacketHistory::SetStoreSize(uint16_t number_to_store) {
|
| + rtc::CritScope lock(&critsect_);
|
| + if (number_to_store > 0) {
|
| + if (!stored_packets_.empty()) {
|
| LOG(LS_WARNING) << "Purging packet history in order to re-set status.";
|
| Free();
|
| }
|
| - assert(!store_);
|
| Allocate(number_to_store);
|
| } else {
|
| Free();
|
| }
|
| }
|
|
|
| +bool RTPPacketHistory::StorePackets() const {
|
| + rtc::CritScope lock(&critsect_);
|
| + return !stored_packets_.empty();
|
| +}
|
| +
|
| void RTPPacketHistory::Allocate(size_t number_to_store) {
|
| - assert(number_to_store > 0);
|
| - assert(number_to_store <= kMaxHistoryCapacity);
|
| - store_ = true;
|
| + RTC_DCHECK_GT(number_to_store, 0u);
|
| + RTC_DCHECK_LE(number_to_store, kMaxHistoryCapacity);
|
| stored_packets_.resize(number_to_store);
|
| }
|
|
|
| void RTPPacketHistory::Free() {
|
| - if (!store_) {
|
| - return;
|
| - }
|
| -
|
| stored_packets_.clear();
|
| -
|
| - store_ = false;
|
| prev_index_ = 0;
|
| }
|
|
|
| -bool RTPPacketHistory::StorePackets() const {
|
| - rtc::CritScope cs(&critsect_);
|
| - return store_;
|
| +RtpPacketToSend* RTPPacketHistory::PutRtpPacket(
|
| + std::unique_ptr<RtpPacketToSend>* packet,
|
| + StorageType type) {
|
| + RTC_DCHECK(packet);
|
| + RTC_DCHECK(*packet);
|
| + rtc::CritScope lock(&critsect_);
|
| + if (stored_packets_.empty()) // aka !StorePackets()
|
| + return packet->get();
|
| + RTC_DCHECK_LT(prev_index_, stored_packets_.size());
|
| + return StorePacket(std::move(*packet), type);
|
| }
|
|
|
| -int32_t RTPPacketHistory::PutRTPPacket(const uint8_t* packet,
|
| - size_t packet_length,
|
| - int64_t capture_time_ms,
|
| - StorageType type) {
|
| - 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;
|
| - }
|
| -
|
| - const uint16_t seq_num = (packet[2] << 8) + packet[3];
|
| -
|
| +RtpPacketToSend* RTPPacketHistory::StorePacket(
|
| + std::unique_ptr<RtpPacketToSend> packet,
|
| + StorageType type) {
|
| + RTC_DCHECK(packet);
|
| // 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 &&
|
| - stored_packets_[prev_index_].send_time == 0) {
|
| - size_t current_size = static_cast<uint16_t>(stored_packets_.size());
|
| + if (stored_packets_[prev_index_].packet &&
|
| + stored_packets_[prev_index_].packet->send_time_ms() == 0) {
|
| + size_t current_size = stored_packets_.size();
|
| if (current_size < kMaxHistoryCapacity) {
|
| size_t expanded_size = std::max(current_size * 3 / 2, current_size + 1);
|
| expanded_size = std::min(expanded_size, kMaxHistoryCapacity);
|
| @@ -108,16 +88,13 @@ 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;
|
| + RtpPacketToSend* stored_packet = packet.get();
|
| + if (packet->capture_time_ms() == 0)
|
| + packet->set_capture_time_ms(clock_->TimeInMilliseconds());
|
|
|
| - 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.
|
| + RTC_DCHECK_EQ(packet->send_time_ms(), 0);
|
| + stored_packets_[prev_index_].sequence_number = packet->SequenceNumber();
|
| + stored_packets_[prev_index_].packet = std::move(packet);
|
| stored_packets_[prev_index_].storage_type = type;
|
| stored_packets_[prev_index_].has_been_retransmitted = false;
|
|
|
| @@ -125,73 +102,24 @@ int32_t RTPPacketHistory::PutRTPPacket(const uint8_t* packet,
|
| if (prev_index_ >= stored_packets_.size()) {
|
| prev_index_ = 0;
|
| }
|
| - return 0;
|
| + return stored_packet;
|
| }
|
|
|
| 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;
|
| -}
|
| -
|
| -bool RTPPacketHistory::SetSent(uint16_t sequence_number) {
|
| - rtc::CritScope cs(&critsect_);
|
| - if (!store_) {
|
| - return false;
|
| - }
|
| -
|
| - 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;
|
| + rtc::CritScope lock(&critsect_);
|
| + size_t index = 0;
|
| + return FindSeqNum(sequence_number, &index);
|
| }
|
|
|
| -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;
|
| +RtpPacketToSend* RTPPacketHistory::GetPacket(uint16_t sequence_number,
|
| + int64_t min_elapsed_time_ms,
|
| + bool retransmit) {
|
| + rtc::CritScope lock(&critsect_);
|
| + size_t index = 0;
|
| bool found = FindSeqNum(sequence_number, &index);
|
| if (!found) {
|
| 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;
|
| }
|
|
|
| // Verify elapsed time since last retrieve, but only for retransmissions and
|
| @@ -199,60 +127,42 @@ bool RTPPacketHistory::GetPacketAndSetSendTime(uint16_t sequence_number,
|
| int64_t now = clock_->TimeInMilliseconds();
|
| 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;
|
| + ((now - stored_packets_[index].packet->send_time_ms()) <
|
| + min_elapsed_time_ms)) {
|
| + 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;
|
| + // Packet shouldn't be retransmitted or is of zero size.
|
| + 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;
|
| -}
|
|
|
| -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;
|
| + return stored_packets_[index].packet.get();
|
| }
|
|
|
| -bool RTPPacketHistory::GetBestFittingPacket(uint8_t* packet,
|
| - size_t* packet_length,
|
| - int64_t* stored_time_ms) {
|
| - rtc::CritScope cs(&critsect_);
|
| - if (!store_)
|
| - return false;
|
| - int index = FindBestFittingPacket(*packet_length);
|
| +RtpPacketToSend* RTPPacketHistory::GetBestFittingPacket(size_t packet_length) {
|
| + rtc::CritScope lock(&critsect_);
|
| + int index = FindBestFittingPacket(packet_length);
|
| if (index < 0)
|
| - return false;
|
| - GetPacket(index, packet, packet_length, stored_time_ms);
|
| - return true;
|
| + return nullptr;
|
| + return stored_packets_[index].packet.get();
|
| }
|
|
|
| -// private, lock should already be taken
|
| bool RTPPacketHistory::FindSeqNum(uint16_t sequence_number,
|
| - int32_t* index) const {
|
| - uint16_t temp_sequence_number = 0;
|
| + size_t* index) const {
|
| + if (stored_packets_.empty())
|
| + return false;
|
| 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);
|
| + int32_t 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,11 +178,8 @@ 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 {
|
| @@ -281,11 +188,11 @@ int RTPPacketHistory::FindBestFittingPacket(size_t size) const {
|
| 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 diff = (stored_packets_[i].packet->size() > size)
|
| + ? (stored_packets_[i].packet->size() - size)
|
| + : (size - stored_packets_[i].packet->size());
|
| if (diff < min_diff) {
|
| min_diff = diff;
|
| best_index = static_cast<int>(i);
|
| @@ -293,7 +200,4 @@ int RTPPacketHistory::FindBestFittingPacket(size_t size) const {
|
| }
|
| return best_index;
|
| }
|
| -
|
| -RTPPacketHistory::StoredPacket::StoredPacket() {}
|
| -
|
| } // namespace webrtc
|
|
|