Commit 7d9b0ba4 authored by hclam@chromium.org's avatar hclam@chromium.org

Cast: Don't cancel re-transmission for some cases

We were aggresively cancelling re-transmission before. This caused an
ill effect with duplicated ACKs that some packets are not transmitted.
This change adds a boolean to control whether or not to cancel rtx.

Review URL: https://codereview.chromium.org/322953004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276824 0039d316-1c4b-4281-b951-d872f2087c98
parent fa0336fa
...@@ -178,11 +178,12 @@ void CastTransportHostFilter::OnSendRtcpFromRtpSender( ...@@ -178,11 +178,12 @@ void CastTransportHostFilter::OnSendRtcpFromRtpSender(
void CastTransportHostFilter::OnResendPackets( void CastTransportHostFilter::OnResendPackets(
int32 channel_id, int32 channel_id,
bool is_audio, bool is_audio,
const media::cast::MissingFramesAndPacketsMap& missing_packets) { const media::cast::MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list) {
media::cast::transport::CastTransportSender* sender = media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id); id_map_.Lookup(channel_id);
if (sender) { if (sender) {
sender->ResendPackets(is_audio, missing_packets); sender->ResendPackets(is_audio, missing_packets, cancel_rtx_if_not_in_list);
} else { } else {
DVLOG(1) DVLOG(1)
<< "CastTransportHostFilter::OnResendPackets on non-existing channel"; << "CastTransportHostFilter::OnResendPackets on non-existing channel";
......
...@@ -53,7 +53,8 @@ class CastTransportHostFilter : public content::BrowserMessageFilter { ...@@ -53,7 +53,8 @@ class CastTransportHostFilter : public content::BrowserMessageFilter {
void OnResendPackets( void OnResendPackets(
int32 channel_id, int32 channel_id,
bool is_audio, bool is_audio,
const media::cast::MissingFramesAndPacketsMap& missing_packets); const media::cast::MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list);
void OnNew( void OnNew(
int32 channel_id, int32 channel_id,
const net::IPEndPoint& remote_end_point); const net::IPEndPoint& remote_end_point);
......
...@@ -132,7 +132,7 @@ TEST_F(CastTransportHostFilterTest, SimpleMessages) { ...@@ -132,7 +132,7 @@ TEST_F(CastTransportHostFilterTest, SimpleMessages) {
missing_packets[1].insert(4); missing_packets[1].insert(4);
missing_packets[1].insert(7); missing_packets[1].insert(7);
CastHostMsg_ResendPackets resend_msg( CastHostMsg_ResendPackets resend_msg(
kChannelId, false, missing_packets); kChannelId, false, missing_packets, true);
FakeSend(resend_msg); FakeSend(resend_msg);
CastHostMsg_Delete delete_msg(kChannelId); CastHostMsg_Delete delete_msg(kChannelId);
......
...@@ -133,11 +133,12 @@ IPC_MESSAGE_CONTROL3( ...@@ -133,11 +133,12 @@ IPC_MESSAGE_CONTROL3(
media::cast::transport::SendRtcpFromRtpSenderData /* data */, media::cast::transport::SendRtcpFromRtpSenderData /* data */,
media::cast::transport::RtcpDlrrReportBlock /* dlrr */) media::cast::transport::RtcpDlrrReportBlock /* dlrr */)
IPC_MESSAGE_CONTROL3( IPC_MESSAGE_CONTROL4(
CastHostMsg_ResendPackets, CastHostMsg_ResendPackets,
int32 /* channel_id */, int32 /* channel_id */,
bool /* is_audio */, bool /* is_audio */,
media::cast::MissingFramesAndPacketsMap /* missing_packets */) media::cast::MissingFramesAndPacketsMap /* missing_packets */,
bool /* cancel_rtx_if_not_in_list */)
IPC_MESSAGE_CONTROL2( IPC_MESSAGE_CONTROL2(
CastHostMsg_New, CastHostMsg_New,
......
...@@ -78,10 +78,12 @@ void CastTransportSenderIPC::SendRtcpFromRtpSender( ...@@ -78,10 +78,12 @@ void CastTransportSenderIPC::SendRtcpFromRtpSender(
void CastTransportSenderIPC::ResendPackets( void CastTransportSenderIPC::ResendPackets(
bool is_audio, bool is_audio,
const media::cast::MissingFramesAndPacketsMap& missing_packets) { const media::cast::MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list) {
Send(new CastHostMsg_ResendPackets(channel_id_, Send(new CastHostMsg_ResendPackets(channel_id_,
is_audio, is_audio,
missing_packets)); missing_packets,
cancel_rtx_if_not_in_list));
} }
void CastTransportSenderIPC::OnReceivedPacket( void CastTransportSenderIPC::OnReceivedPacket(
......
...@@ -47,7 +47,8 @@ class CastTransportSenderIPC ...@@ -47,7 +47,8 @@ class CastTransportSenderIPC
const std::string& c_name) OVERRIDE; const std::string& c_name) OVERRIDE;
virtual void ResendPackets( virtual void ResendPackets(
bool is_audio, bool is_audio,
const media::cast::transport::MissingFramesAndPacketsMap& missing_packets) const media::cast::transport::MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list)
OVERRIDE; OVERRIDE;
void OnReceivedPacket(const media::cast::transport::Packet& packet); void OnReceivedPacket(const media::cast::transport::Packet& packet);
......
...@@ -106,7 +106,7 @@ void AudioSender::SendEncodedAudioFrame( ...@@ -106,7 +106,7 @@ void AudioSender::SendEncodedAudioFrame(
void AudioSender::ResendPackets( void AudioSender::ResendPackets(
const MissingFramesAndPacketsMap& missing_frames_and_packets) { const MissingFramesAndPacketsMap& missing_frames_and_packets) {
DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
transport_sender_->ResendPackets(true, missing_frames_and_packets); transport_sender_->ResendPackets(true, missing_frames_and_packets, false);
} }
void AudioSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) { void AudioSender::IncomingRtcpPacket(scoped_ptr<Packet> packet) {
......
...@@ -92,9 +92,15 @@ class CastTransportSender : public base::NonThreadSafe { ...@@ -92,9 +92,15 @@ class CastTransportSender : public base::NonThreadSafe {
const std::string& c_name) = 0; const std::string& c_name) = 0;
// Retransmission request. // Retransmission request.
// |missing_packets| includes the list of frames and packets in each
// frame to be re-transmitted.
// If |cancel_rtx_if_not_in_list| is used as an optimization to cancel
// pending re-transmission requests of packets not listed in
// |missing_packets|.
virtual void ResendPackets( virtual void ResendPackets(
bool is_audio, bool is_audio,
const MissingFramesAndPacketsMap& missing_packets) = 0; const MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list) = 0;
}; };
} // namespace transport } // namespace transport
......
...@@ -177,13 +177,16 @@ void CastTransportSenderImpl::SendRtcpFromRtpSender( ...@@ -177,13 +177,16 @@ void CastTransportSenderImpl::SendRtcpFromRtpSender(
void CastTransportSenderImpl::ResendPackets( void CastTransportSenderImpl::ResendPackets(
bool is_audio, bool is_audio,
const MissingFramesAndPacketsMap& missing_packets) { const MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list) {
if (is_audio) { if (is_audio) {
DCHECK(audio_sender_) << "Audio sender uninitialized"; DCHECK(audio_sender_) << "Audio sender uninitialized";
audio_sender_->ResendPackets(missing_packets); audio_sender_->ResendPackets(missing_packets,
cancel_rtx_if_not_in_list);
} else { } else {
DCHECK(video_sender_) << "Video sender uninitialized"; DCHECK(video_sender_) << "Video sender uninitialized";
video_sender_->ResendPackets(missing_packets); video_sender_->ResendPackets(missing_packets,
cancel_rtx_if_not_in_list);
} }
} }
......
...@@ -66,7 +66,8 @@ class CastTransportSenderImpl : public CastTransportSender { ...@@ -66,7 +66,8 @@ class CastTransportSenderImpl : public CastTransportSender {
const std::string& c_name) OVERRIDE; const std::string& c_name) OVERRIDE;
virtual void ResendPackets(bool is_audio, virtual void ResendPackets(bool is_audio,
const MissingFramesAndPacketsMap& missing_packets) const MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list)
OVERRIDE; OVERRIDE;
private: private:
......
...@@ -74,7 +74,8 @@ void RtpSender::SendFrame(const EncodedFrame& frame) { ...@@ -74,7 +74,8 @@ void RtpSender::SendFrame(const EncodedFrame& frame) {
} }
void RtpSender::ResendPackets( void RtpSender::ResendPackets(
const MissingFramesAndPacketsMap& missing_frames_and_packets) { const MissingFramesAndPacketsMap& missing_frames_and_packets,
bool cancel_rtx_if_not_in_list) {
DCHECK(storage_); DCHECK(storage_);
// Iterate over all frames in the list. // Iterate over all frames in the list.
for (MissingFramesAndPacketsMap::const_iterator it = for (MissingFramesAndPacketsMap::const_iterator it =
...@@ -98,7 +99,8 @@ void RtpSender::ResendPackets( ...@@ -98,7 +99,8 @@ void RtpSender::ResendPackets(
// If the resend request doesn't include this packet then cancel // If the resend request doesn't include this packet then cancel
// re-transmission already in queue. // re-transmission already in queue.
if (!missing_packet_set.empty() && if (cancel_rtx_if_not_in_list &&
!missing_packet_set.empty() &&
missing_packet_set.find(packet_id) == missing_packet_set.end()) { missing_packet_set.find(packet_id) == missing_packet_set.end()) {
transport_->CancelSendingPacket(it->first); transport_->CancelSendingPacket(it->first);
} else { } else {
......
...@@ -50,7 +50,8 @@ class RtpSender { ...@@ -50,7 +50,8 @@ class RtpSender {
void SendFrame(const EncodedFrame& frame); void SendFrame(const EncodedFrame& frame);
void ResendPackets(const MissingFramesAndPacketsMap& missing_packets); void ResendPackets(const MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list);
size_t send_packet_count() const { size_t send_packet_count() const {
return packetizer_ ? packetizer_->send_packet_count() : 0; return packetizer_ ? packetizer_->send_packet_count() : 0;
......
...@@ -318,8 +318,10 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) { ...@@ -318,8 +318,10 @@ void VideoSender::OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback) {
// Only count duplicated ACKs if there is no NACK request in between. // Only count duplicated ACKs if there is no NACK request in between.
// This is to avoid aggresive resend. // This is to avoid aggresive resend.
duplicate_ack_counter_ = 0; duplicate_ack_counter_ = 0;
// A NACK is also used to cancel pending re-transmissions.
transport_sender_->ResendPackets( transport_sender_->ResendPackets(
false, cast_feedback.missing_frames_and_packets_); false, cast_feedback.missing_frames_and_packets_, true);
} }
base::TimeTicks now = cast_environment_->Clock()->NowTicks(); base::TimeTicks now = cast_environment_->Clock()->NowTicks();
...@@ -370,7 +372,11 @@ void VideoSender::ResendForKickstart() { ...@@ -370,7 +372,11 @@ void VideoSender::ResendForKickstart() {
missing_frames_and_packets.insert( missing_frames_and_packets.insert(
std::make_pair(last_sent_frame_id_, missing)); std::make_pair(last_sent_frame_id_, missing));
last_send_time_ = cast_environment_->Clock()->NowTicks(); last_send_time_ = cast_environment_->Clock()->NowTicks();
transport_sender_->ResendPackets(false, missing_frames_and_packets);
// Sending this extra packet is to kick-start the session. There is
// no need to optimize re-transmission for this case.
transport_sender_->ResendPackets(false, missing_frames_and_packets,
false);
} }
} // namespace cast } // namespace cast
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment