Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / cast / net / rtp / cast_message_builder_unittest.cc
blobbae827a5a8ca419b771ce1e6802e6ea985560f72
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 <stdint.h>
7 #include "base/memory/scoped_ptr.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "media/cast/net/rtcp/rtcp.h"
10 #include "media/cast/net/rtp/cast_message_builder.h"
11 #include "media/cast/net/rtp/framer.h"
12 #include "media/cast/net/rtp/rtp_receiver_defines.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace media {
16 namespace cast {
18 namespace {
19 static const uint32 kSsrc = 0x1234;
20 static const uint32 kShortTimeIncrementMs = 10;
21 static const uint32 kLongTimeIncrementMs = 40;
22 static const int64 kStartMillisecond = INT64_C(12345678900000);
24 typedef std::map<uint32, size_t> MissingPacketsMap;
26 class NackFeedbackVerification : public RtpPayloadFeedback {
27 public:
28 NackFeedbackVerification()
29 : triggered_(false), missing_packets_(), last_frame_acked_(0) {}
31 void CastFeedback(const RtcpCastMessage& cast_feedback) final {
32 EXPECT_EQ(kSsrc, cast_feedback.media_ssrc);
34 last_frame_acked_ = cast_feedback.ack_frame_id;
36 MissingFramesAndPacketsMap::const_iterator frame_it =
37 cast_feedback.missing_frames_and_packets.begin();
39 // Keep track of the number of missing packets per frame.
40 missing_packets_.clear();
41 while (frame_it != cast_feedback.missing_frames_and_packets.end()) {
42 // Check for complete frame lost.
43 if ((frame_it->second.size() == 1) &&
44 (*frame_it->second.begin() == kRtcpCastAllPacketsLost)) {
45 missing_packets_.insert(
46 std::make_pair(frame_it->first, kRtcpCastAllPacketsLost));
47 } else {
48 missing_packets_.insert(
49 std::make_pair(frame_it->first, frame_it->second.size()));
51 ++frame_it;
53 triggered_ = true;
56 size_t num_missing_packets(uint32 frame_id) {
57 MissingPacketsMap::iterator it;
58 it = missing_packets_.find(frame_id);
59 if (it == missing_packets_.end())
60 return 0;
62 return it->second;
65 // Holds value for one call.
66 bool triggered() {
67 bool ret_val = triggered_;
68 triggered_ = false;
69 return ret_val;
72 uint32 last_frame_acked() { return last_frame_acked_; }
74 private:
75 bool triggered_;
76 MissingPacketsMap missing_packets_; // Missing packets per frame.
77 uint32 last_frame_acked_;
79 DISALLOW_COPY_AND_ASSIGN(NackFeedbackVerification);
81 } // namespace
83 class CastMessageBuilderTest : public ::testing::Test {
84 protected:
85 CastMessageBuilderTest()
86 : framer_(&testing_clock_,
87 &feedback_,
88 kSsrc,
89 true,
90 10),
91 cast_msg_builder_(new CastMessageBuilder(&testing_clock_,
92 &feedback_,
93 &framer_,
94 kSsrc,
95 true,
96 0)) {
97 rtp_header_.sender_ssrc = kSsrc;
98 rtp_header_.is_key_frame = false;
99 testing_clock_.Advance(
100 base::TimeDelta::FromMilliseconds(kStartMillisecond));
103 ~CastMessageBuilderTest() override {}
105 void SetFrameIds(uint32 frame_id, uint32 reference_frame_id) {
106 rtp_header_.frame_id = frame_id;
107 rtp_header_.reference_frame_id = reference_frame_id;
110 void SetPacketId(uint16 packet_id) { rtp_header_.packet_id = packet_id; }
112 void SetMaxPacketId(uint16 max_packet_id) {
113 rtp_header_.max_packet_id = max_packet_id;
116 void SetKeyFrame(bool is_key) { rtp_header_.is_key_frame = is_key; }
118 void InsertPacket() {
119 bool duplicate;
120 uint8 payload = 0;
121 if (framer_.InsertPacket(&payload, 1, rtp_header_, &duplicate)) {
122 cast_msg_builder_->CompleteFrameReceived(rtp_header_.frame_id);
124 cast_msg_builder_->UpdateCastMessage();
127 void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) {
128 cast_msg_builder_.reset(new CastMessageBuilder(&testing_clock_,
129 &feedback_,
130 &framer_,
131 kSsrc,
132 false,
133 max_unacked_frames));
136 NackFeedbackVerification feedback_;
137 Framer framer_;
138 scoped_ptr<CastMessageBuilder> cast_msg_builder_;
139 RtpCastHeader rtp_header_;
140 base::SimpleTestTickClock testing_clock_;
142 DISALLOW_COPY_AND_ASSIGN(CastMessageBuilderTest);
145 TEST_F(CastMessageBuilderTest, OneFrameNackList) {
146 SetFrameIds(0, 0);
147 SetPacketId(4);
148 SetMaxPacketId(10);
149 InsertPacket();
150 testing_clock_.Advance(
151 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
152 EXPECT_FALSE(feedback_.triggered());
153 testing_clock_.Advance(
154 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
155 SetPacketId(5);
156 InsertPacket();
157 EXPECT_TRUE(feedback_.triggered());
158 EXPECT_EQ(4u, feedback_.num_missing_packets(0));
161 TEST_F(CastMessageBuilderTest, CompleteFrameMissing) {
162 SetFrameIds(0, 0);
163 SetPacketId(2);
164 SetMaxPacketId(5);
165 InsertPacket();
166 testing_clock_.Advance(
167 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
168 SetFrameIds(2, 1);
169 SetPacketId(2);
170 SetMaxPacketId(5);
171 InsertPacket();
172 EXPECT_TRUE(feedback_.triggered());
173 EXPECT_EQ(kRtcpCastAllPacketsLost, feedback_.num_missing_packets(1));
176 TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
177 SetFrameIds(1, 0);
178 SetPacketId(0);
179 SetMaxPacketId(1);
180 InsertPacket();
181 EXPECT_FALSE(feedback_.triggered());
182 testing_clock_.Advance(
183 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
184 SetFrameIds(2, 1);
185 SetPacketId(0);
186 SetMaxPacketId(0);
187 InsertPacket();
188 EXPECT_TRUE(feedback_.triggered());
189 testing_clock_.Advance(
190 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
191 SetFrameIds(3, 2);
192 SetPacketId(0);
193 SetMaxPacketId(5);
194 InsertPacket();
195 EXPECT_TRUE(feedback_.triggered());
196 EXPECT_EQ(2u, feedback_.last_frame_acked());
197 testing_clock_.Advance(
198 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
199 SetFrameIds(5, 5);
200 SetPacketId(0);
201 SetMaxPacketId(0);
202 SetKeyFrame(true);
203 InsertPacket();
204 testing_clock_.Advance(
205 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
206 framer_.RemoveOldFrames(5); // Simulate 5 being pulled for rendering.
207 cast_msg_builder_->UpdateCastMessage();
208 EXPECT_TRUE(feedback_.triggered());
209 EXPECT_EQ(5u, feedback_.last_frame_acked());
210 testing_clock_.Advance(
211 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
212 SetFrameIds(1, 0);
213 SetPacketId(1);
214 SetMaxPacketId(1);
215 InsertPacket();
216 EXPECT_FALSE(feedback_.triggered());
217 testing_clock_.Advance(
218 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
219 InsertPacket();
220 EXPECT_TRUE(feedback_.triggered());
221 EXPECT_EQ(5u, feedback_.last_frame_acked());
224 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) {
225 SetFrameIds(0, 0);
226 SetPacketId(0);
227 SetMaxPacketId(20);
228 SetKeyFrame(true);
229 InsertPacket();
230 testing_clock_.Advance(
231 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
232 SetPacketId(5);
233 InsertPacket();
234 EXPECT_TRUE(feedback_.triggered());
235 EXPECT_EQ(4u, feedback_.num_missing_packets(0));
238 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
239 SetFrameIds(0, 0);
240 SetPacketId(0);
241 SetMaxPacketId(20);
242 SetKeyFrame(true);
243 InsertPacket();
244 testing_clock_.Advance(
245 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
246 SetPacketId(5);
247 InsertPacket();
248 testing_clock_.Advance(
249 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
250 EXPECT_TRUE(feedback_.triggered());
251 EXPECT_EQ(4u, feedback_.num_missing_packets(0));
252 SetFrameIds(1, 0);
253 SetMaxPacketId(2);
254 SetPacketId(0);
255 SetKeyFrame(false);
256 InsertPacket();
257 testing_clock_.Advance(
258 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
259 EXPECT_TRUE(feedback_.triggered());
260 EXPECT_EQ(19u, feedback_.num_missing_packets(0));
263 TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) {
264 SetFrameIds(0, 0);
265 SetPacketId(0);
266 SetMaxPacketId(20);
267 SetKeyFrame(true);
268 InsertPacket();
269 testing_clock_.Advance(
270 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
271 SetPacketId(5);
272 InsertPacket();
273 testing_clock_.Advance(
274 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
275 EXPECT_TRUE(feedback_.triggered());
276 EXPECT_EQ(4u, feedback_.num_missing_packets(0));
277 SetFrameIds(1, 1);
278 SetMaxPacketId(0);
279 SetPacketId(0);
280 SetKeyFrame(true);
281 InsertPacket();
282 testing_clock_.Advance(
283 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
284 EXPECT_TRUE(feedback_.triggered());
285 EXPECT_EQ(0u, feedback_.num_missing_packets(0));
288 TEST_F(CastMessageBuilderTest, Reset) {
289 InsertPacket();
290 testing_clock_.Advance(
291 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
292 cast_msg_builder_->Reset();
293 framer_.Reset();
294 // Should reset nack list state and request a key frame.
295 cast_msg_builder_->UpdateCastMessage();
296 EXPECT_TRUE(feedback_.triggered());
297 EXPECT_EQ(0u, feedback_.num_missing_packets(0));
300 TEST_F(CastMessageBuilderTest, DeltaAfterReset) {
301 SetFrameIds(0, 0);
302 SetPacketId(0);
303 SetMaxPacketId(0);
304 SetKeyFrame(true);
305 InsertPacket();
306 EXPECT_TRUE(feedback_.triggered());
307 EXPECT_EQ(0u, feedback_.num_missing_packets(0));
308 testing_clock_.Advance(
309 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
310 cast_msg_builder_->Reset();
311 SetFrameIds(1, 0);
312 SetPacketId(0);
313 SetMaxPacketId(0);
314 SetKeyFrame(true);
315 EXPECT_FALSE(feedback_.triggered());
318 TEST_F(CastMessageBuilderTest, BasicRps) {
319 SetFrameIds(0, 0);
320 SetPacketId(0);
321 SetMaxPacketId(0);
322 SetKeyFrame(true);
323 InsertPacket();
324 testing_clock_.Advance(
325 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
326 EXPECT_TRUE(feedback_.triggered());
327 EXPECT_EQ(0u, feedback_.last_frame_acked());
328 SetFrameIds(3, 0);
329 SetKeyFrame(false);
330 InsertPacket();
331 EXPECT_TRUE(feedback_.triggered());
332 EXPECT_EQ(3u, feedback_.last_frame_acked());
333 testing_clock_.Advance(
334 base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
335 framer_.RemoveOldFrames(3); // Simulate 3 being pulled for rendering.
336 cast_msg_builder_->UpdateCastMessage();
337 EXPECT_TRUE(feedback_.triggered());
338 EXPECT_EQ(3u, feedback_.last_frame_acked());
341 TEST_F(CastMessageBuilderTest, InOrderRps) {
342 // Create a pattern - skip to rps, and don't look back.
343 SetFrameIds(0, 0);
344 SetPacketId(0);
345 SetMaxPacketId(0);
346 SetKeyFrame(true);
347 InsertPacket();
348 testing_clock_.Advance(
349 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
350 EXPECT_TRUE(feedback_.triggered());
351 EXPECT_EQ(0u, feedback_.last_frame_acked());
352 SetFrameIds(1, 0);
353 SetPacketId(0);
354 SetMaxPacketId(1);
355 SetKeyFrame(false);
356 InsertPacket();
357 testing_clock_.Advance(
358 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
359 EXPECT_FALSE(feedback_.triggered());
360 SetFrameIds(3, 0);
361 SetPacketId(0);
362 SetMaxPacketId(0);
363 SetKeyFrame(false);
364 InsertPacket();
365 testing_clock_.Advance(
366 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
367 framer_.RemoveOldFrames(3); // Simulate 3 being pulled for rendering.
368 testing_clock_.Advance(
369 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
370 cast_msg_builder_->UpdateCastMessage();
371 EXPECT_TRUE(feedback_.triggered());
372 EXPECT_EQ(3u, feedback_.last_frame_acked());
373 // Make an old frame complete - should not trigger an ack.
374 SetFrameIds(1, 0);
375 SetPacketId(1);
376 SetMaxPacketId(1);
377 SetKeyFrame(false);
378 InsertPacket();
379 testing_clock_.Advance(
380 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
381 EXPECT_FALSE(feedback_.triggered());
382 EXPECT_EQ(3u, feedback_.last_frame_acked());
385 TEST_F(CastMessageBuilderTest, SlowDownAck) {
386 SetDecoderSlowerThanMaxFrameRate(3);
387 SetFrameIds(0, 0);
388 SetPacketId(0);
389 SetMaxPacketId(0);
390 SetKeyFrame(true);
391 InsertPacket();
393 uint32 frame_id;
394 testing_clock_.Advance(
395 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
396 SetKeyFrame(false);
397 for (frame_id = 1; frame_id < 3; ++frame_id) {
398 EXPECT_TRUE(feedback_.triggered());
399 EXPECT_EQ(frame_id - 1, feedback_.last_frame_acked());
400 SetFrameIds(frame_id, frame_id - 1);
401 InsertPacket();
402 testing_clock_.Advance(
403 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
405 // We should now have entered the slowdown ACK state.
406 uint32 expected_frame_id = 1;
407 for (; frame_id < 10; ++frame_id) {
408 if (frame_id % 2) {
409 ++expected_frame_id;
410 EXPECT_TRUE(feedback_.triggered());
411 } else {
412 EXPECT_FALSE(feedback_.triggered());
414 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
415 SetFrameIds(frame_id, frame_id - 1);
416 InsertPacket();
417 testing_clock_.Advance(
418 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
420 EXPECT_FALSE(feedback_.triggered());
421 EXPECT_EQ(expected_frame_id, feedback_.last_frame_acked());
423 // Simulate frame_id being pulled for rendering.
424 framer_.RemoveOldFrames(frame_id);
425 // We should now leave the slowdown ACK state.
426 ++frame_id;
427 SetFrameIds(frame_id, frame_id - 1);
428 InsertPacket();
429 testing_clock_.Advance(
430 base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
431 EXPECT_TRUE(feedback_.triggered());
432 EXPECT_EQ(frame_id, feedback_.last_frame_acked());
435 } // namespace cast
436 } // namespace media