Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media / cast_transport_host_filter.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 "chrome/browser/media/cast_transport_host_filter.h"
6
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/net/chrome_net_log.h"
9 #include "content/public/browser/power_save_blocker.h"
10 #include "media/cast/net/cast_transport_sender.h"
11
12 namespace {
13
14 // How often to send raw events.
15 const int kSendRawEventsIntervalSecs = 1;
16
17 }
18
19 namespace cast {
20
21 CastTransportHostFilter::CastTransportHostFilter()
22     : BrowserMessageFilter(CastMsgStart),
23       weak_factory_(this) {}
24
25 CastTransportHostFilter::~CastTransportHostFilter() {}
26
27 bool CastTransportHostFilter::OnMessageReceived(const IPC::Message& message) {
28   bool handled = true;
29   IPC_BEGIN_MESSAGE_MAP(CastTransportHostFilter, message)
30     IPC_MESSAGE_HANDLER(CastHostMsg_New, OnNew)
31     IPC_MESSAGE_HANDLER(CastHostMsg_Delete, OnDelete)
32     IPC_MESSAGE_HANDLER(CastHostMsg_InitializeAudio, OnInitializeAudio)
33     IPC_MESSAGE_HANDLER(CastHostMsg_InitializeVideo, OnInitializeVideo)
34     IPC_MESSAGE_HANDLER(CastHostMsg_InsertCodedAudioFrame,
35                         OnInsertCodedAudioFrame)
36     IPC_MESSAGE_HANDLER(CastHostMsg_InsertCodedVideoFrame,
37                         OnInsertCodedVideoFrame)
38     IPC_MESSAGE_HANDLER(CastHostMsg_SendSenderReport,
39                         OnSendSenderReport)
40     IPC_MESSAGE_HANDLER(CastHostMsg_ResendPackets,
41                         OnResendPackets)
42     IPC_MESSAGE_UNHANDLED(handled = false);
43   IPC_END_MESSAGE_MAP();
44   return handled;
45 }
46
47 void CastTransportHostFilter::NotifyStatusChange(
48     int32 channel_id,
49     media::cast::CastTransportStatus status) {
50   Send(new CastMsg_NotifyStatusChange(channel_id, status));
51 }
52
53 void CastTransportHostFilter::SendRawEvents(
54     int32 channel_id,
55     const std::vector<media::cast::PacketEvent>& packet_events,
56     const std::vector<media::cast::FrameEvent>& frame_events) {
57   if (!packet_events.empty())
58     Send(new CastMsg_RawEvents(channel_id,
59                                packet_events,
60                                frame_events));
61 }
62
63 void CastTransportHostFilter::SendRtt(int32 channel_id,
64                                       uint32 ssrc,
65                                       base::TimeDelta rtt,
66                                       base::TimeDelta avg_rtt,
67                                       base::TimeDelta min_rtt,
68                                       base::TimeDelta max_rtt) {
69   media::cast::RtcpRttReport report;
70   report.rtt = rtt;
71   report.avg_rtt = avg_rtt;
72   report.min_rtt = min_rtt;
73   report.max_rtt = max_rtt;
74   Send(new CastMsg_Rtt(channel_id, ssrc, report));
75 }
76
77 void CastTransportHostFilter::SendCastMessage(
78     int32 channel_id,
79     uint32 ssrc,
80     const media::cast::RtcpCastMessage& cast_message) {
81   Send(new CastMsg_RtcpCastMessage(channel_id, ssrc, cast_message));
82 }
83
84 void CastTransportHostFilter::OnNew(
85     int32 channel_id,
86     const net::IPEndPoint& remote_end_point) {
87   if (!power_save_blocker_) {
88     DVLOG(1) << ("Preventing the application from being suspended while one or "
89                  "more transports are active for Cast Streaming.");
90     power_save_blocker_ = content::PowerSaveBlocker::Create(
91         content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
92         "Cast is streaming content to a remote receiver.").Pass();
93   }
94
95   if (id_map_.Lookup(channel_id)) {
96     id_map_.Remove(channel_id);
97   }
98
99   scoped_ptr<media::cast::CastTransportSender> sender =
100       media::cast::CastTransportSender::Create(
101           g_browser_process->net_log(),
102           &clock_,
103           remote_end_point,
104           base::Bind(&CastTransportHostFilter::NotifyStatusChange,
105                      weak_factory_.GetWeakPtr(),
106                      channel_id),
107           base::Bind(&CastTransportHostFilter::SendRawEvents,
108                      weak_factory_.GetWeakPtr(),
109                      channel_id),
110           base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs),
111           base::MessageLoopProxy::current());
112   id_map_.AddWithID(sender.release(), channel_id);
113 }
114
115 void CastTransportHostFilter::OnDelete(int32 channel_id) {
116   media::cast::CastTransportSender* sender =
117       id_map_.Lookup(channel_id);
118   if (sender) {
119     id_map_.Remove(channel_id);
120   } else {
121     DVLOG(1) << "CastTransportHostFilter::Delete called "
122              << "on non-existing channel";
123   }
124
125   if (id_map_.IsEmpty()) {
126     DVLOG_IF(1, power_save_blocker_) <<
127         ("Releasing the block on application suspension since no transports "
128          "are active anymore for Cast Streaming.");
129     power_save_blocker_.reset();
130   }
131 }
132
133 void CastTransportHostFilter::OnInitializeAudio(
134     int32 channel_id,
135     const media::cast::CastTransportRtpConfig& config) {
136   media::cast::CastTransportSender* sender =
137       id_map_.Lookup(channel_id);
138   if (sender) {
139     sender->InitializeAudio(
140         config,
141         base::Bind(&CastTransportHostFilter::SendCastMessage,
142                    weak_factory_.GetWeakPtr(),
143                    channel_id, config.ssrc),
144         base::Bind(&CastTransportHostFilter::SendRtt,
145                    weak_factory_.GetWeakPtr(),
146                    channel_id, config.ssrc));
147   } else {
148     DVLOG(1)
149         << "CastTransportHostFilter::OnInitializeAudio on non-existing channel";
150   }
151 }
152
153 void CastTransportHostFilter::OnInitializeVideo(
154     int32 channel_id,
155     const media::cast::CastTransportRtpConfig& config) {
156   media::cast::CastTransportSender* sender =
157       id_map_.Lookup(channel_id);
158   if (sender) {
159     sender->InitializeVideo(
160         config,
161         base::Bind(&CastTransportHostFilter::SendCastMessage,
162                    weak_factory_.GetWeakPtr(),
163                    channel_id, config.ssrc),
164         base::Bind(&CastTransportHostFilter::SendRtt,
165                    weak_factory_.GetWeakPtr(),
166                    channel_id, config.ssrc));
167   } else {
168     DVLOG(1)
169         << "CastTransportHostFilter::OnInitializeVideo on non-existing channel";
170   }
171 }
172
173 void CastTransportHostFilter::OnInsertCodedAudioFrame(
174     int32 channel_id,
175     const media::cast::EncodedFrame& audio_frame) {
176   media::cast::CastTransportSender* sender =
177       id_map_.Lookup(channel_id);
178   if (sender) {
179     sender->InsertCodedAudioFrame(audio_frame);
180   } else {
181     DVLOG(1)
182         << "CastTransportHostFilter::OnInsertCodedAudioFrame "
183         << "on non-existing channel";
184   }
185 }
186
187 void CastTransportHostFilter::OnInsertCodedVideoFrame(
188     int32 channel_id,
189     const media::cast::EncodedFrame& video_frame) {
190   media::cast::CastTransportSender* sender =
191       id_map_.Lookup(channel_id);
192   if (sender) {
193     sender->InsertCodedVideoFrame(video_frame);
194   } else {
195     DVLOG(1)
196         << "CastTransportHostFilter::OnInsertCodedVideoFrame "
197         << "on non-existing channel";
198   }
199 }
200
201 void CastTransportHostFilter::OnSendSenderReport(
202     int32 channel_id,
203     uint32 ssrc,
204     base::TimeTicks current_time,
205     uint32 current_time_as_rtp_timestamp) {
206   media::cast::CastTransportSender* sender =
207       id_map_.Lookup(channel_id);
208   if (sender) {
209     sender->SendSenderReport(ssrc,
210                              current_time,
211                              current_time_as_rtp_timestamp);
212   } else {
213     DVLOG(1)
214         << "CastTransportHostFilter::OnSendSenderReport "
215         << "on non-existing channel";
216   }
217 }
218
219 void CastTransportHostFilter::OnResendPackets(
220     int32 channel_id,
221     bool is_audio,
222     const media::cast::MissingFramesAndPacketsMap& missing_packets,
223     bool cancel_rtx_if_not_in_list,
224     base::TimeDelta dedupe_window) {
225   media::cast::CastTransportSender* sender =
226       id_map_.Lookup(channel_id);
227   if (sender) {
228     sender->ResendPackets(
229         is_audio, missing_packets, cancel_rtx_if_not_in_list, dedupe_window);
230   } else {
231     DVLOG(1)
232         << "CastTransportHostFilter::OnResendPackets on non-existing channel";
233   }
234 }
235
236 }  // namespace cast