blob: 3f7739d506a0523a75f46b7431a6b15ca5e2b961 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/media/cast_transport_host_filter.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/chrome_net_log.h"
#include "content/public/browser/power_save_blocker.h"
#include "media/cast/net/cast_transport_sender.h"
namespace {
// How often to send raw events.
const int kSendRawEventsIntervalSecs = 1;
}
namespace cast {
CastTransportHostFilter::CastTransportHostFilter()
: BrowserMessageFilter(CastMsgStart),
weak_factory_(this) {}
CastTransportHostFilter::~CastTransportHostFilter() {}
bool CastTransportHostFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(CastTransportHostFilter, message)
IPC_MESSAGE_HANDLER(CastHostMsg_New, OnNew)
IPC_MESSAGE_HANDLER(CastHostMsg_Delete, OnDelete)
IPC_MESSAGE_HANDLER(CastHostMsg_InitializeAudio, OnInitializeAudio)
IPC_MESSAGE_HANDLER(CastHostMsg_InitializeVideo, OnInitializeVideo)
IPC_MESSAGE_HANDLER(CastHostMsg_InsertFrame, OnInsertFrame)
IPC_MESSAGE_HANDLER(CastHostMsg_SendSenderReport,
OnSendSenderReport)
IPC_MESSAGE_HANDLER(CastHostMsg_ResendFrameForKickstart,
OnResendFrameForKickstart)
IPC_MESSAGE_HANDLER(CastHostMsg_CancelSendingFrames,
OnCancelSendingFrames)
IPC_MESSAGE_UNHANDLED(handled = false);
IPC_END_MESSAGE_MAP();
return handled;
}
void CastTransportHostFilter::NotifyStatusChange(
int32 channel_id,
media::cast::CastTransportStatus status) {
Send(new CastMsg_NotifyStatusChange(channel_id, status));
}
void CastTransportHostFilter::SendRawEvents(
int32 channel_id,
const std::vector<media::cast::PacketEvent>& packet_events,
const std::vector<media::cast::FrameEvent>& frame_events) {
if (!packet_events.empty())
Send(new CastMsg_RawEvents(channel_id,
packet_events,
frame_events));
}
void CastTransportHostFilter::SendRtt(int32 channel_id,
uint32 ssrc,
base::TimeDelta rtt) {
Send(new CastMsg_Rtt(channel_id, ssrc, rtt));
}
void CastTransportHostFilter::SendCastMessage(
int32 channel_id,
uint32 ssrc,
const media::cast::RtcpCastMessage& cast_message) {
Send(new CastMsg_RtcpCastMessage(channel_id, ssrc, cast_message));
}
void CastTransportHostFilter::OnNew(
int32 channel_id,
const net::IPEndPoint& remote_end_point,
const base::DictionaryValue& options) {
if (!power_save_blocker_) {
DVLOG(1) << ("Preventing the application from being suspended while one or "
"more transports are active for Cast Streaming.");
power_save_blocker_ = content::PowerSaveBlocker::Create(
content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
"Cast is streaming content to a remote receiver.").Pass();
}
if (id_map_.Lookup(channel_id)) {
id_map_.Remove(channel_id);
}
scoped_ptr<media::cast::CastTransportSender> sender =
media::cast::CastTransportSender::Create(
g_browser_process->net_log(),
&clock_,
remote_end_point,
make_scoped_ptr(options.DeepCopy()),
base::Bind(&CastTransportHostFilter::NotifyStatusChange,
weak_factory_.GetWeakPtr(),
channel_id),
base::Bind(&CastTransportHostFilter::SendRawEvents,
weak_factory_.GetWeakPtr(),
channel_id),
base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs),
base::MessageLoopProxy::current());
id_map_.AddWithID(sender.release(), channel_id);
}
void CastTransportHostFilter::OnDelete(int32 channel_id) {
media::cast::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
id_map_.Remove(channel_id);
} else {
DVLOG(1) << "CastTransportHostFilter::Delete called "
<< "on non-existing channel";
}
if (id_map_.IsEmpty()) {
DVLOG_IF(1, power_save_blocker_) <<
("Releasing the block on application suspension since no transports "
"are active anymore for Cast Streaming.");
power_save_blocker_.reset();
}
}
void CastTransportHostFilter::OnInitializeAudio(
int32 channel_id,
const media::cast::CastTransportRtpConfig& config) {
media::cast::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->InitializeAudio(
config,
base::Bind(&CastTransportHostFilter::SendCastMessage,
weak_factory_.GetWeakPtr(),
channel_id, config.ssrc),
base::Bind(&CastTransportHostFilter::SendRtt,
weak_factory_.GetWeakPtr(),
channel_id, config.ssrc));
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnInitializeAudio on non-existing channel";
}
}
void CastTransportHostFilter::OnInitializeVideo(
int32 channel_id,
const media::cast::CastTransportRtpConfig& config) {
media::cast::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->InitializeVideo(
config,
base::Bind(&CastTransportHostFilter::SendCastMessage,
weak_factory_.GetWeakPtr(),
channel_id, config.ssrc),
base::Bind(&CastTransportHostFilter::SendRtt,
weak_factory_.GetWeakPtr(),
channel_id, config.ssrc));
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnInitializeVideo on non-existing channel";
}
}
void CastTransportHostFilter::OnInsertFrame(
int32 channel_id,
uint32 ssrc,
const media::cast::EncodedFrame& frame) {
media::cast::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->InsertFrame(ssrc, frame);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnInsertFrame on non-existing channel";
}
}
void CastTransportHostFilter::OnCancelSendingFrames(
int32 channel_id, uint32 ssrc,
const std::vector<uint32>& frame_ids) {
media::cast::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->CancelSendingFrames(ssrc, frame_ids);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnCancelSendingFrames "
<< "on non-existing channel";
}
}
void CastTransportHostFilter::OnResendFrameForKickstart(
int32 channel_id, uint32 ssrc, uint32 frame_id) {
media::cast::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->ResendFrameForKickstart(ssrc, frame_id);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnResendFrameForKickstart "
<< "on non-existing channel";
}
}
void CastTransportHostFilter::OnSendSenderReport(
int32 channel_id,
uint32 ssrc,
base::TimeTicks current_time,
uint32 current_time_as_rtp_timestamp) {
media::cast::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->SendSenderReport(ssrc,
current_time,
current_time_as_rtp_timestamp);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnSendSenderReport "
<< "on non-existing channel";
}
}
} // namespace cast