blob: 3fbc654c54fd55f1cc7a3b31cd05724294b4f504 [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_;
Tommif6f45432022-05-20 15:21:20 +0200229 VideoReceiveStreamInterface::Decoder h264_decoder;
Tommiae4d0972020-05-18 08:45:38 +0200230 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=="});
Tommif6f45432022-05-20 15:21:20 +0200234 VideoReceiveStreamInterface::Decoder h265_decoder;
Evan Shrubsole1c184772022-04-26 09:47:49 +0200235 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
Tommif6f45432022-05-20 15:21:20 +0200243 void RecreateReceiveStream(
244 absl::optional<VideoReceiveStreamInterface::RecordingState> state =
245 absl::nullopt) {
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200246 if (video_receive_stream_) {
247 video_receive_stream_->UnregisterFromTransport();
248 video_receive_stream_ = nullptr;
249 }
250 timing_ = new VCMTiming(clock_, fake_call_.trials());
Tommiae4d0972020-05-18 08:45:38 +0200251 video_receive_stream_ =
252 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Evan Shrubsole44be5792022-04-26 16:24:41 +0200253 time_controller_.GetTaskQueueFactory(), &fake_call_,
254 kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_,
255 clock_, absl::WrapUnique(timing_), &nack_periodic_processor_,
Evan Shrubsolea4062722022-05-02 17:46:07 +0200256 GetParam() ? &decode_sync_ : nullptr);
Tommi90738dd2021-05-31 17:36:47 +0200257 video_receive_stream_->RegisterWithTransport(
258 &rtp_stream_receiver_controller_);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200259 if (state)
260 video_receive_stream_->SetAndGetRecordingState(std::move(*state), false);
Tommiae4d0972020-05-18 08:45:38 +0200261 }
262
263 protected:
Evan Shrubsole44be5792022-04-26 16:24:41 +0200264 GlobalSimulatedTimeController time_controller_;
265 Clock* const clock_;
266 // Tasks on the main thread can be controlled with the run loop.
Tommiae4d0972020-05-18 08:45:38 +0200267 test::RunLoop loop_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200268 NackPeriodicProcessor nack_periodic_processor_;
Evan Shrubsole1c184772022-04-26 09:47:49 +0200269 testing::NiceMock<MockVideoDecoderFactory> mock_h264_decoder_factory_;
Tommif6f45432022-05-20 15:21:20 +0200270 VideoReceiveStreamInterface::Config config_;
Tommiae4d0972020-05-18 08:45:38 +0200271 internal::CallStats call_stats_;
Evan Shrubsolea4062722022-05-02 17:46:07 +0200272 testing::NiceMock<MockVideoDecoder> mock_decoder_;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200273 FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200274 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200275 MockTransport mock_transport_;
276 PacketRouter packet_router_;
277 RtpStreamReceiverController rtp_stream_receiver_controller_;
278 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
Tommiae4d0972020-05-18 08:45:38 +0200279 VCMTiming* timing_;
Evan Shrubsolea4062722022-05-02 17:46:07 +0200280 test::FakeMetronome fake_metronome_;
281 DecodeSynchronizer decode_sync_;
Evan Shrubsole1c184772022-04-26 09:47:49 +0200282
283 private:
284 test::VideoDecoderProxyFactory h264_decoder_factory_;
Evan Shrubsole14ee8032022-04-26 16:01:44 +0200285 test::FakeDecoder fake_decoder_;
Tommiae4d0972020-05-18 08:45:38 +0200286};
287
Evan Shrubsolea4062722022-05-02 17:46:07 +0200288TEST_P(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) {
Tommiae4d0972020-05-18 08:45:38 +0200289 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
290 RtpPacketToSend rtppacket(nullptr);
291 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
292 memcpy(payload, idr_nalu, sizeof(idr_nalu));
293 rtppacket.SetMarker(true);
294 rtppacket.SetSsrc(1111);
295 rtppacket.SetPayloadType(99);
296 rtppacket.SetSequenceNumber(1);
297 rtppacket.SetTimestamp(0);
Evan Shrubsolea4062722022-05-02 17:46:07 +0200298 EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback(_));
Tommiae4d0972020-05-18 08:45:38 +0200299 video_receive_stream_->Start();
Evan Shrubsolea4062722022-05-02 17:46:07 +0200300 EXPECT_CALL(mock_decoder_, Decode(_, false, _));
Tommiae4d0972020-05-18 08:45:38 +0200301 RtpPacketReceived parsed_packet;
302 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
303 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
Evan Shrubsolea4062722022-05-02 17:46:07 +0200304 EXPECT_CALL(mock_decoder_, Release());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200305
306 time_controller_.AdvanceTime(TimeDelta::Zero());
Tommiae4d0972020-05-18 08:45:38 +0200307}
308
Evan Shrubsolea4062722022-05-02 17:46:07 +0200309TEST_P(VideoReceiveStream2Test, PlayoutDelay) {
Niels Möllerd381eed2020-09-02 15:34:40 +0200310 const VideoPlayoutDelay kPlayoutDelayMs = {123, 321};
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200311 std::unique_ptr<test::FakeEncodedFrame> test_frame =
312 test::FakeFrameBuilder().Id(0).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200313 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
314
315 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100316 auto timings = timing_->GetTimings();
317 EXPECT_EQ(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
318 EXPECT_EQ(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200319
320 // Check that the biggest minimum delay is chosen.
321 video_receive_stream_->SetMinimumPlayoutDelay(400);
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100322 timings = timing_->GetTimings();
323 EXPECT_EQ(400, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200324
325 // Check base minimum delay validation.
326 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
327 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
328 EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100329 timings = timing_->GetTimings();
330 EXPECT_EQ(500, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200331
332 // Check that intermidiate values are remembered and the biggest remembered
333 // is chosen.
334 video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100335 timings = timing_->GetTimings();
336 EXPECT_EQ(400, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200337
338 video_receive_stream_->SetMinimumPlayoutDelay(0);
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100339 timings = timing_->GetTimings();
340 EXPECT_EQ(123, timings.min_playout_delay.ms());
Tommiae4d0972020-05-18 08:45:38 +0200341}
342
Evan Shrubsolea4062722022-05-02 17:46:07 +0200343TEST_P(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100344 const TimeDelta default_max_playout_latency =
345 timing_->GetTimings().max_playout_delay;
Niels Möllerd381eed2020-09-02 15:34:40 +0200346 const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
Tommiae4d0972020-05-18 08:45:38 +0200347
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200348 std::unique_ptr<test::FakeEncodedFrame> test_frame =
349 test::FakeFrameBuilder().Id(0).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200350 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
351
352 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
353
Artem Titovab30d722021-07-27 16:22:11 +0200354 // Ensure that -1 preserves default maximum value from `timing_`.
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100355 auto timings = timing_->GetTimings();
356 EXPECT_EQ(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
357 EXPECT_NE(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
358 EXPECT_EQ(default_max_playout_latency, timings.max_playout_delay);
Tommiae4d0972020-05-18 08:45:38 +0200359}
360
Evan Shrubsolea4062722022-05-02 17:46:07 +0200361TEST_P(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100362 const TimeDelta default_min_playout_latency =
363 timing_->GetTimings().min_playout_delay;
Niels Möllerd381eed2020-09-02 15:34:40 +0200364 const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
Tommiae4d0972020-05-18 08:45:38 +0200365
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200366 std::unique_ptr<test::FakeEncodedFrame> test_frame =
367 test::FakeFrameBuilder().Id(0).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200368 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
369
370 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
371
Artem Titovab30d722021-07-27 16:22:11 +0200372 // Ensure that -1 preserves default minimum value from `timing_`.
Evan Shrubsole8f1159b2022-03-22 12:12:17 +0100373 auto timings = timing_->GetTimings();
374 EXPECT_NE(kPlayoutDelayMs.min_ms, timings.min_playout_delay.ms());
375 EXPECT_EQ(kPlayoutDelayMs.max_ms, timings.max_playout_delay.ms());
376 EXPECT_EQ(default_min_playout_latency, timings.min_playout_delay);
Tommiae4d0972020-05-18 08:45:38 +0200377}
378
Evan Shrubsolea4062722022-05-02 17:46:07 +0200379TEST_P(VideoReceiveStream2Test, MaxCompositionDelayNotSetByDefault) {
Johannes Kron111e9812020-10-26 13:54:40 +0100380 // Default with no playout delay set.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200381 std::unique_ptr<test::FakeEncodedFrame> test_frame0 =
382 test::FakeFrameBuilder().Id(0).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100383 video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
384 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
385
386 // Max composition delay not set for playout delay 0,0.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200387 std::unique_ptr<test::FakeEncodedFrame> test_frame1 =
388 test::FakeFrameBuilder().Id(1).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100389 test_frame1->SetPlayoutDelay({0, 0});
390 video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
391 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
392
393 // Max composition delay not set for playout delay X,Y, where X,Y>0.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200394 std::unique_ptr<test::FakeEncodedFrame> test_frame2 =
395 test::FakeFrameBuilder().Id(2).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100396 test_frame2->SetPlayoutDelay({10, 30});
397 video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
398 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
399}
400
Evan Shrubsolea4062722022-05-02 17:46:07 +0200401TEST_P(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) {
Johannes Kron111e9812020-10-26 13:54:40 +0100402 // Max composition delay set if playout delay X,Y, where X=0,Y>0.
403 const VideoPlayoutDelay kPlayoutDelayMs = {0, 50};
404 const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200405 std::unique_ptr<test::FakeEncodedFrame> test_frame =
406 test::FakeFrameBuilder().Id(0).AsLast().Build();
Johannes Kron111e9812020-10-26 13:54:40 +0100407 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
408 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
409 EXPECT_EQ(kExpectedMaxCompositionDelayInFrames,
410 timing_->MaxCompositionDelayInFrames());
411}
412
Evan Shrubsolea4062722022-05-02 17:46:07 +0200413TEST_P(VideoReceiveStream2Test, LazyDecoderCreation) {
Evan Shrubsole1c184772022-04-26 09:47:49 +0200414 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
415 RtpPacketToSend rtppacket(nullptr);
416 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
417 memcpy(payload, idr_nalu, sizeof(idr_nalu));
418 rtppacket.SetMarker(true);
419 rtppacket.SetSsrc(1111);
420 // H265 payload type.
421 rtppacket.SetPayloadType(99);
422 rtppacket.SetSequenceNumber(1);
423 rtppacket.SetTimestamp(0);
424
425 // Only 1 decoder is created by default. It will be H265 since that was the
426 // first in the decoder list.
427 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
428 EXPECT_CALL(mock_h264_decoder_factory_,
429 CreateVideoDecoder(
430 testing::Field(&SdpVideoFormat::name, testing::Eq("H265"))))
431 .Times(1);
432 video_receive_stream_->Start();
433
434 EXPECT_TRUE(
435 testing::Mock::VerifyAndClearExpectations(&mock_h264_decoder_factory_));
436
437 EXPECT_CALL(mock_h264_decoder_factory_,
438 CreateVideoDecoder(
439 testing::Field(&SdpVideoFormat::name, testing::Eq("H264"))))
440 .Times(1);
441 rtc::Event init_decode_event;
Evan Shrubsolea4062722022-05-02 17:46:07 +0200442 EXPECT_CALL(mock_decoder_, Configure).WillOnce(WithoutArgs([&] {
Evan Shrubsole1c184772022-04-26 09:47:49 +0200443 init_decode_event.Set();
444 return true;
445 }));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200446 EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback(_));
447 EXPECT_CALL(mock_decoder_, Decode(_, false, _));
Evan Shrubsole1c184772022-04-26 09:47:49 +0200448 RtpPacketReceived parsed_packet;
449 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
450 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
Evan Shrubsolea4062722022-05-02 17:46:07 +0200451 EXPECT_CALL(mock_decoder_, Release());
Evan Shrubsole1c184772022-04-26 09:47:49 +0200452
453 // Make sure the decoder thread had a chance to run.
Evan Shrubsole44be5792022-04-26 16:24:41 +0200454 init_decode_event.Wait(kDefaultTimeOut.ms());
Evan Shrubsole1c184772022-04-26 09:47:49 +0200455}
456
Evan Shrubsolea4062722022-05-02 17:46:07 +0200457TEST_P(VideoReceiveStream2Test, PassesNtpTime) {
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200458 const Timestamp kNtpTimestamp = Timestamp::Millis(12345);
459 std::unique_ptr<test::FakeEncodedFrame> test_frame =
460 test::FakeFrameBuilder()
461 .Id(0)
462 .PayloadType(99)
463 .NtpTime(kNtpTimestamp)
464 .AsLast()
465 .Build();
Tommiae4d0972020-05-18 08:45:38 +0200466
467 video_receive_stream_->Start();
468 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200469 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200470 RenderedFrameWith(NtpTimestamp(kNtpTimestamp)));
Tommiae4d0972020-05-18 08:45:38 +0200471}
472
Evan Shrubsolea4062722022-05-02 17:46:07 +0200473TEST_P(VideoReceiveStream2Test, PassesRotation) {
Tommiae4d0972020-05-18 08:45:38 +0200474 const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200475 std::unique_ptr<test::FakeEncodedFrame> test_frame = test::FakeFrameBuilder()
476 .Id(0)
477 .PayloadType(99)
478 .Rotation(kRotation)
479 .AsLast()
480 .Build();
Tommiae4d0972020-05-18 08:45:38 +0200481
482 video_receive_stream_->Start();
483 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200484 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200485 RenderedFrameWith(Rotation(kRotation)));
Tommiae4d0972020-05-18 08:45:38 +0200486}
487
Evan Shrubsolea4062722022-05-02 17:46:07 +0200488TEST_P(VideoReceiveStream2Test, PassesPacketInfos) {
Tommiae4d0972020-05-18 08:45:38 +0200489 RtpPacketInfos packet_infos = CreatePacketInfos(3);
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200490 auto test_frame = test::FakeFrameBuilder()
491 .Id(0)
492 .PayloadType(99)
493 .PacketInfos(packet_infos)
494 .AsLast()
495 .Build();
Tommiae4d0972020-05-18 08:45:38 +0200496
497 video_receive_stream_->Start();
498 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200499 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200500 RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos))));
Tommiae4d0972020-05-18 08:45:38 +0200501}
502
Evan Shrubsolea4062722022-05-02 17:46:07 +0200503TEST_P(VideoReceiveStream2Test, RenderedFrameUpdatesGetSources) {
Tommiae4d0972020-05-18 08:45:38 +0200504 constexpr uint32_t kSsrc = 1111;
505 constexpr uint32_t kCsrc = 9001;
506 constexpr uint32_t kRtpTimestamp = 12345;
507
508 // Prepare one video frame with per-packet information.
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200509 auto test_frame =
510 test::FakeFrameBuilder().Id(0).PayloadType(99).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200511 RtpPacketInfos packet_infos;
512 {
513 RtpPacketInfos::vector_type infos;
514
515 RtpPacketInfo info;
516 info.set_ssrc(kSsrc);
517 info.set_csrcs({kCsrc});
518 info.set_rtp_timestamp(kRtpTimestamp);
519
Johannes Kronf7de74c2021-04-30 13:10:56 +0200520 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
Tommiae4d0972020-05-18 08:45:38 +0200521 infos.push_back(info);
522
Johannes Kronf7de74c2021-04-30 13:10:56 +0200523 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
Tommiae4d0972020-05-18 08:45:38 +0200524 infos.push_back(info);
525
Johannes Kronf7de74c2021-04-30 13:10:56 +0200526 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
Tommiae4d0972020-05-18 08:45:38 +0200527 infos.push_back(info);
528
Johannes Kronf7de74c2021-04-30 13:10:56 +0200529 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(1000));
Tommiae4d0972020-05-18 08:45:38 +0200530 infos.push_back(info);
531
532 packet_infos = RtpPacketInfos(std::move(infos));
533 }
534 test_frame->SetPacketInfos(packet_infos);
535
536 // Start receive stream.
537 video_receive_stream_->Start();
538 EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
539
540 // Render one video frame.
541 int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
542 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Tommiae4d0972020-05-18 08:45:38 +0200543 // Verify that the per-packet information is passed to the renderer.
Evan Shrubsolea4062722022-05-02 17:46:07 +0200544 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut),
Evan Shrubsole44be5792022-04-26 16:24:41 +0200545 RenderedFrameWith(PacketInfos(ElementsAreArray(packet_infos))));
546 int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
Tommiae4d0972020-05-18 08:45:38 +0200547
Artem Titovab30d722021-07-27 16:22:11 +0200548 // Verify that the per-packet information also updates `GetSources()`.
Tommiae4d0972020-05-18 08:45:38 +0200549 std::vector<RtpSource> sources = video_receive_stream_->GetSources();
550 ASSERT_THAT(sources, SizeIs(2));
551 {
552 auto it = std::find_if(sources.begin(), sources.end(),
553 [](const RtpSource& source) {
554 return source.source_type() == RtpSourceType::SSRC;
555 });
556 ASSERT_NE(it, sources.end());
557
558 EXPECT_EQ(it->source_id(), kSsrc);
559 EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
560 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
561 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
562 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
563 }
564 {
565 auto it = std::find_if(sources.begin(), sources.end(),
566 [](const RtpSource& source) {
567 return source.source_type() == RtpSourceType::CSRC;
568 });
569 ASSERT_NE(it, sources.end());
570
571 EXPECT_EQ(it->source_id(), kCsrc);
572 EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
573 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
574 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
575 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
576 }
577}
578
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200579std::unique_ptr<test::FakeEncodedFrame> MakeFrameWithResolution(
Markus Handell588f9b32021-04-08 19:19:50 +0200580 VideoFrameType frame_type,
581 int picture_id,
582 int width,
583 int height) {
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200584 auto frame =
585 test::FakeFrameBuilder().Id(picture_id).PayloadType(99).AsLast().Build();
Tommiae4d0972020-05-18 08:45:38 +0200586 frame->SetFrameType(frame_type);
Markus Handell588f9b32021-04-08 19:19:50 +0200587 frame->_encodedWidth = width;
588 frame->_encodedHeight = height;
Tommiae4d0972020-05-18 08:45:38 +0200589 return frame;
590}
591
Evan Shrubsolea0ee64c2022-04-26 10:09:04 +0200592std::unique_ptr<test::FakeEncodedFrame> MakeFrame(VideoFrameType frame_type,
593 int picture_id) {
Markus Handell588f9b32021-04-08 19:19:50 +0200594 return MakeFrameWithResolution(frame_type, picture_id, 320, 240);
595}
596
Evan Shrubsolea4062722022-05-02 17:46:07 +0200597TEST_P(VideoReceiveStream2Test, PassesFrameWhenEncodedFramesCallbackSet) {
Tommiae4d0972020-05-18 08:45:38 +0200598 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
599 video_receive_stream_->Start();
600 // Expect a keyframe request to be generated
601 EXPECT_CALL(mock_transport_, SendRtcp);
602 EXPECT_CALL(callback, Call);
603 video_receive_stream_->SetAndGetRecordingState(
Tommif6f45432022-05-20 15:21:20 +0200604 VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
605 true);
Tommiae4d0972020-05-18 08:45:38 +0200606 video_receive_stream_->OnCompleteFrame(
607 MakeFrame(VideoFrameType::kVideoFrameKey, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200608 EXPECT_TRUE(fake_renderer_.WaitForFrame(kDefaultTimeOut));
Tommiae4d0972020-05-18 08:45:38 +0200609 video_receive_stream_->Stop();
610}
611
Evan Shrubsolea4062722022-05-02 17:46:07 +0200612TEST_P(VideoReceiveStream2Test, MovesEncodedFrameDispatchStateWhenReCreating) {
Tommiae4d0972020-05-18 08:45:38 +0200613 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
614 video_receive_stream_->Start();
615 // Expect a key frame request over RTCP.
616 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
617 video_receive_stream_->SetAndGetRecordingState(
Tommif6f45432022-05-20 15:21:20 +0200618 VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
619 true);
Tommiae4d0972020-05-18 08:45:38 +0200620 video_receive_stream_->Stop();
Tommif6f45432022-05-20 15:21:20 +0200621 VideoReceiveStreamInterface::RecordingState old_state =
Tommiae4d0972020-05-18 08:45:38 +0200622 video_receive_stream_->SetAndGetRecordingState(
Tommif6f45432022-05-20 15:21:20 +0200623 VideoReceiveStreamInterface::RecordingState(), false);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200624 RecreateReceiveStream(std::move(old_state));
Tommiae4d0972020-05-18 08:45:38 +0200625 video_receive_stream_->Stop();
626}
627
Evan Shrubsolea4062722022-05-02 17:46:07 +0200628TEST_P(VideoReceiveStream2Test, RequestsKeyFramesUntilKeyFrameReceived) {
Evan Shrubsole44be5792022-04-26 16:24:41 +0200629 // Recreate receive stream with shorter delay to test rtx.
630 TimeDelta rtx_delay = TimeDelta::Millis(50);
631 config_.rtp.nack.rtp_history_ms = rtx_delay.ms();
632 auto tick = rtx_delay / 2;
633 RecreateReceiveStream();
634 video_receive_stream_->Start();
Markus Handell588f9b32021-04-08 19:19:50 +0200635
Evan Shrubsole44be5792022-04-26 16:24:41 +0200636 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(testing::Return(0));
637 video_receive_stream_->GenerateKeyFrame();
638 video_receive_stream_->OnCompleteFrame(
639 MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200640 fake_renderer_.WaitForFrame(kDefaultTimeOut);
Tommiae4d0972020-05-18 08:45:38 +0200641 time_controller_.AdvanceTime(tick);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100642 loop_.Flush();
Evan Shrubsole44be5792022-04-26 16:24:41 +0200643 video_receive_stream_->OnCompleteFrame(
644 MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200645 fake_renderer_.WaitForFrame(kDefaultTimeOut);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200646 time_controller_.AdvanceTime(TimeDelta::Zero());
Tommiae4d0972020-05-18 08:45:38 +0200647 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
648
Philipp Hancke006206d2021-03-24 17:49:02 +0100649 // T+keyframetimeout: still no key frame received, expect key frame request
650 // sent again.
Evan Shrubsole44be5792022-04-26 16:24:41 +0200651 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(testing::Return(0));
Tommiae4d0972020-05-18 08:45:38 +0200652 time_controller_.AdvanceTime(tick);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200653 video_receive_stream_->OnCompleteFrame(
654 MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200655 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200656 loop_.Flush();
Tommiae4d0972020-05-18 08:45:38 +0200657 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
658
Philipp Hancke006206d2021-03-24 17:49:02 +0100659 // T+keyframetimeout: now send a key frame - we should not observe new key
660 // frame requests after this.
Tommiae4d0972020-05-18 08:45:38 +0200661 EXPECT_CALL(mock_transport_, SendRtcp).Times(0);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200662 video_receive_stream_->OnCompleteFrame(
663 MakeFrame(VideoFrameType::kVideoFrameKey, 3));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200664 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Tommiae4d0972020-05-18 08:45:38 +0200665 time_controller_.AdvanceTime(2 * tick);
Evan Shrubsole44be5792022-04-26 16:24:41 +0200666 video_receive_stream_->OnCompleteFrame(
667 MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200668 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200669 loop_.Flush();
Tommiae4d0972020-05-18 08:45:38 +0200670}
671
Evan Shrubsolea4062722022-05-02 17:46:07 +0200672TEST_P(VideoReceiveStream2Test,
Markus Handell588f9b32021-04-08 19:19:50 +0200673 DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution) {
Evan Shrubsole44be5792022-04-26 16:24:41 +0200674 video_receive_stream_->Start();
Markus Handell588f9b32021-04-08 19:19:50 +0200675 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200676 video_receive_stream_->SetAndGetRecordingState(
Tommif6f45432022-05-20 15:21:20 +0200677 VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
Markus Handell588f9b32021-04-08 19:19:50 +0200678 /*generate_key_frame=*/false);
679
680 InSequence s;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200681 EXPECT_CALL(callback, Call(Resolution(test::FakeDecoder::kDefaultWidth,
682 test::FakeDecoder::kDefaultHeight)));
Markus Handell588f9b32021-04-08 19:19:50 +0200683 EXPECT_CALL(callback, Call);
684
Evan Shrubsole44be5792022-04-26 16:24:41 +0200685 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200686 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 0, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200687 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200688 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200689 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200690 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Markus Handell588f9b32021-04-08 19:19:50 +0200691
Evan Shrubsole44be5792022-04-26 16:24:41 +0200692 video_receive_stream_->Stop();
Markus Handell588f9b32021-04-08 19:19:50 +0200693}
694
Evan Shrubsolea4062722022-05-02 17:46:07 +0200695TEST_P(VideoReceiveStream2Test,
Markus Handell588f9b32021-04-08 19:19:50 +0200696 DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution) {
Evan Shrubsole44be5792022-04-26 16:24:41 +0200697 video_receive_stream_->Start();
Markus Handell588f9b32021-04-08 19:19:50 +0200698 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200699 video_receive_stream_->SetAndGetRecordingState(
Tommif6f45432022-05-20 15:21:20 +0200700 VideoReceiveStreamInterface::RecordingState(callback.AsStdFunction()),
Markus Handell588f9b32021-04-08 19:19:50 +0200701 /*generate_key_frame=*/false);
702
703 InSequence s;
Evan Shrubsole44be5792022-04-26 16:24:41 +0200704 EXPECT_CALL(callback, Call(Resolution(1080u, 720u)));
Markus Handell588f9b32021-04-08 19:19:50 +0200705 EXPECT_CALL(callback, Call);
706
Evan Shrubsole44be5792022-04-26 16:24:41 +0200707 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200708 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 1080, 720));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200709 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Evan Shrubsole44be5792022-04-26 16:24:41 +0200710 video_receive_stream_->OnCompleteFrame(
Markus Handell588f9b32021-04-08 19:19:50 +0200711 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
Evan Shrubsolea4062722022-05-02 17:46:07 +0200712 EXPECT_THAT(fake_renderer_.WaitForFrame(kDefaultTimeOut), RenderedFrame());
Markus Handell588f9b32021-04-08 19:19:50 +0200713
Evan Shrubsole44be5792022-04-26 16:24:41 +0200714 video_receive_stream_->Stop();
Markus Handell588f9b32021-04-08 19:19:50 +0200715}
716
Evan Shrubsolea4062722022-05-02 17:46:07 +0200717TEST_P(VideoReceiveStream2Test, DependantFramesAreScheduled) {
718 video_receive_stream_->Start();
719
720 auto key_frame = test::FakeFrameBuilder()
721 .Id(0)
722 .PayloadType(99)
723 .Time(kFirstRtpTimestamp)
724 .ReceivedTime(kStartTime)
725 .AsLast()
726 .Build();
727 auto delta_frame = test::FakeFrameBuilder()
728 .Id(1)
729 .PayloadType(99)
730 .Time(RtpTimestampForFrame(1))
731 .ReceivedTime(ReceiveTimeForFrame(1))
732 .Refs({0})
733 .AsLast()
734 .Build();
735
736 // Expect frames are decoded in order.
737 InSequence seq;
738 EXPECT_CALL(mock_decoder_,
739 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _));
740 EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kFirstRtpTimestamp +
741 k30FpsRtpTimestampDelta),
742 _, _))
743 .Times(1);
744 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
745 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
746
747 time_controller_.AdvanceTime(k30FpsDelay);
748 video_receive_stream_->OnCompleteFrame(std::move(delta_frame));
749 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
750
751 video_receive_stream_->Stop();
752}
753
754TEST_P(VideoReceiveStream2Test, FramesScheduledInOrder) {
755 video_receive_stream_->Start();
756
757 auto key_frame = test::FakeFrameBuilder()
758 .Id(0)
759 .PayloadType(99)
760 .Time(kFirstRtpTimestamp)
761 .AsLast()
762 .Build();
763 auto delta_frame1 = test::FakeFrameBuilder()
764 .Id(1)
765 .PayloadType(99)
766 .Time(RtpTimestampForFrame(1))
767 .Refs({0})
768 .AsLast()
769 .Build();
770 auto delta_frame2 = test::FakeFrameBuilder()
771 .Id(2)
772 .PayloadType(99)
773 .Time(RtpTimestampForFrame(2))
774 .Refs({1})
775 .AsLast()
776 .Build();
777
778 // Expect frames are decoded in order despite delta_frame1 arriving first.
779 InSequence seq;
780 EXPECT_CALL(mock_decoder_,
781 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
782 .Times(1);
783 EXPECT_CALL(mock_decoder_,
784 Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
785 .Times(1);
786 EXPECT_CALL(mock_decoder_,
787 Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
788 .Times(1);
789 key_frame->SetReceivedTime(clock_->CurrentTime().ms());
790 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
791 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
792
793 delta_frame2->SetReceivedTime(clock_->CurrentTime().ms());
794 video_receive_stream_->OnCompleteFrame(std::move(delta_frame2));
795 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), DidNotReceiveFrame());
796 // `delta_frame1` arrives late.
797 delta_frame1->SetReceivedTime(clock_->CurrentTime().ms());
798 video_receive_stream_->OnCompleteFrame(std::move(delta_frame1));
799 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
800 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay * 2), RenderedFrame());
801 video_receive_stream_->Stop();
802}
803
804TEST_P(VideoReceiveStream2Test, WaitsforAllSpatialLayers) {
805 video_receive_stream_->Start();
806 auto sl0 = test::FakeFrameBuilder()
807 .Id(0)
808 .PayloadType(99)
809 .Time(kFirstRtpTimestamp)
810 .ReceivedTime(kStartTime)
811 .Build();
812 auto sl1 = test::FakeFrameBuilder()
813 .Id(1)
814 .PayloadType(99)
815 .ReceivedTime(kStartTime)
816 .Time(kFirstRtpTimestamp)
817 .Refs({0})
818 .Build();
819 auto sl2 = test::FakeFrameBuilder()
820 .Id(2)
821 .PayloadType(99)
822 .ReceivedTime(kStartTime)
823 .Time(kFirstRtpTimestamp)
824 .Refs({0, 1})
825 .AsLast()
826 .Build();
827
828 // No decodes should be called until `sl2` is received.
829 EXPECT_CALL(mock_decoder_, Decode).Times(0);
830 sl0->SetReceivedTime(clock_->CurrentTime().ms());
831 video_receive_stream_->OnCompleteFrame(std::move(sl0));
832 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
833 DidNotReceiveFrame());
834 video_receive_stream_->OnCompleteFrame(std::move(sl1));
835 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()),
836 DidNotReceiveFrame());
837 // When `sl2` arrives decode should happen.
838 EXPECT_CALL(mock_decoder_,
839 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
840 .Times(1);
841 video_receive_stream_->OnCompleteFrame(std::move(sl2));
842 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
843 video_receive_stream_->Stop();
844}
845
846TEST_P(VideoReceiveStream2Test, FramesFastForwardOnSystemHalt) {
847 video_receive_stream_->Start();
848
849 // The frame structure looks like this,
850 // F1
851 // /
852 // F0 --> F2
853 //
854 // In this case we will have a system halt simulated. By the time the system
855 // resumes, F1 will be old and so F2 should be decoded.
856 auto key_frame = test::FakeFrameBuilder()
857 .Id(0)
858 .PayloadType(99)
859 .Time(kFirstRtpTimestamp)
860 .AsLast()
861 .Build();
862 auto ffwd_frame = test::FakeFrameBuilder()
863 .Id(1)
864 .PayloadType(99)
865 .Time(RtpTimestampForFrame(1))
866 .Refs({0})
867 .AsLast()
868 .Build();
869 auto rendered_frame = test::FakeFrameBuilder()
870 .Id(2)
871 .PayloadType(99)
872 .Time(RtpTimestampForFrame(2))
873 .Refs({0})
874 .AsLast()
875 .Build();
876 InSequence seq;
877 EXPECT_CALL(mock_decoder_,
878 Decode(test::RtpTimestamp(kFirstRtpTimestamp), _, _))
879 .WillOnce(testing::DoAll(testing::Invoke([&] {
880 // System halt will be simulated in the decode.
881 time_controller_.AdvanceTime(k30FpsDelay * 2);
882 }),
883 DefaultDecodeAction()));
884 EXPECT_CALL(mock_decoder_,
885 Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _));
886 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
887 video_receive_stream_->OnCompleteFrame(std::move(ffwd_frame));
888 video_receive_stream_->OnCompleteFrame(std::move(rendered_frame));
889 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
890 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
891
892 // Check stats show correct dropped frames.
893 auto stats = video_receive_stream_->GetStats();
894 EXPECT_EQ(stats.frames_dropped, 1u);
895
896 video_receive_stream_->Stop();
897}
898
899TEST_P(VideoReceiveStream2Test, BetterFrameInsertedWhileWaitingToDecodeFrame) {
900 video_receive_stream_->Start();
901
902 auto key_frame = test::FakeFrameBuilder()
903 .Id(0)
904 .PayloadType(99)
905 .Time(kFirstRtpTimestamp)
906 .ReceivedTime(ReceiveTimeForFrame(0))
907 .AsLast()
908 .Build();
909 auto f1 = test::FakeFrameBuilder()
910 .Id(1)
911 .PayloadType(99)
912 .Time(RtpTimestampForFrame(1))
913 .ReceivedTime(ReceiveTimeForFrame(1))
914 .Refs({0})
915 .AsLast()
916 .Build();
917 auto f2 = test::FakeFrameBuilder()
918 .Id(2)
919 .PayloadType(99)
920 .Time(RtpTimestampForFrame(2))
921 .ReceivedTime(ReceiveTimeForFrame(2))
922 .Refs({0})
923 .AsLast()
924 .Build();
925
926 video_receive_stream_->OnCompleteFrame(std::move(key_frame));
927 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
928
929 InSequence seq;
930 EXPECT_CALL(mock_decoder_,
931 Decode(test::RtpTimestamp(RtpTimestampForFrame(1)), _, _))
932 .Times(1);
933 EXPECT_CALL(mock_decoder_,
934 Decode(test::RtpTimestamp(RtpTimestampForFrame(2)), _, _))
935 .Times(1);
936 // Simulate f1 arriving after f2 but before f2 is decoded.
937 video_receive_stream_->OnCompleteFrame(std::move(f2));
938 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), DidNotReceiveFrame());
939 video_receive_stream_->OnCompleteFrame(std::move(f1));
940 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
941 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
942
943 video_receive_stream_->Stop();
944}
945
946// Note: This test takes a long time (~10s) to run if the fake metronome is
947// active. Since the test needs to wait for the timestamp to rollover, it has a
948// fake delay of around 6.5 hours. Even though time is simulated, this will be
949// around 1,500,000 metronome tick invocations.
950TEST_P(VideoReceiveStream2Test, RtpTimestampWrapAround) {
951 video_receive_stream_->Start();
952
953 constexpr uint32_t kBaseRtp = std::numeric_limits<uint32_t>::max() / 2;
954 video_receive_stream_->OnCompleteFrame(
955 test::FakeFrameBuilder()
956 .Id(0)
957 .PayloadType(99)
958 .Time(kBaseRtp)
959 .ReceivedTime(clock_->CurrentTime())
960 .AsLast()
961 .Build());
962 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
963 time_controller_.AdvanceTime(k30FpsDelay);
964 video_receive_stream_->OnCompleteFrame(
965 test::FakeFrameBuilder()
966 .Id(1)
967 .PayloadType(99)
968 .Time(kBaseRtp + k30FpsRtpTimestampDelta)
969 .ReceivedTime(clock_->CurrentTime())
970 .AsLast()
971 .Build());
972 EXPECT_THAT(fake_renderer_.WaitForFrame(k30FpsDelay), RenderedFrame());
973
974 // Pause stream so that RTP timestamp wraps around.
975 constexpr uint32_t kLastRtp = kBaseRtp + k30FpsRtpTimestampDelta;
976 constexpr uint32_t kWrapAroundRtp =
977 kLastRtp + std::numeric_limits<uint32_t>::max() / 2 + 1;
978 // Pause for corresponding delay such that RTP timestamp would increase this
979 // much at 30fps.
980 constexpr TimeDelta kWrapAroundDelay =
981 (std::numeric_limits<uint32_t>::max() / 2 + 1) / kRtpTimestampHz;
982
983 time_controller_.AdvanceTime(kWrapAroundDelay);
984 video_receive_stream_->OnCompleteFrame(
985 test::FakeFrameBuilder()
986 .Id(2)
987 .PayloadType(99)
988 .Time(kWrapAroundRtp)
989 .ReceivedTime(clock_->CurrentTime())
990 .AsLast()
991 .Build());
992 EXPECT_CALL(mock_decoder_, Decode(test::RtpTimestamp(kWrapAroundRtp), _, _))
993 .Times(1);
994 EXPECT_THAT(fake_renderer_.WaitForFrame(TimeDelta::Zero()), RenderedFrame());
995
996 video_receive_stream_->Stop();
997}
998
999INSTANTIATE_TEST_SUITE_P(VideoReceiveStream2Test,
1000 VideoReceiveStream2Test,
1001 testing::Bool(),
1002 [](const auto& test_param_info) {
1003 rtc::StringBuilder ss;
1004 ss << (test_param_info.param
1005 ? "ScheduleDecodesWithMetronome"
1006 : "ScheduleDecodesWithPostTask");
1007 return ss.Release();
1008 });
1009
Tommiae4d0972020-05-18 08:45:38 +02001010} // namespace webrtc