Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / chrome / renderer / media / cast_session_delegate.cc
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.
4
5 #include "chrome/renderer/media/cast_session_delegate.h"
6
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"
17
18 using media::cast::AudioSenderConfig;
19 using media::cast::CastEnvironment;
20 using media::cast::CastSender;
21 using media::cast::VideoSenderConfig;
22
23 namespace {
24
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 {
31  public:
32   DummyTransport() {}
33   virtual ~DummyTransport() {}
34
35   // CastTransportSender implementations.
36   virtual void SetPacketReceiver(
37       scoped_refptr<
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,
50       uint32 sending_ssrc,
51       const std::string& c_name) OVERRIDE {}
52   virtual void ResendPackets(
53       bool is_audio,
54       const media::cast::transport::MissingFramesAndPacketsMap& missing_packets)
55       OVERRIDE {}
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 {}
62
63  private:
64   DISALLOW_COPY_AND_ASSIGN(DummyTransport);
65 };
66
67 }  // namespace
68
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()) {
76 }
77
78 CastSessionDelegate::~CastSessionDelegate() {
79   DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
80 }
81
82 void CastSessionDelegate::StartAudio(
83     const AudioSenderConfig& config,
84     const FrameInputAvailableCallback& callback) {
85   DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
86
87   audio_configured_ = true;
88   audio_config_ = config;
89   frame_input_available_callbacks_.push_back(callback);
90   StartSendingInternal();
91 }
92
93 void CastSessionDelegate::StartVideo(
94     const VideoSenderConfig& config,
95     const FrameInputAvailableCallback& callback) {
96   DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
97
98   video_configured_ = true;
99   video_config_ = config;
100   frame_input_available_callbacks_.push_back(callback);
101   StartSendingInternal();
102 }
103
104 void CastSessionDelegate::StartSendingInternal() {
105   DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
106
107   if (cast_environment_)
108     return;
109   if (!audio_configured_ || !video_configured_)
110     return;
111
112   cast_transport_.reset(new DummyTransport());
113   audio_encode_thread_.Start();
114   video_encode_thread_.Start();
115
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(),
124       NULL,
125       video_encode_thread_.message_loop_proxy(),
126       NULL,
127       base::MessageLoopProxy::current(),
128       media::cast::GetDefaultCastSenderLoggingConfig());
129
130   cast_sender_.reset(CastSender::CreateCastSender(
131       cast_environment_,
132       audio_config_,
133       video_config_,
134       NULL,
135       cast_transport_.get()));
136
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());
140   }
141   frame_input_available_callbacks_.clear();
142 }