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 switch (codec_type) { | |
210 case kVideoCodecVP8 : { | |
211 ManageFrameVp8(std::move(frame)); | |
212 break; | |
213 } | |
214 case kVideoCodecVP9 : { | |
215 // TODO(philipel): ManageFrameVp9(std::move(frame)); | |
216 break; | |
217 } | |
218 case kVideoCodecH264 : | |
219 case kVideoCodecI420 : | |
220 case kVideoCodecRED : | |
221 case kVideoCodecULPFEC : | |
stefan-webrtc
2016/04/19 12:24:29
RED and ULPFEC shouldn't end up here at all, so le
philipel
2016/04/19 13:12:01
Done.
| |
222 case kVideoCodecGeneric : | |
223 case kVideoCodecUnknown : | |
224 default : { | |
225 ManageFrameGeneric(std::move(frame)); | |
226 } | |
227 } | |
228 } | |
229 | |
230 void PacketBuffer::RetryStashedFrames() { | |
231 size_t num_stashed_frames = stashed_frames_.size(); | |
232 | |
233 // Clean up stashed frames if there are to many. | |
stefan-webrtc
2016/04/19 12:24:29
too many
philipel
2016/04/19 13:12:01
Done.
| |
234 while (stashed_frames_.size() > kMaxStashedFrames) | |
235 stashed_frames_.pop(); | |
236 | |
237 // Since frames are stashed if there is not enough data to determine their | |
238 // frame references we should at most check |stashed_frames_.size()| in | |
239 // order to not pop and push frames in and endless loop. | |
240 for (size_t i = 0; i < num_stashed_frames && !stashed_frames_.empty(); ++i) { | |
241 std::unique_ptr<RtpFrameObject> frame = std::move(stashed_frames_.front()); | |
242 stashed_frames_.pop(); | |
243 ManageFrame(std::move(frame)); | |
244 } | |
245 } | |
246 | |
247 void PacketBuffer::ManageFrameGeneric( | |
248 std::unique_ptr<RtpFrameObject> frame) { | |
249 size_t index = frame->first_packet() % size_; | |
250 const VCMPacket& packet = data_buffer_[index]; | |
251 | |
252 if (packet.frameType == kVideoFrameKey) | |
253 last_seq_num_for_kf_[frame->last_packet()] = frame->last_packet(); | |
254 | |
255 // Clean up info for old keyframes but make sure to keep info | |
256 // for the last keyframe. | |
257 auto clean_to = last_seq_num_for_kf_.lower_bound(frame->last_packet() - 100); | |
258 if (clean_to != last_seq_num_for_kf_.end() || | |
259 clean_to != (--last_seq_num_for_kf_.end())) { | |
260 last_seq_num_for_kf_.erase(last_seq_num_for_kf_.begin(), clean_to); | |
261 } | |
262 | |
263 // Find the last sequence number of the last frame for the keyframe | |
264 // that this frame indirectly references. | |
265 auto seq_num_it = last_seq_num_for_kf_.upper_bound(frame->last_packet()); | |
266 seq_num_it--; | |
267 | |
268 // Make sure the packet sequence numbers are continuous, otherwise stash | |
269 // this frame. | |
270 if (packet.frameType == kVideoFrameDelta) { | |
271 if (seq_num_it->second != | |
272 static_cast<uint16_t>(frame->first_packet() - 1)) { | |
273 stashed_frames_.emplace(std::move(frame)); | |
274 return; | |
275 } | |
276 } | |
277 | |
278 RTC_DCHECK(AheadOrAt(frame->last_packet(), seq_num_it->first)); | |
279 | |
280 // Since keyframes can cause reordering of the frames delivered from | |
281 // FindFrames() we can't simply assign the picture id according to some | |
282 // incrementing counter. | |
283 frame->picture_id = frame->last_packet(); | |
284 frame->num_references = packet.frameType == kVideoFrameDelta; | |
285 frame->references[0] = seq_num_it->second; | |
286 seq_num_it->second = frame->picture_id; | |
287 | |
288 last_picture_id_ = frame->picture_id; | |
289 frame_callback_->OnCompleteFrame(std::move(frame)); | |
290 RetryStashedFrames(); | |
291 } | |
292 | |
293 void PacketBuffer::ManageFrameVp8(std::unique_ptr<RtpFrameObject> frame) { | |
294 size_t index = frame->first_packet() % size_; | |
295 const VCMPacket& packet = data_buffer_[index]; | |
296 const RTPVideoHeaderVP8& codec_header = | |
297 packet.codecSpecificHeader.codecHeader.VP8; | |
298 | |
299 if (codec_header.pictureId == kNoPictureId || | |
300 codec_header.temporalIdx == kNoTemporalIdx || | |
301 codec_header.tl0PicIdx == kNoTl0PicIdx) { | |
302 ManageFrameGeneric(std::move(frame)); | |
303 return; | |
304 } | |
305 | |
306 frame->picture_id = codec_header.pictureId % kPicIdLength; | |
307 | |
308 if (last_unwrap_ == -1) | |
309 last_unwrap_ = codec_header.pictureId; | |
310 | |
311 if (last_picture_id_ == -1) | |
312 last_picture_id_ = frame->picture_id; | |
313 | |
314 // Find if there has been a gap in fully received frames and save the picture | |
315 // id of those frames in |not_yet_received_frames_|. | |
316 if (AheadOf<uint8_t, kPicIdLength>(frame->picture_id, last_picture_id_)) { | |
317 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); | |
318 while (last_picture_id_ != frame->picture_id) { | |
319 not_yet_received_frames_.insert(last_picture_id_); | |
320 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); | |
321 } | |
322 } | |
323 | |
324 // Clean up info for base layers that are too old. | |
325 uint8_t old_tl0_pic_idx = codec_header.tl0PicIdx - kMaxLayerInfo; | |
326 auto clean_layer_info_to = layer_info_.lower_bound(old_tl0_pic_idx); | |
327 layer_info_.erase(layer_info_.begin(), clean_layer_info_to); | |
328 | |
329 // Clean up info about not yet received frames that are too old. | |
330 uint16_t old_picture_id = Subtract<kPicIdLength>(frame->picture_id, | |
331 kMaxNotYetReceivedFrames); | |
332 auto clean_frames_to = not_yet_received_frames_.lower_bound(old_picture_id); | |
333 not_yet_received_frames_.erase(not_yet_received_frames_.begin(), | |
334 clean_frames_to); | |
335 | |
336 if (packet.frameType == kVideoFrameKey) { | |
337 frame->num_references = 0; | |
338 layer_info_[codec_header.tl0PicIdx].fill(-1); | |
339 CompletedFrameVp8(std::move(frame)); | |
340 return; | |
341 } | |
342 | |
343 auto layer_info_it = layer_info_.find(codec_header.temporalIdx == 0 | |
344 ? codec_header.tl0PicIdx - 1 | |
345 : codec_header.tl0PicIdx); | |
346 | |
347 // If we don't have the base layer frame yet, stash this frame. | |
348 if (layer_info_it == layer_info_.end()) { | |
349 stashed_frames_.emplace(std::move(frame)); | |
350 return; | |
351 } | |
352 | |
353 // A non keyframe base layer frame has been received, copy the layer info | |
354 // from the previous base layer frame and set a reference to the previous | |
355 // base layer frame. | |
356 if (codec_header.temporalIdx == 0) { | |
357 layer_info_it = | |
358 layer_info_ | |
359 .insert(make_pair(codec_header.tl0PicIdx, layer_info_it->second)) | |
360 .first; | |
361 frame->num_references = 1; | |
362 frame->references[0] = layer_info_it->second[0]; | |
363 CompletedFrameVp8(std::move(frame)); | |
364 return; | |
365 } | |
366 | |
367 // Layer sync frame, this frame only references its base layer frame. | |
368 if (codec_header.layerSync) { | |
369 frame->num_references = 1; | |
370 frame->references[0] = layer_info_it->second[0]; | |
371 | |
372 CompletedFrameVp8(std::move(frame)); | |
373 return; | |
374 } | |
375 | |
376 // Find all references for this frame. | |
377 frame->num_references = 0; | |
378 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) { | |
379 RTC_DCHECK_NE(-1, layer_info_it->second[layer]); | |
380 | |
381 // If we have not yet received a frame between this frame and the referenced | |
382 // frame then we have to wait for that frame to be completed first. | |
383 auto not_received_frame_it = | |
384 not_yet_received_frames_.upper_bound(layer_info_it->second[layer]); | |
385 if (not_received_frame_it != not_yet_received_frames_.end() && | |
386 AheadOf<uint8_t, kPicIdLength>(frame->picture_id, | |
387 *not_received_frame_it)) { | |
388 stashed_frames_.emplace(std::move(frame)); | |
389 return; | |
390 } | |
391 | |
392 ++frame->num_references; | |
393 frame->references[layer] = layer_info_it->second[layer]; | |
394 } | |
395 | |
396 CompletedFrameVp8(std::move(frame)); | |
397 } | |
398 | |
399 void PacketBuffer::CompletedFrameVp8(std::unique_ptr<RtpFrameObject> frame) { | |
400 size_t index = frame->first_packet() % size_; | |
401 const VCMPacket& packet = data_buffer_[index]; | |
402 const RTPVideoHeaderVP8& codec_header = | |
403 packet.codecSpecificHeader.codecHeader.VP8; | |
404 | |
405 uint8_t tl0_pic_idx = codec_header.tl0PicIdx; | |
406 uint8_t temporal_index = codec_header.temporalIdx; | |
407 auto layer_info_it = layer_info_.find(tl0_pic_idx); | |
408 | |
409 // Update this layer info and newer. | |
410 while (layer_info_it != layer_info_.end()) { | |
411 if (layer_info_it->second[temporal_index] != -1 && | |
412 AheadOf<uint16_t, kPicIdLength>(layer_info_it->second[temporal_index], | |
413 frame->picture_id)) { | |
414 // The frame was not newer, then no subsequent layer info have to be | |
415 // update. | |
416 break; | |
417 } | |
418 | |
419 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id; | |
420 ++tl0_pic_idx; | |
421 layer_info_it = layer_info_.find(tl0_pic_idx); | |
422 } | |
423 not_yet_received_frames_.erase(frame->picture_id); | |
424 | |
425 for (size_t r = 0; r < frame->num_references; ++r) | |
426 frame->references[r] = UnwrapPictureId(frame->references[r]); | |
427 frame->picture_id = UnwrapPictureId(frame->picture_id); | |
428 | |
429 frame_callback_->OnCompleteFrame(std::move(frame)); | |
430 RetryStashedFrames(); | |
431 } | |
432 | |
433 uint16_t PacketBuffer::UnwrapPictureId(uint16_t picture_id) { | |
434 if (last_unwrap_ == -1) | |
435 last_unwrap_ = picture_id; | |
436 | |
437 uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength; | |
438 uint16_t diff = MinDiff<uint8_t, kPicIdLength>(unwrap_truncated, picture_id); | |
439 | |
440 if (AheadOf<uint8_t, kPicIdLength>(picture_id, unwrap_truncated)) | |
441 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); | |
442 else | |
443 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); | |
444 | |
445 return last_unwrap_; | |
446 } | |
447 | |
195 void PacketBuffer::Flush() { | 448 void PacketBuffer::Flush() { |
196 rtc::CritScope lock(&crit_); | 449 rtc::CritScope lock(&crit_); |
197 for (size_t i = 0; i < size_; ++i) { | 450 for (size_t i = 0; i < size_; ++i) |
198 sequence_buffer_[i].used = false; | 451 sequence_buffer_[i].used = false; |
199 sequence_buffer_[i].continuous = false; | 452 |
200 } | 453 last_seq_num_for_kf_.clear(); |
454 while (!stashed_frames_.empty()) | |
455 stashed_frames_.pop(); | |
456 not_yet_received_frames_.clear(); | |
457 | |
458 first_packet_received_ = false; | |
201 } | 459 } |
202 | 460 |
203 } // namespace video_coding | 461 } // namespace video_coding |
204 } // namespace webrtc | 462 } // namespace webrtc |
OLD | NEW |