diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc index 5a3d1aee01..5b7c00de40 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/logging/rtc_event_log/rtc_event_log_parser.cc @@ -57,10 +57,18 @@ constexpr size_t kStunOverhead = 4; constexpr uint16_t kDefaultOverhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead; +// Starting at a multiple of common audio sample rate (48000) and video tick +// rate (90000) to make a tick count of 0 to correspond to something without +// decimals in base 10. Starting at 0 is not safe as it would cause negative +// wraparound if the first timestamps are out of order. +constexpr uint64_t kStartingCaptureTimeTicks = 90 * 48 * 1000; + struct MediaStreamInfo { - MediaStreamInfo() = default; + MediaStreamInfo() : unwrap_capture_ticks(kStartingCaptureTimeTicks) {} MediaStreamInfo(LoggedMediaType media_type, bool rtx) - : media_type(media_type), rtx(rtx) {} + : media_type(media_type), + rtx(rtx), + unwrap_capture_ticks(kStartingCaptureTimeTicks) {} LoggedMediaType media_type = LoggedMediaType::kUnknown; bool rtx = false; SeqNumUnwrapper unwrap_capture_ticks; @@ -1945,12 +1953,7 @@ std::vector ParsedRtcEventLog::GetPacketInfos( // RTX copy the timestamp of the retransmitted packets. This means that // RTX streams don't have a unique clock offset and frequency, so // the RTP timstamps can't be unwrapped. - - // Add an offset to avoid |capture_ticks| to become negative in the case - // of reordering. - constexpr int64_t kStartingCaptureTimeTicks = 90 * 48 * 1000; - int64_t capture_ticks = - kStartingCaptureTimeTicks + + uint64_t capture_ticks = stream->unwrap_capture_ticks.Unwrap(rtp.header.timestamp); // TODO(srte): Use logged sample rate when it is added to the format. capture_time = Timestamp::seconds( diff --git a/modules/video_coding/frame_buffer2.cc b/modules/video_coding/frame_buffer2.cc index d382b2e8e0..e4def869d2 100644 --- a/modules/video_coding/frame_buffer2.cc +++ b/modules/video_coding/frame_buffer2.cc @@ -328,8 +328,11 @@ void FrameBuffer::UpdateRtt(int64_t rtt_ms) { } bool FrameBuffer::ValidReferences(const EncodedFrame& frame) const { + if (frame.id.picture_id < 0) + return false; + for (size_t i = 0; i < frame.num_references; ++i) { - if (frame.references[i] >= frame.id.picture_id) + if (frame.references[i] < 0 || frame.references[i] >= frame.id.picture_id) return false; for (size_t j = i + 1; j < frame.num_references; ++j) { diff --git a/modules/video_coding/loss_notification_controller.cc b/modules/video_coding/loss_notification_controller.cc index 44cca34abd..6e07bd11be 100644 --- a/modules/video_coding/loss_notification_controller.cc +++ b/modules/video_coding/loss_notification_controller.cc @@ -69,7 +69,7 @@ void LossNotificationController::OnReceivedPacket(const VCMPacket& packet) { if (packet.generic_descriptor->FirstPacketInSubFrame()) { const uint16_t frame_id = packet.generic_descriptor->FrameId(); - const int64_t unwrapped_frame_id = frame_id_unwrapper_.Unwrap(frame_id); + const uint64_t unwrapped_frame_id = frame_id_unwrapper_.Unwrap(frame_id); // Ignore repeated or reordered frames. // TODO(TODO(bugs.webrtc.org/10336): Handle frame reordering. @@ -124,7 +124,7 @@ void LossNotificationController::OnAssembledFrame( return; } - const int64_t unwrapped_frame_id = frame_id_unwrapper_.Unwrap(frame_id); + const uint64_t unwrapped_frame_id = frame_id_unwrapper_.Unwrap(frame_id); if (!AllDependenciesDecodable(unwrapped_frame_id, frame_dependency_diffs)) { return; } @@ -142,7 +142,7 @@ void LossNotificationController::DiscardOldInformation() { } bool LossNotificationController::AllDependenciesDecodable( - int64_t unwrapped_frame_id, + uint64_t unwrapped_frame_id, rtc::ArrayView frame_dependency_diffs) const { RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_task_checker_); @@ -154,7 +154,8 @@ bool LossNotificationController::AllDependenciesDecodable( // One possibility that is ignored, is that the packet may be corrupt. for (uint16_t frame_dependency_diff : frame_dependency_diffs) { - const int64_t unwrapped_ref_frame_id = + RTC_DCHECK_GT(unwrapped_frame_id, frame_dependency_diff); + const uint64_t unwrapped_ref_frame_id = unwrapped_frame_id - frame_dependency_diff; const auto ref_frame_it = diff --git a/modules/video_coding/loss_notification_controller.h b/modules/video_coding/loss_notification_controller.h index 4cdfbb80f9..a2d640fe23 100644 --- a/modules/video_coding/loss_notification_controller.h +++ b/modules/video_coding/loss_notification_controller.h @@ -41,7 +41,7 @@ class LossNotificationController { void DiscardOldInformation(); bool AllDependenciesDecodable( - int64_t unwrapped_frame_id, + uint64_t unwrapped_frame_id, rtc::ArrayView frame_dependency_diffs) const; // When the loss of a packet or the non-decodability of a frame is detected, @@ -70,7 +70,7 @@ class LossNotificationController { RTC_GUARDED_BY(sequenced_task_checker_); // Tracked to avoid processing repeated frames (buggy/malicious remote). - absl::optional last_received_unwrapped_frame_id_ + absl::optional last_received_unwrapped_frame_id_ RTC_GUARDED_BY(sequenced_task_checker_); // Tracked to avoid processing repeated packets. @@ -97,7 +97,7 @@ class LossNotificationController { // Track which frames are decodable. Later frames are also decodable if // all of their dependencies can be found in this container. // (Naturally, later frames must also be assemblable to be decodable.) - std::set decodable_unwrapped_frame_ids_ + std::set decodable_unwrapped_frame_ids_ RTC_GUARDED_BY(sequenced_task_checker_); rtc::SequencedTaskChecker sequenced_task_checker_; diff --git a/modules/video_coding/rtp_frame_reference_finder_unittest.cc b/modules/video_coding/rtp_frame_reference_finder_unittest.cc index 5d8f6f1fcc..1f5016154a 100644 --- a/modules/video_coding/rtp_frame_reference_finder_unittest.cc +++ b/modules/video_coding/rtp_frame_reference_finder_unittest.cc @@ -54,6 +54,8 @@ class FakePacketBuffer : public PacketBuffer { class TestRtpFrameReferenceFinder : public ::testing::Test, public OnCompleteFrameCallback { protected: + static constexpr uint64_t kUnwrappedSequenceStart = 1000000000000000000UL; + TestRtpFrameReferenceFinder() : rand_(0x8739211), ref_packet_buffer_(new FakePacketBuffer()), @@ -216,7 +218,7 @@ class TestRtpFrameReferenceFinder : public ::testing::Test, void CheckReferences(int64_t picture_id_offset, uint16_t sidx, T... refs) const { - int64_t pid = picture_id_offset; + 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 << ":" @@ -251,7 +253,7 @@ class TestRtpFrameReferenceFinder : public ::testing::Test, template void RefsToSet(std::set* m, int64_t ref, T... refs) const { - m->insert(ref); + m->insert(ref + kUnwrappedSequenceStart); RefsToSet(m, refs...); } @@ -292,8 +294,8 @@ TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReordered) { InsertGeneric(sn + 2, sn + 3, false); EXPECT_EQ(2UL, frames_from_callback_.size()); - CheckReferencesGeneric(sn); - CheckReferencesGeneric(sn + 3, sn + 0); + CheckReferencesGeneric(0); + CheckReferencesGeneric(3, 0); } TEST_F(TestRtpFrameReferenceFinder, PaddingPacketsReorderedMultipleKeyframes) { @@ -375,16 +377,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) { @@ -402,16 +404,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) { @@ -419,7 +421,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. @@ -433,10 +435,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) { @@ -452,12 +454,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. @@ -474,13 +476,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. @@ -494,10 +496,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. @@ -515,14 +517,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. @@ -544,18 +546,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. @@ -568,8 +570,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. @@ -591,18 +593,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) { @@ -611,6 +613,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) { @@ -618,29 +621,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; - int64_t pidf = pid + 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; } @@ -661,13 +666,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) { @@ -677,9 +682,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) { @@ -696,15 +701,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) { @@ -715,7 +720,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofInsertOneFrame) { InsertVp9Gof(sn, sn, true, pid, 0, 0, 0, false, false, &ss); - CheckReferencesVp9(pid, 0); + CheckReferencesVp9(0, 0); } TEST_F(TestRtpFrameReferenceFinder, Vp9NoPictureIdReordered) { @@ -733,16 +738,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) { @@ -773,26 +778,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, Vp9GofSpatialLayers_2) { @@ -809,11 +814,11 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofSpatialLayers_2) { InsertVp9Gof(sn + 4, sn + 4, false, pid + 2, 1, 0, 1, false, true); ASSERT_EQ(5UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); - CheckReferencesVp9(pid + 1, 1); - CheckReferencesVp9(pid + 2, 0, pid + 1); - CheckReferencesVp9(pid + 2, 1, pid + 1); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(1, 1); + CheckReferencesVp9(2, 0, 1); + CheckReferencesVp9(2, 1, 1); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0) { @@ -844,26 +849,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) { @@ -883,12 +888,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) { @@ -903,10 +908,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 + 2); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); + CheckReferencesVp9(2, 0, 0); + CheckReferencesVp9(3, 0, 2); // Skip frames with tl0 = 1 @@ -916,26 +921,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 + 10); + CheckReferencesVp9(8, 0); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 10); // Now insert frames with tl0 = 1 InsertVp9Gof(sn + 4, sn + 4, true, pid + 4, 0, 0, 1, false, true, &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) { @@ -966,26 +971,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) { @@ -1016,26 +1021,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) { @@ -1066,26 +1071,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 + 2); - CheckReferencesVp9(pid + 4, 0, pid); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, 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 + 10); - CheckReferencesVp9(pid + 12, 0, pid + 8); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 12); - CheckReferencesVp9(pid + 15, 0, 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 + 18); + 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, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 10); + CheckReferencesVp9(12, 0, 8); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 12); + CheckReferencesVp9(15, 0, 14); + CheckReferencesVp9(16, 0, 12); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 16); + CheckReferencesVp9(19, 0, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersReordered_0212) { @@ -1116,26 +1121,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 + 2); - CheckReferencesVp9(pid + 4, 0, pid); - CheckReferencesVp9(pid + 5, 0, pid + 4); - CheckReferencesVp9(pid + 6, 0, 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 + 10); - CheckReferencesVp9(pid + 12, 0, pid + 8); - CheckReferencesVp9(pid + 13, 0, pid + 12); - CheckReferencesVp9(pid + 14, 0, pid + 12); - CheckReferencesVp9(pid + 15, 0, 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 + 18); + 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, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 10); + CheckReferencesVp9(12, 0, 8); + CheckReferencesVp9(13, 0, 12); + CheckReferencesVp9(14, 0, 12); + CheckReferencesVp9(15, 0, 14); + CheckReferencesVp9(16, 0, 12); + CheckReferencesVp9(17, 0, 16); + CheckReferencesVp9(18, 0, 16); + CheckReferencesVp9(19, 0, 18); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofTemporalLayersUpSwitch_02120212) { @@ -1162,22 +1167,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, @@ -1205,22 +1210,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) { @@ -1244,18 +1249,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 + 6); - CheckReferencesVp9(pid + 8, 0, pid + 4); - CheckReferencesVp9(pid + 9, 0, pid + 8); - CheckReferencesVp9(pid + 10, 0, pid + 8); - CheckReferencesVp9(pid + 11, 0, 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, 6); + CheckReferencesVp9(8, 0, 4); + CheckReferencesVp9(9, 0, 8); + CheckReferencesVp9(10, 0, 8); + CheckReferencesVp9(11, 0, 10); } TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeOneFrame) { @@ -1265,7 +1270,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeOneFrame) { InsertVp9Flex(sn, sn, true, pid, 0, 0, false); ASSERT_EQ(1UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); + CheckReferencesVp9(0, 0); } TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayers) { @@ -1288,20 +1293,20 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayers) { InsertVp9Flex(sn + 13, sn + 13, false, pid + 8, 1, 0, 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) { @@ -1324,28 +1329,27 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9FlexibleModeTwoSpatialLayersReordered) { InsertVp9Flex(sn + 12, sn + 12, false, pid + 8, 0, 0, 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); } TEST_F(TestRtpFrameReferenceFinder, WrappingFlexReference) { InsertVp9Flex(0, 0, false, 0, 0, 0, false, {1}); ASSERT_EQ(1UL, frames_from_callback_.size()); - const EncodedFrame& frame = *frames_from_callback_.begin()->second; - ASSERT_EQ(frame.id.picture_id - frame.references[0], 1); + CheckReferencesVp9(1, 0, 0); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofPidJump) { @@ -1364,7 +1368,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTl0Jump) { GofInfoVP9 ss; ss.SetGofInfoVP9(kTemporalStructureMode3); - InsertVp9Gof(sn, sn, true, pid, 0, 0, 125, true, false, &ss); + InsertVp9Gof(sn, sn, true, pid + 0, 0, 0, 125, true, false, &ss); InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 0, false, true, &ss); } @@ -1381,7 +1385,7 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofTidTooHigh) { InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1); ASSERT_EQ(1UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); + CheckReferencesVp9(0, 0); } TEST_F(TestRtpFrameReferenceFinder, Vp9GofZeroFrames) { @@ -1394,8 +1398,8 @@ TEST_F(TestRtpFrameReferenceFinder, Vp9GofZeroFrames) { InsertVp9Gof(sn + 1, sn + 1, false, pid + 1, 0, 0, 1); ASSERT_EQ(2UL, frames_from_callback_.size()); - CheckReferencesVp9(pid, 0); - CheckReferencesVp9(pid + 1, 0, pid); + CheckReferencesVp9(0, 0); + CheckReferencesVp9(1, 0, 0); } } // namespace video_coding diff --git a/modules/video_coding/video_packet_buffer_unittest.cc b/modules/video_coding/video_packet_buffer_unittest.cc index 9d8a3b0a33..3ef562406b 100644 --- a/modules/video_coding/video_packet_buffer_unittest.cc +++ b/modules/video_coding/video_packet_buffer_unittest.cc @@ -501,7 +501,7 @@ TEST_F(TestPacketBuffer, InsertPacketAfterOldFrameObjectIsRemoved) { uint16_t seq_num = kFirstSeqNum; // Loop until seq_num wraps around. - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(0); while (unwrapper.Unwrap(seq_num) < std::numeric_limits::max()) { Insert(seq_num++, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp); for (int i = 0; i < 5; ++i) { diff --git a/rtc_base/numerics/sequence_number_util.h b/rtc_base/numerics/sequence_number_util.h index 57efb5128d..9a7361d353 100644 --- a/rtc_base/numerics/sequence_number_util.h +++ b/rtc_base/numerics/sequence_number_util.h @@ -81,35 +81,46 @@ struct DescendingSeqNumComp { bool operator()(T a, T b) const { return AheadOf(b, a); } }; -// A sequence number unwrapper where the first unwrapped value equals the -// first value being unwrapped. +// A sequencer number unwrapper where the start value of the unwrapped sequence +// can be set. The unwrapped value is not allowed to wrap. template class SeqNumUnwrapper { + // Use '<' instead of rtc::SafeLt to avoid crbug.com/753488 static_assert( std::is_unsigned::value && - std::numeric_limits::max() < std::numeric_limits::max(), - "Type unwrapped must be an unsigned integer smaller than int64_t."); + std::numeric_limits::max() < std::numeric_limits::max(), + "Type unwrapped must be an unsigned integer smaller than uint64_t."); public: - int64_t Unwrap(T value) { - if (!last_value_) { - last_unwrapped_ = {value}; - } else { - last_unwrapped_ += ForwardDiff(*last_value_, value); + // We want a default value that is close to 2^62 for a two reasons. Firstly, + // we can unwrap wrapping numbers in either direction, and secondly, the + // unwrapped numbers can be stored in either int64_t or uint64_t. We also want + // the default value to be human readable, which makes a power of 10 suitable. + static constexpr uint64_t kDefaultStartValue = 1000000000000000000UL; - if (!AheadOrAt(value, *last_value_)) { - constexpr int64_t kBackwardAdjustment = - M == 0 ? int64_t{std::numeric_limits::max()} + 1 : M; - last_unwrapped_ -= kBackwardAdjustment; - } + SeqNumUnwrapper() : last_unwrapped_(kDefaultStartValue) {} + explicit SeqNumUnwrapper(uint64_t start_at) : last_unwrapped_(start_at) {} + + uint64_t Unwrap(T value) { + if (!last_value_) + last_value_.emplace(value); + + uint64_t unwrapped = 0; + if (AheadOrAt(value, *last_value_)) { + unwrapped = last_unwrapped_ + ForwardDiff(*last_value_, value); + RTC_CHECK_GE(unwrapped, last_unwrapped_); + } else { + unwrapped = last_unwrapped_ - ReverseDiff(*last_value_, value); + RTC_CHECK_LT(unwrapped, last_unwrapped_); } - last_value_ = value; + *last_value_ = value; + last_unwrapped_ = unwrapped; return last_unwrapped_; } private: - int64_t last_unwrapped_ = 0; + uint64_t last_unwrapped_; absl::optional last_value_; }; diff --git a/rtc_base/numerics/sequence_number_util_unittest.cc b/rtc_base/numerics/sequence_number_util_unittest.cc index 09a4514238..881e0177dd 100644 --- a/rtc_base/numerics/sequence_number_util_unittest.cc +++ b/rtc_base/numerics/sequence_number_util_unittest.cc @@ -211,65 +211,82 @@ TEST_F(TestSeqNumUtil, SeqNumComparatorWithDivisor) { } } -TEST(SeqNumUnwrapper, PreserveStartValue) { - SeqNumUnwrapper unwrapper; - EXPECT_EQ(123, unwrapper.Unwrap(123)); +#if GTEST_HAS_DEATH_TEST +#if !defined(WEBRTC_ANDROID) +TEST(SeqNumUnwrapper, NoBackWardWrap) { + SeqNumUnwrapper unwrapper(0); + EXPECT_EQ(0U, unwrapper.Unwrap(0)); + + // The unwrapped sequence is not allowed to wrap, if that happens the + // SeqNumUnwrapper should have been constructed with a higher start value. + EXPECT_DEATH(unwrapper.Unwrap(255), ""); } +TEST(SeqNumUnwrapper, NoForwardWrap) { + SeqNumUnwrapper unwrapper(std::numeric_limits::max()); + EXPECT_EQ(std::numeric_limits::max(), unwrapper.Unwrap(0)); + + // The unwrapped sequence is not allowed to wrap, if that happens the + // SeqNumUnwrapper should have been constructed with a lower start value. + EXPECT_DEATH(unwrapper.Unwrap(1), ""); +} +#endif +#endif + TEST(SeqNumUnwrapper, ForwardWrap) { - SeqNumUnwrapper unwrapper; - EXPECT_EQ(255, unwrapper.Unwrap(255)); - EXPECT_EQ(256, unwrapper.Unwrap(0)); + SeqNumUnwrapper unwrapper(0); + EXPECT_EQ(0U, unwrapper.Unwrap(255)); + EXPECT_EQ(1U, unwrapper.Unwrap(0)); } TEST(SeqNumUnwrapper, ForwardWrapWithDivisor) { - SeqNumUnwrapper unwrapper; - EXPECT_EQ(30, unwrapper.Unwrap(30)); - EXPECT_EQ(36, unwrapper.Unwrap(3)); + SeqNumUnwrapper unwrapper(0); + EXPECT_EQ(0U, unwrapper.Unwrap(30)); + EXPECT_EQ(6U, unwrapper.Unwrap(3)); } TEST(SeqNumUnwrapper, BackWardWrap) { - SeqNumUnwrapper unwrapper; - EXPECT_EQ(0, unwrapper.Unwrap(0)); - EXPECT_EQ(-2, unwrapper.Unwrap(254)); + SeqNumUnwrapper unwrapper(10); + EXPECT_EQ(10U, unwrapper.Unwrap(0)); + EXPECT_EQ(8U, unwrapper.Unwrap(254)); } TEST(SeqNumUnwrapper, BackWardWrapWithDivisor) { - SeqNumUnwrapper unwrapper; - EXPECT_EQ(0, unwrapper.Unwrap(0)); - EXPECT_EQ(-2, unwrapper.Unwrap(31)); + SeqNumUnwrapper unwrapper(10); + EXPECT_EQ(10U, unwrapper.Unwrap(0)); + EXPECT_EQ(8U, unwrapper.Unwrap(31)); } TEST(SeqNumUnwrapper, Unwrap) { - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(0); const uint16_t kMax = std::numeric_limits::max(); const uint16_t kMaxDist = kMax / 2 + 1; - EXPECT_EQ(0, unwrapper.Unwrap(0)); + EXPECT_EQ(0U, unwrapper.Unwrap(0)); EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist)); - EXPECT_EQ(0, unwrapper.Unwrap(0)); + EXPECT_EQ(0U, unwrapper.Unwrap(0)); EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist)); EXPECT_EQ(kMax, unwrapper.Unwrap(kMax)); - EXPECT_EQ(kMax + 1, unwrapper.Unwrap(0)); + EXPECT_EQ(kMax + 1U, unwrapper.Unwrap(0)); EXPECT_EQ(kMax, unwrapper.Unwrap(kMax)); EXPECT_EQ(kMaxDist, unwrapper.Unwrap(kMaxDist)); - EXPECT_EQ(0, unwrapper.Unwrap(0)); + EXPECT_EQ(0U, unwrapper.Unwrap(0)); } TEST(SeqNumUnwrapper, UnwrapOddDivisor) { - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(10); - EXPECT_EQ(10, unwrapper.Unwrap(10)); - EXPECT_EQ(11, unwrapper.Unwrap(0)); - EXPECT_EQ(16, unwrapper.Unwrap(5)); - EXPECT_EQ(21, unwrapper.Unwrap(10)); - EXPECT_EQ(22, unwrapper.Unwrap(0)); - EXPECT_EQ(17, unwrapper.Unwrap(6)); - EXPECT_EQ(12, unwrapper.Unwrap(1)); - EXPECT_EQ(7, unwrapper.Unwrap(7)); - EXPECT_EQ(2, unwrapper.Unwrap(2)); - EXPECT_EQ(0, unwrapper.Unwrap(0)); + EXPECT_EQ(10U, unwrapper.Unwrap(10)); + EXPECT_EQ(11U, unwrapper.Unwrap(0)); + EXPECT_EQ(16U, unwrapper.Unwrap(5)); + EXPECT_EQ(21U, unwrapper.Unwrap(10)); + EXPECT_EQ(22U, unwrapper.Unwrap(0)); + EXPECT_EQ(17U, unwrapper.Unwrap(6)); + EXPECT_EQ(12U, unwrapper.Unwrap(1)); + EXPECT_EQ(7U, unwrapper.Unwrap(7)); + EXPECT_EQ(2U, unwrapper.Unwrap(2)); + EXPECT_EQ(0U, unwrapper.Unwrap(0)); } TEST(SeqNumUnwrapper, ManyForwardWraps) { @@ -279,7 +296,7 @@ TEST(SeqNumUnwrapper, ManyForwardWraps) { SeqNumUnwrapper unwrapper; uint16_t next_unwrap = 0; - int64_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; @@ -291,10 +308,10 @@ TEST(SeqNumUnwrapper, ManyBackwardWraps) { const int kLargeNumber = 4711; const int kMaxStep = kLargeNumber / 2; const int kNumWraps = 100; - SeqNumUnwrapper unwrapper; + SeqNumUnwrapper unwrapper(kLargeNumber * kNumWraps); uint16_t next_unwrap = 0; - int64_t expected = 0; + uint64_t expected = kLargeNumber * kNumWraps; for (uint16_t i = 0; i < kNumWraps * 2 + 1; ++i) { EXPECT_EQ(expected, unwrapper.Unwrap(next_unwrap)); expected -= kMaxStep; diff --git a/rtc_tools/event_log_visualizer/analyzer.cc b/rtc_tools/event_log_visualizer/analyzer.cc index 2023336235..7f07329f25 100644 --- a/rtc_tools/event_log_visualizer/analyzer.cc +++ b/rtc_tools/event_log_visualizer/analyzer.cc @@ -140,10 +140,10 @@ absl::optional EstimateRtpClockFrequency( int64_t end_time_us) { RTC_CHECK(packets.size() >= 2); SeqNumUnwrapper unwrapper; - int64_t first_rtp_timestamp = + uint64_t first_rtp_timestamp = unwrapper.Unwrap(packets[0].rtp.header.timestamp); int64_t first_log_timestamp = packets[0].log_time_us(); - int64_t last_rtp_timestamp = first_rtp_timestamp; + uint64_t last_rtp_timestamp = first_rtp_timestamp; int64_t last_log_timestamp = first_log_timestamp; for (size_t i = 1; i < packets.size(); i++) { if (packets[i].log_time_us() > end_time_us)