OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/media/media_stream_video_capturer_source.h" | 5 #include "content/renderer/media/media_stream_video_capturer_source.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "content/renderer/media/video_capture_impl_manager.h" | 10 #include "content/renderer/media/video_capture_impl_manager.h" |
11 #include "content/renderer/render_thread_impl.h" | 11 #include "content/renderer/render_thread_impl.h" |
12 #include "media/base/bind_to_current_loop.h" | 12 #include "media/base/bind_to_current_loop.h" |
13 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 struct SourceVideoResolution { | 17 // Resolutions used if the source doesn't support capability enumeration. |
18 const struct { | |
18 int width; | 19 int width; |
19 int height; | 20 int height; |
20 }; | 21 } kVideoResolutions[] = {{1920, 1080}, |
22 {1280, 720}, | |
23 {960, 720}, | |
24 {640, 480}, | |
25 {640, 360}, | |
26 {320, 240}, | |
27 {320, 180}}; | |
emircan
2015/03/10 01:40:06
I would prefer the earlier implementation as the s
mcasas
2015/03/13 01:09:33
Totally agree, but until such circumstance arises,
| |
21 | 28 |
22 // Resolutions used if the source doesn't support capability enumeration. | |
23 const SourceVideoResolution kVideoResolutions[] = {{1920, 1080}, | |
24 {1280, 720}, | |
25 {960, 720}, | |
26 {640, 480}, | |
27 {640, 360}, | |
28 {320, 240}, | |
29 {320, 180}}; | |
30 // Frame rates for sources with no support for capability enumeration. | 29 // Frame rates for sources with no support for capability enumeration. |
31 const int kVideoFrameRates[] = {30, 60}; | 30 const int kVideoFrameRates[] = {30, 60}; |
32 | 31 |
33 // Hard upper-bound frame rate for tab/desktop capture. | 32 // Hard upper-bound frame rate for tab/desktop capture. |
34 const double kMaxScreenCastFrameRate = 120.0; | 33 const double kMaxScreenCastFrameRate = 120.0; |
35 | 34 |
36 } // namespace | 35 } // namespace |
37 | 36 |
38 namespace content { | 37 namespace content { |
39 | 38 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 gfx::Size(width, height), | 80 gfx::Size(width, height), |
82 static_cast<float>(std::min(kMaxScreenCastFrameRate, | 81 static_cast<float>(std::min(kMaxScreenCastFrameRate, |
83 max_requested_frame_rate)), | 82 max_requested_frame_rate)), |
84 media::PIXEL_FORMAT_I420))); | 83 media::PIXEL_FORMAT_I420))); |
85 return; | 84 return; |
86 } | 85 } |
87 | 86 |
88 // NULL in unit test. | 87 // NULL in unit test. |
89 if (!RenderThreadImpl::current()) | 88 if (!RenderThreadImpl::current()) |
90 return; | 89 return; |
91 VideoCaptureImplManager* manager = | 90 VideoCaptureImplManager* const manager = |
92 RenderThreadImpl::current()->video_capture_impl_manager(); | 91 RenderThreadImpl::current()->video_capture_impl_manager(); |
93 if (!manager) | 92 if (!manager) |
94 return; | 93 return; |
95 DCHECK(source_formats_callback_.is_null()); | 94 DCHECK(source_formats_callback_.is_null()); |
96 source_formats_callback_ = callback; | 95 source_formats_callback_ = callback; |
97 manager->GetDeviceFormatsInUse( | 96 manager->GetDeviceFormatsInUse( |
98 session_id_, | 97 session_id_, |
99 media::BindToCurrentLoop( | 98 media::BindToCurrentLoop( |
100 base::Bind( | 99 base::Bind( |
101 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, | 100 &VideoCapturerDelegate::OnDeviceFormatsInUseReceived, |
102 weak_factory_.GetWeakPtr()))); | 101 weak_factory_.GetWeakPtr()))); |
103 } | 102 } |
104 | 103 |
105 void VideoCapturerDelegate::StartCapture( | 104 void VideoCapturerDelegate::StartCapture( |
106 const media::VideoCaptureParams& params, | 105 const media::VideoCaptureParams& params, |
107 const VideoCaptureDeliverFrameCB& new_frame_callback, | 106 const VideoCaptureDeliverFrameCB& new_frame_callback, |
108 scoped_refptr<base::SingleThreadTaskRunner> frame_callback_task_runner, | 107 scoped_refptr<base::SingleThreadTaskRunner> frame_callback_task_runner, |
109 const RunningCallback& running_callback) { | 108 const RunningCallback& running_callback) { |
110 DCHECK(params.requested_format.IsValid()); | 109 DCHECK(params.requested_format.IsValid()); |
111 DCHECK(thread_checker_.CalledOnValidThread()); | 110 DCHECK(thread_checker_.CalledOnValidThread()); |
112 running_callback_ = running_callback; | 111 running_callback_ = running_callback; |
113 | 112 |
114 // NULL in unit test. | 113 // NULL in unit test. |
115 if (!RenderThreadImpl::current()) | 114 if (!RenderThreadImpl::current()) |
116 return; | 115 return; |
117 VideoCaptureImplManager* manager = | 116 VideoCaptureImplManager* const manager = |
118 RenderThreadImpl::current()->video_capture_impl_manager(); | 117 RenderThreadImpl::current()->video_capture_impl_manager(); |
119 if (!manager) | 118 if (!manager) |
120 return; | 119 return; |
121 if (frame_callback_task_runner != | 120 if (frame_callback_task_runner != |
122 RenderThreadImpl::current()->GetIOMessageLoopProxy()) { | 121 RenderThreadImpl::current()->GetIOMessageLoopProxy()) { |
123 DCHECK(false) << "Only IO thread supported right now."; | 122 DCHECK(false) << "Only IO thread supported right now."; |
124 running_callback.Run(false); | 123 running_callback.Run(false); |
125 return; | 124 return; |
126 } | 125 } |
127 | 126 |
128 stop_capture_cb_ = | 127 stop_capture_cb_ = manager->StartCapture( |
129 manager->StartCapture( | 128 session_id_, |
130 session_id_, | 129 params, |
131 params, | 130 media::BindToCurrentLoop(base::Bind(&VideoCapturerDelegate::OnStateUpdate, |
132 media::BindToCurrentLoop(base::Bind( | 131 weak_factory_.GetWeakPtr())), |
133 &VideoCapturerDelegate::OnStateUpdateOnRenderThread, | 132 new_frame_callback); |
134 weak_factory_.GetWeakPtr())), | |
135 new_frame_callback); | |
136 } | 133 } |
137 | 134 |
138 void VideoCapturerDelegate::StopCapture() { | 135 void VideoCapturerDelegate::StopCapture() { |
139 // Immediately make sure we don't provide more frames. | 136 // Immediately make sure we don't provide more frames. |
140 DVLOG(3) << "VideoCapturerDelegate::StopCapture()"; | 137 DVLOG(3) << "VideoCapturerDelegate::StopCapture()"; |
141 DCHECK(thread_checker_.CalledOnValidThread()); | 138 DCHECK(thread_checker_.CalledOnValidThread()); |
142 if (!stop_capture_cb_.is_null()) { | 139 if (!stop_capture_cb_.is_null()) { |
143 base::ResetAndReturn(&stop_capture_cb_).Run(); | 140 base::ResetAndReturn(&stop_capture_cb_).Run(); |
144 } | 141 } |
145 running_callback_.Reset(); | 142 running_callback_.Reset(); |
146 source_formats_callback_.Reset(); | 143 source_formats_callback_.Reset(); |
147 } | 144 } |
148 | 145 |
149 void VideoCapturerDelegate::OnStateUpdateOnRenderThread( | 146 void VideoCapturerDelegate::OnStateUpdate( |
150 VideoCaptureState state) { | 147 VideoCaptureState state) { |
151 DCHECK(thread_checker_.CalledOnValidThread()); | 148 DCHECK(thread_checker_.CalledOnValidThread()); |
152 DVLOG(3) << "OnStateUpdateOnRenderThread state = " << state; | 149 DVLOG(3) << "OnStateUpdate state = " << state; |
153 if (state == VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { | 150 if (state == VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { |
154 running_callback_.Run(true); | 151 running_callback_.Run(true); |
155 return; | 152 return; |
156 } | 153 } |
157 if (state > VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { | 154 if (state > VIDEO_CAPTURE_STATE_STARTED && !running_callback_.is_null()) { |
158 base::ResetAndReturn(&running_callback_).Run(false); | 155 base::ResetAndReturn(&running_callback_).Run(false); |
159 } | 156 } |
160 } | 157 } |
161 | 158 |
162 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( | 159 void VideoCapturerDelegate::OnDeviceFormatsInUseReceived( |
163 const media::VideoCaptureFormats& formats_in_use) { | 160 const media::VideoCaptureFormats& formats_in_use) { |
164 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); | 161 DVLOG(3) << "OnDeviceFormatsInUseReceived: " << formats_in_use.size(); |
165 DCHECK(thread_checker_.CalledOnValidThread()); | 162 DCHECK(thread_checker_.CalledOnValidThread()); |
166 // StopCapture() might have destroyed |source_formats_callback_| before | 163 // StopCapture() might have destroyed |source_formats_callback_| before |
167 // arriving here. | 164 // arriving here. |
168 if (source_formats_callback_.is_null()) | 165 if (source_formats_callback_.is_null()) |
169 return; | 166 return; |
170 // If there are no formats in use, try to retrieve the whole list of | 167 // If there are no formats in use, try to retrieve the whole list of |
171 // supported form. | 168 // supported form. |
172 if (!formats_in_use.empty()) { | 169 if (!formats_in_use.empty()) { |
173 source_formats_callback_.Run(formats_in_use); | 170 source_formats_callback_.Run(formats_in_use); |
174 source_formats_callback_.Reset(); | 171 source_formats_callback_.Reset(); |
175 return; | 172 return; |
176 } | 173 } |
177 | 174 |
178 // NULL in unit test. | 175 // NULL in unit test. |
179 if (!RenderThreadImpl::current()) | 176 if (!RenderThreadImpl::current()) |
180 return; | 177 return; |
181 VideoCaptureImplManager* manager = | 178 VideoCaptureImplManager* const manager = |
182 RenderThreadImpl::current()->video_capture_impl_manager(); | 179 RenderThreadImpl::current()->video_capture_impl_manager(); |
183 if (!manager) | 180 if (!manager) |
184 return; | 181 return; |
185 | 182 |
186 manager->GetDeviceSupportedFormats( | 183 manager->GetDeviceSupportedFormats( |
187 session_id_, | 184 session_id_, |
188 media::BindToCurrentLoop( | 185 media::BindToCurrentLoop( |
189 base::Bind( | 186 base::Bind( |
190 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, | 187 &VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated, |
191 weak_factory_.GetWeakPtr()))); | 188 weak_factory_.GetWeakPtr()))); |
192 } | 189 } |
193 | 190 |
194 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( | 191 void VideoCapturerDelegate::OnDeviceSupportedFormatsEnumerated( |
195 const media::VideoCaptureFormats& formats) { | 192 const media::VideoCaptureFormats& formats) { |
196 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() | 193 DVLOG(3) << "OnDeviceSupportedFormatsEnumerated: " << formats.size() |
197 << " received"; | 194 << " received"; |
198 DCHECK(thread_checker_.CalledOnValidThread()); | 195 DCHECK(thread_checker_.CalledOnValidThread()); |
199 // StopCapture() might have destroyed |source_formats_callback_| before | 196 // StopCapture() might have destroyed |source_formats_callback_| before |
200 // arriving here. | 197 // arriving here. |
201 if (source_formats_callback_.is_null()) | 198 if (source_formats_callback_.is_null()) |
202 return; | 199 return; |
203 if (formats.size()) { | 200 if (formats.size()) { |
204 base::ResetAndReturn(&source_formats_callback_).Run(formats); | 201 base::ResetAndReturn(&source_formats_callback_).Run(formats); |
205 } else { | 202 } else { |
206 // The capture device doesn't seem to support capability enumeration, | 203 // The capture device doesn't seem to support capability enumeration, |
207 // compose a fallback list of capabilities. | 204 // compose a fallback list of capabilities. |
208 media::VideoCaptureFormats default_formats; | 205 media::VideoCaptureFormats default_formats; |
209 for (size_t i = 0; i < arraysize(kVideoResolutions); ++i) { | 206 for (const auto& resolution : kVideoResolutions) { |
210 for (size_t j = 0; j < arraysize(kVideoFrameRates); ++j) { | 207 for (const auto& frame_rate : kVideoFrameRates) { |
emircan
2015/03/10 01:40:06
frame_rate is an int so copying by value would be
mcasas
2015/03/13 01:09:33
Done.
| |
211 default_formats.push_back(media::VideoCaptureFormat( | 208 default_formats.push_back(media::VideoCaptureFormat( |
212 gfx::Size(kVideoResolutions[i].width, kVideoResolutions[i].height), | 209 gfx::Size(resolution.width, resolution.height), frame_rate, |
213 kVideoFrameRates[j], media::PIXEL_FORMAT_I420)); | 210 media::PIXEL_FORMAT_I420)); |
214 } | 211 } |
215 } | 212 } |
216 base::ResetAndReturn(&source_formats_callback_).Run(default_formats); | 213 base::ResetAndReturn(&source_formats_callback_).Run(default_formats); |
217 } | 214 } |
218 } | 215 } |
219 | 216 |
220 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( | 217 MediaStreamVideoCapturerSource::MediaStreamVideoCapturerSource( |
221 const SourceStoppedCallback& stop_callback, | 218 const SourceStoppedCallback& stop_callback, |
222 scoped_ptr<media::VideoCapturerSource> delegate) | 219 scoped_ptr<media::VideoCapturerSource> delegate) |
223 : delegate_(delegate.Pass()) { | 220 : delegate_(delegate.Pass()) { |
224 SetStopCallback(stop_callback); | 221 SetStopCallback(stop_callback); |
225 } | 222 } |
226 | 223 |
224 MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() { | |
225 } | |
226 | |
227 void MediaStreamVideoCapturerSource::SetDeviceInfo( | 227 void MediaStreamVideoCapturerSource::SetDeviceInfo( |
228 const StreamDeviceInfo& device_info) { | 228 const StreamDeviceInfo& device_info) { |
229 MediaStreamVideoSource::SetDeviceInfo(device_info); | 229 MediaStreamVideoSource::SetDeviceInfo(device_info); |
230 } | 230 } |
231 | 231 |
232 MediaStreamVideoCapturerSource::~MediaStreamVideoCapturerSource() { | |
233 } | |
234 | |
235 void MediaStreamVideoCapturerSource::GetCurrentSupportedFormats( | 232 void MediaStreamVideoCapturerSource::GetCurrentSupportedFormats( |
236 int max_requested_width, | 233 int max_requested_width, |
237 int max_requested_height, | 234 int max_requested_height, |
238 double max_requested_frame_rate, | 235 double max_requested_frame_rate, |
239 const VideoCaptureDeviceFormatsCB& callback) { | 236 const VideoCaptureDeviceFormatsCB& callback) { |
240 delegate_->GetCurrentSupportedFormats( | 237 delegate_->GetCurrentSupportedFormats( |
241 max_requested_width, | 238 max_requested_width, |
242 max_requested_height, | 239 max_requested_height, |
243 max_requested_frame_rate, | 240 max_requested_frame_rate, |
244 callback); | 241 callback); |
(...skipping 12 matching lines...) Expand all Loading... | |
257 delegate_->StartCapture( | 254 delegate_->StartCapture( |
258 new_params, | 255 new_params, |
259 frame_callback, | 256 frame_callback, |
260 RenderThreadImpl::current() ? | 257 RenderThreadImpl::current() ? |
261 RenderThreadImpl::current()->GetIOMessageLoopProxy() : | 258 RenderThreadImpl::current()->GetIOMessageLoopProxy() : |
262 nullptr, | 259 nullptr, |
263 base::Bind(&MediaStreamVideoCapturerSource::OnStarted, | 260 base::Bind(&MediaStreamVideoCapturerSource::OnStarted, |
264 base::Unretained(this))); | 261 base::Unretained(this))); |
265 } | 262 } |
266 | 263 |
264 void MediaStreamVideoCapturerSource::StopSourceImpl() { | |
265 delegate_->StopCapture(); | |
266 } | |
267 | |
267 void MediaStreamVideoCapturerSource::OnStarted(bool result) { | 268 void MediaStreamVideoCapturerSource::OnStarted(bool result) { |
268 OnStartDone(result ? MEDIA_DEVICE_OK : MEDIA_DEVICE_TRACK_START_FAILURE); | 269 OnStartDone(result ? MEDIA_DEVICE_OK : MEDIA_DEVICE_TRACK_START_FAILURE); |
269 } | 270 } |
270 | 271 |
271 void MediaStreamVideoCapturerSource::StopSourceImpl() { | |
272 delegate_->StopCapture(); | |
273 } | |
274 | |
275 } // namespace content | 272 } // namespace content |
OLD | NEW |