Index: media/cast/net/cast_transport_sender_impl_unittest.cc |
diff --git a/media/cast/net/cast_transport_sender_impl_unittest.cc b/media/cast/net/cast_transport_sender_impl_unittest.cc |
index b8a49cce1f3c2ae4149723ae41117585d6692cbb..7308ab972abb64be176676ffbfa6770e5801f1cd 100644 |
--- a/media/cast/net/cast_transport_sender_impl_unittest.cc |
+++ b/media/cast/net/cast_transport_sender_impl_unittest.cc |
@@ -19,15 +19,43 @@ |
namespace media { |
namespace cast { |
-static const int64 kStartMillisecond = INT64_C(12345678900000); |
+namespace { |
+const int64 kStartMillisecond = INT64_C(12345678900000); |
+const uint32 kVideoSsrc = 1; |
+} // namespace |
class FakePacketSender : public PacketSender { |
public: |
- FakePacketSender() {} |
+ FakePacketSender() |
+ : paused_(false), packets_sent_(0) {} |
virtual bool SendPacket(PacketRef packet, const base::Closure& cb) OVERRIDE { |
+ if (paused_) { |
+ stored_packet_ = packet; |
+ callback_ = cb; |
+ return false; |
+ } |
+ ++packets_sent_; |
return true; |
} |
+ |
+ void SetPaused(bool paused) { |
+ paused_ = paused; |
+ if (!paused && stored_packet_) { |
+ SendPacket(stored_packet_, callback_); |
+ callback_.Run(); |
+ } |
+ } |
+ |
+ int packets_sent() const { return packets_sent_; } |
+ |
+ private: |
+ bool paused_; |
+ base::Closure callback_; |
+ PacketRef stored_packet_; |
+ int packets_sent_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FakePacketSender); |
}; |
class CastTransportSenderImplTest : public ::testing::Test { |
@@ -68,6 +96,18 @@ class CastTransportSenderImplTest : public ::testing::Test { |
task_runner_->RunTasks(); |
} |
+ void InitializeVideo() { |
+ CastTransportRtpConfig rtp_config; |
+ rtp_config.ssrc = kVideoSsrc; |
+ rtp_config.feedback_ssrc = 2; |
+ rtp_config.rtp_payload_type = 3; |
+ rtp_config.stored_frames = 10; |
+ transport_sender_->InitializeVideo(rtp_config, |
+ RtcpCastMessageCallback(), |
+ RtcpRttCallback()); |
+ |
+ } |
+ |
void LogRawEvents(const std::vector<PacketEvent>& packet_events, |
const std::vector<FrameEvent>& frame_events) { |
num_times_callback_called_++; |
@@ -95,5 +135,123 @@ TEST_F(CastTransportSenderImplTest, InitWithLogging) { |
EXPECT_EQ(5, num_times_callback_called_); |
} |
+TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) { |
+ InitWithoutLogging(); |
+ InitializeVideo(); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
+ |
+ // A fake frame that will be decomposed into 4 packets. |
+ EncodedFrame fake_frame; |
+ fake_frame.frame_id = 1; |
+ fake_frame.rtp_timestamp = 1; |
+ fake_frame.dependency = EncodedFrame::KEY; |
+ fake_frame.data.resize(5000, ' '); |
+ |
+ transport_sender_->InsertCodedVideoFrame(fake_frame); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ EXPECT_EQ(4, transport_.packets_sent()); |
+ |
+ // Resend packet 0. |
+ MissingFramesAndPacketsMap missing_packets; |
+ missing_packets[1].insert(0); |
+ missing_packets[1].insert(1); |
+ missing_packets[1].insert(2); |
+ |
+ transport_.SetPaused(true); |
+ transport_sender_->ResendPackets( |
+ kVideoSsrc, missing_packets, true, |
+ base::TimeDelta::FromMilliseconds(10)); |
+ |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ |
+ RtcpCastMessage cast_message; |
+ cast_message.media_ssrc = kVideoSsrc; |
+ cast_message.ack_frame_id = 1; |
+ cast_message.missing_frames_and_packets[1].insert(3); |
+ transport_sender_->OnReceivedCastMessage(kVideoSsrc, |
+ RtcpCastMessageCallback(), |
+ cast_message); |
+ transport_.SetPaused(false); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ |
+ // Resend one packet in the socket when unpaused. |
+ // Resend one more packet from NACK. |
+ EXPECT_EQ(6, transport_.packets_sent()); |
+} |
+ |
+TEST_F(CastTransportSenderImplTest, CancelRetransmits) { |
+ InitWithoutLogging(); |
+ InitializeVideo(); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
+ |
+ // A fake frame that will be decomposed into 4 packets. |
+ EncodedFrame fake_frame; |
+ fake_frame.frame_id = 1; |
+ fake_frame.rtp_timestamp = 1; |
+ fake_frame.dependency = EncodedFrame::KEY; |
+ fake_frame.data.resize(5000, ' '); |
+ |
+ transport_sender_->InsertCodedVideoFrame(fake_frame); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ EXPECT_EQ(4, transport_.packets_sent()); |
+ |
+ // Resend all packets for frame 1. |
+ MissingFramesAndPacketsMap missing_packets; |
+ missing_packets[1].insert(kRtcpCastAllPacketsLost); |
+ |
+ transport_.SetPaused(true); |
+ transport_sender_->ResendPackets( |
+ kVideoSsrc, missing_packets, true, |
+ base::TimeDelta::FromMilliseconds(10)); |
+ |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ std::vector<uint32> cancel_sending_frames; |
+ cancel_sending_frames.push_back(1); |
+ transport_sender_->CancelSendingFrames(kVideoSsrc, |
+ cancel_sending_frames); |
+ transport_.SetPaused(false); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ |
+ // Resend one packet in the socket when unpaused. |
+ EXPECT_EQ(5, transport_.packets_sent()); |
+} |
+ |
+TEST_F(CastTransportSenderImplTest, Kickstart) { |
+ InitWithoutLogging(); |
+ InitializeVideo(); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); |
+ |
+ // A fake frame that will be decomposed into 4 packets. |
+ EncodedFrame fake_frame; |
+ fake_frame.frame_id = 1; |
+ fake_frame.rtp_timestamp = 1; |
+ fake_frame.dependency = EncodedFrame::KEY; |
+ fake_frame.data.resize(5000, ' '); |
+ |
+ transport_.SetPaused(true); |
+ transport_sender_->InsertCodedVideoFrame(fake_frame); |
+ transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1); |
+ transport_.SetPaused(false); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ EXPECT_EQ(4, transport_.packets_sent()); |
+ |
+ // Resend 2 packets for frame 1. |
+ MissingFramesAndPacketsMap missing_packets; |
+ missing_packets[1].insert(0); |
+ missing_packets[1].insert(1); |
+ |
+ transport_.SetPaused(true); |
+ transport_sender_->ResendPackets( |
+ kVideoSsrc, missing_packets, true, |
+ base::TimeDelta::FromMilliseconds(10)); |
+ transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1); |
+ transport_.SetPaused(false); |
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); |
+ |
+ // Resend one packet in the socket when unpaused. |
+ // Two more retransmission packets sent. |
+ EXPECT_EQ(7, transport_.packets_sent()); |
+} |
+ |
} // namespace cast |
} // namespace media |