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

Unified Diff: media/cast/framer/cast_message_builder_unittest.cc

Issue 23467003: Added framer to cast. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rtcp
Patch Set: Created 7 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: media/cast/framer/cast_message_builder_unittest.cc
diff --git a/media/cast/framer/cast_message_builder_unittest.cc b/media/cast/framer/cast_message_builder_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e6d13a33a3459557f4959a7fc24d084025f6db7b
--- /dev/null
+++ b/media/cast/framer/cast_message_builder_unittest.cc
@@ -0,0 +1,512 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/simple_test_tick_clock.h"
+#include "media/cast/framer/cast_message_builder.h"
+#include "media/cast/rtcp/rtcp.h"
+#include "media/cast/rtp_common/rtp_defines.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+namespace cast {
+
+static const uint32 kSsrc = 0x1234;
+static const uint32 kShortTimeIncrementMs = 10;
+static const uint32 kLongTimeIncrementMs = 40;
+static const int64 kStartMillisecond = 123456789;
+
+
+class NackFeedbackVerification : public RtpPayloadFeedback {
+ public:
+ NackFeedbackVerification()
+ : triggered_(false),
+ missing_packets_(),
+ last_frame_acked_(0) {}
+
+
+ virtual void RequestKeyFrame() OVERRIDE {
+ request_key_frame_ = true;
+ }
+
+ virtual void CastFeedback(const RtcpCastMessage& cast_feedback) OVERRIDE {
+ EXPECT_EQ(kSsrc, cast_feedback.media_ssrc_);
+
+ last_frame_acked_ = cast_feedback.ack_frame_id_;
+
+ std::map<uint8, std::set<uint16> >::const_iterator frame_it =
Alpha Left Google 2013/08/28 00:27:31 This looks bulky is there a typedef you can use?
pwestin 2013/08/28 16:40:44 Done.
+ cast_feedback.missing_frames_and_packets_.begin();
+ // Keep track of the number of missing packets per frame.
+ missing_packets_.clear();
+ while (frame_it != cast_feedback.missing_frames_and_packets_.end()) {
+ missing_packets_.insert(std::pair<uint8, int>
Alpha Left Google 2013/08/28 00:27:31 you can just std::make_pair() which does the same
pwestin 2013/08/28 16:40:44 Done.
+ (frame_it->first, frame_it->second.size()));
+ ++frame_it;
+ }
+ triggered_ = true;
+ }
+
+ int num_missing_packets(uint8 frame_id) {
+ std::map<uint8, int>::iterator it;
+ it = missing_packets_.find(frame_id);
+ if (it == missing_packets_.end()) return 0;
+ return it->second;
+ }
+
+ // Holds value for one call.
+ bool triggered() {
+ bool ret_val = triggered_;
+ triggered_ = false;
+ return ret_val;
+ }
+
+ bool request_key_frame() {
+ bool ret_val = request_key_frame_;
+ request_key_frame_ = false;
+ return ret_val;
+ }
+ uint8 last_frame_acked() { return last_frame_acked_; }
Alpha Left Google 2013/08/28 00:27:31 nit: one space after ().
pwestin 2013/08/28 16:40:44 Done.
+
+ private:
+ bool triggered_;
+ // Number of missing packets per frame.
+ std::map<uint8, int> missing_packets_;
Alpha Left Google 2013/08/28 00:27:31 Use a typedef here.
pwestin 2013/08/28 16:40:44 Done.
+ uint8 last_frame_acked_;
+ bool request_key_frame_;
+};
+
+class CastMessageBuilderTest : public ::testing::Test {
+ protected:
+ CastMessageBuilderTest()
+ : feedback_(new NackFeedbackVerification()) {
+ cast_msg_builder_ = new CastMessageBuilder(feedback_,
+ &frame_id_map_,
+ kSsrc,
+ true,
+ 0);
+ rtp_header_.webrtc.header.ssrc = kSsrc;
+ rtp_header_.is_key_frame = false;
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kStartMillisecond));
+ cast_msg_builder_->set_clock(&testing_clock_);
+ }
+
+ ~CastMessageBuilderTest() { }
+
+ void SetFrameId(uint8 frame_id) {
+ rtp_header_.frame_id = frame_id;
+ }
+
+ void SetPacketId(uint16 packet_id) {
+ rtp_header_.packet_id = packet_id;
+ }
+
+ void SetMaxPacketId(uint16 max_packet_id) {
+ rtp_header_.max_packet_id = max_packet_id;
+ }
+
+ void SetKeyFrame(bool is_key) {
+ rtp_header_.is_key_frame = is_key;
+ }
+
+ void SetReferenceFrameId(uint8 reference_frame_id) {
+ rtp_header_.is_reference = true;
+ rtp_header_.reference_frame_id = reference_frame_id;
+ }
+
+ void InsertPacket() {
+ bool complete = false;
+ frame_id_map_.InsertPacket(rtp_header_, &complete);
+ if (complete) {
+ cast_msg_builder_->CompleteFrameReceived(rtp_header_.frame_id,
+ rtp_header_.is_key_frame);
+ }
+ cast_msg_builder_->UpdateCastMessage();
+ }
+
+ void SetDecoderSlowerThanMaxFrameRate(int max_unacked_frames) {
+ delete cast_msg_builder_;
+ cast_msg_builder_ = new CastMessageBuilder(feedback_,
+ &frame_id_map_,
+ kSsrc,
+ false,
+ max_unacked_frames);
+ }
+
+ CastMessageBuilder* cast_msg_builder_;
Alpha Left Google 2013/08/28 00:27:31 Use scoped_ptr<>.
pwestin 2013/08/28 16:40:44 Done.
+ NackFeedbackVerification* feedback_;
+ RtpCastHeader rtp_header_;
+ FrameIdMap frame_id_map_;
+ base::SimpleTestTickClock testing_clock_;
+};
+
+TEST_F(CastMessageBuilderTest, StartWithAKeyFrame) {
+ SetFrameId(3);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ InsertPacket();
+ // Should not trigger ack.
+ EXPECT_FALSE(feedback_->triggered());
+ SetFrameId(5);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+ frame_id_map_.RemoveOldFrames(5); // Simulate 5 being pulled for rendering.
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ cast_msg_builder_->UpdateCastMessage();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(5, feedback_->last_frame_acked());
+}
+
+TEST_F(CastMessageBuilderTest, OneFrameNackList) {
+ SetFrameId(0);
+ SetPacketId(4);
+ SetMaxPacketId(10);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ EXPECT_FALSE(feedback_->triggered());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetPacketId(5);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(4, feedback_->num_missing_packets(0));
+}
+
+TEST_F(CastMessageBuilderTest, CompleteFrameMissing) {
+ // TODO(mikhal): Add indication.
+ SetFrameId(0);
+ SetPacketId(2);
+ SetMaxPacketId(5);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(2);
+ SetPacketId(2);
+ SetMaxPacketId(5);
+ InsertPacket();
+}
+
+TEST_F(CastMessageBuilderTest, FastForwardAck) {
+ SetFrameId(1);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ InsertPacket();
+ EXPECT_FALSE(feedback_->triggered());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(2);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(255, feedback_->last_frame_acked());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(2, feedback_->last_frame_acked());
+}
+
+TEST_F(CastMessageBuilderTest, RemoveOldFrames) {
+ SetFrameId(1);
+ SetPacketId(0);
+ SetMaxPacketId(1);
+ InsertPacket();
+ EXPECT_FALSE(feedback_->triggered());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(2);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(3);
+ SetPacketId(0);
+ SetMaxPacketId(5);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(255, feedback_->last_frame_acked());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(5);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ frame_id_map_.RemoveOldFrames(5); // Simulate 5 being pulled for rendering.
+ cast_msg_builder_->UpdateCastMessage();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(5, feedback_->last_frame_acked());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ SetFrameId(1);
+ SetPacketId(1);
+ SetMaxPacketId(1);
+ InsertPacket();
+ EXPECT_FALSE(feedback_->triggered());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(5, feedback_->last_frame_acked());
+}
+
+TEST_F(CastMessageBuilderTest, WrapFastForward) {
+ SetFrameId(254);
+ SetPacketId(0);
+ SetMaxPacketId(1);
+ SetKeyFrame(true);
+ InsertPacket();
+ EXPECT_FALSE(feedback_->triggered());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(255);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(false);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(253, feedback_->last_frame_acked());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(false);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(253, feedback_->last_frame_acked());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetFrameId(254);
+ SetPacketId(1);
+ SetMaxPacketId(1);
+ SetKeyFrame(true);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(0, feedback_->last_frame_acked());
+}
+
+TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacket) {
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(20);
+ SetKeyFrame(true);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetPacketId(5);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(4, feedback_->num_missing_packets(0));
+}
+
+TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextFrame) {
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(20);
+ SetKeyFrame(true);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetPacketId(5);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(4, feedback_->num_missing_packets(0));
+ SetFrameId(1);
+ SetMaxPacketId(2);
+ SetPacketId(0);
+ SetKeyFrame(false);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(21 - 2, feedback_->num_missing_packets(0));
+}
+
+TEST_F(CastMessageBuilderTest, NackUntilMaxReceivedPacketNextKey) {
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(20);
+ SetKeyFrame(true);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ SetPacketId(5);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(4, feedback_->num_missing_packets(0));
+ SetFrameId(1);
+ SetMaxPacketId(0);
+ SetPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(0, feedback_->num_missing_packets(0));
+}
+
+TEST_F(CastMessageBuilderTest, Reset) {
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ cast_msg_builder_->Reset();
+ frame_id_map_.Clear();
+ // Should reset nack list state and request a key frame.
+ cast_msg_builder_->UpdateCastMessage();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(0, feedback_->num_missing_packets(0));
+}
+
+TEST_F(CastMessageBuilderTest, DeltaAfterReset) {
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(0, feedback_->num_missing_packets(0));
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ cast_msg_builder_->Reset();
+ SetFrameId(1);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ EXPECT_FALSE(feedback_->triggered());
+}
+
+TEST_F(CastMessageBuilderTest, BasicRps) {
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(0, feedback_->last_frame_acked());
+ SetFrameId(3);
+ SetKeyFrame(false);
+ SetReferenceFrameId(0);
+ InsertPacket();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(0, feedback_->last_frame_acked());
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kLongTimeIncrementMs));
+ frame_id_map_.RemoveOldFrames(3); // Simulate 3 being pulled for rendering.
+ cast_msg_builder_->UpdateCastMessage();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(3, feedback_->last_frame_acked());
+}
+
+TEST_F(CastMessageBuilderTest, InOrderRps) {
+ // Create a pattern - skip to rps, and don't look back.
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(0, feedback_->last_frame_acked());
+ SetFrameId(1);
+ SetPacketId(0);
+ SetMaxPacketId(1);
+ SetKeyFrame(false);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ EXPECT_FALSE(feedback_->triggered());
+ SetFrameId(3);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(false);
+ SetReferenceFrameId(0);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ frame_id_map_.RemoveOldFrames(3); // Simulate 3 being pulled for rendering.
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ cast_msg_builder_->UpdateCastMessage();
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(3, feedback_->last_frame_acked());
+ // Make an old frame complete - should not trigger an ack.
+ SetFrameId(1);
+ SetPacketId(1);
+ SetMaxPacketId(1);
+ SetKeyFrame(false);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ EXPECT_FALSE(feedback_->triggered());
+ EXPECT_EQ(3, feedback_->last_frame_acked());
+}
+
+TEST_F(CastMessageBuilderTest, SlowDownAck) {
+ SetDecoderSlowerThanMaxFrameRate(3);
+ SetFrameId(0);
+ SetPacketId(0);
+ SetMaxPacketId(0);
+ SetKeyFrame(true);
+ InsertPacket();
+
+ int frame_id;
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ SetKeyFrame(false);
+ for (frame_id = 1; frame_id < 3; ++frame_id) {
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(frame_id - 1, feedback_->last_frame_acked());
+ SetFrameId(frame_id);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ }
+ // We should now have entered the slowdown ACK state.
+ uint8_t expected_frame_id = 1;
+ for (; frame_id < 10; ++frame_id) {
+ if (frame_id % 2) ++expected_frame_id;
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(expected_frame_id, feedback_->last_frame_acked());
+ SetFrameId(frame_id);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ }
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(expected_frame_id, feedback_->last_frame_acked());
+
+ // Simulate frame_id being pulled for rendering.
+ frame_id_map_.RemoveOldFrames(frame_id);
+ // We should now leave the slowdown ACK state.
+ ++frame_id;
+ SetFrameId(frame_id);
+ InsertPacket();
+ testing_clock_.Advance(
+ base::TimeDelta::FromMilliseconds(kShortTimeIncrementMs));
+ EXPECT_TRUE(feedback_->triggered());
+ EXPECT_EQ(frame_id, feedback_->last_frame_acked());
+}
+
+} // namespace cast
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698