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