15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/media/cast_transport_host_filter.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/browser_process.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/net/chrome_net_log.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cast/transport/cast_transport_sender.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// How often to send raw events.
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kSendRawEventsIntervalSecs = 1;
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace cast {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CastTransportHostFilter::CastTransportHostFilter()
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : BrowserMessageFilter(CastMsgStart) {}
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)CastTransportHostFilter::~CastTransportHostFilter() {}
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool CastTransportHostFilter::OnMessageReceived(const IPC::Message& message) {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool handled = true;
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(CastTransportHostFilter, message)
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_New, OnNew)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_Delete, OnDelete)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_InitializeAudio, OnInitializeAudio)
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_InitializeVideo, OnInitializeVideo)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_InsertCodedAudioFrame,
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnInsertCodedAudioFrame)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_InsertCodedVideoFrame,
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnInsertCodedVideoFrame)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_SendRtcpFromRtpSender,
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        OnSendRtcpFromRtpSender)
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_HANDLER(CastHostMsg_ResendPackets,
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        OnResendPackets)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false);
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_END_MESSAGE_MAP();
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return handled;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::NotifyStatusChange(
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 channel_id,
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    media::cast::transport::CastTransportStatus status) {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new CastMsg_NotifyStatusChange(channel_id, status));
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::ReceivedPacket(
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 channel_id,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<media::cast::transport::Packet> packet) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new CastMsg_ReceivedPacket(channel_id, *packet));
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CastTransportHostFilter::RawEvents(
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int32 channel_id,
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::vector<media::cast::PacketEvent>& packet_events) {
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!packet_events.empty())
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Send(new CastMsg_RawEvents(channel_id, packet_events));
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::OnNew(
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 channel_id,
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const net::IPEndPoint& remote_end_point) {
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (id_map_.Lookup(channel_id)) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    id_map_.Remove(channel_id);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<media::cast::transport::CastTransportSender> sender =
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      media::cast::transport::CastTransportSender::Create(
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          g_browser_process->net_log(),
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          &clock_,
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          remote_end_point,
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&CastTransportHostFilter::NotifyStatusChange,
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::Unretained(this),
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     channel_id),
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::Bind(&CastTransportHostFilter::RawEvents,
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     base::Unretained(this),
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     channel_id),
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::TimeDelta::FromSeconds(kSendRawEventsIntervalSecs),
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          base::MessageLoopProxy::current());
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  sender->SetPacketReceiver(base::Bind(&CastTransportHostFilter::ReceivedPacket,
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       base::Unretained(this),
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       channel_id));
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  id_map_.AddWithID(sender.release(), channel_id);
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::OnDelete(int32 channel_id) {
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::cast::transport::CastTransportSender* sender =
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      id_map_.Lookup(channel_id);
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (sender) {
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    id_map_.Remove(channel_id);
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1) << "CastTransportHostFilter::Delete called "
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)             << "on non-existing channel";
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CastTransportHostFilter::OnInitializeAudio(
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int32 channel_id,
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const media::cast::transport::CastTransportAudioConfig& config) {
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  media::cast::transport::CastTransportSender* sender =
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      id_map_.Lookup(channel_id);
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (sender) {
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    sender->InitializeAudio(config);
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        << "CastTransportHostFilter::OnInitializeAudio on non-existing channel";
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CastTransportHostFilter::OnInitializeVideo(
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int32 channel_id,
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const media::cast::transport::CastTransportVideoConfig& config) {
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  media::cast::transport::CastTransportSender* sender =
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      id_map_.Lookup(channel_id);
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (sender) {
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    sender->InitializeVideo(config);
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1)
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        << "CastTransportHostFilter::OnInitializeVideo on non-existing channel";
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::OnInsertCodedAudioFrame(
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 channel_id,
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const media::cast::transport::EncodedFrame& audio_frame) {
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::cast::transport::CastTransportSender* sender =
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      id_map_.Lookup(channel_id);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (sender) {
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    sender->InsertCodedAudioFrame(audio_frame);
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "CastTransportHostFilter::OnInsertCodedAudioFrame "
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "on non-existing channel";
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::OnInsertCodedVideoFrame(
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 channel_id,
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const media::cast::transport::EncodedFrame& video_frame) {
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::cast::transport::CastTransportSender* sender =
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      id_map_.Lookup(channel_id);
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (sender) {
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    sender->InsertCodedVideoFrame(video_frame);
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "CastTransportHostFilter::OnInsertCodedVideoFrame "
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "on non-existing channel";
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::OnSendRtcpFromRtpSender(
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 channel_id,
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const media::cast::transport::SendRtcpFromRtpSenderData& data,
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const media::cast::transport::RtcpDlrrReportBlock& dlrr) {
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::cast::transport::CastTransportSender* sender =
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      id_map_.Lookup(channel_id);
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (sender) {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sender->SendRtcpFromRtpSender(data.packet_type_flags,
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  data.ntp_seconds,
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  data.ntp_fraction,
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  data.rtp_timestamp,
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  dlrr,
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  data.sending_ssrc,
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  data.c_name);
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "CastTransportHostFilter::OnSendRtcpFromRtpSender "
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "on non-existing channel";
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportHostFilter::OnResendPackets(
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int32 channel_id,
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool is_audio,
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const media::cast::MissingFramesAndPacketsMap& missing_packets,
1826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    bool cancel_rtx_if_not_in_list,
1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::TimeDelta dedupe_window) {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  media::cast::transport::CastTransportSender* sender =
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      id_map_.Lookup(channel_id);
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (sender) {
1876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    sender->ResendPackets(
1886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        is_audio, missing_packets, cancel_rtx_if_not_in_list, dedupe_window);
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DVLOG(1)
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        << "CastTransportHostFilter::OnResendPackets on non-existing channel";
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace cast
196