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

Side by Side Diff: webrtc/modules/video_coding/packet_buffer.cc

Issue 2399373002: Only advance |first_seq_num_| if packets are explicitly cleared from the PacketBuffer. (Closed)
Patch Set: Compile fix 2 Created 4 years, 2 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) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 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
(...skipping 24 matching lines...) Expand all
35 PacketBuffer::PacketBuffer(Clock* clock, 35 PacketBuffer::PacketBuffer(Clock* clock,
36 size_t start_buffer_size, 36 size_t start_buffer_size,
37 size_t max_buffer_size, 37 size_t max_buffer_size,
38 OnReceivedFrameCallback* received_frame_callback) 38 OnReceivedFrameCallback* received_frame_callback)
39 : clock_(clock), 39 : clock_(clock),
40 size_(start_buffer_size), 40 size_(start_buffer_size),
41 max_size_(max_buffer_size), 41 max_size_(max_buffer_size),
42 first_seq_num_(0), 42 first_seq_num_(0),
43 last_seq_num_(0), 43 last_seq_num_(0),
44 first_packet_received_(false), 44 first_packet_received_(false),
45 is_cleared_to_first_seq_num_(false),
45 data_buffer_(start_buffer_size), 46 data_buffer_(start_buffer_size),
46 sequence_buffer_(start_buffer_size), 47 sequence_buffer_(start_buffer_size),
47 received_frame_callback_(received_frame_callback) { 48 received_frame_callback_(received_frame_callback) {
48 RTC_DCHECK_LE(start_buffer_size, max_buffer_size); 49 RTC_DCHECK_LE(start_buffer_size, max_buffer_size);
49 // Buffer size must always be a power of 2. 50 // Buffer size must always be a power of 2.
50 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0); 51 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0);
51 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0); 52 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0);
52 } 53 }
53 54
54 PacketBuffer::~PacketBuffer() {} 55 PacketBuffer::~PacketBuffer() {
56 Clear();
57 }
55 58
56 bool PacketBuffer::InsertPacket(const VCMPacket& packet) { 59 bool PacketBuffer::InsertPacket(const VCMPacket& packet) {
57 rtc::CritScope lock(&crit_); 60 rtc::CritScope lock(&crit_);
58 uint16_t seq_num = packet.seqNum; 61 uint16_t seq_num = packet.seqNum;
59 size_t index = seq_num % size_; 62 size_t index = seq_num % size_;
60 63
61 if (!first_packet_received_) { 64 if (!first_packet_received_) {
62 first_seq_num_ = seq_num - 1; 65 first_seq_num_ = seq_num;
63 last_seq_num_ = seq_num; 66 last_seq_num_ = seq_num;
64 first_packet_received_ = true; 67 first_packet_received_ = true;
68 } else if (AheadOf(first_seq_num_, seq_num)) {
69 // If we have explicitly cleared past this packet then it's old,
70 // don't insert it.
71 if (is_cleared_to_first_seq_num_)
72 return false;
73
74 first_seq_num_ = seq_num;
65 } 75 }
66 76
67 if (sequence_buffer_[index].used) { 77 if (sequence_buffer_[index].used) {
68 // Duplicate packet, do nothing. 78 // Duplicate packet, do nothing.
69 if (data_buffer_[index].seqNum == packet.seqNum) 79 if (data_buffer_[index].seqNum == packet.seqNum)
70 return true; 80 return true;
71 81
72 // The packet buffer is full, try to expand the buffer. 82 // The packet buffer is full, try to expand the buffer.
73 while (ExpandBufferSize() && sequence_buffer_[seq_num % size_].used) { 83 while (ExpandBufferSize() && sequence_buffer_[seq_num % size_].used) {
74 } 84 }
(...skipping 24 matching lines...) Expand all
99 memcpy(payload, packet.dataPtr, packet.sizeBytes); 109 memcpy(payload, packet.dataPtr, packet.sizeBytes);
100 data_buffer_[index].dataPtr = payload; 110 data_buffer_[index].dataPtr = payload;
101 } 111 }
102 112
103 FindFrames(seq_num); 113 FindFrames(seq_num);
104 return true; 114 return true;
105 } 115 }
106 116
107 void PacketBuffer::ClearTo(uint16_t seq_num) { 117 void PacketBuffer::ClearTo(uint16_t seq_num) {
108 rtc::CritScope lock(&crit_); 118 rtc::CritScope lock(&crit_);
109 size_t index = first_seq_num_ % size_; 119
110 while (AheadOf<uint16_t>(seq_num, first_seq_num_ + 1)) { 120 // If the packet buffer was cleared between a frame was created and returned.
111 index = (index + 1) % size_; 121 if (!first_packet_received_)
112 ++first_seq_num_; 122 return;
123
124 is_cleared_to_first_seq_num_ = true;
125 while (AheadOrAt<uint16_t>(seq_num, first_seq_num_)) {
126 size_t index = first_seq_num_ % size_;
113 delete[] data_buffer_[index].dataPtr; 127 delete[] data_buffer_[index].dataPtr;
114 data_buffer_[index].dataPtr = nullptr; 128 data_buffer_[index].dataPtr = nullptr;
115 sequence_buffer_[index].used = false; 129 sequence_buffer_[index].used = false;
130 ++first_seq_num_;
116 } 131 }
117 } 132 }
118 133
134 void PacketBuffer::Clear() {
135 rtc::CritScope lock(&crit_);
136 for (size_t i = 0; i < size_; ++i) {
137 delete[] data_buffer_[i].dataPtr;
138 data_buffer_[i].dataPtr = nullptr;
139 sequence_buffer_[i].used = false;
140 }
141
142 first_packet_received_ = false;
143 is_cleared_to_first_seq_num_ = false;
144 }
145
119 bool PacketBuffer::ExpandBufferSize() { 146 bool PacketBuffer::ExpandBufferSize() {
120 if (size_ == max_size_) 147 if (size_ == max_size_) {
148 LOG(LS_WARNING) << "PacketBuffer is already at max size (" << max_size_
149 << "), failed to increase size.";
121 return false; 150 return false;
151 }
122 152
123 size_t new_size = std::min(max_size_, 2 * size_); 153 size_t new_size = std::min(max_size_, 2 * size_);
124 std::vector<VCMPacket> new_data_buffer(new_size); 154 std::vector<VCMPacket> new_data_buffer(new_size);
125 std::vector<ContinuityInfo> new_sequence_buffer(new_size); 155 std::vector<ContinuityInfo> new_sequence_buffer(new_size);
126 for (size_t i = 0; i < size_; ++i) { 156 for (size_t i = 0; i < size_; ++i) {
127 if (sequence_buffer_[i].used) { 157 if (sequence_buffer_[i].used) {
128 size_t index = sequence_buffer_[i].seq_num % new_size; 158 size_t index = sequence_buffer_[i].seq_num % new_size;
129 new_sequence_buffer[index] = sequence_buffer_[i]; 159 new_sequence_buffer[index] = sequence_buffer_[i];
130 new_data_buffer[index] = data_buffer_[i]; 160 new_data_buffer[index] = data_buffer_[i];
131 } 161 }
132 } 162 }
133 size_ = new_size; 163 size_ = new_size;
134 sequence_buffer_ = std::move(new_sequence_buffer); 164 sequence_buffer_ = std::move(new_sequence_buffer);
135 data_buffer_ = std::move(new_data_buffer); 165 data_buffer_ = std::move(new_data_buffer);
166 LOG(LS_INFO) << "PacketBuffer size expanded to " << new_size;
136 return true; 167 return true;
137 } 168 }
138 169
139 bool PacketBuffer::IsContinuous(uint16_t seq_num) const { 170 bool PacketBuffer::PotentialNewFrame(uint16_t seq_num) const {
140 size_t index = seq_num % size_; 171 size_t index = seq_num % size_;
141 int prev_index = index > 0 ? index - 1 : size_ - 1; 172 int prev_index = index > 0 ? index - 1 : size_ - 1;
142 173
143 if (!sequence_buffer_[index].used) 174 if (!sequence_buffer_[index].used)
144 return false; 175 return false;
145 if (sequence_buffer_[index].frame_created) 176 if (sequence_buffer_[index].frame_created)
146 return false; 177 return false;
147 if (sequence_buffer_[index].frame_begin) 178 if (sequence_buffer_[index].frame_begin &&
179 (!sequence_buffer_[prev_index].used ||
180 AheadOf(seq_num, sequence_buffer_[prev_index].seq_num))) {
181 // The reason we only return true if this packet is the first packet of the
182 // frame and the sequence number is newer than the packet with the previous
183 // index is because we want to avoid an inifite loop in the case where
184 // a single frame containing more packets than the current size of the
185 // packet buffer is inserted.
148 return true; 186 return true;
stefan-webrtc 2016/10/31 15:13:56 Do we have a test case for this?
philipel 2016/10/31 15:16:33 Yes, SingleFrameExpandsBuffer
187 }
149 if (!sequence_buffer_[prev_index].used) 188 if (!sequence_buffer_[prev_index].used)
150 return false; 189 return false;
151 if (sequence_buffer_[prev_index].seq_num != 190 if (sequence_buffer_[prev_index].seq_num !=
152 static_cast<uint16_t>(seq_num - 1)) 191 sequence_buffer_[index].seq_num - 1) {
153 return false; 192 return false;
193 }
154 if (sequence_buffer_[prev_index].continuous) 194 if (sequence_buffer_[prev_index].continuous)
155 return true; 195 return true;
156 196
157 return false; 197 return false;
158 } 198 }
159 199
160 void PacketBuffer::FindFrames(uint16_t seq_num) { 200 void PacketBuffer::FindFrames(uint16_t seq_num) {
161 size_t index = seq_num % size_; 201 while (PotentialNewFrame(seq_num)) {
162 while (IsContinuous(seq_num)) { 202 size_t index = seq_num % size_;
163 sequence_buffer_[index].continuous = true; 203 sequence_buffer_[index].continuous = true;
164 204
165 // If all packets of the frame is continuous, find the first packet of the 205 // If all packets of the frame is continuous, find the first packet of the
166 // frame and create an RtpFrameObject. 206 // frame and create an RtpFrameObject.
167 if (sequence_buffer_[index].frame_end) { 207 if (sequence_buffer_[index].frame_end) {
168 size_t frame_size = 0; 208 size_t frame_size = 0;
169 int max_nack_count = -1; 209 int max_nack_count = -1;
170 uint16_t start_seq_num = seq_num; 210 uint16_t start_seq_num = seq_num;
171 211
172 // Find the start index by searching backward until the packet with 212 // Find the start index by searching backward until the packet with
(...skipping 12 matching lines...) Expand all
185 start_seq_num--; 225 start_seq_num--;
186 } 226 }
187 227
188 std::unique_ptr<RtpFrameObject> frame( 228 std::unique_ptr<RtpFrameObject> frame(
189 new RtpFrameObject(this, start_seq_num, seq_num, frame_size, 229 new RtpFrameObject(this, start_seq_num, seq_num, frame_size,
190 max_nack_count, clock_->TimeInMilliseconds())); 230 max_nack_count, clock_->TimeInMilliseconds()));
191 231
192 received_frame_callback_->OnReceivedFrame(std::move(frame)); 232 received_frame_callback_->OnReceivedFrame(std::move(frame));
193 } 233 }
194 234
195 index = (index + 1) % size_;
196 ++seq_num; 235 ++seq_num;
197 } 236 }
198 } 237 }
199 238
200 void PacketBuffer::ReturnFrame(RtpFrameObject* frame) { 239 void PacketBuffer::ReturnFrame(RtpFrameObject* frame) {
201 rtc::CritScope lock(&crit_); 240 rtc::CritScope lock(&crit_);
202 size_t index = frame->first_seq_num() % size_; 241 size_t index = frame->first_seq_num() % size_;
203 size_t end = (frame->last_seq_num() + 1) % size_; 242 size_t end = (frame->last_seq_num() + 1) % size_;
204 uint16_t seq_num = frame->first_seq_num(); 243 uint16_t seq_num = frame->first_seq_num();
205 while (index != end) { 244 while (index != end) {
206 if (sequence_buffer_[index].seq_num == seq_num) { 245 if (sequence_buffer_[index].seq_num == seq_num) {
207 delete[] data_buffer_[index].dataPtr; 246 delete[] data_buffer_[index].dataPtr;
208 data_buffer_[index].dataPtr = nullptr; 247 data_buffer_[index].dataPtr = nullptr;
209 sequence_buffer_[index].used = false; 248 sequence_buffer_[index].used = false;
210 } 249 }
211 250
212 index = (index + 1) % size_; 251 index = (index + 1) % size_;
213 ++seq_num; 252 ++seq_num;
214 } 253 }
215
216 index = first_seq_num_ % size_;
217 while (AheadOf<uint16_t>(last_seq_num_, first_seq_num_) &&
218 !sequence_buffer_[index].used) {
219 ++first_seq_num_;
220 index = (index + 1) % size_;
221 }
222 } 254 }
223 255
224 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, 256 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame,
225 uint8_t* destination) { 257 uint8_t* destination) {
226 rtc::CritScope lock(&crit_); 258 rtc::CritScope lock(&crit_);
227 259
228 size_t index = frame.first_seq_num() % size_; 260 size_t index = frame.first_seq_num() % size_;
229 size_t end = (frame.last_seq_num() + 1) % size_; 261 size_t end = (frame.last_seq_num() + 1) % size_;
230 uint16_t seq_num = frame.first_seq_num(); 262 uint16_t seq_num = frame.first_seq_num();
231 while (index != end) { 263 while (index != end) {
(...skipping 15 matching lines...) Expand all
247 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) { 279 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) {
248 rtc::CritScope lock(&crit_); 280 rtc::CritScope lock(&crit_);
249 size_t index = seq_num % size_; 281 size_t index = seq_num % size_;
250 if (!sequence_buffer_[index].used || 282 if (!sequence_buffer_[index].used ||
251 seq_num != sequence_buffer_[index].seq_num) { 283 seq_num != sequence_buffer_[index].seq_num) {
252 return nullptr; 284 return nullptr;
253 } 285 }
254 return &data_buffer_[index]; 286 return &data_buffer_[index];
255 } 287 }
256 288
257 void PacketBuffer::Clear() {
258 rtc::CritScope lock(&crit_);
259 for (size_t i = 0; i < size_; ++i)
260 sequence_buffer_[i].used = false;
261
262 first_packet_received_ = false;
263 }
264
265 int PacketBuffer::AddRef() const { 289 int PacketBuffer::AddRef() const {
266 return rtc::AtomicOps::Increment(&ref_count_); 290 return rtc::AtomicOps::Increment(&ref_count_);
267 } 291 }
268 292
269 int PacketBuffer::Release() const { 293 int PacketBuffer::Release() const {
270 int count = rtc::AtomicOps::Decrement(&ref_count_); 294 int count = rtc::AtomicOps::Decrement(&ref_count_);
271 if (!count) { 295 if (!count) {
272 delete this; 296 delete this;
273 } 297 }
274 return count; 298 return count;
275 } 299 }
276 300
277 } // namespace video_coding 301 } // namespace video_coding
278 } // namespace webrtc 302 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/packet_buffer.h ('k') | webrtc/modules/video_coding/video_packet_buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698