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 "media/cast/transport/cast_transport_sender.h"
10
11 namespace {
12
13 // How often to send raw events.
14 const int kSendRawEventsIntervalSecs = 1;
15
16 }
17
18 namespace cast {
19
CastTransportHostFilter()20 CastTransportHostFilter::CastTransportHostFilter()
21 : BrowserMessageFilter(CastMsgStart) {}
22
~CastTransportHostFilter()23 CastTransportHostFilter::~CastTransportHostFilter() {}
24
OnMessageReceived(const IPC::Message & message)25 bool CastTransportHostFilter::OnMessageReceived(const IPC::Message& message) {
26 bool handled = true;
27 IPC_BEGIN_MESSAGE_MAP(CastTransportHostFilter, message)
28 IPC_MESSAGE_HANDLER(CastHostMsg_New, OnNew)
29 IPC_MESSAGE_HANDLER(CastHostMsg_Delete, OnDelete)
30 IPC_MESSAGE_HANDLER(CastHostMsg_InitializeAudio, OnInitializeAudio)
31 IPC_MESSAGE_HANDLER(CastHostMsg_InitializeVideo, OnInitializeVideo)
32 IPC_MESSAGE_HANDLER(CastHostMsg_InsertCodedAudioFrame,
33 OnInsertCodedAudioFrame)
34 IPC_MESSAGE_HANDLER(CastHostMsg_InsertCodedVideoFrame,
35 OnInsertCodedVideoFrame)
36 IPC_MESSAGE_HANDLER(CastHostMsg_SendRtcpFromRtpSender,
37 OnSendRtcpFromRtpSender)
38 IPC_MESSAGE_HANDLER(CastHostMsg_ResendPackets,
39 OnResendPackets)
40 IPC_MESSAGE_UNHANDLED(handled = false);
41 IPC_END_MESSAGE_MAP();
42 return handled;
43 }
44
NotifyStatusChange(int32 channel_id,media::cast::transport::CastTransportStatus status)45 void CastTransportHostFilter::NotifyStatusChange(
46 int32 channel_id,
47 media::cast::transport::CastTransportStatus status) {
48 Send(new CastMsg_NotifyStatusChange(channel_id, status));
49 }
50
ReceivedPacket(int32 channel_id,scoped_ptr<media::cast::transport::Packet> packet)51 void CastTransportHostFilter::ReceivedPacket(
52 int32 channel_id,
53 scoped_ptr<media::cast::transport::Packet> packet) {
54 Send(new CastMsg_ReceivedPacket(channel_id, *packet));
55 }
56
RawEvents(int32 channel_id,const std::vector<media::cast::PacketEvent> & packet_events)57 void CastTransportHostFilter::RawEvents(
58 int32 channel_id,
59 const std::vector<media::cast::PacketEvent>& packet_events) {
60 if (!packet_events.empty())
61 Send(new CastMsg_RawEvents(channel_id, packet_events));
62 }
63
OnNew(int32 channel_id,const net::IPEndPoint & remote_end_point)64 void CastTransportHostFilter::OnNew(
65 int32 channel_id,
66 const net::IPEndPoint& remote_end_point) {
67 if (id_map_.Lookup(channel_id)) {
68 id_map_.Remove(channel_id);
69 }
70
71 scoped_ptr<media::cast::transport::CastTransportSender> sender =
72 media::cast::transport::CastTransportSender::Create(
73 g_browser_process->net_log(),
74 &clock_,
75 remote_end_point,
76 base::Bind(&CastTransportHostFilter::NotifyStatusChange,
77 base::Unretained(this),
78 channel_id),
79 base::Bind(&CastTransportHostFilter::RawEvents,
80 base::Unretained(this),
81 channel_id),
82 base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs),
83 base::MessageLoopProxy::current());
84
85 sender->SetPacketReceiver(base::Bind(&CastTransportHostFilter::ReceivedPacket,
86 base::Unretained(this),
87 channel_id));
88
89 id_map_.AddWithID(sender.release(), channel_id);
90 }
91
OnDelete(int32 channel_id)92 void CastTransportHostFilter::OnDelete(int32 channel_id) {
93 media::cast::transport::CastTransportSender* sender =
94 id_map_.Lookup(channel_id);
95 if (sender) {
96 id_map_.Remove(channel_id);
97 } else {
98 DVLOG(1) << "CastTransportHostFilter::Delete called "
99 << "on non-existing channel";
100 }
101 }
102
OnInitializeAudio(int32 channel_id,const media::cast::transport::CastTransportAudioConfig & config)103 void CastTransportHostFilter::OnInitializeAudio(
104 int32 channel_id,
105 const media::cast::transport::CastTransportAudioConfig& config) {
106 media::cast::transport::CastTransportSender* sender =
107 id_map_.Lookup(channel_id);
108 if (sender) {
109 sender->InitializeAudio(config);
110 } else {
111 DVLOG(1)
112 << "CastTransportHostFilter::OnInitializeAudio on non-existing channel";
113 }
114 }
115
OnInitializeVideo(int32 channel_id,const media::cast::transport::CastTransportVideoConfig & config)116 void CastTransportHostFilter::OnInitializeVideo(
117 int32 channel_id,
118 const media::cast::transport::CastTransportVideoConfig& config) {
119 media::cast::transport::CastTransportSender* sender =
120 id_map_.Lookup(channel_id);
121 if (sender) {
122 sender->InitializeVideo(config);
123 } else {
124 DVLOG(1)
125 << "CastTransportHostFilter::OnInitializeVideo on non-existing channel";
126 }
127 }
128
OnInsertCodedAudioFrame(int32 channel_id,const media::cast::transport::EncodedFrame & audio_frame)129 void CastTransportHostFilter::OnInsertCodedAudioFrame(
130 int32 channel_id,
131 const media::cast::transport::EncodedFrame& audio_frame) {
132 media::cast::transport::CastTransportSender* sender =
133 id_map_.Lookup(channel_id);
134 if (sender) {
135 sender->InsertCodedAudioFrame(audio_frame);
136 } else {
137 DVLOG(1)
138 << "CastTransportHostFilter::OnInsertCodedAudioFrame "
139 << "on non-existing channel";
140 }
141 }
142
OnInsertCodedVideoFrame(int32 channel_id,const media::cast::transport::EncodedFrame & video_frame)143 void CastTransportHostFilter::OnInsertCodedVideoFrame(
144 int32 channel_id,
145 const media::cast::transport::EncodedFrame& video_frame) {
146 media::cast::transport::CastTransportSender* sender =
147 id_map_.Lookup(channel_id);
148 if (sender) {
149 sender->InsertCodedVideoFrame(video_frame);
150 } else {
151 DVLOG(1)
152 << "CastTransportHostFilter::OnInsertCodedVideoFrame "
153 << "on non-existing channel";
154 }
155 }
156
OnSendRtcpFromRtpSender(int32 channel_id,const media::cast::transport::SendRtcpFromRtpSenderData & data,const media::cast::transport::RtcpDlrrReportBlock & dlrr)157 void CastTransportHostFilter::OnSendRtcpFromRtpSender(
158 int32 channel_id,
159 const media::cast::transport::SendRtcpFromRtpSenderData& data,
160 const media::cast::transport::RtcpDlrrReportBlock& dlrr) {
161 media::cast::transport::CastTransportSender* sender =
162 id_map_.Lookup(channel_id);
163 if (sender) {
164 sender->SendRtcpFromRtpSender(data.packet_type_flags,
165 data.ntp_seconds,
166 data.ntp_fraction,
167 data.rtp_timestamp,
168 dlrr,
169 data.sending_ssrc,
170 data.c_name);
171 } else {
172 DVLOG(1)
173 << "CastTransportHostFilter::OnSendRtcpFromRtpSender "
174 << "on non-existing channel";
175 }
176 }
177
OnResendPackets(int32 channel_id,bool is_audio,const media::cast::MissingFramesAndPacketsMap & missing_packets,bool cancel_rtx_if_not_in_list,base::TimeDelta dedupe_window)178 void CastTransportHostFilter::OnResendPackets(
179 int32 channel_id,
180 bool is_audio,
181 const media::cast::MissingFramesAndPacketsMap& missing_packets,
182 bool cancel_rtx_if_not_in_list,
183 base::TimeDelta dedupe_window) {
184 media::cast::transport::CastTransportSender* sender =
185 id_map_.Lookup(channel_id);
186 if (sender) {
187 sender->ResendPackets(
188 is_audio, missing_packets, cancel_rtx_if_not_in_list, dedupe_window);
189 } else {
190 DVLOG(1)
191 << "CastTransportHostFilter::OnResendPackets on non-existing channel";
192 }
193 }
194
195 } // namespace cast
196