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/rtp_frame_reference_finder.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/base/logging.h" | 17 #include "webrtc/base/logging.h" |
18 #include "webrtc/modules/video_coding/frame_object.h" | 18 #include "webrtc/modules/video_coding/frame_object.h" |
| 19 #include "webrtc/modules/video_coding/packet_buffer.h" |
19 | 20 |
20 namespace webrtc { | 21 namespace webrtc { |
21 namespace video_coding { | 22 namespace video_coding { |
22 | 23 |
23 PacketBuffer::PacketBuffer(size_t start_buffer_size, | 24 RtpFrameReferenceFinder::RtpFrameReferenceFinder( |
24 size_t max_buffer_size, | 25 OnCompleteFrameCallback* frame_callback) |
25 OnCompleteFrameCallback* frame_callback) | 26 : last_picture_id_(-1), |
26 : size_(start_buffer_size), | |
27 max_size_(max_buffer_size), | |
28 first_seq_num_(0), | |
29 last_seq_num_(0), | |
30 first_packet_received_(false), | |
31 data_buffer_(start_buffer_size), | |
32 sequence_buffer_(start_buffer_size), | |
33 frame_callback_(frame_callback), | |
34 last_picture_id_(-1), | |
35 last_unwrap_(-1), | 27 last_unwrap_(-1), |
36 current_ss_idx_(0) { | 28 current_ss_idx_(0), |
37 RTC_DCHECK_LE(start_buffer_size, max_buffer_size); | 29 frame_callback_(frame_callback) {} |
38 // Buffer size must always be a power of 2. | |
39 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0); | |
40 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0); | |
41 } | |
42 | 30 |
43 bool PacketBuffer::InsertPacket(const VCMPacket& packet) { | 31 void RtpFrameReferenceFinder::ManageFrame( |
| 32 std::unique_ptr<RtpFrameObject> frame) { |
44 rtc::CritScope lock(&crit_); | 33 rtc::CritScope lock(&crit_); |
45 uint16_t seq_num = packet.seqNum; | 34 switch (frame->codec_type()) { |
46 size_t index = seq_num % size_; | |
47 | |
48 if (!first_packet_received_) { | |
49 first_seq_num_ = seq_num - 1; | |
50 last_seq_num_ = seq_num; | |
51 first_packet_received_ = true; | |
52 } | |
53 | |
54 if (sequence_buffer_[index].used) { | |
55 // Duplicate packet, do nothing. | |
56 if (data_buffer_[index].seqNum == packet.seqNum) | |
57 return true; | |
58 | |
59 // The packet buffer is full, try to expand the buffer. | |
60 while (ExpandBufferSize() && sequence_buffer_[seq_num % size_].used) { | |
61 } | |
62 index = seq_num % size_; | |
63 | |
64 // Packet buffer is still full. | |
65 if (sequence_buffer_[index].used) | |
66 return false; | |
67 } | |
68 | |
69 if (AheadOf(seq_num, last_seq_num_)) | |
70 last_seq_num_ = seq_num; | |
71 | |
72 sequence_buffer_[index].frame_begin = packet.isFirstPacket; | |
73 sequence_buffer_[index].frame_end = packet.markerBit; | |
74 sequence_buffer_[index].seq_num = packet.seqNum; | |
75 sequence_buffer_[index].continuous = false; | |
76 sequence_buffer_[index].frame_created = false; | |
77 sequence_buffer_[index].used = true; | |
78 data_buffer_[index] = packet; | |
79 | |
80 FindFrames(seq_num); | |
81 return true; | |
82 } | |
83 | |
84 void PacketBuffer::ClearTo(uint16_t seq_num) { | |
85 rtc::CritScope lock(&crit_); | |
86 size_t index = first_seq_num_ % size_; | |
87 while (AheadOf<uint16_t>(seq_num, first_seq_num_ + 1)) { | |
88 index = (index + 1) % size_; | |
89 first_seq_num_ = Add<1 << 16>(first_seq_num_, 1); | |
90 sequence_buffer_[index].used = false; | |
91 } | |
92 } | |
93 | |
94 bool PacketBuffer::ExpandBufferSize() { | |
95 if (size_ == max_size_) | |
96 return false; | |
97 | |
98 size_t new_size = std::min(max_size_, 2 * size_); | |
99 std::vector<VCMPacket> new_data_buffer(new_size); | |
100 std::vector<ContinuityInfo> new_sequence_buffer(new_size); | |
101 for (size_t i = 0; i < size_; ++i) { | |
102 if (sequence_buffer_[i].used) { | |
103 size_t index = sequence_buffer_[i].seq_num % new_size; | |
104 new_sequence_buffer[index] = sequence_buffer_[i]; | |
105 new_data_buffer[index] = data_buffer_[i]; | |
106 } | |
107 } | |
108 size_ = new_size; | |
109 sequence_buffer_ = std::move(new_sequence_buffer); | |
110 data_buffer_ = std::move(new_data_buffer); | |
111 return true; | |
112 } | |
113 | |
114 bool PacketBuffer::IsContinuous(uint16_t seq_num) const { | |
115 size_t index = seq_num % size_; | |
116 int prev_index = index > 0 ? index - 1 : size_ - 1; | |
117 | |
118 if (!sequence_buffer_[index].used) | |
119 return false; | |
120 if (sequence_buffer_[index].frame_created) | |
121 return false; | |
122 if (sequence_buffer_[index].frame_begin) | |
123 return true; | |
124 if (!sequence_buffer_[prev_index].used) | |
125 return false; | |
126 if (sequence_buffer_[prev_index].seq_num != | |
127 static_cast<uint16_t>(seq_num - 1)) | |
128 return false; | |
129 if (sequence_buffer_[prev_index].continuous) | |
130 return true; | |
131 | |
132 return false; | |
133 } | |
134 | |
135 void PacketBuffer::FindFrames(uint16_t seq_num) { | |
136 size_t index = seq_num % size_; | |
137 while (IsContinuous(seq_num)) { | |
138 sequence_buffer_[index].continuous = true; | |
139 | |
140 // If all packets of the frame is continuous, find the first packet of the | |
141 // frame and create an RtpFrameObject. | |
142 if (sequence_buffer_[index].frame_end) { | |
143 int start_index = index; | |
144 uint16_t start_seq_num = seq_num; | |
145 | |
146 while (!sequence_buffer_[start_index].frame_begin) { | |
147 sequence_buffer_[start_index].frame_created = true; | |
148 start_index = start_index > 0 ? start_index - 1 : size_ - 1; | |
149 start_seq_num--; | |
150 } | |
151 sequence_buffer_[start_index].frame_created = true; | |
152 | |
153 std::unique_ptr<RtpFrameObject> frame( | |
154 new RtpFrameObject(this, start_seq_num, seq_num)); | |
155 ManageFrame(std::move(frame)); | |
156 } | |
157 | |
158 index = (index + 1) % size_; | |
159 ++seq_num; | |
160 } | |
161 } | |
162 | |
163 void PacketBuffer::ReturnFrame(RtpFrameObject* frame) { | |
164 rtc::CritScope lock(&crit_); | |
165 size_t index = frame->first_seq_num() % size_; | |
166 size_t end = (frame->last_seq_num() + 1) % size_; | |
167 uint16_t seq_num = frame->first_seq_num(); | |
168 while (index != end) { | |
169 if (sequence_buffer_[index].seq_num == seq_num) | |
170 sequence_buffer_[index].used = false; | |
171 | |
172 index = (index + 1) % size_; | |
173 ++seq_num; | |
174 } | |
175 | |
176 index = first_seq_num_ % size_; | |
177 while (AheadOf<uint16_t>(last_seq_num_, first_seq_num_) && | |
178 !sequence_buffer_[index].used) { | |
179 ++first_seq_num_; | |
180 index = (index + 1) % size_; | |
181 } | |
182 } | |
183 | |
184 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, | |
185 uint8_t* destination) { | |
186 rtc::CritScope lock(&crit_); | |
187 | |
188 size_t index = frame.first_seq_num() % size_; | |
189 size_t end = (frame.last_seq_num() + 1) % size_; | |
190 uint16_t seq_num = frame.first_seq_num(); | |
191 while (index != end) { | |
192 if (!sequence_buffer_[index].used || | |
193 sequence_buffer_[index].seq_num != seq_num) { | |
194 return false; | |
195 } | |
196 | |
197 const uint8_t* source = data_buffer_[index].dataPtr; | |
198 size_t length = data_buffer_[index].sizeBytes; | |
199 memcpy(destination, source, length); | |
200 destination += length; | |
201 index = (index + 1) % size_; | |
202 ++seq_num; | |
203 } | |
204 return true; | |
205 } | |
206 | |
207 void PacketBuffer::ManageFrame(std::unique_ptr<RtpFrameObject> frame) { | |
208 size_t start_index = frame->first_seq_num() % size_; | |
209 VideoCodecType codec_type = data_buffer_[start_index].codec; | |
210 | |
211 switch (codec_type) { | |
212 case kVideoCodecULPFEC: | 35 case kVideoCodecULPFEC: |
213 case kVideoCodecRED: | 36 case kVideoCodecRED: |
214 case kVideoCodecUnknown: | 37 case kVideoCodecUnknown: |
215 RTC_NOTREACHED(); | 38 RTC_NOTREACHED(); |
216 break; | 39 break; |
217 case kVideoCodecVP8: | 40 case kVideoCodecVP8: |
218 ManageFrameVp8(std::move(frame)); | 41 ManageFrameVp8(std::move(frame)); |
219 break; | 42 break; |
220 case kVideoCodecVP9: | 43 case kVideoCodecVP9: |
221 ManageFrameVp9(std::move(frame)); | 44 ManageFrameVp9(std::move(frame)); |
222 break; | 45 break; |
223 case kVideoCodecH264: | 46 case kVideoCodecH264: |
224 case kVideoCodecI420: | 47 case kVideoCodecI420: |
225 case kVideoCodecGeneric: | 48 case kVideoCodecGeneric: |
226 ManageFrameGeneric(std::move(frame)); | 49 ManageFrameGeneric(std::move(frame)); |
227 break; | 50 break; |
228 } | 51 } |
229 } | 52 } |
230 | 53 |
231 void PacketBuffer::RetryStashedFrames() { | 54 void RtpFrameReferenceFinder::RetryStashedFrames() { |
232 size_t num_stashed_frames = stashed_frames_.size(); | 55 size_t num_stashed_frames = stashed_frames_.size(); |
233 | 56 |
234 // Clean up stashed frames if there are too many. | 57 // Clean up stashed frames if there are too many. |
235 while (stashed_frames_.size() > kMaxStashedFrames) | 58 while (stashed_frames_.size() > kMaxStashedFrames) |
236 stashed_frames_.pop(); | 59 stashed_frames_.pop(); |
237 | 60 |
238 // Since frames are stashed if there is not enough data to determine their | 61 // Since frames are stashed if there is not enough data to determine their |
239 // frame references we should at most check |stashed_frames_.size()| in | 62 // frame references we should at most check |stashed_frames_.size()| in |
240 // order to not pop and push frames in and endless loop. | 63 // order to not pop and push frames in and endless loop. |
241 for (size_t i = 0; i < num_stashed_frames && !stashed_frames_.empty(); ++i) { | 64 for (size_t i = 0; i < num_stashed_frames && !stashed_frames_.empty(); ++i) { |
242 std::unique_ptr<RtpFrameObject> frame = std::move(stashed_frames_.front()); | 65 std::unique_ptr<RtpFrameObject> frame = std::move(stashed_frames_.front()); |
243 stashed_frames_.pop(); | 66 stashed_frames_.pop(); |
244 ManageFrame(std::move(frame)); | 67 ManageFrame(std::move(frame)); |
245 } | 68 } |
246 } | 69 } |
247 | 70 |
248 void PacketBuffer::ManageFrameGeneric( | 71 void RtpFrameReferenceFinder::ManageFrameGeneric( |
249 std::unique_ptr<RtpFrameObject> frame) { | 72 std::unique_ptr<RtpFrameObject> frame) { |
250 size_t index = frame->first_seq_num() % size_; | 73 if (frame->frame_type() == kVideoFrameKey) |
251 const VCMPacket& packet = data_buffer_[index]; | |
252 | |
253 if (packet.frameType == kVideoFrameKey) | |
254 last_seq_num_gop_[frame->last_seq_num()] = frame->last_seq_num(); | 74 last_seq_num_gop_[frame->last_seq_num()] = frame->last_seq_num(); |
255 | 75 |
256 // We have received a frame but not yet a keyframe, stash this frame. | 76 // We have received a frame but not yet a keyframe, stash this frame. |
257 if (last_seq_num_gop_.empty()) { | 77 if (last_seq_num_gop_.empty()) { |
258 stashed_frames_.emplace(std::move(frame)); | 78 stashed_frames_.emplace(std::move(frame)); |
259 return; | 79 return; |
260 } | 80 } |
261 | 81 |
262 // Clean up info for old keyframes but make sure to keep info | 82 // Clean up info for old keyframes but make sure to keep info |
263 // for the last keyframe. | 83 // for the last keyframe. |
264 auto clean_to = last_seq_num_gop_.lower_bound(frame->last_seq_num() - 100); | 84 auto clean_to = last_seq_num_gop_.lower_bound(frame->last_seq_num() - 100); |
265 if (clean_to != last_seq_num_gop_.end()) | 85 if (clean_to != last_seq_num_gop_.end()) |
266 last_seq_num_gop_.erase(last_seq_num_gop_.begin(), clean_to); | 86 last_seq_num_gop_.erase(last_seq_num_gop_.begin(), clean_to); |
267 | 87 |
268 // Find the last sequence number of the last frame for the keyframe | 88 // Find the last sequence number of the last frame for the keyframe |
269 // that this frame indirectly references. | 89 // that this frame indirectly references. |
270 auto seq_num_it = last_seq_num_gop_.upper_bound(frame->last_seq_num()); | 90 auto seq_num_it = last_seq_num_gop_.upper_bound(frame->last_seq_num()); |
271 seq_num_it--; | 91 seq_num_it--; |
272 | 92 |
273 // Make sure the packet sequence numbers are continuous, otherwise stash | 93 // Make sure the packet sequence numbers are continuous, otherwise stash |
274 // this frame. | 94 // this frame. |
275 if (packet.frameType == kVideoFrameDelta) { | 95 if (frame->frame_type() == kVideoFrameDelta) { |
276 if (seq_num_it->second != | 96 if (seq_num_it->second != |
277 static_cast<uint16_t>(frame->first_seq_num() - 1)) { | 97 static_cast<uint16_t>(frame->first_seq_num() - 1)) { |
278 stashed_frames_.emplace(std::move(frame)); | 98 stashed_frames_.emplace(std::move(frame)); |
279 return; | 99 return; |
280 } | 100 } |
281 } | 101 } |
282 | 102 |
283 RTC_DCHECK(AheadOrAt(frame->last_seq_num(), seq_num_it->first)); | 103 RTC_DCHECK(AheadOrAt(frame->last_seq_num(), seq_num_it->first)); |
284 | 104 |
285 // Since keyframes can cause reordering of the frames delivered from | 105 // Since keyframes can cause reordering we can't simply assign the |
286 // FindFrames() we can't simply assign the picture id according to some | 106 // picture id according to some incrementing counter. |
287 // incrementing counter. | |
288 frame->picture_id = frame->last_seq_num(); | 107 frame->picture_id = frame->last_seq_num(); |
289 frame->num_references = packet.frameType == kVideoFrameDelta; | 108 frame->num_references = frame->frame_type() == kVideoFrameDelta; |
290 frame->references[0] = seq_num_it->second; | 109 frame->references[0] = seq_num_it->second; |
291 seq_num_it->second = frame->picture_id; | 110 seq_num_it->second = frame->picture_id; |
292 | 111 |
293 last_picture_id_ = frame->picture_id; | 112 last_picture_id_ = frame->picture_id; |
294 frame_callback_->OnCompleteFrame(std::move(frame)); | 113 frame_callback_->OnCompleteFrame(std::move(frame)); |
295 RetryStashedFrames(); | 114 RetryStashedFrames(); |
296 } | 115 } |
297 | 116 |
298 void PacketBuffer::ManageFrameVp8(std::unique_ptr<RtpFrameObject> frame) { | 117 void RtpFrameReferenceFinder::ManageFrameVp8( |
299 size_t index = frame->first_seq_num() % size_; | 118 std::unique_ptr<RtpFrameObject> frame) { |
300 const VCMPacket& packet = data_buffer_[index]; | 119 RTPVideoTypeHeader* rtp_codec_header = frame->GetCodecHeader(); |
301 const RTPVideoHeaderVP8& codec_header = | 120 if (!rtp_codec_header) |
302 packet.codecSpecificHeader.codecHeader.VP8; | 121 return; |
| 122 |
| 123 const RTPVideoHeaderVP8& codec_header = rtp_codec_header->VP8; |
303 | 124 |
304 if (codec_header.pictureId == kNoPictureId || | 125 if (codec_header.pictureId == kNoPictureId || |
305 codec_header.temporalIdx == kNoTemporalIdx || | 126 codec_header.temporalIdx == kNoTemporalIdx || |
306 codec_header.tl0PicIdx == kNoTl0PicIdx) { | 127 codec_header.tl0PicIdx == kNoTl0PicIdx) { |
307 ManageFrameGeneric(std::move(frame)); | 128 ManageFrameGeneric(std::move(frame)); |
308 return; | 129 return; |
309 } | 130 } |
310 | 131 |
311 frame->picture_id = codec_header.pictureId % kPicIdLength; | 132 frame->picture_id = codec_header.pictureId % kPicIdLength; |
312 | 133 |
(...skipping 12 matching lines...) Expand all Loading... |
325 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); | 146 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); |
326 } | 147 } |
327 } | 148 } |
328 | 149 |
329 // Clean up info for base layers that are too old. | 150 // Clean up info for base layers that are too old. |
330 uint8_t old_tl0_pic_idx = codec_header.tl0PicIdx - kMaxLayerInfo; | 151 uint8_t old_tl0_pic_idx = codec_header.tl0PicIdx - kMaxLayerInfo; |
331 auto clean_layer_info_to = layer_info_.lower_bound(old_tl0_pic_idx); | 152 auto clean_layer_info_to = layer_info_.lower_bound(old_tl0_pic_idx); |
332 layer_info_.erase(layer_info_.begin(), clean_layer_info_to); | 153 layer_info_.erase(layer_info_.begin(), clean_layer_info_to); |
333 | 154 |
334 // Clean up info about not yet received frames that are too old. | 155 // Clean up info about not yet received frames that are too old. |
335 uint16_t old_picture_id = Subtract<kPicIdLength>(frame->picture_id, | 156 uint16_t old_picture_id = |
336 kMaxNotYetReceivedFrames); | 157 Subtract<kPicIdLength>(frame->picture_id, kMaxNotYetReceivedFrames); |
337 auto clean_frames_to = not_yet_received_frames_.lower_bound(old_picture_id); | 158 auto clean_frames_to = not_yet_received_frames_.lower_bound(old_picture_id); |
338 not_yet_received_frames_.erase(not_yet_received_frames_.begin(), | 159 not_yet_received_frames_.erase(not_yet_received_frames_.begin(), |
339 clean_frames_to); | 160 clean_frames_to); |
340 | 161 |
341 if (packet.frameType == kVideoFrameKey) { | 162 if (frame->frame_type() == kVideoFrameKey) { |
342 frame->num_references = 0; | 163 frame->num_references = 0; |
343 layer_info_[codec_header.tl0PicIdx].fill(-1); | 164 layer_info_[codec_header.tl0PicIdx].fill(-1); |
344 CompletedFrameVp8(std::move(frame)); | 165 CompletedFrameVp8(std::move(frame)); |
345 return; | 166 return; |
346 } | 167 } |
347 | 168 |
348 auto layer_info_it = layer_info_.find(codec_header.temporalIdx == 0 | 169 auto layer_info_it = layer_info_.find(codec_header.temporalIdx == 0 |
349 ? codec_header.tl0PicIdx - 1 | 170 ? codec_header.tl0PicIdx - 1 |
350 : codec_header.tl0PicIdx); | 171 : codec_header.tl0PicIdx); |
351 | 172 |
(...skipping 27 matching lines...) Expand all Loading... |
379 } | 200 } |
380 | 201 |
381 // Find all references for this frame. | 202 // Find all references for this frame. |
382 frame->num_references = 0; | 203 frame->num_references = 0; |
383 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) { | 204 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) { |
384 RTC_DCHECK_NE(-1, layer_info_it->second[layer]); | 205 RTC_DCHECK_NE(-1, layer_info_it->second[layer]); |
385 | 206 |
386 // If we have not yet received a frame between this frame and the referenced | 207 // If we have not yet received a frame between this frame and the referenced |
387 // frame then we have to wait for that frame to be completed first. | 208 // frame then we have to wait for that frame to be completed first. |
388 auto not_received_frame_it = | 209 auto not_received_frame_it = |
389 not_yet_received_frames_.upper_bound(layer_info_it->second[layer]); | 210 not_yet_received_frames_.upper_bound(layer_info_it->second[layer]); |
390 if (not_received_frame_it != not_yet_received_frames_.end() && | 211 if (not_received_frame_it != not_yet_received_frames_.end() && |
391 AheadOf<uint16_t, kPicIdLength>(frame->picture_id, | 212 AheadOf<uint16_t, kPicIdLength>(frame->picture_id, |
392 *not_received_frame_it)) { | 213 *not_received_frame_it)) { |
393 stashed_frames_.emplace(std::move(frame)); | 214 stashed_frames_.emplace(std::move(frame)); |
394 return; | 215 return; |
395 } | 216 } |
396 | 217 |
397 ++frame->num_references; | 218 ++frame->num_references; |
398 frame->references[layer] = layer_info_it->second[layer]; | 219 frame->references[layer] = layer_info_it->second[layer]; |
399 } | 220 } |
400 | 221 |
401 CompletedFrameVp8(std::move(frame)); | 222 CompletedFrameVp8(std::move(frame)); |
402 } | 223 } |
403 | 224 |
404 void PacketBuffer::CompletedFrameVp8(std::unique_ptr<RtpFrameObject> frame) { | 225 void RtpFrameReferenceFinder::CompletedFrameVp8( |
405 size_t index = frame->first_seq_num() % size_; | 226 std::unique_ptr<RtpFrameObject> frame) { |
406 const VCMPacket& packet = data_buffer_[index]; | 227 RTPVideoTypeHeader* rtp_codec_header = frame->GetCodecHeader(); |
407 const RTPVideoHeaderVP8& codec_header = | 228 if (!rtp_codec_header) |
408 packet.codecSpecificHeader.codecHeader.VP8; | 229 return; |
| 230 |
| 231 const RTPVideoHeaderVP8& codec_header = rtp_codec_header->VP8; |
409 | 232 |
410 uint8_t tl0_pic_idx = codec_header.tl0PicIdx; | 233 uint8_t tl0_pic_idx = codec_header.tl0PicIdx; |
411 uint8_t temporal_index = codec_header.temporalIdx; | 234 uint8_t temporal_index = codec_header.temporalIdx; |
412 auto layer_info_it = layer_info_.find(tl0_pic_idx); | 235 auto layer_info_it = layer_info_.find(tl0_pic_idx); |
413 | 236 |
414 // Update this layer info and newer. | 237 // Update this layer info and newer. |
415 while (layer_info_it != layer_info_.end()) { | 238 while (layer_info_it != layer_info_.end()) { |
416 if (layer_info_it->second[temporal_index] != -1 && | 239 if (layer_info_it->second[temporal_index] != -1 && |
417 AheadOf<uint16_t, kPicIdLength>(layer_info_it->second[temporal_index], | 240 AheadOf<uint16_t, kPicIdLength>(layer_info_it->second[temporal_index], |
418 frame->picture_id)) { | 241 frame->picture_id)) { |
419 // The frame was not newer, then no subsequent layer info have to be | 242 // The frame was not newer, then no subsequent layer info have to be |
420 // update. | 243 // update. |
421 break; | 244 break; |
422 } | 245 } |
423 | 246 |
424 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id; | 247 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id; |
425 ++tl0_pic_idx; | 248 ++tl0_pic_idx; |
426 layer_info_it = layer_info_.find(tl0_pic_idx); | 249 layer_info_it = layer_info_.find(tl0_pic_idx); |
427 } | 250 } |
428 not_yet_received_frames_.erase(frame->picture_id); | 251 not_yet_received_frames_.erase(frame->picture_id); |
429 | 252 |
430 for (size_t i = 0; i < frame->num_references; ++i) | 253 for (size_t i = 0; i < frame->num_references; ++i) |
431 frame->references[i] = UnwrapPictureId(frame->references[i]); | 254 frame->references[i] = UnwrapPictureId(frame->references[i]); |
432 frame->picture_id = UnwrapPictureId(frame->picture_id); | 255 frame->picture_id = UnwrapPictureId(frame->picture_id); |
433 | 256 |
434 frame_callback_->OnCompleteFrame(std::move(frame)); | 257 frame_callback_->OnCompleteFrame(std::move(frame)); |
435 RetryStashedFrames(); | 258 RetryStashedFrames(); |
436 } | 259 } |
437 | 260 |
438 void PacketBuffer::ManageFrameVp9(std::unique_ptr<RtpFrameObject> frame) { | 261 void RtpFrameReferenceFinder::ManageFrameVp9( |
439 size_t index = frame->first_seq_num() % size_; | 262 std::unique_ptr<RtpFrameObject> frame) { |
440 const VCMPacket& packet = data_buffer_[index]; | 263 RTPVideoTypeHeader* rtp_codec_header = frame->GetCodecHeader(); |
441 const RTPVideoHeaderVP9& codec_header = | 264 if (!rtp_codec_header) |
442 packet.codecSpecificHeader.codecHeader.VP9; | 265 return; |
| 266 |
| 267 const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9; |
443 | 268 |
444 if (codec_header.picture_id == kNoPictureId) { | 269 if (codec_header.picture_id == kNoPictureId) { |
445 ManageFrameGeneric(std::move(frame)); | 270 ManageFrameGeneric(std::move(frame)); |
446 return; | 271 return; |
447 } | 272 } |
448 | 273 |
449 frame->spatial_layer = codec_header.spatial_idx; | 274 frame->spatial_layer = codec_header.spatial_idx; |
450 frame->inter_layer_predicted = codec_header.inter_layer_predicted; | 275 frame->inter_layer_predicted = codec_header.inter_layer_predicted; |
451 frame->picture_id = codec_header.picture_id % kPicIdLength; | 276 frame->picture_id = codec_header.picture_id % kPicIdLength; |
452 | 277 |
(...skipping 28 matching lines...) Expand all Loading... |
481 frame->picture_id, &scalability_structures_[current_ss_idx_]); | 306 frame->picture_id, &scalability_structures_[current_ss_idx_]); |
482 gof_info_.insert(std::make_pair(codec_header.tl0_pic_idx, pid_and_gof)); | 307 gof_info_.insert(std::make_pair(codec_header.tl0_pic_idx, pid_and_gof)); |
483 } | 308 } |
484 } | 309 } |
485 | 310 |
486 // Clean up info for base layers that are too old. | 311 // Clean up info for base layers that are too old. |
487 uint8_t old_tl0_pic_idx = codec_header.tl0_pic_idx - kMaxGofSaved; | 312 uint8_t old_tl0_pic_idx = codec_header.tl0_pic_idx - kMaxGofSaved; |
488 auto clean_gof_info_to = gof_info_.lower_bound(old_tl0_pic_idx); | 313 auto clean_gof_info_to = gof_info_.lower_bound(old_tl0_pic_idx); |
489 gof_info_.erase(gof_info_.begin(), clean_gof_info_to); | 314 gof_info_.erase(gof_info_.begin(), clean_gof_info_to); |
490 | 315 |
491 if (packet.frameType == kVideoFrameKey) { | 316 if (frame->frame_type() == kVideoFrameKey) { |
492 // When using GOF all keyframes must include the scalability structure. | 317 // When using GOF all keyframes must include the scalability structure. |
493 if (!codec_header.ss_data_available) | 318 if (!codec_header.ss_data_available) |
494 LOG(LS_WARNING) << "Received keyframe without scalability structure"; | 319 LOG(LS_WARNING) << "Received keyframe without scalability structure"; |
495 | 320 |
496 frame->num_references = 0; | 321 frame->num_references = 0; |
497 GofInfoVP9* gof = gof_info_.find(codec_header.tl0_pic_idx)->second.second; | 322 GofInfoVP9* gof = gof_info_.find(codec_header.tl0_pic_idx)->second.second; |
498 FrameReceivedVp9(frame->picture_id, *gof); | 323 FrameReceivedVp9(frame->picture_id, *gof); |
499 CompletedFrameVp9(std::move(frame)); | 324 CompletedFrameVp9(std::move(frame)); |
500 return; | 325 return; |
501 } | 326 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 // then ignore this reference. | 384 // then ignore this reference. |
560 if (UpSwitchInIntervalVp9(frame->picture_id, codec_header.temporal_idx, | 385 if (UpSwitchInIntervalVp9(frame->picture_id, codec_header.temporal_idx, |
561 frame->references[i])) { | 386 frame->references[i])) { |
562 --frame->num_references; | 387 --frame->num_references; |
563 } | 388 } |
564 } | 389 } |
565 | 390 |
566 CompletedFrameVp9(std::move(frame)); | 391 CompletedFrameVp9(std::move(frame)); |
567 } | 392 } |
568 | 393 |
569 bool PacketBuffer::MissingRequiredFrameVp9(uint16_t picture_id, | 394 bool RtpFrameReferenceFinder::MissingRequiredFrameVp9(uint16_t picture_id, |
570 const GofInfoVP9& gof) { | 395 const GofInfoVP9& gof) { |
571 size_t diff = ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, picture_id); | 396 size_t diff = ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, picture_id); |
572 size_t gof_idx = diff % gof.num_frames_in_gof; | 397 size_t gof_idx = diff % gof.num_frames_in_gof; |
573 size_t temporal_idx = gof.temporal_idx[gof_idx]; | 398 size_t temporal_idx = gof.temporal_idx[gof_idx]; |
574 | 399 |
575 // For every reference this frame has, check if there is a frame missing in | 400 // For every reference this frame has, check if there is a frame missing in |
576 // the interval (|ref_pid|, |picture_id|) in any of the lower temporal | 401 // the interval (|ref_pid|, |picture_id|) in any of the lower temporal |
577 // layers. If so, we are missing a required frame. | 402 // layers. If so, we are missing a required frame. |
578 uint8_t num_references = gof.num_ref_pics[gof_idx]; | 403 uint8_t num_references = gof.num_ref_pics[gof_idx]; |
579 for (size_t i = 0; i < num_references; ++i) { | 404 for (size_t i = 0; i < num_references; ++i) { |
580 uint16_t ref_pid = | 405 uint16_t ref_pid = |
581 Subtract<kPicIdLength>(picture_id, gof.pid_diff[gof_idx][i]); | 406 Subtract<kPicIdLength>(picture_id, gof.pid_diff[gof_idx][i]); |
582 for (size_t l = 0; l < temporal_idx; ++l) { | 407 for (size_t l = 0; l < temporal_idx; ++l) { |
583 auto missing_frame_it = missing_frames_for_layer_[l].lower_bound(ref_pid); | 408 auto missing_frame_it = missing_frames_for_layer_[l].lower_bound(ref_pid); |
584 if (missing_frame_it != missing_frames_for_layer_[l].end() && | 409 if (missing_frame_it != missing_frames_for_layer_[l].end() && |
585 AheadOf<uint16_t, kPicIdLength>(picture_id, *missing_frame_it)) { | 410 AheadOf<uint16_t, kPicIdLength>(picture_id, *missing_frame_it)) { |
586 return true; | 411 return true; |
587 } | 412 } |
588 } | 413 } |
589 } | 414 } |
590 return false; | 415 return false; |
591 } | 416 } |
592 | 417 |
593 void PacketBuffer::FrameReceivedVp9(uint16_t picture_id, | 418 void RtpFrameReferenceFinder::FrameReceivedVp9(uint16_t picture_id, |
594 const GofInfoVP9& gof) { | 419 const GofInfoVP9& gof) { |
595 RTC_DCHECK_NE(-1, last_picture_id_); | 420 RTC_DCHECK_NE(-1, last_picture_id_); |
596 | 421 |
597 // If there is a gap, find which temporal layer the missing frames | 422 // If there is a gap, find which temporal layer the missing frames |
598 // belong to and add the frame as missing for that temporal layer. | 423 // belong to and add the frame as missing for that temporal layer. |
599 // Otherwise, remove this frame from the set of missing frames. | 424 // Otherwise, remove this frame from the set of missing frames. |
600 if (AheadOf<uint16_t, kPicIdLength>(picture_id, last_picture_id_)) { | 425 if (AheadOf<uint16_t, kPicIdLength>(picture_id, last_picture_id_)) { |
601 size_t diff = | 426 size_t diff = |
602 ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, last_picture_id_); | 427 ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, last_picture_id_); |
603 size_t gof_idx = diff % gof.num_frames_in_gof; | 428 size_t gof_idx = diff % gof.num_frames_in_gof; |
604 | 429 |
605 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); | 430 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); |
606 while (last_picture_id_ != picture_id) { | 431 while (last_picture_id_ != picture_id) { |
607 ++gof_idx; | 432 ++gof_idx; |
608 RTC_DCHECK_NE(0ul, gof_idx % gof.num_frames_in_gof); | 433 RTC_DCHECK_NE(0ul, gof_idx % gof.num_frames_in_gof); |
609 size_t temporal_idx = gof.temporal_idx[gof_idx]; | 434 size_t temporal_idx = gof.temporal_idx[gof_idx]; |
610 missing_frames_for_layer_[temporal_idx].insert(last_picture_id_); | 435 missing_frames_for_layer_[temporal_idx].insert(last_picture_id_); |
611 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); | 436 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); |
612 } | 437 } |
613 } else { | 438 } else { |
614 size_t diff = | 439 size_t diff = |
615 ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, picture_id); | 440 ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, picture_id); |
616 size_t gof_idx = diff % gof.num_frames_in_gof; | 441 size_t gof_idx = diff % gof.num_frames_in_gof; |
617 size_t temporal_idx = gof.temporal_idx[gof_idx]; | 442 size_t temporal_idx = gof.temporal_idx[gof_idx]; |
618 missing_frames_for_layer_[temporal_idx].erase(picture_id); | 443 missing_frames_for_layer_[temporal_idx].erase(picture_id); |
619 } | 444 } |
620 } | 445 } |
621 | 446 |
622 bool PacketBuffer::UpSwitchInIntervalVp9(uint16_t picture_id, | 447 bool RtpFrameReferenceFinder::UpSwitchInIntervalVp9(uint16_t picture_id, |
623 uint8_t temporal_idx, | 448 uint8_t temporal_idx, |
624 uint16_t pid_ref) { | 449 uint16_t pid_ref) { |
625 for (auto up_switch_it = up_switch_.upper_bound(pid_ref); | 450 for (auto up_switch_it = up_switch_.upper_bound(pid_ref); |
626 up_switch_it != up_switch_.end() && | 451 up_switch_it != up_switch_.end() && |
627 AheadOf<uint16_t, kPicIdLength>(picture_id, up_switch_it->first); | 452 AheadOf<uint16_t, kPicIdLength>(picture_id, up_switch_it->first); |
628 ++up_switch_it) { | 453 ++up_switch_it) { |
629 if (up_switch_it->second < temporal_idx) | 454 if (up_switch_it->second < temporal_idx) |
630 return true; | 455 return true; |
631 } | 456 } |
632 | 457 |
633 return false; | 458 return false; |
634 } | 459 } |
635 | 460 |
636 void PacketBuffer::CompletedFrameVp9(std::unique_ptr<RtpFrameObject> frame) { | 461 void RtpFrameReferenceFinder::CompletedFrameVp9( |
| 462 std::unique_ptr<RtpFrameObject> frame) { |
637 for (size_t i = 0; i < frame->num_references; ++i) | 463 for (size_t i = 0; i < frame->num_references; ++i) |
638 frame->references[i] = UnwrapPictureId(frame->references[i]); | 464 frame->references[i] = UnwrapPictureId(frame->references[i]); |
639 frame->picture_id = UnwrapPictureId(frame->picture_id); | 465 frame->picture_id = UnwrapPictureId(frame->picture_id); |
640 | 466 |
641 frame_callback_->OnCompleteFrame(std::move(frame)); | 467 frame_callback_->OnCompleteFrame(std::move(frame)); |
642 RetryStashedFrames(); | 468 RetryStashedFrames(); |
643 } | 469 } |
644 | 470 |
645 uint16_t PacketBuffer::UnwrapPictureId(uint16_t picture_id) { | 471 uint16_t RtpFrameReferenceFinder::UnwrapPictureId(uint16_t picture_id) { |
646 RTC_DCHECK_NE(-1, last_unwrap_); | 472 RTC_DCHECK_NE(-1, last_unwrap_); |
647 | 473 |
648 uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength; | 474 uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength; |
649 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id); | 475 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id); |
650 | 476 |
651 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated)) | 477 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated)) |
652 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); | 478 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); |
653 else | 479 else |
654 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); | 480 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); |
655 | 481 |
656 return last_unwrap_; | 482 return last_unwrap_; |
657 } | 483 } |
658 | 484 |
659 void PacketBuffer::Flush() { | |
660 rtc::CritScope lock(&crit_); | |
661 for (size_t i = 0; i < size_; ++i) | |
662 sequence_buffer_[i].used = false; | |
663 | |
664 last_seq_num_gop_.clear(); | |
665 while (!stashed_frames_.empty()) | |
666 stashed_frames_.pop(); | |
667 not_yet_received_frames_.clear(); | |
668 | |
669 first_packet_received_ = false; | |
670 } | |
671 | |
672 } // namespace video_coding | 485 } // namespace video_coding |
673 } // namespace webrtc | 486 } // namespace webrtc |
OLD | NEW |