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

Side by Side Diff: media/cast/net/cast_transport_sender_impl.cc

Issue 445933002: Cast: Move retransmission to the transport (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: IPC Created 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/cast/net/cast_transport_sender_impl.h" 5 #include "media/cast/net/cast_transport_sender_impl.h"
6 6
7 #include "base/single_thread_task_runner.h" 7 #include "base/single_thread_task_runner.h"
8 #include "media/cast/net/cast_transport_config.h" 8 #include "media/cast/net/cast_transport_config.h"
9 #include "media/cast/net/cast_transport_defines.h" 9 #include "media/cast/net/cast_transport_defines.h"
10 #include "media/cast/net/udp_transport.h" 10 #include "media/cast/net/udp_transport.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 pacer_.RegisterAudioSsrc(config.ssrc); 104 pacer_.RegisterAudioSsrc(config.ssrc);
105 pacer_.RegisterPrioritySsrc(config.ssrc); 105 pacer_.RegisterPrioritySsrc(config.ssrc);
106 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); 106 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED);
107 } else { 107 } else {
108 audio_sender_.reset(); 108 audio_sender_.reset();
109 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED); 109 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED);
110 return; 110 return;
111 } 111 }
112 112
113 audio_rtcp_session_.reset( 113 audio_rtcp_session_.reset(
114 new Rtcp(cast_message_cb, 114 new Rtcp(base::Bind(&CastTransportSenderImpl::OnReceivedCastMessage,
115 rtt_cb, 115 weak_factory_.GetWeakPtr(), config.ssrc,
116 cast_message_cb),
117 base::Bind(&CastTransportSenderImpl::OnReceivedRtt,
118 weak_factory_.GetWeakPtr(), rtt_cb),
116 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, 119 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage,
117 weak_factory_.GetWeakPtr(), AUDIO_EVENT), 120 weak_factory_.GetWeakPtr(), AUDIO_EVENT),
118 clock_, 121 clock_,
119 &pacer_, 122 &pacer_,
120 config.ssrc, 123 config.ssrc,
121 config.feedback_ssrc)); 124 config.feedback_ssrc));
122 pacer_.RegisterAudioSsrc(config.ssrc); 125 pacer_.RegisterAudioSsrc(config.ssrc);
123 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); 126 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED);
124 } 127 }
125 128
126 void CastTransportSenderImpl::InitializeVideo( 129 void CastTransportSenderImpl::InitializeVideo(
127 const CastTransportRtpConfig& config, 130 const CastTransportRtpConfig& config,
128 const RtcpCastMessageCallback& cast_message_cb, 131 const RtcpCastMessageCallback& cast_message_cb,
129 const RtcpRttCallback& rtt_cb) { 132 const RtcpRttCallback& rtt_cb) {
130 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) 133 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty())
131 << "Unsafe to send video with encryption DISABLED."; 134 << "Unsafe to send video with encryption DISABLED.";
132 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) { 135 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) {
133 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); 136 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED);
134 return; 137 return;
135 } 138 }
136 139
137 video_sender_.reset(new RtpSender(clock_, transport_task_runner_, &pacer_)); 140 video_sender_.reset(new RtpSender(clock_, transport_task_runner_, &pacer_));
138 if (!video_sender_->Initialize(config)) { 141 if (!video_sender_->Initialize(config)) {
139 video_sender_.reset(); 142 video_sender_.reset();
140 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); 143 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED);
141 return; 144 return;
142 } 145 }
143 146
144 video_rtcp_session_.reset( 147 video_rtcp_session_.reset(
145 new Rtcp(cast_message_cb, 148 new Rtcp(base::Bind(&CastTransportSenderImpl::OnReceivedCastMessage,
hubbe 2014/08/11 19:11:49 Do we really want one rtcp object for audio and on
Alpha Left Google 2014/08/11 21:03:17 Yes we do. RTCP object maintain some states intern
146 rtt_cb, 149 weak_factory_.GetWeakPtr(), config.ssrc,
150 cast_message_cb),
151 base::Bind(&CastTransportSenderImpl::OnReceivedRtt,
152 weak_factory_.GetWeakPtr(), rtt_cb),
147 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage, 153 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage,
148 weak_factory_.GetWeakPtr(), VIDEO_EVENT), 154 weak_factory_.GetWeakPtr(), VIDEO_EVENT),
149 clock_, 155 clock_,
150 &pacer_, 156 &pacer_,
151 config.ssrc, 157 config.ssrc,
152 config.feedback_ssrc)); 158 config.feedback_ssrc));
153 pacer_.RegisterVideoSsrc(config.ssrc); 159 pacer_.RegisterVideoSsrc(config.ssrc);
154 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED); 160 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED);
155 } 161 }
156 162
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 audio_sender_->send_packet_count(), audio_sender_->send_octet_count()); 201 audio_sender_->send_packet_count(), audio_sender_->send_octet_count());
196 } else if (video_sender_ && ssrc == video_sender_->ssrc()) { 202 } else if (video_sender_ && ssrc == video_sender_->ssrc()) {
197 video_rtcp_session_->SendRtcpFromRtpSender( 203 video_rtcp_session_->SendRtcpFromRtpSender(
198 current_time, current_time_as_rtp_timestamp, 204 current_time, current_time_as_rtp_timestamp,
199 video_sender_->send_packet_count(), video_sender_->send_octet_count()); 205 video_sender_->send_packet_count(), video_sender_->send_octet_count());
200 } else { 206 } else {
201 NOTREACHED() << "Invalid request for sending RTCP packet."; 207 NOTREACHED() << "Invalid request for sending RTCP packet.";
202 } 208 }
203 } 209 }
204 210
211 void CastTransportSenderImpl::CancelSendingFrames(
212 uint32 ssrc,
213 const std::set<uint32>& frame_ids) {
214 // Cancel resends of acked frames.
215 MissingFramesAndPacketsMap missing_frames_and_packets;
216 PacketIdSet missing;
217 for (std::set<uint32>::const_iterator it = frame_ids.begin();
218 it != frame_ids.end(); ++it) {
219 missing_frames_and_packets[*it] = missing;
220 }
221 ResendPackets(ssrc, missing_frames_and_packets, true, base::TimeDelta());
hubbe 2014/08/11 19:11:50 Why not call audio/video_sender->CancelSendingFram
Alpha Left Google 2014/08/11 21:03:18 Done.
222 }
223
224 void CastTransportSenderImpl::ResendFrameForKickstart(uint32 ssrc,
225 uint32 frame_id) {
226 // Send the last packet of the encoded frame to kick start
227 // retransmission. This gives enough information to the receiver what
228 // packets and frames are missing.
229 MissingFramesAndPacketsMap missing_frames_and_packets;
230 PacketIdSet missing;
231 missing.insert(kRtcpCastLastPacket);
232 missing_frames_and_packets.insert(std::make_pair(frame_id, missing));
233
234 // Sending this extra packet is to kick-start the session. There is
235 // no need to optimize re-transmission for this case.
236 ResendPackets(ssrc, missing_frames_and_packets, false, most_recent_rtt_);
hubbe 2014/08/11 19:11:49 Why not call audio/video_sender_->ResendFrameForKi
Alpha Left Google 2014/08/11 21:03:17 Done.
237 }
238
205 void CastTransportSenderImpl::ResendPackets( 239 void CastTransportSenderImpl::ResendPackets(
206 bool is_audio, 240 uint32 ssrc,
207 const MissingFramesAndPacketsMap& missing_packets, 241 const MissingFramesAndPacketsMap& missing_packets,
208 bool cancel_rtx_if_not_in_list, 242 bool cancel_rtx_if_not_in_list,
209 base::TimeDelta dedupe_window) { 243 base::TimeDelta dedupe_window) {
210 if (is_audio) { 244 if (audio_sender_ && ssrc == audio_sender_->ssrc()) {
211 DCHECK(audio_sender_) << "Audio sender uninitialized";
212 audio_sender_->ResendPackets(missing_packets, 245 audio_sender_->ResendPackets(missing_packets,
213 cancel_rtx_if_not_in_list, 246 cancel_rtx_if_not_in_list,
214 dedupe_window); 247 dedupe_window);
215 } else { 248 } else if (video_sender_ && ssrc == video_sender_->ssrc()) {
216 DCHECK(video_sender_) << "Video sender uninitialized";
217 video_sender_->ResendPackets(missing_packets, 249 video_sender_->ResendPackets(missing_packets,
218 cancel_rtx_if_not_in_list, 250 cancel_rtx_if_not_in_list,
219 dedupe_window); 251 dedupe_window);
252 } else {
253 NOTREACHED() << "Invalid request for retransmission.";
220 } 254 }
221 } 255 }
222 256
223 PacketReceiverCallback CastTransportSenderImpl::PacketReceiverForTesting() { 257 PacketReceiverCallback CastTransportSenderImpl::PacketReceiverForTesting() {
224 return base::Bind(&CastTransportSenderImpl::OnReceivedPacket, 258 return base::Bind(&CastTransportSenderImpl::OnReceivedPacket,
225 weak_factory_.GetWeakPtr()); 259 weak_factory_.GetWeakPtr());
226 } 260 }
227 261
228 void CastTransportSenderImpl::SendRawEvents() { 262 void CastTransportSenderImpl::SendRawEvents() {
229 DCHECK(event_subscriber_.get()); 263 DCHECK(event_subscriber_.get());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 break; 320 break;
287 default: 321 default:
288 VLOG(2) << "Received log message via RTCP that we did not expect: " 322 VLOG(2) << "Received log message via RTCP that we did not expect: "
289 << static_cast<int>(event_it->type); 323 << static_cast<int>(event_it->type);
290 break; 324 break;
291 } 325 }
292 } 326 }
293 } 327 }
294 } 328 }
295 329
330 void CastTransportSenderImpl::OnReceivedRtt(const RtcpRttCallback& rtt_cb,
331 base::TimeDelta rtt,
332 base::TimeDelta avg_rtt,
333 base::TimeDelta min_rtt,
334 base::TimeDelta max_rtt) {
335 if (!rtt_cb.is_null())
336 rtt_cb.Run(rtt, avg_rtt, min_rtt, max_rtt);
337
338 most_recent_rtt_ = rtt;
hubbe 2014/08/11 19:11:49 Seems like it would be cleaner to just have the rt
Alpha Left Google 2014/08/11 21:03:18 Done.
339 }
340
341 void CastTransportSenderImpl::OnReceivedCastMessage(
342 uint32 ssrc,
343 const RtcpCastMessageCallback& cast_message_cb,
344 const RtcpCastMessage& cast_message) {
345 if (!cast_message_cb.is_null())
346 cast_message_cb.Run(cast_message);
347
348 if (cast_message.missing_frames_and_packets.empty())
349 return;
350
351 const bool is_audio = audio_sender_ && audio_sender_->ssrc() == ssrc;
352
353 // This call does two things.
354 // 1. Specifies that retransmissions for packets not listed in the set are
355 // cancelled.
356 // 2. Specifies a deduplication window. For video this would be the most
357 // recent RTT. For audio there is no deduplication.
358 ResendPackets(ssrc,
359 cast_message.missing_frames_and_packets,
360 true,
361 is_audio ? base::TimeDelta() : most_recent_rtt_);
362 }
363
296 } // namespace cast 364 } // namespace cast
297 } // namespace media 365 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698