From 44be579b4a1166894b7340eb4333f747f5dff52f Mon Sep 17 00:00:00 2001 From: Evan Shrubsole Date: Tue, 26 Apr 2022 16:24:41 +0200 Subject: [PATCH] Make all VideoReceiveStream2Test use simulated time Adds matchers to webrtc::VideoFrame to help with the tests. Bug: webrtc:14003 Change-Id: I62fc1c577bb76b21a96741ba829f6dcd53a308c1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260184 Reviewed-by: Rasmus Brandt Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Evan Shrubsole Cr-Commit-Position: refs/heads/main@{#36755} --- api/video/DEPS | 4 + api/video/test/BUILD.gn | 12 + api/video/test/video_frame_matchers.h | 34 +++ video/BUILD.gn | 3 + video/video_receive_stream2_unittest.cc | 369 +++++++++--------------- 5 files changed, 195 insertions(+), 227 deletions(-) create mode 100644 api/video/test/video_frame_matchers.h diff --git a/api/video/DEPS b/api/video/DEPS index 0176e4dc14..1c9815c847 100644 --- a/api/video/DEPS +++ b/api/video/DEPS @@ -52,4 +52,8 @@ specific_include_rules = { "rtp_video_frame_assembler.h": [ "+modules/rtp_rtcp/source/rtp_packet_received.h", ], + + "video_frame_matchers\.h": [ + "+test/gmock.h", + ], } diff --git a/api/video/test/BUILD.gn b/api/video/test/BUILD.gn index 23975f1bad..5d654cff1a 100644 --- a/api/video/test/BUILD.gn +++ b/api/video/test/BUILD.gn @@ -39,3 +39,15 @@ rtc_source_set("mock_recordable_encoded_frame") { "../../../test:test_support", ] } + +rtc_source_set("video_frame_matchers") { + testonly = true + visibility = [ "*" ] + sources = [ "video_frame_matchers.h" ] + + deps = [ + "..:video_frame", + "../..:rtp_packet_info", + "../../../test:test_support", + ] +} diff --git a/api/video/test/video_frame_matchers.h b/api/video/test/video_frame_matchers.h new file mode 100644 index 0000000000..250459377b --- /dev/null +++ b/api/video/test/video_frame_matchers.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_VIDEO_TEST_VIDEO_FRAME_MATCHERS_H_ +#define API_VIDEO_TEST_VIDEO_FRAME_MATCHERS_H_ + +#include "api/rtp_packet_infos.h" +#include "api/video/video_frame.h" +#include "test/gmock.h" + +namespace webrtc::test::video_frame_matchers { + +MATCHER_P(Rotation, rotation, "") { + return ::testing::Matches(::testing::Eq(rotation))(arg.rotation()); +} + +MATCHER_P(NtpTimestamp, ntp_ts, "") { + return arg.ntp_time_ms() == ntp_ts.ms(); +} + +MATCHER_P(PacketInfos, m, "") { + return ::testing::Matches(m)(arg.packet_infos()); +} + +} // namespace webrtc::test::video_frame_matchers + +#endif // API_VIDEO_TEST_VIDEO_FRAME_MATCHERS_H_ diff --git a/video/BUILD.gn b/video/BUILD.gn index 417e648a4d..385f37f843 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -860,6 +860,7 @@ if (rtc_include_tests) { "../api:scoped_refptr", "../api:sequence_checker", "../api:simulated_network_api", + "../api:time_controller", "../api:transport_api", "../api/adaptation:resource_adaptation_api", "../api/crypto:options", @@ -874,11 +875,13 @@ if (rtc_include_tests) { "../api/units:timestamp", "../api/video:builtin_video_bitrate_allocator_factory", "../api/video:encoded_image", + "../api/video:recordable_encoded_frame", "../api/video:video_adaptation", "../api/video:video_bitrate_allocation", "../api/video:video_frame", "../api/video:video_frame_type", "../api/video:video_rtp_headers", + "../api/video/test:video_frame_matchers", "../api/video_codecs:video_codecs_api", "../api/video_codecs:vp8_temporal_layers_factory", "../call:call_interfaces", diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc index 09f7f5301c..1026710a98 100644 --- a/video/video_receive_stream2_unittest.cc +++ b/video/video_receive_stream2_unittest.cc @@ -19,10 +19,15 @@ #include #include "absl/memory/memory.h" +#include "absl/types/optional.h" #include "api/task_queue/default_task_queue_factory.h" #include "api/test/mock_video_decoder.h" #include "api/test/mock_video_decoder_factory.h" +#include "api/test/time_controller.h" #include "api/test/video/function_video_decoder_factory.h" +#include "api/units/time_delta.h" +#include "api/video/recordable_encoded_frame.h" +#include "api/video/test/video_frame_matchers.h" #include "api/video/video_frame.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" @@ -54,30 +59,83 @@ void PrintTo(const SdpVideoFormat& value, std::ostream* os) { *os << value.ToString(); } +void PrintTo(const RecordableEncodedFrame::EncodedResolution& value, + std::ostream* os) { + *os << value.width << "x" << value.height; +} + +void PrintTo(const RecordableEncodedFrame& value, std::ostream* os) { + *os << "RecordableEncodedFrame(render_time=" << value.render_time() + << " resolution=" << ::testing::PrintToString(value.resolution()) << ")"; +} + namespace { +using test::video_frame_matchers::NtpTimestamp; +using test::video_frame_matchers::PacketInfos; +using test::video_frame_matchers::Rotation; using ::testing::_; using ::testing::AllOf; using ::testing::ElementsAreArray; +using ::testing::Eq; using ::testing::Field; using ::testing::InSequence; using ::testing::Invoke; using ::testing::IsEmpty; using ::testing::Property; +using ::testing::Return; using ::testing::SizeIs; using ::testing::WithoutArgs; -constexpr int kDefaultTimeOutMs = 50; +auto RenderedFrameWith(::testing::Matcher m) { + return Optional(m); +} + +constexpr TimeDelta kDefaultTimeOut = TimeDelta::Millis(50); constexpr int kDefaultNumCpuCores = 2; +constexpr Timestamp kStartTime = Timestamp::Millis(1'337'000); + +class FakeVideoRenderer : public rtc::VideoSinkInterface { + public: + explicit FakeVideoRenderer(test::RunLoop* loop) : loop_(loop) {} + ~FakeVideoRenderer() override = default; + + void OnFrame(const webrtc::VideoFrame& frame) override { + last_frame_ = frame; + frame_wait_.Set(); + } + + absl::optional WaitForRenderedFrame(TimeDelta wait) { + if (!last_frame_) { + loop_->Flush(); + frame_wait_.Wait(wait.ms()); + } + absl::optional ret = std::move(last_frame_); + last_frame_.reset(); + return ret; + } + + private: + absl::optional last_frame_; + test::RunLoop* const loop_; + rtc::Event frame_wait_; +}; + +MATCHER_P2(Resolution, w, h, "") { + return arg.resolution().width == w && arg.resolution().height == h; +} + } // namespace class VideoReceiveStream2Test : public ::testing::Test { public: VideoReceiveStream2Test() - : task_queue_factory_(CreateDefaultTaskQueueFactory()), + : time_controller_(kStartTime), + clock_(time_controller_.GetClock()), config_(&mock_transport_, &mock_h264_decoder_factory_), - call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()), + call_stats_(clock_, loop_.task_queue()), + fake_renderer_(&loop_), h264_decoder_factory_(&mock_h264_video_decoder_) { fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/"); @@ -122,12 +180,11 @@ class VideoReceiveStream2Test : public ::testing::Test { config_.decoders = {h265_decoder, h264_decoder}; - clock_ = Clock::GetRealTimeClock(); - - ReCreateReceiveStream(VideoReceiveStream::RecordingState()); + RecreateReceiveStream(); } - void ReCreateReceiveStream(VideoReceiveStream::RecordingState state) { + void RecreateReceiveStream(absl::optional + state = absl::nullopt) { if (video_receive_stream_) { video_receive_stream_->UnregisterFromTransport(); video_receive_stream_ = nullptr; @@ -135,29 +192,32 @@ class VideoReceiveStream2Test : public ::testing::Test { timing_ = new VCMTiming(clock_, fake_call_.trials()); video_receive_stream_ = std::make_unique( - task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores, - &packet_router_, config_.Copy(), &call_stats_, clock_, - absl::WrapUnique(timing_), &nack_periodic_processor_, nullptr); + time_controller_.GetTaskQueueFactory(), &fake_call_, + kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_, + clock_, absl::WrapUnique(timing_), &nack_periodic_processor_, + nullptr); video_receive_stream_->RegisterWithTransport( &rtp_stream_receiver_controller_); - video_receive_stream_->SetAndGetRecordingState(std::move(state), false); + if (state) + video_receive_stream_->SetAndGetRecordingState(std::move(*state), false); } protected: + GlobalSimulatedTimeController time_controller_; + Clock* const clock_; + // Tasks on the main thread can be controlled with the run loop. test::RunLoop loop_; - const std::unique_ptr task_queue_factory_; NackPeriodicProcessor nack_periodic_processor_; testing::NiceMock mock_h264_decoder_factory_; VideoReceiveStream::Config config_; internal::CallStats call_stats_; testing::NiceMock mock_h264_video_decoder_; - cricket::FakeVideoRenderer fake_renderer_; + FakeVideoRenderer fake_renderer_; cricket::FakeCall fake_call_; MockTransport mock_transport_; PacketRouter packet_router_; RtpStreamReceiverController rtp_stream_receiver_controller_; std::unique_ptr video_receive_stream_; - Clock* clock_; VCMTiming* timing_; private: @@ -175,11 +235,6 @@ TEST_F(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) { rtppacket.SetPayloadType(99); rtppacket.SetSequenceNumber(1); rtppacket.SetTimestamp(0); - rtc::Event init_decode_event; - EXPECT_CALL(mock_h264_video_decoder_, Configure).WillOnce(WithoutArgs([&] { - init_decode_event.Set(); - return true; - })); EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_)); video_receive_stream_->Start(); EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _)); @@ -187,8 +242,8 @@ TEST_F(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) { ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size())); rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet); EXPECT_CALL(mock_h264_video_decoder_, Release()); - // Make sure the decoder thread had a chance to run. - init_decode_event.Wait(kDefaultTimeOutMs); + + time_controller_.AdvanceTime(TimeDelta::Zero()); } TEST_F(VideoReceiveStream2Test, PlayoutDelay) { @@ -336,7 +391,7 @@ TEST_F(VideoReceiveStream2Test, LazyDecoderCreation) { EXPECT_CALL(mock_h264_video_decoder_, Release()); // Make sure the decoder thread had a chance to run. - init_decode_event.Wait(kDefaultTimeOutMs); + init_decode_event.Wait(kDefaultTimeOut.ms()); } TEST_F(VideoReceiveStream2Test, PassesNtpTime) { @@ -351,8 +406,8 @@ TEST_F(VideoReceiveStream2Test, PassesNtpTime) { video_receive_stream_->Start(); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); - EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs)); - EXPECT_EQ(kNtpTimestamp.ms(), fake_renderer_.ntp_time_ms()); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(NtpTimestamp(kNtpTimestamp))); } TEST_F(VideoReceiveStream2Test, PassesRotation) { @@ -366,9 +421,8 @@ TEST_F(VideoReceiveStream2Test, PassesRotation) { video_receive_stream_->Start(); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); - EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs)); - - EXPECT_EQ(kRotation, fake_renderer_.rotation()); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(Rotation(kRotation))); } TEST_F(VideoReceiveStream2Test, PassesPacketInfos) { @@ -382,9 +436,8 @@ TEST_F(VideoReceiveStream2Test, PassesPacketInfos) { video_receive_stream_->Start(); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); - EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs)); - - EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos)); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos)))); } TEST_F(VideoReceiveStream2Test, RenderedFrameUpdatesGetSources) { @@ -427,11 +480,10 @@ TEST_F(VideoReceiveStream2Test, RenderedFrameUpdatesGetSources) { // Render one video frame. int64_t timestamp_ms_min = clock_->TimeInMilliseconds(); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); - EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs)); - int64_t timestamp_ms_max = clock_->TimeInMilliseconds(); - // Verify that the per-packet information is passed to the renderer. - EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos)); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos)))); + int64_t timestamp_ms_max = clock_->TimeInMilliseconds(); // Verify that the per-packet information also updates `GetSources()`. std::vector sources = video_receive_stream_->GetSources(); @@ -492,7 +544,7 @@ TEST_F(VideoReceiveStream2Test, PassesFrameWhenEncodedFramesCallbackSet) { VideoReceiveStream::RecordingState(callback.AsStdFunction()), true); video_receive_stream_->OnCompleteFrame( MakeFrame(VideoFrameType::kVideoFrameKey, 0)); - EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs)); + EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut)); video_receive_stream_->Stop(); } @@ -507,241 +559,104 @@ TEST_F(VideoReceiveStream2Test, MovesEncodedFrameDispatchStateWhenReCreating) { VideoReceiveStream::RecordingState old_state = video_receive_stream_->SetAndGetRecordingState( VideoReceiveStream::RecordingState(), false); - ReCreateReceiveStream(std::move(old_state)); + RecreateReceiveStream(std::move(old_state)); video_receive_stream_->Stop(); } -class VideoReceiveStream2TestWithSimulatedClock - : public ::testing::TestWithParam> { - public: - class FakeRenderer : public rtc::VideoSinkInterface { - public: - void SignalDoneAfterFrames(int num_frames_received) { - signal_after_frame_count_ = num_frames_received; - if (frame_count_ == signal_after_frame_count_) - event_.Set(); - } +TEST_F(VideoReceiveStream2Test, RequestsKeyFramesUntilKeyFrameReceived) { + // Recreate receive stream with shorter delay to test rtx. + TimeDelta rtx_delay = TimeDelta::Millis(50); + config_.rtp.nack.rtp_history_ms = rtx_delay.ms(); + auto tick = rtx_delay / 2; + RecreateReceiveStream(); + video_receive_stream_->Start(); - void OnFrame(const webrtc::VideoFrame& frame) override { - if (++frame_count_ == signal_after_frame_count_) - event_.Set(); - } - - void WaitUntilDone() { event_.Wait(rtc::Event::kForever); } - - private: - int signal_after_frame_count_ = std::numeric_limits::max(); - int frame_count_ = 0; - rtc::Event event_; - }; - - class FakeDecoder2 : public test::FakeDecoder { - public: - explicit FakeDecoder2(std::function decode_callback) - : callback_(decode_callback) {} - - int32_t Decode(const EncodedImage& input, - bool missing_frames, - int64_t render_time_ms) override { - int32_t result = - FakeDecoder::Decode(input, missing_frames, render_time_ms); - callback_(); - return result; - } - - private: - std::function callback_; - }; - - static VideoReceiveStream::Config GetConfig( - Transport* transport, - VideoDecoderFactory* decoder_factory, - rtc::VideoSinkInterface* renderer) { - VideoReceiveStream::Config config(transport, decoder_factory); - config.rtp.remote_ssrc = 1111; - config.rtp.local_ssrc = 2222; - config.rtp.nack.rtp_history_ms = std::get<0>(GetParam()).ms(); // rtx-time. - config.renderer = renderer; - VideoReceiveStream::Decoder fake_decoder; - fake_decoder.payload_type = 99; - fake_decoder.video_format = SdpVideoFormat("VP8"); - config.decoders.push_back(fake_decoder); - return config; - } - - VideoReceiveStream2TestWithSimulatedClock() - : time_controller_(Timestamp::Millis(4711)), - fake_decoder_factory_([this] { - return std::make_unique([this] { OnFrameDecoded(); }); - }), - config_(GetConfig(&mock_transport_, - &fake_decoder_factory_, - &fake_renderer_)), - call_stats_(time_controller_.GetClock(), loop_.task_queue()), - video_receive_stream_( - time_controller_.GetTaskQueueFactory(), - &fake_call_, - /*num_cores=*/2, - &packet_router_, - config_.Copy(), - &call_stats_, - time_controller_.GetClock(), - std::make_unique(time_controller_.GetClock(), - fake_call_.trials()), - &nack_periodic_processor_, - nullptr) { - if (std::get<1>(GetParam())) { - fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/"); - } else { - fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer2/"); - } - video_receive_stream_.RegisterWithTransport( - &rtp_stream_receiver_controller_); - video_receive_stream_.Start(); - } - - ~VideoReceiveStream2TestWithSimulatedClock() override { - video_receive_stream_.UnregisterFromTransport(); - } - - void OnFrameDecoded() { event_->Set(); } - - void PassEncodedFrameAndWait(std::unique_ptr frame) { - event_ = std::make_unique(); - // This call will eventually end up in the Decoded method where the - // event is set. - video_receive_stream_.OnCompleteFrame(std::move(frame)); - // FrameBuffer3 runs on the test sequence so flush to ensure that decoding - // happens. - loop_.Flush(); - ASSERT_TRUE(event_->Wait(1000)); - } - - protected: - GlobalSimulatedTimeController time_controller_; - test::RunLoop loop_; - test::FunctionVideoDecoderFactory fake_decoder_factory_; - MockTransport mock_transport_; - FakeRenderer fake_renderer_; - cricket::FakeCall fake_call_; - NackPeriodicProcessor nack_periodic_processor_; - VideoReceiveStream::Config config_; - internal::CallStats call_stats_; - PacketRouter packet_router_; - RtpStreamReceiverController rtp_stream_receiver_controller_; - webrtc::internal::VideoReceiveStream2 video_receive_stream_; - std::unique_ptr event_; -}; - -TEST_P(VideoReceiveStream2TestWithSimulatedClock, - RequestsKeyFramesUntilKeyFrameReceived) { - auto tick = std::get<0>(GetParam()) / 2; - bool sent_rtcp = false; - EXPECT_CALL(mock_transport_, SendRtcp) - .Times(1) - .WillOnce(Invoke([&sent_rtcp]() { - sent_rtcp = true; - return 0; - })); - video_receive_stream_.GenerateKeyFrame(); - PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 0)); + EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(testing::Return(0)); + video_receive_stream_->GenerateKeyFrame(); + video_receive_stream_->OnCompleteFrame( + MakeFrame(VideoFrameType::kVideoFrameDelta, 0)); + fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut); time_controller_.AdvanceTime(tick); loop_.Flush(); - PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 1)); + video_receive_stream_->OnCompleteFrame( + MakeFrame(VideoFrameType::kVideoFrameDelta, 1)); + fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut); + time_controller_.AdvanceTime(TimeDelta::Zero()); testing::Mock::VerifyAndClearExpectations(&mock_transport_); - EXPECT_TRUE(sent_rtcp); // T+keyframetimeout: still no key frame received, expect key frame request // sent again. - sent_rtcp = false; - EXPECT_CALL(mock_transport_, SendRtcp) - .Times(1) - .WillOnce(Invoke([&sent_rtcp]() { - sent_rtcp = true; - return 0; - })); + EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(testing::Return(0)); time_controller_.AdvanceTime(tick); - PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 2)); - loop_.PostTask([this]() { loop_.Quit(); }); - loop_.Run(); + video_receive_stream_->OnCompleteFrame( + MakeFrame(VideoFrameType::kVideoFrameDelta, 2)); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(_)); + loop_.Flush(); testing::Mock::VerifyAndClearExpectations(&mock_transport_); - EXPECT_TRUE(sent_rtcp); // T+keyframetimeout: now send a key frame - we should not observe new key // frame requests after this. EXPECT_CALL(mock_transport_, SendRtcp).Times(0); - PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameKey, 3)); + video_receive_stream_->OnCompleteFrame( + MakeFrame(VideoFrameType::kVideoFrameKey, 3)); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(_)); time_controller_.AdvanceTime(2 * tick); - PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 4)); - loop_.PostTask([this]() { loop_.Quit(); }); - loop_.Run(); + video_receive_stream_->OnCompleteFrame( + MakeFrame(VideoFrameType::kVideoFrameDelta, 4)); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(_)); + loop_.Flush(); } -TEST_P(VideoReceiveStream2TestWithSimulatedClock, +TEST_F(VideoReceiveStream2Test, DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution) { - video_receive_stream_.Start(); + video_receive_stream_->Start(); testing::MockFunction callback; - video_receive_stream_.SetAndGetRecordingState( + video_receive_stream_->SetAndGetRecordingState( VideoReceiveStream::RecordingState(callback.AsStdFunction()), /*generate_key_frame=*/false); InSequence s; - EXPECT_CALL( - callback, - Call(AllOf( - Property(&RecordableEncodedFrame::resolution, - Field(&RecordableEncodedFrame::EncodedResolution::width, - test::FakeDecoder::kDefaultWidth)), - Property(&RecordableEncodedFrame::resolution, - Field(&RecordableEncodedFrame::EncodedResolution::height, - test::FakeDecoder::kDefaultHeight))))); + EXPECT_CALL(callback, Call(Resolution(test::FakeDecoder::kDefaultWidth, + test::FakeDecoder::kDefaultHeight))); EXPECT_CALL(callback, Call); - fake_renderer_.SignalDoneAfterFrames(2); - PassEncodedFrameAndWait( + video_receive_stream_->OnCompleteFrame( MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 0, 0)); - PassEncodedFrameAndWait( + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(_)); + video_receive_stream_->OnCompleteFrame( MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0)); - fake_renderer_.WaitUntilDone(); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(_)); - video_receive_stream_.Stop(); + video_receive_stream_->Stop(); } -TEST_P(VideoReceiveStream2TestWithSimulatedClock, +TEST_F(VideoReceiveStream2Test, DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution) { - video_receive_stream_.Start(); + video_receive_stream_->Start(); testing::MockFunction callback; - video_receive_stream_.SetAndGetRecordingState( + video_receive_stream_->SetAndGetRecordingState( VideoReceiveStream::RecordingState(callback.AsStdFunction()), /*generate_key_frame=*/false); InSequence s; - EXPECT_CALL( - callback, - Call(AllOf( - Property( - &RecordableEncodedFrame::resolution, - Field(&RecordableEncodedFrame::EncodedResolution::width, 1080)), - Property(&RecordableEncodedFrame::resolution, - Field(&RecordableEncodedFrame::EncodedResolution::height, - 720))))); + EXPECT_CALL(callback, Call(Resolution(1080u, 720u))); EXPECT_CALL(callback, Call); - fake_renderer_.SignalDoneAfterFrames(2); - PassEncodedFrameAndWait( + video_receive_stream_->OnCompleteFrame( MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 1080, 720)); - PassEncodedFrameAndWait( + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(_)); + video_receive_stream_->OnCompleteFrame( MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0)); - fake_renderer_.WaitUntilDone(); + EXPECT_THAT(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOut), + RenderedFrameWith(_)); - video_receive_stream_.Stop(); + video_receive_stream_->Stop(); } -INSTANTIATE_TEST_SUITE_P( - RtxTime, - VideoReceiveStream2TestWithSimulatedClock, - ::testing::Combine(::testing::Values(TimeDelta::Millis(200), - TimeDelta::Millis(50)), - ::testing::Bool())); - } // namespace webrtc