Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: content/browser/renderer_host/media/video_capture_manager.cc

Issue 2738763002: [Mojo Video Capture] Introduce abstraction BuildableVideoCaptureDevice (Closed)
Patch Set: Rebase to March 30 Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/renderer_host/media/video_capture_manager.h" 5 #include "content/browser/renderer_host/media/video_capture_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/location.h" 14 #include "base/location.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 17 #include "base/metrics/histogram_macros.h"
18 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
21 #include "base/task_runner_util.h" 21 #include "base/task_runner_util.h"
22 #include "base/threading/sequenced_worker_pool.h" 22 #include "base/threading/sequenced_worker_pool.h"
23 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
24 #include "build/build_config.h" 24 #include "build/build_config.h"
25 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" 25 #include "content/browser/media/capture/desktop_capture_device_uma_types.h"
26 #include "content/browser/media/capture/web_contents_video_capture_device.h" 26 #include "content/browser/media/capture/web_contents_video_capture_device.h"
27 #include "content/browser/media/media_internals.h" 27 #include "content/browser/media/media_internals.h"
28 #include "content/browser/renderer_host/media/in_process_buildable_video_capture _device.h"
28 #include "content/browser/renderer_host/media/video_capture_controller.h" 29 #include "content/browser/renderer_host/media/video_capture_controller.h"
29 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" 30 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h"
30 #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
31 #include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread. h"
32 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/desktop_media_id.h" 32 #include "content/public/browser/desktop_media_id.h"
34 #include "content/public/common/media_stream_request.h" 33 #include "content/public/common/media_stream_request.h"
35 #include "media/base/bind_to_current_loop.h" 34 #include "media/base/bind_to_current_loop.h"
36 #include "media/base/media_switches.h" 35 #include "media/base/media_switches.h"
37 #include "media/base/video_facing.h" 36 #include "media/base/video_facing.h"
38 #include "media/capture/video/video_capture_buffer_pool_impl.h" 37 #include "media/capture/video/video_capture_buffer_pool_impl.h"
39 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" 38 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
40 #include "media/capture/video/video_capture_device.h" 39 #include "media/capture/video/video_capture_device.h"
41 #include "media/capture/video/video_capture_device_client.h" 40 #include "media/capture/video/video_capture_device_client.h"
(...skipping 10 matching lines...) Expand all
52 #endif 51 #endif
53 52
54 #if defined(OS_ANDROID) 53 #if defined(OS_ANDROID)
55 #include "content/browser/media/capture/screen_capture_device_android.h" 54 #include "content/browser/media/capture/screen_capture_device_android.h"
56 #endif 55 #endif
57 56
58 #endif // defined(ENABLE_SCREEN_CAPTURE) 57 #endif // defined(ENABLE_SCREEN_CAPTURE)
59 58
60 namespace { 59 namespace {
61 60
62 class VideoFrameConsumerFeedbackObserverOnTaskRunner
63 : public media::VideoFrameConsumerFeedbackObserver {
64 public:
65 VideoFrameConsumerFeedbackObserverOnTaskRunner(
66 media::VideoFrameConsumerFeedbackObserver* observer,
67 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
68 : observer_(observer), task_runner_(std::move(task_runner)) {}
69
70 void OnUtilizationReport(int frame_feedback_id, double utilization) override {
71 task_runner_->PostTask(
72 FROM_HERE,
73 base::Bind(
74 &media::VideoFrameConsumerFeedbackObserver::OnUtilizationReport,
75 base::Unretained(observer_), frame_feedback_id, utilization));
76 }
77
78 private:
79 media::VideoFrameConsumerFeedbackObserver* const observer_;
80 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
81 };
82
83 // Compares two VideoCaptureFormat by checking smallest frame_size area, then 61 // Compares two VideoCaptureFormat by checking smallest frame_size area, then
84 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that 62 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that
85 // the first entry for a given resolution has the largest frame rate, as needed 63 // the first entry for a given resolution has the largest frame rate, as needed
86 // by the ConsolidateCaptureFormats() method. 64 // by the ConsolidateCaptureFormats() method.
87 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, 65 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1,
88 const media::VideoCaptureFormat& format2) { 66 const media::VideoCaptureFormat& format2) {
89 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); 67 DCHECK(format1.frame_size.GetCheckedArea().IsValid());
90 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); 68 DCHECK(format2.frame_size.GetCheckedArea().IsValid());
91 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == 69 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) ==
92 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { 70 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) {
(...skipping 25 matching lines...) Expand all
118 formats->erase(last, formats->end()); 96 formats->erase(last, formats->end());
119 // Mark all formats as I420, since this is what the renderer side will get 97 // Mark all formats as I420, since this is what the renderer side will get
120 // anyhow: the actual pixel format is decided at the device level. 98 // anyhow: the actual pixel format is decided at the device level.
121 // Don't do this for Y16 format as it is handled separatelly. 99 // Don't do this for Y16 format as it is handled separatelly.
122 for (auto& format : *formats) { 100 for (auto& format : *formats) {
123 if (format.pixel_format != media::PIXEL_FORMAT_Y16) 101 if (format.pixel_format != media::PIXEL_FORMAT_Y16)
124 format.pixel_format = media::PIXEL_FORMAT_I420; 102 format.pixel_format = media::PIXEL_FORMAT_I420;
125 } 103 }
126 } 104 }
127 105
128 // The maximum number of video frame buffers in-flight at any one time. This
129 // value should be based on the logical capacity of the capture pipeline, and
130 // not on hardware performance. For example, tab capture requires more buffers
131 // than webcam capture because the pipeline is longer (it includes read-backs
132 // pending in the GPU pipeline).
133 const int kMaxNumberOfBuffers = 3;
134 // TODO(miu): The value for tab capture should be determined programmatically.
135 // http://crbug.com/460318
136 const int kMaxNumberOfBuffersForTabCapture = 10;
137
138 // Used for logging capture events. 106 // Used for logging capture events.
139 // Elements in this enum should not be deleted or rearranged; the only 107 // Elements in this enum should not be deleted or rearranged; the only
140 // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT. 108 // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT.
141 enum VideoCaptureEvent { 109 enum VideoCaptureEvent {
142 VIDEO_CAPTURE_START_CAPTURE = 0, 110 VIDEO_CAPTURE_START_CAPTURE = 0,
143 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1, 111 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1,
144 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2, 112 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2,
145 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE = 3, 113 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE = 3,
146 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB = 4, 114 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB = 4,
147 NUM_VIDEO_CAPTURE_EVENT 115 NUM_VIDEO_CAPTURE_EVENT
148 }; 116 };
149 117
150 void LogVideoCaptureEvent(VideoCaptureEvent event) { 118 void LogVideoCaptureEvent(VideoCaptureEvent event) {
151 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", 119 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", event,
152 event,
153 NUM_VIDEO_CAPTURE_EVENT); 120 NUM_VIDEO_CAPTURE_EVENT);
154 } 121 }
155 122
156 // Counter used for identifying a DeviceRequest to start a capture device.
157 static int g_device_start_id = 0;
158
159 const media::VideoCaptureSessionId kFakeSessionId = -1; 123 const media::VideoCaptureSessionId kFakeSessionId = -1;
160 124
161 std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
162 const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) {
163 return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb);
164 }
165
166 } // namespace 125 } // namespace
167 126
168 namespace content { 127 namespace content {
169 128
170 // Instances of this struct go through several different phases during their
171 // lifetime.
172 // Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of
173 // only the |video_capture_controller|. Clients can already connect to the
174 // controller, but there is no |video_capture_device| present.
175 // Phase 2: When a request to "start" the entry comes in (via
176 // HandleQueuedStartRequest()), creation of |video_capture_device| is scheduled
177 // to run asynchronously on the Device Thread.
178 // Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this
179 // newly created VideoCaptureDevice instance is connected to the
180 // VideoCaptureController via SetConsumerFeedbackObserver().
181 // Phase 4: This phase can only be reached on Android. When the application goes
182 // to the background, the |video_capture_device| is asynchronously stopped and
183 // released on the Device Thread. When the application is resumed, we
184 // transition to Phase 2.
185 struct VideoCaptureManager::DeviceEntry {
186 public:
187 DeviceEntry(MediaStreamType stream_type,
188 const std::string& id,
189 const media::VideoCaptureParams& params);
190 ~DeviceEntry();
191 std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient();
192
193 const int serial_id;
194 const MediaStreamType stream_type;
195 const std::string id;
196 const media::VideoCaptureParams parameters;
197 VideoCaptureController video_capture_controller;
198 std::unique_ptr<media::VideoCaptureDevice> video_capture_device;
199 };
200
201 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported 129 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported
202 // video formats. 130 // video formats.
203 struct VideoCaptureManager::DeviceInfo { 131 struct VideoCaptureManager::DeviceInfo {
204 DeviceInfo(); 132 DeviceInfo();
205 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); 133 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor);
206 DeviceInfo(const DeviceInfo& other); 134 DeviceInfo(const DeviceInfo& other);
207 ~DeviceInfo(); 135 ~DeviceInfo();
208 DeviceInfo& operator=(const DeviceInfo& other); 136 DeviceInfo& operator=(const DeviceInfo& other);
209 137
210 media::VideoCaptureDeviceDescriptor descriptor; 138 media::VideoCaptureDeviceDescriptor descriptor;
(...skipping 17 matching lines...) Expand all
228 156
229 private: 157 private:
230 const int serial_id_; 158 const int serial_id_;
231 const media::VideoCaptureSessionId session_id_; 159 const media::VideoCaptureSessionId session_id_;
232 const media::VideoCaptureParams params_; 160 const media::VideoCaptureParams params_;
233 // Set to true if the device should be stopped before it has successfully 161 // Set to true if the device should be stopped before it has successfully
234 // been started. 162 // been started.
235 bool abort_start_; 163 bool abort_start_;
236 }; 164 };
237 165
238 VideoCaptureManager::DeviceEntry::DeviceEntry(
239 MediaStreamType stream_type,
240 const std::string& id,
241 const media::VideoCaptureParams& params)
242 : serial_id(g_device_start_id++),
243 stream_type(stream_type),
244 id(id),
245 parameters(params) {}
246
247 VideoCaptureManager::DeviceEntry::~DeviceEntry() {
248 DCHECK_CURRENTLY_ON(BrowserThread::IO);
249 // DCHECK that this DeviceEntry does not still own a
250 // media::VideoCaptureDevice. media::VideoCaptureDevice must be deleted on
251 // the device thread.
252 DCHECK(video_capture_device == nullptr);
253 }
254
255 std::unique_ptr<media::VideoCaptureDevice::Client>
256 VideoCaptureManager::DeviceEntry::CreateDeviceClient() {
257 DCHECK_CURRENTLY_ON(BrowserThread::IO);
258
259 const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE
260 ? kMaxNumberOfBuffersForTabCapture
261 : kMaxNumberOfBuffers;
262 scoped_refptr<media::VideoCaptureBufferPool> buffer_pool =
263 new media::VideoCaptureBufferPoolImpl(
264 base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
265 max_buffers);
266
267 return base::MakeUnique<media::VideoCaptureDeviceClient>(
268 base::MakeUnique<VideoFrameReceiverOnIOThread>(
269 video_capture_controller.GetWeakPtrForIOThread()),
270 std::move(buffer_pool),
271 base::Bind(&CreateGpuJpegDecoder,
272 base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer,
273 video_capture_controller.GetWeakPtrForIOThread())));
274 }
275
276 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; 166 VideoCaptureManager::DeviceInfo::DeviceInfo() = default;
277 167
278 VideoCaptureManager::DeviceInfo::DeviceInfo( 168 VideoCaptureManager::DeviceInfo::DeviceInfo(
279 media::VideoCaptureDeviceDescriptor descriptor) 169 media::VideoCaptureDeviceDescriptor descriptor)
280 : descriptor(descriptor) {} 170 : descriptor(descriptor) {}
281 171
282 VideoCaptureManager::DeviceInfo::DeviceInfo( 172 VideoCaptureManager::DeviceInfo::DeviceInfo(
283 const VideoCaptureManager::DeviceInfo& other) = default; 173 const VideoCaptureManager::DeviceInfo& other) = default;
284 174
285 VideoCaptureManager::DeviceInfo::~DeviceInfo() = default; 175 VideoCaptureManager::DeviceInfo::~DeviceInfo() = default;
286 176
287 VideoCaptureManager::DeviceInfo& VideoCaptureManager::DeviceInfo::operator=( 177 VideoCaptureManager::DeviceInfo& VideoCaptureManager::DeviceInfo::operator=(
288 const VideoCaptureManager::DeviceInfo& other) = default; 178 const VideoCaptureManager::DeviceInfo& other) = default;
289 179
290 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( 180 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest(
291 int serial_id, 181 int serial_id,
292 media::VideoCaptureSessionId session_id, 182 media::VideoCaptureSessionId session_id,
293 const media::VideoCaptureParams& params) 183 const media::VideoCaptureParams& params)
294 : serial_id_(serial_id), 184 : serial_id_(serial_id),
295 session_id_(session_id), 185 session_id_(session_id),
296 params_(params), 186 params_(params),
297 abort_start_(false) { 187 abort_start_(false) {}
298 }
299 188
300 VideoCaptureManager::VideoCaptureManager( 189 VideoCaptureManager::VideoCaptureManager(
301 std::unique_ptr<media::VideoCaptureDeviceFactory> factory, 190 std::unique_ptr<media::VideoCaptureDeviceFactory> factory,
302 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) 191 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner)
303 : device_task_runner_(std::move(device_task_runner)), 192 : device_task_runner_(std::move(device_task_runner)),
304 new_capture_session_id_(1), 193 new_capture_session_id_(1),
305 video_capture_device_factory_(std::move(factory)) {} 194 video_capture_device_factory_(std::move(factory)) {}
306 195
307 VideoCaptureManager::~VideoCaptureManager() { 196 VideoCaptureManager::~VideoCaptureManager() {
308 DCHECK(devices_.empty()); 197 DCHECK(controllers_.empty());
309 DCHECK(device_start_queue_.empty()); 198 DCHECK(device_start_queue_.empty());
310 } 199 }
311 200
312 void VideoCaptureManager::AddVideoCaptureObserver( 201 void VideoCaptureManager::AddVideoCaptureObserver(
313 media::VideoCaptureObserver* observer) { 202 media::VideoCaptureObserver* observer) {
314 DCHECK(observer); 203 DCHECK(observer);
315 DCHECK_CURRENTLY_ON(BrowserThread::IO); 204 DCHECK_CURRENTLY_ON(BrowserThread::IO);
316 capture_observers_.AddObserver(observer); 205 capture_observers_.AddObserver(observer);
317 } 206 }
318 207
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 devices_info_cache_); 247 devices_info_cache_);
359 // OK to use base::Unretained() since we own the VCDFactory and |this| is 248 // OK to use base::Unretained() since we own the VCDFactory and |this| is
360 // bound in |devices_enumerated_callback|. 249 // bound in |devices_enumerated_callback|.
361 device_task_runner_->PostTask( 250 device_task_runner_->PostTask(
362 FROM_HERE, 251 FROM_HERE,
363 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors, 252 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors,
364 base::Unretained(video_capture_device_factory_.get()), 253 base::Unretained(video_capture_device_factory_.get()),
365 devices_enumerated_callback)); 254 devices_enumerated_callback));
366 } 255 }
367 256
257 const media::VideoCaptureDeviceDescriptor*
258 VideoCaptureManager::LookupDeviceDescriptor(const std::string& id) {
259 const DeviceInfo* info = GetDeviceInfoById(id);
260 return info ? (&info->descriptor) : nullptr;
261 }
262
368 int VideoCaptureManager::Open(const MediaStreamDevice& device) { 263 int VideoCaptureManager::Open(const MediaStreamDevice& device) {
369 DCHECK_CURRENTLY_ON(BrowserThread::IO); 264 DCHECK_CURRENTLY_ON(BrowserThread::IO);
370 265
371 // Generate a new id for the session being opened. 266 // Generate a new id for the session being opened.
372 const media::VideoCaptureSessionId capture_session_id = 267 const media::VideoCaptureSessionId capture_session_id =
373 new_capture_session_id_++; 268 new_capture_session_id_++;
374 269
375 DCHECK(sessions_.find(capture_session_id) == sessions_.end()); 270 DCHECK(sessions_.find(capture_session_id) == sessions_.end());
376 DVLOG(1) << "VideoCaptureManager::Open, id " << capture_session_id; 271 DVLOG(1) << "VideoCaptureManager::Open, id " << capture_session_id;
377 272
(...skipping 12 matching lines...) Expand all
390 void VideoCaptureManager::Close(int capture_session_id) { 285 void VideoCaptureManager::Close(int capture_session_id) {
391 DCHECK_CURRENTLY_ON(BrowserThread::IO); 286 DCHECK_CURRENTLY_ON(BrowserThread::IO);
392 DVLOG(1) << "VideoCaptureManager::Close, id " << capture_session_id; 287 DVLOG(1) << "VideoCaptureManager::Close, id " << capture_session_id;
393 288
394 SessionMap::iterator session_it = sessions_.find(capture_session_id); 289 SessionMap::iterator session_it = sessions_.find(capture_session_id);
395 if (session_it == sessions_.end()) { 290 if (session_it == sessions_.end()) {
396 NOTREACHED(); 291 NOTREACHED();
397 return; 292 return;
398 } 293 }
399 294
400 DeviceEntry* const existing_device = 295 VideoCaptureController* const existing_device = LookupControllerByTypeAndId(
401 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); 296 session_it->second.type, session_it->second.id);
402 if (existing_device) { 297 if (existing_device) {
403 // Remove any client that is still using the session. This is safe to call 298 // Remove any client that is still using the session. This is safe to call
404 // even if there are no clients using the session. 299 // even if there are no clients using the session.
405 existing_device->video_capture_controller.StopSession(capture_session_id); 300 existing_device->StopSession(capture_session_id);
406 301
407 // StopSession() may have removed the last client, so we might need to 302 // StopSession() may have removed the last client, so we might need to
408 // close the device. 303 // close the device.
409 DestroyDeviceEntryIfNoClients(existing_device); 304 DestroyControllerIfNoClients(existing_device);
410 } 305 }
411 306
412 // Notify listeners asynchronously, and forget the session. 307 // Notify listeners asynchronously, and forget the session.
413 base::ThreadTaskRunnerHandle::Get()->PostTask( 308 base::ThreadTaskRunnerHandle::Get()->PostTask(
414 FROM_HERE, base::Bind(&VideoCaptureManager::OnClosed, this, 309 FROM_HERE, base::Bind(&VideoCaptureManager::OnClosed, this,
415 session_it->second.type, capture_session_id)); 310 session_it->second.type, capture_session_id));
416 sessions_.erase(session_it); 311 sessions_.erase(session_it);
417 } 312 }
418 313
419 void VideoCaptureManager::QueueStartDevice( 314 void VideoCaptureManager::QueueStartDevice(
420 media::VideoCaptureSessionId session_id, 315 media::VideoCaptureSessionId session_id,
421 DeviceEntry* entry, 316 VideoCaptureController* controller,
422 const media::VideoCaptureParams& params) { 317 const media::VideoCaptureParams& params) {
423 DCHECK_CURRENTLY_ON(BrowserThread::IO); 318 DCHECK_CURRENTLY_ON(BrowserThread::IO);
424 device_start_queue_.push_back( 319 device_start_queue_.push_back(
425 CaptureDeviceStartRequest(entry->serial_id, session_id, params)); 320 CaptureDeviceStartRequest(controller->serial_id(), session_id, params));
426 if (device_start_queue_.size() == 1) 321 if (device_start_queue_.size() == 1)
427 HandleQueuedStartRequest(); 322 HandleQueuedStartRequest();
428 } 323 }
429 324
430 void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) { 325 void VideoCaptureManager::DoStopDevice(VideoCaptureController* controller) {
431 DCHECK_CURRENTLY_ON(BrowserThread::IO); 326 DCHECK_CURRENTLY_ON(BrowserThread::IO);
432 // TODO(mcasas): use a helper function https://crbug.com/624854. 327 // TODO(mcasas): use a helper function https://crbug.com/624854.
433 DCHECK( 328 DCHECK(std::find_if(
434 std::find_if(devices_.begin(), devices_.end(), 329 controllers_.begin(), controllers_.end(),
435 [entry](const std::unique_ptr<DeviceEntry>& device_entry) { 330 [controller](
436 return device_entry.get() == entry; 331 const scoped_refptr<VideoCaptureController>& device_entry) {
437 }) != devices_.end()); 332 return device_entry.get() == controller;
333 }) != controllers_.end());
438 334
439 // Find the matching start request. 335 // Find the matching start request.
440 for (DeviceStartQueue::reverse_iterator request = 336 for (DeviceStartQueue::reverse_iterator request =
441 device_start_queue_.rbegin(); 337 device_start_queue_.rbegin();
442 request != device_start_queue_.rend(); ++request) { 338 request != device_start_queue_.rend(); ++request) {
443 if (request->serial_id() == entry->serial_id) { 339 if (request->serial_id() == controller->serial_id()) {
444 request->set_abort_start(); 340 request->set_abort_start();
445 DVLOG(3) << "DoStopDevice, aborting start request for device " 341 DVLOG(3) << "DoStopDevice, aborting start request for device "
446 << entry->id << " serial_id = " << entry->serial_id; 342 << controller->device_id()
343 << " serial_id = " << controller->serial_id();
447 return; 344 return;
448 } 345 }
449 } 346 }
450 347
451 const DeviceInfo* device_info = GetDeviceInfoById(entry->id); 348 const DeviceInfo* device_info = GetDeviceInfoById(controller->device_id());
452 if (device_info != nullptr) { 349 if (device_info != nullptr) {
453 for (auto& observer : capture_observers_) 350 for (auto& observer : capture_observers_)
454 observer.OnVideoCaptureStopped(device_info->descriptor.facing); 351 observer.OnVideoCaptureStopped(device_info->descriptor.facing);
455 } 352 }
456 353
457 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id 354 DVLOG(3) << "DoStopDevice. Send stop request for device = "
458 << " serial_id = " << entry->serial_id << "."; 355 << controller->device_id()
459 entry->video_capture_controller.OnLog( 356 << " serial_id = " << controller->serial_id() << ".";
460 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); 357 controller->OnLog(base::StringPrintf("Stopping device: id: %s",
461 entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr); 358 controller->device_id().c_str()));
462 359
463 // |entry->video_capture_device| can be null if creating the device has 360 if (controller->IsDeviceAlive()) {
464 // failed. 361 // Since we may be removing |controller| from |controllers_| while
465 if (entry->video_capture_device) { 362 // ReleaseDeviceAsnyc() is executing, we pass it shared ownership to
466 device_task_runner_->PostTask( 363 // |controller|.
467 FROM_HERE, 364 controller->ReleaseDeviceAsync(base::Bind(
468 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, 365 [](scoped_refptr<VideoCaptureController>) {},
469 base::Passed(&entry->video_capture_device))); 366 GetControllerSharedRefFromSerialId(controller->serial_id())));
470 } 367 }
471 } 368 }
472 369
473 void VideoCaptureManager::HandleQueuedStartRequest() { 370 void VideoCaptureManager::HandleQueuedStartRequest() {
474 DCHECK_CURRENTLY_ON(BrowserThread::IO); 371 DCHECK_CURRENTLY_ON(BrowserThread::IO);
475 // Remove all start requests that have been aborted. 372 // Remove all start requests that have been aborted.
476 while (device_start_queue_.begin() != device_start_queue_.end() && 373 while (device_start_queue_.begin() != device_start_queue_.end() &&
477 device_start_queue_.begin()->abort_start()) { 374 device_start_queue_.begin()->abort_start()) {
478 device_start_queue_.pop_front(); 375 device_start_queue_.pop_front();
479 } 376 }
480 DeviceStartQueue::iterator request = device_start_queue_.begin(); 377 DeviceStartQueue::iterator request = device_start_queue_.begin();
481 if (request == device_start_queue_.end()) 378 if (request == device_start_queue_.end())
482 return; 379 return;
483 380
484 const int serial_id = request->serial_id(); 381 const int serial_id = request->serial_id();
485 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); 382 VideoCaptureController* const controller =
486 DCHECK(entry); 383 LookupControllerBySerialId(serial_id);
384 DCHECK(controller);
487 385
488 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " 386 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = "
489 << entry->id << " start id = " << entry->serial_id; 387 << controller->device_id()
388 << " start id = " << controller->serial_id();
490 389
491 std::unique_ptr<media::VideoCaptureDevice::Client> device_client = 390 // The method CreateAndStartDeviceAsync() is going to run asynchronously.
492 entry->CreateDeviceClient(); 391 // Since we may be removing the controller while it is executing, we need to
493 392 // pass it shared ownership to itself so that it stays alive while executing.
494 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> 393 // And since the execution may make callbacks into |this|, we also need
495 start_capture_function; 394 // to pass it shared ownership to |this|.
496 395 // TODO(chfremer): Check if request->params() can actually be different from
497 switch (entry->stream_type) { 396 // controller->parameters, and simplify if this is not the case.
498 case MEDIA_DEVICE_VIDEO_CAPTURE: { 397 controller->CreateAndStartDeviceAsync(
499 // We look up the device id from the renderer in our local enumeration 398 request->params(),
500 // since the renderer does not have all the information that might be 399 static_cast<BuildableVideoCaptureDevice::Callbacks*>(this),
501 // held in the browser-side VideoCaptureDevice::Name structure. 400 base::Bind([](scoped_refptr<VideoCaptureManager>,
502 const DeviceInfo* found = GetDeviceInfoById(entry->id); 401 scoped_refptr<VideoCaptureController>) {},
503 if (found) { 402 scoped_refptr<VideoCaptureManager>(this),
504 entry->video_capture_controller.OnLog( 403 GetControllerSharedRefFromSerialId(serial_id)));
505 base::StringPrintf("Starting device: id: %s, name: %s, api: %s",
506 found->descriptor.device_id.c_str(),
507 found->descriptor.GetNameAndModel().c_str(),
508 found->descriptor.GetCaptureApiTypeString()));
509
510 for (auto& observer : capture_observers_)
511 observer.OnVideoCaptureStarted(found->descriptor.facing);
512
513 start_capture_function =
514 base::Bind(&VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread,
515 this, found->descriptor, request->params(),
516 base::Passed(std::move(device_client)));
517 } else {
518 // Errors from DoStartDeviceCaptureOnDeviceThread go via
519 // VideoCaptureDeviceClient::OnError, which needs some thread
520 // dancing to get errors processed on the IO thread. But since
521 // we're on that thread, we call VideoCaptureController
522 // methods directly.
523 const std::string log_message = base::StringPrintf(
524 "Error on %s:%d: device %s unknown. Maybe recently disconnected?",
525 __FILE__, __LINE__, entry->id.c_str());
526 DLOG(ERROR) << log_message;
527 entry->video_capture_controller.OnLog(log_message);
528 entry->video_capture_controller.OnError();
529 // Drop the failed start request.
530 device_start_queue_.pop_front();
531
532 return;
533 }
534 break;
535 }
536 case MEDIA_TAB_VIDEO_CAPTURE:
537 start_capture_function = base::Bind(
538 &VideoCaptureManager::DoStartTabCaptureOnDeviceThread, this,
539 entry->id, request->params(), base::Passed(std::move(device_client)));
540 break;
541
542 case MEDIA_DESKTOP_VIDEO_CAPTURE:
543 start_capture_function = base::Bind(
544 &VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, this,
545 entry->id, request->params(), base::Passed(std::move(device_client)));
546 break;
547
548 default: {
549 NOTIMPLEMENTED();
550 return;
551 }
552 }
553 base::PostTaskAndReplyWithResult(
554 device_task_runner_.get(), FROM_HERE, start_capture_function,
555 base::Bind(&VideoCaptureManager::OnDeviceStarted, this,
556 request->serial_id()));
557 } 404 }
558 405
559 void VideoCaptureManager::OnDeviceStarted( 406 void VideoCaptureManager::WillStartDevice(media::VideoFacingMode facing_mode) {
560 int serial_id, 407 for (auto& observer : capture_observers_)
561 std::unique_ptr<VideoCaptureDevice> device) { 408 observer.OnVideoCaptureStarted(facing_mode);
409 }
410
411 void VideoCaptureManager::DidStartDevice(VideoCaptureController* controller) {
562 DVLOG(3) << __func__; 412 DVLOG(3) << __func__;
563 DCHECK_CURRENTLY_ON(BrowserThread::IO); 413 DCHECK_CURRENTLY_ON(BrowserThread::IO);
564 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); 414 DCHECK(controller);
565 // |device| can be null if creation failed in 415 DCHECK_EQ(controller->serial_id(), device_start_queue_.begin()->serial_id());
566 // DoStartDeviceCaptureOnDeviceThread.
567 if (device_start_queue_.front().abort_start()) { 416 if (device_start_queue_.front().abort_start()) {
568 // The device is no longer wanted. Stop the device again. 417 // A request to release the device may have arrived during the asynchronous
569 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; 418 // device startup.
570 media::VideoCaptureDevice* device_ptr = device.get(); 419 DVLOG(3) << "Device release request has been issued while device was "
571 base::Closure closure = 420 << "starting up asynchronously.";
572 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, 421 controller->ReleaseDeviceAsync(base::Bind(
573 base::Passed(&device)); 422 [](scoped_refptr<VideoCaptureController>) {},
574 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { 423 GetControllerSharedRefFromSerialId(controller->serial_id())));
575 // PostTask failed. The device must be stopped anyway.
576 device_ptr->StopAndDeAllocate();
577 }
578 } else { 424 } else {
579 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); 425 if (controller->stream_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) {
580 DCHECK(entry);
581 DCHECK(!entry->video_capture_device);
582 if (device) {
583 // Passing raw pointer |device.get()| to the controller is safe,
584 // because we transfer ownership of it to |entry|. We are calling
585 // SetConsumerFeedbackObserver(nullptr) before releasing
586 // |entry->video_capture_device_| on the |device_task_runner_|.
587 entry->video_capture_controller.SetConsumerFeedbackObserver(
588 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>(
589 device.get(), device_task_runner_));
590 }
591 entry->video_capture_device = std::move(device);
592
593 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
594 const media::VideoCaptureSessionId session_id = 426 const media::VideoCaptureSessionId session_id =
595 device_start_queue_.front().session_id(); 427 device_start_queue_.front().session_id();
596 DCHECK(session_id != kFakeSessionId); 428 DCHECK(session_id != kFakeSessionId);
597 MaybePostDesktopCaptureWindowId(session_id); 429 MaybePostDesktopCaptureWindowId(session_id);
598 } 430 }
599 431
600 auto it = photo_request_queue_.begin(); 432 auto it = photo_request_queue_.begin();
601 while (it != photo_request_queue_.end()) { 433 while (it != photo_request_queue_.end()) {
602 auto request = it++; 434 auto request = it++;
603 DeviceEntry* maybe_entry = GetDeviceEntryBySessionId(request->first); 435 VideoCaptureController* maybe_entry =
604 if (maybe_entry && maybe_entry->video_capture_device) { 436 LookupControllerBySessionId(request->first);
605 request->second.Run(maybe_entry->video_capture_device.get()); 437 if (maybe_entry && maybe_entry->IsDeviceAlive()) {
438 request->second.Run();
606 photo_request_queue_.erase(request); 439 photo_request_queue_.erase(request);
607 } 440 }
608 } 441 }
609 } 442 }
610 443
611 device_start_queue_.pop_front(); 444 device_start_queue_.pop_front();
612 HandleQueuedStartRequest(); 445 HandleQueuedStartRequest();
613 } 446 }
614 447
615 std::unique_ptr<media::VideoCaptureDevice> 448 void VideoCaptureManager::OnDeviceStartFailed(
616 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( 449 VideoCaptureController* controller) {
617 const VideoCaptureDeviceDescriptor& descriptor, 450 const std::string log_message = base::StringPrintf(
618 const media::VideoCaptureParams& params, 451 "Starting device %s has failed. Maybe recently disconnected?",
619 std::unique_ptr<VideoCaptureDevice::Client> device_client) { 452 controller->device_id().c_str());
620 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); 453 DLOG(ERROR) << log_message;
621 DCHECK(IsOnDeviceThread()); 454 controller->OnLog(log_message);
455 controller->OnError();
622 456
623 std::unique_ptr<VideoCaptureDevice> video_capture_device; 457 device_start_queue_.pop_front();
624 video_capture_device = 458 HandleQueuedStartRequest();
625 video_capture_device_factory_->CreateDevice(descriptor);
626
627 if (!video_capture_device) {
628 device_client->OnError(FROM_HERE, "Could not create capture device");
629 return nullptr;
630 }
631
632 video_capture_device->AllocateAndStart(params, std::move(device_client));
633 return video_capture_device;
634 }
635
636 std::unique_ptr<media::VideoCaptureDevice>
637 VideoCaptureManager::DoStartTabCaptureOnDeviceThread(
638 const std::string& id,
639 const media::VideoCaptureParams& params,
640 std::unique_ptr<VideoCaptureDevice::Client> device_client) {
641 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
642 DCHECK(IsOnDeviceThread());
643
644 std::unique_ptr<VideoCaptureDevice> video_capture_device;
645 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
646 video_capture_device = WebContentsVideoCaptureDevice::Create(id);
647 #endif
648
649 if (!video_capture_device) {
650 device_client->OnError(FROM_HERE, "Could not create capture device");
651 return nullptr;
652 }
653
654 video_capture_device->AllocateAndStart(params, std::move(device_client));
655 return video_capture_device;
656 }
657
658 std::unique_ptr<media::VideoCaptureDevice>
659 VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread(
660 const std::string& id,
661 const media::VideoCaptureParams& params,
662 std::unique_ptr<VideoCaptureDevice::Client> device_client) {
663 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
664 DCHECK(IsOnDeviceThread());
665
666 std::unique_ptr<VideoCaptureDevice> video_capture_device;
667 #if defined(ENABLE_SCREEN_CAPTURE)
668 DesktopMediaID desktop_id = DesktopMediaID::Parse(id);
669 if (desktop_id.is_null()) {
670 device_client->OnError(FROM_HERE, "Desktop media ID is null");
671 return nullptr;
672 }
673
674 if (desktop_id.type == DesktopMediaID::TYPE_WEB_CONTENTS) {
675 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
676 video_capture_device = WebContentsVideoCaptureDevice::Create(id);
677 IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED);
678 if (desktop_id.audio_share) {
679 IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITH_AUDIO);
680 } else {
681 IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITHOUT_AUDIO);
682 }
683 #endif
684 } else {
685 #if defined(OS_ANDROID)
686 video_capture_device = base::MakeUnique<ScreenCaptureDeviceAndroid>();
687 #else
688 #if defined(USE_AURA)
689 video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id);
690 #endif // defined(USE_AURA)
691 #if BUILDFLAG(ENABLE_WEBRTC)
692 if (!video_capture_device)
693 video_capture_device = DesktopCaptureDevice::Create(desktop_id);
694 #endif // BUILDFLAG(ENABLE_WEBRTC)
695 #endif // defined (OS_ANDROID)
696 }
697 #endif // defined(ENABLE_SCREEN_CAPTURE)
698
699 if (!video_capture_device) {
700 device_client->OnError(FROM_HERE, "Could not create capture device");
701 return nullptr;
702 }
703
704 video_capture_device->AllocateAndStart(params, std::move(device_client));
705 return video_capture_device;
706 } 459 }
707 460
708 void VideoCaptureManager::StartCaptureForClient( 461 void VideoCaptureManager::StartCaptureForClient(
709 media::VideoCaptureSessionId session_id, 462 media::VideoCaptureSessionId session_id,
710 const media::VideoCaptureParams& params, 463 const media::VideoCaptureParams& params,
711 VideoCaptureControllerID client_id, 464 VideoCaptureControllerID client_id,
712 VideoCaptureControllerEventHandler* client_handler, 465 VideoCaptureControllerEventHandler* client_handler,
713 const DoneCB& done_cb) { 466 const DoneCB& done_cb) {
714 DCHECK_CURRENTLY_ON(BrowserThread::IO); 467 DCHECK_CURRENTLY_ON(BrowserThread::IO);
715 DVLOG(1) << __func__ << ", session_id = " << session_id << ", request: " 468 DVLOG(1) << __func__ << ", session_id = " << session_id << ", request: "
716 << media::VideoCaptureFormat::ToString(params.requested_format); 469 << media::VideoCaptureFormat::ToString(params.requested_format);
717 470
718 DeviceEntry* entry = GetOrCreateDeviceEntry(session_id, params); 471 VideoCaptureController* controller =
719 if (!entry) { 472 GetOrCreateController(session_id, params);
473 if (!controller) {
720 done_cb.Run(base::WeakPtr<VideoCaptureController>()); 474 done_cb.Run(base::WeakPtr<VideoCaptureController>());
721 return; 475 return;
722 } 476 }
723 477
724 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); 478 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE);
725 479
726 // First client starts the device. 480 // First client starts the device.
727 if (!entry->video_capture_controller.HasActiveClient() && 481 if (!controller->HasActiveClient() && !controller->HasPausedClient()) {
728 !entry->video_capture_controller.HasPausedClient()) { 482 DVLOG(1) << "VideoCaptureManager starting device (id = "
729 DVLOG(1) << "VideoCaptureManager starting device (type = " 483 << controller->device_id() << ")";
730 << entry->stream_type << ", id = " << entry->id << ")"; 484 QueueStartDevice(session_id, controller, params);
731 QueueStartDevice(session_id, entry, params);
732 } 485 }
733 // Run the callback first, as AddClient() may trigger OnFrameInfo(). 486 // Run the callback first, as AddClient() may trigger OnFrameInfo().
734 done_cb.Run(entry->video_capture_controller.GetWeakPtrForIOThread()); 487 done_cb.Run(controller->GetWeakPtrForIOThread());
735 entry->video_capture_controller.AddClient(client_id, client_handler, 488 controller->AddClient(client_id, client_handler, session_id, params);
736 session_id, params);
737 } 489 }
738 490
739 void VideoCaptureManager::StopCaptureForClient( 491 void VideoCaptureManager::StopCaptureForClient(
740 VideoCaptureController* controller, 492 VideoCaptureController* controller,
741 VideoCaptureControllerID client_id, 493 VideoCaptureControllerID client_id,
742 VideoCaptureControllerEventHandler* client_handler, 494 VideoCaptureControllerEventHandler* client_handler,
743 bool aborted_due_to_error) { 495 bool aborted_due_to_error) {
744 DCHECK_CURRENTLY_ON(BrowserThread::IO); 496 DCHECK_CURRENTLY_ON(BrowserThread::IO);
745 DCHECK(controller); 497 DCHECK(controller);
746 DCHECK(client_handler); 498 DCHECK(client_handler);
747 499
748 DeviceEntry* entry = GetDeviceEntryByController(controller); 500 if (!IsControllerPointerValid(controller)) {
749 if (!entry) {
750 NOTREACHED(); 501 NOTREACHED();
751 return; 502 return;
752 } 503 }
753 if (!aborted_due_to_error) { 504 if (!aborted_due_to_error) {
754 if (controller->has_received_frames()) { 505 if (controller->has_received_frames()) {
755 LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_OK); 506 LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_OK);
756 } else if (entry->stream_type == MEDIA_DEVICE_VIDEO_CAPTURE) { 507 } else if (controller->stream_type() == MEDIA_DEVICE_VIDEO_CAPTURE) {
757 LogVideoCaptureEvent( 508 LogVideoCaptureEvent(
758 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE); 509 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE);
759 } else { 510 } else {
760 LogVideoCaptureEvent( 511 LogVideoCaptureEvent(
761 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB); 512 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB);
762 } 513 }
763 } else { 514 } else {
764 LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR); 515 LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR);
765 for (auto it : sessions_) { 516 for (auto it : sessions_) {
766 if (it.second.type == entry->stream_type && it.second.id == entry->id) { 517 if (it.second.type == controller->stream_type() &&
518 it.second.id == controller->device_id()) {
767 for (auto& listener : listeners_) 519 for (auto& listener : listeners_)
768 listener.Aborted(it.second.type, it.first); 520 listener.Aborted(it.second.type, it.first);
769 // Aborted() call might synchronously destroy |entry|, recheck. 521 // Aborted() call might synchronously destroy |controller|, recheck.
770 entry = GetDeviceEntryByController(controller); 522 if (!IsControllerPointerValid(controller))
771 if (!entry)
772 return; 523 return;
773 break; 524 break;
774 } 525 }
775 } 526 }
776 } 527 }
777 528
778 // Detach client from controller. 529 // Detach client from controller.
779 const media::VideoCaptureSessionId session_id = 530 const media::VideoCaptureSessionId session_id =
780 controller->RemoveClient(client_id, client_handler); 531 controller->RemoveClient(client_id, client_handler);
781 DVLOG(1) << __func__ << ", session_id = " << session_id; 532 DVLOG(1) << __func__ << ", session_id = " << session_id;
782 533
783 // If controller has no more clients, delete controller and device. 534 // If controller has no more clients, delete controller and device.
784 DestroyDeviceEntryIfNoClients(entry); 535 DestroyControllerIfNoClients(controller);
785 } 536 }
786 537
787 void VideoCaptureManager::PauseCaptureForClient( 538 void VideoCaptureManager::PauseCaptureForClient(
788 VideoCaptureController* controller, 539 VideoCaptureController* controller,
789 VideoCaptureControllerID client_id, 540 VideoCaptureControllerID client_id,
790 VideoCaptureControllerEventHandler* client_handler) { 541 VideoCaptureControllerEventHandler* client_handler) {
791 DCHECK_CURRENTLY_ON(BrowserThread::IO); 542 DCHECK_CURRENTLY_ON(BrowserThread::IO);
792 DCHECK(controller); 543 DCHECK(controller);
793 DCHECK(client_handler); 544 DCHECK(client_handler);
794 DeviceEntry* entry = GetDeviceEntryByController(controller); 545 if (!IsControllerPointerValid(controller))
795 if (!entry) 546 NOTREACHED() << "Got Null controller while pausing capture";
796 NOTREACHED() << "Got Null entry while pausing capture";
797 547
798 const bool had_active_client = controller->HasActiveClient(); 548 const bool had_active_client = controller->HasActiveClient();
799 controller->PauseClient(client_id, client_handler); 549 controller->PauseClient(client_id, client_handler);
800 if (!had_active_client || controller->HasActiveClient()) 550 if (!had_active_client || controller->HasActiveClient())
801 return; 551 return;
802 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { 552 if (!controller->IsDeviceAlive())
803 device_task_runner_->PostTask( 553 return;
804 FROM_HERE, 554 controller->MaybeSuspend();
805 base::Bind(&VideoCaptureDevice::MaybeSuspend,
806 // Unretained is safe to use here because |device| would be
807 // null if it was scheduled for shutdown and destruction, and
808 // because this task is guaranteed to run before the task
809 // that destroys the |device|.
810 base::Unretained(device)));
811 }
812 } 555 }
813 556
814 void VideoCaptureManager::ResumeCaptureForClient( 557 void VideoCaptureManager::ResumeCaptureForClient(
815 media::VideoCaptureSessionId session_id, 558 media::VideoCaptureSessionId session_id,
816 const media::VideoCaptureParams& params, 559 const media::VideoCaptureParams& params,
817 VideoCaptureController* controller, 560 VideoCaptureController* controller,
818 VideoCaptureControllerID client_id, 561 VideoCaptureControllerID client_id,
819 VideoCaptureControllerEventHandler* client_handler) { 562 VideoCaptureControllerEventHandler* client_handler) {
820 DCHECK_CURRENTLY_ON(BrowserThread::IO); 563 DCHECK_CURRENTLY_ON(BrowserThread::IO);
821 DCHECK(controller); 564 DCHECK(controller);
822 DCHECK(client_handler); 565 DCHECK(client_handler);
823 566
824 DeviceEntry* entry = GetDeviceEntryByController(controller); 567 if (!IsControllerPointerValid(controller))
825 if (!entry) 568 NOTREACHED() << "Got Null controller while resuming capture";
826 NOTREACHED() << "Got Null entry while resuming capture";
827 569
828 const bool had_active_client = controller->HasActiveClient(); 570 const bool had_active_client = controller->HasActiveClient();
829 controller->ResumeClient(client_id, client_handler); 571 controller->ResumeClient(client_id, client_handler);
830 if (had_active_client || !controller->HasActiveClient()) 572 if (had_active_client || !controller->HasActiveClient())
831 return; 573 return;
832 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { 574 if (!controller->IsDeviceAlive())
833 device_task_runner_->PostTask( 575 return;
834 FROM_HERE, 576 controller->Resume();
835 base::Bind(&VideoCaptureDevice::Resume,
836 // Unretained is safe to use here because |device| would be
837 // null if it was scheduled for shutdown and destruction, and
838 // because this task is guaranteed to run before the task
839 // that destroys the |device|.
840 base::Unretained(device)));
841 }
842 } 577 }
843 578
844 void VideoCaptureManager::RequestRefreshFrameForClient( 579 void VideoCaptureManager::RequestRefreshFrameForClient(
845 VideoCaptureController* controller) { 580 VideoCaptureController* controller) {
846 DCHECK_CURRENTLY_ON(BrowserThread::IO); 581 DCHECK_CURRENTLY_ON(BrowserThread::IO);
847 582
848 if (DeviceEntry* entry = GetDeviceEntryByController(controller)) { 583 if (IsControllerPointerValid(controller)) {
849 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { 584 if (!controller->IsDeviceAlive())
850 device_task_runner_->PostTask( 585 return;
851 FROM_HERE, 586 controller->RequestRefreshFrame();
852 base::Bind(&VideoCaptureDevice::RequestRefreshFrame,
853 // Unretained is safe to use here because |device| would be
854 // null if it was scheduled for shutdown and destruction,
855 // and because this task is guaranteed to run before the
856 // task that destroys the |device|.
857 base::Unretained(device)));
858 }
859 } 587 }
860 } 588 }
861 589
862 bool VideoCaptureManager::GetDeviceSupportedFormats( 590 bool VideoCaptureManager::GetDeviceSupportedFormats(
863 media::VideoCaptureSessionId capture_session_id, 591 media::VideoCaptureSessionId capture_session_id,
864 media::VideoCaptureFormats* supported_formats) { 592 media::VideoCaptureFormats* supported_formats) {
865 DCHECK_CURRENTLY_ON(BrowserThread::IO); 593 DCHECK_CURRENTLY_ON(BrowserThread::IO);
866 DCHECK(supported_formats->empty()); 594 DCHECK(supported_formats->empty());
867 595
868 SessionMap::iterator it = sessions_.find(capture_session_id); 596 SessionMap::iterator it = sessions_.find(capture_session_id);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 return GetDeviceFormatsInUse(it->second.type, it->second.id, formats_in_use); 628 return GetDeviceFormatsInUse(it->second.type, it->second.id, formats_in_use);
901 } 629 }
902 630
903 bool VideoCaptureManager::GetDeviceFormatsInUse( 631 bool VideoCaptureManager::GetDeviceFormatsInUse(
904 MediaStreamType stream_type, 632 MediaStreamType stream_type,
905 const std::string& device_id, 633 const std::string& device_id,
906 media::VideoCaptureFormats* formats_in_use) { 634 media::VideoCaptureFormats* formats_in_use) {
907 DCHECK_CURRENTLY_ON(BrowserThread::IO); 635 DCHECK_CURRENTLY_ON(BrowserThread::IO);
908 DCHECK(formats_in_use->empty()); 636 DCHECK(formats_in_use->empty());
909 // Return the currently in-use format(s) of the device, if it's started. 637 // Return the currently in-use format(s) of the device, if it's started.
910 DeviceEntry* device_in_use = 638 VideoCaptureController* device_in_use =
911 GetDeviceEntryByTypeAndId(stream_type, device_id); 639 LookupControllerByTypeAndId(stream_type, device_id);
912 if (device_in_use) { 640 if (device_in_use) {
913 // Currently only one format-in-use is supported at the VCC level. 641 // Currently only one format-in-use is supported at the VCC level.
914 formats_in_use->push_back( 642 formats_in_use->push_back(device_in_use->GetVideoCaptureFormat());
915 device_in_use->video_capture_controller.GetVideoCaptureFormat());
916 } 643 }
917 return true; 644 return true;
918 } 645 }
919 646
920 void VideoCaptureManager::SetDesktopCaptureWindowId( 647 void VideoCaptureManager::SetDesktopCaptureWindowId(
921 media::VideoCaptureSessionId session_id, 648 media::VideoCaptureSessionId session_id,
922 gfx::NativeViewId window_id) { 649 gfx::NativeViewId window_id) {
923 DCHECK_CURRENTLY_ON(BrowserThread::IO); 650 DCHECK_CURRENTLY_ON(BrowserThread::IO);
924 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; 651 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id;
925 652
926 notification_window_ids_[session_id] = window_id; 653 notification_window_ids_[session_id] = window_id;
927 MaybePostDesktopCaptureWindowId(session_id); 654 MaybePostDesktopCaptureWindowId(session_id);
928 } 655 }
929 656
930 void VideoCaptureManager::MaybePostDesktopCaptureWindowId( 657 void VideoCaptureManager::MaybePostDesktopCaptureWindowId(
931 media::VideoCaptureSessionId session_id) { 658 media::VideoCaptureSessionId session_id) {
932 SessionMap::iterator session_it = sessions_.find(session_id); 659 SessionMap::iterator session_it = sessions_.find(session_id);
933 if (session_it == sessions_.end()) 660 if (session_it == sessions_.end())
934 return; 661 return;
935 662
936 DeviceEntry* const existing_device = 663 VideoCaptureController* const existing_device = LookupControllerByTypeAndId(
937 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); 664 session_it->second.type, session_it->second.id);
938 if (!existing_device) { 665 if (!existing_device) {
939 DVLOG(2) << "Failed to find an existing screen capture device."; 666 DVLOG(2) << "Failed to find an existing screen capture device.";
940 return; 667 return;
941 } 668 }
942 669
943 if (!existing_device->video_capture_device) { 670 if (!existing_device->IsDeviceAlive()) {
944 DVLOG(2) << "Screen capture device not yet started."; 671 DVLOG(2) << "Screen capture device not yet started.";
945 return; 672 return;
946 } 673 }
947 674
948 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); 675 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type());
949 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); 676 DesktopMediaID id = DesktopMediaID::Parse(existing_device->device_id());
950 if (id.is_null()) 677 if (id.is_null())
951 return; 678 return;
952 679
953 auto window_id_it = notification_window_ids_.find(session_id); 680 auto window_id_it = notification_window_ids_.find(session_id);
954 if (window_id_it == notification_window_ids_.end()) { 681 if (window_id_it == notification_window_ids_.end()) {
955 DVLOG(2) << "Notification window id not set for screen capture."; 682 DVLOG(2) << "Notification window id not set for screen capture.";
956 return; 683 return;
957 } 684 }
958 685
959 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to 686 existing_device->SetDesktopCaptureWindowIdAsync(
960 // the device_task_runner_. This is safe since the device is destroyed on the 687 window_id_it->second,
961 // device_task_runner_. 688 base::Bind([](scoped_refptr<VideoCaptureManager>) {},
962 device_task_runner_->PostTask( 689 scoped_refptr<VideoCaptureManager>(this)));
963 FROM_HERE,
964 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread,
965 this, existing_device->video_capture_device.get(),
966 window_id_it->second));
967
968 notification_window_ids_.erase(window_id_it); 690 notification_window_ids_.erase(window_id_it);
969 } 691 }
970 692
971 void VideoCaptureManager::GetPhotoCapabilities( 693 void VideoCaptureManager::GetPhotoCapabilities(
972 int session_id, 694 int session_id,
973 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { 695 media::VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
974 DCHECK_CURRENTLY_ON(BrowserThread::IO); 696 DCHECK_CURRENTLY_ON(BrowserThread::IO);
975 697
976 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); 698 const VideoCaptureController* controller =
977 if (!entry) 699 LookupControllerBySessionId(session_id);
700 if (!controller)
978 return; 701 return;
979 VideoCaptureDevice* device = entry->video_capture_device.get(); 702 if (controller->IsDeviceAlive()) {
980 if (device) { 703 controller->GetPhotoCapabilities(std::move(callback));
981 VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device);
982 return; 704 return;
983 } 705 }
984 // |entry| is known but |device| is nullptr, queue up a request for later. 706 // Queue up a request for later.
985 photo_request_queue_.emplace_back( 707 photo_request_queue_.emplace_back(
986 session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this, 708 session_id,
987 base::Passed(&callback))); 709 base::Bind(&VideoCaptureController::GetPhotoCapabilities,
710 base::Unretained(controller), base::Passed(&callback)));
988 } 711 }
989 712
990 void VideoCaptureManager::SetPhotoOptions( 713 void VideoCaptureManager::SetPhotoOptions(
991 int session_id, 714 int session_id,
992 media::mojom::PhotoSettingsPtr settings, 715 media::mojom::PhotoSettingsPtr settings,
993 VideoCaptureDevice::SetPhotoOptionsCallback callback) { 716 media::VideoCaptureDevice::SetPhotoOptionsCallback callback) {
994 DCHECK_CURRENTLY_ON(BrowserThread::IO); 717 DCHECK_CURRENTLY_ON(BrowserThread::IO);
995 718
996 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); 719 VideoCaptureController* controller = LookupControllerBySessionId(session_id);
997 if (!entry) 720 if (!controller)
998 return; 721 return;
999 VideoCaptureDevice* device = entry->video_capture_device.get(); 722 if (controller->IsDeviceAlive()) {
1000 if (device) { 723 controller->SetPhotoOptions(std::move(settings), std::move(callback));
1001 VideoCaptureManager::DoSetPhotoOptions(std::move(callback),
1002 std::move(settings), device);
1003 return; 724 return;
1004 } 725 }
1005 // |entry| is known but |device| is nullptr, queue up a request for later. 726 // Queue up a request for later.
1006 photo_request_queue_.emplace_back( 727 photo_request_queue_.emplace_back(
1007 session_id, base::Bind(&VideoCaptureManager::DoSetPhotoOptions, this, 728 session_id, base::Bind(&VideoCaptureController::SetPhotoOptions,
1008 base::Passed(&callback), base::Passed(&settings))); 729 base::Unretained(controller),
730 base::Passed(&settings), base::Passed(&callback)));
1009 } 731 }
1010 732
1011 void VideoCaptureManager::TakePhoto( 733 void VideoCaptureManager::TakePhoto(
1012 int session_id, 734 int session_id,
1013 VideoCaptureDevice::TakePhotoCallback callback) { 735 media::VideoCaptureDevice::TakePhotoCallback callback) {
1014 DCHECK_CURRENTLY_ON(BrowserThread::IO); 736 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1015 737
1016 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); 738 VideoCaptureController* controller = LookupControllerBySessionId(session_id);
1017 if (!entry) 739 if (!controller)
1018 return; 740 return;
1019 VideoCaptureDevice* device = entry->video_capture_device.get(); 741 if (controller->IsDeviceAlive()) {
1020 if (device) { 742 controller->TakePhoto(std::move(callback));
1021 VideoCaptureManager::DoTakePhoto(std::move(callback), device);
1022 return; 743 return;
1023 } 744 }
1024 // |entry| is known but |device| is nullptr, queue up a request for later. 745 // Queue up a request for later.
1025 photo_request_queue_.emplace_back( 746 photo_request_queue_.emplace_back(
1026 session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this, 747 session_id,
1027 base::Passed(&callback))); 748 base::Bind(&VideoCaptureController::TakePhoto,
1028 } 749 base::Unretained(controller), base::Passed(&callback)));
1029
1030 void VideoCaptureManager::DoStopDeviceOnDeviceThread(
1031 std::unique_ptr<VideoCaptureDevice> device) {
1032 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
1033 DCHECK(IsOnDeviceThread());
1034 device->StopAndDeAllocate();
1035 DVLOG(3) << "DoStopDeviceOnDeviceThread";
1036 } 750 }
1037 751
1038 void VideoCaptureManager::OnOpened( 752 void VideoCaptureManager::OnOpened(
1039 MediaStreamType stream_type, 753 MediaStreamType stream_type,
1040 media::VideoCaptureSessionId capture_session_id) { 754 media::VideoCaptureSessionId capture_session_id) {
1041 DCHECK_CURRENTLY_ON(BrowserThread::IO); 755 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1042 for (auto& listener : listeners_) 756 for (auto& listener : listeners_)
1043 listener.Opened(stream_type, capture_session_id); 757 listener.Opened(stream_type, capture_session_id);
1044 } 758 }
1045 759
(...skipping 17 matching lines...) Expand all
1063 777
1064 // Walk the |devices_info_cache_| and produce a 778 // Walk the |devices_info_cache_| and produce a
1065 // media::VideoCaptureDeviceDescriptors for return purposes. 779 // media::VideoCaptureDeviceDescriptors for return purposes.
1066 media::VideoCaptureDeviceDescriptors devices; 780 media::VideoCaptureDeviceDescriptors devices;
1067 std::vector<std::tuple<media::VideoCaptureDeviceDescriptor, 781 std::vector<std::tuple<media::VideoCaptureDeviceDescriptor,
1068 media::VideoCaptureFormats>> 782 media::VideoCaptureFormats>>
1069 descriptors_and_formats; 783 descriptors_and_formats;
1070 for (const auto& it : devices_info_cache_) { 784 for (const auto& it : devices_info_cache_) {
1071 devices.emplace_back(it.descriptor); 785 devices.emplace_back(it.descriptor);
1072 descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats); 786 descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats);
1073 }
1074
1075 if (!descriptors_and_formats.empty()) {
1076 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities( 787 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities(
1077 descriptors_and_formats); 788 descriptors_and_formats);
1078 } 789 }
1079 790
1080 client_callback.Run(devices); 791 client_callback.Run(devices);
1081 } 792 }
1082 793
1083 bool VideoCaptureManager::IsOnDeviceThread() const {
1084 return device_task_runner_->BelongsToCurrentThread();
1085 }
1086
1087 void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread( 794 void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread(
1088 base::Callback<void(const VideoCaptureManager::DeviceInfos&)> 795 base::Callback<void(const VideoCaptureManager::DeviceInfos&)>
1089 on_devices_enumerated_callback, 796 on_devices_enumerated_callback,
1090 const VideoCaptureManager::DeviceInfos& old_device_info_cache, 797 const VideoCaptureManager::DeviceInfos& old_device_info_cache,
1091 std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors_snapshot) { 798 std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors_snapshot) {
1092 DCHECK(IsOnDeviceThread()); 799 DCHECK(device_task_runner_->BelongsToCurrentThread());
1093 // Construct |new_devices_info_cache| with the cached devices that are still 800 // Construct |new_devices_info_cache| with the cached devices that are still
1094 // present in the system, and remove their names from |names_snapshot|, so we 801 // present in the system, and remove their names from |names_snapshot|, so we
1095 // keep there the truly new devices. 802 // keep there the truly new devices.
1096 VideoCaptureManager::DeviceInfos new_devices_info_cache; 803 VideoCaptureManager::DeviceInfos new_devices_info_cache;
1097 for (const auto& device_info : old_device_info_cache) { 804 for (const auto& device_info : old_device_info_cache) {
1098 for (VideoCaptureDeviceDescriptors::iterator it = 805 for (VideoCaptureDeviceDescriptors::iterator it =
1099 descriptors_snapshot->begin(); 806 descriptors_snapshot->begin();
1100 it != descriptors_snapshot->end(); ++it) { 807 it != descriptors_snapshot->end(); ++it) {
1101 if (device_info.descriptor.device_id == it->device_id) { 808 if (device_info.descriptor.device_id == it->device_id) {
1102 new_devices_info_cache.push_back(device_info); 809 new_devices_info_cache.push_back(device_info);
1103 descriptors_snapshot->erase(it); 810 descriptors_snapshot->erase(it);
1104 break; 811 break;
1105 } 812 }
1106 } 813 }
1107 } 814 }
1108 815
1109 // Get the device info for the new devices in |names_snapshot|. 816 // Get the device info for the new devices in |names_snapshot|.
1110 for (const auto& it : *descriptors_snapshot) { 817 for (const auto& it : *descriptors_snapshot) {
1111 DeviceInfo device_info(it); 818 DeviceInfo device_info(it);
1112 video_capture_device_factory_->GetSupportedFormats( 819 video_capture_device_factory_->GetSupportedFormats(
1113 it, &device_info.supported_formats); 820 it, &device_info.supported_formats);
1114 ConsolidateCaptureFormats(&device_info.supported_formats); 821 ConsolidateCaptureFormats(&device_info.supported_formats);
1115 new_devices_info_cache.push_back(device_info); 822 new_devices_info_cache.push_back(device_info);
1116 } 823 }
1117 824
1118 on_devices_enumerated_callback.Run(new_devices_info_cache); 825 on_devices_enumerated_callback.Run(new_devices_info_cache);
1119 } 826 }
1120 827
1121 void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { 828 void VideoCaptureManager::DestroyControllerIfNoClients(
829 VideoCaptureController* controller) {
1122 DCHECK_CURRENTLY_ON(BrowserThread::IO); 830 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1123 // Removal of the last client stops the device. 831 // Removal of the last client stops the device.
1124 if (!entry->video_capture_controller.HasActiveClient() && 832 if (!controller->HasActiveClient() && !controller->HasPausedClient()) {
1125 !entry->video_capture_controller.HasPausedClient()) {
1126 DVLOG(1) << "VideoCaptureManager stopping device (type = " 833 DVLOG(1) << "VideoCaptureManager stopping device (type = "
1127 << entry->stream_type << ", id = " << entry->id << ")"; 834 << controller->stream_type()
835 << ", id = " << controller->device_id() << ")";
1128 836
1129 // The DeviceEntry is removed from |devices_| immediately. The controller is 837 // The VideoCaptureController is removed from |controllers_| immediately.
1130 // deleted immediately, and the device is freed asynchronously. After this 838 // The controller is deleted immediately, and the device is freed
1131 // point, subsequent requests to open this same device ID will create a new 839 // asynchronously. After this point, subsequent requests to open this same
1132 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. 840 // device ID will create a new VideoCaptureController,
1133 DoStopDevice(entry); 841 // VideoCaptureController, and VideoCaptureDevice.
842 DoStopDevice(controller);
1134 // TODO(mcasas): use a helper function https://crbug.com/624854. 843 // TODO(mcasas): use a helper function https://crbug.com/624854.
1135 DeviceEntries::iterator device_it = 844 auto controller_iter = std::find_if(
1136 std::find_if(devices_.begin(), devices_.end(), 845 controllers_.begin(), controllers_.end(),
1137 [entry](const std::unique_ptr<DeviceEntry>& device_entry) { 846 [controller](
1138 return device_entry.get() == entry; 847 const scoped_refptr<VideoCaptureController>& device_entry) {
1139 }); 848 return device_entry.get() == controller;
1140 devices_.erase(device_it); 849 });
850 controllers_.erase(controller_iter);
1141 } 851 }
1142 } 852 }
1143 853
1144 VideoCaptureManager::DeviceEntry* 854 VideoCaptureController* VideoCaptureManager::LookupControllerBySessionId(
1145 VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) { 855 int session_id) {
1146 DCHECK_CURRENTLY_ON(BrowserThread::IO); 856 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1147 SessionMap::const_iterator session_it = sessions_.find(session_id); 857 SessionMap::const_iterator session_it = sessions_.find(session_id);
1148 if (session_it == sessions_.end()) 858 if (session_it == sessions_.end())
1149 return nullptr; 859 return nullptr;
1150 860
1151 return GetDeviceEntryByTypeAndId(session_it->second.type, 861 return LookupControllerByTypeAndId(session_it->second.type,
1152 session_it->second.id); 862 session_it->second.id);
1153 } 863 }
1154 864
1155 VideoCaptureManager::DeviceEntry* 865 VideoCaptureController* VideoCaptureManager::LookupControllerByTypeAndId(
1156 VideoCaptureManager::GetDeviceEntryByTypeAndId(
1157 MediaStreamType type, 866 MediaStreamType type,
1158 const std::string& device_id) const { 867 const std::string& device_id) const {
1159 DCHECK_CURRENTLY_ON(BrowserThread::IO); 868 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1160 869
1161 for (const std::unique_ptr<DeviceEntry>& device : devices_) { 870 for (const auto& entry : controllers_) {
1162 if (type == device->stream_type && device_id == device->id) 871 if (type == entry->stream_type() && device_id == entry->device_id())
1163 return device.get(); 872 return entry.get();
1164 } 873 }
1165 return nullptr; 874 return nullptr;
1166 } 875 }
1167 876
1168 VideoCaptureManager::DeviceEntry* 877 bool VideoCaptureManager::IsControllerPointerValid(
1169 VideoCaptureManager::GetDeviceEntryByController(
1170 const VideoCaptureController* controller) const { 878 const VideoCaptureController* controller) const {
1171 DCHECK_CURRENTLY_ON(BrowserThread::IO); 879 DCHECK_CURRENTLY_ON(BrowserThread::IO);
880 return base::ContainsValue(controllers_, controller);
881 }
1172 882
1173 // Look up |controller| in |devices_|. 883 VideoCaptureController* VideoCaptureManager::LookupControllerBySerialId(
1174 for (const std::unique_ptr<DeviceEntry>& device : devices_) { 884 int serial_id) const {
1175 if (&device->video_capture_controller == controller) 885 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1176 return device.get(); 886
887 for (const auto& entry : controllers_) {
888 if (entry->serial_id() == serial_id)
889 return entry.get();
1177 } 890 }
1178 return nullptr; 891 return nullptr;
1179 } 892 }
1180 893
1181 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId( 894 scoped_refptr<VideoCaptureController>
1182 int serial_id) const { 895 VideoCaptureManager::GetControllerSharedRefFromSerialId(int serial_id) const {
1183 DCHECK_CURRENTLY_ON(BrowserThread::IO); 896 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1184 897
1185 for (const std::unique_ptr<DeviceEntry>& device : devices_) { 898 for (const auto& entry : controllers_) {
1186 if (device->serial_id == serial_id) 899 if (entry->serial_id() == serial_id)
1187 return device.get(); 900 return entry;
1188 } 901 }
1189 return nullptr; 902 return nullptr;
1190 } 903 }
1191 904
1192 VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById( 905 VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById(
1193 const std::string& id) { 906 const std::string& id) {
1194 for (auto& it : devices_info_cache_) { 907 for (auto& it : devices_info_cache_) {
1195 if (it.descriptor.device_id == id) 908 if (it.descriptor.device_id == id)
1196 return &it; 909 return &it;
1197 } 910 }
1198 return nullptr; 911 return nullptr;
1199 } 912 }
1200 913
1201 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( 914 VideoCaptureController* VideoCaptureManager::GetOrCreateController(
1202 media::VideoCaptureSessionId capture_session_id, 915 media::VideoCaptureSessionId capture_session_id,
1203 const media::VideoCaptureParams& params) { 916 const media::VideoCaptureParams& params) {
1204 DCHECK_CURRENTLY_ON(BrowserThread::IO); 917 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1205 918
1206 SessionMap::iterator session_it = sessions_.find(capture_session_id); 919 SessionMap::iterator session_it = sessions_.find(capture_session_id);
1207 if (session_it == sessions_.end()) 920 if (session_it == sessions_.end())
1208 return nullptr; 921 return nullptr;
1209 const MediaStreamDevice& device_info = session_it->second; 922 const MediaStreamDevice& device_info = session_it->second;
1210 923
1211 // Check if another session has already opened this device. If so, just 924 // Check if another session has already opened this device. If so, just
1212 // use that opened device. 925 // use that opened device.
1213 DeviceEntry* const existing_device = 926 VideoCaptureController* const existing_device =
1214 GetDeviceEntryByTypeAndId(device_info.type, device_info.id); 927 LookupControllerByTypeAndId(device_info.type, device_info.id);
1215 if (existing_device) { 928 if (existing_device) {
1216 DCHECK_EQ(device_info.type, existing_device->stream_type); 929 DCHECK_EQ(device_info.type, existing_device->stream_type());
1217 return existing_device; 930 return existing_device;
1218 } 931 }
1219 932
1220 devices_.emplace_back( 933 VideoCaptureController* new_device_entry = new VideoCaptureController(
1221 new DeviceEntry(device_info.type, device_info.id, params)); 934 device_info.id, device_info.type, params,
1222 return devices_.back().get(); 935 base::MakeUnique<InProcessBuildableVideoCaptureDevice>(
1223 } 936 device_task_runner_, video_capture_device_factory_.get()));
1224 937 controllers_.emplace_back(new_device_entry);
1225 void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread( 938 return new_device_entry;
1226 media::VideoCaptureDevice* device,
1227 gfx::NativeViewId window_id) {
1228 DCHECK(IsOnDeviceThread());
1229 #if defined(ENABLE_SCREEN_CAPTURE) && BUILDFLAG(ENABLE_WEBRTC) && !defined(OS_AN DROID)
1230 DesktopCaptureDevice* desktop_device =
1231 static_cast<DesktopCaptureDevice*>(device);
1232 desktop_device->SetNotificationWindowId(window_id);
1233 VLOG(2) << "Screen capture notification window passed on device thread.";
1234 #endif
1235 }
1236
1237 void VideoCaptureManager::DoGetPhotoCapabilities(
1238 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback,
1239 VideoCaptureDevice* device) {
1240 // Unretained() is safe to use here because |device| would be null if it
1241 // was scheduled for shutdown and destruction, and because this task is
1242 // guaranteed to run before the task that destroys the |device|.
1243 device_task_runner_->PostTask(
1244 FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities,
1245 base::Unretained(device), base::Passed(&callback)));
1246 }
1247
1248 void VideoCaptureManager::DoSetPhotoOptions(
1249 VideoCaptureDevice::SetPhotoOptionsCallback callback,
1250 media::mojom::PhotoSettingsPtr settings,
1251 VideoCaptureDevice* device) {
1252 // Unretained() is safe to use here because |device| would be null if it
1253 // was scheduled for shutdown and destruction, and because this task is
1254 // guaranteed to run before the task that destroys the |device|.
1255 device_task_runner_->PostTask(
1256 FROM_HERE,
1257 base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device),
1258 base::Passed(&settings), base::Passed(&callback)));
1259 }
1260
1261 void VideoCaptureManager::DoTakePhoto(
1262 VideoCaptureDevice::TakePhotoCallback callback,
1263 VideoCaptureDevice* device) {
1264 // Unretained() is safe to use here because |device| would be null if it
1265 // was scheduled for shutdown and destruction, and because this task is
1266 // guaranteed to run before the task that destroys the |device|.
1267 device_task_runner_->PostTask(
1268 FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto,
1269 base::Unretained(device), base::Passed(&callback)));
1270 } 939 }
1271 940
1272 base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration( 941 base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration(
1273 const std::string& device_id) { 942 const std::string& device_id) {
1274 VideoCaptureManager::DeviceInfo* info = GetDeviceInfoById(device_id); 943 VideoCaptureManager::DeviceInfo* info = GetDeviceInfoById(device_id);
1275 if (!info) 944 if (!info)
1276 return base::Optional<CameraCalibration>(); 945 return base::Optional<CameraCalibration>();
1277 return info->descriptor.camera_calibration; 946 return info->descriptor.camera_calibration;
1278 } 947 }
1279 948
(...skipping 10 matching lines...) Expand all
1290 application_state_has_running_activities_ = true; 959 application_state_has_running_activities_ = true;
1291 } else if (state == base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES) { 960 } else if (state == base::android::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES) {
1292 ReleaseDevices(); 961 ReleaseDevices();
1293 application_state_has_running_activities_ = false; 962 application_state_has_running_activities_ = false;
1294 } 963 }
1295 } 964 }
1296 965
1297 void VideoCaptureManager::ReleaseDevices() { 966 void VideoCaptureManager::ReleaseDevices() {
1298 DCHECK_CURRENTLY_ON(BrowserThread::IO); 967 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1299 968
1300 for (auto& entry : devices_) { 969 for (auto& controller : controllers_) {
1301 // Do not stop Content Video Capture devices, e.g. Tab or Screen capture. 970 // Do not stop Content Video Capture devices, e.g. Tab or Screen capture.
1302 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) 971 if (controller->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE)
1303 continue; 972 continue;
1304 973
1305 DoStopDevice(entry.get()); 974 DoStopDevice(controller.get());
1306 } 975 }
1307 } 976 }
1308 977
1309 void VideoCaptureManager::ResumeDevices() { 978 void VideoCaptureManager::ResumeDevices() {
1310 DCHECK_CURRENTLY_ON(BrowserThread::IO); 979 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1311 980
1312 for (auto& entry : devices_) { 981 for (auto& controller : controllers_) {
1313 // Do not resume Content Video Capture devices, e.g. Tab or Screen capture. 982 // Do not resume Content Video Capture devices, e.g. Tab or Screen capture.
1314 // Do not try to restart already running devices. 983 // Do not try to restart already running devices.
1315 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE || 984 if (controller->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE ||
1316 entry->video_capture_device) 985 controller->IsDeviceAlive())
1317 continue; 986 continue;
1318 987
1319 // Check if the device is already in the start queue. 988 // Check if the device is already in the start queue.
1320 bool device_in_queue = false; 989 bool device_in_queue = false;
1321 for (auto& request : device_start_queue_) { 990 for (auto& request : device_start_queue_) {
1322 if (request.serial_id() == entry->serial_id) { 991 if (request.serial_id() == controller->serial_id()) {
1323 device_in_queue = true; 992 device_in_queue = true;
1324 break; 993 break;
1325 } 994 }
1326 } 995 }
1327 996
1328 if (!device_in_queue) { 997 if (!device_in_queue) {
1329 // Session ID is only valid for Screen capture. So we can fake it to 998 // Session ID is only valid for Screen capture. So we can fake it to
1330 // resume video capture devices here. 999 // resume video capture devices here.
1331 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); 1000 QueueStartDevice(kFakeSessionId, controller.get(),
1001 controller->parameters());
1332 } 1002 }
1333 } 1003 }
1334 } 1004 }
1335 #endif // defined(OS_ANDROID) 1005 #endif // defined(OS_ANDROID)
1336 1006
1337 } // namespace content 1007 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698