1 // Copyright 2013 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.
5 #include "chrome/renderer/media/cast_session_delegate.h"
7 #include "base/logging.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "content/public/renderer/p2p_socket_client.h"
10 #include "content/public/renderer/render_thread.h"
11 #include "media/cast/cast_config.h"
12 #include "media/cast/cast_environment.h"
13 #include "media/cast/cast_sender.h"
14 #include "media/cast/logging/logging_defines.h"
15 #include "media/cast/transport/cast_transport_config.h"
16 #include "media/cast/transport/cast_transport_sender.h"
18 using media::cast::AudioSenderConfig;
19 using media::cast::CastEnvironment;
20 using media::cast::CastSender;
21 using media::cast::VideoSenderConfig;
25 // This is a dummy class that does nothing. This is needed temporarily
26 // to enable tests for cast.streaming extension APIs.
27 // The real implementation of CastTransportSender is to use IPC to send
28 // data to the browser process.
29 // See crbug.com/327482 for more details.
30 class DummyTransport : public media::cast::transport::CastTransportSender {
33 virtual ~DummyTransport() {}
35 // CastTransportSender implementations.
36 virtual void SetPacketReceiver(
38 media::cast::transport::PacketReceiver> packet_receiver) OVERRIDE {}
39 virtual void InsertCodedAudioFrame(
40 const media::cast::transport::EncodedAudioFrame* audio_frame,
41 const base::TimeTicks& recorded_time) OVERRIDE {}
42 virtual void InsertCodedVideoFrame(
43 const media::cast::transport::EncodedVideoFrame* video_frame,
44 const base::TimeTicks& capture_time) OVERRIDE {}
45 virtual void SendRtcpFromRtpSender(
46 uint32 packet_type_flags,
47 const media::cast::transport::RtcpSenderInfo& sender_info,
48 const media::cast::transport::RtcpDlrrReportBlock& dlrr,
49 const media::cast::transport::RtcpSenderLogMessage& sender_log,
51 const std::string& c_name) OVERRIDE {}
52 virtual void ResendPackets(
54 const media::cast::transport::MissingFramesAndPacketsMap& missing_packets)
56 virtual void RtpAudioStatistics(
57 const base::TimeTicks& now,
58 media::cast::transport::RtcpSenderInfo* sender_info) OVERRIDE {}
59 virtual void RtpVideoStatistics(
60 const base::TimeTicks& now,
61 media::cast::transport::RtcpSenderInfo* sender_info) OVERRIDE {}
64 DISALLOW_COPY_AND_ASSIGN(DummyTransport);
69 CastSessionDelegate::CastSessionDelegate()
70 : audio_encode_thread_("CastAudioEncodeThread"),
71 video_encode_thread_("CastVideoEncodeThread"),
72 audio_configured_(false),
73 video_configured_(false),
74 io_message_loop_proxy_(
75 content::RenderThread::Get()->GetIOMessageLoopProxy()) {
78 CastSessionDelegate::~CastSessionDelegate() {
79 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
82 void CastSessionDelegate::StartAudio(
83 const AudioSenderConfig& config,
84 const FrameInputAvailableCallback& callback) {
85 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
87 audio_configured_ = true;
88 audio_config_ = config;
89 frame_input_available_callbacks_.push_back(callback);
90 StartSendingInternal();
93 void CastSessionDelegate::StartVideo(
94 const VideoSenderConfig& config,
95 const FrameInputAvailableCallback& callback) {
96 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
98 video_configured_ = true;
99 video_config_ = config;
100 frame_input_available_callbacks_.push_back(callback);
101 StartSendingInternal();
104 void CastSessionDelegate::StartSendingInternal() {
105 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
107 if (cast_environment_)
109 if (!audio_configured_ || !video_configured_)
112 cast_transport_.reset(new DummyTransport());
113 audio_encode_thread_.Start();
114 video_encode_thread_.Start();
116 // CastSender uses the renderer's IO thread as the main thread. This reduces
117 // thread hopping for incoming video frames and outgoing network packets.
118 // There's no need to decode so no thread assigned for decoding.
119 // Get default logging: All disabled.
120 cast_environment_ = new CastEnvironment(
121 scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(),
122 base::MessageLoopProxy::current(),
123 audio_encode_thread_.message_loop_proxy(),
125 video_encode_thread_.message_loop_proxy(),
127 base::MessageLoopProxy::current(),
128 media::cast::GetDefaultCastSenderLoggingConfig());
130 cast_sender_.reset(CastSender::CreateCastSender(
135 cast_transport_.get()));
137 for (size_t i = 0; i < frame_input_available_callbacks_.size(); ++i) {
138 frame_input_available_callbacks_[i].Run(
139 cast_sender_->frame_input());
141 frame_input_available_callbacks_.clear();