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

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

Powered by Google App Engine
This is Rietveld 408576698