diff --git a/video/decode_synchronizer_unittest.cc b/video/decode_synchronizer_unittest.cc index db9540f0ce..81d63029a9 100644 --- a/video/decode_synchronizer_unittest.cc +++ b/video/decode_synchronizer_unittest.cc @@ -19,7 +19,6 @@ #include "api/units/time_delta.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/run_loop.h" #include "test/time_controller/simulated_time_controller.h" #include "video/frame_decode_scheduler.h" #include "video/frame_decode_timing.h" @@ -37,12 +36,13 @@ class DecodeSynchronizerTest : public ::testing::Test { : time_controller_(Timestamp::Millis(1337)), clock_(time_controller_.GetClock()), metronome_(kTickPeriod), - decode_synchronizer_(clock_, &metronome_, run_loop_.task_queue()) {} + decode_synchronizer_(clock_, + &metronome_, + time_controller_.GetMainThread()) {} protected: GlobalSimulatedTimeController time_controller_; Clock* clock_; - test::RunLoop run_loop_; test::ForcedTickMetronome metronome_; DecodeSynchronizer decode_synchronizer_; }; @@ -77,7 +77,7 @@ TEST_F(DecodeSynchronizerTest, AllFramesReadyBeforeNextTickDecoded) { Call(Eq(frame_rtp), Eq(frame_sched.render_time))); } metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Cleanup scheduler1->Stop(); @@ -98,7 +98,7 @@ TEST_F(DecodeSynchronizerTest, FramesNotDecodedIfDecodeTimeIsInNextInterval) { mock_callback.AsStdFunction()); metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); // No decodes should have happened in this tick. ::testing::Mock::VerifyAndClearExpectations(&mock_callback); @@ -106,7 +106,7 @@ TEST_F(DecodeSynchronizerTest, FramesNotDecodedIfDecodeTimeIsInNextInterval) { EXPECT_CALL(mock_callback, Call(Eq(frame_rtp), Eq(frame_sched.render_time))); time_controller_.AdvanceTime(kTickPeriod); metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Cleanup scheduler->Stop(); @@ -124,13 +124,13 @@ TEST_F(DecodeSynchronizerTest, FrameDecodedOnce) { mock_callback.AsStdFunction()); EXPECT_CALL(mock_callback, Call(_, _)).Times(1); metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); ::testing::Mock::VerifyAndClearExpectations(&mock_callback); // Trigger tick again. No frame should be decoded now. time_controller_.AdvanceTime(kTickPeriod); metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Cleanup scheduler->Stop(); @@ -151,7 +151,7 @@ TEST_F(DecodeSynchronizerTest, FrameWithDecodeTimeInPastDecodedImmediately) { ::testing::Mock::VerifyAndClearExpectations(&mock_callback); metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Cleanup scheduler->Stop(); @@ -176,7 +176,7 @@ TEST_F(DecodeSynchronizerTest, time_controller_.AdvanceTime(kTickPeriod); metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); // A frame that would be behind by exactly kMaxAllowedFrameDelay after next // tick should decode at the next tick. @@ -191,7 +191,7 @@ TEST_F(DecodeSynchronizerTest, EXPECT_CALL(mock_callback, Call(Eq(180000u), _)).Times(1); time_controller_.AdvanceTime(kTickPeriod); metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); // Cleanup scheduler->Stop(); @@ -212,7 +212,7 @@ TEST_F(DecodeSynchronizerTest, FramesNotReleasedAfterStop) { // No callback should occur on this tick since Stop() was called before. metronome_.Tick(); - run_loop_.Flush(); + time_controller_.AdvanceTime(TimeDelta::Zero()); } TEST_F(DecodeSynchronizerTest, MetronomeNotListenedWhenNoStreamsAreActive) { diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc index f6b7df33fd..2e17f7f813 100644 --- a/video/video_receive_stream2_unittest.cc +++ b/video/video_receive_stream2_unittest.cc @@ -12,9 +12,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -49,7 +51,6 @@ #include "test/gtest.h" #include "test/mock_transport.h" #include "test/rtcp_packet_parser.h" -#include "test/run_loop.h" #include "test/time_controller/simulated_time_controller.h" #include "test/video_decoder_proxy_factory.h" #include "video/call_stats2.h" @@ -118,37 +119,33 @@ constexpr uint32_t kFirstRtpTimestamp = 90000; class FakeVideoRenderer : public rtc::VideoSinkInterface { public: - explicit FakeVideoRenderer(TimeController* time_controller, - test::RunLoop* loop) - : time_controller_(time_controller), loop_(loop) {} + explicit FakeVideoRenderer(TimeController* time_controller) + : time_controller_(time_controller) {} ~FakeVideoRenderer() override = default; void OnFrame(const VideoFrame& frame) override { RTC_LOG(LS_VERBOSE) << "Received frame with timestamp=" << frame.timestamp(); - if (last_frame_) { - RTC_LOG(LS_VERBOSE) << "Already had frame queue with timestamp=" - << last_frame_->timestamp(); + if (!last_frame_.empty()) { + RTC_LOG(LS_INFO) << "Already had frame queue with timestamp=" + << last_frame_.back().timestamp(); } - last_frame_ = frame; + last_frame_.push_back(frame); } // If `advance_time`, then the clock will always advance by `timeout`. absl::optional WaitForFrame(TimeDelta timeout, bool advance_time = false) { auto start = time_controller_->GetClock()->CurrentTime(); - if (!last_frame_) { - loop_->Flush(); + if (last_frame_.empty()) { time_controller_->AdvanceTime(TimeDelta::Zero()); - time_controller_->Wait( - [this] { - loop_->Flush(); - return last_frame_.has_value(); - }, - timeout); + time_controller_->Wait([this] { return !last_frame_.empty(); }, timeout); + } + absl::optional ret; + if (!last_frame_.empty()) { + ret = last_frame_.front(); + last_frame_.pop_front(); } - absl::optional ret = std::move(last_frame_); - last_frame_.reset(); if (advance_time) { time_controller_->AdvanceTime( timeout - (time_controller_->GetClock()->CurrentTime() - start)); @@ -157,9 +154,8 @@ class FakeVideoRenderer : public rtc::VideoSinkInterface { } private: - absl::optional last_frame_; + std::deque last_frame_; TimeController* const time_controller_; - test::RunLoop* const loop_; }; MATCHER_P2(Resolution, w, h, "") { @@ -167,7 +163,12 @@ MATCHER_P2(Resolution, w, h, "") { } MATCHER_P(RtpTimestamp, timestamp, "") { - return arg.timestamp() == timestamp; + if (arg.timestamp() != timestamp) { + *result_listener->stream() + << "rtp timestamp was " << arg.timestamp() << " != " << timestamp; + return false; + } + return true; } // Rtp timestamp for in order frame at 30fps. @@ -194,11 +195,13 @@ class VideoReceiveStream2Test : public ::testing::TestWithParam { : time_controller_(kStartTime), clock_(time_controller_.GetClock()), config_(&mock_transport_, &mock_h264_decoder_factory_), - call_stats_(clock_, loop_.task_queue()), - fake_renderer_(&time_controller_, &loop_), + call_stats_(clock_, time_controller_.GetMainThread()), + fake_renderer_(&time_controller_), fake_metronome_(time_controller_.GetTaskQueueFactory(), TimeDelta::Millis(16)), - decode_sync_(clock_, &fake_metronome_, loop_.task_queue()), + decode_sync_(clock_, + &fake_metronome_, + time_controller_.GetMainThread()), h264_decoder_factory_(&mock_decoder_) { if (UseMetronome()) { fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:SyncDecoding/"); @@ -226,6 +229,7 @@ class VideoReceiveStream2Test : public ::testing::TestWithParam { .WillByDefault( Invoke(&rtcp_packet_parser_, &test::RtcpPacketParser::Parse)); } + ~VideoReceiveStream2Test() override { if (video_receive_stream_) { video_receive_stream_->Stop(); @@ -276,8 +280,6 @@ class VideoReceiveStream2Test : public ::testing::TestWithParam { protected: GlobalSimulatedTimeController time_controller_; Clock* const clock_; - // Tasks on the main thread can be controlled with the run loop. - test::RunLoop loop_; NackPeriodicProcessor nack_periodic_processor_; testing::NiceMock mock_h264_decoder_factory_; VideoReceiveStreamInterface::Config config_; @@ -432,7 +434,6 @@ TEST_P(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) { EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames, Eq(absl::nullopt)); time_controller_.AdvanceTime(k30FpsDelay); - loop_.Flush(); // Max composition delay not set for playout delay 0,0. std::unique_ptr test_frame1 = @@ -447,7 +448,6 @@ TEST_P(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) { EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames, Eq(absl::nullopt)); time_controller_.AdvanceTime(k30FpsDelay); - loop_.Flush(); // Max composition delay not set for playout delay X,Y, where X,Y>0. std::unique_ptr test_frame2 = @@ -463,7 +463,6 @@ TEST_P(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) { Eq(absl::nullopt)); time_controller_.AdvanceTime(k30FpsDelay); - loop_.Flush(); // Max composition delay set if playout delay X,Y, where X=0,Y>0. const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps. @@ -711,7 +710,6 @@ TEST_P(VideoReceiveStream2Test, RequestsKeyFramesUntilKeyFrameReceived) { MakeFrame(VideoFrameType::kVideoFrameDelta, 0)); fake_renderer_.WaitForFrame(kDefaultTimeOut); time_controller_.AdvanceTime(tick); - loop_.Flush(); video_receive_stream_->OnCompleteFrame( MakeFrame(VideoFrameType::kVideoFrameDelta, 1)); fake_renderer_.WaitForFrame(kDefaultTimeOut); @@ -726,7 +724,6 @@ TEST_P(VideoReceiveStream2Test, RequestsKeyFramesUntilKeyFrameReceived) { video_receive_stream_->OnCompleteFrame( MakeFrame(VideoFrameType::kVideoFrameDelta, 2)); EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame()); - loop_.Flush(); testing::Mock::VerifyAndClearExpectations(&mock_transport_); EXPECT_THAT(rtcp_packet_parser_.pli()->num_packets(), Eq(2)); @@ -740,7 +737,6 @@ TEST_P(VideoReceiveStream2Test, RequestsKeyFramesUntilKeyFrameReceived) { video_receive_stream_->OnCompleteFrame( MakeFrame(VideoFrameType::kVideoFrameDelta, 4)); EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame()); - loop_.Flush(); EXPECT_THAT(rtcp_packet_parser_.pli()->num_packets(), Eq(2)); } @@ -962,8 +958,10 @@ TEST_P(VideoReceiveStream2Test, FramesFastForwardOnSystemHalt) { video_receive_stream_->OnCompleteFrame(std::move(key_frame)); video_receive_stream_->OnCompleteFrame(std::move(ffwd_frame)); video_receive_stream_->OnCompleteFrame(std::move(rendered_frame)); - EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame()); - EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame()); + EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), + RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(0)))); + EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), + RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(2)))); // Check stats show correct dropped frames. auto stats = video_receive_stream_->GetStats(); @@ -1024,6 +1022,7 @@ TEST_P(VideoReceiveStream2Test, BetterFrameInsertedWhileWaitingToDecodeFrame) { // fake delay of around 6.5 hours. Even though time is simulated, this will be // around 1,500,000 metronome tick invocations. TEST_P(VideoReceiveStream2Test, RtpTimestampWrapAround) { + EXPECT_CALL(mock_transport_, SendRtcp).Times(AnyNumber()); video_receive_stream_->Start(); constexpr uint32_t kBaseRtp = std::numeric_limits::max() / 2;