From d4fac6957e14068f8dbf2ab4a20006b1df044274 Mon Sep 17 00:00:00 2001 From: philipel Date: Mon, 4 Sep 2017 07:03:46 -0700 Subject: [PATCH] Unwrap picture ids in the RtpFrameReferencerFinder. First CL to avoid working with wrapping picture ids. After the references of a frame has been determined they are then unwrapped. BUG=webrtc:7874 Review-Url: https://codereview.webrtc.org/2985283002 Cr-Commit-Position: refs/heads/master@{#19663} --- webrtc/modules/video_coding/frame_buffer2.cc | 2 +- webrtc/modules/video_coding/frame_object.h | 4 +- .../rtp_frame_reference_finder.cc | 48 +- .../video_coding/rtp_frame_reference_finder.h | 13 +- .../rtp_frame_reference_finder_unittest.cc | 693 +++++++++--------- .../video_coding/sequence_number_util.h | 8 +- .../sequence_number_util_unittest.cc | 10 +- webrtc/video/rtp_video_stream_receiver.cc | 4 +- webrtc/video/rtp_video_stream_receiver.h | 8 +- 9 files changed, 399 insertions(+), 391 deletions(-) diff --git a/webrtc/modules/video_coding/frame_buffer2.cc b/webrtc/modules/video_coding/frame_buffer2.cc index 7fcb728ae4..f314ccb5f6 100644 --- a/webrtc/modules/video_coding/frame_buffer2.cc +++ b/webrtc/modules/video_coding/frame_buffer2.cc @@ -249,7 +249,7 @@ void FrameBuffer::Stop() { bool FrameBuffer::ValidReferences(const FrameObject& frame) const { for (size_t i = 0; i < frame.num_references; ++i) { - if (AheadOrAt(frame.references[i], frame.picture_id)) + if (AheadOrAt(frame.references[i], frame.picture_id)) return false; for (size_t j = i + 1; j < frame.num_references; ++j) { if (frame.references[i] == frame.references[j]) diff --git a/webrtc/modules/video_coding/frame_object.h b/webrtc/modules/video_coding/frame_object.h index 5299ed8152..90c1c00564 100644 --- a/webrtc/modules/video_coding/frame_object.h +++ b/webrtc/modules/video_coding/frame_object.h @@ -49,14 +49,14 @@ class FrameObject : public webrtc::VCMEncodedFrame { // The tuple (|picture_id|, |spatial_layer|) uniquely identifies a frame // object. For codec types that don't necessarily have picture ids they // have to be constructed from the header data relevant to that codec. - uint16_t picture_id; + int64_t picture_id; uint8_t spatial_layer; uint32_t timestamp; // TODO(philipel): Add simple modify/access functions to prevent adding too // many |references|. size_t num_references; - uint16_t references[kMaxFrameReferences]; + int64_t references[kMaxFrameReferences]; bool inter_layer_predicted; }; diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder.cc b/webrtc/modules/video_coding/rtp_frame_reference_finder.cc index 52947cb2d0..e167e15c52 100644 --- a/webrtc/modules/video_coding/rtp_frame_reference_finder.cc +++ b/webrtc/modules/video_coding/rtp_frame_reference_finder.cc @@ -176,7 +176,7 @@ RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame, if (last_unwrap_ == -1) last_unwrap_ = picture_id; - frame->picture_id = UnwrapPictureId(picture_id % kPicIdLength); + frame->picture_id = unwrapper_.Unwrap(picture_id); frame->num_references = frame->frame_type() == kVideoFrameKey ? 0 : 1; frame->references[0] = frame->picture_id - 1; return kHandOff; @@ -228,22 +228,25 @@ RtpFrameReferenceFinder::ManageFrameGeneric(RtpFrameObject* frame, // picture id according to some incrementing counter. frame->picture_id = frame->last_seq_num(); frame->num_references = frame->frame_type() == kVideoFrameDelta; - frame->references[0] = last_picture_id_gop; - if (AheadOf(frame->picture_id, last_picture_id_gop)) { + frame->references[0] = generic_unwrapper_.Unwrap(last_picture_id_gop); + if (AheadOf(frame->picture_id, last_picture_id_gop)) { seq_num_it->second.first = frame->picture_id; seq_num_it->second.second = frame->picture_id; } last_picture_id_ = frame->picture_id; UpdateLastPictureIdWithPadding(frame->picture_id); + frame->picture_id = generic_unwrapper_.Unwrap(frame->picture_id); return kHandOff; } RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8( RtpFrameObject* frame) { rtc::Optional rtp_codec_header = frame->GetCodecHeader(); - if (!rtp_codec_header) + if (!rtp_codec_header) { + LOG(LS_WARNING) << "Failed to get codec header from frame, dropping frame."; return kDrop; + } const RTPVideoHeaderVP8& codec_header = rtp_codec_header->VP8; @@ -285,7 +288,7 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8( if (frame->frame_type() == kVideoFrameKey) { frame->num_references = 0; layer_info_[codec_header.tl0PicIdx].fill(-1); - UpdateLayerInfoVp8(frame, codec_header); + UpdateLayerInfoVp8(frame); return kHandOff; } @@ -307,7 +310,7 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8( .first; frame->num_references = 1; frame->references[0] = layer_info_it->second[0]; - UpdateLayerInfoVp8(frame, codec_header); + UpdateLayerInfoVp8(frame); return kHandOff; } @@ -316,7 +319,7 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8( frame->num_references = 1; frame->references[0] = layer_info_it->second[0]; - UpdateLayerInfoVp8(frame, codec_header); + UpdateLayerInfoVp8(frame); return kHandOff; } @@ -359,13 +362,14 @@ RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp8( frame->references[layer] = layer_info_it->second[layer]; } - UpdateLayerInfoVp8(frame, codec_header); + UpdateLayerInfoVp8(frame); return kHandOff; } -void RtpFrameReferenceFinder::UpdateLayerInfoVp8( - RtpFrameObject* frame, - const RTPVideoHeaderVP8& codec_header) { +void RtpFrameReferenceFinder::UpdateLayerInfoVp8(RtpFrameObject* frame) { + rtc::Optional rtp_codec_header = frame->GetCodecHeader(); + RTC_DCHECK(rtp_codec_header); + const RTPVideoHeaderVP8& codec_header = rtp_codec_header->VP8; uint8_t tl0_pic_idx = codec_header.tl0PicIdx; uint8_t temporal_index = codec_header.temporalIdx; auto layer_info_it = layer_info_.find(tl0_pic_idx); @@ -392,8 +396,10 @@ void RtpFrameReferenceFinder::UpdateLayerInfoVp8( RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9( RtpFrameObject* frame) { rtc::Optional rtp_codec_header = frame->GetCodecHeader(); - if (!rtp_codec_header) + if (!rtp_codec_header) { + LOG(LS_WARNING) << "Failed to get codec header from frame, dropping frame."; return kDrop; + } const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9; @@ -585,22 +591,8 @@ bool RtpFrameReferenceFinder::UpSwitchInIntervalVp9(uint16_t picture_id, void RtpFrameReferenceFinder::UnwrapPictureIds(RtpFrameObject* frame) { for (size_t i = 0; i < frame->num_references; ++i) - frame->references[i] = UnwrapPictureId(frame->references[i]); - frame->picture_id = UnwrapPictureId(frame->picture_id); -} - -uint16_t RtpFrameReferenceFinder::UnwrapPictureId(uint16_t picture_id) { - RTC_DCHECK_NE(-1, last_unwrap_); - - uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength; - uint16_t diff = MinDiff(unwrap_truncated, picture_id); - - if (AheadOf(picture_id, unwrap_truncated)) - last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); - else - last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); - - return last_unwrap_; + frame->references[i] = unwrapper_.Unwrap(frame->references[i]); + frame->picture_id = unwrapper_.Unwrap(frame->picture_id); } } // namespace video_coding diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder.h b/webrtc/modules/video_coding/rtp_frame_reference_finder.h index f31ee6435c..601e7c48d8 100644 --- a/webrtc/modules/video_coding/rtp_frame_reference_finder.h +++ b/webrtc/modules/video_coding/rtp_frame_reference_finder.h @@ -99,8 +99,7 @@ class RtpFrameReferenceFinder { // Updates necessary layer info state used to determine frame references for // Vp8. - void UpdateLayerInfoVp8(RtpFrameObject* frame, - const RTPVideoHeaderVP8& codec_header) + void UpdateLayerInfoVp8(RtpFrameObject* frame) EXCLUSIVE_LOCKS_REQUIRED(crit_); // Find references for Vp9 frames @@ -126,8 +125,6 @@ class RtpFrameReferenceFinder { // Unwrap |frame|s picture id and its references to 16 bits. void UnwrapPictureIds(RtpFrameObject* frame) EXCLUSIVE_LOCKS_REQUIRED(crit_); - // All picture ids are unwrapped to 16 bits. - uint16_t UnwrapPictureId(uint16_t picture_id) EXCLUSIVE_LOCKS_REQUIRED(crit_); // Returns true if the frame is old and should be dropped. // TODO(philipel): Remove when VP9 PID/TL0 does not jump mid-stream (should be @@ -214,6 +211,14 @@ class RtpFrameReferenceFinder { int cleared_to_seq_num_ GUARDED_BY(crit_); OnCompleteFrameCallback* frame_callback_; + + // Unwrapper used to unwrap generic RTP streams. In a generic stream we derive + // a picture id from the packet sequence number. + SeqNumUnwrapper generic_unwrapper_ GUARDED_BY(crit_); + + // Unwrapper used to unwrap VP8/VP9 streams which have their picture id + // specified. + SeqNumUnwrapper unwrapper_ GUARDED_BY(crit_); }; } // namespace video_coding diff --git a/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc b/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc index 7d1c86d7fa..5500430391 100644 --- a/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc +++ b/webrtc/modules/video_coding/rtp_frame_reference_finder_unittest.cc @@ -54,16 +54,18 @@ class FakePacketBuffer : public PacketBuffer { class TestRtpFrameReferenceFinder : public ::testing::Test, public OnCompleteFrameCallback { protected: + static constexpr uint64_t kUnwrappedSequenceStart = 10000000000000000000UL; + TestRtpFrameReferenceFinder() : rand_(0x8739211), ref_packet_buffer_(new FakePacketBuffer()), reference_finder_(new RtpFrameReferenceFinder(this)), frames_from_callback_(FrameComp()) {} - uint16_t Rand() { return rand_.Rand(std::numeric_limits::max()); } + uint16_t Rand() { return rand_.Rand(); } void OnCompleteFrame(std::unique_ptr frame) override { - uint16_t pid = frame->picture_id; + int64_t pid = frame->picture_id; uint16_t sidx = frame->spatial_layer; auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx)); if (frame_it != frames_from_callback_.end()) { @@ -203,7 +205,10 @@ class TestRtpFrameReferenceFinder : public ::testing::Test, // delivered from the packet buffer, and if so, if it has the references // specified by |refs|. template - void CheckReferences(uint16_t pid, uint16_t sidx, T... refs) const { + void CheckReferences(int64_t picture_id_offset, + uint16_t sidx, + T... refs) const { + int64_t pid = kUnwrappedSequenceStart + picture_id_offset; auto frame_it = frames_from_callback_.find(std::make_pair(pid, sidx)); if (frame_it == frames_from_callback_.end()) { ADD_FAILURE() << "Could not find frame with (pid:sidx): (" << pid << ":" @@ -211,54 +216,51 @@ class TestRtpFrameReferenceFinder : public ::testing::Test, return; } - std::set actual_refs; - for (uint8_t r = 0; r < frame_it->second->num_references; ++r) { + std::set actual_refs; + for (uint8_t r = 0; r < frame_it->second->num_references; ++r) actual_refs.insert(frame_it->second->references[r]); - } - std::set expected_refs; + std::set expected_refs; RefsToSet(&expected_refs, refs...); ASSERT_EQ(expected_refs, actual_refs); } template - void CheckReferencesGeneric(uint16_t pid, T... refs) const { + void CheckReferencesGeneric(int64_t pid, T... refs) const { CheckReferences(pid, 0, refs...); } template - void CheckReferencesVp8(uint16_t pid, T... refs) const { + void CheckReferencesVp8(int64_t pid, T... refs) const { CheckReferences(pid, 0, refs...); } template - void CheckReferencesVp9(uint16_t pid, uint8_t sidx, T... refs) const { + void CheckReferencesVp9(int64_t pid, uint8_t sidx, T... refs) const { CheckReferences(pid, sidx, refs...); } template - void RefsToSet(std::set* m, uint16_t ref, T... refs) const { - m->insert(ref); + void RefsToSet(std::set* m, int64_t ref, T... refs) const { + m->insert(ref + kUnwrappedSequenceStart); RefsToSet(m, refs...); } - void RefsToSet(std::set* m) const {} + void RefsToSet(std::set* m) const {} Random rand_; rtc::scoped_refptr ref_packet_buffer_; std::unique_ptr reference_finder_; struct FrameComp { - bool operator()(const std::pair f1, - const std::pair f2) const { + bool operator()(const std::pair f1, + const std::pair f2) const { if (f1.first == f2.first) return f1.second < f2.second; return f1.first < f2.first; } }; - std::map, - std::unique_ptr, - FrameComp> + std::map, std::unique_ptr, FrameComp> frames_from_callback_; }; @@ -281,8 +283,8 @@ TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReordered) { InsertGeneric(sn + 2, sn + 3, false); EXPECT_EQ(2UL, frames_from_callback_.size()); - CheckReferencesGeneric(sn); - CheckReferencesGeneric(sn + 3, sn); + CheckReferencesGeneric(0); + CheckReferencesGeneric(3, 0); } TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReorderedMultipleKeyframes) { @@ -364,16 +366,16 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8NoPictureId) { InsertVp8(sn + 21, sn + 21, false); ASSERT_EQ(10UL, frames_from_callback_.size()); - CheckReferencesVp8(sn + 2); - CheckReferencesVp8(sn + 4, sn + 2); - CheckReferencesVp8(sn + 8, sn + 4); - CheckReferencesVp8(sn + 9, sn + 8); - CheckReferencesVp8(sn + 11, sn + 9); - CheckReferencesVp8(sn + 12); - CheckReferencesVp8(sn + 17, sn + 12); - CheckReferencesVp8(sn + 18, sn + 17); - CheckReferencesVp8(sn + 20, sn + 18); - CheckReferencesVp8(sn + 21, sn + 20); + CheckReferencesVp8(0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(6, 2); + CheckReferencesVp8(7, 6); + CheckReferencesVp8(9, 7); + CheckReferencesVp8(10); + CheckReferencesVp8(15, 10); + CheckReferencesVp8(16, 15); + CheckReferencesVp8(18, 16); + CheckReferencesVp8(19, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp8NoPictureIdReordered) { @@ -391,16 +393,16 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8NoPictureIdReordered) { InsertVp8(sn + 21, sn + 21, false); ASSERT_EQ(10UL, frames_from_callback_.size()); - CheckReferencesVp8(sn + 2); - CheckReferencesVp8(sn + 4, sn + 2); - CheckReferencesVp8(sn + 8, sn + 4); - CheckReferencesVp8(sn + 9, sn + 8); - CheckReferencesVp8(sn + 11, sn + 9); - CheckReferencesVp8(sn + 12); - CheckReferencesVp8(sn + 17, sn + 12); - CheckReferencesVp8(sn + 18, sn + 17); - CheckReferencesVp8(sn + 20, sn + 18); - CheckReferencesVp8(sn + 21, sn + 20); + CheckReferencesVp8(0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(6, 2); + CheckReferencesVp8(7, 6); + CheckReferencesVp8(9, 7); + CheckReferencesVp8(10); + CheckReferencesVp8(15, 10); + CheckReferencesVp8(16, 15); + CheckReferencesVp8(18, 16); + CheckReferencesVp8(19, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp8KeyFrameReferences) { @@ -408,7 +410,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8KeyFrameReferences) { InsertVp8(sn, sn, true); ASSERT_EQ(1UL, frames_from_callback_.size()); - CheckReferencesVp8(sn); + CheckReferencesVp8(0); } // Test with 1 temporal layer. @@ -422,10 +424,10 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_0) { InsertVp8(sn + 3, sn + 3, false, pid + 3, 0, 4); ASSERT_EQ(4UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid + 1); - CheckReferencesVp8(pid + 3, pid + 2); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 1); + CheckReferencesVp8(3, 2); } TEST_F(TestRtpFrameReferenceFinder, Vp8DuplicateTl1Frames) { @@ -441,12 +443,12 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8DuplicateTl1Frames) { InsertVp8(sn + 5, sn + 5, false, pid + 5, 1, 2); ASSERT_EQ(6UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid); - CheckReferencesVp8(pid + 3, pid + 1, pid + 2); - CheckReferencesVp8(pid + 4, pid + 2); - CheckReferencesVp8(pid + 5, pid + 3, pid + 4); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(3, 1, 2); + CheckReferencesVp8(4, 2); + CheckReferencesVp8(5, 3, 4); } // Test with 1 temporal layer. @@ -463,13 +465,13 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_0) { InsertVp8(sn + 4, sn + 4, false, pid + 4, 0, 5); ASSERT_EQ(7UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid + 1); - CheckReferencesVp8(pid + 3, pid + 2); - CheckReferencesVp8(pid + 4, pid + 3); - CheckReferencesVp8(pid + 5, pid + 4); - CheckReferencesVp8(pid + 6, pid + 5); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 1); + CheckReferencesVp8(3, 2); + CheckReferencesVp8(4, 3); + CheckReferencesVp8(5, 4); + CheckReferencesVp8(6, 5); } // Test with 2 temporal layers in a 01 pattern. @@ -483,10 +485,10 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_01) { InsertVp8(sn + 3, sn + 3, false, pid + 3, 1, 0); ASSERT_EQ(4UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid); - CheckReferencesVp8(pid + 3, pid + 1, pid + 2); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(3, 1, 2); } // Test with 2 temporal layers in a 01 pattern. @@ -504,14 +506,14 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_01) { InsertVp8(sn + 7, sn + 7, false, pid + 7, 1, 2); ASSERT_EQ(8UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid); - CheckReferencesVp8(pid + 3, pid + 1, pid + 2); - CheckReferencesVp8(pid + 4, pid + 2); - CheckReferencesVp8(pid + 5, pid + 3, pid + 4); - CheckReferencesVp8(pid + 6, pid + 4); - CheckReferencesVp8(pid + 7, pid + 5, pid + 6); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(3, 1, 2); + CheckReferencesVp8(4, 2); + CheckReferencesVp8(5, 3, 4); + CheckReferencesVp8(6, 4); + CheckReferencesVp8(7, 5, 6); } // Test with 3 temporal layers in a 0212 pattern. @@ -533,18 +535,18 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayers_0212) { InsertVp8(sn + 11, sn + 11, false, pid + 11, 2, 57); ASSERT_EQ(12UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid); - CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2); - CheckReferencesVp8(pid + 4, pid); - CheckReferencesVp8(pid + 5, pid + 2, pid + 3, pid + 4); - CheckReferencesVp8(pid + 6, pid + 2, pid + 4); - CheckReferencesVp8(pid + 7, pid + 4, pid + 5, pid + 6); - CheckReferencesVp8(pid + 8, pid + 4); - CheckReferencesVp8(pid + 9, pid + 8); - CheckReferencesVp8(pid + 10, pid + 8); - CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(3, 0, 1, 2); + CheckReferencesVp8(4, 0); + CheckReferencesVp8(5, 2, 3, 4); + CheckReferencesVp8(6, 2, 4); + CheckReferencesVp8(7, 4, 5, 6); + CheckReferencesVp8(8, 4); + CheckReferencesVp8(9, 8); + CheckReferencesVp8(10, 8); + CheckReferencesVp8(11, 8, 9, 10); } // Test with 3 temporal layers in a 0212 pattern. @@ -557,8 +559,8 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersMissingFrame_0212) { InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, 55, false); ASSERT_EQ(2UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 2, pid); + CheckReferencesVp8(0); + CheckReferencesVp8(2, 0); } // Test with 3 temporal layers in a 0212 pattern. @@ -580,18 +582,18 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8TemporalLayersReordering_0212) { InsertVp8(sn + 10, sn + 10, false, pid + 10, 1, 57, true); ASSERT_EQ(12UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid); - CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2); - CheckReferencesVp8(pid + 4, pid); - CheckReferencesVp8(pid + 5, pid + 2, pid + 3, pid + 4); - CheckReferencesVp8(pid + 6, pid + 2, pid + 4); - CheckReferencesVp8(pid + 7, pid + 4, pid + 5, pid + 6); - CheckReferencesVp8(pid + 8, pid + 4); - CheckReferencesVp8(pid + 9, pid + 8); - CheckReferencesVp8(pid + 10, pid + 8); - CheckReferencesVp8(pid + 11, pid + 8, pid + 9, pid + 10); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(3, 0, 1, 2); + CheckReferencesVp8(4, 0); + CheckReferencesVp8(5, 2, 3, 4); + CheckReferencesVp8(6, 2, 4); + CheckReferencesVp8(7, 4, 5, 6); + CheckReferencesVp8(8, 4); + CheckReferencesVp8(9, 8); + CheckReferencesVp8(10, 8); + CheckReferencesVp8(11, 8, 9, 10); } TEST_F(TestRtpFrameReferenceFinder, Vp8InsertManyFrames_0212) { @@ -600,6 +602,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8InsertManyFrames_0212) { const int keyframes_to_insert = 50; const int frames_per_keyframe = 120; // Should be a multiple of 4. + int64_t offset = 0; uint8_t tl0 = 128; for (int k = 0; k < keyframes_to_insert; ++k) { @@ -607,29 +610,31 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8InsertManyFrames_0212) { InsertVp8(sn + 1, sn + 1, false, pid + 1, 2, tl0, true); InsertVp8(sn + 2, sn + 2, false, pid + 2, 1, tl0, true); InsertVp8(sn + 3, sn + 3, false, pid + 3, 2, tl0, false); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid); - CheckReferencesVp8(pid + 3, pid, pid + 1, pid + 2); + CheckReferencesVp8(offset); + CheckReferencesVp8(offset + 1, offset); + CheckReferencesVp8(offset + 2, offset); + CheckReferencesVp8(offset + 3, offset, offset + 1, offset + 2); frames_from_callback_.clear(); ++tl0; for (int f = 4; f < frames_per_keyframe; f += 4) { uint16_t sf = sn + f; uint16_t pidf = pid + f; + int64_t offsetf = offset + f; InsertVp8(sf, sf, false, pidf, 0, tl0, false); InsertVp8(sf + 1, sf + 1, false, pidf + 1, 2, tl0, false); InsertVp8(sf + 2, sf + 2, false, pidf + 2, 1, tl0, false); InsertVp8(sf + 3, sf + 3, false, pidf + 3, 2, tl0, false); - CheckReferencesVp8(pidf, pidf - 4); - CheckReferencesVp8(pidf + 1, pidf, pidf - 1, pidf - 2); - CheckReferencesVp8(pidf + 2, pidf, pidf - 2); - CheckReferencesVp8(pidf + 3, pidf, pidf + 1, pidf + 2); + CheckReferencesVp8(offsetf, offsetf - 4); + CheckReferencesVp8(offsetf + 1, offsetf, offsetf - 1, offsetf - 2); + CheckReferencesVp8(offsetf + 2, offsetf, offsetf - 2); + CheckReferencesVp8(offsetf + 3, offsetf, offsetf + 1, offsetf + 2); frames_from_callback_.clear(); ++tl0; } + offset += frames_per_keyframe; pid += frames_per_keyframe; sn += frames_per_keyframe; } @@ -650,13 +655,13 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8LayerSync) { InsertVp8(sn + 7, sn + 7, false, pid + 7, 1, 3, false); ASSERT_EQ(7UL, frames_from_callback_.size()); - CheckReferencesVp8(pid); - CheckReferencesVp8(pid + 1, pid); - CheckReferencesVp8(pid + 2, pid); - CheckReferencesVp8(pid + 4, pid + 2); - CheckReferencesVp8(pid + 5, pid + 4); - CheckReferencesVp8(pid + 6, pid + 4); - CheckReferencesVp8(pid + 7, pid + 6, pid + 5); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(4, 2); + CheckReferencesVp8(5, 4); + CheckReferencesVp8(6, 4); + CheckReferencesVp8(7, 6, 5); } TEST_F(TestRtpFrameReferenceFinder, Vp8Tl1SyncFrameAfterTl1Frame) { @@ -666,9 +671,9 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8Tl1SyncFrameAfterTl1Frame) { InsertVp8(1003, 1003, false, 5, 1, 248, true); // due to this frame. ASSERT_EQ(3UL, frames_from_callback_.size()); - CheckReferencesVp8(1); - CheckReferencesVp8(3, 1); - CheckReferencesVp8(5, 3); + CheckReferencesVp8(0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(4, 2); } TEST_F(TestRtpFrameReferenceFinder, Vp8DetectMissingFrame_0212) { @@ -685,15 +690,15 @@ TEST_F(TestRtpFrameReferenceFinder, Vp8DetectMissingFrame_0212) { InsertVp8(5, 5, false, 5, 0, 2, false); ASSERT_EQ(8UL, frames_from_callback_.size()); - CheckReferencesVp8(1); - CheckReferencesVp8(2, 1); - CheckReferencesVp8(3, 1); - CheckReferencesVp8(4, 3, 2, 1); + CheckReferencesVp8(0); + CheckReferencesVp8(1, 0); + CheckReferencesVp8(2, 0); + CheckReferencesVp8(3, 2, 1, 0); - CheckReferencesVp8(5, 1); - CheckReferencesVp8(6, 5, 4, 3); - CheckReferencesVp8(7, 5, 3); - CheckReferencesVp8(8, 7, 6, 5); + CheckReferencesVp8(4, 0); + CheckReferencesVp8(5, 4, 3, 2); + CheckReferencesVp8(6, 4, 2); + CheckReferencesVp8(7, 6, 5, 4); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofInsertOneFrame) { @@ -704,7 +709,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofInsertOneFrame) { InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, &ss); - CheckReferencesVp9(pid, 0); + CheckReferencesVp9(0, 0); } TEST_F(TestRtpFrameReferenceFinder, Vp9NoPictureIdReordered) { @@ -722,16 +727,16 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9NoPictureIdReordered) { InsertVp9Gof(sn + 18, sn + 18, false); ASSERT_EQ(10UL, frames_from_callback_.size()); - CheckReferencesVp9(sn + 2, 0); - CheckReferencesVp9(sn + 4, 0, sn + 2); - CheckReferencesVp9(sn + 8, 0, sn + 4); - CheckReferencesVp9(sn + 9, 0, sn + 8); - CheckReferencesVp9(sn + 11, 0, sn + 9); - CheckReferencesVp9(sn + 12, 0); - CheckReferencesVp9(sn + 17, 0, sn + 12); - CheckReferencesVp9(sn + 18, 0, sn + 17); - CheckReferencesVp9(sn + 20, 0, sn + 18); - CheckReferencesVp9(sn + 21, 0, sn + 20); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(6, 0, 2); + CheckReferencesVp9(7, 0, 6); + CheckReferencesVp9(9, 0, 7); + CheckReferencesVp9(10, 0); + CheckReferencesVp9(15, 0, 10); + CheckReferencesVp9(16, 0, 15); + CheckReferencesVp9(18, 0, 16); + CheckReferencesVp9(19, 0, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0) { @@ -762,26 +767,26 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0) { InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 0, 19, false); ASSERT_EQ(20UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid + 1); - CheckReferencesVp9(pid + 3, 0, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid + 3); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 5); - CheckReferencesVp9(pid + 7, 0, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 7); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 9); - CheckReferencesVp9(pid + 11, 0, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 11); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 13); - CheckReferencesVp9(pid + 15, 0, pid + 14); - CheckReferencesVp9(pid + 16, 0, pid + 15); - CheckReferencesVp9(pid + 17, 0, pid + 16); - CheckReferencesVp9(pid + 18, 0, pid + 17); - CheckReferencesVp9(pid + 19, 0, pid + 18); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 1); + CheckReferencesVp9(3, 0, 2); + CheckReferencesVp9(4, 0, 3); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 5); + CheckReferencesVp9(7, 0, 6); + CheckReferencesVp9(8, 0, 7); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 9); + CheckReferencesVp9(11, 0, 10); + CheckReferencesVp9(12, 0, 11); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 13); + CheckReferencesVp9(15, 0, 14); + CheckReferencesVp9(16, 0, 15); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 17); + CheckReferencesVp9(19, 0, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0) { @@ -812,26 +817,26 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0) { InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 18, false); ASSERT_EQ(20UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid + 1); - CheckReferencesVp9(pid + 3, 0, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid + 3); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 5); - CheckReferencesVp9(pid + 7, 0, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 7); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 9); - CheckReferencesVp9(pid + 11, 0, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 11); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 13); - CheckReferencesVp9(pid + 15, 0, pid + 14); - CheckReferencesVp9(pid + 16, 0, pid + 15); - CheckReferencesVp9(pid + 17, 0, pid + 16); - CheckReferencesVp9(pid + 18, 0, pid + 17); - CheckReferencesVp9(pid + 19, 0, pid + 18); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 1); + CheckReferencesVp9(3, 0, 2); + CheckReferencesVp9(4, 0, 3); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 5); + CheckReferencesVp9(7, 0, 6); + CheckReferencesVp9(8, 0, 7); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 9); + CheckReferencesVp9(11, 0, 10); + CheckReferencesVp9(12, 0, 11); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 13); + CheckReferencesVp9(15, 0, 14); + CheckReferencesVp9(16, 0, 15); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 17); + CheckReferencesVp9(19, 0, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_01) { @@ -851,12 +856,12 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_01) { InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 1, 5, false); ASSERT_EQ(6UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 4, 0); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 10); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(4, 0); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 10); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) { @@ -871,10 +876,10 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) { InsertVp9Gof(sn + 3, sn + 3, false, pid + 3, 0, 2, 0, false); ASSERT_EQ(4UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 1, 2); // Skip frames with tl0 = 1 @@ -884,26 +889,26 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSkipFramesTemporalLayers_0212) { InsertVp9Gof(sn + 11, sn + 11, false, pid + 11, 0, 2, 2, false); ASSERT_EQ(8UL, frames_from_callback_.size()); - CheckReferencesVp9(pid + 8, 0); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10); + CheckReferencesVp9(8, 0); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 9, 10); // Now insert frames with tl0 = 1 InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 1, false, &ss); InsertVp9Gof(sn + 7, sn + 7, false, pid + 7, 0, 2, 1, false); ASSERT_EQ(9UL, frames_from_callback_.size()); - CheckReferencesVp9(pid + 4, 0); + CheckReferencesVp9(4, 0); // Rest of frames belonging to tl0 = 1 InsertVp9Gof(sn + 5, sn + 5, false, pid + 5, 0, 2, 1, false); InsertVp9Gof(sn + 6, sn + 6, false, pid + 6, 0, 1, 1, true); // up-switch ASSERT_EQ(12UL, frames_from_callback_.size()); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 6); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(7, 0, 6); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_01) { @@ -934,26 +939,26 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_01) { InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 1, 9, false); ASSERT_EQ(20UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid + 2); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 6); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 10); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 12); - CheckReferencesVp9(pid + 15, 0, pid + 14); - CheckReferencesVp9(pid + 16, 0, pid + 14); - CheckReferencesVp9(pid + 17, 0, pid + 16); - CheckReferencesVp9(pid + 18, 0, pid + 16); - CheckReferencesVp9(pid + 19, 0, pid + 18); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 2); + CheckReferencesVp9(4, 0, 2); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(7, 0, 6); + CheckReferencesVp9(8, 0, 6); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 10); + CheckReferencesVp9(12, 0, 10); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 12); + CheckReferencesVp9(15, 0, 14); + CheckReferencesVp9(16, 0, 14); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 16); + CheckReferencesVp9(19, 0, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01) { @@ -984,26 +989,26 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01) { InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 0, 9, false); ASSERT_EQ(20UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid + 2); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 6); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 10); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 12); - CheckReferencesVp9(pid + 15, 0, pid + 14); - CheckReferencesVp9(pid + 16, 0, pid + 14); - CheckReferencesVp9(pid + 17, 0, pid + 16); - CheckReferencesVp9(pid + 18, 0, pid + 16); - CheckReferencesVp9(pid + 19, 0, pid + 18); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 2); + CheckReferencesVp9(4, 0, 2); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(7, 0, 6); + CheckReferencesVp9(8, 0, 6); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 10); + CheckReferencesVp9(12, 0, 10); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 12); + CheckReferencesVp9(15, 0, 14); + CheckReferencesVp9(16, 0, 14); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 16); + CheckReferencesVp9(19, 0, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0212) { @@ -1034,26 +1039,26 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayers_0212) { InsertVp9Gof(sn + 19, sn + 19, false, pid + 19, 0, 2, 4, false); ASSERT_EQ(20UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 5, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 4); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 8); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 12); - CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14); - CheckReferencesVp9(pid + 16, 0, pid + 12); - CheckReferencesVp9(pid + 17, 0, pid + 16); - CheckReferencesVp9(pid + 18, 0, pid + 16); - CheckReferencesVp9(pid + 19, 0, pid + 17, pid + 18); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 1, 2); + CheckReferencesVp9(4, 0, 0); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(7, 0, 5, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 9, 10); + CheckReferencesVp9(12, 0, 8); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 12); + CheckReferencesVp9(15, 0, 13, 14); + CheckReferencesVp9(16, 0, 12); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 16); + CheckReferencesVp9(19, 0, 17, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0212) { @@ -1084,26 +1089,26 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0212) { InsertVp9Gof(sn + 18, sn + 18, false, pid + 18, 0, 1, 4, false); ASSERT_EQ(20UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 5, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 4); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 8); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 12); - CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14); - CheckReferencesVp9(pid + 16, 0, pid + 12); - CheckReferencesVp9(pid + 17, 0, pid + 16); - CheckReferencesVp9(pid + 18, 0, pid + 16); - CheckReferencesVp9(pid + 19, 0, pid + 17, pid + 18); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 1, 2); + CheckReferencesVp9(4, 0, 0); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(7, 0, 5, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 9, 10); + CheckReferencesVp9(12, 0, 8); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 12); + CheckReferencesVp9(15, 0, 13, 14); + CheckReferencesVp9(16, 0, 12); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 16); + CheckReferencesVp9(19, 0, 17, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersUpSwitch_02120212) { @@ -1130,22 +1135,22 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersUpSwitch_02120212) { InsertVp9Gof(sn + 15, sn + 15, false, pid + 15, 0, 2, 3, false); ASSERT_EQ(16UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid); - CheckReferencesVp9(pid + 5, 0, pid + 3, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 2, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 4); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 8); - CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12); - CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 1, 2); + CheckReferencesVp9(4, 0, 0); + CheckReferencesVp9(5, 0, 3, 4); + CheckReferencesVp9(6, 0, 2, 4); + CheckReferencesVp9(7, 0, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 9, 10); + CheckReferencesVp9(12, 0, 8); + CheckReferencesVp9(13, 0, 11, 12); + CheckReferencesVp9(14, 0, 10, 12); + CheckReferencesVp9(15, 0, 13, 14); } TEST_F(TestRtpFrameReferenceFinder, @@ -1173,22 +1178,22 @@ TEST_F(TestRtpFrameReferenceFinder, InsertVp9Gof(sn + 14, sn + 14, false, pid + 14, 0, 1, 3, false); ASSERT_EQ(16UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 1, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid); - CheckReferencesVp9(pid + 5, 0, pid + 3, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 2, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 4); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10); - CheckReferencesVp9(pid + 12, 0, pid + 8); - CheckReferencesVp9(pid + 13, 0, pid + 11, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 10, pid + 12); - CheckReferencesVp9(pid + 15, 0, pid + 13, pid + 14); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 1, 2); + CheckReferencesVp9(4, 0, 0); + CheckReferencesVp9(5, 0, 3, 4); + CheckReferencesVp9(6, 0, 2, 4); + CheckReferencesVp9(7, 0, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 9, 10); + CheckReferencesVp9(12, 0, 8); + CheckReferencesVp9(13, 0, 11, 12); + CheckReferencesVp9(14, 0, 10, 12); + CheckReferencesVp9(15, 0, 13, 14); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01_0212) { @@ -1212,18 +1217,18 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_01_0212) { InsertVp9Gof(sn + 9, sn + 9, false, pid + 9, 0, 2, 3, false); ASSERT_EQ(12UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 3, 0, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 7, 0, pid + 5, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 4); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, pid + 9, pid + 10); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 2); + CheckReferencesVp9(4, 0, 0); + CheckReferencesVp9(5, 0, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(7, 0, 5, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 9, 10); } TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeOneFrame) { @@ -1233,7 +1238,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeOneFrame) { InsertVp9Flex(sn, sn, true, pid, 0, 0, 0, false); ASSERT_EQ(1UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); + CheckReferencesVp9(0, 0); } TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayers) { @@ -1256,20 +1261,20 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayers) { InsertVp9Flex(sn + 13, sn + 13, false, pid + 8, 1, 0, 4, false, {1}); ASSERT_EQ(14UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid, 1); - CheckReferencesVp9(pid + 1, 1, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 2, 1, pid + 1); - CheckReferencesVp9(pid + 3, 1, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid + 2); - CheckReferencesVp9(pid + 4, 1, pid + 3); - CheckReferencesVp9(pid + 5, 1, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 6, 1, pid + 5); - CheckReferencesVp9(pid + 7, 1, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 6); - CheckReferencesVp9(pid + 8, 1, pid + 7); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(0, 1); + CheckReferencesVp9(1, 1, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(2, 1, 1); + CheckReferencesVp9(3, 1, 2); + CheckReferencesVp9(4, 0, 2); + CheckReferencesVp9(4, 1, 3); + CheckReferencesVp9(5, 1, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(6, 1, 5); + CheckReferencesVp9(7, 1, 6); + CheckReferencesVp9(8, 0, 6); + CheckReferencesVp9(8, 1, 7); } TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayersReordered) { @@ -1292,20 +1297,20 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayersReordered) { InsertVp9Flex(sn + 12, sn + 12, false, pid + 8, 0, 0, 4, false, {2}); ASSERT_EQ(14UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid, 1); - CheckReferencesVp9(pid + 1, 1, pid); - CheckReferencesVp9(pid + 2, 0, pid); - CheckReferencesVp9(pid + 2, 1, pid + 1); - CheckReferencesVp9(pid + 3, 1, pid + 2); - CheckReferencesVp9(pid + 4, 0, pid + 2); - CheckReferencesVp9(pid + 4, 1, pid + 3); - CheckReferencesVp9(pid + 5, 1, pid + 4); - CheckReferencesVp9(pid + 6, 0, pid + 4); - CheckReferencesVp9(pid + 6, 1, pid + 5); - CheckReferencesVp9(pid + 7, 1, pid + 6); - CheckReferencesVp9(pid + 8, 0, pid + 6); - CheckReferencesVp9(pid + 8, 1, pid + 7); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(0, 1); + CheckReferencesVp9(1, 1, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(2, 1, 1); + CheckReferencesVp9(3, 1, 2); + CheckReferencesVp9(4, 0, 2); + CheckReferencesVp9(4, 1, 3); + CheckReferencesVp9(5, 1, 4); + CheckReferencesVp9(6, 0, 4); + CheckReferencesVp9(6, 1, 5); + CheckReferencesVp9(7, 1, 6); + CheckReferencesVp9(8, 0, 6); + CheckReferencesVp9(8, 1, 7); } } // namespace video_coding diff --git a/webrtc/modules/video_coding/sequence_number_util.h b/webrtc/modules/video_coding/sequence_number_util.h index 008e5f1623..05f33676d5 100644 --- a/webrtc/modules/video_coding/sequence_number_util.h +++ b/webrtc/modules/video_coding/sequence_number_util.h @@ -91,7 +91,13 @@ class SeqNumUnwrapper { "Type unwrapped must be an unsigned integer smaller than uint64_t."); public: - SeqNumUnwrapper() : last_unwrapped_(0) {} + // We want a value that is close to 2^63 for two reasons. Firstly, we + // can unwrap wrapping numbers in either direction, and secondly, we avoid + // causing a crash on bad input. We also want the default value to be somewhat + // human readable, a power of 10 for example. + static constexpr uint64_t kDefaultStartValue = 10000000000000000000UL; + + SeqNumUnwrapper() : last_unwrapped_(kDefaultStartValue) {} explicit SeqNumUnwrapper(uint64_t start_at) : last_unwrapped_(start_at) {} uint64_t Unwrap(T value) { diff --git a/webrtc/modules/video_coding/sequence_number_util_unittest.cc b/webrtc/modules/video_coding/sequence_number_util_unittest.cc index e0db1a8a5f..8555fc2da1 100644 --- a/webrtc/modules/video_coding/sequence_number_util_unittest.cc +++ b/webrtc/modules/video_coding/sequence_number_util_unittest.cc @@ -212,7 +212,7 @@ TEST_F(TestSeqNumUtil, SeqNumComparatorWithDivisor) { #if GTEST_HAS_DEATH_TEST #if !defined(WEBRTC_ANDROID) TEST(SeqNumUnwrapper, NoBackWardWrap) { - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(0); EXPECT_EQ(0U, unwrapper.Unwrap(0)); // The unwrapped sequence is not allowed to wrap, if that happens the @@ -232,13 +232,13 @@ TEST(SeqNumUnwrapper, NoForwardWrap) { #endif TEST(SeqNumUnwrapper, ForwardWrap) { - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(0); EXPECT_EQ(0U, unwrapper.Unwrap(255)); EXPECT_EQ(1U, unwrapper.Unwrap(0)); } TEST(SeqNumUnwrapper, ForwardWrapWithDivisor) { - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(0); EXPECT_EQ(0U, unwrapper.Unwrap(30)); EXPECT_EQ(6U, unwrapper.Unwrap(3)); } @@ -256,7 +256,7 @@ TEST(SeqNumUnwrapper, BackWardWrapWithDivisor) { } TEST(SeqNumUnwrapper, Unwrap) { - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(0); const uint16_t kMax = std::numeric_limits::max(); const uint16_t kMaxDist = kMax / 2 + 1; @@ -294,7 +294,7 @@ TEST(SeqNumUnwrapper, ManyForwardWraps) { SeqNumUnwrapper unwrapper; uint16_t next_unwrap = 0; - uint64_t expected = 0; + uint64_t expected = decltype(unwrapper)::kDefaultStartValue; for (int i = 0; i < kNumWraps * 2 + 1; ++i) { EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap)); expected += kMaxStep; diff --git a/webrtc/video/rtp_video_stream_receiver.cc b/webrtc/video/rtp_video_stream_receiver.cc index 0dbb2f7da0..a47055abf0 100644 --- a/webrtc/video/rtp_video_stream_receiver.cc +++ b/webrtc/video/rtp_video_stream_receiver.cc @@ -589,7 +589,7 @@ bool RtpVideoStreamReceiver::DeliverRtcp(const uint8_t* rtcp_packet, return true; } -void RtpVideoStreamReceiver::FrameContinuous(uint16_t picture_id) { +void RtpVideoStreamReceiver::FrameContinuous(int64_t picture_id) { if (!nack_module_) return; @@ -604,7 +604,7 @@ void RtpVideoStreamReceiver::FrameContinuous(uint16_t picture_id) { nack_module_->ClearUpTo(seq_num); } -void RtpVideoStreamReceiver::FrameDecoded(uint16_t picture_id) { +void RtpVideoStreamReceiver::FrameDecoded(int64_t picture_id) { int seq_num = -1; { rtc::CritScope lock(&last_seq_num_cs_); diff --git a/webrtc/video/rtp_video_stream_receiver.h b/webrtc/video/rtp_video_stream_receiver.h index 15af2e60ee..f65280e627 100644 --- a/webrtc/video/rtp_video_stream_receiver.h +++ b/webrtc/video/rtp_video_stream_receiver.h @@ -93,9 +93,9 @@ class RtpVideoStreamReceiver : public RtpData, bool DeliverRtcp(const uint8_t* rtcp_packet, size_t rtcp_packet_length); - void FrameContinuous(uint16_t seq_num); + void FrameContinuous(int64_t seq_num); - void FrameDecoded(uint16_t seq_num); + void FrameDecoded(int64_t seq_num); void SignalNetworkState(NetworkState state); @@ -199,8 +199,8 @@ class RtpVideoStreamReceiver : public RtpData, rtc::scoped_refptr packet_buffer_; std::unique_ptr reference_finder_; rtc::CriticalSection last_seq_num_cs_; - std::map> - last_seq_num_for_pic_id_ GUARDED_BY(last_seq_num_cs_); + std::map last_seq_num_for_pic_id_ + GUARDED_BY(last_seq_num_cs_); video_coding::H264SpsPpsTracker tracker_; // TODO(johan): Remove pt_codec_params_ once // https://bugs.chromium.org/p/webrtc/issues/detail?id=6883 is resolved.