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

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

Issue 1961053002: Logic for finding frame references moved from PacketBuffer to new class (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 7 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/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),
terelius 2016/05/09 16:39:18 Is ss_idx an established name, or could we find so
philipel 2016/05/11 09:40:32 Kind of, it is not as established as a GOF or GOP
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/rtp_frame_reference_finder.h ('k') | webrtc/modules/video_coding/video_coding.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698