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

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

Issue 1847193003: Convert Vp8 Rtp headers to frame references. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Feedback fixes/ Created 4 years, 8 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
11 #include "webrtc/modules/video_coding/packet_buffer.h" 11 #include "webrtc/modules/video_coding/packet_buffer.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <limits> 14 #include <limits>
15 15
16 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
17 #include "webrtc/modules/video_coding/frame_object.h" 17 #include "webrtc/modules/video_coding/frame_object.h"
18 #include "webrtc/modules/video_coding/sequence_number_util.h"
19 18
20 namespace webrtc { 19 namespace webrtc {
21 namespace video_coding { 20 namespace video_coding {
22 21
23 PacketBuffer::PacketBuffer(size_t start_buffer_size, 22 PacketBuffer::PacketBuffer(size_t start_buffer_size,
24 size_t max_buffer_size, 23 size_t max_buffer_size,
25 OnCompleteFrameCallback* frame_callback) 24 OnCompleteFrameCallback* frame_callback)
26 : size_(start_buffer_size), 25 : size_(start_buffer_size),
27 max_size_(max_buffer_size), 26 max_size_(max_buffer_size),
27 first_seq_num_(0),
28 last_seq_num_(0), 28 last_seq_num_(0),
29 first_seq_num_(0), 29 first_packet_received_(false),
30 initialized_(false),
31 data_buffer_(start_buffer_size), 30 data_buffer_(start_buffer_size),
32 sequence_buffer_(start_buffer_size), 31 sequence_buffer_(start_buffer_size),
33 frame_callback_(frame_callback) { 32 frame_callback_(frame_callback),
33 last_picture_id_(-1),
34 last_unwrap_(-1) {
34 RTC_DCHECK_LE(start_buffer_size, max_buffer_size); 35 RTC_DCHECK_LE(start_buffer_size, max_buffer_size);
35 // Buffer size must always be a power of 2. 36 // Buffer size must always be a power of 2.
36 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0); 37 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0);
37 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0); 38 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0);
38 } 39 }
39 40
40 bool PacketBuffer::InsertPacket(const VCMPacket& packet) { 41 bool PacketBuffer::InsertPacket(const VCMPacket& packet) {
41 rtc::CritScope lock(&crit_); 42 rtc::CritScope lock(&crit_);
42 uint16_t seq_num = packet.seqNum; 43 uint16_t seq_num = packet.seqNum;
43 int index = seq_num % size_; 44 size_t index = seq_num % size_;
44 45
45 if (!initialized_) { 46 if (!first_packet_received_) {
46 first_seq_num_ = seq_num - 1; 47 first_seq_num_ = seq_num - 1;
47 last_seq_num_ = seq_num; 48 last_seq_num_ = seq_num;
48 initialized_ = true; 49 first_packet_received_ = true;
49 } 50 }
50 51
51 if (sequence_buffer_[index].used) { 52 if (sequence_buffer_[index].used) {
52 // Duplicate packet, do nothing. 53 // Duplicate packet, do nothing.
53 if (data_buffer_[index].seqNum == packet.seqNum) 54 if (data_buffer_[index].seqNum == packet.seqNum)
54 return true; 55 return true;
55 56
56 // The packet buffer is full, try to expand the buffer. 57 // The packet buffer is full, try to expand the buffer.
57 while (ExpandBufferSize() && sequence_buffer_[seq_num % size_].used) { 58 while (ExpandBufferSize() && sequence_buffer_[seq_num % size_].used) {
58 } 59 }
59 index = seq_num % size_; 60 index = seq_num % size_;
60 61
61 // Packet buffer is still full. 62 // Packet buffer is still full.
62 if (sequence_buffer_[index].used) 63 if (sequence_buffer_[index].used)
63 return false; 64 return false;
64 } 65 }
65 66
66 if (AheadOf(seq_num, last_seq_num_)) 67 if (AheadOf(seq_num, last_seq_num_))
67 last_seq_num_ = seq_num; 68 last_seq_num_ = seq_num;
68 69
69 sequence_buffer_[index].frame_begin = packet.isFirstPacket; 70 sequence_buffer_[index].frame_begin = packet.isFirstPacket;
70 sequence_buffer_[index].frame_end = packet.markerBit; 71 sequence_buffer_[index].frame_end = packet.markerBit;
71 sequence_buffer_[index].seq_num = packet.seqNum; 72 sequence_buffer_[index].seq_num = packet.seqNum;
72 sequence_buffer_[index].continuous = false; 73 sequence_buffer_[index].continuous = false;
74 sequence_buffer_[index].frame_created = false;
73 sequence_buffer_[index].used = true; 75 sequence_buffer_[index].used = true;
74 data_buffer_[index] = packet; 76 data_buffer_[index] = packet;
75 77
76 FindCompleteFrames(seq_num); 78 FindFrames(seq_num);
77 return true; 79 return true;
78 } 80 }
79 81
80 void PacketBuffer::ClearTo(uint16_t seq_num) { 82 void PacketBuffer::ClearTo(uint16_t seq_num) {
81 rtc::CritScope lock(&crit_); 83 rtc::CritScope lock(&crit_);
82 int index = first_seq_num_ % size_; 84 size_t index = first_seq_num_ % size_;
83 while (AheadOf<uint16_t>(seq_num, first_seq_num_ + 1)) { 85 while (AheadOf<uint16_t>(seq_num, first_seq_num_ + 1)) {
84 index = (index + 1) % size_; 86 index = (index + 1) % size_;
85 first_seq_num_ = Add<1 << 16>(first_seq_num_, 1); 87 first_seq_num_ = Add<1 << 16>(first_seq_num_, 1);
86 sequence_buffer_[index].used = false; 88 sequence_buffer_[index].used = false;
87 } 89 }
88 } 90 }
89 91
90 bool PacketBuffer::ExpandBufferSize() { 92 bool PacketBuffer::ExpandBufferSize() {
91 if (size_ == max_size_) 93 if (size_ == max_size_)
92 return false; 94 return false;
93 95
94 size_t new_size = std::min(max_size_, 2 * size_); 96 size_t new_size = std::min(max_size_, 2 * size_);
95 std::vector<VCMPacket> new_data_buffer(new_size); 97 std::vector<VCMPacket> new_data_buffer(new_size);
96 std::vector<ContinuityInfo> new_sequence_buffer(new_size); 98 std::vector<ContinuityInfo> new_sequence_buffer(new_size);
97 for (size_t i = 0; i < size_; ++i) { 99 for (size_t i = 0; i < size_; ++i) {
98 if (sequence_buffer_[i].used) { 100 if (sequence_buffer_[i].used) {
99 int index = sequence_buffer_[i].seq_num % new_size; 101 size_t index = sequence_buffer_[i].seq_num % new_size;
100 new_sequence_buffer[index] = sequence_buffer_[i]; 102 new_sequence_buffer[index] = sequence_buffer_[i];
101 new_data_buffer[index] = data_buffer_[i]; 103 new_data_buffer[index] = data_buffer_[i];
102 } 104 }
103 } 105 }
104 size_ = new_size; 106 size_ = new_size;
105 sequence_buffer_ = std::move(new_sequence_buffer); 107 sequence_buffer_ = std::move(new_sequence_buffer);
106 data_buffer_ = std::move(new_data_buffer); 108 data_buffer_ = std::move(new_data_buffer);
107 return true; 109 return true;
108 } 110 }
109 111
110 bool PacketBuffer::IsContinuous(uint16_t seq_num) const { 112 bool PacketBuffer::IsContinuous(uint16_t seq_num) const {
111 int index = seq_num % size_; 113 size_t index = seq_num % size_;
112 int prev_index = index > 0 ? index - 1 : size_ - 1; 114 int prev_index = index > 0 ? index - 1 : size_ - 1;
115
113 if (!sequence_buffer_[index].used) 116 if (!sequence_buffer_[index].used)
114 return false; 117 return false;
118 if (sequence_buffer_[index].frame_created)
119 return false;
115 if (sequence_buffer_[index].frame_begin) 120 if (sequence_buffer_[index].frame_begin)
116 return true; 121 return true;
117 if (!sequence_buffer_[prev_index].used) 122 if (!sequence_buffer_[prev_index].used)
118 return false; 123 return false;
124 if (sequence_buffer_[prev_index].seq_num !=
125 static_cast<uint16_t>(seq_num - 1))
126 return false;
119 if (sequence_buffer_[prev_index].continuous) 127 if (sequence_buffer_[prev_index].continuous)
120 return true; 128 return true;
121 129
122 return false; 130 return false;
123 } 131 }
124 132
125 void PacketBuffer::FindCompleteFrames(uint16_t seq_num) { 133 void PacketBuffer::FindFrames(uint16_t seq_num) {
126 int index = seq_num % size_; 134 size_t index = seq_num % size_;
127 while (IsContinuous(seq_num)) { 135 while (IsContinuous(seq_num)) {
128 sequence_buffer_[index].continuous = true; 136 sequence_buffer_[index].continuous = true;
129 137
130 // If the frame is complete, find the first packet of the frame and 138 // If all packets of the frame is continuous, find the first packet of the
131 // create a FrameObject. 139 // frame and create an RtpFrameObject.
132 if (sequence_buffer_[index].frame_end) { 140 if (sequence_buffer_[index].frame_end) {
133 int rindex = index; 141 int start_index = index;
134 uint16_t start_seq_num = seq_num; 142 uint16_t start_seq_num = seq_num;
135 while (!sequence_buffer_[rindex].frame_begin) { 143
136 rindex = rindex > 0 ? rindex - 1 : size_ - 1; 144 while (!sequence_buffer_[start_index].frame_begin) {
145 sequence_buffer_[start_index].frame_created = true;
146 start_index = start_index > 0 ? start_index - 1 : size_ - 1;
137 start_seq_num--; 147 start_seq_num--;
138 } 148 }
149 sequence_buffer_[start_index].frame_created = true;
139 150
140 std::unique_ptr<FrameObject> frame( 151 std::unique_ptr<RtpFrameObject> frame(
141 new RtpFrameObject(this, 1, start_seq_num, seq_num)); 152 new RtpFrameObject(this, start_seq_num, seq_num));
142 frame_callback_->OnCompleteFrame(std::move(frame)); 153 ManageFrame(std::move(frame));
143 } 154 }
144 155
145 index = (index + 1) % size_; 156 index = (index + 1) % size_;
146 ++seq_num; 157 ++seq_num;
147 } 158 }
148 } 159 }
149 160
150 void PacketBuffer::ReturnFrame(RtpFrameObject* frame) { 161 void PacketBuffer::ReturnFrame(RtpFrameObject* frame) {
151 rtc::CritScope lock(&crit_); 162 rtc::CritScope lock(&crit_);
152 int index = frame->first_packet() % size_; 163 size_t index = frame->first_packet() % size_;
153 int end = (frame->last_packet() + 1) % size_; 164 size_t end = (frame->last_packet() + 1) % size_;
154 uint16_t seq_num = frame->first_packet(); 165 uint16_t seq_num = frame->first_packet();
155 while (index != end) { 166 while (index != end) {
156 if (sequence_buffer_[index].seq_num == seq_num) { 167 if (sequence_buffer_[index].seq_num == seq_num)
157 sequence_buffer_[index].used = false; 168 sequence_buffer_[index].used = false;
158 sequence_buffer_[index].continuous = false; 169
159 }
160 index = (index + 1) % size_; 170 index = (index + 1) % size_;
161 ++seq_num; 171 ++seq_num;
162 } 172 }
163 173
164 index = first_seq_num_ % size_; 174 index = first_seq_num_ % size_;
165 while (AheadOf<uint16_t>(last_seq_num_, first_seq_num_) && 175 while (AheadOf<uint16_t>(last_seq_num_, first_seq_num_) &&
166 !sequence_buffer_[index].used) { 176 !sequence_buffer_[index].used) {
167 ++first_seq_num_; 177 ++first_seq_num_;
168 index = (index + 1) % size_; 178 index = (index + 1) % size_;
169 } 179 }
170 } 180 }
171 181
172 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, 182 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame,
173 uint8_t* destination) { 183 uint8_t* destination) {
174 rtc::CritScope lock(&crit_); 184 rtc::CritScope lock(&crit_);
175 185
176 int index = frame.first_packet() % size_; 186 size_t index = frame.first_packet() % size_;
177 int end = (frame.last_packet() + 1) % size_; 187 size_t end = (frame.last_packet() + 1) % size_;
178 uint16_t seq_num = frame.first_packet(); 188 uint16_t seq_num = frame.first_packet();
179 while (index != end) { 189 while (index != end) {
180 if (!sequence_buffer_[index].used || 190 if (!sequence_buffer_[index].used ||
181 sequence_buffer_[index].seq_num != seq_num) { 191 sequence_buffer_[index].seq_num != seq_num) {
182 return false; 192 return false;
183 } 193 }
184 194
185 const uint8_t* source = data_buffer_[index].dataPtr; 195 const uint8_t* source = data_buffer_[index].dataPtr;
186 size_t length = data_buffer_[index].sizeBytes; 196 size_t length = data_buffer_[index].sizeBytes;
187 memcpy(destination, source, length); 197 memcpy(destination, source, length);
188 destination += length; 198 destination += length;
189 index = (index + 1) % size_; 199 index = (index + 1) % size_;
190 ++seq_num; 200 ++seq_num;
191 } 201 }
192 return true; 202 return true;
193 } 203 }
194 204
205 void PacketBuffer::ManageFrame(std::unique_ptr<RtpFrameObject> frame) {
206 size_t start_index = frame->first_packet() % size_;
207 VideoCodecType codec_type = data_buffer_[start_index].codec;
208
209 if (codec_type == kVideoCodecVP8) {
210 ManageFrameVp8(std::move(frame));
211 } else if (codec_type == kVideoCodecVP9) {
212 // TODO(philipel): ManageFrameVp9(std::move(frame));
213 } else {
214 ManageFrameGeneric(std::move(frame));
215 }
216 }
217
218 void PacketBuffer::RetryStashedFrames() {
219 size_t num_stashed_frames = stashed_frames_.size();
220
221 // Clean up stashed frames if there are to many.
222 while (stashed_frames_.size() > 10)
223 stashed_frames_.pop();
224
225 // Since frames are stashed if there is not enough data to determine their
226 // frame references we should at most check |stashed_frames_.size()| in
227 // order to not pop and push frames in and endless loop.
228 for (size_t i = 0; i < num_stashed_frames && !stashed_frames_.empty(); ++i) {
229 std::unique_ptr<RtpFrameObject> frame = std::move(stashed_frames_.front());
230 stashed_frames_.pop();
231 ManageFrame(std::move(frame));
232 }
233 }
234
235 void PacketBuffer::ManageFrameGeneric(
stefan-webrtc 2016/04/19 10:38:19 Did we decide on whether to break out the ManageFr
philipel 2016/04/19 11:52:07 Yes, I will break out this functionality into sepa
236 std::unique_ptr<RtpFrameObject> frame) {
237 size_t index = frame->first_packet() % size_;
238 const VCMPacket& packet = data_buffer_[index];
239
240 if (packet.frameType == kVideoFrameKey)
241 last_seq_num_for_kf_[frame->last_packet()] = frame->last_packet();
242
243 // Clean up info for old keyframes but make sure to keep info
244 // for the last keyframe.
245 auto clean_to = last_seq_num_for_kf_.lower_bound(frame->last_packet() - 100);
246 if (clean_to != last_seq_num_for_kf_.end() ||
247 clean_to != (--last_seq_num_for_kf_.end())) {
248 last_seq_num_for_kf_.erase(last_seq_num_for_kf_.begin(), clean_to);
249 }
250
251 // Find the last sequence number of the last frame for the keyframe
252 // that this frame indirectly references.
253 auto seq_num_it = last_seq_num_for_kf_.upper_bound(frame->last_packet());
254 seq_num_it--;
255
256 // Make sure the packet sequence numbers are continuous, otherwise stash
257 // this frame.
258 if (packet.frameType == kVideoFrameDelta) {
259 if (seq_num_it->second !=
260 static_cast<uint16_t>(frame->first_packet() - 1)) {
261 stashed_frames_.emplace(std::move(frame));
262 return;
263 }
264 }
265
266 RTC_DCHECK(AheadOrAt(frame->last_packet(), seq_num_it->first));
267
268 // Since keyframes can cause reordering of the frames delivered from
269 // FindFrames() we can't simply assign the picture id according to some
270 // incrementing counter.
271 frame->picture_id = frame->last_packet();
272 frame->num_references = packet.frameType == kVideoFrameDelta;
273 frame->references[0] = seq_num_it->second;
274 seq_num_it->second = frame->picture_id;
275
276 last_picture_id_ = frame->picture_id;
277 frame_callback_->OnCompleteFrame(std::move(frame));
278 RetryStashedFrames();
279 }
280
281 void PacketBuffer::ManageFrameVp8(std::unique_ptr<RtpFrameObject> frame) {
282 size_t index = frame->first_packet() % size_;
283 const VCMPacket& packet = data_buffer_[index];
284 const RTPVideoHeaderVP8& codec_header =
285 packet.codecSpecificHeader.codecHeader.VP8;
286
287 if (codec_header.pictureId == kNoPictureId ||
288 codec_header.temporalIdx == kNoTemporalIdx ||
289 codec_header.tl0PicIdx == kNoTl0PicIdx) {
290 ManageFrameGeneric(std::move(frame));
291 return;
292 }
293
294 frame->picture_id = codec_header.pictureId % kPicIdLength;
295
296 if (last_unwrap_ == -1)
297 last_unwrap_ = codec_header.pictureId;
298
299 if (last_picture_id_ == -1)
300 last_picture_id_ = frame->picture_id;
301
302 // Find if there has been a gap in fully received frames and save the picture
303 // id of those frames in |not_yet_received_frames_|.
304 if (AheadOf<uint8_t, kPicIdLength>(frame->picture_id, last_picture_id_)) {
305 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1);
306 while (last_picture_id_ != frame->picture_id) {
307 not_yet_received_frames_.insert(last_picture_id_);
308 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1);
309 }
310 }
311
312 // Clean up info for base layers that are too old.
313 uint8_t old_tl0_pic_idx = codec_header.tl0PicIdx - 10;
314 auto clean_layer_info_to = layer_info_.lower_bound(old_tl0_pic_idx);
315 layer_info_.erase(layer_info_.begin(), clean_layer_info_to);
316
317 // Clean up info about not yet received frames that are too old.
318 uint16_t old_picture_id = Subtract<kPicIdLength>(frame->picture_id, 20);
319 auto clean_frames_to = not_yet_received_frames_.lower_bound(old_picture_id);
320 not_yet_received_frames_.erase(not_yet_received_frames_.begin(),
321 clean_frames_to);
322
323 if (packet.frameType == kVideoFrameKey) {
324 frame->num_references = 0;
325 layer_info_[codec_header.tl0PicIdx].fill(-1);
326 CompletedFrameVp8(std::move(frame));
327 return;
328 }
329
330 auto layer_info_it = layer_info_.find(codec_header.temporalIdx == 0
331 ? codec_header.tl0PicIdx - 1
332 : codec_header.tl0PicIdx);
333
334 // If we don't have the base layer frame yet, stash this frame.
335 if (layer_info_it == layer_info_.end()) {
336 stashed_frames_.emplace(std::move(frame));
337 return;
338 }
339
340 // A non keyframe base layer frame has been received, copy the layer info
341 // from the previous base layer frame and set a reference to the previous
342 // base layer frame.
343 if (codec_header.temporalIdx == 0) {
344 layer_info_it =
345 layer_info_
346 .insert(make_pair(codec_header.tl0PicIdx, layer_info_it->second))
347 .first;
348 frame->num_references = 1;
349 frame->references[0] = layer_info_it->second[0];
350 CompletedFrameVp8(std::move(frame));
351 return;
352 }
353
354 // Layer sync frame, this frame only references its base layer frame.
355 if (codec_header.layerSync) {
356 frame->num_references = 1;
357 frame->references[0] = layer_info_it->second[0];
358
359 CompletedFrameVp8(std::move(frame));
360 return;
361 }
362
363 // Find all references for this frame.
364 frame->num_references = 0;
365 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) {
366 RTC_DCHECK_NE(-1, layer_info_it->second[layer]);
367 ++frame->num_references;
368 frame->references[layer] = layer_info_it->second[layer];
369
370 // If we have not yet received a frame between this frame and the referenced
371 // frame then we have to wait for that frame to be completed first.
372 auto not_received_frame_it =
373 not_yet_received_frames_.upper_bound(frame->references[layer]);
374 if (not_received_frame_it != not_yet_received_frames_.end() &&
375 AheadOf<uint8_t, kPicIdLength>(frame->picture_id,
376 *not_received_frame_it)) {
377 stashed_frames_.emplace(std::move(frame));
378 return;
379 }
380 }
381
382 CompletedFrameVp8(std::move(frame));
383 }
384
385 void PacketBuffer::CompletedFrameVp8(std::unique_ptr<RtpFrameObject> frame) {
386 size_t index = frame->first_packet() % size_;
387 const VCMPacket& packet = data_buffer_[index];
388 const RTPVideoHeaderVP8& codec_header =
389 packet.codecSpecificHeader.codecHeader.VP8;
390
391 uint8_t tl0_pic_idx = codec_header.tl0PicIdx;
392 uint8_t temporal_index = codec_header.temporalIdx;
393 auto layer_info_it = layer_info_.find(tl0_pic_idx);
394
395 // Update this layer info and newer.
396 while (layer_info_it != layer_info_.end()) {
397 if (layer_info_it->second[temporal_index] != -1 &&
398 AheadOf<uint16_t, kPicIdLength>(layer_info_it->second[temporal_index],
399 frame->picture_id)) {
400 // The frame was not newer, then no subsequent layer info have to be
401 // update.
402 break;
403 }
404
405 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id;
406 ++tl0_pic_idx;
407 layer_info_it = layer_info_.find(tl0_pic_idx);
408 }
409 not_yet_received_frames_.erase(frame->picture_id);
410
411 for (size_t r = 0; r < frame->num_references; ++r)
412 frame->references[r] = UnwrapPictureId(frame->references[r]);
413 frame->picture_id = UnwrapPictureId(frame->picture_id);
414
415 frame_callback_->OnCompleteFrame(std::move(frame));
416 RetryStashedFrames();
417 }
418
419 uint16_t PacketBuffer::UnwrapPictureId(uint16_t picture_id) {
420 if (last_unwrap_ == -1)
421 last_unwrap_ = picture_id;
422
423 uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength;
424 uint16_t diff = MinDiff<uint8_t, kPicIdLength>(unwrap_truncated, picture_id);
425
426 if (AheadOf<uint8_t, kPicIdLength>(picture_id, unwrap_truncated))
427 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff);
428 else
429 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff);
430
431 return last_unwrap_;
432 }
433
195 void PacketBuffer::Flush() { 434 void PacketBuffer::Flush() {
196 rtc::CritScope lock(&crit_); 435 rtc::CritScope lock(&crit_);
197 for (size_t i = 0; i < size_; ++i) { 436 for (size_t i = 0; i < size_; ++i)
198 sequence_buffer_[i].used = false; 437 sequence_buffer_[i].used = false;
199 sequence_buffer_[i].continuous = false; 438
200 } 439 last_seq_num_for_kf_.clear();
440 while (!stashed_frames_.empty())
441 stashed_frames_.pop();
442 not_yet_received_frames_.clear();
443
444 first_packet_received_ = false;
201 } 445 }
202 446
203 } // namespace video_coding 447 } // namespace video_coding
204 } // namespace webrtc 448 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698