Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(824)

Side by Side Diff: media/cast/transport/pacing/paced_sender_unittest.cc

Issue 388663003: Cast: Reshuffle files under media/cast (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: missing includes Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/cast/transport/pacing/paced_sender.cc ('k') | media/cast/transport/rtcp/rtcp_builder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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.
4
5 #include <stdint.h>
6
7 #include "base/big_endian.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "media/cast/logging/simple_event_subscriber.h"
10 #include "media/cast/test/fake_single_thread_task_runner.h"
11 #include "media/cast/transport/pacing/paced_sender.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13
14 namespace media {
15 namespace cast {
16 namespace transport {
17
18 using testing::_;
19
20 static const uint8 kValue = 123;
21 static const size_t kSize1 = 100;
22 static const size_t kSize2 = 101;
23 static const size_t kSize3 = 102;
24 static const size_t kSize4 = 103;
25 static const size_t kNackSize = 104;
26 static const int64 kStartMillisecond = INT64_C(12345678900000);
27 static const uint32 kVideoSsrc = 0x1234;
28 static const uint32 kAudioSsrc = 0x5678;
29
30 class TestPacketSender : public PacketSender {
31 public:
32 TestPacketSender() {}
33
34 virtual bool SendPacket(PacketRef packet, const base::Closure& cb) OVERRIDE {
35 EXPECT_FALSE(expected_packet_size_.empty());
36 size_t expected_packet_size = expected_packet_size_.front();
37 expected_packet_size_.pop_front();
38 EXPECT_EQ(expected_packet_size, packet->data.size());
39 return true;
40 }
41
42 void AddExpectedSize(int expected_packet_size, int repeat_count) {
43 for (int i = 0; i < repeat_count; ++i) {
44 expected_packet_size_.push_back(expected_packet_size);
45 }
46 }
47
48 public:
49 std::list<int> expected_packet_size_;
50
51 DISALLOW_COPY_AND_ASSIGN(TestPacketSender);
52 };
53
54 class PacedSenderTest : public ::testing::Test {
55 protected:
56 PacedSenderTest() {
57 logging_.AddRawEventSubscriber(&subscriber_);
58 testing_clock_.Advance(
59 base::TimeDelta::FromMilliseconds(kStartMillisecond));
60 task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_);
61 paced_sender_.reset(new PacedSender(
62 &testing_clock_, &logging_, &mock_transport_, task_runner_));
63 paced_sender_->RegisterAudioSsrc(kAudioSsrc);
64 paced_sender_->RegisterVideoSsrc(kVideoSsrc);
65 }
66
67 virtual ~PacedSenderTest() {
68 logging_.RemoveRawEventSubscriber(&subscriber_);
69 }
70
71 static void UpdateCastTransportStatus(transport::CastTransportStatus status) {
72 NOTREACHED();
73 }
74
75 SendPacketVector CreateSendPacketVector(size_t packet_size,
76 int num_of_packets_in_frame,
77 bool audio) {
78 DCHECK_GE(packet_size, 12u);
79 SendPacketVector packets;
80 base::TimeTicks frame_tick = testing_clock_.NowTicks();
81 // Advance the clock so that we don't get the same frame_tick
82 // next time this function is called.
83 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1));
84 for (int i = 0; i < num_of_packets_in_frame; ++i) {
85 PacketKey key = PacedPacketSender::MakePacketKey(
86 frame_tick,
87 audio ? kAudioSsrc : kVideoSsrc, // ssrc
88 i);
89
90 PacketRef packet(new base::RefCountedData<Packet>);
91 packet->data.resize(packet_size, kValue);
92 // Write ssrc to packet so that it can be recognized as a
93 // "video frame" for logging purposes.
94 base::BigEndianWriter writer(
95 reinterpret_cast<char*>(&packet->data[8]), 4);
96 bool success = writer.WriteU32(audio ? kAudioSsrc : kVideoSsrc);
97 DCHECK(success);
98 packets.push_back(std::make_pair(key, packet));
99 }
100 return packets;
101 }
102
103 // Use this function to drain the packet list in PacedSender without having
104 // to test the pacing implementation details.
105 bool RunUntilEmpty(int max_tries) {
106 for (int i = 0; i < max_tries; i++) {
107 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10));
108 task_runner_->RunTasks();
109 if (mock_transport_.expected_packet_size_.empty())
110 return true;
111 i++;
112 }
113
114 return mock_transport_.expected_packet_size_.empty();
115 }
116
117 LoggingImpl logging_;
118 SimpleEventSubscriber subscriber_;
119 base::SimpleTestTickClock testing_clock_;
120 TestPacketSender mock_transport_;
121 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
122 scoped_ptr<PacedSender> paced_sender_;
123
124 DISALLOW_COPY_AND_ASSIGN(PacedSenderTest);
125 };
126
127 TEST_F(PacedSenderTest, PassThroughRtcp) {
128 mock_transport_.AddExpectedSize(kSize1, 2);
129 SendPacketVector packets = CreateSendPacketVector(kSize1, 1, true);
130
131 EXPECT_TRUE(paced_sender_->SendPackets(packets));
132 EXPECT_TRUE(paced_sender_->ResendPackets(packets, base::TimeDelta()));
133
134 mock_transport_.AddExpectedSize(kSize2, 1);
135 Packet tmp(kSize2, kValue);
136 EXPECT_TRUE(paced_sender_->SendRtcpPacket(
137 1,
138 new base::RefCountedData<Packet>(tmp)));
139 }
140
141 TEST_F(PacedSenderTest, BasicPace) {
142 int num_of_packets = 27;
143 SendPacketVector packets = CreateSendPacketVector(kSize1,
144 num_of_packets,
145 false);
146
147 mock_transport_.AddExpectedSize(kSize1, 10);
148 EXPECT_TRUE(paced_sender_->SendPackets(packets));
149
150 // Check that we get the next burst.
151 mock_transport_.AddExpectedSize(kSize1, 10);
152
153 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(10);
154 testing_clock_.Advance(timeout);
155 task_runner_->RunTasks();
156
157 // If we call process too early make sure we don't send any packets.
158 timeout = base::TimeDelta::FromMilliseconds(5);
159 testing_clock_.Advance(timeout);
160 task_runner_->RunTasks();
161
162 // Check that we get the next burst.
163 mock_transport_.AddExpectedSize(kSize1, 7);
164 testing_clock_.Advance(timeout);
165 task_runner_->RunTasks();
166
167 // Check that we don't get any more packets.
168 EXPECT_TRUE(RunUntilEmpty(3));
169
170 std::vector<PacketEvent> packet_events;
171 subscriber_.GetPacketEventsAndReset(&packet_events);
172 EXPECT_EQ(num_of_packets, static_cast<int>(packet_events.size()));
173 int sent_to_network_event_count = 0;
174 for (std::vector<PacketEvent>::iterator it = packet_events.begin();
175 it != packet_events.end();
176 ++it) {
177 if (it->type == PACKET_SENT_TO_NETWORK)
178 sent_to_network_event_count++;
179 else
180 FAIL() << "Got unexpected event type " << CastLoggingToString(it->type);
181 }
182 EXPECT_EQ(num_of_packets, sent_to_network_event_count);
183 }
184
185 TEST_F(PacedSenderTest, PaceWithNack) {
186 // Testing what happen when we get multiple NACK requests for a fully lost
187 // frames just as we sent the first packets in a frame.
188 int num_of_packets_in_frame = 12;
189 int num_of_packets_in_nack = 12;
190
191 SendPacketVector nack_packets =
192 CreateSendPacketVector(kNackSize, num_of_packets_in_nack, false);
193
194 SendPacketVector first_frame_packets =
195 CreateSendPacketVector(kSize1, num_of_packets_in_frame, false);
196
197 SendPacketVector second_frame_packets =
198 CreateSendPacketVector(kSize2, num_of_packets_in_frame, true);
199
200 // Check that the first burst of the frame go out on the wire.
201 mock_transport_.AddExpectedSize(kSize1, 10);
202 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets));
203
204 // Add first NACK request.
205 EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets, base::TimeDelta()));
206
207 // Check that we get the first NACK burst.
208 mock_transport_.AddExpectedSize(kNackSize, 10);
209 base::TimeDelta timeout = base::TimeDelta::FromMilliseconds(10);
210 testing_clock_.Advance(timeout);
211 task_runner_->RunTasks();
212
213 // Add second NACK request.
214 EXPECT_TRUE(paced_sender_->ResendPackets(nack_packets, base::TimeDelta()));
215
216 // Check that we get the next NACK burst.
217 mock_transport_.AddExpectedSize(kNackSize, 10);
218 testing_clock_.Advance(timeout);
219 task_runner_->RunTasks();
220
221 // End of NACK plus two packets from the oldest frame.
222 // Note that two of the NACKs have been de-duped.
223 mock_transport_.AddExpectedSize(kNackSize, 2);
224 mock_transport_.AddExpectedSize(kSize1, 2);
225 testing_clock_.Advance(timeout);
226 task_runner_->RunTasks();
227
228 // Add second frame.
229 // Make sure we don't delay the second frame due to the previous packets.
230 mock_transport_.AddExpectedSize(kSize2, 10);
231 EXPECT_TRUE(paced_sender_->SendPackets(second_frame_packets));
232
233 // Last packets of frame 2.
234 mock_transport_.AddExpectedSize(kSize2, 2);
235 testing_clock_.Advance(timeout);
236 task_runner_->RunTasks();
237
238 // No more packets.
239 EXPECT_TRUE(RunUntilEmpty(5));
240
241 std::vector<PacketEvent> packet_events;
242 subscriber_.GetPacketEventsAndReset(&packet_events);
243 int expected_video_network_event_count = num_of_packets_in_frame;
244 int expected_video_retransmitted_event_count = 2 * num_of_packets_in_nack;
245 expected_video_retransmitted_event_count -= 2; // 2 packets deduped
246 int expected_audio_network_event_count = num_of_packets_in_frame;
247 EXPECT_EQ(expected_video_network_event_count +
248 expected_video_retransmitted_event_count +
249 expected_audio_network_event_count,
250 static_cast<int>(packet_events.size()));
251 int audio_network_event_count = 0;
252 int video_network_event_count = 0;
253 int video_retransmitted_event_count = 0;
254 for (std::vector<PacketEvent>::iterator it = packet_events.begin();
255 it != packet_events.end();
256 ++it) {
257 if (it->type == PACKET_SENT_TO_NETWORK) {
258 if (it->media_type == VIDEO_EVENT)
259 video_network_event_count++;
260 else
261 audio_network_event_count++;
262 } else if (it->type == PACKET_RETRANSMITTED) {
263 if (it->media_type == VIDEO_EVENT)
264 video_retransmitted_event_count++;
265 } else {
266 FAIL() << "Got unexpected event type " << CastLoggingToString(it->type);
267 }
268 }
269 EXPECT_EQ(expected_audio_network_event_count, audio_network_event_count);
270 EXPECT_EQ(expected_video_network_event_count, video_network_event_count);
271 EXPECT_EQ(expected_video_retransmitted_event_count,
272 video_retransmitted_event_count);
273 }
274
275 TEST_F(PacedSenderTest, PaceWith60fps) {
276 // Testing what happen when we get multiple NACK requests for a fully lost
277 // frames just as we sent the first packets in a frame.
278 int num_of_packets_in_frame = 17;
279
280 SendPacketVector first_frame_packets =
281 CreateSendPacketVector(kSize1, num_of_packets_in_frame, false);
282
283 SendPacketVector second_frame_packets =
284 CreateSendPacketVector(kSize2, num_of_packets_in_frame, false);
285
286 SendPacketVector third_frame_packets =
287 CreateSendPacketVector(kSize3, num_of_packets_in_frame, false);
288
289 SendPacketVector fourth_frame_packets =
290 CreateSendPacketVector(kSize4, num_of_packets_in_frame, false);
291
292 base::TimeDelta timeout_10ms = base::TimeDelta::FromMilliseconds(10);
293
294 // Check that the first burst of the frame go out on the wire.
295 mock_transport_.AddExpectedSize(kSize1, 10);
296 EXPECT_TRUE(paced_sender_->SendPackets(first_frame_packets));
297
298 mock_transport_.AddExpectedSize(kSize1, 7);
299 testing_clock_.Advance(timeout_10ms);
300 task_runner_->RunTasks();
301
302 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(6));
303
304 // Add second frame, after 16 ms.
305 mock_transport_.AddExpectedSize(kSize2, 3);
306 EXPECT_TRUE(paced_sender_->SendPackets(second_frame_packets));
307 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(4));
308
309 mock_transport_.AddExpectedSize(kSize2, 10);
310 testing_clock_.Advance(timeout_10ms);
311 task_runner_->RunTasks();
312
313 mock_transport_.AddExpectedSize(kSize2, 4);
314 testing_clock_.Advance(timeout_10ms);
315 task_runner_->RunTasks();
316
317 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(3));
318
319 // Add third frame, after 33 ms.
320 mock_transport_.AddExpectedSize(kSize3, 6);
321 EXPECT_TRUE(paced_sender_->SendPackets(third_frame_packets));
322
323 mock_transport_.AddExpectedSize(kSize3, 10);
324 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(7));
325 task_runner_->RunTasks();
326
327 // Add fourth frame, after 50 ms.
328 EXPECT_TRUE(paced_sender_->SendPackets(fourth_frame_packets));
329
330 mock_transport_.AddExpectedSize(kSize3, 1);
331 mock_transport_.AddExpectedSize(kSize4, 9);
332 testing_clock_.Advance(timeout_10ms);
333 task_runner_->RunTasks();
334
335 mock_transport_.AddExpectedSize(kSize4, 8);
336 testing_clock_.Advance(timeout_10ms);
337 task_runner_->RunTasks();
338
339 testing_clock_.Advance(timeout_10ms);
340 task_runner_->RunTasks();
341
342 testing_clock_.Advance(timeout_10ms);
343 task_runner_->RunTasks();
344
345 // No more packets.
346 EXPECT_TRUE(RunUntilEmpty(5));
347 }
348
349 } // namespace transport
350 } // namespace cast
351 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/transport/pacing/paced_sender.cc ('k') | media/cast/transport/rtcp/rtcp_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698