1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2017 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "video/video_receive_stream2.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
14*d9f75844SAndroid Build Coastguard Worker #include <cstddef>
15*d9f75844SAndroid Build Coastguard Worker #include <deque>
16*d9f75844SAndroid Build Coastguard Worker #include <limits>
17*d9f75844SAndroid Build Coastguard Worker #include <memory>
18*d9f75844SAndroid Build Coastguard Worker #include <ostream>
19*d9f75844SAndroid Build Coastguard Worker #include <queue>
20*d9f75844SAndroid Build Coastguard Worker #include <tuple>
21*d9f75844SAndroid Build Coastguard Worker #include <utility>
22*d9f75844SAndroid Build Coastguard Worker #include <vector>
23*d9f75844SAndroid Build Coastguard Worker
24*d9f75844SAndroid Build Coastguard Worker #include "absl/memory/memory.h"
25*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/metronome/test/fake_metronome.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/test/mock_video_decoder.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/test/mock_video_decoder_factory.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/test/time_controller.h"
30*d9f75844SAndroid Build Coastguard Worker #include "api/units/frequency.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/video/encoded_image.h"
33*d9f75844SAndroid Build Coastguard Worker #include "api/video/recordable_encoded_frame.h"
34*d9f75844SAndroid Build Coastguard Worker #include "api/video/test/video_frame_matchers.h"
35*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_frame.h"
36*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/sdp_video_format.h"
37*d9f75844SAndroid Build Coastguard Worker #include "api/video_codecs/video_decoder.h"
38*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_stream_receiver_controller.h"
39*d9f75844SAndroid Build Coastguard Worker #include "call/video_receive_stream.h"
40*d9f75844SAndroid Build Coastguard Worker #include "common_video/test/utilities.h"
41*d9f75844SAndroid Build Coastguard Worker #include "media/engine/fake_webrtc_call.h"
42*d9f75844SAndroid Build Coastguard Worker #include "modules/pacing/packet_router.h"
43*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
44*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/encoded_frame.h"
45*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
46*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
47*d9f75844SAndroid Build Coastguard Worker #include "test/fake_decoder.h"
48*d9f75844SAndroid Build Coastguard Worker #include "test/fake_encoded_frame.h"
49*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
50*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
51*d9f75844SAndroid Build Coastguard Worker #include "test/mock_transport.h"
52*d9f75844SAndroid Build Coastguard Worker #include "test/rtcp_packet_parser.h"
53*d9f75844SAndroid Build Coastguard Worker #include "test/time_controller/simulated_time_controller.h"
54*d9f75844SAndroid Build Coastguard Worker #include "test/video_decoder_proxy_factory.h"
55*d9f75844SAndroid Build Coastguard Worker #include "video/call_stats2.h"
56*d9f75844SAndroid Build Coastguard Worker
57*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
58*d9f75844SAndroid Build Coastguard Worker
59*d9f75844SAndroid Build Coastguard Worker // Printing SdpVideoFormat for gmock argument matchers.
PrintTo(const SdpVideoFormat & value,std::ostream * os)60*d9f75844SAndroid Build Coastguard Worker void PrintTo(const SdpVideoFormat& value, std::ostream* os) {
61*d9f75844SAndroid Build Coastguard Worker *os << value.ToString();
62*d9f75844SAndroid Build Coastguard Worker }
63*d9f75844SAndroid Build Coastguard Worker
PrintTo(const RecordableEncodedFrame::EncodedResolution & value,std::ostream * os)64*d9f75844SAndroid Build Coastguard Worker void PrintTo(const RecordableEncodedFrame::EncodedResolution& value,
65*d9f75844SAndroid Build Coastguard Worker std::ostream* os) {
66*d9f75844SAndroid Build Coastguard Worker *os << value.width << "x" << value.height;
67*d9f75844SAndroid Build Coastguard Worker }
68*d9f75844SAndroid Build Coastguard Worker
PrintTo(const RecordableEncodedFrame & value,std::ostream * os)69*d9f75844SAndroid Build Coastguard Worker void PrintTo(const RecordableEncodedFrame& value, std::ostream* os) {
70*d9f75844SAndroid Build Coastguard Worker *os << "RecordableEncodedFrame(render_time=" << value.render_time()
71*d9f75844SAndroid Build Coastguard Worker << " resolution=" << ::testing::PrintToString(value.resolution()) << ")";
72*d9f75844SAndroid Build Coastguard Worker }
73*d9f75844SAndroid Build Coastguard Worker
74*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
75*d9f75844SAndroid Build Coastguard Worker
76*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
77*d9f75844SAndroid Build Coastguard Worker
78*d9f75844SAndroid Build Coastguard Worker namespace {
79*d9f75844SAndroid Build Coastguard Worker
80*d9f75844SAndroid Build Coastguard Worker using test::video_frame_matchers::NtpTimestamp;
81*d9f75844SAndroid Build Coastguard Worker using test::video_frame_matchers::PacketInfos;
82*d9f75844SAndroid Build Coastguard Worker using test::video_frame_matchers::Rotation;
83*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
84*d9f75844SAndroid Build Coastguard Worker using ::testing::AllOf;
85*d9f75844SAndroid Build Coastguard Worker using ::testing::AnyNumber;
86*d9f75844SAndroid Build Coastguard Worker using ::testing::ElementsAreArray;
87*d9f75844SAndroid Build Coastguard Worker using ::testing::Eq;
88*d9f75844SAndroid Build Coastguard Worker using ::testing::Field;
89*d9f75844SAndroid Build Coastguard Worker using ::testing::InSequence;
90*d9f75844SAndroid Build Coastguard Worker using ::testing::Invoke;
91*d9f75844SAndroid Build Coastguard Worker using ::testing::IsEmpty;
92*d9f75844SAndroid Build Coastguard Worker using ::testing::Optional;
93*d9f75844SAndroid Build Coastguard Worker using ::testing::Pointee;
94*d9f75844SAndroid Build Coastguard Worker using ::testing::Property;
95*d9f75844SAndroid Build Coastguard Worker using ::testing::Return;
96*d9f75844SAndroid Build Coastguard Worker using ::testing::SizeIs;
97*d9f75844SAndroid Build Coastguard Worker using ::testing::WithoutArgs;
98*d9f75844SAndroid Build Coastguard Worker
RenderedFrameWith(::testing::Matcher<VideoFrame> m)99*d9f75844SAndroid Build Coastguard Worker auto RenderedFrameWith(::testing::Matcher<VideoFrame> m) {
100*d9f75844SAndroid Build Coastguard Worker return Optional(m);
101*d9f75844SAndroid Build Coastguard Worker }
RenderedFrame()102*d9f75844SAndroid Build Coastguard Worker auto RenderedFrame() {
103*d9f75844SAndroid Build Coastguard Worker return RenderedFrameWith(_);
104*d9f75844SAndroid Build Coastguard Worker }
DidNotReceiveFrame()105*d9f75844SAndroid Build Coastguard Worker testing::Matcher<absl::optional<VideoFrame>> DidNotReceiveFrame() {
106*d9f75844SAndroid Build Coastguard Worker return Eq(absl::nullopt);
107*d9f75844SAndroid Build Coastguard Worker }
108*d9f75844SAndroid Build Coastguard Worker
109*d9f75844SAndroid Build Coastguard Worker constexpr TimeDelta kDefaultTimeOut = TimeDelta::Millis(50);
110*d9f75844SAndroid Build Coastguard Worker constexpr int kDefaultNumCpuCores = 2;
111*d9f75844SAndroid Build Coastguard Worker
112*d9f75844SAndroid Build Coastguard Worker constexpr Timestamp kStartTime = Timestamp::Millis(1'337'000);
113*d9f75844SAndroid Build Coastguard Worker constexpr Frequency k30Fps = Frequency::Hertz(30);
114*d9f75844SAndroid Build Coastguard Worker constexpr TimeDelta k30FpsDelay = 1 / k30Fps;
115*d9f75844SAndroid Build Coastguard Worker constexpr Frequency kRtpTimestampHz = Frequency::KiloHertz(90);
116*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t k30FpsRtpTimestampDelta = kRtpTimestampHz / k30Fps;
117*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kFirstRtpTimestamp = 90000;
118*d9f75844SAndroid Build Coastguard Worker
119*d9f75844SAndroid Build Coastguard Worker class FakeVideoRenderer : public rtc::VideoSinkInterface<VideoFrame> {
120*d9f75844SAndroid Build Coastguard Worker public:
FakeVideoRenderer(TimeController * time_controller)121*d9f75844SAndroid Build Coastguard Worker explicit FakeVideoRenderer(TimeController* time_controller)
122*d9f75844SAndroid Build Coastguard Worker : time_controller_(time_controller) {}
123*d9f75844SAndroid Build Coastguard Worker ~FakeVideoRenderer() override = default;
124*d9f75844SAndroid Build Coastguard Worker
OnFrame(const VideoFrame & frame)125*d9f75844SAndroid Build Coastguard Worker void OnFrame(const VideoFrame& frame) override {
126*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_VERBOSE) << "Received frame with timestamp="
127*d9f75844SAndroid Build Coastguard Worker << frame.timestamp();
128*d9f75844SAndroid Build Coastguard Worker if (!last_frame_.empty()) {
129*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "Already had frame queue with timestamp="
130*d9f75844SAndroid Build Coastguard Worker << last_frame_.back().timestamp();
131*d9f75844SAndroid Build Coastguard Worker }
132*d9f75844SAndroid Build Coastguard Worker last_frame_.push_back(frame);
133*d9f75844SAndroid Build Coastguard Worker }
134*d9f75844SAndroid Build Coastguard Worker
135*d9f75844SAndroid Build Coastguard Worker // If `advance_time`, then the clock will always advance by `timeout`.
WaitForFrame(TimeDelta timeout,bool advance_time=false)136*d9f75844SAndroid Build Coastguard Worker absl::optional<VideoFrame> WaitForFrame(TimeDelta timeout,
137*d9f75844SAndroid Build Coastguard Worker bool advance_time = false) {
138*d9f75844SAndroid Build Coastguard Worker auto start = time_controller_->GetClock()->CurrentTime();
139*d9f75844SAndroid Build Coastguard Worker if (last_frame_.empty()) {
140*d9f75844SAndroid Build Coastguard Worker time_controller_->AdvanceTime(TimeDelta::Zero());
141*d9f75844SAndroid Build Coastguard Worker time_controller_->Wait([this] { return !last_frame_.empty(); }, timeout);
142*d9f75844SAndroid Build Coastguard Worker }
143*d9f75844SAndroid Build Coastguard Worker absl::optional<VideoFrame> ret;
144*d9f75844SAndroid Build Coastguard Worker if (!last_frame_.empty()) {
145*d9f75844SAndroid Build Coastguard Worker ret = last_frame_.front();
146*d9f75844SAndroid Build Coastguard Worker last_frame_.pop_front();
147*d9f75844SAndroid Build Coastguard Worker }
148*d9f75844SAndroid Build Coastguard Worker if (advance_time) {
149*d9f75844SAndroid Build Coastguard Worker time_controller_->AdvanceTime(
150*d9f75844SAndroid Build Coastguard Worker timeout - (time_controller_->GetClock()->CurrentTime() - start));
151*d9f75844SAndroid Build Coastguard Worker }
152*d9f75844SAndroid Build Coastguard Worker return ret;
153*d9f75844SAndroid Build Coastguard Worker }
154*d9f75844SAndroid Build Coastguard Worker
155*d9f75844SAndroid Build Coastguard Worker private:
156*d9f75844SAndroid Build Coastguard Worker std::deque<VideoFrame> last_frame_;
157*d9f75844SAndroid Build Coastguard Worker TimeController* const time_controller_;
158*d9f75844SAndroid Build Coastguard Worker };
159*d9f75844SAndroid Build Coastguard Worker
160*d9f75844SAndroid Build Coastguard Worker MATCHER_P2(MatchResolution, w, h, "") {
161*d9f75844SAndroid Build Coastguard Worker return arg.resolution().width == w && arg.resolution().height == h;
162*d9f75844SAndroid Build Coastguard Worker }
163*d9f75844SAndroid Build Coastguard Worker
164*d9f75844SAndroid Build Coastguard Worker MATCHER_P(RtpTimestamp, timestamp, "") {
165*d9f75844SAndroid Build Coastguard Worker if (arg.timestamp() != timestamp) {
166*d9f75844SAndroid Build Coastguard Worker *result_listener->stream()
167*d9f75844SAndroid Build Coastguard Worker << "rtp timestamp was " << arg.timestamp() << " != " << timestamp;
168*d9f75844SAndroid Build Coastguard Worker return false;
169*d9f75844SAndroid Build Coastguard Worker }
170*d9f75844SAndroid Build Coastguard Worker return true;
171*d9f75844SAndroid Build Coastguard Worker }
172*d9f75844SAndroid Build Coastguard Worker
173*d9f75844SAndroid Build Coastguard Worker // Rtp timestamp for in order frame at 30fps.
RtpTimestampForFrame(int id)174*d9f75844SAndroid Build Coastguard Worker uint32_t RtpTimestampForFrame(int id) {
175*d9f75844SAndroid Build Coastguard Worker return kFirstRtpTimestamp + id * k30FpsRtpTimestampDelta;
176*d9f75844SAndroid Build Coastguard Worker }
177*d9f75844SAndroid Build Coastguard Worker
178*d9f75844SAndroid Build Coastguard Worker // Receive time for in order frame at 30fps.
ReceiveTimeForFrame(int id)179*d9f75844SAndroid Build Coastguard Worker Timestamp ReceiveTimeForFrame(int id) {
180*d9f75844SAndroid Build Coastguard Worker return kStartTime + id * k30FpsDelay;
181*d9f75844SAndroid Build Coastguard Worker }
182*d9f75844SAndroid Build Coastguard Worker
183*d9f75844SAndroid Build Coastguard Worker } // namespace
184*d9f75844SAndroid Build Coastguard Worker
185*d9f75844SAndroid Build Coastguard Worker class VideoReceiveStream2Test : public ::testing::TestWithParam<bool> {
186*d9f75844SAndroid Build Coastguard Worker public:
DefaultDecodeAction()187*d9f75844SAndroid Build Coastguard Worker auto DefaultDecodeAction() {
188*d9f75844SAndroid Build Coastguard Worker return Invoke(&fake_decoder_, &test::FakeDecoder::Decode);
189*d9f75844SAndroid Build Coastguard Worker }
190*d9f75844SAndroid Build Coastguard Worker
UseMetronome() const191*d9f75844SAndroid Build Coastguard Worker bool UseMetronome() const { return GetParam(); }
192*d9f75844SAndroid Build Coastguard Worker
VideoReceiveStream2Test()193*d9f75844SAndroid Build Coastguard Worker VideoReceiveStream2Test()
194*d9f75844SAndroid Build Coastguard Worker : time_controller_(kStartTime),
195*d9f75844SAndroid Build Coastguard Worker clock_(time_controller_.GetClock()),
196*d9f75844SAndroid Build Coastguard Worker config_(&mock_transport_, &mock_h264_decoder_factory_),
197*d9f75844SAndroid Build Coastguard Worker call_stats_(clock_, time_controller_.GetMainThread()),
198*d9f75844SAndroid Build Coastguard Worker fake_renderer_(&time_controller_),
199*d9f75844SAndroid Build Coastguard Worker fake_metronome_(TimeDelta::Millis(16)),
200*d9f75844SAndroid Build Coastguard Worker decode_sync_(clock_,
201*d9f75844SAndroid Build Coastguard Worker &fake_metronome_,
202*d9f75844SAndroid Build Coastguard Worker time_controller_.GetMainThread()),
203*d9f75844SAndroid Build Coastguard Worker h264_decoder_factory_(&mock_decoder_) {
204*d9f75844SAndroid Build Coastguard Worker // By default, mock decoder factory is backed by VideoDecoderProxyFactory.
205*d9f75844SAndroid Build Coastguard Worker ON_CALL(mock_h264_decoder_factory_, CreateVideoDecoder)
206*d9f75844SAndroid Build Coastguard Worker .WillByDefault(
207*d9f75844SAndroid Build Coastguard Worker Invoke(&h264_decoder_factory_,
208*d9f75844SAndroid Build Coastguard Worker &test::VideoDecoderProxyFactory::CreateVideoDecoder));
209*d9f75844SAndroid Build Coastguard Worker
210*d9f75844SAndroid Build Coastguard Worker // By default, mock decode will wrap the fake decoder.
211*d9f75844SAndroid Build Coastguard Worker ON_CALL(mock_decoder_, Configure)
212*d9f75844SAndroid Build Coastguard Worker .WillByDefault(Invoke(&fake_decoder_, &test::FakeDecoder::Configure));
213*d9f75844SAndroid Build Coastguard Worker ON_CALL(mock_decoder_, Decode).WillByDefault(DefaultDecodeAction());
214*d9f75844SAndroid Build Coastguard Worker ON_CALL(mock_decoder_, RegisterDecodeCompleteCallback)
215*d9f75844SAndroid Build Coastguard Worker .WillByDefault(
216*d9f75844SAndroid Build Coastguard Worker Invoke(&fake_decoder_,
217*d9f75844SAndroid Build Coastguard Worker &test::FakeDecoder::RegisterDecodeCompleteCallback));
218*d9f75844SAndroid Build Coastguard Worker ON_CALL(mock_decoder_, Release)
219*d9f75844SAndroid Build Coastguard Worker .WillByDefault(Invoke(&fake_decoder_, &test::FakeDecoder::Release));
220*d9f75844SAndroid Build Coastguard Worker ON_CALL(mock_transport_, SendRtcp)
221*d9f75844SAndroid Build Coastguard Worker .WillByDefault(
222*d9f75844SAndroid Build Coastguard Worker Invoke(&rtcp_packet_parser_, &test::RtcpPacketParser::Parse));
223*d9f75844SAndroid Build Coastguard Worker }
224*d9f75844SAndroid Build Coastguard Worker
~VideoReceiveStream2Test()225*d9f75844SAndroid Build Coastguard Worker ~VideoReceiveStream2Test() override {
226*d9f75844SAndroid Build Coastguard Worker if (video_receive_stream_) {
227*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
228*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->UnregisterFromTransport();
229*d9f75844SAndroid Build Coastguard Worker }
230*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(TimeDelta::Zero());
231*d9f75844SAndroid Build Coastguard Worker }
232*d9f75844SAndroid Build Coastguard Worker
SetUp()233*d9f75844SAndroid Build Coastguard Worker void SetUp() override {
234*d9f75844SAndroid Build Coastguard Worker config_.rtp.remote_ssrc = 1111;
235*d9f75844SAndroid Build Coastguard Worker config_.rtp.local_ssrc = 2222;
236*d9f75844SAndroid Build Coastguard Worker config_.renderer = &fake_renderer_;
237*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::Decoder h264_decoder;
238*d9f75844SAndroid Build Coastguard Worker h264_decoder.payload_type = 99;
239*d9f75844SAndroid Build Coastguard Worker h264_decoder.video_format = SdpVideoFormat("H264");
240*d9f75844SAndroid Build Coastguard Worker h264_decoder.video_format.parameters.insert(
241*d9f75844SAndroid Build Coastguard Worker {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
242*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::Decoder h265_decoder;
243*d9f75844SAndroid Build Coastguard Worker h265_decoder.payload_type = 100;
244*d9f75844SAndroid Build Coastguard Worker h265_decoder.video_format = SdpVideoFormat("H265");
245*d9f75844SAndroid Build Coastguard Worker
246*d9f75844SAndroid Build Coastguard Worker config_.decoders = {h265_decoder, h264_decoder};
247*d9f75844SAndroid Build Coastguard Worker
248*d9f75844SAndroid Build Coastguard Worker RecreateReceiveStream();
249*d9f75844SAndroid Build Coastguard Worker }
250*d9f75844SAndroid Build Coastguard Worker
RecreateReceiveStream(absl::optional<VideoReceiveStreamInterface::RecordingState> state=absl::nullopt)251*d9f75844SAndroid Build Coastguard Worker void RecreateReceiveStream(
252*d9f75844SAndroid Build Coastguard Worker absl::optional<VideoReceiveStreamInterface::RecordingState> state =
253*d9f75844SAndroid Build Coastguard Worker absl::nullopt) {
254*d9f75844SAndroid Build Coastguard Worker if (video_receive_stream_) {
255*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->UnregisterFromTransport();
256*d9f75844SAndroid Build Coastguard Worker video_receive_stream_ = nullptr;
257*d9f75844SAndroid Build Coastguard Worker }
258*d9f75844SAndroid Build Coastguard Worker timing_ = new VCMTiming(clock_, fake_call_.trials());
259*d9f75844SAndroid Build Coastguard Worker video_receive_stream_ =
260*d9f75844SAndroid Build Coastguard Worker std::make_unique<webrtc::internal::VideoReceiveStream2>(
261*d9f75844SAndroid Build Coastguard Worker time_controller_.GetTaskQueueFactory(), &fake_call_,
262*d9f75844SAndroid Build Coastguard Worker kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_,
263*d9f75844SAndroid Build Coastguard Worker clock_, absl::WrapUnique(timing_), &nack_periodic_processor_,
264*d9f75844SAndroid Build Coastguard Worker UseMetronome() ? &decode_sync_ : nullptr, nullptr);
265*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->RegisterWithTransport(
266*d9f75844SAndroid Build Coastguard Worker &rtp_stream_receiver_controller_);
267*d9f75844SAndroid Build Coastguard Worker if (state)
268*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetAndGetRecordingState(std::move(*state), false);
269*d9f75844SAndroid Build Coastguard Worker }
270*d9f75844SAndroid Build Coastguard Worker
271*d9f75844SAndroid Build Coastguard Worker protected:
272*d9f75844SAndroid Build Coastguard Worker GlobalSimulatedTimeController time_controller_;
273*d9f75844SAndroid Build Coastguard Worker Clock* const clock_;
274*d9f75844SAndroid Build Coastguard Worker NackPeriodicProcessor nack_periodic_processor_;
275*d9f75844SAndroid Build Coastguard Worker testing::NiceMock<MockVideoDecoderFactory> mock_h264_decoder_factory_;
276*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::Config config_;
277*d9f75844SAndroid Build Coastguard Worker internal::CallStats call_stats_;
278*d9f75844SAndroid Build Coastguard Worker testing::NiceMock<MockVideoDecoder> mock_decoder_;
279*d9f75844SAndroid Build Coastguard Worker FakeVideoRenderer fake_renderer_;
280*d9f75844SAndroid Build Coastguard Worker cricket::FakeCall fake_call_;
281*d9f75844SAndroid Build Coastguard Worker MockTransport mock_transport_;
282*d9f75844SAndroid Build Coastguard Worker test::RtcpPacketParser rtcp_packet_parser_;
283*d9f75844SAndroid Build Coastguard Worker PacketRouter packet_router_;
284*d9f75844SAndroid Build Coastguard Worker RtpStreamReceiverController rtp_stream_receiver_controller_;
285*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
286*d9f75844SAndroid Build Coastguard Worker VCMTiming* timing_;
287*d9f75844SAndroid Build Coastguard Worker test::FakeMetronome fake_metronome_;
288*d9f75844SAndroid Build Coastguard Worker DecodeSynchronizer decode_sync_;
289*d9f75844SAndroid Build Coastguard Worker
290*d9f75844SAndroid Build Coastguard Worker private:
291*d9f75844SAndroid Build Coastguard Worker test::VideoDecoderProxyFactory h264_decoder_factory_;
292*d9f75844SAndroid Build Coastguard Worker test::FakeDecoder fake_decoder_;
293*d9f75844SAndroid Build Coastguard Worker };
294*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,CreateFrameFromH264FmtpSpropAndIdr)295*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) {
296*d9f75844SAndroid Build Coastguard Worker constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
297*d9f75844SAndroid Build Coastguard Worker RtpPacketToSend rtppacket(nullptr);
298*d9f75844SAndroid Build Coastguard Worker uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
299*d9f75844SAndroid Build Coastguard Worker memcpy(payload, idr_nalu, sizeof(idr_nalu));
300*d9f75844SAndroid Build Coastguard Worker rtppacket.SetMarker(true);
301*d9f75844SAndroid Build Coastguard Worker rtppacket.SetSsrc(1111);
302*d9f75844SAndroid Build Coastguard Worker rtppacket.SetPayloadType(99);
303*d9f75844SAndroid Build Coastguard Worker rtppacket.SetSequenceNumber(1);
304*d9f75844SAndroid Build Coastguard Worker rtppacket.SetTimestamp(0);
305*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback(_));
306*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
307*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Decode(_, false, _));
308*d9f75844SAndroid Build Coastguard Worker RtpPacketReceived parsed_packet;
309*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
310*d9f75844SAndroid Build Coastguard Worker rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
311*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Release());
312*d9f75844SAndroid Build Coastguard Worker
313*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(TimeDelta::Zero());
314*d9f75844SAndroid Build Coastguard Worker }
315*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,PlayoutDelay)316*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PlayoutDelay) {
317*d9f75844SAndroid Build Coastguard Worker const VideoPlayoutDelay kPlayoutDelayMs = {123, 321};
318*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame =
319*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(0).AsLast().Build();
320*d9f75844SAndroid Build Coastguard Worker test_frame->SetPlayoutDelay(kPlayoutDelayMs);
321*d9f75844SAndroid Build Coastguard Worker
322*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame));
323*d9f75844SAndroid Build Coastguard Worker auto timings = timing_->GetTimings();
324*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
325*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
326*d9f75844SAndroid Build Coastguard Worker
327*d9f75844SAndroid Build Coastguard Worker // Check that the biggest minimum delay is chosen.
328*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetMinimumPlayoutDelay(400);
329*d9f75844SAndroid Build Coastguard Worker timings = timing_->GetTimings();
330*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(400, timings.min_playout_delay.ms());
331*d9f75844SAndroid Build Coastguard Worker
332*d9f75844SAndroid Build Coastguard Worker // Check base minimum delay validation.
333*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
334*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
335*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
336*d9f75844SAndroid Build Coastguard Worker timings = timing_->GetTimings();
337*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(500, timings.min_playout_delay.ms());
338*d9f75844SAndroid Build Coastguard Worker
339*d9f75844SAndroid Build Coastguard Worker // Check that intermidiate values are remembered and the biggest remembered
340*d9f75844SAndroid Build Coastguard Worker // is chosen.
341*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
342*d9f75844SAndroid Build Coastguard Worker timings = timing_->GetTimings();
343*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(400, timings.min_playout_delay.ms());
344*d9f75844SAndroid Build Coastguard Worker
345*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetMinimumPlayoutDelay(0);
346*d9f75844SAndroid Build Coastguard Worker timings = timing_->GetTimings();
347*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(123, timings.min_playout_delay.ms());
348*d9f75844SAndroid Build Coastguard Worker }
349*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,PlayoutDelayPreservesDefaultMaxValue)350*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
351*d9f75844SAndroid Build Coastguard Worker const TimeDelta default_max_playout_latency =
352*d9f75844SAndroid Build Coastguard Worker timing_->GetTimings().max_playout_delay;
353*d9f75844SAndroid Build Coastguard Worker const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
354*d9f75844SAndroid Build Coastguard Worker
355*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame =
356*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(0).AsLast().Build();
357*d9f75844SAndroid Build Coastguard Worker test_frame->SetPlayoutDelay(kPlayoutDelayMs);
358*d9f75844SAndroid Build Coastguard Worker
359*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame));
360*d9f75844SAndroid Build Coastguard Worker
361*d9f75844SAndroid Build Coastguard Worker // Ensure that -1 preserves default maximum value from `timing_`.
362*d9f75844SAndroid Build Coastguard Worker auto timings = timing_->GetTimings();
363*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
364*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
365*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(default_max_playout_latency, timings.max_playout_delay);
366*d9f75844SAndroid Build Coastguard Worker }
367*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,PlayoutDelayPreservesDefaultMinValue)368*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
369*d9f75844SAndroid Build Coastguard Worker const TimeDelta default_min_playout_latency =
370*d9f75844SAndroid Build Coastguard Worker timing_->GetTimings().min_playout_delay;
371*d9f75844SAndroid Build Coastguard Worker const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
372*d9f75844SAndroid Build Coastguard Worker
373*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame =
374*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(0).AsLast().Build();
375*d9f75844SAndroid Build Coastguard Worker test_frame->SetPlayoutDelay(kPlayoutDelayMs);
376*d9f75844SAndroid Build Coastguard Worker
377*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame));
378*d9f75844SAndroid Build Coastguard Worker
379*d9f75844SAndroid Build Coastguard Worker // Ensure that -1 preserves default minimum value from `timing_`.
380*d9f75844SAndroid Build Coastguard Worker auto timings = timing_->GetTimings();
381*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
382*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
383*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(default_min_playout_latency, timings.min_playout_delay);
384*d9f75844SAndroid Build Coastguard Worker }
385*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,RenderParametersSetToDefaultValues)386*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, RenderParametersSetToDefaultValues) {
387*d9f75844SAndroid Build Coastguard Worker // Default render parameters.
388*d9f75844SAndroid Build Coastguard Worker const VideoFrame::RenderParameters kDefaultRenderParameters;
389*d9f75844SAndroid Build Coastguard Worker // Default with no playout delay set.
390*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame0 =
391*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(0).AsLast().Build();
392*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
393*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(timing_->RenderParameters(), kDefaultRenderParameters);
394*d9f75844SAndroid Build Coastguard Worker }
395*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,UseLowLatencyRenderingSetFromPlayoutDelay)396*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, UseLowLatencyRenderingSetFromPlayoutDelay) {
397*d9f75844SAndroid Build Coastguard Worker // use_low_latency_rendering set if playout delay set to min=0, max<=500 ms.
398*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame0 =
399*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(0).AsLast().Build();
400*d9f75844SAndroid Build Coastguard Worker test_frame0->SetPlayoutDelay({/*min_ms=*/0, /*max_ms=*/0});
401*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
402*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(timing_->RenderParameters().use_low_latency_rendering);
403*d9f75844SAndroid Build Coastguard Worker
404*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame1 =
405*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(1).AsLast().Build();
406*d9f75844SAndroid Build Coastguard Worker test_frame1->SetPlayoutDelay({/*min_ms=*/0, /*max_ms=*/500});
407*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
408*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(timing_->RenderParameters().use_low_latency_rendering);
409*d9f75844SAndroid Build Coastguard Worker }
410*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,MaxCompositionDelaySetFromMaxPlayoutDelay)411*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) {
412*d9f75844SAndroid Build Coastguard Worker // The max composition delay is dependent on the number of frames in the
413*d9f75844SAndroid Build Coastguard Worker // pre-decode queue. It's therefore important to advance the time as the test
414*d9f75844SAndroid Build Coastguard Worker // runs to get the correct expectations of max_composition_delay_in_frames.
415*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
416*d9f75844SAndroid Build Coastguard Worker // Max composition delay not set if no playout delay is set.
417*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame0 =
418*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
419*d9f75844SAndroid Build Coastguard Worker .Id(0)
420*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(0))
421*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(0))
422*d9f75844SAndroid Build Coastguard Worker .AsLast()
423*d9f75844SAndroid Build Coastguard Worker .Build();
424*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
425*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames,
426*d9f75844SAndroid Build Coastguard Worker Eq(absl::nullopt));
427*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(k30FpsDelay);
428*d9f75844SAndroid Build Coastguard Worker
429*d9f75844SAndroid Build Coastguard Worker // Max composition delay not set for playout delay 0,0.
430*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame1 =
431*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
432*d9f75844SAndroid Build Coastguard Worker .Id(1)
433*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(1))
434*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(1))
435*d9f75844SAndroid Build Coastguard Worker .AsLast()
436*d9f75844SAndroid Build Coastguard Worker .Build();
437*d9f75844SAndroid Build Coastguard Worker test_frame1->SetPlayoutDelay({0, 0});
438*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
439*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames,
440*d9f75844SAndroid Build Coastguard Worker Eq(absl::nullopt));
441*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(k30FpsDelay);
442*d9f75844SAndroid Build Coastguard Worker
443*d9f75844SAndroid Build Coastguard Worker // Max composition delay not set for playout delay X,Y, where X,Y>0.
444*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame2 =
445*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
446*d9f75844SAndroid Build Coastguard Worker .Id(2)
447*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(2))
448*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(2))
449*d9f75844SAndroid Build Coastguard Worker .AsLast()
450*d9f75844SAndroid Build Coastguard Worker .Build();
451*d9f75844SAndroid Build Coastguard Worker test_frame2->SetPlayoutDelay({10, 30});
452*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
453*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames,
454*d9f75844SAndroid Build Coastguard Worker Eq(absl::nullopt));
455*d9f75844SAndroid Build Coastguard Worker
456*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(k30FpsDelay);
457*d9f75844SAndroid Build Coastguard Worker
458*d9f75844SAndroid Build Coastguard Worker // Max composition delay set if playout delay X,Y, where X=0,Y>0.
459*d9f75844SAndroid Build Coastguard Worker const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
460*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame3 =
461*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
462*d9f75844SAndroid Build Coastguard Worker .Id(3)
463*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(3))
464*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(3))
465*d9f75844SAndroid Build Coastguard Worker .AsLast()
466*d9f75844SAndroid Build Coastguard Worker .Build();
467*d9f75844SAndroid Build Coastguard Worker test_frame3->SetPlayoutDelay({0, 50});
468*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame3));
469*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(timing_->RenderParameters().max_composition_delay_in_frames,
470*d9f75844SAndroid Build Coastguard Worker Optional(kExpectedMaxCompositionDelayInFrames));
471*d9f75844SAndroid Build Coastguard Worker }
472*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,LazyDecoderCreation)473*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, LazyDecoderCreation) {
474*d9f75844SAndroid Build Coastguard Worker constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
475*d9f75844SAndroid Build Coastguard Worker RtpPacketToSend rtppacket(nullptr);
476*d9f75844SAndroid Build Coastguard Worker uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
477*d9f75844SAndroid Build Coastguard Worker memcpy(payload, idr_nalu, sizeof(idr_nalu));
478*d9f75844SAndroid Build Coastguard Worker rtppacket.SetMarker(true);
479*d9f75844SAndroid Build Coastguard Worker rtppacket.SetSsrc(1111);
480*d9f75844SAndroid Build Coastguard Worker // H265 payload type.
481*d9f75844SAndroid Build Coastguard Worker rtppacket.SetPayloadType(99);
482*d9f75844SAndroid Build Coastguard Worker rtppacket.SetSequenceNumber(1);
483*d9f75844SAndroid Build Coastguard Worker rtppacket.SetTimestamp(0);
484*d9f75844SAndroid Build Coastguard Worker
485*d9f75844SAndroid Build Coastguard Worker // No decoders are created by default.
486*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
487*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
488*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(TimeDelta::Zero());
489*d9f75844SAndroid Build Coastguard Worker
490*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(
491*d9f75844SAndroid Build Coastguard Worker testing::Mock::VerifyAndClearExpectations(&mock_h264_decoder_factory_));
492*d9f75844SAndroid Build Coastguard Worker // Verify that the decoder is created when we receive payload data and tries
493*d9f75844SAndroid Build Coastguard Worker // to decode a frame.
494*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(
495*d9f75844SAndroid Build Coastguard Worker mock_h264_decoder_factory_,
496*d9f75844SAndroid Build Coastguard Worker CreateVideoDecoder(Field(&SdpVideoFormat::name, testing::Eq("H264"))));
497*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Configure);
498*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback);
499*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Decode);
500*d9f75844SAndroid Build Coastguard Worker RtpPacketReceived parsed_packet;
501*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
502*d9f75844SAndroid Build Coastguard Worker rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
503*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Release);
504*d9f75844SAndroid Build Coastguard Worker
505*d9f75844SAndroid Build Coastguard Worker // Make sure the decoder thread had a chance to run.
506*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(TimeDelta::Zero());
507*d9f75844SAndroid Build Coastguard Worker }
508*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,PassesNtpTime)509*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PassesNtpTime) {
510*d9f75844SAndroid Build Coastguard Worker const Timestamp kNtpTimestamp = Timestamp::Millis(12345);
511*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame =
512*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
513*d9f75844SAndroid Build Coastguard Worker .Id(0)
514*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
515*d9f75844SAndroid Build Coastguard Worker .NtpTime(kNtpTimestamp)
516*d9f75844SAndroid Build Coastguard Worker .AsLast()
517*d9f75844SAndroid Build Coastguard Worker .Build();
518*d9f75844SAndroid Build Coastguard Worker
519*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
520*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame));
521*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
522*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(NtpTimestamp(kNtpTimestamp)));
523*d9f75844SAndroid Build Coastguard Worker }
524*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,PassesRotation)525*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PassesRotation) {
526*d9f75844SAndroid Build Coastguard Worker const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
527*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> test_frame = test::FakeFrameBuilder()
528*d9f75844SAndroid Build Coastguard Worker .Id(0)
529*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
530*d9f75844SAndroid Build Coastguard Worker .Rotation(kRotation)
531*d9f75844SAndroid Build Coastguard Worker .AsLast()
532*d9f75844SAndroid Build Coastguard Worker .Build();
533*d9f75844SAndroid Build Coastguard Worker
534*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
535*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame));
536*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
537*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(Rotation(kRotation)));
538*d9f75844SAndroid Build Coastguard Worker }
539*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,PassesPacketInfos)540*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PassesPacketInfos) {
541*d9f75844SAndroid Build Coastguard Worker RtpPacketInfos packet_infos = CreatePacketInfos(3);
542*d9f75844SAndroid Build Coastguard Worker auto test_frame = test::FakeFrameBuilder()
543*d9f75844SAndroid Build Coastguard Worker .Id(0)
544*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
545*d9f75844SAndroid Build Coastguard Worker .PacketInfos(packet_infos)
546*d9f75844SAndroid Build Coastguard Worker .AsLast()
547*d9f75844SAndroid Build Coastguard Worker .Build();
548*d9f75844SAndroid Build Coastguard Worker
549*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
550*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame));
551*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
552*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos))));
553*d9f75844SAndroid Build Coastguard Worker }
554*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,RenderedFrameUpdatesGetSources)555*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, RenderedFrameUpdatesGetSources) {
556*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kSsrc = 1111;
557*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kCsrc = 9001;
558*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kRtpTimestamp = 12345;
559*d9f75844SAndroid Build Coastguard Worker
560*d9f75844SAndroid Build Coastguard Worker // Prepare one video frame with per-packet information.
561*d9f75844SAndroid Build Coastguard Worker auto test_frame =
562*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(0).PayloadType(99).AsLast().Build();
563*d9f75844SAndroid Build Coastguard Worker RtpPacketInfos packet_infos;
564*d9f75844SAndroid Build Coastguard Worker {
565*d9f75844SAndroid Build Coastguard Worker RtpPacketInfos::vector_type infos;
566*d9f75844SAndroid Build Coastguard Worker
567*d9f75844SAndroid Build Coastguard Worker RtpPacketInfo info;
568*d9f75844SAndroid Build Coastguard Worker info.set_ssrc(kSsrc);
569*d9f75844SAndroid Build Coastguard Worker info.set_csrcs({kCsrc});
570*d9f75844SAndroid Build Coastguard Worker info.set_rtp_timestamp(kRtpTimestamp);
571*d9f75844SAndroid Build Coastguard Worker
572*d9f75844SAndroid Build Coastguard Worker info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
573*d9f75844SAndroid Build Coastguard Worker infos.push_back(info);
574*d9f75844SAndroid Build Coastguard Worker
575*d9f75844SAndroid Build Coastguard Worker info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
576*d9f75844SAndroid Build Coastguard Worker infos.push_back(info);
577*d9f75844SAndroid Build Coastguard Worker
578*d9f75844SAndroid Build Coastguard Worker info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
579*d9f75844SAndroid Build Coastguard Worker infos.push_back(info);
580*d9f75844SAndroid Build Coastguard Worker
581*d9f75844SAndroid Build Coastguard Worker info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(1000));
582*d9f75844SAndroid Build Coastguard Worker infos.push_back(info);
583*d9f75844SAndroid Build Coastguard Worker
584*d9f75844SAndroid Build Coastguard Worker packet_infos = RtpPacketInfos(std::move(infos));
585*d9f75844SAndroid Build Coastguard Worker }
586*d9f75844SAndroid Build Coastguard Worker test_frame->SetPacketInfos(packet_infos);
587*d9f75844SAndroid Build Coastguard Worker
588*d9f75844SAndroid Build Coastguard Worker // Start receive stream.
589*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
590*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
591*d9f75844SAndroid Build Coastguard Worker
592*d9f75844SAndroid Build Coastguard Worker // Render one video frame.
593*d9f75844SAndroid Build Coastguard Worker int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
594*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(test_frame));
595*d9f75844SAndroid Build Coastguard Worker // Verify that the per-packet information is passed to the renderer.
596*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
597*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos))));
598*d9f75844SAndroid Build Coastguard Worker int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
599*d9f75844SAndroid Build Coastguard Worker
600*d9f75844SAndroid Build Coastguard Worker // Verify that the per-packet information also updates `GetSources()`.
601*d9f75844SAndroid Build Coastguard Worker std::vector<RtpSource> sources = video_receive_stream_->GetSources();
602*d9f75844SAndroid Build Coastguard Worker ASSERT_THAT(sources, SizeIs(2));
603*d9f75844SAndroid Build Coastguard Worker {
604*d9f75844SAndroid Build Coastguard Worker auto it = std::find_if(sources.begin(), sources.end(),
605*d9f75844SAndroid Build Coastguard Worker [](const RtpSource& source) {
606*d9f75844SAndroid Build Coastguard Worker return source.source_type() == RtpSourceType::SSRC;
607*d9f75844SAndroid Build Coastguard Worker });
608*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(it, sources.end());
609*d9f75844SAndroid Build Coastguard Worker
610*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(it->source_id(), kSsrc);
611*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
612*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
613*d9f75844SAndroid Build Coastguard Worker EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
614*d9f75844SAndroid Build Coastguard Worker EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
615*d9f75844SAndroid Build Coastguard Worker }
616*d9f75844SAndroid Build Coastguard Worker {
617*d9f75844SAndroid Build Coastguard Worker auto it = std::find_if(sources.begin(), sources.end(),
618*d9f75844SAndroid Build Coastguard Worker [](const RtpSource& source) {
619*d9f75844SAndroid Build Coastguard Worker return source.source_type() == RtpSourceType::CSRC;
620*d9f75844SAndroid Build Coastguard Worker });
621*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(it, sources.end());
622*d9f75844SAndroid Build Coastguard Worker
623*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(it->source_id(), kCsrc);
624*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
625*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
626*d9f75844SAndroid Build Coastguard Worker EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
627*d9f75844SAndroid Build Coastguard Worker EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
628*d9f75844SAndroid Build Coastguard Worker }
629*d9f75844SAndroid Build Coastguard Worker }
630*d9f75844SAndroid Build Coastguard Worker
MakeFrameWithResolution(VideoFrameType frame_type,int picture_id,int width,int height)631*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> MakeFrameWithResolution(
632*d9f75844SAndroid Build Coastguard Worker VideoFrameType frame_type,
633*d9f75844SAndroid Build Coastguard Worker int picture_id,
634*d9f75844SAndroid Build Coastguard Worker int width,
635*d9f75844SAndroid Build Coastguard Worker int height) {
636*d9f75844SAndroid Build Coastguard Worker auto frame =
637*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder().Id(picture_id).PayloadType(99).AsLast().Build();
638*d9f75844SAndroid Build Coastguard Worker frame->SetFrameType(frame_type);
639*d9f75844SAndroid Build Coastguard Worker frame->_encodedWidth = width;
640*d9f75844SAndroid Build Coastguard Worker frame->_encodedHeight = height;
641*d9f75844SAndroid Build Coastguard Worker return frame;
642*d9f75844SAndroid Build Coastguard Worker }
643*d9f75844SAndroid Build Coastguard Worker
MakeFrame(VideoFrameType frame_type,int picture_id)644*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<test::FakeEncodedFrame> MakeFrame(VideoFrameType frame_type,
645*d9f75844SAndroid Build Coastguard Worker int picture_id) {
646*d9f75844SAndroid Build Coastguard Worker return MakeFrameWithResolution(frame_type, picture_id, 320, 240);
647*d9f75844SAndroid Build Coastguard Worker }
648*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,PassesFrameWhenEncodedFramesCallbackSet)649*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PassesFrameWhenEncodedFramesCallbackSet) {
650*d9f75844SAndroid Build Coastguard Worker testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
651*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
652*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(callback, Call);
653*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetAndGetRecordingState(
654*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
655*d9f75844SAndroid Build Coastguard Worker true);
656*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
657*d9f75844SAndroid Build Coastguard Worker MakeFrame(VideoFrameType::kVideoFrameKey, 0));
658*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(fake_renderer_.WaitForFrame(kDefaultTimeOut));
659*d9f75844SAndroid Build Coastguard Worker
660*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(rtcp_packet_parser_.pli()->num_packets(), Eq(1));
661*d9f75844SAndroid Build Coastguard Worker
662*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
663*d9f75844SAndroid Build Coastguard Worker }
664*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,MovesEncodedFrameDispatchStateWhenReCreating)665*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, MovesEncodedFrameDispatchStateWhenReCreating) {
666*d9f75844SAndroid Build Coastguard Worker testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
667*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
668*d9f75844SAndroid Build Coastguard Worker // Expect a key frame request over RTCP.
669*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetAndGetRecordingState(
670*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
671*d9f75844SAndroid Build Coastguard Worker true);
672*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
673*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::RecordingState old_state =
674*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetAndGetRecordingState(
675*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::RecordingState(), false);
676*d9f75844SAndroid Build Coastguard Worker RecreateReceiveStream(std::move(old_state));
677*d9f75844SAndroid Build Coastguard Worker
678*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(rtcp_packet_parser_.pli()->num_packets(), Eq(1));
679*d9f75844SAndroid Build Coastguard Worker
680*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
681*d9f75844SAndroid Build Coastguard Worker }
682*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,RequestsKeyFramesUntilKeyFrameReceived)683*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, RequestsKeyFramesUntilKeyFrameReceived) {
684*d9f75844SAndroid Build Coastguard Worker // Recreate receive stream with shorter delay to test rtx.
685*d9f75844SAndroid Build Coastguard Worker TimeDelta rtx_delay = TimeDelta::Millis(50);
686*d9f75844SAndroid Build Coastguard Worker config_.rtp.nack.rtp_history_ms = rtx_delay.ms();
687*d9f75844SAndroid Build Coastguard Worker auto tick = rtx_delay / 2;
688*d9f75844SAndroid Build Coastguard Worker RecreateReceiveStream();
689*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
690*d9f75844SAndroid Build Coastguard Worker
691*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->GenerateKeyFrame();
692*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
693*d9f75844SAndroid Build Coastguard Worker MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
694*d9f75844SAndroid Build Coastguard Worker fake_renderer_.WaitForFrame(kDefaultTimeOut);
695*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(tick);
696*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
697*d9f75844SAndroid Build Coastguard Worker MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
698*d9f75844SAndroid Build Coastguard Worker fake_renderer_.WaitForFrame(kDefaultTimeOut);
699*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(TimeDelta::Zero());
700*d9f75844SAndroid Build Coastguard Worker testing::Mock::VerifyAndClearExpectations(&mock_transport_);
701*d9f75844SAndroid Build Coastguard Worker
702*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(rtcp_packet_parser_.pli()->num_packets(), Eq(1));
703*d9f75844SAndroid Build Coastguard Worker
704*d9f75844SAndroid Build Coastguard Worker // T+keyframetimeout: still no key frame received, expect key frame request
705*d9f75844SAndroid Build Coastguard Worker // sent again.
706*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(tick);
707*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
708*d9f75844SAndroid Build Coastguard Worker MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
709*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
710*d9f75844SAndroid Build Coastguard Worker testing::Mock::VerifyAndClearExpectations(&mock_transport_);
711*d9f75844SAndroid Build Coastguard Worker
712*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(rtcp_packet_parser_.pli()->num_packets(), Eq(2));
713*d9f75844SAndroid Build Coastguard Worker
714*d9f75844SAndroid Build Coastguard Worker // T+keyframetimeout: now send a key frame - we should not observe new key
715*d9f75844SAndroid Build Coastguard Worker // frame requests after this.
716*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
717*d9f75844SAndroid Build Coastguard Worker MakeFrame(VideoFrameType::kVideoFrameKey, 3));
718*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
719*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(2 * tick);
720*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
721*d9f75844SAndroid Build Coastguard Worker MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
722*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
723*d9f75844SAndroid Build Coastguard Worker
724*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(rtcp_packet_parser_.pli()->num_packets(), Eq(2));
725*d9f75844SAndroid Build Coastguard Worker }
726*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution)727*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test,
728*d9f75844SAndroid Build Coastguard Worker DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution) {
729*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
730*d9f75844SAndroid Build Coastguard Worker testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
731*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetAndGetRecordingState(
732*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
733*d9f75844SAndroid Build Coastguard Worker /*generate_key_frame=*/false);
734*d9f75844SAndroid Build Coastguard Worker
735*d9f75844SAndroid Build Coastguard Worker InSequence s;
736*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(callback,
737*d9f75844SAndroid Build Coastguard Worker Call(MatchResolution(test::FakeDecoder::kDefaultWidth,
738*d9f75844SAndroid Build Coastguard Worker test::FakeDecoder::kDefaultHeight)));
739*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(callback, Call);
740*d9f75844SAndroid Build Coastguard Worker
741*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
742*d9f75844SAndroid Build Coastguard Worker MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 0, 0));
743*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
744*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
745*d9f75844SAndroid Build Coastguard Worker MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
746*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
747*d9f75844SAndroid Build Coastguard Worker
748*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
749*d9f75844SAndroid Build Coastguard Worker }
750*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution)751*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test,
752*d9f75844SAndroid Build Coastguard Worker DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution) {
753*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
754*d9f75844SAndroid Build Coastguard Worker testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
755*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->SetAndGetRecordingState(
756*d9f75844SAndroid Build Coastguard Worker VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
757*d9f75844SAndroid Build Coastguard Worker /*generate_key_frame=*/false);
758*d9f75844SAndroid Build Coastguard Worker
759*d9f75844SAndroid Build Coastguard Worker InSequence s;
760*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(callback, Call(MatchResolution(1080u, 720u)));
761*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(callback, Call);
762*d9f75844SAndroid Build Coastguard Worker
763*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
764*d9f75844SAndroid Build Coastguard Worker MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 1080, 720));
765*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
766*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
767*d9f75844SAndroid Build Coastguard Worker MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
768*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
769*d9f75844SAndroid Build Coastguard Worker
770*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
771*d9f75844SAndroid Build Coastguard Worker }
772*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,DependantFramesAreScheduled)773*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, DependantFramesAreScheduled) {
774*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
775*d9f75844SAndroid Build Coastguard Worker
776*d9f75844SAndroid Build Coastguard Worker auto key_frame = test::FakeFrameBuilder()
777*d9f75844SAndroid Build Coastguard Worker .Id(0)
778*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
779*d9f75844SAndroid Build Coastguard Worker .Time(kFirstRtpTimestamp)
780*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(kStartTime)
781*d9f75844SAndroid Build Coastguard Worker .AsLast()
782*d9f75844SAndroid Build Coastguard Worker .Build();
783*d9f75844SAndroid Build Coastguard Worker auto delta_frame = test::FakeFrameBuilder()
784*d9f75844SAndroid Build Coastguard Worker .Id(1)
785*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
786*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(1))
787*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(1))
788*d9f75844SAndroid Build Coastguard Worker .Refs({0})
789*d9f75844SAndroid Build Coastguard Worker .AsLast()
790*d9f75844SAndroid Build Coastguard Worker .Build();
791*d9f75844SAndroid Build Coastguard Worker
792*d9f75844SAndroid Build Coastguard Worker // Expect frames are decoded in order.
793*d9f75844SAndroid Build Coastguard Worker InSequence seq;
794*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
795*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _));
796*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp +
797*d9f75844SAndroid Build Coastguard Worker k30FpsRtpTimestampDelta),
798*d9f75844SAndroid Build Coastguard Worker _, _))
799*d9f75844SAndroid Build Coastguard Worker .Times(1);
800*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(key_frame));
801*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
802*d9f75844SAndroid Build Coastguard Worker
803*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(k30FpsDelay);
804*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(delta_frame));
805*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
806*d9f75844SAndroid Build Coastguard Worker
807*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
808*d9f75844SAndroid Build Coastguard Worker }
809*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,FramesScheduledInOrder)810*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, FramesScheduledInOrder) {
811*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
812*d9f75844SAndroid Build Coastguard Worker
813*d9f75844SAndroid Build Coastguard Worker auto key_frame = test::FakeFrameBuilder()
814*d9f75844SAndroid Build Coastguard Worker .Id(0)
815*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
816*d9f75844SAndroid Build Coastguard Worker .Time(kFirstRtpTimestamp)
817*d9f75844SAndroid Build Coastguard Worker .AsLast()
818*d9f75844SAndroid Build Coastguard Worker .Build();
819*d9f75844SAndroid Build Coastguard Worker auto delta_frame1 = test::FakeFrameBuilder()
820*d9f75844SAndroid Build Coastguard Worker .Id(1)
821*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
822*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(1))
823*d9f75844SAndroid Build Coastguard Worker .Refs({0})
824*d9f75844SAndroid Build Coastguard Worker .AsLast()
825*d9f75844SAndroid Build Coastguard Worker .Build();
826*d9f75844SAndroid Build Coastguard Worker auto delta_frame2 = test::FakeFrameBuilder()
827*d9f75844SAndroid Build Coastguard Worker .Id(2)
828*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
829*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(2))
830*d9f75844SAndroid Build Coastguard Worker .Refs({1})
831*d9f75844SAndroid Build Coastguard Worker .AsLast()
832*d9f75844SAndroid Build Coastguard Worker .Build();
833*d9f75844SAndroid Build Coastguard Worker
834*d9f75844SAndroid Build Coastguard Worker // Expect frames are decoded in order despite delta_frame1 arriving first.
835*d9f75844SAndroid Build Coastguard Worker InSequence seq;
836*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
837*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
838*d9f75844SAndroid Build Coastguard Worker .Times(1);
839*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
840*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
841*d9f75844SAndroid Build Coastguard Worker .Times(1);
842*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
843*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
844*d9f75844SAndroid Build Coastguard Worker .Times(1);
845*d9f75844SAndroid Build Coastguard Worker key_frame->SetReceivedTime(clock_->CurrentTime().ms());
846*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(key_frame));
847*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
848*d9f75844SAndroid Build Coastguard Worker
849*d9f75844SAndroid Build Coastguard Worker delta_frame2->SetReceivedTime(clock_->CurrentTime().ms());
850*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(delta_frame2));
851*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), DidNotReceiveFrame());
852*d9f75844SAndroid Build Coastguard Worker // `delta_frame1` arrives late.
853*d9f75844SAndroid Build Coastguard Worker delta_frame1->SetReceivedTime(clock_->CurrentTime().ms());
854*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(delta_frame1));
855*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
856*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay * 2), RenderedFrame());
857*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
858*d9f75844SAndroid Build Coastguard Worker }
859*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,WaitsforAllSpatialLayers)860*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, WaitsforAllSpatialLayers) {
861*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
862*d9f75844SAndroid Build Coastguard Worker auto sl0 = test::FakeFrameBuilder()
863*d9f75844SAndroid Build Coastguard Worker .Id(0)
864*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
865*d9f75844SAndroid Build Coastguard Worker .Time(kFirstRtpTimestamp)
866*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(kStartTime)
867*d9f75844SAndroid Build Coastguard Worker .Build();
868*d9f75844SAndroid Build Coastguard Worker auto sl1 = test::FakeFrameBuilder()
869*d9f75844SAndroid Build Coastguard Worker .Id(1)
870*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
871*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(kStartTime)
872*d9f75844SAndroid Build Coastguard Worker .Time(kFirstRtpTimestamp)
873*d9f75844SAndroid Build Coastguard Worker .Refs({0})
874*d9f75844SAndroid Build Coastguard Worker .Build();
875*d9f75844SAndroid Build Coastguard Worker auto sl2 = test::FakeFrameBuilder()
876*d9f75844SAndroid Build Coastguard Worker .Id(2)
877*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
878*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(kStartTime)
879*d9f75844SAndroid Build Coastguard Worker .Time(kFirstRtpTimestamp)
880*d9f75844SAndroid Build Coastguard Worker .Refs({0, 1})
881*d9f75844SAndroid Build Coastguard Worker .AsLast()
882*d9f75844SAndroid Build Coastguard Worker .Build();
883*d9f75844SAndroid Build Coastguard Worker
884*d9f75844SAndroid Build Coastguard Worker // No decodes should be called until `sl2` is received.
885*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Decode).Times(0);
886*d9f75844SAndroid Build Coastguard Worker sl0->SetReceivedTime(clock_->CurrentTime().ms());
887*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(sl0));
888*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
889*d9f75844SAndroid Build Coastguard Worker DidNotReceiveFrame());
890*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(sl1));
891*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
892*d9f75844SAndroid Build Coastguard Worker DidNotReceiveFrame());
893*d9f75844SAndroid Build Coastguard Worker // When `sl2` arrives decode should happen.
894*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
895*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
896*d9f75844SAndroid Build Coastguard Worker .Times(1);
897*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(sl2));
898*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
899*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
900*d9f75844SAndroid Build Coastguard Worker }
901*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,FramesFastForwardOnSystemHalt)902*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, FramesFastForwardOnSystemHalt) {
903*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
904*d9f75844SAndroid Build Coastguard Worker
905*d9f75844SAndroid Build Coastguard Worker // The frame structure looks like this,
906*d9f75844SAndroid Build Coastguard Worker // F1
907*d9f75844SAndroid Build Coastguard Worker // /
908*d9f75844SAndroid Build Coastguard Worker // F0 --> F2
909*d9f75844SAndroid Build Coastguard Worker //
910*d9f75844SAndroid Build Coastguard Worker // In this case we will have a system halt simulated. By the time the system
911*d9f75844SAndroid Build Coastguard Worker // resumes, F1 will be old and so F2 should be decoded.
912*d9f75844SAndroid Build Coastguard Worker auto key_frame = test::FakeFrameBuilder()
913*d9f75844SAndroid Build Coastguard Worker .Id(0)
914*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
915*d9f75844SAndroid Build Coastguard Worker .Time(kFirstRtpTimestamp)
916*d9f75844SAndroid Build Coastguard Worker .AsLast()
917*d9f75844SAndroid Build Coastguard Worker .Build();
918*d9f75844SAndroid Build Coastguard Worker auto ffwd_frame = test::FakeFrameBuilder()
919*d9f75844SAndroid Build Coastguard Worker .Id(1)
920*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
921*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(1))
922*d9f75844SAndroid Build Coastguard Worker .Refs({0})
923*d9f75844SAndroid Build Coastguard Worker .AsLast()
924*d9f75844SAndroid Build Coastguard Worker .Build();
925*d9f75844SAndroid Build Coastguard Worker auto rendered_frame = test::FakeFrameBuilder()
926*d9f75844SAndroid Build Coastguard Worker .Id(2)
927*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
928*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(2))
929*d9f75844SAndroid Build Coastguard Worker .Refs({0})
930*d9f75844SAndroid Build Coastguard Worker .AsLast()
931*d9f75844SAndroid Build Coastguard Worker .Build();
932*d9f75844SAndroid Build Coastguard Worker InSequence seq;
933*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
934*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
935*d9f75844SAndroid Build Coastguard Worker .WillOnce(testing::DoAll(Invoke([&] {
936*d9f75844SAndroid Build Coastguard Worker // System halt will be simulated in the decode.
937*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(k30FpsDelay * 2);
938*d9f75844SAndroid Build Coastguard Worker }),
939*d9f75844SAndroid Build Coastguard Worker DefaultDecodeAction()));
940*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
941*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _));
942*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(key_frame));
943*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(ffwd_frame));
944*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(rendered_frame));
945*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
946*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(0))));
947*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
948*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(2))));
949*d9f75844SAndroid Build Coastguard Worker
950*d9f75844SAndroid Build Coastguard Worker // Check stats show correct dropped frames.
951*d9f75844SAndroid Build Coastguard Worker auto stats = video_receive_stream_->GetStats();
952*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(stats.frames_dropped, 1u);
953*d9f75844SAndroid Build Coastguard Worker
954*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
955*d9f75844SAndroid Build Coastguard Worker }
956*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,BetterFrameInsertedWhileWaitingToDecodeFrame)957*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, BetterFrameInsertedWhileWaitingToDecodeFrame) {
958*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
959*d9f75844SAndroid Build Coastguard Worker
960*d9f75844SAndroid Build Coastguard Worker auto key_frame = test::FakeFrameBuilder()
961*d9f75844SAndroid Build Coastguard Worker .Id(0)
962*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
963*d9f75844SAndroid Build Coastguard Worker .Time(kFirstRtpTimestamp)
964*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(0))
965*d9f75844SAndroid Build Coastguard Worker .AsLast()
966*d9f75844SAndroid Build Coastguard Worker .Build();
967*d9f75844SAndroid Build Coastguard Worker auto f1 = test::FakeFrameBuilder()
968*d9f75844SAndroid Build Coastguard Worker .Id(1)
969*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
970*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(1))
971*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(1))
972*d9f75844SAndroid Build Coastguard Worker .Refs({0})
973*d9f75844SAndroid Build Coastguard Worker .AsLast()
974*d9f75844SAndroid Build Coastguard Worker .Build();
975*d9f75844SAndroid Build Coastguard Worker auto f2 = test::FakeFrameBuilder()
976*d9f75844SAndroid Build Coastguard Worker .Id(2)
977*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
978*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(2))
979*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(2))
980*d9f75844SAndroid Build Coastguard Worker .Refs({0})
981*d9f75844SAndroid Build Coastguard Worker .AsLast()
982*d9f75844SAndroid Build Coastguard Worker .Build();
983*d9f75844SAndroid Build Coastguard Worker
984*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(key_frame));
985*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
986*d9f75844SAndroid Build Coastguard Worker
987*d9f75844SAndroid Build Coastguard Worker InSequence seq;
988*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
989*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
990*d9f75844SAndroid Build Coastguard Worker .Times(1);
991*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_,
992*d9f75844SAndroid Build Coastguard Worker Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
993*d9f75844SAndroid Build Coastguard Worker .Times(1);
994*d9f75844SAndroid Build Coastguard Worker // Simulate f1 arriving after f2 but before f2 is decoded.
995*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(f2));
996*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), DidNotReceiveFrame());
997*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(std::move(f1));
998*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
999*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
1000*d9f75844SAndroid Build Coastguard Worker
1001*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
1002*d9f75844SAndroid Build Coastguard Worker }
1003*d9f75844SAndroid Build Coastguard Worker
1004*d9f75844SAndroid Build Coastguard Worker // Note: This test takes a long time (~10s) to run if the fake metronome is
1005*d9f75844SAndroid Build Coastguard Worker // active. Since the test needs to wait for the timestamp to rollover, it has a
1006*d9f75844SAndroid Build Coastguard Worker // fake delay of around 6.5 hours. Even though time is simulated, this will be
1007*d9f75844SAndroid Build Coastguard Worker // around 1,500,000 metronome tick invocations.
TEST_P(VideoReceiveStream2Test,RtpTimestampWrapAround)1008*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, RtpTimestampWrapAround) {
1009*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_transport_, SendRtcp).Times(AnyNumber());
1010*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
1011*d9f75844SAndroid Build Coastguard Worker
1012*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kBaseRtp = std::numeric_limits<uint32_t>::max() / 2;
1013*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1014*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1015*d9f75844SAndroid Build Coastguard Worker .Id(0)
1016*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1017*d9f75844SAndroid Build Coastguard Worker .Time(kBaseRtp)
1018*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(clock_->CurrentTime())
1019*d9f75844SAndroid Build Coastguard Worker .AsLast()
1020*d9f75844SAndroid Build Coastguard Worker .Build());
1021*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
1022*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(k30FpsDelay);
1023*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1024*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1025*d9f75844SAndroid Build Coastguard Worker .Id(1)
1026*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1027*d9f75844SAndroid Build Coastguard Worker .Time(kBaseRtp + k30FpsRtpTimestampDelta)
1028*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(clock_->CurrentTime())
1029*d9f75844SAndroid Build Coastguard Worker .AsLast()
1030*d9f75844SAndroid Build Coastguard Worker .Build());
1031*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
1032*d9f75844SAndroid Build Coastguard Worker
1033*d9f75844SAndroid Build Coastguard Worker // Pause stream so that RTP timestamp wraps around.
1034*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kLastRtp = kBaseRtp + k30FpsRtpTimestampDelta;
1035*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t kWrapAroundRtp =
1036*d9f75844SAndroid Build Coastguard Worker kLastRtp + std::numeric_limits<uint32_t>::max() / 2 + 1;
1037*d9f75844SAndroid Build Coastguard Worker // Pause for corresponding delay such that RTP timestamp would increase this
1038*d9f75844SAndroid Build Coastguard Worker // much at 30fps.
1039*d9f75844SAndroid Build Coastguard Worker constexpr TimeDelta kWrapAroundDelay =
1040*d9f75844SAndroid Build Coastguard Worker (std::numeric_limits<uint32_t>::max() / 2 + 1) / kRtpTimestampHz;
1041*d9f75844SAndroid Build Coastguard Worker
1042*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(kWrapAroundDelay);
1043*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1044*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1045*d9f75844SAndroid Build Coastguard Worker .Id(2)
1046*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1047*d9f75844SAndroid Build Coastguard Worker .Time(kWrapAroundRtp)
1048*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(clock_->CurrentTime())
1049*d9f75844SAndroid Build Coastguard Worker .AsLast()
1050*d9f75844SAndroid Build Coastguard Worker .Build());
1051*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kWrapAroundRtp), _, _))
1052*d9f75844SAndroid Build Coastguard Worker .Times(1);
1053*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
1054*d9f75844SAndroid Build Coastguard Worker
1055*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
1056*d9f75844SAndroid Build Coastguard Worker }
1057*d9f75844SAndroid Build Coastguard Worker
1058*d9f75844SAndroid Build Coastguard Worker // If a frame was lost causing the stream to become temporarily non-decodable
1059*d9f75844SAndroid Build Coastguard Worker // and the sender reduces their framerate during this time, the video stream
1060*d9f75844SAndroid Build Coastguard Worker // should start decoding at the new framerate. However, if the connection is
1061*d9f75844SAndroid Build Coastguard Worker // poor, a keyframe will take a long time to send. If the timing of the incoming
1062*d9f75844SAndroid Build Coastguard Worker // frames was not kept up to date with the new framerate while the stream was
1063*d9f75844SAndroid Build Coastguard Worker // decodable, this late frame will have a large delay as the rtp timestamp of
1064*d9f75844SAndroid Build Coastguard Worker // this keyframe will look like the frame arrived early if the frame-rate was
1065*d9f75844SAndroid Build Coastguard Worker // not updated.
TEST_P(VideoReceiveStream2Test,PoorConnectionWithFpsChangeDuringLostFrame)1066*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, PoorConnectionWithFpsChangeDuringLostFrame) {
1067*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
1068*d9f75844SAndroid Build Coastguard Worker
1069*d9f75844SAndroid Build Coastguard Worker constexpr Frequency k15Fps = Frequency::Hertz(15);
1070*d9f75844SAndroid Build Coastguard Worker constexpr TimeDelta k15FpsDelay = 1 / k15Fps;
1071*d9f75844SAndroid Build Coastguard Worker constexpr uint32_t k15FpsRtpTimestampDelta = kRtpTimestampHz / k15Fps;
1072*d9f75844SAndroid Build Coastguard Worker
1073*d9f75844SAndroid Build Coastguard Worker // Initial keyframe and frames at 30fps.
1074*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1075*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1076*d9f75844SAndroid Build Coastguard Worker .Id(0)
1077*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1078*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(0))
1079*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(0))
1080*d9f75844SAndroid Build Coastguard Worker .AsLast()
1081*d9f75844SAndroid Build Coastguard Worker .Build());
1082*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay, /*advance_time=*/true),
1083*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(0))));
1084*d9f75844SAndroid Build Coastguard Worker
1085*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1086*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1087*d9f75844SAndroid Build Coastguard Worker .Id(1)
1088*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1089*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(1))
1090*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(1))
1091*d9f75844SAndroid Build Coastguard Worker .Refs({0})
1092*d9f75844SAndroid Build Coastguard Worker .AsLast()
1093*d9f75844SAndroid Build Coastguard Worker .Build());
1094*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay, /*advance_time=*/true),
1095*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(1))));
1096*d9f75844SAndroid Build Coastguard Worker
1097*d9f75844SAndroid Build Coastguard Worker // Simulate lost frame 2, followed by 2 second of frames at 30fps, followed by
1098*d9f75844SAndroid Build Coastguard Worker // 2 second of frames at 15 fps, and then a keyframe.
1099*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(k30FpsDelay);
1100*d9f75844SAndroid Build Coastguard Worker
1101*d9f75844SAndroid Build Coastguard Worker Timestamp send_30fps_end_time = clock_->CurrentTime() + TimeDelta::Seconds(2);
1102*d9f75844SAndroid Build Coastguard Worker int id = 3;
1103*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_transport_, SendRtcp).Times(AnyNumber());
1104*d9f75844SAndroid Build Coastguard Worker while (clock_->CurrentTime() < send_30fps_end_time) {
1105*d9f75844SAndroid Build Coastguard Worker ++id;
1106*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1107*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1108*d9f75844SAndroid Build Coastguard Worker .Id(id)
1109*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1110*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(id))
1111*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(id))
1112*d9f75844SAndroid Build Coastguard Worker .Refs({id - 1})
1113*d9f75844SAndroid Build Coastguard Worker .AsLast()
1114*d9f75844SAndroid Build Coastguard Worker .Build());
1115*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay, /*advance_time=*/true),
1116*d9f75844SAndroid Build Coastguard Worker Eq(absl::nullopt));
1117*d9f75844SAndroid Build Coastguard Worker }
1118*d9f75844SAndroid Build Coastguard Worker uint32_t current_rtp = RtpTimestampForFrame(id);
1119*d9f75844SAndroid Build Coastguard Worker Timestamp send_15fps_end_time = clock_->CurrentTime() + TimeDelta::Seconds(2);
1120*d9f75844SAndroid Build Coastguard Worker while (clock_->CurrentTime() < send_15fps_end_time) {
1121*d9f75844SAndroid Build Coastguard Worker ++id;
1122*d9f75844SAndroid Build Coastguard Worker current_rtp += k15FpsRtpTimestampDelta;
1123*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1124*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1125*d9f75844SAndroid Build Coastguard Worker .Id(id)
1126*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1127*d9f75844SAndroid Build Coastguard Worker .Time(current_rtp)
1128*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(clock_->CurrentTime())
1129*d9f75844SAndroid Build Coastguard Worker .Refs({id - 1})
1130*d9f75844SAndroid Build Coastguard Worker .AsLast()
1131*d9f75844SAndroid Build Coastguard Worker .Build());
1132*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k15FpsDelay, /*advance_time=*/true),
1133*d9f75844SAndroid Build Coastguard Worker Eq(absl::nullopt));
1134*d9f75844SAndroid Build Coastguard Worker }
1135*d9f75844SAndroid Build Coastguard Worker
1136*d9f75844SAndroid Build Coastguard Worker ++id;
1137*d9f75844SAndroid Build Coastguard Worker current_rtp += k15FpsRtpTimestampDelta;
1138*d9f75844SAndroid Build Coastguard Worker // Insert keyframe which will recover the stream. However, on a poor
1139*d9f75844SAndroid Build Coastguard Worker // connection the keyframe will take significant time to send.
1140*d9f75844SAndroid Build Coastguard Worker constexpr TimeDelta kKeyframeDelay = TimeDelta::Millis(200);
1141*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1142*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1143*d9f75844SAndroid Build Coastguard Worker .Id(id)
1144*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1145*d9f75844SAndroid Build Coastguard Worker .Time(current_rtp)
1146*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(clock_->CurrentTime() + kKeyframeDelay)
1147*d9f75844SAndroid Build Coastguard Worker .AsLast()
1148*d9f75844SAndroid Build Coastguard Worker .Build());
1149*d9f75844SAndroid Build Coastguard Worker // If the framerate was not updated to be 15fps from the frames that arrived
1150*d9f75844SAndroid Build Coastguard Worker // previously, this will fail, as the delay will be longer.
1151*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k15FpsDelay, /*advance_time=*/true),
1152*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(current_rtp)));
1153*d9f75844SAndroid Build Coastguard Worker
1154*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
1155*d9f75844SAndroid Build Coastguard Worker }
1156*d9f75844SAndroid Build Coastguard Worker
TEST_P(VideoReceiveStream2Test,StreamShouldNotTimeoutWhileWaitingForFrame)1157*d9f75844SAndroid Build Coastguard Worker TEST_P(VideoReceiveStream2Test, StreamShouldNotTimeoutWhileWaitingForFrame) {
1158*d9f75844SAndroid Build Coastguard Worker // Disable smoothing since this makes it hard to test frame timing.
1159*d9f75844SAndroid Build Coastguard Worker config_.enable_prerenderer_smoothing = false;
1160*d9f75844SAndroid Build Coastguard Worker RecreateReceiveStream();
1161*d9f75844SAndroid Build Coastguard Worker
1162*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Start();
1163*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(mock_transport_, SendRtcp).Times(AnyNumber());
1164*d9f75844SAndroid Build Coastguard Worker
1165*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1166*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1167*d9f75844SAndroid Build Coastguard Worker .Id(0)
1168*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1169*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(0))
1170*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(0))
1171*d9f75844SAndroid Build Coastguard Worker .AsLast()
1172*d9f75844SAndroid Build Coastguard Worker .Build());
1173*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay, /*advance_time=*/true),
1174*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(0))));
1175*d9f75844SAndroid Build Coastguard Worker
1176*d9f75844SAndroid Build Coastguard Worker for (int id = 1; id < 30; ++id) {
1177*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1178*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1179*d9f75844SAndroid Build Coastguard Worker .Id(id)
1180*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1181*d9f75844SAndroid Build Coastguard Worker .Time(RtpTimestampForFrame(id))
1182*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(ReceiveTimeForFrame(id))
1183*d9f75844SAndroid Build Coastguard Worker .Refs({0})
1184*d9f75844SAndroid Build Coastguard Worker .AsLast()
1185*d9f75844SAndroid Build Coastguard Worker .Build());
1186*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay, /*advance_time=*/true),
1187*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(RtpTimestampForFrame(id))));
1188*d9f75844SAndroid Build Coastguard Worker }
1189*d9f75844SAndroid Build Coastguard Worker
1190*d9f75844SAndroid Build Coastguard Worker // Simulate a pause in the stream, followed by a decodable frame that is ready
1191*d9f75844SAndroid Build Coastguard Worker // long in the future. The stream should not timeout in this case, but rather
1192*d9f75844SAndroid Build Coastguard Worker // decode the frame just before the timeout.
1193*d9f75844SAndroid Build Coastguard Worker time_controller_.AdvanceTime(TimeDelta::Millis(2900));
1194*d9f75844SAndroid Build Coastguard Worker uint32_t late_decode_rtp = kFirstRtpTimestamp + 200 * k30FpsRtpTimestampDelta;
1195*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->OnCompleteFrame(
1196*d9f75844SAndroid Build Coastguard Worker test::FakeFrameBuilder()
1197*d9f75844SAndroid Build Coastguard Worker .Id(121)
1198*d9f75844SAndroid Build Coastguard Worker .PayloadType(99)
1199*d9f75844SAndroid Build Coastguard Worker .Time(late_decode_rtp)
1200*d9f75844SAndroid Build Coastguard Worker .ReceivedTime(clock_->CurrentTime())
1201*d9f75844SAndroid Build Coastguard Worker .AsLast()
1202*d9f75844SAndroid Build Coastguard Worker .Build());
1203*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Millis(100),
1204*d9f75844SAndroid Build Coastguard Worker /*advance_time=*/true),
1205*d9f75844SAndroid Build Coastguard Worker RenderedFrameWith(RtpTimestamp(late_decode_rtp)));
1206*d9f75844SAndroid Build Coastguard Worker
1207*d9f75844SAndroid Build Coastguard Worker video_receive_stream_->Stop();
1208*d9f75844SAndroid Build Coastguard Worker }
1209*d9f75844SAndroid Build Coastguard Worker
1210*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(VideoReceiveStream2Test,
1211*d9f75844SAndroid Build Coastguard Worker VideoReceiveStream2Test,
1212*d9f75844SAndroid Build Coastguard Worker testing::Bool(),
__anon4a717d8c0602(const auto& test_param_info) 1213*d9f75844SAndroid Build Coastguard Worker [](const auto& test_param_info) {
1214*d9f75844SAndroid Build Coastguard Worker return (test_param_info.param
1215*d9f75844SAndroid Build Coastguard Worker ? "ScheduleDecodesWithMetronome"
1216*d9f75844SAndroid Build Coastguard Worker : "ScheduleDecodesWithPostTask");
1217*d9f75844SAndroid Build Coastguard Worker });
1218*d9f75844SAndroid Build Coastguard Worker
1219*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
1220