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

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

Issue 387933005: Cast: Refactor RTCP handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test Created 6 years, 5 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 14 matching lines...) Expand all
25 new CastTransportSenderImpl(net_log, 25 new CastTransportSenderImpl(net_log,
26 clock, 26 clock,
27 remote_end_point, 27 remote_end_point,
28 status_callback, 28 status_callback,
29 raw_events_callback, 29 raw_events_callback,
30 raw_events_callback_interval, 30 raw_events_callback_interval,
31 transport_task_runner.get(), 31 transport_task_runner.get(),
32 NULL)); 32 NULL));
33 } 33 }
34 34
35 PacketReceiverCallback CastTransportSender::PacketReceiverForTesting() {
36 return PacketReceiverCallback();
37 }
38
35 CastTransportSenderImpl::CastTransportSenderImpl( 39 CastTransportSenderImpl::CastTransportSenderImpl(
36 net::NetLog* net_log, 40 net::NetLog* net_log,
37 base::TickClock* clock, 41 base::TickClock* clock,
38 const net::IPEndPoint& remote_end_point, 42 const net::IPEndPoint& remote_end_point,
39 const CastTransportStatusCallback& status_callback, 43 const CastTransportStatusCallback& status_callback,
40 const BulkRawEventsCallback& raw_events_callback, 44 const BulkRawEventsCallback& raw_events_callback,
41 base::TimeDelta raw_events_callback_interval, 45 base::TimeDelta raw_events_callback_interval,
42 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, 46 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
43 PacketSender* external_transport) 47 PacketSender* external_transport)
44 : clock_(clock), 48 : clock_(clock),
45 status_callback_(status_callback), 49 status_callback_(status_callback),
46 transport_task_runner_(transport_task_runner), 50 transport_task_runner_(transport_task_runner),
47 transport_(external_transport ? NULL 51 transport_(external_transport ? NULL
48 : new UdpTransport(net_log, 52 : new UdpTransport(net_log,
49 transport_task_runner, 53 transport_task_runner,
50 net::IPEndPoint(), 54 net::IPEndPoint(),
51 remote_end_point, 55 remote_end_point,
52 status_callback)), 56 status_callback)),
53 logging_(),
54 pacer_(clock, 57 pacer_(clock,
55 &logging_, 58 &logging_,
56 external_transport ? external_transport : transport_.get(), 59 external_transport ? external_transport : transport_.get(),
57 transport_task_runner), 60 transport_task_runner),
58 rtcp_builder_(&pacer_), 61 raw_events_callback_(raw_events_callback),
59 raw_events_callback_(raw_events_callback) { 62 raw_events_callback_interval_(raw_events_callback_interval),
63 weak_factory_(this) {
60 DCHECK(clock_); 64 DCHECK(clock_);
61 if (!raw_events_callback_.is_null()) { 65 if (!raw_events_callback_.is_null()) {
62 DCHECK(raw_events_callback_interval > base::TimeDelta()); 66 DCHECK(raw_events_callback_interval > base::TimeDelta());
63 event_subscriber_.reset(new SimpleEventSubscriber); 67 event_subscriber_.reset(new SimpleEventSubscriber);
64 logging_.AddRawEventSubscriber(event_subscriber_.get()); 68 logging_.AddRawEventSubscriber(event_subscriber_.get());
65 raw_events_timer_.Start(FROM_HERE, 69 transport_task_runner->PostDelayedTask(
66 raw_events_callback_interval, 70 FROM_HERE,
67 this, 71 base::Bind(&CastTransportSenderImpl::SendRawEvents,
68 &CastTransportSenderImpl::SendRawEvents); 72 weak_factory_.GetWeakPtr()),
73 raw_events_callback_interval);
69 } 74 }
70 if (transport_) { 75 if (transport_) {
71 // The default DSCP value for cast is AF41. Which gives it a higher 76 // The default DSCP value for cast is AF41. Which gives it a higher
72 // priority over other traffic. 77 // priority over other traffic.
73 transport_->SetDscp(net::DSCP_AF41); 78 transport_->SetDscp(net::DSCP_AF41);
74 } 79 }
75 } 80 }
76 81
77 CastTransportSenderImpl::~CastTransportSenderImpl() { 82 CastTransportSenderImpl::~CastTransportSenderImpl() {
78 if (event_subscriber_.get()) 83 if (event_subscriber_.get())
79 logging_.RemoveRawEventSubscriber(event_subscriber_.get()); 84 logging_.RemoveRawEventSubscriber(event_subscriber_.get());
80 } 85 }
81 86
82 void CastTransportSenderImpl::InitializeAudio( 87 void CastTransportSenderImpl::InitializeAudio(
83 const CastTransportRtpConfig& config) { 88 const CastTransportRtpConfig& config,
89 const RtcpCastMessageCallback& cast_message_cb,
90 const RtcpRttCallback& rtt_cb) {
84 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) 91 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty())
85 << "Unsafe to send audio with encryption DISABLED."; 92 << "Unsafe to send audio with encryption DISABLED.";
86 if (!audio_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) { 93 if (!audio_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) {
87 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED); 94 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED);
88 return; 95 return;
89 } 96 }
97
90 audio_sender_.reset(new RtpSender(clock_, transport_task_runner_, &pacer_)); 98 audio_sender_.reset(new RtpSender(clock_, transport_task_runner_, &pacer_));
91 if (audio_sender_->Initialize(config)) { 99 if (audio_sender_->Initialize(config)) {
92 // Audio packets have a higher priority. 100 // Audio packets have a higher priority.
93 pacer_.RegisterAudioSsrc(config.ssrc); 101 pacer_.RegisterAudioSsrc(config.ssrc);
94 pacer_.RegisterPrioritySsrc(config.ssrc); 102 pacer_.RegisterPrioritySsrc(config.ssrc);
95 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED); 103 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED);
96 } else { 104 } else {
97 audio_sender_.reset(); 105 audio_sender_.reset();
98 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED); 106 status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED);
107 return;
99 } 108 }
109
110 audio_rtcp_session_.reset(
111 new Rtcp(cast_message_cb,
112 rtt_cb,
113 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage,
114 weak_factory_.GetWeakPtr(), AUDIO_EVENT),
115 clock_,
116 &pacer_,
117 config.ssrc,
118 config.feedback_ssrc,
119 config.c_name));
120 pacer_.RegisterAudioSsrc(config.ssrc);
121
122 // Only start receiving once.
123 if (!video_sender_)
124 StartReceiving();
125 status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED);
100 } 126 }
101 127
102 void CastTransportSenderImpl::InitializeVideo( 128 void CastTransportSenderImpl::InitializeVideo(
103 const CastTransportRtpConfig& config) { 129 const CastTransportRtpConfig& config,
130 const RtcpCastMessageCallback& cast_message_cb,
131 const RtcpRttCallback& rtt_cb) {
104 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty()) 132 LOG_IF(WARNING, config.aes_key.empty() || config.aes_iv_mask.empty())
105 << "Unsafe to send video with encryption DISABLED."; 133 << "Unsafe to send video with encryption DISABLED.";
106 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) { 134 if (!video_encryptor_.Initialize(config.aes_key, config.aes_iv_mask)) {
107 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); 135 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED);
108 return; 136 return;
109 } 137 }
138
110 video_sender_.reset(new RtpSender(clock_, transport_task_runner_, &pacer_)); 139 video_sender_.reset(new RtpSender(clock_, transport_task_runner_, &pacer_));
111 if (video_sender_->Initialize(config)) { 140 if (!video_sender_->Initialize(config)) {
112 pacer_.RegisterVideoSsrc(config.ssrc);
113 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED);
114 } else {
115 video_sender_.reset(); 141 video_sender_.reset();
116 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED); 142 status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED);
143 return;
117 } 144 }
118 }
119 145
120 void CastTransportSenderImpl::SetPacketReceiver( 146 video_rtcp_session_.reset(
121 const PacketReceiverCallback& packet_receiver) { 147 new Rtcp(cast_message_cb,
122 transport_->StartReceiving(packet_receiver); 148 rtt_cb,
149 base::Bind(&CastTransportSenderImpl::OnReceivedLogMessage,
150 weak_factory_.GetWeakPtr(), VIDEO_EVENT),
151 clock_,
152 &pacer_,
153 config.ssrc,
154 config.feedback_ssrc,
155 config.c_name));
156 pacer_.RegisterVideoSsrc(config.ssrc);
157
158 // Only start receiving once.
159 if (!audio_sender_)
160 StartReceiving();
161 status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED);
123 } 162 }
124 163
125 namespace { 164 namespace {
126 void EncryptAndSendFrame(const EncodedFrame& frame, 165 void EncryptAndSendFrame(const EncodedFrame& frame,
127 TransportEncryptionHandler* encryptor, 166 TransportEncryptionHandler* encryptor,
128 RtpSender* sender) { 167 RtpSender* sender) {
129 if (encryptor->is_activated()) { 168 if (encryptor->is_activated()) {
130 EncodedFrame encrypted_frame; 169 EncodedFrame encrypted_frame;
131 frame.CopyMetadataTo(&encrypted_frame); 170 frame.CopyMetadataTo(&encrypted_frame);
132 if (encryptor->Encrypt(frame.frame_id, frame.data, &encrypted_frame.data)) { 171 if (encryptor->Encrypt(frame.frame_id, frame.data, &encrypted_frame.data)) {
(...skipping 13 matching lines...) Expand all
146 DCHECK(audio_sender_) << "Audio sender uninitialized"; 185 DCHECK(audio_sender_) << "Audio sender uninitialized";
147 EncryptAndSendFrame(audio_frame, &audio_encryptor_, audio_sender_.get()); 186 EncryptAndSendFrame(audio_frame, &audio_encryptor_, audio_sender_.get());
148 } 187 }
149 188
150 void CastTransportSenderImpl::InsertCodedVideoFrame( 189 void CastTransportSenderImpl::InsertCodedVideoFrame(
151 const EncodedFrame& video_frame) { 190 const EncodedFrame& video_frame) {
152 DCHECK(video_sender_) << "Video sender uninitialized"; 191 DCHECK(video_sender_) << "Video sender uninitialized";
153 EncryptAndSendFrame(video_frame, &video_encryptor_, video_sender_.get()); 192 EncryptAndSendFrame(video_frame, &video_encryptor_, video_sender_.get());
154 } 193 }
155 194
156 void CastTransportSenderImpl::SendRtcpFromRtpSender( 195 void CastTransportSenderImpl::SendSenderReport(
157 uint32 packet_type_flags, 196 uint32 ssrc,
158 uint32 ntp_seconds, 197 base::TimeTicks current_time,
159 uint32 ntp_fraction, 198 uint32 current_time_as_rtp_timestamp) {
160 uint32 rtp_timestamp, 199 if (audio_sender_ && ssrc == audio_sender_->ssrc()) {
161 const RtcpDlrrReportBlock& dlrr, 200 audio_rtcp_session_->SendRtcpFromRtpSender(
162 uint32 sending_ssrc, 201 current_time, current_time_as_rtp_timestamp,
163 const std::string& c_name) { 202 audio_sender_->send_packet_count(), audio_sender_->send_octet_count());
164 RtcpSenderInfo sender_info; 203 } else if (video_sender_ && ssrc == video_sender_->ssrc()) {
165 sender_info.ntp_seconds = ntp_seconds; 204 video_rtcp_session_->SendRtcpFromRtpSender(
166 sender_info.ntp_fraction = ntp_fraction; 205 current_time, current_time_as_rtp_timestamp,
167 sender_info.rtp_timestamp = rtp_timestamp; 206 video_sender_->send_packet_count(), video_sender_->send_octet_count());
168 if (audio_sender_ && audio_sender_->ssrc() == sending_ssrc) {
169 sender_info.send_packet_count = audio_sender_->send_packet_count();
170 sender_info.send_octet_count = audio_sender_->send_octet_count();
171 } else if (video_sender_ && video_sender_->ssrc() == sending_ssrc) {
172 sender_info.send_packet_count = video_sender_->send_packet_count();
173 sender_info.send_octet_count = video_sender_->send_octet_count();
174 } else { 207 } else {
175 LOG(ERROR) << "Sending RTCP with an invalid SSRC."; 208 NOTREACHED() << "Invalid request for sending RTCP packet.";
176 return;
177 } 209 }
178 rtcp_builder_.SendRtcpFromRtpSender(
179 packet_type_flags, sender_info, dlrr, sending_ssrc, c_name);
180 } 210 }
181 211
182 void CastTransportSenderImpl::ResendPackets( 212 void CastTransportSenderImpl::ResendPackets(
183 bool is_audio, 213 bool is_audio,
184 const MissingFramesAndPacketsMap& missing_packets, 214 const MissingFramesAndPacketsMap& missing_packets,
185 bool cancel_rtx_if_not_in_list, 215 bool cancel_rtx_if_not_in_list,
186 base::TimeDelta dedupe_window) { 216 base::TimeDelta dedupe_window) {
187 if (is_audio) { 217 if (is_audio) {
188 DCHECK(audio_sender_) << "Audio sender uninitialized"; 218 DCHECK(audio_sender_) << "Audio sender uninitialized";
189 audio_sender_->ResendPackets(missing_packets, 219 audio_sender_->ResendPackets(missing_packets,
190 cancel_rtx_if_not_in_list, 220 cancel_rtx_if_not_in_list,
191 dedupe_window); 221 dedupe_window);
192 } else { 222 } else {
193 DCHECK(video_sender_) << "Video sender uninitialized"; 223 DCHECK(video_sender_) << "Video sender uninitialized";
194 video_sender_->ResendPackets(missing_packets, 224 video_sender_->ResendPackets(missing_packets,
195 cancel_rtx_if_not_in_list, 225 cancel_rtx_if_not_in_list,
196 dedupe_window); 226 dedupe_window);
197 } 227 }
198 } 228 }
199 229
230 PacketReceiverCallback CastTransportSenderImpl::PacketReceiverForTesting() {
231 return base::Bind(&CastTransportSenderImpl::OnReceivedPacket,
232 weak_factory_.GetWeakPtr());
233 }
234
200 void CastTransportSenderImpl::SendRawEvents() { 235 void CastTransportSenderImpl::SendRawEvents() {
201 DCHECK(event_subscriber_.get()); 236 DCHECK(event_subscriber_.get());
202 DCHECK(!raw_events_callback_.is_null()); 237 DCHECK(!raw_events_callback_.is_null());
203 std::vector<PacketEvent> packet_events; 238 std::vector<PacketEvent> packet_events;
239 std::vector<FrameEvent> frame_events;
204 event_subscriber_->GetPacketEventsAndReset(&packet_events); 240 event_subscriber_->GetPacketEventsAndReset(&packet_events);
205 raw_events_callback_.Run(packet_events); 241 event_subscriber_->GetFrameEventsAndReset(&frame_events);
242 raw_events_callback_.Run(packet_events, frame_events);
243
244 transport_task_runner_->PostDelayedTask(
245 FROM_HERE,
246 base::Bind(&CastTransportSenderImpl::SendRawEvents,
247 weak_factory_.GetWeakPtr()),
248 raw_events_callback_interval_);
249 }
250
251 void CastTransportSenderImpl::StartReceiving() {
252 if (!transport_)
253 return;
254 transport_->StartReceiving(
255 base::Bind(&CastTransportSenderImpl::OnReceivedPacket,
256 weak_factory_.GetWeakPtr()));
257 }
258
259 void CastTransportSenderImpl::OnReceivedPacket(scoped_ptr<Packet> packet) {
260 if (audio_rtcp_session_ &&
261 audio_rtcp_session_->IncomingRtcpPacket(&packet->front(),
262 packet->size())) {
263 return;
264 }
265 if (video_rtcp_session_ &&
266 video_rtcp_session_->IncomingRtcpPacket(&packet->front(),
267 packet->size())) {
268 return;
269 }
270 VLOG(1) << "Stale packet received.";
271 }
272
273 void CastTransportSenderImpl::OnReceivedLogMessage(
274 EventMediaType media_type,
275 const RtcpReceiverLogMessage& log) {
276 // Add received log messages into our log system.
277 RtcpReceiverLogMessage::const_iterator it = log.begin();
278 for (; it != log.end(); ++it) {
279 uint32 rtp_timestamp = it->rtp_timestamp_;
280
281 RtcpReceiverEventLogMessages::const_iterator event_it =
282 it->event_log_messages_.begin();
283 for (; event_it != it->event_log_messages_.end(); ++event_it) {
284 switch (event_it->type) {
285 case PACKET_RECEIVED:
286 logging_.InsertPacketEvent(
287 event_it->event_timestamp, event_it->type,
288 media_type, rtp_timestamp,
289 kFrameIdUnknown, event_it->packet_id, 0, 0);
290 break;
291 case FRAME_ACK_SENT:
292 case FRAME_DECODED:
293 logging_.InsertFrameEvent(
294 event_it->event_timestamp, event_it->type, media_type,
295 rtp_timestamp, kFrameIdUnknown);
296 break;
297 case FRAME_PLAYOUT:
298 logging_.InsertFrameEventWithDelay(
299 event_it->event_timestamp, event_it->type, media_type,
300 rtp_timestamp, kFrameIdUnknown, event_it->delay_delta);
301 break;
302 default:
303 VLOG(2) << "Received log message via RTCP that we did not expect: "
304 << static_cast<int>(event_it->type);
305 break;
306 }
307 }
308 }
206 } 309 }
207 310
208 } // namespace cast 311 } // namespace cast
209 } // namespace media 312 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/net/cast_transport_sender_impl.h ('k') | media/cast/net/cast_transport_sender_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698