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.
5 #include "chrome/browser/media/cast_transport_host_filter.h"
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"
14 // How often to send raw events.
15 const int kSendRawEventsIntervalSecs
= 1;
21 CastTransportHostFilter::CastTransportHostFilter()
22 : BrowserMessageFilter(CastMsgStart
),
23 weak_factory_(this) {}
25 CastTransportHostFilter::~CastTransportHostFilter() {}
27 bool CastTransportHostFilter::OnMessageReceived(const IPC::Message
& message
) {
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_InsertFrame
, OnInsertFrame
)
35 IPC_MESSAGE_HANDLER(CastHostMsg_SendSenderReport
,
37 IPC_MESSAGE_HANDLER(CastHostMsg_ResendFrameForKickstart
,
38 OnResendFrameForKickstart
)
39 IPC_MESSAGE_HANDLER(CastHostMsg_CancelSendingFrames
,
40 OnCancelSendingFrames
)
41 IPC_MESSAGE_UNHANDLED(handled
= false);
42 IPC_END_MESSAGE_MAP();
46 void CastTransportHostFilter::NotifyStatusChange(
48 media::cast::CastTransportStatus status
) {
49 Send(new CastMsg_NotifyStatusChange(channel_id
, status
));
52 void CastTransportHostFilter::SendRawEvents(
54 const std::vector
<media::cast::PacketEvent
>& packet_events
,
55 const std::vector
<media::cast::FrameEvent
>& frame_events
) {
56 if (!packet_events
.empty())
57 Send(new CastMsg_RawEvents(channel_id
,
62 void CastTransportHostFilter::SendRtt(int32 channel_id
,
64 base::TimeDelta rtt
) {
65 Send(new CastMsg_Rtt(channel_id
, ssrc
, rtt
));
68 void CastTransportHostFilter::SendCastMessage(
71 const media::cast::RtcpCastMessage
& cast_message
) {
72 Send(new CastMsg_RtcpCastMessage(channel_id
, ssrc
, cast_message
));
75 void CastTransportHostFilter::OnNew(
77 const net::IPEndPoint
& remote_end_point
,
78 const base::DictionaryValue
& options
) {
79 if (!power_save_blocker_
) {
80 DVLOG(1) << ("Preventing the application from being suspended while one or "
81 "more transports are active for Cast Streaming.");
82 power_save_blocker_
= content::PowerSaveBlocker::Create(
83 content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension
,
84 "Cast is streaming content to a remote receiver.").Pass();
87 if (id_map_
.Lookup(channel_id
)) {
88 id_map_
.Remove(channel_id
);
91 scoped_ptr
<media::cast::CastTransportSender
> sender
=
92 media::cast::CastTransportSender::Create(
93 g_browser_process
->net_log(),
96 make_scoped_ptr(options
.DeepCopy()),
97 base::Bind(&CastTransportHostFilter::NotifyStatusChange
,
98 weak_factory_
.GetWeakPtr(),
100 base::Bind(&CastTransportHostFilter::SendRawEvents
,
101 weak_factory_
.GetWeakPtr(),
103 base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs
),
104 base::MessageLoopProxy::current());
105 id_map_
.AddWithID(sender
.release(), channel_id
);
108 void CastTransportHostFilter::OnDelete(int32 channel_id
) {
109 media::cast::CastTransportSender
* sender
=
110 id_map_
.Lookup(channel_id
);
112 id_map_
.Remove(channel_id
);
114 DVLOG(1) << "CastTransportHostFilter::Delete called "
115 << "on non-existing channel";
118 if (id_map_
.IsEmpty()) {
119 DVLOG_IF(1, power_save_blocker_
) <<
120 ("Releasing the block on application suspension since no transports "
121 "are active anymore for Cast Streaming.");
122 power_save_blocker_
.reset();
126 void CastTransportHostFilter::OnInitializeAudio(
128 const media::cast::CastTransportRtpConfig
& config
) {
129 media::cast::CastTransportSender
* sender
=
130 id_map_
.Lookup(channel_id
);
132 sender
->InitializeAudio(
134 base::Bind(&CastTransportHostFilter::SendCastMessage
,
135 weak_factory_
.GetWeakPtr(),
136 channel_id
, config
.ssrc
),
137 base::Bind(&CastTransportHostFilter::SendRtt
,
138 weak_factory_
.GetWeakPtr(),
139 channel_id
, config
.ssrc
));
142 << "CastTransportHostFilter::OnInitializeAudio on non-existing channel";
146 void CastTransportHostFilter::OnInitializeVideo(
148 const media::cast::CastTransportRtpConfig
& config
) {
149 media::cast::CastTransportSender
* sender
=
150 id_map_
.Lookup(channel_id
);
152 sender
->InitializeVideo(
154 base::Bind(&CastTransportHostFilter::SendCastMessage
,
155 weak_factory_
.GetWeakPtr(),
156 channel_id
, config
.ssrc
),
157 base::Bind(&CastTransportHostFilter::SendRtt
,
158 weak_factory_
.GetWeakPtr(),
159 channel_id
, config
.ssrc
));
162 << "CastTransportHostFilter::OnInitializeVideo on non-existing channel";
166 void CastTransportHostFilter::OnInsertFrame(
169 const media::cast::EncodedFrame
& frame
) {
170 media::cast::CastTransportSender
* sender
=
171 id_map_
.Lookup(channel_id
);
173 sender
->InsertFrame(ssrc
, frame
);
176 << "CastTransportHostFilter::OnInsertFrame on non-existing channel";
180 void CastTransportHostFilter::OnCancelSendingFrames(
181 int32 channel_id
, uint32 ssrc
,
182 const std::vector
<uint32
>& frame_ids
) {
183 media::cast::CastTransportSender
* sender
=
184 id_map_
.Lookup(channel_id
);
186 sender
->CancelSendingFrames(ssrc
, frame_ids
);
189 << "CastTransportHostFilter::OnCancelSendingFrames "
190 << "on non-existing channel";
194 void CastTransportHostFilter::OnResendFrameForKickstart(
195 int32 channel_id
, uint32 ssrc
, uint32 frame_id
) {
196 media::cast::CastTransportSender
* sender
=
197 id_map_
.Lookup(channel_id
);
199 sender
->ResendFrameForKickstart(ssrc
, frame_id
);
202 << "CastTransportHostFilter::OnResendFrameForKickstart "
203 << "on non-existing channel";
207 void CastTransportHostFilter::OnSendSenderReport(
210 base::TimeTicks current_time
,
211 uint32 current_time_as_rtp_timestamp
) {
212 media::cast::CastTransportSender
* sender
=
213 id_map_
.Lookup(channel_id
);
215 sender
->SendSenderReport(ssrc
,
217 current_time_as_rtp_timestamp
);
220 << "CastTransportHostFilter::OnSendSenderReport "
221 << "on non-existing channel";