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/renderer/media/cast_transport_sender_ipc.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/id_map.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/cast_messages.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/renderer/media/cast_ipc_dispatcher.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ipc/ipc_channel_proxy.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cast/cast_sender.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/cast/transport/cast_transport_sender.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CastTransportSenderIPC::CastTransportSenderIPC(
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const net::IPEndPoint& remote_end_point,
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const media::cast::transport::CastTransportStatusCallback& status_cb,
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const media::cast::transport::BulkRawEventsCallback& raw_events_cb)
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : status_callback_(status_cb), raw_events_callback_(raw_events_cb) {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (CastIPCDispatcher::Get()) {
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    channel_id_ = CastIPCDispatcher::Get()->AddSender(this);
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Send(new CastHostMsg_New(channel_id_, remote_end_point));
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CastTransportSenderIPC::~CastTransportSenderIPC() {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new CastHostMsg_Delete(channel_id_));
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (CastIPCDispatcher::Get()) {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CastIPCDispatcher::Get()->RemoveSender(channel_id_);
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::SetPacketReceiver(
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const media::cast::transport::PacketReceiverCallback& packet_callback) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  packet_callback_ = packet_callback;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CastTransportSenderIPC::InitializeAudio(
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const media::cast::transport::CastTransportAudioConfig& config) {
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new CastHostMsg_InitializeAudio(channel_id_, config));
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CastTransportSenderIPC::InitializeVideo(
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const media::cast::transport::CastTransportVideoConfig& config) {
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Send(new CastHostMsg_InitializeVideo(channel_id_, config));
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::InsertCodedAudioFrame(
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const media::cast::transport::EncodedFrame& audio_frame) {
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Send(new CastHostMsg_InsertCodedAudioFrame(channel_id_, audio_frame));
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::InsertCodedVideoFrame(
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const media::cast::transport::EncodedFrame& video_frame) {
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Send(new CastHostMsg_InsertCodedVideoFrame(channel_id_, video_frame));
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::SendRtcpFromRtpSender(
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32 packet_type_flags,
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    uint32 ntp_seconds,
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    uint32 ntp_fraction,
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    uint32 rtp_timestamp,
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const media::cast::transport::RtcpDlrrReportBlock& dlrr,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    uint32 sending_ssrc,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& c_name) {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct media::cast::transport::SendRtcpFromRtpSenderData data;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.packet_type_flags = packet_type_flags;
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.sending_ssrc = sending_ssrc;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  data.c_name = c_name;
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  data.ntp_seconds = ntp_seconds;
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  data.ntp_fraction = ntp_fraction;
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  data.rtp_timestamp = rtp_timestamp;
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new CastHostMsg_SendRtcpFromRtpSender(
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      channel_id_,
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      data,
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      dlrr));
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::ResendPackets(
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool is_audio,
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const media::cast::MissingFramesAndPacketsMap& missing_packets,
826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    bool cancel_rtx_if_not_in_list,
836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::TimeDelta dedupe_window) {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Send(new CastHostMsg_ResendPackets(channel_id_,
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     is_audio,
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                     missing_packets,
876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                     cancel_rtx_if_not_in_list,
886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                     dedupe_window));
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::OnReceivedPacket(
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const media::cast::Packet& packet) {
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!packet_callback_.is_null()) {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(hubbe): Perhaps an non-ownership-transferring cb here?
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<media::cast::transport::Packet> packet_copy(
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new media::cast::transport::Packet(packet));
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    packet_callback_.Run(packet_copy.Pass());
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1) << "CastIPCDispatcher::OnReceivedPacket no packet callback yet.";
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::OnNotifyStatusChange(
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    media::cast::transport::CastTransportStatus status) {
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  status_callback_.Run(status);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CastTransportSenderIPC::OnRawEvents(
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::vector<media::cast::PacketEvent>& packet_events) {
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  raw_events_callback_.Run(packet_events);
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CastTransportSenderIPC::Send(IPC::Message* message) {
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (CastIPCDispatcher::Get()) {
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CastIPCDispatcher::Get()->Send(message);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delete message;
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
120