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

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

Issue 2985283002: Unwrap picture ids in the RtpFrameReferencerFinder. (Closed)
Patch Set: Feedback Created 3 years, 3 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
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 169
170 RtpFrameReferenceFinder::FrameDecision 170 RtpFrameReferenceFinder::FrameDecision
171 RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame, 171 RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame,
172 int picture_id) { 172 int picture_id) {
173 // If |picture_id| is specified then we use that to set the frame references, 173 // If |picture_id| is specified then we use that to set the frame references,
174 // otherwise we use sequence number. 174 // otherwise we use sequence number.
175 if (picture_id != kNoPictureId) { 175 if (picture_id != kNoPictureId) {
176 if (last_unwrap_ == -1) 176 if (last_unwrap_ == -1)
177 last_unwrap_ = picture_id; 177 last_unwrap_ = picture_id;
178 178
179 frame->picture_id = UnwrapPictureId(picture_id % kPicIdLength); 179 frame->picture_id = unwrapper_.Unwrap(picture_id);
180 frame->num_references = frame->frame_type() == kVideoFrameKey ? 0 : 1; 180 frame->num_references = frame->frame_type() == kVideoFrameKey ? 0 : 1;
181 frame->references[0] = frame->picture_id - 1; 181 frame->references[0] = frame->picture_id - 1;
182 return kHandOff; 182 return kHandOff;
183 } 183 }
184 184
185 if (frame->frame_type() == kVideoFrameKey) { 185 if (frame->frame_type() == kVideoFrameKey) {
186 last_seq_num_gop_.insert(std::make_pair( 186 last_seq_num_gop_.insert(std::make_pair(
187 frame->last_seq_num(), 187 frame->last_seq_num(),
188 std::make_pair(frame->last_seq_num(), frame->last_seq_num()))); 188 std::make_pair(frame->last_seq_num(), frame->last_seq_num())));
189 } 189 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 if (prev_seq_num != last_picture_id_with_padding_gop) 221 if (prev_seq_num != last_picture_id_with_padding_gop)
222 return kStash; 222 return kStash;
223 } 223 }
224 224
225 RTC_DCHECK(AheadOrAt(frame->last_seq_num(), seq_num_it->first)); 225 RTC_DCHECK(AheadOrAt(frame->last_seq_num(), seq_num_it->first));
226 226
227 // Since keyframes can cause reordering we can't simply assign the 227 // Since keyframes can cause reordering we can't simply assign the
228 // picture id according to some incrementing counter. 228 // picture id according to some incrementing counter.
229 frame->picture_id = frame->last_seq_num(); 229 frame->picture_id = frame->last_seq_num();
230 frame->num_references = frame->frame_type() == kVideoFrameDelta; 230 frame->num_references = frame->frame_type() == kVideoFrameDelta;
231 frame->references[0] = last_picture_id_gop; 231 frame->references[0] = generic_unwrapper_.Unwrap(last_picture_id_gop);
232 if (AheadOf(frame->picture_id, last_picture_id_gop)) { 232 if (AheadOf<uint16_t>(frame->picture_id, last_picture_id_gop)) {
233 seq_num_it->second.first = frame->picture_id; 233 seq_num_it->second.first = frame->picture_id;
234 seq_num_it->second.second = frame->picture_id; 234 seq_num_it->second.second = frame->picture_id;
235 } 235 }
236 236
237 last_picture_id_ = frame->picture_id; 237 last_picture_id_ = frame->picture_id;
238 UpdateLastPictureIdWithPadding(frame->picture_id); 238 UpdateLastPictureIdWithPadding(frame->picture_id);
239 frame->picture_id = generic_unwrapper_.Unwrap(frame->picture_id);
239 return kHandOff; 240 return kHandOff;
240 } 241 }
241 242
242 RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8( 243 RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8(
243 RtpFrameObject* frame) { 244 RtpFrameObject* frame) {
244 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader(); 245 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader();
245 if (!rtp_codec_header) 246 if (!rtp_codec_header) {
247 LOG(LS_WARNING) << "Failed to get codec header from frame, dropping frame.";
246 return kDrop; 248 return kDrop;
249 }
247 250
248 const RTPVideoHeaderVP8& codec_header = rtp_codec_header->VP8; 251 const RTPVideoHeaderVP8& codec_header = rtp_codec_header->VP8;
249 252
250 if (codec_header.pictureId == kNoPictureId || 253 if (codec_header.pictureId == kNoPictureId ||
251 codec_header.temporalIdx == kNoTemporalIdx || 254 codec_header.temporalIdx == kNoTemporalIdx ||
252 codec_header.tl0PicIdx == kNoTl0PicIdx) { 255 codec_header.tl0PicIdx == kNoTl0PicIdx) {
253 return ManageFrameGeneric(std::move(frame), codec_header.pictureId); 256 return ManageFrameGeneric(std::move(frame), codec_header.pictureId);
254 } 257 }
255 258
256 frame->picture_id = codec_header.pictureId % kPicIdLength; 259 frame->picture_id = codec_header.pictureId % kPicIdLength;
(...skipping 21 matching lines...) Expand all
278 // Clean up info about not yet received frames that are too old. 281 // Clean up info about not yet received frames that are too old.
279 uint16_t old_picture_id = 282 uint16_t old_picture_id =
280 Subtract<kPicIdLength>(frame->picture_id, kMaxNotYetReceivedFrames); 283 Subtract<kPicIdLength>(frame->picture_id, kMaxNotYetReceivedFrames);
281 auto clean_frames_to = not_yet_received_frames_.lower_bound(old_picture_id); 284 auto clean_frames_to = not_yet_received_frames_.lower_bound(old_picture_id);
282 not_yet_received_frames_.erase(not_yet_received_frames_.begin(), 285 not_yet_received_frames_.erase(not_yet_received_frames_.begin(),
283 clean_frames_to); 286 clean_frames_to);
284 287
285 if (frame->frame_type() == kVideoFrameKey) { 288 if (frame->frame_type() == kVideoFrameKey) {
286 frame->num_references = 0; 289 frame->num_references = 0;
287 layer_info_[codec_header.tl0PicIdx].fill(-1); 290 layer_info_[codec_header.tl0PicIdx].fill(-1);
288 UpdateLayerInfoVp8(frame, codec_header); 291 UpdateLayerInfoVp8(frame);
289 return kHandOff; 292 return kHandOff;
290 } 293 }
291 294
292 auto layer_info_it = layer_info_.find(codec_header.temporalIdx == 0 295 auto layer_info_it = layer_info_.find(codec_header.temporalIdx == 0
293 ? codec_header.tl0PicIdx - 1 296 ? codec_header.tl0PicIdx - 1
294 : codec_header.tl0PicIdx); 297 : codec_header.tl0PicIdx);
295 298
296 // If we don't have the base layer frame yet, stash this frame. 299 // If we don't have the base layer frame yet, stash this frame.
297 if (layer_info_it == layer_info_.end()) 300 if (layer_info_it == layer_info_.end())
298 return kStash; 301 return kStash;
299 302
300 // A non keyframe base layer frame has been received, copy the layer info 303 // A non keyframe base layer frame has been received, copy the layer info
301 // from the previous base layer frame and set a reference to the previous 304 // from the previous base layer frame and set a reference to the previous
302 // base layer frame. 305 // base layer frame.
303 if (codec_header.temporalIdx == 0) { 306 if (codec_header.temporalIdx == 0) {
304 layer_info_it = 307 layer_info_it =
305 layer_info_ 308 layer_info_
306 .insert(make_pair(codec_header.tl0PicIdx, layer_info_it->second)) 309 .insert(make_pair(codec_header.tl0PicIdx, layer_info_it->second))
307 .first; 310 .first;
308 frame->num_references = 1; 311 frame->num_references = 1;
309 frame->references[0] = layer_info_it->second[0]; 312 frame->references[0] = layer_info_it->second[0];
310 UpdateLayerInfoVp8(frame, codec_header); 313 UpdateLayerInfoVp8(frame);
311 return kHandOff; 314 return kHandOff;
312 } 315 }
313 316
314 // Layer sync frame, this frame only references its base layer frame. 317 // Layer sync frame, this frame only references its base layer frame.
315 if (codec_header.layerSync) { 318 if (codec_header.layerSync) {
316 frame->num_references = 1; 319 frame->num_references = 1;
317 frame->references[0] = layer_info_it->second[0]; 320 frame->references[0] = layer_info_it->second[0];
318 321
319 UpdateLayerInfoVp8(frame, codec_header); 322 UpdateLayerInfoVp8(frame);
320 return kHandOff; 323 return kHandOff;
321 } 324 }
322 325
323 // Find all references for this frame. 326 // Find all references for this frame.
324 frame->num_references = 0; 327 frame->num_references = 0;
325 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) { 328 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) {
326 // If we have not yet received a previous frame on this temporal layer, 329 // If we have not yet received a previous frame on this temporal layer,
327 // stash this frame. 330 // stash this frame.
328 if (layer_info_it->second[layer] == -1) 331 if (layer_info_it->second[layer] == -1)
329 return kStash; 332 return kStash;
(...skipping 22 matching lines...) Expand all
352 << " and packet range [" << frame->first_seq_num() << ", " 355 << " and packet range [" << frame->first_seq_num() << ", "
353 << frame->last_seq_num() << "] already received, " 356 << frame->last_seq_num() << "] already received, "
354 << " dropping frame."; 357 << " dropping frame.";
355 return kDrop; 358 return kDrop;
356 } 359 }
357 360
358 ++frame->num_references; 361 ++frame->num_references;
359 frame->references[layer] = layer_info_it->second[layer]; 362 frame->references[layer] = layer_info_it->second[layer];
360 } 363 }
361 364
362 UpdateLayerInfoVp8(frame, codec_header); 365 UpdateLayerInfoVp8(frame);
363 return kHandOff; 366 return kHandOff;
364 } 367 }
365 368
366 void RtpFrameReferenceFinder::UpdateLayerInfoVp8( 369 void RtpFrameReferenceFinder::UpdateLayerInfoVp8(RtpFrameObject* frame) {
367 RtpFrameObject* frame, 370 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader();
368 const RTPVideoHeaderVP8& codec_header) { 371 RTC_DCHECK(rtp_codec_header);
372 const RTPVideoHeaderVP8& codec_header = rtp_codec_header->VP8;
369 uint8_t tl0_pic_idx = codec_header.tl0PicIdx; 373 uint8_t tl0_pic_idx = codec_header.tl0PicIdx;
370 uint8_t temporal_index = codec_header.temporalIdx; 374 uint8_t temporal_index = codec_header.temporalIdx;
371 auto layer_info_it = layer_info_.find(tl0_pic_idx); 375 auto layer_info_it = layer_info_.find(tl0_pic_idx);
372 376
373 // Update this layer info and newer. 377 // Update this layer info and newer.
374 while (layer_info_it != layer_info_.end()) { 378 while (layer_info_it != layer_info_.end()) {
375 if (layer_info_it->second[temporal_index] != -1 && 379 if (layer_info_it->second[temporal_index] != -1 &&
376 AheadOf<uint16_t, kPicIdLength>(layer_info_it->second[temporal_index], 380 AheadOf<uint16_t, kPicIdLength>(layer_info_it->second[temporal_index],
377 frame->picture_id)) { 381 frame->picture_id)) {
378 // The frame was not newer, then no subsequent layer info have to be 382 // The frame was not newer, then no subsequent layer info have to be
379 // update. 383 // update.
380 break; 384 break;
381 } 385 }
382 386
383 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id; 387 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id;
384 ++tl0_pic_idx; 388 ++tl0_pic_idx;
385 layer_info_it = layer_info_.find(tl0_pic_idx); 389 layer_info_it = layer_info_.find(tl0_pic_idx);
386 } 390 }
387 not_yet_received_frames_.erase(frame->picture_id); 391 not_yet_received_frames_.erase(frame->picture_id);
388 392
389 UnwrapPictureIds(frame); 393 UnwrapPictureIds(frame);
390 } 394 }
391 395
392 RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9( 396 RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9(
393 RtpFrameObject* frame) { 397 RtpFrameObject* frame) {
394 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader(); 398 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader();
395 if (!rtp_codec_header) 399 if (!rtp_codec_header) {
400 LOG(LS_WARNING) << "Failed to get codec header from frame, dropping frame.";
396 return kDrop; 401 return kDrop;
402 }
397 403
398 const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9; 404 const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9;
399 405
400 if (codec_header.picture_id == kNoPictureId || 406 if (codec_header.picture_id == kNoPictureId ||
401 codec_header.temporal_idx == kNoTemporalIdx) { 407 codec_header.temporal_idx == kNoTemporalIdx) {
402 return ManageFrameGeneric(std::move(frame), codec_header.picture_id); 408 return ManageFrameGeneric(std::move(frame), codec_header.picture_id);
403 } 409 }
404 410
405 frame->spatial_layer = codec_header.spatial_idx; 411 frame->spatial_layer = codec_header.spatial_idx;
406 frame->inter_layer_predicted = codec_header.inter_layer_predicted; 412 frame->inter_layer_predicted = codec_header.inter_layer_predicted;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 ++up_switch_it) { 584 ++up_switch_it) {
579 if (up_switch_it->second < temporal_idx) 585 if (up_switch_it->second < temporal_idx)
580 return true; 586 return true;
581 } 587 }
582 588
583 return false; 589 return false;
584 } 590 }
585 591
586 void RtpFrameReferenceFinder::UnwrapPictureIds(RtpFrameObject* frame) { 592 void RtpFrameReferenceFinder::UnwrapPictureIds(RtpFrameObject* frame) {
587 for (size_t i = 0; i < frame->num_references; ++i) 593 for (size_t i = 0; i < frame->num_references; ++i)
588 frame->references[i] = UnwrapPictureId(frame->references[i]); 594 frame->references[i] = unwrapper_.Unwrap(frame->references[i]);
589 frame->picture_id = UnwrapPictureId(frame->picture_id); 595 frame->picture_id = unwrapper_.Unwrap(frame->picture_id);
590 }
591
592 uint16_t RtpFrameReferenceFinder::UnwrapPictureId(uint16_t picture_id) {
593 RTC_DCHECK_NE(-1, last_unwrap_);
594
595 uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength;
596 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id);
597
598 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated))
599 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff);
600 else
601 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff);
602
603 return last_unwrap_;
604 } 596 }
605 597
606 } // namespace video_coding 598 } // namespace video_coding
607 } // namespace webrtc 599 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698