blob: a9e7e8a6cea7145c02c2f0d82e27c36d76ccef1c [file] [log] [blame]
Tommiae4d0972020-05-18 08:45:38 +02001/*
2 * Copyright 2017 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "video/video_receive_stream2.h"
12
13#include <algorithm>
Evan Shrubsolea4062722022-05-02 17:46:07 +020014#include <cstddef>
Markus Handell588f9b32021-04-08 19:19:50 +020015#include <limits>
Tommiae4d0972020-05-18 08:45:38 +020016#include <memory>
Evan Shrubsole1c184772022-04-26 09:47:49 +020017#include <ostream>
Evan Shrubsole9a999052021-12-12 15:27:00 +010018#include <tuple>
Tommiae4d0972020-05-18 08:45:38 +020019#include <utility>
20#include <vector>
21
Evan Shrubsole6dbc1722022-03-22 12:20:11 +010022#include "absl/memory/memory.h"
Evan Shrubsole44be5792022-04-26 16:24:41 +020023#include "absl/types/optional.h"
Evan Shrubsolea4062722022-05-02 17:46:07 +020024#include "api/metronome/test/fake_metronome.h"
Tommiae4d0972020-05-18 08:45:38 +020025#include "api/task_queue/default_task_queue_factory.h"
Danil Chapovalov9cd4d492021-08-03 14:59:00 +020026#include "api/test/mock_video_decoder.h"
27#include "api/test/mock_video_decoder_factory.h"
Evan Shrubsole44be5792022-04-26 16:24:41 +020028#include "api/test/time_controller.h"
Tommiae4d0972020-05-18 08:45:38 +020029#include "api/test/video/function_video_decoder_factory.h"
Evan Shrubsolea4062722022-05-02 17:46:07 +020030#include "api/units/frequency.h"
Evan Shrubsole44be5792022-04-26 16:24:41 +020031#include "api/units/time_delta.h"
Evan Shrubsolea4062722022-05-02 17:46:07 +020032#include "api/video/encoded_image.h"
Evan Shrubsole44be5792022-04-26 16:24:41 +020033#include "api/video/recordable_encoded_frame.h"
34#include "api/video/test/video_frame_matchers.h"
Markus Handell588f9b32021-04-08 19:19:50 +020035#include "api/video/video_frame.h"
Evan Shrubsole1c184772022-04-26 09:47:49 +020036#include "api/video_codecs/sdp_video_format.h"
Tommiae4d0972020-05-18 08:45:38 +020037#include "api/video_codecs/video_decoder.h"
38#include "call/rtp_stream_receiver_controller.h"
Evan Shrubsole1c184772022-04-26 09:47:49 +020039#include "call/video_receive_stream.h"
Tommiae4d0972020-05-18 08:45:38 +020040#include "common_video/test/utilities.h"
41#include "media/base/fake_video_renderer.h"
Tommi90738dd2021-05-31 17:36:47 +020042#include "media/engine/fake_webrtc_call.h"
Tommiae4d0972020-05-18 08:45:38 +020043#include "modules/pacing/packet_router.h"
44#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Tommiae4d0972020-05-18 08:45:38 +020045#include "modules/video_coding/encoded_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020046#include "rtc_base/event.h"
Evan Shrubsolea4062722022-05-02 17:46:07 +020047#include "rtc_base/strings/string_builder.h"
Tommiae4d0972020-05-18 08:45:38 +020048#include "system_wrappers/include/clock.h"
49#include "test/fake_decoder.h"
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +020050#include "test/fake_encoded_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020051#include "test/gmock.h"
52#include "test/gtest.h"
Danil Chapovalov9cd4d492021-08-03 14:59:00 +020053#include "test/mock_transport.h"
Tommiae4d0972020-05-18 08:45:38 +020054#include "test/run_loop.h"
Jonas Oreland8ca06132022-03-14 12:52:48 +010055#include "test/scoped_key_value_config.h"
Tommiae4d0972020-05-18 08:45:38 +020056#include "test/time_controller/simulated_time_controller.h"
57#include "test/video_decoder_proxy_factory.h"
58#include "video/call_stats2.h"
59
60namespace webrtc {
Evan Shrubsole1c184772022-04-26 09:47:49 +020061
62// Printing SdpVideoFormat for gmock argument matchers.
63void PrintTo(const SdpVideoFormat& value, std::ostream* os) {
64 *os << value.ToString();
65}
66
Evan Shrubsole44be5792022-04-26 16:24:41 +020067void PrintTo(const RecordableEncodedFrame::EncodedResolution& value,
68 std::ostream* os) {
69 *os << value.width << "x" << value.height;
70}
71
72void PrintTo(const RecordableEncodedFrame& value, std::ostream* os) {
73 *os << "RecordableEncodedFrame(render_time=" << value.render_time()
74 << " resolution=" << ::testing::PrintToString(value.resolution()) << ")";
75}
76
Evan Shrubsolea4062722022-05-02 17:46:07 +020077} // namespace webrtc
78
79namespace webrtc {
80
Tommiae4d0972020-05-18 08:45:38 +020081namespace {
82
Evan Shrubsole44be5792022-04-26 16:24:41 +020083using test::video_frame_matchers::NtpTimestamp;
84using test::video_frame_matchers::PacketInfos;
85using test::video_frame_matchers::Rotation;
Tommiae4d0972020-05-18 08:45:38 +020086using ::testing::_;
Markus Handell588f9b32021-04-08 19:19:50 +020087using ::testing::AllOf;
Tommiae4d0972020-05-18 08:45:38 +020088using ::testing::ElementsAreArray;
Evan Shrubsole44be5792022-04-26 16:24:41 +020089using ::testing::Eq;
Markus Handell588f9b32021-04-08 19:19:50 +020090using ::testing::Field;
91using ::testing::InSequence;
Tommiae4d0972020-05-18 08:45:38 +020092using ::testing::Invoke;
93using ::testing::IsEmpty;
Evan Shrubsolea4062722022-05-02 17:46:07 +020094using ::testing::Pointee;
Markus Handell588f9b32021-04-08 19:19:50 +020095using ::testing::Property;
Evan Shrubsole44be5792022-04-26 16:24:41 +020096using ::testing::Return;
Tommiae4d0972020-05-18 08:45:38 +020097using ::testing::SizeIs;
Danil Chapovalovd08930d2021-08-12 13:26:55 +020098using ::testing::WithoutArgs;
Tommiae4d0972020-05-18 08:45:38 +020099
Evan Shrubsole44be5792022-04-26 16:24:41 +0200100auto RenderedFrameWith(::testing::Matcher<VideoFrame> m) {
101 return Optional(m);
102}
Evan Shrubsolea4062722022-05-02 17:46:07 +0200103auto RenderedFrame() {
104 return RenderedFrameWith(_);
105}
106testing::Matcher<absl::optional<VideoFrame>> DidNotReceiveFrame() {
107 return Eq(absl::nullopt);
108}
Evan Shrubsole44be5792022-04-26 16:24:41 +0200109
110constexpr TimeDelta kDefaultTimeOut = TimeDelta::Millis(50);
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200111constexpr int kDefaultNumCpuCores = 2;
Tommiae4d0972020-05-18 08:45:38 +0200112
Evan Shrubsole44be5792022-04-26 16:24:41 +0200113constexpr Timestamp kStartTime = Timestamp::Millis(1'337'000);
Evan Shrubsolea4062722022-05-02 17:46:07 +0200114constexpr Frequency k30Fps = Frequency::Hertz(30);
115constexpr TimeDelta k30FpsDelay = 1 / k30Fps;
116constexpr Frequency kRtpTimestampHz = Frequency::KiloHertz(90);
117constexpr uint32_t k30FpsRtpTimestampDelta = kRtpTimestampHz / k30Fps;
118constexpr uint32_t kFirstRtpTimestamp = 90000;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200119
120class FakeVideoRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
121 public:
Evan Shrubsolea4062722022-05-02 17:46:07 +0200122 explicit FakeVideoRenderer(TimeController* time_controller,
123 test::RunLoop* loop)
124 : time_controller_(time_controller), loop_(loop) {}
Evan Shrubsole44be5792022-04-26 16:24:41 +0200125 ~FakeVideoRenderer() override = default;
126
127 void OnFrame(const webrtc::VideoFrame& frame) override {
128 last_frame_ = frame;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200129 }
130
Evan Shrubsolea4062722022-05-02 17:46:07 +0200131 absl::optional<webrtc::VideoFrame> WaitForFrame(TimeDelta timeout) {
Evan Shrubsole44be5792022-04-26 16:24:41 +0200132 if (!last_frame_) {
133 loop_->Flush();
Evan Shrubsolea4062722022-05-02 17:46:07 +0200134 time_controller_->AdvanceTime(TimeDelta::Zero());
135 time_controller_->Wait(
136 [this] {
137 loop_->Flush();
138 return last_frame_.has_value();
139 },
140 timeout);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200141 }
142 absl::optional<webrtc::VideoFrame> ret = std::move(last_frame_);
143 last_frame_.reset();
144 return ret;
145 }
146
147 private:
148 absl::optional<webrtc::VideoFrame> last_frame_;
Evan Shrubsolea4062722022-05-02 17:46:07 +0200149 TimeController* const time_controller_;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200150 test::RunLoop* const loop_;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200151};
152
153MATCHER_P2(Resolution, w, h, "") {
154 return arg.resolution().width == w && arg.resolution().height == h;
155}
156
Evan Shrubsolea4062722022-05-02 17:46:07 +0200157MATCHER_P(Id, id, "") {
158 return arg.id() == id;
159}
160
161// Rtp timestamp for in order frame at 30fps.
162uint32_t RtpTimestampForFrame(int id) {
163 return kFirstRtpTimestamp + id * k30FpsRtpTimestampDelta;
164}
165
166// Receive time for in order frame at 30fps.
167Timestamp ReceiveTimeForFrame(int id) {
168 return kStartTime + id * k30FpsDelay;
169}
170
Tommiae4d0972020-05-18 08:45:38 +0200171} // namespace
172
Evan Shrubsolea4062722022-05-02 17:46:07 +0200173class VideoReceiveStream2Test : public ::testing::TestWithParam<bool> {
Tommiae4d0972020-05-18 08:45:38 +0200174 public:
Evan Shrubsolea4062722022-05-02 17:46:07 +0200175 auto DefaultDecodeAction() {
176 return testing::Invoke(&fake_decoder_, &test::FakeDecoder::Decode);
177 }
178
179 bool UseMetronome() const { return GetParam(); }
180
Tommiae4d0972020-05-18 08:45:38 +0200181 VideoReceiveStream2Test()
Evan Shrubsole44be5792022-04-26 16:24:41 +0200182 : time_controller_(kStartTime),
183 clock_(time_controller_.GetClock()),
Evan Shrubsole1c184772022-04-26 09:47:49 +0200184 config_(&mock_transport_, &mock_h264_decoder_factory_),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200185 call_stats_(clock_, loop_.task_queue()),
Evan Shrubsolea4062722022-05-02 17:46:07 +0200186 fake_renderer_(&time_controller_, &loop_),
187 fake_metronome_(time_controller_.GetTaskQueueFactory(),
188 TimeDelta::Millis(16)),
189 decode_sync_(clock_, &fake_metronome_, loop_.task_queue()),
190 h264_decoder_factory_(&mock_decoder_) {
191 if (UseMetronome()) {
192 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:SyncDecoding/");
193 } else {
194 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/");
195 }
Evan Shrubsole1c184772022-04-26 09:47:49 +0200196
197 // By default, mock decoder factory is backed by VideoDecoderProxyFactory.
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200198 ON_CALL(mock_h264_decoder_factory_, CreateVideoDecoder)
Evan Shrubsole1c184772022-04-26 09:47:49 +0200199 .WillByDefault(testing::Invoke(
200 &h264_decoder_factory_,
201 &test::VideoDecoderProxyFactory::CreateVideoDecoder));
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200202
203 // By default, mock decode will wrap the fake decoder.
Evan Shrubsolea4062722022-05-02 17:46:07 +0200204 ON_CALL(mock_decoder_, Configure)
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200205 .WillByDefault(
206 testing::Invoke(&fake_decoder_, &test::FakeDecoder::Configure));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200207 ON_CALL(mock_decoder_, Decode).WillByDefault(DefaultDecodeAction());
208 ON_CALL(mock_decoder_, RegisterDecodeCompleteCallback)
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200209 .WillByDefault(testing::Invoke(
210 &fake_decoder_,
211 &test::FakeDecoder::RegisterDecodeCompleteCallback));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200212 ON_CALL(mock_decoder_, Release)
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200213 .WillByDefault(
214 testing::Invoke(&fake_decoder_, &test::FakeDecoder::Release));
Jonas Oreland8ca06132022-03-14 12:52:48 +0100215 }
Tommi90738dd2021-05-31 17:36:47 +0200216 ~VideoReceiveStream2Test() override {
Evan Shrubsolea4062722022-05-02 17:46:07 +0200217 if (video_receive_stream_) {
218 video_receive_stream_->Stop();
Tommi90738dd2021-05-31 17:36:47 +0200219 video_receive_stream_->UnregisterFromTransport();
Evan Shrubsolea4062722022-05-02 17:46:07 +0200220 }
221 fake_metronome_.Stop();
222 time_controller_.AdvanceTime(TimeDelta::Zero());
Tommi90738dd2021-05-31 17:36:47 +0200223 }
Tommiae4d0972020-05-18 08:45:38 +0200224
Tommi90738dd2021-05-31 17:36:47 +0200225 void SetUp() override {
Tommiae4d0972020-05-18 08:45:38 +0200226 config_.rtp.remote_ssrc = 1111;
227 config_.rtp.local_ssrc = 2222;
228 config_.renderer = &fake_renderer_;
229 VideoReceiveStream::Decoder h264_decoder;
230 h264_decoder.payload_type = 99;
231 h264_decoder.video_format = SdpVideoFormat("H264");
232 h264_decoder.video_format.parameters.insert(
233 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
Evan Shrubsole1c184772022-04-26 09:47:49 +0200234 VideoReceiveStream::Decoder h265_decoder;
235 h265_decoder.payload_type = 100;
236 h265_decoder.video_format = SdpVideoFormat("H265");
237
238 config_.decoders = {h265_decoder, h264_decoder};
Tommiae4d0972020-05-18 08:45:38 +0200239
Evan Shrubsole44be5792022-04-26 16:24:41 +0200240 RecreateReceiveStream();
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200241 }
242
Evan Shrubsole44be5792022-04-26 16:24:41 +0200243 void RecreateReceiveStream(absl::optional<VideoReceiveStream::RecordingState>
244 state = absl::nullopt) {
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200245 if (video_receive_stream_) {
246 video_receive_stream_->UnregisterFromTransport();
247 video_receive_stream_ = nullptr;
248 }
249 timing_ = new VCMTiming(clock_, fake_call_.trials());
Tommiae4d0972020-05-18 08:45:38 +0200250 video_receive_stream_ =
251 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Evan Shrubsole44be5792022-04-26 16:24:41 +0200252 time_controller_.GetTaskQueueFactory(), &fake_call_,
253 kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_,
254 clock_, absl::WrapUnique(timing_), &nack_periodic_processor_,
Evan Shrubsolea4062722022-05-02 17:46:07 +0200255 GetParam() ? &decode_sync_ : nullptr);
Tommi90738dd2021-05-31 17:36:47 +0200256 video_receive_stream_->RegisterWithTransport(
257 &rtp_stream_receiver_controller_);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200258 if (state)
259 video_receive_stream_->SetAndGetRecordingState(std::move(*state), false);
Tommiae4d0972020-05-18 08:45:38 +0200260 }
261
262 protected:
Evan Shrubsole44be5792022-04-26 16:24:41 +0200263 GlobalSimulatedTimeController time_controller_;
264 Clock* const clock_;
265 // Tasks on the main thread can be controlled with the run loop.
Tommiae4d0972020-05-18 08:45:38 +0200266 test::RunLoop loop_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200267 NackPeriodicProcessor nack_periodic_processor_;
Evan Shrubsole1c184772022-04-26 09:47:49 +0200268 testing::NiceMock<MockVideoDecoderFactory> mock_h264_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200269 VideoReceiveStream::Config config_;
270 internal::CallStats call_stats_;
Evan Shrubsolea4062722022-05-02 17:46:07 +0200271 testing::NiceMock<MockVideoDecoder> mock_decoder_;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200272 FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200273 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200274 MockTransport mock_transport_;
275 PacketRouter packet_router_;
276 RtpStreamReceiverController rtp_stream_receiver_controller_;
277 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
Tommiae4d0972020-05-18 08:45:38 +0200278 VCMTiming* timing_;
Evan Shrubsolea4062722022-05-02 17:46:07 +0200279 test::FakeMetronome fake_metronome_;
280 DecodeSynchronizer decode_sync_;
Evan Shrubsole1c184772022-04-26 09:47:49 +0200281
282 private:
283 test::VideoDecoderProxyFactory h264_decoder_factory_;
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200284 test::FakeDecoder fake_decoder_;
Tommiae4d0972020-05-18 08:45:38 +0200285};
286
Evan Shrubsolea4062722022-05-02 17:46:07 +0200287TEST_P(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) {
Tommiae4d0972020-05-18 08:45:38 +0200288 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
289 RtpPacketToSend rtppacket(nullptr);
290 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
291 memcpy(payload, idr_nalu, sizeof(idr_nalu));
292 rtppacket.SetMarker(true);
293 rtppacket.SetSsrc(1111);
294 rtppacket.SetPayloadType(99);
295 rtppacket.SetSequenceNumber(1);
296 rtppacket.SetTimestamp(0);
Evan Shrubsolea4062722022-05-02 17:46:07 +0200297 EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback(_));
Tommiae4d0972020-05-18 08:45:38 +0200298 video_receive_stream_->Start();
Evan Shrubsolea4062722022-05-02 17:46:07 +0200299 EXPECT_CALL(mock_decoder_, Decode(_, false, _));
Tommiae4d0972020-05-18 08:45:38 +0200300 RtpPacketReceived parsed_packet;
301 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
302 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
Evan Shrubsolea4062722022-05-02 17:46:07 +0200303 EXPECT_CALL(mock_decoder_, Release());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200304
305 time_controller_.AdvanceTime(TimeDelta::Zero());
Tommiae4d0972020-05-18 08:45:38 +0200306}
307
Evan Shrubsolea4062722022-05-02 17:46:07 +0200308TEST_P(VideoReceiveStream2Test, PlayoutDelay) {
Niels Möllerd381eed2020-09-02 15:34:40 +0200309 const VideoPlayoutDelay kPlayoutDelayMs = {123, 321};
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200310 std::unique_ptr<test::FakeEncodedFrame> test_frame =
311 test::FakeFrameBuilder().Id(0).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200312 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
313
314 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100315 auto timings = timing_->GetTimings();
316 EXPECT_EQ(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
317 EXPECT_EQ(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200318
319 // Check that the biggest minimum delay is chosen.
320 video_receive_stream_->SetMinimumPlayoutDelay(400);
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100321 timings = timing_->GetTimings();
322 EXPECT_EQ(400, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200323
324 // Check base minimum delay validation.
325 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
326 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
327 EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100328 timings = timing_->GetTimings();
329 EXPECT_EQ(500, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200330
331 // Check that intermidiate values are remembered and the biggest remembered
332 // is chosen.
333 video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100334 timings = timing_->GetTimings();
335 EXPECT_EQ(400, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200336
337 video_receive_stream_->SetMinimumPlayoutDelay(0);
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100338 timings = timing_->GetTimings();
339 EXPECT_EQ(123, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200340}
341
Evan Shrubsolea4062722022-05-02 17:46:07 +0200342TEST_P(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100343 const TimeDelta default_max_playout_latency =
344 timing_->GetTimings().max_playout_delay;
Niels Möllerd381eed2020-09-02 15:34:40 +0200345 const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
Tommiae4d0972020-05-18 08:45:38 +0200346
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200347 std::unique_ptr<test::FakeEncodedFrame> test_frame =
348 test::FakeFrameBuilder().Id(0).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200349 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
350
351 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
352
Artem Titovab30d722021-07-27 16:22:11 +0200353 // Ensure that -1 preserves default maximum value from `timing_`.
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100354 auto timings = timing_->GetTimings();
355 EXPECT_EQ(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
356 EXPECT_NE(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
357 EXPECT_EQ(default_max_playout_latency, timings.max_playout_delay);
Tommiae4d0972020-05-18 08:45:38 +0200358}
359
Evan Shrubsolea4062722022-05-02 17:46:07 +0200360TEST_P(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100361 const TimeDelta default_min_playout_latency =
362 timing_->GetTimings().min_playout_delay;
Niels Möllerd381eed2020-09-02 15:34:40 +0200363 const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
Tommiae4d0972020-05-18 08:45:38 +0200364
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200365 std::unique_ptr<test::FakeEncodedFrame> test_frame =
366 test::FakeFrameBuilder().Id(0).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200367 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
368
369 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
370
Artem Titovab30d722021-07-27 16:22:11 +0200371 // Ensure that -1 preserves default minimum value from `timing_`.
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100372 auto timings = timing_->GetTimings();
373 EXPECT_NE(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
374 EXPECT_EQ(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
375 EXPECT_EQ(default_min_playout_latency, timings.min_playout_delay);
Tommiae4d0972020-05-18 08:45:38 +0200376}
377
Evan Shrubsolea4062722022-05-02 17:46:07 +0200378TEST_P(VideoReceiveStream2Test, MaxCompositionDelayNotSetByDefault) {
Johannes Kron111e9812020-10-26 13:54:40 +0100379 // Default with no playout delay set.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200380 std::unique_ptr<test::FakeEncodedFrame> test_frame0 =
381 test::FakeFrameBuilder().Id(0).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100382 video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
383 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
384
385 // Max composition delay not set for playout delay 0,0.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200386 std::unique_ptr<test::FakeEncodedFrame> test_frame1 =
387 test::FakeFrameBuilder().Id(1).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100388 test_frame1->SetPlayoutDelay({0, 0});
389 video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
390 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
391
392 // Max composition delay not set for playout delay X,Y, where X,Y>0.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200393 std::unique_ptr<test::FakeEncodedFrame> test_frame2 =
394 test::FakeFrameBuilder().Id(2).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100395 test_frame2->SetPlayoutDelay({10, 30});
396 video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
397 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
398}
399
Evan Shrubsolea4062722022-05-02 17:46:07 +0200400TEST_P(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) {
Johannes Kron111e9812020-10-26 13:54:40 +0100401 // Max composition delay set if playout delay X,Y, where X=0,Y>0.
402 const VideoPlayoutDelay kPlayoutDelayMs = {0, 50};
403 const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200404 std::unique_ptr<test::FakeEncodedFrame> test_frame =
405 test::FakeFrameBuilder().Id(0).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100406 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
407 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
408 EXPECT_EQ(kExpectedMaxCompositionDelayInFrames,
409 timing_->MaxCompositionDelayInFrames());
410}
411
Evan Shrubsolea4062722022-05-02 17:46:07 +0200412TEST_P(VideoReceiveStream2Test, LazyDecoderCreation) {
Evan Shrubsole1c184772022-04-26 09:47:49 +0200413 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
414 RtpPacketToSend rtppacket(nullptr);
415 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
416 memcpy(payload, idr_nalu, sizeof(idr_nalu));
417 rtppacket.SetMarker(true);
418 rtppacket.SetSsrc(1111);
419 // H265 payload type.
420 rtppacket.SetPayloadType(99);
421 rtppacket.SetSequenceNumber(1);
422 rtppacket.SetTimestamp(0);
423
424 // Only 1 decoder is created by default. It will be H265 since that was the
425 // first in the decoder list.
426 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
427 EXPECT_CALL(mock_h264_decoder_factory_,
428 CreateVideoDecoder(
429 testing::Field(&SdpVideoFormat::name, testing::Eq("H265"))))
430 .Times(1);
431 video_receive_stream_->Start();
432
433 EXPECT_TRUE(
434 testing::Mock::VerifyAndClearExpectations(&mock_h264_decoder_factory_));
435
436 EXPECT_CALL(mock_h264_decoder_factory_,
437 CreateVideoDecoder(
438 testing::Field(&SdpVideoFormat::name, testing::Eq("H264"))))
439 .Times(1);
440 rtc::Event init_decode_event;
Evan Shrubsolea4062722022-05-02 17:46:07 +0200441 EXPECT_CALL(mock_decoder_, Configure).WillOnce(WithoutArgs([&] {
Evan Shrubsole1c184772022-04-26 09:47:49 +0200442 init_decode_event.Set();
443 return true;
444 }));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200445 EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback(_));
446 EXPECT_CALL(mock_decoder_, Decode(_, false, _));
Evan Shrubsole1c184772022-04-26 09:47:49 +0200447 RtpPacketReceived parsed_packet;
448 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
449 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
Evan Shrubsolea4062722022-05-02 17:46:07 +0200450 EXPECT_CALL(mock_decoder_, Release());
Evan Shrubsole1c184772022-04-26 09:47:49 +0200451
452 // Make sure the decoder thread had a chance to run.
Evan Shrubsole44be5792022-04-26 16:24:41 +0200453 init_decode_event.Wait(kDefaultTimeOut.ms());
Evan Shrubsole1c184772022-04-26 09:47:49 +0200454}
455
Evan Shrubsolea4062722022-05-02 17:46:07 +0200456TEST_P(VideoReceiveStream2Test, PassesNtpTime) {
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200457 const Timestamp kNtpTimestamp = Timestamp::Millis(12345);
458 std::unique_ptr<test::FakeEncodedFrame> test_frame =
459 test::FakeFrameBuilder()
460 .Id(0)
461 .PayloadType(99)
462 .NtpTime(kNtpTimestamp)
463 .AsLast()
464 .Build();
Tommiae4d0972020-05-18 08:45:38 +0200465
466 video_receive_stream_->Start();
467 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200468 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200469 RenderedFrameWith(NtpTimestamp(kNtpTimestamp)));
Tommiae4d0972020-05-18 08:45:38 +0200470}
471
Evan Shrubsolea4062722022-05-02 17:46:07 +0200472TEST_P(VideoReceiveStream2Test, PassesRotation) {
Tommiae4d0972020-05-18 08:45:38 +0200473 const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200474 std::unique_ptr<test::FakeEncodedFrame> test_frame = test::FakeFrameBuilder()
475 .Id(0)
476 .PayloadType(99)
477 .Rotation(kRotation)
478 .AsLast()
479 .Build();
Tommiae4d0972020-05-18 08:45:38 +0200480
481 video_receive_stream_->Start();
482 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200483 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200484 RenderedFrameWith(Rotation(kRotation)));
Tommiae4d0972020-05-18 08:45:38 +0200485}
486
Evan Shrubsolea4062722022-05-02 17:46:07 +0200487TEST_P(VideoReceiveStream2Test, PassesPacketInfos) {
Tommiae4d0972020-05-18 08:45:38 +0200488 RtpPacketInfos packet_infos = CreatePacketInfos(3);
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200489 auto test_frame = test::FakeFrameBuilder()
490 .Id(0)
491 .PayloadType(99)
492 .PacketInfos(packet_infos)
493 .AsLast()
494 .Build();
Tommiae4d0972020-05-18 08:45:38 +0200495
496 video_receive_stream_->Start();
497 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200498 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200499 RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos))));
Tommiae4d0972020-05-18 08:45:38 +0200500}
501
Evan Shrubsolea4062722022-05-02 17:46:07 +0200502TEST_P(VideoReceiveStream2Test, RenderedFrameUpdatesGetSources) {
Tommiae4d0972020-05-18 08:45:38 +0200503 constexpr uint32_t kSsrc = 1111;
504 constexpr uint32_t kCsrc = 9001;
505 constexpr uint32_t kRtpTimestamp = 12345;
506
507 // Prepare one video frame with per-packet information.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200508 auto test_frame =
509 test::FakeFrameBuilder().Id(0).PayloadType(99).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200510 RtpPacketInfos packet_infos;
511 {
512 RtpPacketInfos::vector_type infos;
513
514 RtpPacketInfo info;
515 info.set_ssrc(kSsrc);
516 info.set_csrcs({kCsrc});
517 info.set_rtp_timestamp(kRtpTimestamp);
518
Johannes Kronf7de74c2021-04-30 13:10:56 +0200519 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
Tommiae4d0972020-05-18 08:45:38 +0200520 infos.push_back(info);
521
Johannes Kronf7de74c2021-04-30 13:10:56 +0200522 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
Tommiae4d0972020-05-18 08:45:38 +0200523 infos.push_back(info);
524
Johannes Kronf7de74c2021-04-30 13:10:56 +0200525 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
Tommiae4d0972020-05-18 08:45:38 +0200526 infos.push_back(info);
527
Johannes Kronf7de74c2021-04-30 13:10:56 +0200528 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(1000));
Tommiae4d0972020-05-18 08:45:38 +0200529 infos.push_back(info);
530
531 packet_infos = RtpPacketInfos(std::move(infos));
532 }
533 test_frame->SetPacketInfos(packet_infos);
534
535 // Start receive stream.
536 video_receive_stream_->Start();
537 EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
538
539 // Render one video frame.
540 int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
541 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Tommiae4d0972020-05-18 08:45:38 +0200542 // Verify that the per-packet information is passed to the renderer.
Evan Shrubsolea4062722022-05-02 17:46:07 +0200543 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200544 RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos))));
545 int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
Tommiae4d0972020-05-18 08:45:38 +0200546
Artem Titovab30d722021-07-27 16:22:11 +0200547 // Verify that the per-packet information also updates `GetSources()`.
Tommiae4d0972020-05-18 08:45:38 +0200548 std::vector<RtpSource> sources = video_receive_stream_->GetSources();
549 ASSERT_THAT(sources, SizeIs(2));
550 {
551 auto it = std::find_if(sources.begin(), sources.end(),
552 [](const RtpSource& source) {
553 return source.source_type() == RtpSourceType::SSRC;
554 });
555 ASSERT_NE(it, sources.end());
556
557 EXPECT_EQ(it->source_id(), kSsrc);
558 EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
559 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
560 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
561 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
562 }
563 {
564 auto it = std::find_if(sources.begin(), sources.end(),
565 [](const RtpSource& source) {
566 return source.source_type() == RtpSourceType::CSRC;
567 });
568 ASSERT_NE(it, sources.end());
569
570 EXPECT_EQ(it->source_id(), kCsrc);
571 EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
572 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
573 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
574 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
575 }
576}
577
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200578std::unique_ptr<test::FakeEncodedFrame> MakeFrameWithResolution(
Markus Handell588f9b32021-04-08 19:19:50 +0200579 VideoFrameType frame_type,
580 int picture_id,
581 int width,
582 int height) {
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200583 auto frame =
584 test::FakeFrameBuilder().Id(picture_id).PayloadType(99).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200585 frame->SetFrameType(frame_type);
Markus Handell588f9b32021-04-08 19:19:50 +0200586 frame->_encodedWidth = width;
587 frame->_encodedHeight = height;
Tommiae4d0972020-05-18 08:45:38 +0200588 return frame;
589}
590
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200591std::unique_ptr<test::FakeEncodedFrame> MakeFrame(VideoFrameType frame_type,
592 int picture_id) {
Markus Handell588f9b32021-04-08 19:19:50 +0200593 return MakeFrameWithResolution(frame_type, picture_id, 320, 240);
594}
595
Evan Shrubsolea4062722022-05-02 17:46:07 +0200596TEST_P(VideoReceiveStream2Test, PassesFrameWhenEncodedFramesCallbackSet) {
Tommiae4d0972020-05-18 08:45:38 +0200597 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
598 video_receive_stream_->Start();
599 // Expect a keyframe request to be generated
600 EXPECT_CALL(mock_transport_, SendRtcp);
601 EXPECT_CALL(callback, Call);
602 video_receive_stream_->SetAndGetRecordingState(
603 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
604 video_receive_stream_->OnCompleteFrame(
605 MakeFrame(VideoFrameType::kVideoFrameKey, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200606 EXPECT_TRUE(fake_renderer_.WaitForFrame(kDefaultTimeOut));
Tommiae4d0972020-05-18 08:45:38 +0200607 video_receive_stream_->Stop();
608}
609
Evan Shrubsolea4062722022-05-02 17:46:07 +0200610TEST_P(VideoReceiveStream2Test, MovesEncodedFrameDispatchStateWhenReCreating) {
Tommiae4d0972020-05-18 08:45:38 +0200611 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
612 video_receive_stream_->Start();
613 // Expect a key frame request over RTCP.
614 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
615 video_receive_stream_->SetAndGetRecordingState(
616 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
617 video_receive_stream_->Stop();
618 VideoReceiveStream::RecordingState old_state =
619 video_receive_stream_->SetAndGetRecordingState(
620 VideoReceiveStream::RecordingState(), false);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200621 RecreateReceiveStream(std::move(old_state));
Tommiae4d0972020-05-18 08:45:38 +0200622 video_receive_stream_->Stop();
623}
624
Evan Shrubsolea4062722022-05-02 17:46:07 +0200625TEST_P(VideoReceiveStream2Test, RequestsKeyFramesUntilKeyFrameReceived) {
Evan Shrubsole44be5792022-04-26 16:24:41 +0200626 // Recreate receive stream with shorter delay to test rtx.
627 TimeDelta rtx_delay = TimeDelta::Millis(50);
628 config_.rtp.nack.rtp_history_ms = rtx_delay.ms();
629 auto tick = rtx_delay / 2;
630 RecreateReceiveStream();
631 video_receive_stream_->Start();
Markus Handell588f9b32021-04-08 19:19:50 +0200632
Evan Shrubsole44be5792022-04-26 16:24:41 +0200633 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(testing::Return(0));
634 video_receive_stream_->GenerateKeyFrame();
635 video_receive_stream_->OnCompleteFrame(
636 MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200637 fake_renderer_.WaitForFrame(kDefaultTimeOut);
Tommiae4d0972020-05-18 08:45:38 +0200638 time_controller_.AdvanceTime(tick);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100639 loop_.Flush();
Evan Shrubsole44be5792022-04-26 16:24:41 +0200640 video_receive_stream_->OnCompleteFrame(
641 MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200642 fake_renderer_.WaitForFrame(kDefaultTimeOut);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200643 time_controller_.AdvanceTime(TimeDelta::Zero());
Tommiae4d0972020-05-18 08:45:38 +0200644 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
645
Philipp Hancke006206d2021-03-24 17:49:02 +0100646 // T+keyframetimeout: still no key frame received, expect key frame request
647 // sent again.
Evan Shrubsole44be5792022-04-26 16:24:41 +0200648 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(testing::Return(0));
Tommiae4d0972020-05-18 08:45:38 +0200649 time_controller_.AdvanceTime(tick);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200650 video_receive_stream_->OnCompleteFrame(
651 MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200652 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200653 loop_.Flush();
Tommiae4d0972020-05-18 08:45:38 +0200654 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
655
Philipp Hancke006206d2021-03-24 17:49:02 +0100656 // T+keyframetimeout: now send a key frame - we should not observe new key
657 // frame requests after this.
Tommiae4d0972020-05-18 08:45:38 +0200658 EXPECT_CALL(mock_transport_, SendRtcp).Times(0);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200659 video_receive_stream_->OnCompleteFrame(
660 MakeFrame(VideoFrameType::kVideoFrameKey, 3));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200661 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Tommiae4d0972020-05-18 08:45:38 +0200662 time_controller_.AdvanceTime(2 * tick);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200663 video_receive_stream_->OnCompleteFrame(
664 MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200665 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200666 loop_.Flush();
Tommiae4d0972020-05-18 08:45:38 +0200667}
668
Evan Shrubsolea4062722022-05-02 17:46:07 +0200669TEST_P(VideoReceiveStream2Test,
Markus Handell588f9b32021-04-08 19:19:50 +0200670 DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution) {
Evan Shrubsole44be5792022-04-26 16:24:41 +0200671 video_receive_stream_->Start();
Markus Handell588f9b32021-04-08 19:19:50 +0200672 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200673 video_receive_stream_->SetAndGetRecordingState(
Markus Handell588f9b32021-04-08 19:19:50 +0200674 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
675 /*generate_key_frame=*/false);
676
677 InSequence s;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200678 EXPECT_CALL(callback, Call(Resolution(test::FakeDecoder::kDefaultWidth,
679 test::FakeDecoder::kDefaultHeight)));
Markus Handell588f9b32021-04-08 19:19:50 +0200680 EXPECT_CALL(callback, Call);
681
Evan Shrubsole44be5792022-04-26 16:24:41 +0200682 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200683 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 0, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200684 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200685 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200686 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200687 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Markus Handell588f9b32021-04-08 19:19:50 +0200688
Evan Shrubsole44be5792022-04-26 16:24:41 +0200689 video_receive_stream_->Stop();
Markus Handell588f9b32021-04-08 19:19:50 +0200690}
691
Evan Shrubsolea4062722022-05-02 17:46:07 +0200692TEST_P(VideoReceiveStream2Test,
Markus Handell588f9b32021-04-08 19:19:50 +0200693 DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution) {
Evan Shrubsole44be5792022-04-26 16:24:41 +0200694 video_receive_stream_->Start();
Markus Handell588f9b32021-04-08 19:19:50 +0200695 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200696 video_receive_stream_->SetAndGetRecordingState(
Markus Handell588f9b32021-04-08 19:19:50 +0200697 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
698 /*generate_key_frame=*/false);
699
700 InSequence s;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200701 EXPECT_CALL(callback, Call(Resolution(1080u, 720u)));
Markus Handell588f9b32021-04-08 19:19:50 +0200702 EXPECT_CALL(callback, Call);
703
Evan Shrubsole44be5792022-04-26 16:24:41 +0200704 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200705 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 1080, 720));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200706 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200707 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200708 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200709 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Markus Handell588f9b32021-04-08 19:19:50 +0200710
Evan Shrubsole44be5792022-04-26 16:24:41 +0200711 video_receive_stream_->Stop();
Markus Handell588f9b32021-04-08 19:19:50 +0200712}
713
Evan Shrubsolea4062722022-05-02 17:46:07 +0200714TEST_P(VideoReceiveStream2Test, DependantFramesAreScheduled) {
715 video_receive_stream_->Start();
716
717 auto key_frame = test::FakeFrameBuilder()
718 .Id(0)
719 .PayloadType(99)
720 .Time(kFirstRtpTimestamp)
721 .ReceivedTime(kStartTime)
722 .AsLast()
723 .Build();
724 auto delta_frame = test::FakeFrameBuilder()
725 .Id(1)
726 .PayloadType(99)
727 .Time(RtpTimestampForFrame(1))
728 .ReceivedTime(ReceiveTimeForFrame(1))
729 .Refs({0})
730 .AsLast()
731 .Build();
732
733 // Expect frames are decoded in order.
734 InSequence seq;
735 EXPECT_CALL(mock_decoder_,
736 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _));
737 EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp +
738 k30FpsRtpTimestampDelta),
739 _, _))
740 .Times(1);
741 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
742 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
743
744 time_controller_.AdvanceTime(k30FpsDelay);
745 video_receive_stream_->OnCompleteFrame(std::move(delta_frame));
746 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
747
748 video_receive_stream_->Stop();
749}
750
751TEST_P(VideoReceiveStream2Test, FramesScheduledInOrder) {
752 video_receive_stream_->Start();
753
754 auto key_frame = test::FakeFrameBuilder()
755 .Id(0)
756 .PayloadType(99)
757 .Time(kFirstRtpTimestamp)
758 .AsLast()
759 .Build();
760 auto delta_frame1 = test::FakeFrameBuilder()
761 .Id(1)
762 .PayloadType(99)
763 .Time(RtpTimestampForFrame(1))
764 .Refs({0})
765 .AsLast()
766 .Build();
767 auto delta_frame2 = test::FakeFrameBuilder()
768 .Id(2)
769 .PayloadType(99)
770 .Time(RtpTimestampForFrame(2))
771 .Refs({1})
772 .AsLast()
773 .Build();
774
775 // Expect frames are decoded in order despite delta_frame1 arriving first.
776 InSequence seq;
777 EXPECT_CALL(mock_decoder_,
778 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
779 .Times(1);
780 EXPECT_CALL(mock_decoder_,
781 Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
782 .Times(1);
783 EXPECT_CALL(mock_decoder_,
784 Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
785 .Times(1);
786 key_frame->SetReceivedTime(clock_->CurrentTime().ms());
787 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
788 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
789
790 delta_frame2->SetReceivedTime(clock_->CurrentTime().ms());
791 video_receive_stream_->OnCompleteFrame(std::move(delta_frame2));
792 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), DidNotReceiveFrame());
793 // `delta_frame1` arrives late.
794 delta_frame1->SetReceivedTime(clock_->CurrentTime().ms());
795 video_receive_stream_->OnCompleteFrame(std::move(delta_frame1));
796 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
797 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay * 2), RenderedFrame());
798 video_receive_stream_->Stop();
799}
800
801TEST_P(VideoReceiveStream2Test, WaitsforAllSpatialLayers) {
802 video_receive_stream_->Start();
803 auto sl0 = test::FakeFrameBuilder()
804 .Id(0)
805 .PayloadType(99)
806 .Time(kFirstRtpTimestamp)
807 .ReceivedTime(kStartTime)
808 .Build();
809 auto sl1 = test::FakeFrameBuilder()
810 .Id(1)
811 .PayloadType(99)
812 .ReceivedTime(kStartTime)
813 .Time(kFirstRtpTimestamp)
814 .Refs({0})
815 .Build();
816 auto sl2 = test::FakeFrameBuilder()
817 .Id(2)
818 .PayloadType(99)
819 .ReceivedTime(kStartTime)
820 .Time(kFirstRtpTimestamp)
821 .Refs({0, 1})
822 .AsLast()
823 .Build();
824
825 // No decodes should be called until `sl2` is received.
826 EXPECT_CALL(mock_decoder_, Decode).Times(0);
827 sl0->SetReceivedTime(clock_->CurrentTime().ms());
828 video_receive_stream_->OnCompleteFrame(std::move(sl0));
829 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
830 DidNotReceiveFrame());
831 video_receive_stream_->OnCompleteFrame(std::move(sl1));
832 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
833 DidNotReceiveFrame());
834 // When `sl2` arrives decode should happen.
835 EXPECT_CALL(mock_decoder_,
836 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
837 .Times(1);
838 video_receive_stream_->OnCompleteFrame(std::move(sl2));
839 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
840 video_receive_stream_->Stop();
841}
842
843TEST_P(VideoReceiveStream2Test, FramesFastForwardOnSystemHalt) {
844 video_receive_stream_->Start();
845
846 // The frame structure looks like this,
847 // F1
848 // /
849 // F0 --> F2
850 //
851 // In this case we will have a system halt simulated. By the time the system
852 // resumes, F1 will be old and so F2 should be decoded.
853 auto key_frame = test::FakeFrameBuilder()
854 .Id(0)
855 .PayloadType(99)
856 .Time(kFirstRtpTimestamp)
857 .AsLast()
858 .Build();
859 auto ffwd_frame = test::FakeFrameBuilder()
860 .Id(1)
861 .PayloadType(99)
862 .Time(RtpTimestampForFrame(1))
863 .Refs({0})
864 .AsLast()
865 .Build();
866 auto rendered_frame = test::FakeFrameBuilder()
867 .Id(2)
868 .PayloadType(99)
869 .Time(RtpTimestampForFrame(2))
870 .Refs({0})
871 .AsLast()
872 .Build();
873 InSequence seq;
874 EXPECT_CALL(mock_decoder_,
875 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
876 .WillOnce(testing::DoAll(testing::Invoke([&] {
877 // System halt will be simulated in the decode.
878 time_controller_.AdvanceTime(k30FpsDelay * 2);
879 }),
880 DefaultDecodeAction()));
881 EXPECT_CALL(mock_decoder_,
882 Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _));
883 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
884 video_receive_stream_->OnCompleteFrame(std::move(ffwd_frame));
885 video_receive_stream_->OnCompleteFrame(std::move(rendered_frame));
886 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
887 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
888
889 // Check stats show correct dropped frames.
890 auto stats = video_receive_stream_->GetStats();
891 EXPECT_EQ(stats.frames_dropped, 1u);
892
893 video_receive_stream_->Stop();
894}
895
896TEST_P(VideoReceiveStream2Test, BetterFrameInsertedWhileWaitingToDecodeFrame) {
897 video_receive_stream_->Start();
898
899 auto key_frame = test::FakeFrameBuilder()
900 .Id(0)
901 .PayloadType(99)
902 .Time(kFirstRtpTimestamp)
903 .ReceivedTime(ReceiveTimeForFrame(0))
904 .AsLast()
905 .Build();
906 auto f1 = test::FakeFrameBuilder()
907 .Id(1)
908 .PayloadType(99)
909 .Time(RtpTimestampForFrame(1))
910 .ReceivedTime(ReceiveTimeForFrame(1))
911 .Refs({0})
912 .AsLast()
913 .Build();
914 auto f2 = test::FakeFrameBuilder()
915 .Id(2)
916 .PayloadType(99)
917 .Time(RtpTimestampForFrame(2))
918 .ReceivedTime(ReceiveTimeForFrame(2))
919 .Refs({0})
920 .AsLast()
921 .Build();
922
923 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
924 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
925
926 InSequence seq;
927 EXPECT_CALL(mock_decoder_,
928 Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
929 .Times(1);
930 EXPECT_CALL(mock_decoder_,
931 Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
932 .Times(1);
933 // Simulate f1 arriving after f2 but before f2 is decoded.
934 video_receive_stream_->OnCompleteFrame(std::move(f2));
935 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), DidNotReceiveFrame());
936 video_receive_stream_->OnCompleteFrame(std::move(f1));
937 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
938 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
939
940 video_receive_stream_->Stop();
941}
942
943// Note: This test takes a long time (~10s) to run if the fake metronome is
944// active. Since the test needs to wait for the timestamp to rollover, it has a
945// fake delay of around 6.5 hours. Even though time is simulated, this will be
946// around 1,500,000 metronome tick invocations.
947TEST_P(VideoReceiveStream2Test, RtpTimestampWrapAround) {
948 video_receive_stream_->Start();
949
950 constexpr uint32_t kBaseRtp = std::numeric_limits<uint32_t>::max() / 2;
951 video_receive_stream_->OnCompleteFrame(
952 test::FakeFrameBuilder()
953 .Id(0)
954 .PayloadType(99)
955 .Time(kBaseRtp)
956 .ReceivedTime(clock_->CurrentTime())
957 .AsLast()
958 .Build());
959 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
960 time_controller_.AdvanceTime(k30FpsDelay);
961 video_receive_stream_->OnCompleteFrame(
962 test::FakeFrameBuilder()
963 .Id(1)
964 .PayloadType(99)
965 .Time(kBaseRtp + k30FpsRtpTimestampDelta)
966 .ReceivedTime(clock_->CurrentTime())
967 .AsLast()
968 .Build());
969 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
970
971 // Pause stream so that RTP timestamp wraps around.
972 constexpr uint32_t kLastRtp = kBaseRtp + k30FpsRtpTimestampDelta;
973 constexpr uint32_t kWrapAroundRtp =
974 kLastRtp + std::numeric_limits<uint32_t>::max() / 2 + 1;
975 // Pause for corresponding delay such that RTP timestamp would increase this
976 // much at 30fps.
977 constexpr TimeDelta kWrapAroundDelay =
978 (std::numeric_limits<uint32_t>::max() / 2 + 1) / kRtpTimestampHz;
979
980 time_controller_.AdvanceTime(kWrapAroundDelay);
981 video_receive_stream_->OnCompleteFrame(
982 test::FakeFrameBuilder()
983 .Id(2)
984 .PayloadType(99)
985 .Time(kWrapAroundRtp)
986 .ReceivedTime(clock_->CurrentTime())
987 .AsLast()
988 .Build());
989 EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kWrapAroundRtp), _, _))
990 .Times(1);
991 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
992
993 video_receive_stream_->Stop();
994}
995
996INSTANTIATE_TEST_SUITE_P(VideoReceiveStream2Test,
997 VideoReceiveStream2Test,
998 testing::Bool(),
999 [](const auto& test_param_info) {
1000 rtc::StringBuilder ss;
1001 ss << (test_param_info.param
1002 ? "ScheduleDecodesWithMetronome"
1003 : "ScheduleDecodesWithPostTask");
1004 return ss.Release();
1005 });
1006
Tommiae4d0972020-05-18 08:45:38 +02001007} // namespace webrtc