blob: f3372b1c3e8c40edeb2b5b47ad1792dbcdc147a2 [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>
Markus Handell588f9b32021-04-08 19:19:50 +020014#include <limits>
Tommiae4d0972020-05-18 08:45:38 +020015#include <memory>
16#include <utility>
17#include <vector>
18
19#include "api/task_queue/default_task_queue_factory.h"
20#include "api/test/video/function_video_decoder_factory.h"
Markus Handell588f9b32021-04-08 19:19:50 +020021#include "api/video/video_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020022#include "api/video_codecs/video_decoder.h"
23#include "call/rtp_stream_receiver_controller.h"
24#include "common_video/test/utilities.h"
25#include "media/base/fake_video_renderer.h"
Tommi90738dd2021-05-31 17:36:47 +020026#include "media/engine/fake_webrtc_call.h"
Tommiae4d0972020-05-18 08:45:38 +020027#include "modules/pacing/packet_router.h"
28#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
29#include "modules/utility/include/process_thread.h"
30#include "modules/video_coding/encoded_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020031#include "rtc_base/event.h"
32#include "system_wrappers/include/clock.h"
33#include "test/fake_decoder.h"
34#include "test/field_trial.h"
35#include "test/gmock.h"
36#include "test/gtest.h"
37#include "test/run_loop.h"
38#include "test/time_controller/simulated_time_controller.h"
39#include "test/video_decoder_proxy_factory.h"
40#include "video/call_stats2.h"
41
42namespace webrtc {
43namespace {
44
45using ::testing::_;
Markus Handell588f9b32021-04-08 19:19:50 +020046using ::testing::AllOf;
Tommiae4d0972020-05-18 08:45:38 +020047using ::testing::ElementsAreArray;
Markus Handell588f9b32021-04-08 19:19:50 +020048using ::testing::Field;
49using ::testing::InSequence;
Tommiae4d0972020-05-18 08:45:38 +020050using ::testing::Invoke;
51using ::testing::IsEmpty;
Markus Handell588f9b32021-04-08 19:19:50 +020052using ::testing::Property;
Tommiae4d0972020-05-18 08:45:38 +020053using ::testing::SizeIs;
54
55constexpr int kDefaultTimeOutMs = 50;
56
57class MockTransport : public Transport {
58 public:
59 MOCK_METHOD(bool,
60 SendRtp,
61 (const uint8_t*, size_t length, const PacketOptions& options),
62 (override));
63 MOCK_METHOD(bool, SendRtcp, (const uint8_t*, size_t length), (override));
64};
65
66class MockVideoDecoder : public VideoDecoder {
67 public:
68 MOCK_METHOD(int32_t,
69 InitDecode,
70 (const VideoCodec*, int32_t number_of_cores),
71 (override));
72 MOCK_METHOD(int32_t,
73 Decode,
74 (const EncodedImage& input,
75 bool missing_frames,
76 int64_t render_time_ms),
77 (override));
78 MOCK_METHOD(int32_t,
79 RegisterDecodeCompleteCallback,
80 (DecodedImageCallback*),
81 (override));
82 MOCK_METHOD(int32_t, Release, (), (override));
83 const char* ImplementationName() const { return "MockVideoDecoder"; }
84};
85
Johannes Kron16359f62021-02-18 23:37:22 +010086class MockVideoDecoderFactory : public VideoDecoderFactory {
87 public:
88 MOCK_CONST_METHOD0(GetSupportedFormats, std::vector<SdpVideoFormat>());
89
90 MOCK_METHOD1(CreateVideoDecoder,
91 std::unique_ptr<VideoDecoder>(const SdpVideoFormat& format));
92};
93
philipelca188092021-03-23 12:00:49 +010094class FrameObjectFake : public EncodedFrame {
Tommiae4d0972020-05-18 08:45:38 +020095 public:
96 void SetPayloadType(uint8_t payload_type) { _payloadType = payload_type; }
97
98 void SetRotation(const VideoRotation& rotation) { rotation_ = rotation; }
99
100 void SetNtpTime(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; }
101
102 int64_t ReceivedTime() const override { return 0; }
103
104 int64_t RenderTime() const override { return _renderTimeMs; }
105};
106
107} // namespace
108
109class VideoReceiveStream2Test : public ::testing::Test {
110 public:
111 VideoReceiveStream2Test()
112 : process_thread_(ProcessThread::Create("TestThread")),
113 task_queue_factory_(CreateDefaultTaskQueueFactory()),
114 config_(&mock_transport_),
115 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()),
philipel668b0532020-07-23 13:13:40 +0200116 h264_decoder_factory_(&mock_h264_video_decoder_) {}
Tommi90738dd2021-05-31 17:36:47 +0200117 ~VideoReceiveStream2Test() override {
118 if (video_receive_stream_)
119 video_receive_stream_->UnregisterFromTransport();
120 }
Tommiae4d0972020-05-18 08:45:38 +0200121
Tommi90738dd2021-05-31 17:36:47 +0200122 void SetUp() override {
Tommiae4d0972020-05-18 08:45:38 +0200123 constexpr int kDefaultNumCpuCores = 2;
124 config_.rtp.remote_ssrc = 1111;
125 config_.rtp.local_ssrc = 2222;
126 config_.renderer = &fake_renderer_;
Philip Eliasson2b068ce2020-08-03 15:55:10 +0000127 config_.decoder_factory = &h264_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200128 VideoReceiveStream::Decoder h264_decoder;
129 h264_decoder.payload_type = 99;
130 h264_decoder.video_format = SdpVideoFormat("H264");
131 h264_decoder.video_format.parameters.insert(
132 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
Johannes Kron16359f62021-02-18 23:37:22 +0100133 config_.decoders.clear();
Tommiae4d0972020-05-18 08:45:38 +0200134 config_.decoders.push_back(h264_decoder);
Tommiae4d0972020-05-18 08:45:38 +0200135
136 clock_ = Clock::GetRealTimeClock();
137 timing_ = new VCMTiming(clock_);
138
139 video_receive_stream_ =
140 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Tommi90738dd2021-05-31 17:36:47 +0200141 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
Tommiae4d0972020-05-18 08:45:38 +0200142 &packet_router_, config_.Copy(), process_thread_.get(),
143 &call_stats_, clock_, timing_);
Tommi90738dd2021-05-31 17:36:47 +0200144 video_receive_stream_->RegisterWithTransport(
145 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200146 }
147
148 protected:
149 test::RunLoop loop_;
150 std::unique_ptr<ProcessThread> process_thread_;
151 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
152 VideoReceiveStream::Config config_;
153 internal::CallStats call_stats_;
154 MockVideoDecoder mock_h264_video_decoder_;
Tommiae4d0972020-05-18 08:45:38 +0200155 test::VideoDecoderProxyFactory h264_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200156 cricket::FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200157 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200158 MockTransport mock_transport_;
159 PacketRouter packet_router_;
160 RtpStreamReceiverController rtp_stream_receiver_controller_;
161 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
162 Clock* clock_;
163 VCMTiming* timing_;
164};
165
166TEST_F(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) {
167 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
168 RtpPacketToSend rtppacket(nullptr);
169 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
170 memcpy(payload, idr_nalu, sizeof(idr_nalu));
171 rtppacket.SetMarker(true);
172 rtppacket.SetSsrc(1111);
173 rtppacket.SetPayloadType(99);
174 rtppacket.SetSequenceNumber(1);
175 rtppacket.SetTimestamp(0);
176 rtc::Event init_decode_event_;
177 EXPECT_CALL(mock_h264_video_decoder_, InitDecode(_, _))
178 .WillOnce(Invoke([&init_decode_event_](const VideoCodec* config,
179 int32_t number_of_cores) {
180 init_decode_event_.Set();
181 return 0;
182 }));
183 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
184 video_receive_stream_->Start();
185 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
186 RtpPacketReceived parsed_packet;
187 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
188 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
189 EXPECT_CALL(mock_h264_video_decoder_, Release());
190 // Make sure the decoder thread had a chance to run.
191 init_decode_event_.Wait(kDefaultTimeOutMs);
192}
193
194TEST_F(VideoReceiveStream2Test, PlayoutDelay) {
Niels Möllerd381eed2020-09-02 15:34:40 +0200195 const VideoPlayoutDelay kPlayoutDelayMs = {123, 321};
Tommiae4d0972020-05-18 08:45:38 +0200196 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100197 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200198 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
199
200 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
201 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
202 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
203
204 // Check that the biggest minimum delay is chosen.
205 video_receive_stream_->SetMinimumPlayoutDelay(400);
206 EXPECT_EQ(400, timing_->min_playout_delay());
207
208 // Check base minimum delay validation.
209 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
210 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
211 EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
212 EXPECT_EQ(500, timing_->min_playout_delay());
213
214 // Check that intermidiate values are remembered and the biggest remembered
215 // is chosen.
216 video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
217 EXPECT_EQ(400, timing_->min_playout_delay());
218
219 video_receive_stream_->SetMinimumPlayoutDelay(0);
220 EXPECT_EQ(123, timing_->min_playout_delay());
221}
222
223TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
224 const int default_max_playout_latency = timing_->max_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200225 const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
Tommiae4d0972020-05-18 08:45:38 +0200226
227 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100228 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200229 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
230
231 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
232
233 // Ensure that -1 preserves default maximum value from |timing_|.
234 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
235 EXPECT_NE(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
236 EXPECT_EQ(default_max_playout_latency, timing_->max_playout_delay());
237}
238
239TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
240 const int default_min_playout_latency = timing_->min_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200241 const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
Tommiae4d0972020-05-18 08:45:38 +0200242
243 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100244 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200245 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
246
247 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
248
249 // Ensure that -1 preserves default minimum value from |timing_|.
250 EXPECT_NE(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
251 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
252 EXPECT_EQ(default_min_playout_latency, timing_->min_playout_delay());
253}
254
Johannes Kron111e9812020-10-26 13:54:40 +0100255TEST_F(VideoReceiveStream2Test, MaxCompositionDelayNotSetByDefault) {
256 // Default with no playout delay set.
257 std::unique_ptr<FrameObjectFake> test_frame0(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100258 test_frame0->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100259 video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
260 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
261
262 // Max composition delay not set for playout delay 0,0.
263 std::unique_ptr<FrameObjectFake> test_frame1(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100264 test_frame1->SetId(1);
Johannes Kron111e9812020-10-26 13:54:40 +0100265 test_frame1->SetPlayoutDelay({0, 0});
266 video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
267 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
268
269 // Max composition delay not set for playout delay X,Y, where X,Y>0.
270 std::unique_ptr<FrameObjectFake> test_frame2(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100271 test_frame2->SetId(2);
Johannes Kron111e9812020-10-26 13:54:40 +0100272 test_frame2->SetPlayoutDelay({10, 30});
273 video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
274 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
275}
276
277TEST_F(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) {
278 // Max composition delay set if playout delay X,Y, where X=0,Y>0.
279 const VideoPlayoutDelay kPlayoutDelayMs = {0, 50};
280 const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
281 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100282 test_frame->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100283 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
284 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
285 EXPECT_EQ(kExpectedMaxCompositionDelayInFrames,
286 timing_->MaxCompositionDelayInFrames());
287}
288
Tommiae4d0972020-05-18 08:45:38 +0200289class VideoReceiveStream2TestWithFakeDecoder : public ::testing::Test {
290 public:
291 VideoReceiveStream2TestWithFakeDecoder()
292 : fake_decoder_factory_(
293 []() { return std::make_unique<test::FakeDecoder>(); }),
294 process_thread_(ProcessThread::Create("TestThread")),
295 task_queue_factory_(CreateDefaultTaskQueueFactory()),
296 config_(&mock_transport_),
297 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
Tommi90738dd2021-05-31 17:36:47 +0200298 ~VideoReceiveStream2TestWithFakeDecoder() override {
299 if (video_receive_stream_)
300 video_receive_stream_->UnregisterFromTransport();
301 }
Tommiae4d0972020-05-18 08:45:38 +0200302
Tommi90738dd2021-05-31 17:36:47 +0200303 void SetUp() override {
Tommiae4d0972020-05-18 08:45:38 +0200304 config_.rtp.remote_ssrc = 1111;
305 config_.rtp.local_ssrc = 2222;
306 config_.renderer = &fake_renderer_;
Philip Eliasson2b068ce2020-08-03 15:55:10 +0000307 config_.decoder_factory = &fake_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200308 VideoReceiveStream::Decoder fake_decoder;
309 fake_decoder.payload_type = 99;
310 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200311 config_.decoders.push_back(fake_decoder);
312 clock_ = Clock::GetRealTimeClock();
313 ReCreateReceiveStream(VideoReceiveStream::RecordingState());
314 }
315
316 void ReCreateReceiveStream(VideoReceiveStream::RecordingState state) {
317 constexpr int kDefaultNumCpuCores = 2;
Tommi90738dd2021-05-31 17:36:47 +0200318 if (video_receive_stream_) {
319 video_receive_stream_->UnregisterFromTransport();
320 video_receive_stream_ = nullptr;
321 }
Tommiae4d0972020-05-18 08:45:38 +0200322 timing_ = new VCMTiming(clock_);
323 video_receive_stream_.reset(new webrtc::internal::VideoReceiveStream2(
Tommi90738dd2021-05-31 17:36:47 +0200324 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
325 &packet_router_, config_.Copy(), process_thread_.get(), &call_stats_,
326 clock_, timing_));
327 video_receive_stream_->RegisterWithTransport(
328 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200329 video_receive_stream_->SetAndGetRecordingState(std::move(state), false);
330 }
331
332 protected:
333 test::RunLoop loop_;
334 test::FunctionVideoDecoderFactory fake_decoder_factory_;
335 std::unique_ptr<ProcessThread> process_thread_;
336 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
337 VideoReceiveStream::Config config_;
338 internal::CallStats call_stats_;
339 cricket::FakeVideoRenderer fake_renderer_;
340 MockTransport mock_transport_;
341 PacketRouter packet_router_;
342 RtpStreamReceiverController rtp_stream_receiver_controller_;
Tommi90738dd2021-05-31 17:36:47 +0200343 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200344 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
345 Clock* clock_;
346 VCMTiming* timing_;
347};
348
349TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesNtpTime) {
350 const int64_t kNtpTimestamp = 12345;
351 auto test_frame = std::make_unique<FrameObjectFake>();
352 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100353 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200354 test_frame->SetNtpTime(kNtpTimestamp);
355
356 video_receive_stream_->Start();
357 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
358 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
359 EXPECT_EQ(kNtpTimestamp, fake_renderer_.ntp_time_ms());
360}
361
362TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesRotation) {
363 const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
364 auto test_frame = std::make_unique<FrameObjectFake>();
365 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100366 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200367 test_frame->SetRotation(kRotation);
368
369 video_receive_stream_->Start();
370 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
371 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
372
373 EXPECT_EQ(kRotation, fake_renderer_.rotation());
374}
375
376TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesPacketInfos) {
377 auto test_frame = std::make_unique<FrameObjectFake>();
378 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100379 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200380 RtpPacketInfos packet_infos = CreatePacketInfos(3);
381 test_frame->SetPacketInfos(packet_infos);
382
383 video_receive_stream_->Start();
384 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
385 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
386
387 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
388}
389
390TEST_F(VideoReceiveStream2TestWithFakeDecoder, RenderedFrameUpdatesGetSources) {
391 constexpr uint32_t kSsrc = 1111;
392 constexpr uint32_t kCsrc = 9001;
393 constexpr uint32_t kRtpTimestamp = 12345;
394
395 // Prepare one video frame with per-packet information.
396 auto test_frame = std::make_unique<FrameObjectFake>();
397 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100398 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200399 RtpPacketInfos packet_infos;
400 {
401 RtpPacketInfos::vector_type infos;
402
403 RtpPacketInfo info;
404 info.set_ssrc(kSsrc);
405 info.set_csrcs({kCsrc});
406 info.set_rtp_timestamp(kRtpTimestamp);
407
Johannes Kronf7de74c2021-04-30 13:10:56 +0200408 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
Tommiae4d0972020-05-18 08:45:38 +0200409 infos.push_back(info);
410
Johannes Kronf7de74c2021-04-30 13:10:56 +0200411 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
Tommiae4d0972020-05-18 08:45:38 +0200412 infos.push_back(info);
413
Johannes Kronf7de74c2021-04-30 13:10:56 +0200414 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
Tommiae4d0972020-05-18 08:45:38 +0200415 infos.push_back(info);
416
Johannes Kronf7de74c2021-04-30 13:10:56 +0200417 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(1000));
Tommiae4d0972020-05-18 08:45:38 +0200418 infos.push_back(info);
419
420 packet_infos = RtpPacketInfos(std::move(infos));
421 }
422 test_frame->SetPacketInfos(packet_infos);
423
424 // Start receive stream.
425 video_receive_stream_->Start();
426 EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
427
428 // Render one video frame.
429 int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
430 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
431 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
432 int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
433
434 // Verify that the per-packet information is passed to the renderer.
435 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
436
437 // Verify that the per-packet information also updates |GetSources()|.
438 std::vector<RtpSource> sources = video_receive_stream_->GetSources();
439 ASSERT_THAT(sources, SizeIs(2));
440 {
441 auto it = std::find_if(sources.begin(), sources.end(),
442 [](const RtpSource& source) {
443 return source.source_type() == RtpSourceType::SSRC;
444 });
445 ASSERT_NE(it, sources.end());
446
447 EXPECT_EQ(it->source_id(), kSsrc);
448 EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
449 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
450 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
451 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
452 }
453 {
454 auto it = std::find_if(sources.begin(), sources.end(),
455 [](const RtpSource& source) {
456 return source.source_type() == RtpSourceType::CSRC;
457 });
458 ASSERT_NE(it, sources.end());
459
460 EXPECT_EQ(it->source_id(), kCsrc);
461 EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
462 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
463 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
464 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
465 }
466}
467
Markus Handell588f9b32021-04-08 19:19:50 +0200468std::unique_ptr<FrameObjectFake> MakeFrameWithResolution(
469 VideoFrameType frame_type,
470 int picture_id,
471 int width,
472 int height) {
Tommiae4d0972020-05-18 08:45:38 +0200473 auto frame = std::make_unique<FrameObjectFake>();
474 frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100475 frame->SetId(picture_id);
Tommiae4d0972020-05-18 08:45:38 +0200476 frame->SetFrameType(frame_type);
Markus Handell588f9b32021-04-08 19:19:50 +0200477 frame->_encodedWidth = width;
478 frame->_encodedHeight = height;
Tommiae4d0972020-05-18 08:45:38 +0200479 return frame;
480}
481
Markus Handell588f9b32021-04-08 19:19:50 +0200482std::unique_ptr<FrameObjectFake> MakeFrame(VideoFrameType frame_type,
483 int picture_id) {
484 return MakeFrameWithResolution(frame_type, picture_id, 320, 240);
485}
486
Tommiae4d0972020-05-18 08:45:38 +0200487TEST_F(VideoReceiveStream2TestWithFakeDecoder,
488 PassesFrameWhenEncodedFramesCallbackSet) {
489 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
490 video_receive_stream_->Start();
491 // Expect a keyframe request to be generated
492 EXPECT_CALL(mock_transport_, SendRtcp);
493 EXPECT_CALL(callback, Call);
494 video_receive_stream_->SetAndGetRecordingState(
495 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
496 video_receive_stream_->OnCompleteFrame(
497 MakeFrame(VideoFrameType::kVideoFrameKey, 0));
498 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
499 video_receive_stream_->Stop();
500}
501
502TEST_F(VideoReceiveStream2TestWithFakeDecoder,
503 MovesEncodedFrameDispatchStateWhenReCreating) {
504 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
505 video_receive_stream_->Start();
506 // Expect a key frame request over RTCP.
507 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
508 video_receive_stream_->SetAndGetRecordingState(
509 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
510 video_receive_stream_->Stop();
511 VideoReceiveStream::RecordingState old_state =
512 video_receive_stream_->SetAndGetRecordingState(
513 VideoReceiveStream::RecordingState(), false);
514 ReCreateReceiveStream(std::move(old_state));
515 video_receive_stream_->Stop();
516}
517
Philipp Hancke006206d2021-03-24 17:49:02 +0100518class VideoReceiveStream2TestWithSimulatedClock
519 : public ::testing::TestWithParam<int> {
Tommiae4d0972020-05-18 08:45:38 +0200520 public:
Markus Handell588f9b32021-04-08 19:19:50 +0200521 class FakeRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
522 public:
523 void SignalDoneAfterFrames(int num_frames_received) {
524 signal_after_frame_count_ = num_frames_received;
525 if (frame_count_ == signal_after_frame_count_)
526 event_.Set();
527 }
528
529 void OnFrame(const webrtc::VideoFrame& frame) override {
530 if (++frame_count_ == signal_after_frame_count_)
531 event_.Set();
532 }
533
534 void WaitUntilDone() { event_.Wait(rtc::Event::kForever); }
535
536 private:
537 int signal_after_frame_count_ = std::numeric_limits<int>::max();
538 int frame_count_ = 0;
539 rtc::Event event_;
540 };
541
Tommiae4d0972020-05-18 08:45:38 +0200542 class FakeDecoder2 : public test::FakeDecoder {
543 public:
544 explicit FakeDecoder2(std::function<void()> decode_callback)
545 : callback_(decode_callback) {}
546
547 int32_t Decode(const EncodedImage& input,
548 bool missing_frames,
549 int64_t render_time_ms) override {
550 int32_t result =
551 FakeDecoder::Decode(input, missing_frames, render_time_ms);
552 callback_();
553 return result;
554 }
555
556 private:
557 std::function<void()> callback_;
558 };
559
560 static VideoReceiveStream::Config GetConfig(
561 Transport* transport,
562 VideoDecoderFactory* decoder_factory,
563 rtc::VideoSinkInterface<webrtc::VideoFrame>* renderer) {
564 VideoReceiveStream::Config config(transport);
565 config.rtp.remote_ssrc = 1111;
566 config.rtp.local_ssrc = 2222;
Philipp Hancke006206d2021-03-24 17:49:02 +0100567 config.rtp.nack.rtp_history_ms = GetParam(); // rtx-time.
Tommiae4d0972020-05-18 08:45:38 +0200568 config.renderer = renderer;
Philip Eliasson2b068ce2020-08-03 15:55:10 +0000569 config.decoder_factory = decoder_factory;
Tommiae4d0972020-05-18 08:45:38 +0200570 VideoReceiveStream::Decoder fake_decoder;
571 fake_decoder.payload_type = 99;
572 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200573 config.decoders.push_back(fake_decoder);
574 return config;
575 }
576
577 VideoReceiveStream2TestWithSimulatedClock()
578 : time_controller_(Timestamp::Millis(4711)),
579 fake_decoder_factory_([this] {
580 return std::make_unique<FakeDecoder2>([this] { OnFrameDecoded(); });
581 }),
582 process_thread_(time_controller_.CreateProcessThread("ProcessThread")),
583 config_(GetConfig(&mock_transport_,
584 &fake_decoder_factory_,
585 &fake_renderer_)),
586 call_stats_(time_controller_.GetClock(), loop_.task_queue()),
587 video_receive_stream_(time_controller_.GetTaskQueueFactory(),
Tommi90738dd2021-05-31 17:36:47 +0200588 &fake_call_,
Tommiae4d0972020-05-18 08:45:38 +0200589 /*num_cores=*/2,
590 &packet_router_,
591 config_.Copy(),
592 process_thread_.get(),
593 &call_stats_,
594 time_controller_.GetClock(),
595 new VCMTiming(time_controller_.GetClock())) {
Tommi90738dd2021-05-31 17:36:47 +0200596 video_receive_stream_.RegisterWithTransport(
597 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200598 video_receive_stream_.Start();
599 }
600
Tommi90738dd2021-05-31 17:36:47 +0200601 ~VideoReceiveStream2TestWithSimulatedClock() override {
602 video_receive_stream_.UnregisterFromTransport();
603 }
604
Tommiae4d0972020-05-18 08:45:38 +0200605 void OnFrameDecoded() { event_->Set(); }
606
philipelca188092021-03-23 12:00:49 +0100607 void PassEncodedFrameAndWait(std::unique_ptr<EncodedFrame> frame) {
Tommiae4d0972020-05-18 08:45:38 +0200608 event_ = std::make_unique<rtc::Event>();
609 // This call will eventually end up in the Decoded method where the
610 // event is set.
611 video_receive_stream_.OnCompleteFrame(std::move(frame));
612 event_->Wait(rtc::Event::kForever);
613 }
614
615 protected:
616 GlobalSimulatedTimeController time_controller_;
617 test::RunLoop loop_;
618 test::FunctionVideoDecoderFactory fake_decoder_factory_;
619 std::unique_ptr<ProcessThread> process_thread_;
620 MockTransport mock_transport_;
Markus Handell588f9b32021-04-08 19:19:50 +0200621 FakeRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200622 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200623 VideoReceiveStream::Config config_;
624 internal::CallStats call_stats_;
625 PacketRouter packet_router_;
626 RtpStreamReceiverController rtp_stream_receiver_controller_;
627 webrtc::internal::VideoReceiveStream2 video_receive_stream_;
628 std::unique_ptr<rtc::Event> event_;
629};
630
Philipp Hancke006206d2021-03-24 17:49:02 +0100631TEST_P(VideoReceiveStream2TestWithSimulatedClock,
Tommiae4d0972020-05-18 08:45:38 +0200632 RequestsKeyFramesUntilKeyFrameReceived) {
Philipp Hancke006206d2021-03-24 17:49:02 +0100633 auto tick = TimeDelta::Millis(GetParam() / 2);
Tommiae4d0972020-05-18 08:45:38 +0200634 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(Invoke([this]() {
635 loop_.Quit();
636 return 0;
637 }));
638 video_receive_stream_.GenerateKeyFrame();
639 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
640 time_controller_.AdvanceTime(tick);
641 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
642 loop_.Run();
643 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
644
Philipp Hancke006206d2021-03-24 17:49:02 +0100645 // T+keyframetimeout: still no key frame received, expect key frame request
646 // sent again.
Tommiae4d0972020-05-18 08:45:38 +0200647 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(Invoke([this]() {
648 loop_.Quit();
649 return 0;
650 }));
651 time_controller_.AdvanceTime(tick);
652 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
653 loop_.Run();
654 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);
659 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameKey, 3));
660 time_controller_.AdvanceTime(2 * tick);
661 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
662 loop_.PostTask([this]() { loop_.Quit(); });
663 loop_.Run();
664}
665
Markus Handell588f9b32021-04-08 19:19:50 +0200666TEST_P(VideoReceiveStream2TestWithSimulatedClock,
667 DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution) {
668 video_receive_stream_.Start();
669 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
670 video_receive_stream_.SetAndGetRecordingState(
671 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
672 /*generate_key_frame=*/false);
673
674 InSequence s;
675 EXPECT_CALL(
676 callback,
677 Call(AllOf(
678 Property(&RecordableEncodedFrame::resolution,
679 Field(&RecordableEncodedFrame::EncodedResolution::width,
680 test::FakeDecoder::kDefaultWidth)),
681 Property(&RecordableEncodedFrame::resolution,
682 Field(&RecordableEncodedFrame::EncodedResolution::height,
683 test::FakeDecoder::kDefaultHeight)))));
684 EXPECT_CALL(callback, Call);
685
686 fake_renderer_.SignalDoneAfterFrames(2);
687 PassEncodedFrameAndWait(
688 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 0, 0));
689 PassEncodedFrameAndWait(
690 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
691 fake_renderer_.WaitUntilDone();
692
693 video_receive_stream_.Stop();
694}
695
696TEST_P(VideoReceiveStream2TestWithSimulatedClock,
697 DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution) {
698 video_receive_stream_.Start();
699 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
700 video_receive_stream_.SetAndGetRecordingState(
701 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
702 /*generate_key_frame=*/false);
703
704 InSequence s;
705 EXPECT_CALL(
706 callback,
707 Call(AllOf(
708 Property(
709 &RecordableEncodedFrame::resolution,
710 Field(&RecordableEncodedFrame::EncodedResolution::width, 1080)),
711 Property(&RecordableEncodedFrame::resolution,
712 Field(&RecordableEncodedFrame::EncodedResolution::height,
713 720)))));
714 EXPECT_CALL(callback, Call);
715
716 fake_renderer_.SignalDoneAfterFrames(2);
717 PassEncodedFrameAndWait(
718 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 1080, 720));
719 PassEncodedFrameAndWait(
720 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
721 fake_renderer_.WaitUntilDone();
722
723 video_receive_stream_.Stop();
724}
725
Philipp Hancke006206d2021-03-24 17:49:02 +0100726INSTANTIATE_TEST_SUITE_P(
727 RtxTime,
728 VideoReceiveStream2TestWithSimulatedClock,
729 ::testing::Values(internal::VideoReceiveStream2::kMaxWaitForKeyFrameMs,
730 50 /*ms*/));
731
Johannes Kron16359f62021-02-18 23:37:22 +0100732class VideoReceiveStream2TestWithLazyDecoderCreation : public ::testing::Test {
733 public:
734 VideoReceiveStream2TestWithLazyDecoderCreation()
735 : process_thread_(ProcessThread::Create("TestThread")),
736 task_queue_factory_(CreateDefaultTaskQueueFactory()),
737 config_(&mock_transport_),
738 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
739
Tommi90738dd2021-05-31 17:36:47 +0200740 ~VideoReceiveStream2TestWithLazyDecoderCreation() override {
741 video_receive_stream_->UnregisterFromTransport();
742 }
743
744 void SetUp() override {
Johannes Kron16359f62021-02-18 23:37:22 +0100745 webrtc::test::ScopedFieldTrials field_trials(
746 "WebRTC-PreStreamDecoders/max:0/");
747 constexpr int kDefaultNumCpuCores = 2;
748 config_.rtp.remote_ssrc = 1111;
749 config_.rtp.local_ssrc = 2222;
750 config_.renderer = &fake_renderer_;
751 config_.decoder_factory = &mock_h264_decoder_factory_;
752 VideoReceiveStream::Decoder h264_decoder;
753 h264_decoder.payload_type = 99;
754 h264_decoder.video_format = SdpVideoFormat("H264");
755 h264_decoder.video_format.parameters.insert(
756 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
757 config_.decoders.clear();
758 config_.decoders.push_back(h264_decoder);
759
760 clock_ = Clock::GetRealTimeClock();
761 timing_ = new VCMTiming(clock_);
762
763 video_receive_stream_ =
764 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Tommi90738dd2021-05-31 17:36:47 +0200765 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
Johannes Kron16359f62021-02-18 23:37:22 +0100766 &packet_router_, config_.Copy(), process_thread_.get(),
767 &call_stats_, clock_, timing_);
Tommi90738dd2021-05-31 17:36:47 +0200768 video_receive_stream_->RegisterWithTransport(
769 &rtp_stream_receiver_controller_);
Johannes Kron16359f62021-02-18 23:37:22 +0100770 }
771
772 protected:
773 test::RunLoop loop_;
774 std::unique_ptr<ProcessThread> process_thread_;
775 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
776 VideoReceiveStream::Config config_;
777 internal::CallStats call_stats_;
778 MockVideoDecoder mock_h264_video_decoder_;
779 MockVideoDecoderFactory mock_h264_decoder_factory_;
780 cricket::FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200781 cricket::FakeCall fake_call_;
Johannes Kron16359f62021-02-18 23:37:22 +0100782 MockTransport mock_transport_;
783 PacketRouter packet_router_;
784 RtpStreamReceiverController rtp_stream_receiver_controller_;
785 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
786 Clock* clock_;
787 VCMTiming* timing_;
788};
789
790TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation, LazyDecoderCreation) {
791 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
792 RtpPacketToSend rtppacket(nullptr);
793 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
794 memcpy(payload, idr_nalu, sizeof(idr_nalu));
795 rtppacket.SetMarker(true);
796 rtppacket.SetSsrc(1111);
797 rtppacket.SetPayloadType(99);
798 rtppacket.SetSequenceNumber(1);
799 rtppacket.SetTimestamp(0);
800
801 // No decoder is created here.
802 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
803 video_receive_stream_->Start();
804
805 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_))
806 .WillOnce(Invoke([this](const SdpVideoFormat& format) {
807 test::VideoDecoderProxyFactory h264_decoder_factory(
808 &mock_h264_video_decoder_);
809 return h264_decoder_factory.CreateVideoDecoder(format);
810 }));
811 rtc::Event init_decode_event_;
812 EXPECT_CALL(mock_h264_video_decoder_, InitDecode(_, _))
813 .WillOnce(Invoke([&init_decode_event_](const VideoCodec* config,
814 int32_t number_of_cores) {
815 init_decode_event_.Set();
816 return 0;
817 }));
818 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
819 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
820 RtpPacketReceived parsed_packet;
821 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
822 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
823 EXPECT_CALL(mock_h264_video_decoder_, Release());
824
825 // Make sure the decoder thread had a chance to run.
826 init_decode_event_.Wait(kDefaultTimeOutMs);
827}
828
829TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation,
830 DeregisterDecoderThatsNotCreated) {
831 // No decoder is created here.
832 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
833 video_receive_stream_->Start();
834 video_receive_stream_->Stop();
835}
836
Tommiae4d0972020-05-18 08:45:38 +0200837} // namespace webrtc