blob: f0916c1601e4398750599e05f5a60a991c6d40e5 [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>
14#include <memory>
15#include <utility>
16#include <vector>
17
18#include "api/task_queue/default_task_queue_factory.h"
19#include "api/test/video/function_video_decoder_factory.h"
20#include "api/video_codecs/video_decoder.h"
21#include "call/rtp_stream_receiver_controller.h"
22#include "common_video/test/utilities.h"
23#include "media/base/fake_video_renderer.h"
24#include "modules/pacing/packet_router.h"
25#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
26#include "modules/utility/include/process_thread.h"
27#include "modules/video_coding/encoded_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020028#include "rtc_base/event.h"
29#include "system_wrappers/include/clock.h"
30#include "test/fake_decoder.h"
31#include "test/field_trial.h"
32#include "test/gmock.h"
33#include "test/gtest.h"
34#include "test/run_loop.h"
35#include "test/time_controller/simulated_time_controller.h"
36#include "test/video_decoder_proxy_factory.h"
37#include "video/call_stats2.h"
38
39namespace webrtc {
40namespace {
41
42using ::testing::_;
43using ::testing::ElementsAreArray;
44using ::testing::Invoke;
45using ::testing::IsEmpty;
46using ::testing::SizeIs;
47
48constexpr int kDefaultTimeOutMs = 50;
49
50class MockTransport : public Transport {
51 public:
52 MOCK_METHOD(bool,
53 SendRtp,
54 (const uint8_t*, size_t length, const PacketOptions& options),
55 (override));
56 MOCK_METHOD(bool, SendRtcp, (const uint8_t*, size_t length), (override));
57};
58
59class MockVideoDecoder : public VideoDecoder {
60 public:
61 MOCK_METHOD(int32_t,
62 InitDecode,
63 (const VideoCodec*, int32_t number_of_cores),
64 (override));
65 MOCK_METHOD(int32_t,
66 Decode,
67 (const EncodedImage& input,
68 bool missing_frames,
69 int64_t render_time_ms),
70 (override));
71 MOCK_METHOD(int32_t,
72 RegisterDecodeCompleteCallback,
73 (DecodedImageCallback*),
74 (override));
75 MOCK_METHOD(int32_t, Release, (), (override));
76 const char* ImplementationName() const { return "MockVideoDecoder"; }
77};
78
Johannes Kron16359f62021-02-18 23:37:22 +010079class MockVideoDecoderFactory : public VideoDecoderFactory {
80 public:
81 MOCK_CONST_METHOD0(GetSupportedFormats, std::vector<SdpVideoFormat>());
82
83 MOCK_METHOD1(CreateVideoDecoder,
84 std::unique_ptr<VideoDecoder>(const SdpVideoFormat& format));
85};
86
philipelca188092021-03-23 12:00:49 +010087class FrameObjectFake : public EncodedFrame {
Tommiae4d0972020-05-18 08:45:38 +020088 public:
89 void SetPayloadType(uint8_t payload_type) { _payloadType = payload_type; }
90
91 void SetRotation(const VideoRotation& rotation) { rotation_ = rotation; }
92
93 void SetNtpTime(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; }
94
95 int64_t ReceivedTime() const override { return 0; }
96
97 int64_t RenderTime() const override { return _renderTimeMs; }
98};
99
100} // namespace
101
102class VideoReceiveStream2Test : public ::testing::Test {
103 public:
104 VideoReceiveStream2Test()
105 : process_thread_(ProcessThread::Create("TestThread")),
106 task_queue_factory_(CreateDefaultTaskQueueFactory()),
107 config_(&mock_transport_),
108 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()),
philipel668b0532020-07-23 13:13:40 +0200109 h264_decoder_factory_(&mock_h264_video_decoder_) {}
Tommiae4d0972020-05-18 08:45:38 +0200110
111 void SetUp() {
112 constexpr int kDefaultNumCpuCores = 2;
113 config_.rtp.remote_ssrc = 1111;
114 config_.rtp.local_ssrc = 2222;
115 config_.renderer = &fake_renderer_;
Philip Eliasson2b068ce2020-08-03 15:55:10 +0000116 config_.decoder_factory = &h264_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200117 VideoReceiveStream::Decoder h264_decoder;
118 h264_decoder.payload_type = 99;
119 h264_decoder.video_format = SdpVideoFormat("H264");
120 h264_decoder.video_format.parameters.insert(
121 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
Johannes Kron16359f62021-02-18 23:37:22 +0100122 config_.decoders.clear();
Tommiae4d0972020-05-18 08:45:38 +0200123 config_.decoders.push_back(h264_decoder);
Tommiae4d0972020-05-18 08:45:38 +0200124
125 clock_ = Clock::GetRealTimeClock();
126 timing_ = new VCMTiming(clock_);
127
128 video_receive_stream_ =
129 std::make_unique<webrtc::internal::VideoReceiveStream2>(
130 task_queue_factory_.get(), loop_.task_queue(),
131 &rtp_stream_receiver_controller_, kDefaultNumCpuCores,
132 &packet_router_, config_.Copy(), process_thread_.get(),
133 &call_stats_, clock_, timing_);
134 }
135
136 protected:
137 test::RunLoop loop_;
138 std::unique_ptr<ProcessThread> process_thread_;
139 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
140 VideoReceiveStream::Config config_;
141 internal::CallStats call_stats_;
142 MockVideoDecoder mock_h264_video_decoder_;
Tommiae4d0972020-05-18 08:45:38 +0200143 test::VideoDecoderProxyFactory h264_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200144 cricket::FakeVideoRenderer fake_renderer_;
145 MockTransport mock_transport_;
146 PacketRouter packet_router_;
147 RtpStreamReceiverController rtp_stream_receiver_controller_;
148 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
149 Clock* clock_;
150 VCMTiming* timing_;
151};
152
153TEST_F(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) {
154 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
155 RtpPacketToSend rtppacket(nullptr);
156 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
157 memcpy(payload, idr_nalu, sizeof(idr_nalu));
158 rtppacket.SetMarker(true);
159 rtppacket.SetSsrc(1111);
160 rtppacket.SetPayloadType(99);
161 rtppacket.SetSequenceNumber(1);
162 rtppacket.SetTimestamp(0);
163 rtc::Event init_decode_event_;
164 EXPECT_CALL(mock_h264_video_decoder_, InitDecode(_, _))
165 .WillOnce(Invoke([&init_decode_event_](const VideoCodec* config,
166 int32_t number_of_cores) {
167 init_decode_event_.Set();
168 return 0;
169 }));
170 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
171 video_receive_stream_->Start();
172 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
173 RtpPacketReceived parsed_packet;
174 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
175 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
176 EXPECT_CALL(mock_h264_video_decoder_, Release());
177 // Make sure the decoder thread had a chance to run.
178 init_decode_event_.Wait(kDefaultTimeOutMs);
179}
180
181TEST_F(VideoReceiveStream2Test, PlayoutDelay) {
Niels Möllerd381eed2020-09-02 15:34:40 +0200182 const VideoPlayoutDelay kPlayoutDelayMs = {123, 321};
Tommiae4d0972020-05-18 08:45:38 +0200183 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100184 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200185 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
186
187 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
188 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
189 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
190
191 // Check that the biggest minimum delay is chosen.
192 video_receive_stream_->SetMinimumPlayoutDelay(400);
193 EXPECT_EQ(400, timing_->min_playout_delay());
194
195 // Check base minimum delay validation.
196 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
197 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
198 EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
199 EXPECT_EQ(500, timing_->min_playout_delay());
200
201 // Check that intermidiate values are remembered and the biggest remembered
202 // is chosen.
203 video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
204 EXPECT_EQ(400, timing_->min_playout_delay());
205
206 video_receive_stream_->SetMinimumPlayoutDelay(0);
207 EXPECT_EQ(123, timing_->min_playout_delay());
208}
209
210TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
211 const int default_max_playout_latency = timing_->max_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200212 const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
Tommiae4d0972020-05-18 08:45:38 +0200213
214 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100215 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200216 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
217
218 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
219
220 // Ensure that -1 preserves default maximum value from |timing_|.
221 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
222 EXPECT_NE(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
223 EXPECT_EQ(default_max_playout_latency, timing_->max_playout_delay());
224}
225
226TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
227 const int default_min_playout_latency = timing_->min_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200228 const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
Tommiae4d0972020-05-18 08:45:38 +0200229
230 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100231 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200232 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
233
234 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
235
236 // Ensure that -1 preserves default minimum value from |timing_|.
237 EXPECT_NE(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
238 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
239 EXPECT_EQ(default_min_playout_latency, timing_->min_playout_delay());
240}
241
Johannes Kron111e9812020-10-26 13:54:40 +0100242TEST_F(VideoReceiveStream2Test, MaxCompositionDelayNotSetByDefault) {
243 // Default with no playout delay set.
244 std::unique_ptr<FrameObjectFake> test_frame0(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100245 test_frame0->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100246 video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
247 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
248
249 // Max composition delay not set for playout delay 0,0.
250 std::unique_ptr<FrameObjectFake> test_frame1(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100251 test_frame1->SetId(1);
Johannes Kron111e9812020-10-26 13:54:40 +0100252 test_frame1->SetPlayoutDelay({0, 0});
253 video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
254 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
255
256 // Max composition delay not set for playout delay X,Y, where X,Y>0.
257 std::unique_ptr<FrameObjectFake> test_frame2(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100258 test_frame2->SetId(2);
Johannes Kron111e9812020-10-26 13:54:40 +0100259 test_frame2->SetPlayoutDelay({10, 30});
260 video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
261 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
262}
263
264TEST_F(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) {
265 // Max composition delay set if playout delay X,Y, where X=0,Y>0.
266 const VideoPlayoutDelay kPlayoutDelayMs = {0, 50};
267 const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
268 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100269 test_frame->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100270 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
271 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
272 EXPECT_EQ(kExpectedMaxCompositionDelayInFrames,
273 timing_->MaxCompositionDelayInFrames());
274}
275
Tommiae4d0972020-05-18 08:45:38 +0200276class VideoReceiveStream2TestWithFakeDecoder : public ::testing::Test {
277 public:
278 VideoReceiveStream2TestWithFakeDecoder()
279 : fake_decoder_factory_(
280 []() { return std::make_unique<test::FakeDecoder>(); }),
281 process_thread_(ProcessThread::Create("TestThread")),
282 task_queue_factory_(CreateDefaultTaskQueueFactory()),
283 config_(&mock_transport_),
284 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
285
286 void SetUp() {
287 config_.rtp.remote_ssrc = 1111;
288 config_.rtp.local_ssrc = 2222;
289 config_.renderer = &fake_renderer_;
Philip Eliasson2b068ce2020-08-03 15:55:10 +0000290 config_.decoder_factory = &fake_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200291 VideoReceiveStream::Decoder fake_decoder;
292 fake_decoder.payload_type = 99;
293 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200294 config_.decoders.push_back(fake_decoder);
295 clock_ = Clock::GetRealTimeClock();
296 ReCreateReceiveStream(VideoReceiveStream::RecordingState());
297 }
298
299 void ReCreateReceiveStream(VideoReceiveStream::RecordingState state) {
300 constexpr int kDefaultNumCpuCores = 2;
301 video_receive_stream_ = nullptr;
302 timing_ = new VCMTiming(clock_);
303 video_receive_stream_.reset(new webrtc::internal::VideoReceiveStream2(
304 task_queue_factory_.get(), loop_.task_queue(),
305 &rtp_stream_receiver_controller_, kDefaultNumCpuCores, &packet_router_,
306 config_.Copy(), process_thread_.get(), &call_stats_, clock_, timing_));
307 video_receive_stream_->SetAndGetRecordingState(std::move(state), false);
308 }
309
310 protected:
311 test::RunLoop loop_;
312 test::FunctionVideoDecoderFactory fake_decoder_factory_;
313 std::unique_ptr<ProcessThread> process_thread_;
314 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
315 VideoReceiveStream::Config config_;
316 internal::CallStats call_stats_;
317 cricket::FakeVideoRenderer fake_renderer_;
318 MockTransport mock_transport_;
319 PacketRouter packet_router_;
320 RtpStreamReceiverController rtp_stream_receiver_controller_;
321 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
322 Clock* clock_;
323 VCMTiming* timing_;
324};
325
326TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesNtpTime) {
327 const int64_t kNtpTimestamp = 12345;
328 auto test_frame = std::make_unique<FrameObjectFake>();
329 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100330 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200331 test_frame->SetNtpTime(kNtpTimestamp);
332
333 video_receive_stream_->Start();
334 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
335 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
336 EXPECT_EQ(kNtpTimestamp, fake_renderer_.ntp_time_ms());
337}
338
339TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesRotation) {
340 const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
341 auto test_frame = std::make_unique<FrameObjectFake>();
342 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100343 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200344 test_frame->SetRotation(kRotation);
345
346 video_receive_stream_->Start();
347 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
348 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
349
350 EXPECT_EQ(kRotation, fake_renderer_.rotation());
351}
352
353TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesPacketInfos) {
354 auto test_frame = std::make_unique<FrameObjectFake>();
355 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100356 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200357 RtpPacketInfos packet_infos = CreatePacketInfos(3);
358 test_frame->SetPacketInfos(packet_infos);
359
360 video_receive_stream_->Start();
361 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
362 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
363
364 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
365}
366
367TEST_F(VideoReceiveStream2TestWithFakeDecoder, RenderedFrameUpdatesGetSources) {
368 constexpr uint32_t kSsrc = 1111;
369 constexpr uint32_t kCsrc = 9001;
370 constexpr uint32_t kRtpTimestamp = 12345;
371
372 // Prepare one video frame with per-packet information.
373 auto test_frame = std::make_unique<FrameObjectFake>();
374 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100375 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200376 RtpPacketInfos packet_infos;
377 {
378 RtpPacketInfos::vector_type infos;
379
380 RtpPacketInfo info;
381 info.set_ssrc(kSsrc);
382 info.set_csrcs({kCsrc});
383 info.set_rtp_timestamp(kRtpTimestamp);
384
385 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 5000);
386 infos.push_back(info);
387
388 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 3000);
389 infos.push_back(info);
390
391 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 2000);
392 infos.push_back(info);
393
394 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 4000);
395 infos.push_back(info);
396
397 packet_infos = RtpPacketInfos(std::move(infos));
398 }
399 test_frame->SetPacketInfos(packet_infos);
400
401 // Start receive stream.
402 video_receive_stream_->Start();
403 EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
404
405 // Render one video frame.
406 int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
407 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
408 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
409 int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
410
411 // Verify that the per-packet information is passed to the renderer.
412 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
413
414 // Verify that the per-packet information also updates |GetSources()|.
415 std::vector<RtpSource> sources = video_receive_stream_->GetSources();
416 ASSERT_THAT(sources, SizeIs(2));
417 {
418 auto it = std::find_if(sources.begin(), sources.end(),
419 [](const RtpSource& source) {
420 return source.source_type() == RtpSourceType::SSRC;
421 });
422 ASSERT_NE(it, sources.end());
423
424 EXPECT_EQ(it->source_id(), kSsrc);
425 EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
426 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
427 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
428 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
429 }
430 {
431 auto it = std::find_if(sources.begin(), sources.end(),
432 [](const RtpSource& source) {
433 return source.source_type() == RtpSourceType::CSRC;
434 });
435 ASSERT_NE(it, sources.end());
436
437 EXPECT_EQ(it->source_id(), kCsrc);
438 EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
439 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
440 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
441 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
442 }
443}
444
445std::unique_ptr<FrameObjectFake> MakeFrame(VideoFrameType frame_type,
446 int picture_id) {
447 auto frame = std::make_unique<FrameObjectFake>();
448 frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100449 frame->SetId(picture_id);
Tommiae4d0972020-05-18 08:45:38 +0200450 frame->SetFrameType(frame_type);
451 return frame;
452}
453
454TEST_F(VideoReceiveStream2TestWithFakeDecoder,
455 PassesFrameWhenEncodedFramesCallbackSet) {
456 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
457 video_receive_stream_->Start();
458 // Expect a keyframe request to be generated
459 EXPECT_CALL(mock_transport_, SendRtcp);
460 EXPECT_CALL(callback, Call);
461 video_receive_stream_->SetAndGetRecordingState(
462 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
463 video_receive_stream_->OnCompleteFrame(
464 MakeFrame(VideoFrameType::kVideoFrameKey, 0));
465 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
466 video_receive_stream_->Stop();
467}
468
469TEST_F(VideoReceiveStream2TestWithFakeDecoder,
470 MovesEncodedFrameDispatchStateWhenReCreating) {
471 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
472 video_receive_stream_->Start();
473 // Expect a key frame request over RTCP.
474 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
475 video_receive_stream_->SetAndGetRecordingState(
476 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
477 video_receive_stream_->Stop();
478 VideoReceiveStream::RecordingState old_state =
479 video_receive_stream_->SetAndGetRecordingState(
480 VideoReceiveStream::RecordingState(), false);
481 ReCreateReceiveStream(std::move(old_state));
482 video_receive_stream_->Stop();
483}
484
Philipp Hancke006206d2021-03-24 17:49:02 +0100485class VideoReceiveStream2TestWithSimulatedClock
486 : public ::testing::TestWithParam<int> {
Tommiae4d0972020-05-18 08:45:38 +0200487 public:
488 class FakeDecoder2 : public test::FakeDecoder {
489 public:
490 explicit FakeDecoder2(std::function<void()> decode_callback)
491 : callback_(decode_callback) {}
492
493 int32_t Decode(const EncodedImage& input,
494 bool missing_frames,
495 int64_t render_time_ms) override {
496 int32_t result =
497 FakeDecoder::Decode(input, missing_frames, render_time_ms);
498 callback_();
499 return result;
500 }
501
502 private:
503 std::function<void()> callback_;
504 };
505
506 static VideoReceiveStream::Config GetConfig(
507 Transport* transport,
508 VideoDecoderFactory* decoder_factory,
509 rtc::VideoSinkInterface<webrtc::VideoFrame>* renderer) {
510 VideoReceiveStream::Config config(transport);
511 config.rtp.remote_ssrc = 1111;
512 config.rtp.local_ssrc = 2222;
Philipp Hancke006206d2021-03-24 17:49:02 +0100513 config.rtp.nack.rtp_history_ms = GetParam(); // rtx-time.
Tommiae4d0972020-05-18 08:45:38 +0200514 config.renderer = renderer;
Philip Eliasson2b068ce2020-08-03 15:55:10 +0000515 config.decoder_factory = decoder_factory;
Tommiae4d0972020-05-18 08:45:38 +0200516 VideoReceiveStream::Decoder fake_decoder;
517 fake_decoder.payload_type = 99;
518 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200519 config.decoders.push_back(fake_decoder);
520 return config;
521 }
522
523 VideoReceiveStream2TestWithSimulatedClock()
524 : time_controller_(Timestamp::Millis(4711)),
525 fake_decoder_factory_([this] {
526 return std::make_unique<FakeDecoder2>([this] { OnFrameDecoded(); });
527 }),
528 process_thread_(time_controller_.CreateProcessThread("ProcessThread")),
529 config_(GetConfig(&mock_transport_,
530 &fake_decoder_factory_,
531 &fake_renderer_)),
532 call_stats_(time_controller_.GetClock(), loop_.task_queue()),
533 video_receive_stream_(time_controller_.GetTaskQueueFactory(),
534 loop_.task_queue(),
535 &rtp_stream_receiver_controller_,
536 /*num_cores=*/2,
537 &packet_router_,
538 config_.Copy(),
539 process_thread_.get(),
540 &call_stats_,
541 time_controller_.GetClock(),
542 new VCMTiming(time_controller_.GetClock())) {
543 video_receive_stream_.Start();
544 }
545
546 void OnFrameDecoded() { event_->Set(); }
547
philipelca188092021-03-23 12:00:49 +0100548 void PassEncodedFrameAndWait(std::unique_ptr<EncodedFrame> frame) {
Tommiae4d0972020-05-18 08:45:38 +0200549 event_ = std::make_unique<rtc::Event>();
550 // This call will eventually end up in the Decoded method where the
551 // event is set.
552 video_receive_stream_.OnCompleteFrame(std::move(frame));
553 event_->Wait(rtc::Event::kForever);
554 }
555
556 protected:
557 GlobalSimulatedTimeController time_controller_;
558 test::RunLoop loop_;
559 test::FunctionVideoDecoderFactory fake_decoder_factory_;
560 std::unique_ptr<ProcessThread> process_thread_;
561 MockTransport mock_transport_;
562 cricket::FakeVideoRenderer fake_renderer_;
563 VideoReceiveStream::Config config_;
564 internal::CallStats call_stats_;
565 PacketRouter packet_router_;
566 RtpStreamReceiverController rtp_stream_receiver_controller_;
567 webrtc::internal::VideoReceiveStream2 video_receive_stream_;
568 std::unique_ptr<rtc::Event> event_;
569};
570
Philipp Hancke006206d2021-03-24 17:49:02 +0100571TEST_P(VideoReceiveStream2TestWithSimulatedClock,
Tommiae4d0972020-05-18 08:45:38 +0200572 RequestsKeyFramesUntilKeyFrameReceived) {
Philipp Hancke006206d2021-03-24 17:49:02 +0100573 auto tick = TimeDelta::Millis(GetParam() / 2);
Tommiae4d0972020-05-18 08:45:38 +0200574 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(Invoke([this]() {
575 loop_.Quit();
576 return 0;
577 }));
578 video_receive_stream_.GenerateKeyFrame();
579 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
580 time_controller_.AdvanceTime(tick);
581 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
582 loop_.Run();
583 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
584
Philipp Hancke006206d2021-03-24 17:49:02 +0100585 // T+keyframetimeout: still no key frame received, expect key frame request
586 // sent again.
Tommiae4d0972020-05-18 08:45:38 +0200587 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(Invoke([this]() {
588 loop_.Quit();
589 return 0;
590 }));
591 time_controller_.AdvanceTime(tick);
592 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
593 loop_.Run();
594 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
595
Philipp Hancke006206d2021-03-24 17:49:02 +0100596 // T+keyframetimeout: now send a key frame - we should not observe new key
597 // frame requests after this.
Tommiae4d0972020-05-18 08:45:38 +0200598 EXPECT_CALL(mock_transport_, SendRtcp).Times(0);
599 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameKey, 3));
600 time_controller_.AdvanceTime(2 * tick);
601 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
602 loop_.PostTask([this]() { loop_.Quit(); });
603 loop_.Run();
604}
605
Philipp Hancke006206d2021-03-24 17:49:02 +0100606INSTANTIATE_TEST_SUITE_P(
607 RtxTime,
608 VideoReceiveStream2TestWithSimulatedClock,
609 ::testing::Values(internal::VideoReceiveStream2::kMaxWaitForKeyFrameMs,
610 50 /*ms*/));
611
Johannes Kron16359f62021-02-18 23:37:22 +0100612class VideoReceiveStream2TestWithLazyDecoderCreation : public ::testing::Test {
613 public:
614 VideoReceiveStream2TestWithLazyDecoderCreation()
615 : process_thread_(ProcessThread::Create("TestThread")),
616 task_queue_factory_(CreateDefaultTaskQueueFactory()),
617 config_(&mock_transport_),
618 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
619
620 void SetUp() {
621 webrtc::test::ScopedFieldTrials field_trials(
622 "WebRTC-PreStreamDecoders/max:0/");
623 constexpr int kDefaultNumCpuCores = 2;
624 config_.rtp.remote_ssrc = 1111;
625 config_.rtp.local_ssrc = 2222;
626 config_.renderer = &fake_renderer_;
627 config_.decoder_factory = &mock_h264_decoder_factory_;
628 VideoReceiveStream::Decoder h264_decoder;
629 h264_decoder.payload_type = 99;
630 h264_decoder.video_format = SdpVideoFormat("H264");
631 h264_decoder.video_format.parameters.insert(
632 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
633 config_.decoders.clear();
634 config_.decoders.push_back(h264_decoder);
635
636 clock_ = Clock::GetRealTimeClock();
637 timing_ = new VCMTiming(clock_);
638
639 video_receive_stream_ =
640 std::make_unique<webrtc::internal::VideoReceiveStream2>(
641 task_queue_factory_.get(), loop_.task_queue(),
642 &rtp_stream_receiver_controller_, kDefaultNumCpuCores,
643 &packet_router_, config_.Copy(), process_thread_.get(),
644 &call_stats_, clock_, timing_);
645 }
646
647 protected:
648 test::RunLoop loop_;
649 std::unique_ptr<ProcessThread> process_thread_;
650 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
651 VideoReceiveStream::Config config_;
652 internal::CallStats call_stats_;
653 MockVideoDecoder mock_h264_video_decoder_;
654 MockVideoDecoderFactory mock_h264_decoder_factory_;
655 cricket::FakeVideoRenderer fake_renderer_;
656 MockTransport mock_transport_;
657 PacketRouter packet_router_;
658 RtpStreamReceiverController rtp_stream_receiver_controller_;
659 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
660 Clock* clock_;
661 VCMTiming* timing_;
662};
663
664TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation, LazyDecoderCreation) {
665 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
666 RtpPacketToSend rtppacket(nullptr);
667 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
668 memcpy(payload, idr_nalu, sizeof(idr_nalu));
669 rtppacket.SetMarker(true);
670 rtppacket.SetSsrc(1111);
671 rtppacket.SetPayloadType(99);
672 rtppacket.SetSequenceNumber(1);
673 rtppacket.SetTimestamp(0);
674
675 // No decoder is created here.
676 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
677 video_receive_stream_->Start();
678
679 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_))
680 .WillOnce(Invoke([this](const SdpVideoFormat& format) {
681 test::VideoDecoderProxyFactory h264_decoder_factory(
682 &mock_h264_video_decoder_);
683 return h264_decoder_factory.CreateVideoDecoder(format);
684 }));
685 rtc::Event init_decode_event_;
686 EXPECT_CALL(mock_h264_video_decoder_, InitDecode(_, _))
687 .WillOnce(Invoke([&init_decode_event_](const VideoCodec* config,
688 int32_t number_of_cores) {
689 init_decode_event_.Set();
690 return 0;
691 }));
692 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
693 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
694 RtpPacketReceived parsed_packet;
695 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
696 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
697 EXPECT_CALL(mock_h264_video_decoder_, Release());
698
699 // Make sure the decoder thread had a chance to run.
700 init_decode_event_.Wait(kDefaultTimeOutMs);
701}
702
703TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation,
704 DeregisterDecoderThatsNotCreated) {
705 // No decoder is created here.
706 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
707 video_receive_stream_->Start();
708 video_receive_stream_->Stop();
709}
710
Tommiae4d0972020-05-18 08:45:38 +0200711} // namespace webrtc