blob: aa9cee35c8387f1bd9e4e88f7fd41f26798d273e [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
485class VideoReceiveStream2TestWithSimulatedClock : public ::testing::Test {
486 public:
487 class FakeDecoder2 : public test::FakeDecoder {
488 public:
489 explicit FakeDecoder2(std::function<void()> decode_callback)
490 : callback_(decode_callback) {}
491
492 int32_t Decode(const EncodedImage& input,
493 bool missing_frames,
494 int64_t render_time_ms) override {
495 int32_t result =
496 FakeDecoder::Decode(input, missing_frames, render_time_ms);
497 callback_();
498 return result;
499 }
500
501 private:
502 std::function<void()> callback_;
503 };
504
505 static VideoReceiveStream::Config GetConfig(
506 Transport* transport,
507 VideoDecoderFactory* decoder_factory,
508 rtc::VideoSinkInterface<webrtc::VideoFrame>* renderer) {
509 VideoReceiveStream::Config config(transport);
510 config.rtp.remote_ssrc = 1111;
511 config.rtp.local_ssrc = 2222;
512 config.renderer = renderer;
Philip Eliasson2b068ce2020-08-03 15:55:10 +0000513 config.decoder_factory = decoder_factory;
Tommiae4d0972020-05-18 08:45:38 +0200514 VideoReceiveStream::Decoder fake_decoder;
515 fake_decoder.payload_type = 99;
516 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200517 config.decoders.push_back(fake_decoder);
518 return config;
519 }
520
521 VideoReceiveStream2TestWithSimulatedClock()
522 : time_controller_(Timestamp::Millis(4711)),
523 fake_decoder_factory_([this] {
524 return std::make_unique<FakeDecoder2>([this] { OnFrameDecoded(); });
525 }),
526 process_thread_(time_controller_.CreateProcessThread("ProcessThread")),
527 config_(GetConfig(&mock_transport_,
528 &fake_decoder_factory_,
529 &fake_renderer_)),
530 call_stats_(time_controller_.GetClock(), loop_.task_queue()),
531 video_receive_stream_(time_controller_.GetTaskQueueFactory(),
532 loop_.task_queue(),
533 &rtp_stream_receiver_controller_,
534 /*num_cores=*/2,
535 &packet_router_,
536 config_.Copy(),
537 process_thread_.get(),
538 &call_stats_,
539 time_controller_.GetClock(),
540 new VCMTiming(time_controller_.GetClock())) {
541 video_receive_stream_.Start();
542 }
543
544 void OnFrameDecoded() { event_->Set(); }
545
philipelca188092021-03-23 12:00:49 +0100546 void PassEncodedFrameAndWait(std::unique_ptr<EncodedFrame> frame) {
Tommiae4d0972020-05-18 08:45:38 +0200547 event_ = std::make_unique<rtc::Event>();
548 // This call will eventually end up in the Decoded method where the
549 // event is set.
550 video_receive_stream_.OnCompleteFrame(std::move(frame));
551 event_->Wait(rtc::Event::kForever);
552 }
553
554 protected:
555 GlobalSimulatedTimeController time_controller_;
556 test::RunLoop loop_;
557 test::FunctionVideoDecoderFactory fake_decoder_factory_;
558 std::unique_ptr<ProcessThread> process_thread_;
559 MockTransport mock_transport_;
560 cricket::FakeVideoRenderer fake_renderer_;
561 VideoReceiveStream::Config config_;
562 internal::CallStats call_stats_;
563 PacketRouter packet_router_;
564 RtpStreamReceiverController rtp_stream_receiver_controller_;
565 webrtc::internal::VideoReceiveStream2 video_receive_stream_;
566 std::unique_ptr<rtc::Event> event_;
567};
568
569TEST_F(VideoReceiveStream2TestWithSimulatedClock,
570 RequestsKeyFramesUntilKeyFrameReceived) {
571 auto tick = TimeDelta::Millis(
572 internal::VideoReceiveStream2::kMaxWaitForKeyFrameMs / 2);
573 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(Invoke([this]() {
574 loop_.Quit();
575 return 0;
576 }));
577 video_receive_stream_.GenerateKeyFrame();
578 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
579 time_controller_.AdvanceTime(tick);
580 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
581 loop_.Run();
582 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
583
584 // T+200ms: still no key frame received, expect key frame request sent again.
585 EXPECT_CALL(mock_transport_, SendRtcp).Times(1).WillOnce(Invoke([this]() {
586 loop_.Quit();
587 return 0;
588 }));
589 time_controller_.AdvanceTime(tick);
590 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
591 loop_.Run();
592 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
593
594 // T+200ms: now send a key frame - we should not observe new key frame
595 // requests after this.
596 EXPECT_CALL(mock_transport_, SendRtcp).Times(0);
597 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameKey, 3));
598 time_controller_.AdvanceTime(2 * tick);
599 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
600 loop_.PostTask([this]() { loop_.Quit(); });
601 loop_.Run();
602}
603
Johannes Kron16359f62021-02-18 23:37:22 +0100604class VideoReceiveStream2TestWithLazyDecoderCreation : public ::testing::Test {
605 public:
606 VideoReceiveStream2TestWithLazyDecoderCreation()
607 : process_thread_(ProcessThread::Create("TestThread")),
608 task_queue_factory_(CreateDefaultTaskQueueFactory()),
609 config_(&mock_transport_),
610 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
611
612 void SetUp() {
613 webrtc::test::ScopedFieldTrials field_trials(
614 "WebRTC-PreStreamDecoders/max:0/");
615 constexpr int kDefaultNumCpuCores = 2;
616 config_.rtp.remote_ssrc = 1111;
617 config_.rtp.local_ssrc = 2222;
618 config_.renderer = &fake_renderer_;
619 config_.decoder_factory = &mock_h264_decoder_factory_;
620 VideoReceiveStream::Decoder h264_decoder;
621 h264_decoder.payload_type = 99;
622 h264_decoder.video_format = SdpVideoFormat("H264");
623 h264_decoder.video_format.parameters.insert(
624 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
625 config_.decoders.clear();
626 config_.decoders.push_back(h264_decoder);
627
628 clock_ = Clock::GetRealTimeClock();
629 timing_ = new VCMTiming(clock_);
630
631 video_receive_stream_ =
632 std::make_unique<webrtc::internal::VideoReceiveStream2>(
633 task_queue_factory_.get(), loop_.task_queue(),
634 &rtp_stream_receiver_controller_, kDefaultNumCpuCores,
635 &packet_router_, config_.Copy(), process_thread_.get(),
636 &call_stats_, clock_, timing_);
637 }
638
639 protected:
640 test::RunLoop loop_;
641 std::unique_ptr<ProcessThread> process_thread_;
642 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
643 VideoReceiveStream::Config config_;
644 internal::CallStats call_stats_;
645 MockVideoDecoder mock_h264_video_decoder_;
646 MockVideoDecoderFactory mock_h264_decoder_factory_;
647 cricket::FakeVideoRenderer fake_renderer_;
648 MockTransport mock_transport_;
649 PacketRouter packet_router_;
650 RtpStreamReceiverController rtp_stream_receiver_controller_;
651 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
652 Clock* clock_;
653 VCMTiming* timing_;
654};
655
656TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation, LazyDecoderCreation) {
657 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
658 RtpPacketToSend rtppacket(nullptr);
659 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
660 memcpy(payload, idr_nalu, sizeof(idr_nalu));
661 rtppacket.SetMarker(true);
662 rtppacket.SetSsrc(1111);
663 rtppacket.SetPayloadType(99);
664 rtppacket.SetSequenceNumber(1);
665 rtppacket.SetTimestamp(0);
666
667 // No decoder is created here.
668 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
669 video_receive_stream_->Start();
670
671 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_))
672 .WillOnce(Invoke([this](const SdpVideoFormat& format) {
673 test::VideoDecoderProxyFactory h264_decoder_factory(
674 &mock_h264_video_decoder_);
675 return h264_decoder_factory.CreateVideoDecoder(format);
676 }));
677 rtc::Event init_decode_event_;
678 EXPECT_CALL(mock_h264_video_decoder_, InitDecode(_, _))
679 .WillOnce(Invoke([&init_decode_event_](const VideoCodec* config,
680 int32_t number_of_cores) {
681 init_decode_event_.Set();
682 return 0;
683 }));
684 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
685 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
686 RtpPacketReceived parsed_packet;
687 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
688 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
689 EXPECT_CALL(mock_h264_video_decoder_, Release());
690
691 // Make sure the decoder thread had a chance to run.
692 init_decode_event_.Wait(kDefaultTimeOutMs);
693}
694
695TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation,
696 DeregisterDecoderThatsNotCreated) {
697 // No decoder is created here.
698 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
699 video_receive_stream_->Start();
700 video_receive_stream_->Stop();
701}
702
Tommiae4d0972020-05-18 08:45:38 +0200703} // namespace webrtc