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