Index: media/cast/transport/rtp_sender/packet_storage/packet_storage.cc |
diff --git a/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc b/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc |
index 6206d02f429b1d6c6f560160b0a972dd45a0e4a6..ea1eb0b7c41f2111d66901f73ebb26d3c8c50677 100644 |
--- a/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc |
+++ b/media/cast/transport/rtp_sender/packet_storage/packet_storage.cc |
@@ -12,28 +12,49 @@ |
namespace cast { |
namespace transport { |
+// Limit the max time delay to avoid frame id wrap around; 256 / 60 fps. |
+const int kMaxAllowedTimeStoredMs = 4000; |
+ |
typedef PacketMap::iterator PacketMapIterator; |
+typedef TimeToPacketMap::iterator TimeToPacketIterator; |
-PacketStorage::PacketStorage(int stored_frames) |
- : stored_frames_(stored_frames) { |
+ |
+PacketStorage::PacketStorage(base::TickClock* clock, int max_time_stored_ms) |
+ : clock_(clock) { |
+ max_time_stored_ = base::TimeDelta::FromMilliseconds(max_time_stored_ms); |
+ DCHECK_LE(max_time_stored_ms, kMaxAllowedTimeStoredMs) << "Invalid argument"; |
} |
PacketStorage::~PacketStorage() { |
} |
-bool PacketStorage::IsValid() const { |
- return stored_frames_ > 0 && stored_frames_ <= kMaxStoredFrames; |
-} |
+void PacketStorage::CleanupOldPackets(base::TimeTicks now) { |
+ TimeToPacketIterator time_it = time_to_packet_map_.begin(); |
-void PacketStorage::CleanupOldPackets(uint32 current_frame_id) { |
- uint32 frame_to_remove = current_frame_id - stored_frames_; |
- while (!stored_packets_.empty()) { |
- if (IsOlderFrameId(stored_packets_.begin()->first.first, |
- frame_to_remove)) { |
- stored_packets_.erase(stored_packets_.begin()); |
- } else { |
+ // Check max size. |
+ while (time_to_packet_map_.size() >= kMaxStoredPackets) { |
+ PacketMapIterator store_it = stored_packets_.find(time_it->second); |
+ |
+ // We should always find the packet. |
+ DCHECK(store_it != stored_packets_.end()) << "Invalid state"; |
+ time_to_packet_map_.erase(time_it); |
+ stored_packets_.erase(store_it); |
+ time_it = time_to_packet_map_.begin(); |
+ } |
+ |
+ // Time out old packets. |
+ while (time_it != time_to_packet_map_.end()) { |
+ if (now < time_it->first + max_time_stored_) { |
break; |
} |
+ // Packet too old. |
+ PacketMapIterator store_it = stored_packets_.find(time_it->second); |
+ |
+ // We should always find the packet. |
+ DCHECK(store_it != stored_packets_.end()) << "Invalid state"; |
+ time_to_packet_map_.erase(time_it); |
+ stored_packets_.erase(store_it); |
+ time_it = time_to_packet_map_.begin(); |
} |
} |
@@ -41,8 +62,11 @@ |
uint16 packet_id, |
const PacketKey& key, |
PacketRef packet) { |
- CleanupOldPackets(frame_id); |
- StorageIndex index(frame_id, packet_id); |
+ base::TimeTicks now = clock_->NowTicks(); |
+ CleanupOldPackets(now); |
+ |
+ // Internally we only use the 8 LSB of the frame id. |
+ uint32 index = ((0xff & frame_id) << 16) + packet_id; |
PacketMapIterator it = stored_packets_.find(index); |
if (it != stored_packets_.end()) { |
// We have already saved this. |
@@ -50,6 +74,7 @@ |
return; |
} |
stored_packets_[index] = std::make_pair(key, packet); |
+ time_to_packet_map_.insert(std::make_pair(now, index)); |
} |
void PacketStorage::GetPackets( |
@@ -84,10 +109,11 @@ |
} |
} |
-bool PacketStorage::GetPacket32(uint32 frame_id, |
- uint16 packet_id, |
- SendPacketVector* packets) { |
- StorageIndex index(frame_id, packet_id); |
+bool PacketStorage::GetPacket(uint8 frame_id, |
+ uint16 packet_id, |
+ SendPacketVector* packets) { |
+ // Internally we only use the 8 LSB of the frame id. |
+ uint32 index = (static_cast<uint32>(frame_id) << 16) + packet_id; |
PacketMapIterator it = stored_packets_.find(index); |
if (it == stored_packets_.end()) { |
return false; |
@@ -111,26 +137,6 @@ |
return true; |
} |
-bool PacketStorage::GetPacket(uint8 frame_id_8bit, |
- uint16 packet_id, |
- SendPacketVector* packets) { |
- if (stored_packets_.empty()) { |
- return false; |
- } |
- uint32 last_stored = stored_packets_.rbegin()->first.first; |
- uint32 frame_id_32bit = (last_stored & ~0xFF) | frame_id_8bit; |
- if (IsNewerFrameId(frame_id_32bit, last_stored)) { |
- frame_id_32bit -= 0x100; |
- } |
- DCHECK_EQ(frame_id_8bit, frame_id_32bit & 0xff); |
- DCHECK(IsOlderFrameId(frame_id_32bit, last_stored) && |
- IsNewerFrameId(frame_id_32bit + stored_frames_ + 1, last_stored)) |
- << " 32bit: " << frame_id_32bit |
- << " 8bit: " << static_cast<int>(frame_id_8bit) |
- << " last_stored: " << last_stored; |
- return GetPacket32(frame_id_32bit, packet_id, packets); |
-} |
- |
} // namespace transport |
} // namespace cast |
} // namespace media |