1 // Copyright 2015 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_receiver_session.h"
7 #include "base/location.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "chrome/renderer/media/cast_receiver_audio_valve.h"
11 #include "content/public/renderer/render_thread.h"
12 #include "media/base/audio_capturer_source.h"
13 #include "media/base/bind_to_current_loop.h"
14 #include "media/base/video_capturer_source.h"
15 #include "third_party/WebKit/public/platform/WebMediaStream.h"
16 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
17 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
19 // This is a render thread object.
20 class CastReceiverSession::AudioCapturerSource
:
21 public media::AudioCapturerSource
{
24 const scoped_refptr
<CastReceiverSession
> cast_receiver_session
);
25 void Initialize(const media::AudioParameters
& params
,
26 CaptureCallback
* callback
,
27 int session_id
) override
;
28 void Start() override
;
30 void SetVolume(double volume
) override
;
31 void SetAutomaticGainControl(bool enable
) override
;
33 ~AudioCapturerSource() override
;
34 const scoped_refptr
<CastReceiverSession
> cast_receiver_session_
;
35 scoped_refptr
<CastReceiverAudioValve
> audio_valve_
;
38 // This is a render thread object.
39 class CastReceiverSession::VideoCapturerSource
40 : public media::VideoCapturerSource
{
42 explicit VideoCapturerSource(
43 const scoped_refptr
<CastReceiverSession
> cast_receiver_session
);
45 void GetCurrentSupportedFormats(
46 int max_requested_width
,
47 int max_requested_height
,
48 double max_requested_frame_rate
,
49 const VideoCaptureDeviceFormatsCB
& callback
) override
;
50 void StartCapture(const media::VideoCaptureParams
& params
,
51 const VideoCaptureDeliverFrameCB
& frame_callback
,
52 const RunningCallback
& running_callback
) override
;
53 void StopCapture() override
;
55 const scoped_refptr
<CastReceiverSession
> cast_receiver_session_
;
58 CastReceiverSession::CastReceiverSession()
59 : delegate_(new CastReceiverSessionDelegate()),
61 content::RenderThread::Get()->GetIOMessageLoopProxy()) {}
63 CastReceiverSession::~CastReceiverSession() {
64 // We should always be able to delete the object on the IO thread.
65 CHECK(io_task_runner_
->DeleteSoon(FROM_HERE
, delegate_
.release()));
68 void CastReceiverSession::Start(
69 const media::cast::FrameReceiverConfig
& audio_config
,
70 const media::cast::FrameReceiverConfig
& video_config
,
71 const net::IPEndPoint
& local_endpoint
,
72 const net::IPEndPoint
& remote_endpoint
,
73 scoped_ptr
<base::DictionaryValue
> options
,
74 const media::VideoCaptureFormat
& capture_format
,
75 const StartCB
& start_callback
,
76 const CastReceiverSessionDelegate::ErrorCallback
& error_callback
) {
77 audio_config_
= audio_config
;
78 video_config_
= video_config
;
79 format_
= capture_format
;
80 io_task_runner_
->PostTask(
82 base::Bind(&CastReceiverSessionDelegate::Start
,
83 base::Unretained(delegate_
.get()),
88 base::Passed(&options
),
90 media::BindToCurrentLoop(error_callback
)));
91 scoped_refptr
<media::AudioCapturerSource
> audio(
92 new CastReceiverSession::AudioCapturerSource(this));
93 scoped_ptr
<media::VideoCapturerSource
> video(
94 new CastReceiverSession::VideoCapturerSource(this));
95 base::ThreadTaskRunnerHandle::Get()->PostTask(
96 FROM_HERE
, base::Bind(start_callback
, audio
, base::Passed(&video
)));
99 void CastReceiverSession::StartAudio(
100 scoped_refptr
<CastReceiverAudioValve
> audio_valve
) {
101 io_task_runner_
->PostTask(
103 base::Bind(&CastReceiverSessionDelegate::StartAudio
,
104 base::Unretained(delegate_
.get()),
108 void CastReceiverSession::StartVideo(
109 content::VideoCaptureDeliverFrameCB frame_callback
) {
110 io_task_runner_
->PostTask(
112 base::Bind(&CastReceiverSessionDelegate::StartVideo
,
113 base::Unretained(delegate_
.get()),
117 void CastReceiverSession::StopVideo() {
118 io_task_runner_
->PostTask(
120 base::Bind(&CastReceiverSessionDelegate::StopVideo
,
121 base::Unretained(delegate_
.get())));
124 CastReceiverSession::VideoCapturerSource::VideoCapturerSource(
125 const scoped_refptr
<CastReceiverSession
> cast_receiver_session
)
126 : cast_receiver_session_(cast_receiver_session
) {
129 void CastReceiverSession::VideoCapturerSource::GetCurrentSupportedFormats(
130 int max_requested_width
,
131 int max_requested_height
,
132 double max_requested_frame_rate
,
133 const VideoCaptureDeviceFormatsCB
& callback
) {
134 std::vector
<media::VideoCaptureFormat
> formats
;
135 if (cast_receiver_session_
->format_
.IsValid())
136 formats
.push_back(cast_receiver_session_
->format_
);
137 callback
.Run(formats
);
140 void CastReceiverSession::VideoCapturerSource::StartCapture(
141 const media::VideoCaptureParams
& params
,
142 const VideoCaptureDeliverFrameCB
& frame_callback
,
143 const RunningCallback
& running_callback
) {
144 cast_receiver_session_
->StartVideo(frame_callback
);
145 running_callback
.Run(true);
148 void CastReceiverSession::VideoCapturerSource::StopCapture() {
149 cast_receiver_session_
->StopVideo();
152 CastReceiverSession::AudioCapturerSource::AudioCapturerSource(
153 const scoped_refptr
<CastReceiverSession
> cast_receiver_session
)
154 : cast_receiver_session_(cast_receiver_session
) {
157 CastReceiverSession::AudioCapturerSource::~AudioCapturerSource() {
158 DCHECK(!audio_valve_
);
161 void CastReceiverSession::AudioCapturerSource::Initialize(
162 const media::AudioParameters
& params
,
163 CaptureCallback
* callback
,
165 // TODO(hubbe): Consider converting the audio to whatever the caller wants.
166 if (params
.sample_rate() !=
167 cast_receiver_session_
->audio_config_
.rtp_timebase
||
168 params
.channels() != cast_receiver_session_
->audio_config_
.channels
) {
169 callback
->OnCaptureError(std::string());
172 audio_valve_
= new CastReceiverAudioValve(callback
);
175 void CastReceiverSession::AudioCapturerSource::Start() {
176 DCHECK(audio_valve_
);
177 cast_receiver_session_
->StartAudio(audio_valve_
);
180 void CastReceiverSession::AudioCapturerSource::Stop() {
181 audio_valve_
->Stop();
182 audio_valve_
= nullptr;
185 void CastReceiverSession::AudioCapturerSource::SetVolume(double volume
) {
189 void CastReceiverSession::AudioCapturerSource::SetAutomaticGainControl(