Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(566)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtp_packet_history.cc

Issue 1945773002: RtpPacketHistory rewritten to use RtpPacket class. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h" 11 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h"
12 12
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <string.h> // memset
16
17 #include <algorithm> 13 #include <algorithm>
18 #include <limits> 14 #include <limits>
19 #include <set>
20 15
21 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
22 #include "webrtc/base/logging.h" 17 #include "webrtc/base/logging.h"
23 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 18 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
19 #include "webrtc/system_wrappers/include/clock.h"
24 20
25 namespace webrtc { 21 namespace webrtc {
22 namespace {
23 constexpr size_t kMinPacketRequestBytes = 50;
24 } // namespace
25 constexpr size_t RtpPacketHistory::kMaxCapacity;
26 26
27 static const int kMinPacketRequestBytes = 50; 27 RtpPacketHistory::RtpPacketHistory(Clock* clock)
28 : clock_(clock), store_(false), prev_index_(0) {}
28 29
29 RTPPacketHistory::RTPPacketHistory(Clock* clock) 30 RtpPacketHistory::~RtpPacketHistory() {}
30 : clock_(clock),
31 store_(false),
32 prev_index_(0) {}
33 31
34 RTPPacketHistory::~RTPPacketHistory() { 32 void RtpPacketHistory::SetStorePacketsStatus(bool enable,
35 }
36
37 void RTPPacketHistory::SetStorePacketsStatus(bool enable,
38 uint16_t number_to_store) { 33 uint16_t number_to_store) {
39 rtc::CritScope cs(&critsect_); 34 rtc::CritScope cs(&critsect_);
40 if (enable) { 35 if (enable) {
41 if (store_) { 36 if (store_) {
42 LOG(LS_WARNING) << "Purging packet history in order to re-set status."; 37 LOG(LS_WARNING) << "Purging packet history in order to re-set status.";
43 Free(); 38 Free();
44 } 39 }
45 assert(!store_); 40 RTC_DCHECK(!store_);
46 Allocate(number_to_store); 41 Allocate(number_to_store);
47 } else { 42 } else {
48 Free(); 43 Free();
49 } 44 }
50 } 45 }
51 46
52 void RTPPacketHistory::Allocate(size_t number_to_store) { 47 void RtpPacketHistory::Allocate(size_t number_to_store) {
53 assert(number_to_store > 0); 48 RTC_DCHECK_GT(number_to_store, 0u);
54 assert(number_to_store <= kMaxHistoryCapacity); 49 RTC_DCHECK_LE(number_to_store, kMaxCapacity);
55 store_ = true; 50 store_ = true;
56 stored_packets_.resize(number_to_store); 51 stored_packets_.resize(number_to_store);
57 } 52 }
58 53
59 void RTPPacketHistory::Free() { 54 void RtpPacketHistory::Free() {
60 if (!store_) { 55 if (!store_) {
61 return; 56 return;
62 } 57 }
63 58
64 stored_packets_.clear(); 59 stored_packets_.clear();
65 60
66 store_ = false; 61 store_ = false;
67 prev_index_ = 0; 62 prev_index_ = 0;
68 } 63 }
69 64
70 bool RTPPacketHistory::StorePackets() const { 65 bool RtpPacketHistory::StorePackets() const {
71 rtc::CritScope cs(&critsect_); 66 rtc::CritScope cs(&critsect_);
72 return store_; 67 return store_;
73 } 68 }
74 69
75 int32_t RTPPacketHistory::PutRTPPacket(const uint8_t* packet, 70 void RtpPacketHistory::PutRtpPacket(std::unique_ptr<RtpPacketToSend> packet,
76 size_t packet_length, 71 StorageType type,
77 int64_t capture_time_ms, 72 bool sent) {
78 StorageType type) { 73 RTC_DCHECK(packet);
79 rtc::CritScope cs(&critsect_); 74 rtc::CritScope cs(&critsect_);
80 if (!store_) { 75 if (!store_) {
81 return 0; 76 return;
82 } 77 }
83 78
84 assert(packet);
85 assert(packet_length > 3);
86
87 if (packet_length > IP_PACKET_SIZE) {
88 LOG(LS_WARNING) << "Failed to store RTP packet with length: "
89 << packet_length;
90 return -1;
91 }
92
93 const uint16_t seq_num = (packet[2] << 8) + packet[3];
94
95 // If index we're about to overwrite contains a packet that has not 79 // If index we're about to overwrite contains a packet that has not
96 // yet been sent (probably pending in paced sender), we need to expand 80 // yet been sent (probably pending in paced sender), we need to expand
97 // the buffer. 81 // the buffer.
98 if (stored_packets_[prev_index_].length > 0 && 82 if (stored_packets_[prev_index_].packet &&
99 stored_packets_[prev_index_].send_time == 0) { 83 stored_packets_[prev_index_].send_time == 0) {
100 size_t current_size = static_cast<uint16_t>(stored_packets_.size()); 84 size_t current_size = static_cast<uint16_t>(stored_packets_.size());
101 if (current_size < kMaxHistoryCapacity) { 85 if (current_size < kMaxCapacity) {
102 size_t expanded_size = std::max(current_size * 3 / 2, current_size + 1); 86 size_t expanded_size = std::max(current_size * 3 / 2, current_size + 1);
103 expanded_size = std::min(expanded_size, kMaxHistoryCapacity); 87 expanded_size = std::min(expanded_size, kMaxCapacity);
104 Allocate(expanded_size); 88 Allocate(expanded_size);
105 // Causes discontinuity, but that's OK-ish. FindSeqNum() will still work, 89 // Causes discontinuity, but that's OK-ish. FindSeqNum() will still work,
106 // but may be slower - at least until buffer has wrapped around once. 90 // but may be slower - at least until buffer has wrapped around once.
107 prev_index_ = current_size; 91 prev_index_ = current_size;
108 } 92 }
109 } 93 }
110 94
111 // Store packet 95 // Store packet.
112 // TODO(sprang): Overhaul this class and get rid of this copy step. 96 if (packet->capture_time_ms() <= 0)
113 // (Finally introduce the RtpPacket class?) 97 packet->set_capture_time_ms(clock_->TimeInMilliseconds());
114 memcpy(stored_packets_[prev_index_].data, packet, packet_length); 98 stored_packets_[prev_index_].sequence_number = packet->SequenceNumber();
115 stored_packets_[prev_index_].length = packet_length; 99 stored_packets_[prev_index_].send_time =
116 100 (sent ? clock_->TimeInMilliseconds() : 0);
117 stored_packets_[prev_index_].sequence_number = seq_num;
118 stored_packets_[prev_index_].time_ms =
119 (capture_time_ms > 0) ? capture_time_ms : clock_->TimeInMilliseconds();
120 stored_packets_[prev_index_].send_time = 0; // Packet not sent.
121 stored_packets_[prev_index_].storage_type = type; 101 stored_packets_[prev_index_].storage_type = type;
122 stored_packets_[prev_index_].has_been_retransmitted = false; 102 stored_packets_[prev_index_].has_been_retransmitted = false;
103 stored_packets_[prev_index_].packet = std::move(packet);
123 104
124 ++prev_index_; 105 ++prev_index_;
125 if (prev_index_ >= stored_packets_.size()) { 106 if (prev_index_ >= stored_packets_.size()) {
126 prev_index_ = 0; 107 prev_index_ = 0;
127 } 108 }
128 return 0;
129 } 109 }
130 110
131 bool RTPPacketHistory::HasRTPPacket(uint16_t sequence_number) const { 111 bool RtpPacketHistory::HasRtpPacket(uint16_t sequence_number) const {
132 rtc::CritScope cs(&critsect_); 112 rtc::CritScope cs(&critsect_);
133 if (!store_) { 113 if (!store_) {
134 return false; 114 return false;
135 } 115 }
136 116
137 int32_t index = 0; 117 int unused_index = 0;
138 bool found = FindSeqNum(sequence_number, &index); 118 return FindSeqNum(sequence_number, &unused_index);
139 if (!found) { 119 }
140 return false; 120
121 std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacketAndSetSendTime(
122 uint16_t sequence_number,
123 int64_t min_elapsed_time_ms,
124 bool retransmit) {
125 rtc::CritScope cs(&critsect_);
126 if (!store_) {
127 return nullptr;
141 } 128 }
142 129
143 if (stored_packets_[index].length == 0) { 130 int index = 0;
144 // Invalid length. 131 if (!FindSeqNum(sequence_number, &index)) {
145 return false; 132 LOG(LS_WARNING) << "No match for getting seqNum " << sequence_number;
133 return nullptr;
146 } 134 }
147 return true; 135 RTC_DCHECK_EQ(sequence_number,
148 } 136 stored_packets_[index].packet->SequenceNumber());
149
150 bool RTPPacketHistory::SetSent(uint16_t sequence_number) {
151 rtc::CritScope cs(&critsect_);
152 if (!store_) {
153 return false;
154 }
155
156 int32_t index = 0;
157 bool found = FindSeqNum(sequence_number, &index);
158 if (!found) {
159 return false;
160 }
161
162 // Send time already set.
163 if (stored_packets_[index].send_time != 0) {
164 return false;
165 }
166
167 stored_packets_[index].send_time = clock_->TimeInMilliseconds();
168 return true;
169 }
170
171 bool RTPPacketHistory::GetPacketAndSetSendTime(uint16_t sequence_number,
172 int64_t min_elapsed_time_ms,
173 bool retransmit,
174 uint8_t* packet,
175 size_t* packet_length,
176 int64_t* stored_time_ms) {
177 rtc::CritScope cs(&critsect_);
178 RTC_CHECK_GE(*packet_length, static_cast<size_t>(IP_PACKET_SIZE));
179 if (!store_)
180 return false;
181
182 int32_t index = 0;
183 bool found = FindSeqNum(sequence_number, &index);
184 if (!found) {
185 LOG(LS_WARNING) << "No match for getting seqNum " << sequence_number;
186 return false;
187 }
188
189 size_t length = stored_packets_[index].length;
190 assert(length <= IP_PACKET_SIZE);
191 if (length == 0) {
192 LOG(LS_WARNING) << "No match for getting seqNum " << sequence_number
193 << ", len " << length;
194 return false;
195 }
196 137
197 // Verify elapsed time since last retrieve, but only for retransmissions and 138 // Verify elapsed time since last retrieve, but only for retransmissions and
198 // always send packet upon first retransmission request. 139 // always send packet upon first retransmission request.
199 int64_t now = clock_->TimeInMilliseconds(); 140 int64_t now = clock_->TimeInMilliseconds();
200 if (min_elapsed_time_ms > 0 && retransmit && 141 if (min_elapsed_time_ms > 0 && retransmit &&
201 stored_packets_[index].has_been_retransmitted && 142 stored_packets_[index].has_been_retransmitted &&
202 ((now - stored_packets_[index].send_time) < min_elapsed_time_ms)) { 143 ((now - stored_packets_[index].send_time) < min_elapsed_time_ms)) {
203 return false; 144 return nullptr;
204 } 145 }
205 146
206 if (retransmit) { 147 if (retransmit) {
207 if (stored_packets_[index].storage_type == kDontRetransmit) { 148 if (stored_packets_[index].storage_type == kDontRetransmit) {
208 // No bytes copied since this packet shouldn't be retransmitted or is 149 // No bytes copied since this packet shouldn't be retransmitted.
209 // of zero size. 150 return nullptr;
210 return false;
211 } 151 }
212 stored_packets_[index].has_been_retransmitted = true; 152 stored_packets_[index].has_been_retransmitted = true;
213 } 153 }
214 stored_packets_[index].send_time = clock_->TimeInMilliseconds(); 154 stored_packets_[index].send_time = clock_->TimeInMilliseconds();
215 GetPacket(index, packet, packet_length, stored_time_ms); 155 return GetPacket(index);
216 return true;
217 } 156 }
218 157
219 void RTPPacketHistory::GetPacket(int index, 158 std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetPacket(int index) const {
220 uint8_t* packet, 159 const RtpPacketToSend& stored = *stored_packets_[index].packet;
221 size_t* packet_length, 160 return std::unique_ptr<RtpPacketToSend>(new RtpPacketToSend(stored));
222 int64_t* stored_time_ms) const {
223 // Get packet.
224 size_t length = stored_packets_[index].length;
225 memcpy(packet, stored_packets_[index].data, length);
226 *packet_length = length;
227 *stored_time_ms = stored_packets_[index].time_ms;
228 } 161 }
229 162
230 bool RTPPacketHistory::GetBestFittingPacket(uint8_t* packet, 163 std::unique_ptr<RtpPacketToSend> RtpPacketHistory::GetBestFittingPacket(
231 size_t* packet_length, 164 size_t packet_length) const {
232 int64_t* stored_time_ms) {
233 rtc::CritScope cs(&critsect_); 165 rtc::CritScope cs(&critsect_);
234 if (!store_) 166 if (!store_)
235 return false; 167 return nullptr;
236 int index = FindBestFittingPacket(*packet_length); 168 int index = FindBestFittingPacket(packet_length);
237 if (index < 0) 169 if (index < 0)
238 return false; 170 return nullptr;
239 GetPacket(index, packet, packet_length, stored_time_ms); 171 return GetPacket(index);
240 return true;
241 } 172 }
242 173
243 // private, lock should already be taken 174 bool RtpPacketHistory::FindSeqNum(uint16_t sequence_number, int* index) const {
244 bool RTPPacketHistory::FindSeqNum(uint16_t sequence_number,
245 int32_t* index) const {
246 uint16_t temp_sequence_number = 0;
247 if (prev_index_ > 0) { 175 if (prev_index_ > 0) {
248 *index = prev_index_ - 1; 176 *index = prev_index_ - 1;
249 temp_sequence_number = stored_packets_[*index].sequence_number;
250 } else { 177 } else {
251 *index = stored_packets_.size() - 1; 178 *index = stored_packets_.size() - 1; // Wrap.
252 temp_sequence_number = stored_packets_[*index].sequence_number; // wrap
253 } 179 }
180 uint16_t temp_sequence_number = stored_packets_[*index].sequence_number;
254 181
255 int32_t idx = (prev_index_ - 1) - (temp_sequence_number - sequence_number); 182 int idx = *index - (temp_sequence_number - sequence_number);
256 if (idx >= 0 && idx < static_cast<int>(stored_packets_.size())) { 183 if (idx >= 0 && idx < static_cast<int>(stored_packets_.size())) {
257 *index = idx; 184 *index = idx;
258 temp_sequence_number = stored_packets_[*index].sequence_number; 185 temp_sequence_number = stored_packets_[*index].sequence_number;
259 } 186 }
260 187
261 if (temp_sequence_number != sequence_number) { 188 if (temp_sequence_number != sequence_number) {
262 // We did not found a match, search all. 189 // We did not found a match, search all.
263 for (uint16_t m = 0; m < stored_packets_.size(); m++) { 190 for (uint16_t m = 0; m < stored_packets_.size(); m++) {
264 if (stored_packets_[m].sequence_number == sequence_number) { 191 if (stored_packets_[m].sequence_number == sequence_number) {
265 *index = m; 192 *index = m;
266 temp_sequence_number = stored_packets_[*index].sequence_number; 193 temp_sequence_number = stored_packets_[*index].sequence_number;
267 break; 194 break;
268 } 195 }
269 } 196 }
270 } 197 }
271 if (temp_sequence_number == sequence_number) { 198 return temp_sequence_number == sequence_number &&
272 // We found a match. 199 stored_packets_[*index].packet;
273 return true;
274 }
275 return false;
276 } 200 }
277 201
278 int RTPPacketHistory::FindBestFittingPacket(size_t size) const { 202 int RtpPacketHistory::FindBestFittingPacket(size_t size) const {
279 if (size < kMinPacketRequestBytes || stored_packets_.empty()) 203 if (size < kMinPacketRequestBytes || stored_packets_.empty())
280 return -1; 204 return -1;
281 size_t min_diff = std::numeric_limits<size_t>::max(); 205 size_t min_diff = std::numeric_limits<size_t>::max();
282 int best_index = -1; // Returned unchanged if we don't find anything. 206 int best_index = -1; // Returned unchanged if we don't find anything.
283 for (size_t i = 0; i < stored_packets_.size(); ++i) { 207 for (size_t i = 0; i < stored_packets_.size(); ++i) {
284 if (stored_packets_[i].length == 0) 208 if (!stored_packets_[i].packet)
285 continue; 209 continue;
286 size_t diff = (stored_packets_[i].length > size) 210 size_t stored_size = stored_packets_[i].packet->size();
287 ? (stored_packets_[i].length - size) 211 size_t diff =
288 : (size - stored_packets_[i].length); 212 (stored_size > size) ? (stored_size - size) : (size - stored_size);
289 if (diff < min_diff) { 213 if (diff < min_diff) {
290 min_diff = diff; 214 min_diff = diff;
291 best_index = static_cast<int>(i); 215 best_index = static_cast<int>(i);
292 } 216 }
293 } 217 }
294 return best_index; 218 return best_index;
295 } 219 }
296 220
297 RTPPacketHistory::StoredPacket::StoredPacket() {}
298
299 } // namespace webrtc 221 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_packet_history.h ('k') | webrtc/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698