+TEST_F(CastTransportSenderImplTest, InitWithOptions) {
+ InitWithOptions();
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));
+ EXPECT_EQ(0, 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_->InsertFrame(kVideoSsrc, 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);
+ DedupInfo dedup_info;
+ dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
+ transport_sender_->ResendPackets(
+ kVideoSsrc, missing_packets, true, dedup_info);
+
+ 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_->InsertFrame(kVideoSsrc, 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);
+ DedupInfo dedup_info;
+ dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
+ transport_sender_->ResendPackets(
+ kVideoSsrc, missing_packets, true, dedup_info);
+
+ 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_->InsertFrame(kVideoSsrc, 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);
+ DedupInfo dedup_info;
+ dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10);
+ transport_sender_->ResendPackets(
+ kVideoSsrc, missing_packets, true, dedup_info);
+ 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());
+}
+
+TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) {
+ InitWithoutLogging();
+ InitializeAudio();
+ InitializeVideo();
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50));
+
+ // Send two audio frames.
+ EncodedFrame fake_audio;
+ fake_audio.frame_id = 1;
+ fake_audio.reference_time = testing_clock_.NowTicks();
+ fake_audio.dependency = EncodedFrame::KEY;
+ fake_audio.data.resize(100, ' ');
+ transport_sender_->InsertFrame(kAudioSsrc, fake_audio);
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
+ fake_audio.frame_id = 2;
+ fake_audio.reference_time = testing_clock_.NowTicks();
+ transport_sender_->InsertFrame(kAudioSsrc, fake_audio);
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
+ EXPECT_EQ(2, transport_.packets_sent());
+
+ // Ack the first audio frame.
+ RtcpCastMessage cast_message;
+ cast_message.media_ssrc = kAudioSsrc;
+ cast_message.ack_frame_id = 1;
+ transport_sender_->OnReceivedCastMessage(kAudioSsrc,
+ RtcpCastMessageCallback(),
+ cast_message);
+ task_runner_->RunTasks();
+ EXPECT_EQ(2, transport_.packets_sent());
+
+ // Send a fake video frame that will be decomposed into 4 packets.
+ EncodedFrame fake_video;
+ fake_video.frame_id = 1;
+ fake_video.dependency = EncodedFrame::KEY;
+ fake_video.data.resize(5000, ' ');
+ transport_sender_->InsertFrame(kVideoSsrc, fake_video);
+ task_runner_->RunTasks();
+ EXPECT_EQ(6, transport_.packets_sent());
+
+ // Retransmission is reject because audio is not acked yet.
+ cast_message.media_ssrc = kVideoSsrc;
+ cast_message.ack_frame_id = 0;
+ cast_message.missing_frames_and_packets[1].insert(3);
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10));
+ transport_sender_->OnReceivedCastMessage(kVideoSsrc,
+ RtcpCastMessageCallback(),
+ cast_message);
+ task_runner_->RunTasks();
+ EXPECT_EQ(6, transport_.packets_sent());
+
+ // Ack the second audio frame.
+ cast_message.media_ssrc = kAudioSsrc;
+ cast_message.ack_frame_id = 2;
+ cast_message.missing_frames_and_packets.clear();
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
+ transport_sender_->OnReceivedCastMessage(kAudioSsrc,
+ RtcpCastMessageCallback(),
+ cast_message);
+ task_runner_->RunTasks();
+ EXPECT_EQ(6, transport_.packets_sent());
+
+ // Retransmission of video packet now accepted.
+ cast_message.media_ssrc = kVideoSsrc;
+ cast_message.ack_frame_id = 1;
+ cast_message.missing_frames_and_packets[1].insert(3);
+ task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2));
+ transport_sender_->OnReceivedCastMessage(kVideoSsrc,
+ RtcpCastMessageCallback(),
+ cast_message);
+ task_runner_->RunTasks();
+ EXPECT_EQ(7, transport_.packets_sent());
+}
+