1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <gtest/gtest.h>
9 #include "base/bind_helpers.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/test/simple_test_tick_clock.h"
12 #include "base/values.h"
13 #include "media/cast/cast_config.h"
14 #include "media/cast/net/cast_transport_config.h"
15 #include "media/cast/net/cast_transport_sender_impl.h"
16 #include "media/cast/net/rtcp/rtcp.h"
17 #include "media/cast/test/fake_single_thread_task_runner.h"
18 #include "testing/gtest/include/gtest/gtest.h"
24 const int64 kStartMillisecond
= INT64_C(12345678900000);
25 const uint32 kVideoSsrc
= 1;
26 const uint32 kAudioSsrc
= 2;
29 class FakePacketSender
: public PacketSender
{
32 : paused_(false), packets_sent_(0), bytes_sent_(0) {}
34 bool SendPacket(PacketRef packet
, const base::Closure
& cb
) final
{
36 stored_packet_
= packet
;
41 bytes_sent_
+= packet
->data
.size();
45 int64
GetBytesSent() final
{ return bytes_sent_
; }
47 void SetPaused(bool paused
) {
49 if (!paused
&& stored_packet_
.get()) {
50 SendPacket(stored_packet_
, callback_
);
55 int packets_sent() const { return packets_sent_
; }
59 base::Closure callback_
;
60 PacketRef stored_packet_
;
64 DISALLOW_COPY_AND_ASSIGN(FakePacketSender
);
67 class CastTransportSenderImplTest
: public ::testing::Test
{
69 CastTransportSenderImplTest()
70 : num_times_callback_called_(0) {
71 testing_clock_
.Advance(
72 base::TimeDelta::FromMilliseconds(kStartMillisecond
));
73 task_runner_
= new test::FakeSingleThreadTaskRunner(&testing_clock_
);
76 ~CastTransportSenderImplTest() override
{}
78 void InitWithoutLogging() {
79 transport_sender_
.reset(
80 new CastTransportSenderImpl(NULL
,
84 make_scoped_ptr(new base::DictionaryValue
),
85 base::Bind(&UpdateCastTransportStatus
),
86 BulkRawEventsCallback(),
89 PacketReceiverCallback(),
91 task_runner_
->RunTasks();
94 void InitWithOptions() {
95 scoped_ptr
<base::DictionaryValue
> options(
96 new base::DictionaryValue
);
97 options
->SetBoolean("DHCP", true);
98 options
->SetBoolean("disable_wifi_scan", true);
99 options
->SetBoolean("media_streaming_mode", true);
100 options
->SetInteger("pacer_target_burst_size", 20);
101 options
->SetInteger("pacer_max_burst_size", 100);
102 transport_sender_
.reset(
103 new CastTransportSenderImpl(NULL
,
108 base::Bind(&UpdateCastTransportStatus
),
109 BulkRawEventsCallback(),
112 PacketReceiverCallback(),
114 task_runner_
->RunTasks();
117 void InitWithLogging() {
118 transport_sender_
.reset(new CastTransportSenderImpl(
123 make_scoped_ptr(new base::DictionaryValue
),
124 base::Bind(&UpdateCastTransportStatus
),
125 base::Bind(&CastTransportSenderImplTest::LogRawEvents
,
126 base::Unretained(this)),
127 base::TimeDelta::FromMilliseconds(10),
129 PacketReceiverCallback(),
131 task_runner_
->RunTasks();
134 void InitializeVideo() {
135 CastTransportRtpConfig rtp_config
;
136 rtp_config
.ssrc
= kVideoSsrc
;
137 rtp_config
.feedback_ssrc
= 2;
138 rtp_config
.rtp_payload_type
= 3;
139 transport_sender_
->InitializeVideo(rtp_config
,
140 RtcpCastMessageCallback(),
144 void InitializeAudio() {
145 CastTransportRtpConfig rtp_config
;
146 rtp_config
.ssrc
= kAudioSsrc
;
147 rtp_config
.feedback_ssrc
= 3;
148 rtp_config
.rtp_payload_type
= 4;
149 transport_sender_
->InitializeAudio(rtp_config
,
150 RtcpCastMessageCallback(),
154 void LogRawEvents(const std::vector
<PacketEvent
>& packet_events
,
155 const std::vector
<FrameEvent
>& frame_events
) {
156 num_times_callback_called_
++;
159 static void UpdateCastTransportStatus(CastTransportStatus status
) {
162 base::SimpleTestTickClock testing_clock_
;
163 scoped_refptr
<test::FakeSingleThreadTaskRunner
> task_runner_
;
164 scoped_ptr
<CastTransportSenderImpl
> transport_sender_
;
165 FakePacketSender transport_
;
166 int num_times_callback_called_
;
169 TEST_F(CastTransportSenderImplTest
, InitWithoutLogging
) {
170 InitWithoutLogging();
171 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(50));
172 EXPECT_EQ(0, num_times_callback_called_
);
175 TEST_F(CastTransportSenderImplTest
, InitWithLogging
) {
177 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(50));
178 EXPECT_EQ(5, num_times_callback_called_
);
181 TEST_F(CastTransportSenderImplTest
, InitWithOptions
) {
183 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(50));
184 EXPECT_EQ(0, num_times_callback_called_
);
187 TEST_F(CastTransportSenderImplTest
, NacksCancelRetransmits
) {
188 InitWithoutLogging();
190 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(50));
192 // A fake frame that will be decomposed into 4 packets.
193 EncodedFrame fake_frame
;
194 fake_frame
.frame_id
= 1;
195 fake_frame
.rtp_timestamp
= 1;
196 fake_frame
.dependency
= EncodedFrame::KEY
;
197 fake_frame
.data
.resize(5000, ' ');
199 transport_sender_
->InsertFrame(kVideoSsrc
, fake_frame
);
200 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
201 EXPECT_EQ(4, transport_
.packets_sent());
204 MissingFramesAndPacketsMap missing_packets
;
205 missing_packets
[1].insert(0);
206 missing_packets
[1].insert(1);
207 missing_packets
[1].insert(2);
209 transport_
.SetPaused(true);
210 DedupInfo dedup_info
;
211 dedup_info
.resend_interval
= base::TimeDelta::FromMilliseconds(10);
212 transport_sender_
->ResendPackets(
213 kVideoSsrc
, missing_packets
, true, dedup_info
);
215 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
217 RtcpCastMessage cast_message
;
218 cast_message
.media_ssrc
= kVideoSsrc
;
219 cast_message
.ack_frame_id
= 1;
220 cast_message
.missing_frames_and_packets
[1].insert(3);
221 transport_sender_
->OnReceivedCastMessage(kVideoSsrc
,
222 RtcpCastMessageCallback(),
224 transport_
.SetPaused(false);
225 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
227 // Resend one packet in the socket when unpaused.
228 // Resend one more packet from NACK.
229 EXPECT_EQ(6, transport_
.packets_sent());
232 TEST_F(CastTransportSenderImplTest
, CancelRetransmits
) {
233 InitWithoutLogging();
235 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(50));
237 // A fake frame that will be decomposed into 4 packets.
238 EncodedFrame fake_frame
;
239 fake_frame
.frame_id
= 1;
240 fake_frame
.rtp_timestamp
= 1;
241 fake_frame
.dependency
= EncodedFrame::KEY
;
242 fake_frame
.data
.resize(5000, ' ');
244 transport_sender_
->InsertFrame(kVideoSsrc
, fake_frame
);
245 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
246 EXPECT_EQ(4, transport_
.packets_sent());
248 // Resend all packets for frame 1.
249 MissingFramesAndPacketsMap missing_packets
;
250 missing_packets
[1].insert(kRtcpCastAllPacketsLost
);
252 transport_
.SetPaused(true);
253 DedupInfo dedup_info
;
254 dedup_info
.resend_interval
= base::TimeDelta::FromMilliseconds(10);
255 transport_sender_
->ResendPackets(
256 kVideoSsrc
, missing_packets
, true, dedup_info
);
258 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
259 std::vector
<uint32
> cancel_sending_frames
;
260 cancel_sending_frames
.push_back(1);
261 transport_sender_
->CancelSendingFrames(kVideoSsrc
,
262 cancel_sending_frames
);
263 transport_
.SetPaused(false);
264 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
266 // Resend one packet in the socket when unpaused.
267 EXPECT_EQ(5, transport_
.packets_sent());
270 TEST_F(CastTransportSenderImplTest
, Kickstart
) {
271 InitWithoutLogging();
273 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(50));
275 // A fake frame that will be decomposed into 4 packets.
276 EncodedFrame fake_frame
;
277 fake_frame
.frame_id
= 1;
278 fake_frame
.rtp_timestamp
= 1;
279 fake_frame
.dependency
= EncodedFrame::KEY
;
280 fake_frame
.data
.resize(5000, ' ');
282 transport_
.SetPaused(true);
283 transport_sender_
->InsertFrame(kVideoSsrc
, fake_frame
);
284 transport_sender_
->ResendFrameForKickstart(kVideoSsrc
, 1);
285 transport_
.SetPaused(false);
286 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
287 EXPECT_EQ(4, transport_
.packets_sent());
289 // Resend 2 packets for frame 1.
290 MissingFramesAndPacketsMap missing_packets
;
291 missing_packets
[1].insert(0);
292 missing_packets
[1].insert(1);
294 transport_
.SetPaused(true);
295 DedupInfo dedup_info
;
296 dedup_info
.resend_interval
= base::TimeDelta::FromMilliseconds(10);
297 transport_sender_
->ResendPackets(
298 kVideoSsrc
, missing_packets
, true, dedup_info
);
299 transport_sender_
->ResendFrameForKickstart(kVideoSsrc
, 1);
300 transport_
.SetPaused(false);
301 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
303 // Resend one packet in the socket when unpaused.
304 // Two more retransmission packets sent.
305 EXPECT_EQ(7, transport_
.packets_sent());
308 TEST_F(CastTransportSenderImplTest
, DedupRetransmissionWithAudio
) {
309 InitWithoutLogging();
312 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(50));
314 // Send two audio frames.
315 EncodedFrame fake_audio
;
316 fake_audio
.frame_id
= 1;
317 fake_audio
.reference_time
= testing_clock_
.NowTicks();
318 fake_audio
.dependency
= EncodedFrame::KEY
;
319 fake_audio
.data
.resize(100, ' ');
320 transport_sender_
->InsertFrame(kAudioSsrc
, fake_audio
);
321 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(2));
322 fake_audio
.frame_id
= 2;
323 fake_audio
.reference_time
= testing_clock_
.NowTicks();
324 transport_sender_
->InsertFrame(kAudioSsrc
, fake_audio
);
325 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(2));
326 EXPECT_EQ(2, transport_
.packets_sent());
328 // Ack the first audio frame.
329 RtcpCastMessage cast_message
;
330 cast_message
.media_ssrc
= kAudioSsrc
;
331 cast_message
.ack_frame_id
= 1;
332 transport_sender_
->OnReceivedCastMessage(kAudioSsrc
,
333 RtcpCastMessageCallback(),
335 task_runner_
->RunTasks();
336 EXPECT_EQ(2, transport_
.packets_sent());
338 // Send a fake video frame that will be decomposed into 4 packets.
339 EncodedFrame fake_video
;
340 fake_video
.frame_id
= 1;
341 fake_video
.dependency
= EncodedFrame::KEY
;
342 fake_video
.data
.resize(5000, ' ');
343 transport_sender_
->InsertFrame(kVideoSsrc
, fake_video
);
344 task_runner_
->RunTasks();
345 EXPECT_EQ(6, transport_
.packets_sent());
347 // Retransmission is reject because audio is not acked yet.
348 cast_message
.media_ssrc
= kVideoSsrc
;
349 cast_message
.ack_frame_id
= 0;
350 cast_message
.missing_frames_and_packets
[1].insert(3);
351 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(10));
352 transport_sender_
->OnReceivedCastMessage(kVideoSsrc
,
353 RtcpCastMessageCallback(),
355 task_runner_
->RunTasks();
356 EXPECT_EQ(6, transport_
.packets_sent());
358 // Ack the second audio frame.
359 cast_message
.media_ssrc
= kAudioSsrc
;
360 cast_message
.ack_frame_id
= 2;
361 cast_message
.missing_frames_and_packets
.clear();
362 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(2));
363 transport_sender_
->OnReceivedCastMessage(kAudioSsrc
,
364 RtcpCastMessageCallback(),
366 task_runner_
->RunTasks();
367 EXPECT_EQ(6, transport_
.packets_sent());
369 // Retransmission of video packet now accepted.
370 cast_message
.media_ssrc
= kVideoSsrc
;
371 cast_message
.ack_frame_id
= 1;
372 cast_message
.missing_frames_and_packets
[1].insert(3);
373 task_runner_
->Sleep(base::TimeDelta::FromMilliseconds(2));
374 transport_sender_
->OnReceivedCastMessage(kVideoSsrc
,
375 RtcpCastMessageCallback(),
377 task_runner_
->RunTasks();
378 EXPECT_EQ(7, transport_
.packets_sent());