blob: 503660eca6bdc5364b7240daf5d0ddc96e3da7b6 [file] [log] [blame]
johanf2183ff2017-02-28 01:33:09 -08001/*
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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "video/video_receive_stream.h"
12
Chen Xing90f3b892019-06-25 10:16:14 +020013#include <algorithm>
Mirko Bonadei317a1f02019-09-17 17:06:18 +020014#include <memory>
Ruslan Burakov493a6502019-02-27 15:32:48 +010015#include <utility>
johanf2183ff2017-02-28 01:33:09 -080016#include <vector>
17
Danil Chapovalovd3ba2362019-04-10 17:01:23 +020018#include "api/task_queue/default_task_queue_factory.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020019#include "api/test/video/function_video_decoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "api/video_codecs/video_decoder.h"
21#include "call/rtp_stream_receiver_controller.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020022#include "common_video/test/utilities.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "media/base/fake_video_renderer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#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"
Markus Handell269ac812019-12-03 14:31:45 +010027#include "modules/video_coding/encoded_frame.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/critical_section.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020029#include "rtc_base/event.h"
30#include "system_wrappers/include/clock.h"
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020031#include "test/fake_decoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "test/field_trial.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020033#include "test/gmock.h"
34#include "test/gtest.h"
Markus Handell269ac812019-12-03 14:31:45 +010035#include "test/time_controller/simulated_time_controller.h"
Niels Möllercbcbc222018-09-28 09:07:24 +020036#include "test/video_decoder_proxy_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020037#include "video/call_stats.h"
johanf2183ff2017-02-28 01:33:09 -080038
nisse0f15f922017-06-21 01:05:22 -070039namespace webrtc {
40namespace {
41
Mirko Bonadei6a489f22019-04-09 15:11:12 +020042using ::testing::_;
Chen Xing90f3b892019-06-25 10:16:14 +020043using ::testing::ElementsAreArray;
Mirko Bonadei6a489f22019-04-09 15:11:12 +020044using ::testing::Invoke;
Chen Xing90f3b892019-06-25 10:16:14 +020045using ::testing::IsEmpty;
46using ::testing::SizeIs;
johanf2183ff2017-02-28 01:33:09 -080047
48constexpr int kDefaultTimeOutMs = 50;
49
johanf2183ff2017-02-28 01:33:09 -080050class MockTransport : public Transport {
51 public:
52 MOCK_METHOD3(SendRtp,
53 bool(const uint8_t* packet,
54 size_t length,
55 const PacketOptions& options));
56 MOCK_METHOD2(SendRtcp, bool(const uint8_t* packet, size_t length));
57};
58
59class MockVideoDecoder : public VideoDecoder {
60 public:
61 MOCK_METHOD2(InitDecode,
62 int32_t(const VideoCodec* config, int32_t number_of_cores));
Niels Möller7aacdd92019-03-25 09:11:40 +010063 MOCK_METHOD3(Decode,
johanf2183ff2017-02-28 01:33:09 -080064 int32_t(const EncodedImage& input,
65 bool missing_frames,
johanf2183ff2017-02-28 01:33:09 -080066 int64_t render_time_ms));
67 MOCK_METHOD1(RegisterDecodeCompleteCallback,
68 int32_t(DecodedImageCallback* callback));
69 MOCK_METHOD0(Release, int32_t(void));
70 const char* ImplementationName() const { return "MockVideoDecoder"; }
71};
72
Ruslan Burakov493a6502019-02-27 15:32:48 +010073class FrameObjectFake : public video_coding::EncodedFrame {
74 public:
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +020075 void SetPayloadType(uint8_t payload_type) { _payloadType = payload_type; }
76
77 void SetRotation(const VideoRotation& rotation) { rotation_ = rotation; }
78
79 void SetNtpTime(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; }
80
Ruslan Burakov493a6502019-02-27 15:32:48 +010081 int64_t ReceivedTime() const override { return 0; }
82
83 int64_t RenderTime() const override { return _renderTimeMs; }
84};
85
johanf2183ff2017-02-28 01:33:09 -080086} // namespace
87
Mirko Bonadei6a489f22019-04-09 15:11:12 +020088class VideoReceiveStreamTest : public ::testing::Test {
johanf2183ff2017-02-28 01:33:09 -080089 public:
90 VideoReceiveStreamTest()
Tommi38c5d932018-03-27 23:11:09 +020091 : process_thread_(ProcessThread::Create("TestThread")),
Danil Chapovalovd3ba2362019-04-10 17:01:23 +020092 task_queue_factory_(CreateDefaultTaskQueueFactory()),
johanf2183ff2017-02-28 01:33:09 -080093 config_(&mock_transport_),
Niels Möllercbcbc222018-09-28 09:07:24 +020094 call_stats_(Clock::GetRealTimeClock(), process_thread_.get()),
95 h264_decoder_factory_(&mock_h264_video_decoder_),
96 null_decoder_factory_(&mock_null_video_decoder_) {}
johanf2183ff2017-02-28 01:33:09 -080097
98 void SetUp() {
99 constexpr int kDefaultNumCpuCores = 2;
100 config_.rtp.remote_ssrc = 1111;
101 config_.rtp.local_ssrc = 2222;
102 config_.renderer = &fake_renderer_;
103 VideoReceiveStream::Decoder h264_decoder;
104 h264_decoder.payload_type = 99;
Niels Möllercb7e1d22018-09-11 15:56:04 +0200105 h264_decoder.video_format = SdpVideoFormat("H264");
106 h264_decoder.video_format.parameters.insert(
johanf2183ff2017-02-28 01:33:09 -0800107 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
Niels Möllercbcbc222018-09-28 09:07:24 +0200108 h264_decoder.decoder_factory = &h264_decoder_factory_;
johanf2183ff2017-02-28 01:33:09 -0800109 config_.decoders.push_back(h264_decoder);
110 VideoReceiveStream::Decoder null_decoder;
111 null_decoder.payload_type = 98;
Niels Möllercb7e1d22018-09-11 15:56:04 +0200112 null_decoder.video_format = SdpVideoFormat("null");
Niels Möllercbcbc222018-09-28 09:07:24 +0200113 null_decoder.decoder_factory = &null_decoder_factory_;
johanf2183ff2017-02-28 01:33:09 -0800114 config_.decoders.push_back(null_decoder);
115
Chen Xing90f3b892019-06-25 10:16:14 +0200116 clock_ = Clock::GetRealTimeClock();
117 timing_ = new VCMTiming(clock_);
Ruslan Burakov493a6502019-02-27 15:32:48 +0100118
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200119 video_receive_stream_ =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200120 std::make_unique<webrtc::internal::VideoReceiveStream>(
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200121 task_queue_factory_.get(), &rtp_stream_receiver_controller_,
122 kDefaultNumCpuCores, &packet_router_, config_.Copy(),
Chen Xing90f3b892019-06-25 10:16:14 +0200123 process_thread_.get(), &call_stats_, clock_, timing_);
johanf2183ff2017-02-28 01:33:09 -0800124 }
125
126 protected:
Tommi38c5d932018-03-27 23:11:09 +0200127 std::unique_ptr<ProcessThread> process_thread_;
Danil Chapovalovd3ba2362019-04-10 17:01:23 +0200128 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
johanf2183ff2017-02-28 01:33:09 -0800129 VideoReceiveStream::Config config_;
130 CallStats call_stats_;
131 MockVideoDecoder mock_h264_video_decoder_;
132 MockVideoDecoder mock_null_video_decoder_;
Niels Möllercbcbc222018-09-28 09:07:24 +0200133 test::VideoDecoderProxyFactory h264_decoder_factory_;
134 test::VideoDecoderProxyFactory null_decoder_factory_;
johanf2183ff2017-02-28 01:33:09 -0800135 cricket::FakeVideoRenderer fake_renderer_;
136 MockTransport mock_transport_;
137 PacketRouter packet_router_;
nisse0f15f922017-06-21 01:05:22 -0700138 RtpStreamReceiverController rtp_stream_receiver_controller_;
johanf2183ff2017-02-28 01:33:09 -0800139 std::unique_ptr<webrtc::internal::VideoReceiveStream> video_receive_stream_;
Chen Xing90f3b892019-06-25 10:16:14 +0200140 Clock* clock_;
Ruslan Burakov493a6502019-02-27 15:32:48 +0100141 VCMTiming* timing_;
johanf2183ff2017-02-28 01:33:09 -0800142};
143
144TEST_F(VideoReceiveStreamTest, CreateFrameFromH264FmtpSpropAndIdr) {
145 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
146 RtpPacketToSend rtppacket(nullptr);
147 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
148 memcpy(payload, idr_nalu, sizeof(idr_nalu));
149 rtppacket.SetMarker(true);
150 rtppacket.SetSsrc(1111);
151 rtppacket.SetPayloadType(99);
152 rtppacket.SetSequenceNumber(1);
153 rtppacket.SetTimestamp(0);
Niels Möllerc572ff32018-11-07 08:43:50 +0100154 rtc::Event init_decode_event_;
johanf2183ff2017-02-28 01:33:09 -0800155 EXPECT_CALL(mock_h264_video_decoder_, InitDecode(_, _))
156 .WillOnce(Invoke([&init_decode_event_](const VideoCodec* config,
157 int32_t number_of_cores) {
158 init_decode_event_.Set();
159 return 0;
160 }));
161 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
162 video_receive_stream_->Start();
Niels Möller7aacdd92019-03-25 09:11:40 +0100163 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
nissed2ef3142017-05-11 08:00:58 -0700164 RtpPacketReceived parsed_packet;
165 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
nisse0f15f922017-06-21 01:05:22 -0700166 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
johanf2183ff2017-02-28 01:33:09 -0800167 EXPECT_CALL(mock_h264_video_decoder_, Release());
168 // Make sure the decoder thread had a chance to run.
169 init_decode_event_.Wait(kDefaultTimeOutMs);
170}
nisse0f15f922017-06-21 01:05:22 -0700171
Ruslan Burakov493a6502019-02-27 15:32:48 +0100172TEST_F(VideoReceiveStreamTest, PlayoutDelay) {
Johannes Kron3b698172019-08-28 12:41:11 +0000173 const PlayoutDelay kPlayoutDelayMs = {123, 321};
Ruslan Burakov493a6502019-02-27 15:32:48 +0100174 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
175 test_frame->id.picture_id = 0;
176 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
177
178 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
179 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
180 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
181
182 // Check that the biggest minimum delay is chosen.
183 video_receive_stream_->SetMinimumPlayoutDelay(400);
184 EXPECT_EQ(400, timing_->min_playout_delay());
185
186 // Check base minimum delay validation.
187 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
188 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
189 EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
190 EXPECT_EQ(500, timing_->min_playout_delay());
191
192 // Check that intermidiate values are remembered and the biggest remembered
193 // is chosen.
194 video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
195 EXPECT_EQ(400, timing_->min_playout_delay());
196
197 video_receive_stream_->SetMinimumPlayoutDelay(0);
198 EXPECT_EQ(123, timing_->min_playout_delay());
199}
200
Johannes Kron3b698172019-08-28 12:41:11 +0000201TEST_F(VideoReceiveStreamTest, PlayoutDelayPreservesDefaultMaxValue) {
Ruslan Burakov493a6502019-02-27 15:32:48 +0100202 const int default_max_playout_latency = timing_->max_playout_delay();
Johannes Kron3b698172019-08-28 12:41:11 +0000203 const PlayoutDelay kPlayoutDelayMs = {123, -1};
Ruslan Burakov493a6502019-02-27 15:32:48 +0100204
205 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
206 test_frame->id.picture_id = 0;
207 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
208
209 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
210
Johannes Kron3b698172019-08-28 12:41:11 +0000211 // Ensure that -1 preserves default maximum value from |timing_|.
212 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
213 EXPECT_NE(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
Ruslan Burakov493a6502019-02-27 15:32:48 +0100214 EXPECT_EQ(default_max_playout_latency, timing_->max_playout_delay());
215}
216
Johannes Kron3b698172019-08-28 12:41:11 +0000217TEST_F(VideoReceiveStreamTest, PlayoutDelayPreservesDefaultMinValue) {
218 const int default_min_playout_latency = timing_->min_playout_delay();
219 const PlayoutDelay kPlayoutDelayMs = {-1, 321};
Ruslan Burakov493a6502019-02-27 15:32:48 +0100220
221 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
222 test_frame->id.picture_id = 0;
223 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
224
Johannes Kron87bed472019-08-28 12:40:45 +0000225 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Johannes Kron87bed472019-08-28 12:40:45 +0000226
Johannes Kron3b698172019-08-28 12:41:11 +0000227 // Ensure that -1 preserves default minimum value from |timing_|.
228 EXPECT_NE(kPlayoutDelayMs.min_ms, timing_->min_playout_delay());
229 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay());
230 EXPECT_EQ(default_min_playout_latency, timing_->min_playout_delay());
Ruslan Burakov493a6502019-02-27 15:32:48 +0100231}
232
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200233class VideoReceiveStreamTestWithFakeDecoder : public ::testing::Test {
234 public:
235 VideoReceiveStreamTestWithFakeDecoder()
236 : fake_decoder_factory_(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200237 []() { return std::make_unique<test::FakeDecoder>(); }),
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200238 process_thread_(ProcessThread::Create("TestThread")),
239 task_queue_factory_(CreateDefaultTaskQueueFactory()),
240 config_(&mock_transport_),
241 call_stats_(Clock::GetRealTimeClock(), process_thread_.get()) {}
242
243 void SetUp() {
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200244 config_.rtp.remote_ssrc = 1111;
245 config_.rtp.local_ssrc = 2222;
246 config_.renderer = &fake_renderer_;
247 VideoReceiveStream::Decoder fake_decoder;
248 fake_decoder.payload_type = 99;
249 fake_decoder.video_format = SdpVideoFormat("VP8");
250 fake_decoder.decoder_factory = &fake_decoder_factory_;
251 config_.decoders.push_back(fake_decoder);
Chen Xing90f3b892019-06-25 10:16:14 +0200252 clock_ = Clock::GetRealTimeClock();
Markus Handell269ac812019-12-03 14:31:45 +0100253 ReCreateReceiveStream(VideoReceiveStream::RecordingState());
254 }
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200255
Markus Handell269ac812019-12-03 14:31:45 +0100256 void ReCreateReceiveStream(VideoReceiveStream::RecordingState state) {
257 constexpr int kDefaultNumCpuCores = 2;
258 video_receive_stream_ = nullptr;
259 timing_ = new VCMTiming(clock_);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200260 video_receive_stream_.reset(new webrtc::internal::VideoReceiveStream(
261 task_queue_factory_.get(), &rtp_stream_receiver_controller_,
262 kDefaultNumCpuCores, &packet_router_, config_.Copy(),
Chen Xing90f3b892019-06-25 10:16:14 +0200263 process_thread_.get(), &call_stats_, clock_, timing_));
Markus Handell269ac812019-12-03 14:31:45 +0100264 video_receive_stream_->SetAndGetRecordingState(std::move(state), false);
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200265 }
266
267 protected:
268 test::FunctionVideoDecoderFactory fake_decoder_factory_;
269 std::unique_ptr<ProcessThread> process_thread_;
270 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
271 VideoReceiveStream::Config config_;
272 CallStats call_stats_;
273 cricket::FakeVideoRenderer fake_renderer_;
274 MockTransport mock_transport_;
275 PacketRouter packet_router_;
276 RtpStreamReceiverController rtp_stream_receiver_controller_;
277 std::unique_ptr<webrtc::internal::VideoReceiveStream> video_receive_stream_;
Chen Xing90f3b892019-06-25 10:16:14 +0200278 Clock* clock_;
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200279 VCMTiming* timing_;
280};
281
282TEST_F(VideoReceiveStreamTestWithFakeDecoder, PassesNtpTime) {
283 const int64_t kNtpTimestamp = 12345;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200284 auto test_frame = std::make_unique<FrameObjectFake>();
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200285 test_frame->SetPayloadType(99);
286 test_frame->id.picture_id = 0;
287 test_frame->SetNtpTime(kNtpTimestamp);
288
289 video_receive_stream_->Start();
290 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
291 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
292 EXPECT_EQ(kNtpTimestamp, fake_renderer_.ntp_time_ms());
293}
294
295TEST_F(VideoReceiveStreamTestWithFakeDecoder, PassesRotation) {
296 const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200297 auto test_frame = std::make_unique<FrameObjectFake>();
Ilya Nikolaevskiy2ebf5232019-05-13 16:13:36 +0200298 test_frame->SetPayloadType(99);
299 test_frame->id.picture_id = 0;
300 test_frame->SetRotation(kRotation);
301
302 video_receive_stream_->Start();
303 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
304 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
305
306 EXPECT_EQ(kRotation, fake_renderer_.rotation());
307}
308
Chen Xingf00bf422019-06-20 10:05:55 +0200309TEST_F(VideoReceiveStreamTestWithFakeDecoder, PassesPacketInfos) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200310 auto test_frame = std::make_unique<FrameObjectFake>();
Chen Xingf00bf422019-06-20 10:05:55 +0200311 test_frame->SetPayloadType(99);
312 test_frame->id.picture_id = 0;
313 RtpPacketInfos packet_infos = CreatePacketInfos(3);
314 test_frame->SetPacketInfos(packet_infos);
315
316 video_receive_stream_->Start();
317 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
318 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
319
Chen Xing90f3b892019-06-25 10:16:14 +0200320 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
321}
322
323TEST_F(VideoReceiveStreamTestWithFakeDecoder, RenderedFrameUpdatesGetSources) {
324 constexpr uint32_t kSsrc = 1111;
325 constexpr uint32_t kCsrc = 9001;
326 constexpr uint32_t kRtpTimestamp = 12345;
327
328 // Prepare one video frame with per-packet information.
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200329 auto test_frame = std::make_unique<FrameObjectFake>();
Chen Xing90f3b892019-06-25 10:16:14 +0200330 test_frame->SetPayloadType(99);
331 test_frame->id.picture_id = 0;
332 RtpPacketInfos packet_infos;
333 {
334 RtpPacketInfos::vector_type infos;
335
336 RtpPacketInfo info;
337 info.set_ssrc(kSsrc);
338 info.set_csrcs({kCsrc});
339 info.set_rtp_timestamp(kRtpTimestamp);
340
341 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 5000);
342 infos.push_back(info);
343
344 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 3000);
345 infos.push_back(info);
346
347 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 2000);
348 infos.push_back(info);
349
350 info.set_receive_time_ms(clock_->TimeInMilliseconds() - 4000);
351 infos.push_back(info);
352
353 packet_infos = RtpPacketInfos(std::move(infos));
354 }
355 test_frame->SetPacketInfos(packet_infos);
356
357 // Start receive stream.
358 video_receive_stream_->Start();
359 EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
360
361 // Render one video frame.
362 int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
363 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
364 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
365 int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
366
367 // Verify that the per-packet information is passed to the renderer.
368 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
369
370 // Verify that the per-packet information also updates |GetSources()|.
371 std::vector<RtpSource> sources = video_receive_stream_->GetSources();
372 ASSERT_THAT(sources, SizeIs(2));
373 {
374 auto it = std::find_if(sources.begin(), sources.end(),
375 [](const RtpSource& source) {
376 return source.source_type() == RtpSourceType::SSRC;
377 });
378 ASSERT_NE(it, sources.end());
379
380 EXPECT_EQ(it->source_id(), kSsrc);
381 EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
382 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
383 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
384 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
385 }
386 {
387 auto it = std::find_if(sources.begin(), sources.end(),
388 [](const RtpSource& source) {
389 return source.source_type() == RtpSourceType::CSRC;
390 });
391 ASSERT_NE(it, sources.end());
392
393 EXPECT_EQ(it->source_id(), kCsrc);
394 EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
395 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
396 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
397 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
398 }
Chen Xingf00bf422019-06-20 10:05:55 +0200399}
400
Markus Handell269ac812019-12-03 14:31:45 +0100401std::unique_ptr<FrameObjectFake> MakeFrame(VideoFrameType frame_type,
402 int picture_id) {
403 auto frame = std::make_unique<FrameObjectFake>();
404 frame->SetPayloadType(99);
405 frame->id.picture_id = picture_id;
406 frame->SetFrameType(frame_type);
407 return frame;
408}
409
410TEST_F(VideoReceiveStreamTestWithFakeDecoder,
411 PassesFrameWhenEncodedFramesCallbackSet) {
412 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
413 video_receive_stream_->Start();
414 // Expect a keyframe request to be generated
415 EXPECT_CALL(mock_transport_, SendRtcp);
416 EXPECT_CALL(callback, Call);
417 video_receive_stream_->SetAndGetRecordingState(
418 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
419 video_receive_stream_->OnCompleteFrame(
420 MakeFrame(VideoFrameType::kVideoFrameKey, 0));
421 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
422 video_receive_stream_->Stop();
423}
424
425TEST_F(VideoReceiveStreamTestWithFakeDecoder,
426 MovesEncodedFrameDispatchStateWhenReCreating) {
427 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
428 video_receive_stream_->Start();
429 // Expect a key frame request over RTCP.
430 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
431 video_receive_stream_->SetAndGetRecordingState(
432 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
433 video_receive_stream_->Stop();
434 VideoReceiveStream::RecordingState old_state =
435 video_receive_stream_->SetAndGetRecordingState(
436 VideoReceiveStream::RecordingState(), false);
437 ReCreateReceiveStream(std::move(old_state));
438 video_receive_stream_->Stop();
439}
440
441class VideoReceiveStreamTestWithSimulatedClock : public ::testing::Test {
442 public:
443 class FakeDecoder2 : public test::FakeDecoder {
444 public:
445 explicit FakeDecoder2(std::function<void()> decode_callback)
446 : callback_(decode_callback) {}
447
448 int32_t Decode(const EncodedImage& input,
449 bool missing_frames,
450 int64_t render_time_ms) override {
451 int32_t result =
452 FakeDecoder::Decode(input, missing_frames, render_time_ms);
453 callback_();
454 return result;
455 }
456
457 private:
458 std::function<void()> callback_;
459 };
460
461 static VideoReceiveStream::Config GetConfig(
462 Transport* transport,
463 VideoDecoderFactory* decoder_factory,
464 rtc::VideoSinkInterface<webrtc::VideoFrame>* renderer) {
465 VideoReceiveStream::Config config(transport);
466 config.rtp.remote_ssrc = 1111;
467 config.rtp.local_ssrc = 2222;
468 config.renderer = renderer;
469 VideoReceiveStream::Decoder fake_decoder;
470 fake_decoder.payload_type = 99;
471 fake_decoder.video_format = SdpVideoFormat("VP8");
472 fake_decoder.decoder_factory = decoder_factory;
473 config.decoders.push_back(fake_decoder);
474 return config;
475 }
476
477 VideoReceiveStreamTestWithSimulatedClock()
478 : time_controller_(Timestamp::ms(4711)),
479 fake_decoder_factory_([this] {
480 return std::make_unique<FakeDecoder2>([this] { OnFrameDecoded(); });
481 }),
482 process_thread_(time_controller_.CreateProcessThread("ProcessThread")),
483 config_(GetConfig(&mock_transport_,
484 &fake_decoder_factory_,
485 &fake_renderer_)),
486 call_stats_(time_controller_.GetClock(), process_thread_.get()),
487 video_receive_stream_(time_controller_.GetTaskQueueFactory(),
488 &rtp_stream_receiver_controller_,
489 /*num_cores=*/2,
490 &packet_router_,
491 config_.Copy(),
492 process_thread_.get(),
493 &call_stats_,
494 time_controller_.GetClock(),
495 new VCMTiming(time_controller_.GetClock())) {
Sebastian Jansson340af972019-12-04 10:07:48 +0100496 video_receive_stream_.Start();
Markus Handell269ac812019-12-03 14:31:45 +0100497 }
498
499 void OnFrameDecoded() { event_->Set(); }
500
501 void PassEncodedFrameAndWait(
502 std::unique_ptr<video_coding::EncodedFrame> frame) {
Markus Handell269ac812019-12-03 14:31:45 +0100503 event_ = std::make_unique<rtc::Event>();
504 // This call will eventually end up in the Decoded method where the
505 // event is set.
506 video_receive_stream_.OnCompleteFrame(std::move(frame));
507 event_->Wait(rtc::Event::kForever);
Markus Handell269ac812019-12-03 14:31:45 +0100508 }
509
510 protected:
511 GlobalSimulatedTimeController time_controller_;
512 test::FunctionVideoDecoderFactory fake_decoder_factory_;
513 std::unique_ptr<ProcessThread> process_thread_;
514 MockTransport mock_transport_;
515 cricket::FakeVideoRenderer fake_renderer_;
516 VideoReceiveStream::Config config_;
517 CallStats call_stats_;
518 PacketRouter packet_router_;
519 RtpStreamReceiverController rtp_stream_receiver_controller_;
520 webrtc::internal::VideoReceiveStream video_receive_stream_;
521 std::unique_ptr<rtc::Event> event_;
522};
523
524TEST_F(VideoReceiveStreamTestWithSimulatedClock,
525 RequestsKeyFramesUntilKeyFrameReceived) {
526 auto tick =
527 TimeDelta::ms(internal::VideoReceiveStream::kMaxWaitForKeyFrameMs / 2);
528 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
529 video_receive_stream_.GenerateKeyFrame();
530 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
Markus Handell486cc552019-12-03 14:37:28 +0100531 time_controller_.AdvanceTime(tick);
Markus Handell269ac812019-12-03 14:31:45 +0100532 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
533 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
534
535 // T+200ms: still no key frame received, expect key frame request sent again.
536 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
Markus Handell486cc552019-12-03 14:37:28 +0100537 time_controller_.AdvanceTime(tick);
Markus Handell269ac812019-12-03 14:31:45 +0100538 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
539 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
540
541 // T+200ms: now send a key frame - we should not observe new key frame
542 // requests after this.
543 EXPECT_CALL(mock_transport_, SendRtcp).Times(0);
544 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameKey, 3));
Markus Handell486cc552019-12-03 14:37:28 +0100545 time_controller_.AdvanceTime(2 * tick);
Markus Handell269ac812019-12-03 14:31:45 +0100546 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
547}
548
johanf2183ff2017-02-28 01:33:09 -0800549} // namespace webrtc