blob: b09ca96c25b9146a6c0a1f2ab1657191fbd6659f [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 "media/cast/transport/cast_transport_sender.h"
namespace {
// How often to send raw events.
const int kSendRawEventsIntervalSecs = 1;
}
namespace cast {
CastTransportHostFilter::CastTransportHostFilter()
: BrowserMessageFilter(CastMsgStart) {}
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_InsertCodedAudioFrame,
OnInsertCodedAudioFrame)
IPC_MESSAGE_HANDLER(CastHostMsg_InsertCodedVideoFrame,
OnInsertCodedVideoFrame)
IPC_MESSAGE_HANDLER(CastHostMsg_SendRtcpFromRtpSender,
OnSendRtcpFromRtpSender)
IPC_MESSAGE_HANDLER(CastHostMsg_ResendPackets,
OnResendPackets)
IPC_MESSAGE_UNHANDLED(handled = false);
IPC_END_MESSAGE_MAP();
return handled;
}
void CastTransportHostFilter::NotifyStatusChange(
int32 channel_id,
media::cast::transport::CastTransportStatus status) {
Send(new CastMsg_NotifyStatusChange(channel_id, status));
}
void CastTransportHostFilter::ReceivedPacket(
int32 channel_id,
scoped_ptr<media::cast::transport::Packet> packet) {
Send(new CastMsg_ReceivedPacket(channel_id, *packet));
}
void CastTransportHostFilter::RawEvents(
int32 channel_id,
const std::vector<media::cast::PacketEvent>& packet_events) {
if (!packet_events.empty())
Send(new CastMsg_RawEvents(channel_id, packet_events));
}
void CastTransportHostFilter::OnNew(
int32 channel_id,
const net::IPEndPoint& remote_end_point) {
if (id_map_.Lookup(channel_id)) {
id_map_.Remove(channel_id);
}
scoped_ptr<media::cast::transport::CastTransportSender> sender =
media::cast::transport::CastTransportSender::Create(
g_browser_process->net_log(),
&clock_,
remote_end_point,
base::Bind(&CastTransportHostFilter::NotifyStatusChange,
base::Unretained(this),
channel_id),
base::Bind(&CastTransportHostFilter::RawEvents,
base::Unretained(this),
channel_id),
base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs),
base::MessageLoopProxy::current());
sender->SetPacketReceiver(base::Bind(&CastTransportHostFilter::ReceivedPacket,
base::Unretained(this),
channel_id));
id_map_.AddWithID(sender.release(), channel_id);
}
void CastTransportHostFilter::OnDelete(int32 channel_id) {
media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
id_map_.Remove(channel_id);
} else {
DVLOG(1) << "CastTransportHostFilter::Delete called "
<< "on non-existing channel";
}
}
void CastTransportHostFilter::OnInitializeAudio(
int32 channel_id,
const media::cast::transport::CastTransportAudioConfig& config) {
media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->InitializeAudio(config);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnInitializeAudio on non-existing channel";
}
}
void CastTransportHostFilter::OnInitializeVideo(
int32 channel_id,
const media::cast::transport::CastTransportVideoConfig& config) {
media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->InitializeVideo(config);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnInitializeVideo on non-existing channel";
}
}
void CastTransportHostFilter::OnInsertCodedAudioFrame(
int32 channel_id,
const media::cast::transport::EncodedFrame& audio_frame) {
media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->InsertCodedAudioFrame(audio_frame);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnInsertCodedAudioFrame "
<< "on non-existing channel";
}
}
void CastTransportHostFilter::OnInsertCodedVideoFrame(
int32 channel_id,
const media::cast::transport::EncodedFrame& video_frame) {
media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->InsertCodedVideoFrame(video_frame);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnInsertCodedVideoFrame "
<< "on non-existing channel";
}
}
void CastTransportHostFilter::OnSendRtcpFromRtpSender(
int32 channel_id,
const media::cast::transport::SendRtcpFromRtpSenderData& data,
const media::cast::transport::RtcpDlrrReportBlock& dlrr) {
media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->SendRtcpFromRtpSender(data.packet_type_flags,
data.ntp_seconds,
data.ntp_fraction,
data.rtp_timestamp,
dlrr,
data.sending_ssrc,
data.c_name);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnSendRtcpFromRtpSender "
<< "on non-existing channel";
}
}
void CastTransportHostFilter::OnResendPackets(
int32 channel_id,
bool is_audio,
const media::cast::MissingFramesAndPacketsMap& missing_packets,
bool cancel_rtx_if_not_in_list,
base::TimeDelta dedupe_window) {
media::cast::transport::CastTransportSender* sender =
id_map_.Lookup(channel_id);
if (sender) {
sender->ResendPackets(
is_audio, missing_packets, cancel_rtx_if_not_in_list, dedupe_window);
} else {
DVLOG(1)
<< "CastTransportHostFilter::OnResendPackets on non-existing channel";
}
}
} // namespace cast