| 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 | 
|  |