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

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 Feb 10th and change similarity to 10 Created 3 years, 9 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
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_capture_device_entry.h"
31 #include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread. h"
32 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/desktop_media_id.h" 33 #include "content/public/browser/desktop_media_id.h"
34 #include "content/public/common/media_stream_request.h" 34 #include "content/public/common/media_stream_request.h"
35 #include "media/base/bind_to_current_loop.h" 35 #include "media/base/bind_to_current_loop.h"
36 #include "media/base/media_switches.h" 36 #include "media/base/media_switches.h"
37 #include "media/base/video_facing.h" 37 #include "media/base/video_facing.h"
38 #include "media/capture/video/video_capture_buffer_pool_impl.h" 38 #include "media/capture/video/video_capture_buffer_pool_impl.h"
39 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" 39 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
40 #include "media/capture/video/video_capture_device.h" 40 #include "media/capture/video/video_capture_device.h"
41 #include "media/capture/video/video_capture_device_client.h" 41 #include "media/capture/video/video_capture_device_client.h"
(...skipping 10 matching lines...) Expand all
52 #endif 52 #endif
53 53
54 #if defined(OS_ANDROID) 54 #if defined(OS_ANDROID)
55 #include "content/browser/media/capture/screen_capture_device_android.h" 55 #include "content/browser/media/capture/screen_capture_device_android.h"
56 #endif 56 #endif
57 57
58 #endif // defined(ENABLE_SCREEN_CAPTURE) 58 #endif // defined(ENABLE_SCREEN_CAPTURE)
59 59
60 namespace { 60 namespace {
61 61
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 62 // Compares two VideoCaptureFormat by checking smallest frame_size area, then
84 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that 63 // 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 64 // the first entry for a given resolution has the largest frame rate, as needed
86 // by the ConsolidateCaptureFormats() method. 65 // by the ConsolidateCaptureFormats() method.
87 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, 66 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1,
88 const media::VideoCaptureFormat& format2) { 67 const media::VideoCaptureFormat& format2) {
89 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); 68 DCHECK(format1.frame_size.GetCheckedArea().IsValid());
90 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); 69 DCHECK(format2.frame_size.GetCheckedArea().IsValid());
91 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == 70 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) ==
92 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { 71 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) {
(...skipping 25 matching lines...) Expand all
118 formats->erase(last, formats->end()); 97 formats->erase(last, formats->end());
119 // Mark all formats as I420, since this is what the renderer side will get 98 // 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. 99 // anyhow: the actual pixel format is decided at the device level.
121 // Don't do this for Y16 format as it is handled separatelly. 100 // Don't do this for Y16 format as it is handled separatelly.
122 for (auto& format : *formats) { 101 for (auto& format : *formats) {
123 if (format.pixel_format != media::PIXEL_FORMAT_Y16) 102 if (format.pixel_format != media::PIXEL_FORMAT_Y16)
124 format.pixel_format = media::PIXEL_FORMAT_I420; 103 format.pixel_format = media::PIXEL_FORMAT_I420;
125 } 104 }
126 } 105 }
127 106
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. 107 // Used for logging capture events.
139 // Elements in this enum should not be deleted or rearranged; the only 108 // 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. 109 // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT.
141 enum VideoCaptureEvent { 110 enum VideoCaptureEvent {
142 VIDEO_CAPTURE_START_CAPTURE = 0, 111 VIDEO_CAPTURE_START_CAPTURE = 0,
143 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1, 112 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1,
144 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2, 113 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2,
145 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE = 3, 114 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, 115 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB = 4,
147 NUM_VIDEO_CAPTURE_EVENT 116 NUM_VIDEO_CAPTURE_EVENT
148 }; 117 };
149 118
150 void LogVideoCaptureEvent(VideoCaptureEvent event) { 119 void LogVideoCaptureEvent(VideoCaptureEvent event) {
151 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", 120 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", event,
152 event,
153 NUM_VIDEO_CAPTURE_EVENT); 121 NUM_VIDEO_CAPTURE_EVENT);
154 } 122 }
155 123
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; 124 const media::VideoCaptureSessionId kFakeSessionId = -1;
160 125
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 126 } // namespace
167 127
168 namespace content { 128 namespace content {
169 129
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 130 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported
202 // video formats. 131 // video formats.
203 struct VideoCaptureManager::DeviceInfo { 132 struct VideoCaptureManager::DeviceInfo {
204 DeviceInfo(); 133 DeviceInfo();
205 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); 134 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor);
206 DeviceInfo(const DeviceInfo& other); 135 DeviceInfo(const DeviceInfo& other);
207 ~DeviceInfo(); 136 ~DeviceInfo();
208 DeviceInfo& operator=(const DeviceInfo& other); 137 DeviceInfo& operator=(const DeviceInfo& other);
209 138
210 media::VideoCaptureDeviceDescriptor descriptor; 139 media::VideoCaptureDeviceDescriptor descriptor;
(...skipping 17 matching lines...) Expand all
228 157
229 private: 158 private:
230 const int serial_id_; 159 const int serial_id_;
231 const media::VideoCaptureSessionId session_id_; 160 const media::VideoCaptureSessionId session_id_;
232 const media::VideoCaptureParams params_; 161 const media::VideoCaptureParams params_;
233 // Set to true if the device should be stopped before it has successfully 162 // Set to true if the device should be stopped before it has successfully
234 // been started. 163 // been started.
235 bool abort_start_; 164 bool abort_start_;
236 }; 165 };
237 166
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; 167 VideoCaptureManager::DeviceInfo::DeviceInfo() = default;
277 168
278 VideoCaptureManager::DeviceInfo::DeviceInfo( 169 VideoCaptureManager::DeviceInfo::DeviceInfo(
279 media::VideoCaptureDeviceDescriptor descriptor) 170 media::VideoCaptureDeviceDescriptor descriptor)
280 : descriptor(descriptor) {} 171 : descriptor(descriptor) {}
281 172
282 VideoCaptureManager::DeviceInfo::DeviceInfo( 173 VideoCaptureManager::DeviceInfo::DeviceInfo(
283 const VideoCaptureManager::DeviceInfo& other) = default; 174 const VideoCaptureManager::DeviceInfo& other) = default;
284 175
285 VideoCaptureManager::DeviceInfo::~DeviceInfo() = default; 176 VideoCaptureManager::DeviceInfo::~DeviceInfo() = default;
286 177
287 VideoCaptureManager::DeviceInfo& VideoCaptureManager::DeviceInfo::operator=( 178 VideoCaptureManager::DeviceInfo& VideoCaptureManager::DeviceInfo::operator=(
288 const VideoCaptureManager::DeviceInfo& other) = default; 179 const VideoCaptureManager::DeviceInfo& other) = default;
289 180
290 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( 181 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest(
291 int serial_id, 182 int serial_id,
292 media::VideoCaptureSessionId session_id, 183 media::VideoCaptureSessionId session_id,
293 const media::VideoCaptureParams& params) 184 const media::VideoCaptureParams& params)
294 : serial_id_(serial_id), 185 : serial_id_(serial_id),
295 session_id_(session_id), 186 session_id_(session_id),
296 params_(params), 187 params_(params),
297 abort_start_(false) { 188 abort_start_(false) {}
298 }
299 189
300 VideoCaptureManager::VideoCaptureManager( 190 VideoCaptureManager::VideoCaptureManager(
301 std::unique_ptr<media::VideoCaptureDeviceFactory> factory, 191 std::unique_ptr<media::VideoCaptureDeviceFactory> factory,
302 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) 192 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner)
303 : device_task_runner_(std::move(device_task_runner)), 193 : device_task_runner_(std::move(device_task_runner)),
304 new_capture_session_id_(1), 194 new_capture_session_id_(1),
305 video_capture_device_factory_(std::move(factory)) {} 195 video_capture_device_factory_(std::move(factory)) {}
306 196
307 VideoCaptureManager::~VideoCaptureManager() { 197 VideoCaptureManager::~VideoCaptureManager() {
308 DCHECK(devices_.empty()); 198 DCHECK(devices_.empty());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 devices_info_cache_); 248 devices_info_cache_);
359 // OK to use base::Unretained() since we own the VCDFactory and |this| is 249 // OK to use base::Unretained() since we own the VCDFactory and |this| is
360 // bound in |devices_enumerated_callback|. 250 // bound in |devices_enumerated_callback|.
361 device_task_runner_->PostTask( 251 device_task_runner_->PostTask(
362 FROM_HERE, 252 FROM_HERE,
363 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors, 253 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors,
364 base::Unretained(video_capture_device_factory_.get()), 254 base::Unretained(video_capture_device_factory_.get()),
365 devices_enumerated_callback)); 255 devices_enumerated_callback));
366 } 256 }
367 257
258 bool VideoCaptureManager::LookupDeviceDescriptor(
miu 2017/03/11 01:13:22 Suggestion for simplification: media::VideoCaptur
chfremer 2017/03/13 22:02:03 Done.
259 const std::string& id,
260 media::VideoCaptureDeviceDescriptor* descriptor) {
261 const DeviceInfo* found = GetDeviceInfoById(id);
262 if (!found)
263 return false;
264 *descriptor = found->descriptor;
265 return true;
266 }
267
368 int VideoCaptureManager::Open(const MediaStreamDevice& device) { 268 int VideoCaptureManager::Open(const MediaStreamDevice& device) {
369 DCHECK_CURRENTLY_ON(BrowserThread::IO); 269 DCHECK_CURRENTLY_ON(BrowserThread::IO);
370 270
371 // Generate a new id for the session being opened. 271 // Generate a new id for the session being opened.
372 const media::VideoCaptureSessionId capture_session_id = 272 const media::VideoCaptureSessionId capture_session_id =
373 new_capture_session_id_++; 273 new_capture_session_id_++;
374 274
375 DCHECK(sessions_.find(capture_session_id) == sessions_.end()); 275 DCHECK(sessions_.find(capture_session_id) == sessions_.end());
376 DVLOG(1) << "VideoCaptureManager::Open, id " << capture_session_id; 276 DVLOG(1) << "VideoCaptureManager::Open, id " << capture_session_id;
377 277
(...skipping 12 matching lines...) Expand all
390 void VideoCaptureManager::Close(int capture_session_id) { 290 void VideoCaptureManager::Close(int capture_session_id) {
391 DCHECK_CURRENTLY_ON(BrowserThread::IO); 291 DCHECK_CURRENTLY_ON(BrowserThread::IO);
392 DVLOG(1) << "VideoCaptureManager::Close, id " << capture_session_id; 292 DVLOG(1) << "VideoCaptureManager::Close, id " << capture_session_id;
393 293
394 SessionMap::iterator session_it = sessions_.find(capture_session_id); 294 SessionMap::iterator session_it = sessions_.find(capture_session_id);
395 if (session_it == sessions_.end()) { 295 if (session_it == sessions_.end()) {
396 NOTREACHED(); 296 NOTREACHED();
397 return; 297 return;
398 } 298 }
399 299
400 DeviceEntry* const existing_device = 300 VideoCaptureDeviceEntry* const existing_device =
401 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); 301 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id);
402 if (existing_device) { 302 if (existing_device) {
403 // Remove any client that is still using the session. This is safe to call 303 // Remove any client that is still using the session. This is safe to call
404 // even if there are no clients using the session. 304 // even if there are no clients using the session.
405 existing_device->video_capture_controller.StopSession(capture_session_id); 305 existing_device->StopSession(capture_session_id);
406 306
407 // StopSession() may have removed the last client, so we might need to 307 // StopSession() may have removed the last client, so we might need to
408 // close the device. 308 // close the device.
409 DestroyDeviceEntryIfNoClients(existing_device); 309 DestroyDeviceEntryIfNoClients(existing_device);
410 } 310 }
411 311
412 // Notify listeners asynchronously, and forget the session. 312 // Notify listeners asynchronously, and forget the session.
413 base::ThreadTaskRunnerHandle::Get()->PostTask( 313 base::ThreadTaskRunnerHandle::Get()->PostTask(
414 FROM_HERE, base::Bind(&VideoCaptureManager::OnClosed, this, 314 FROM_HERE, base::Bind(&VideoCaptureManager::OnClosed, this,
415 session_it->second.type, capture_session_id)); 315 session_it->second.type, capture_session_id));
416 sessions_.erase(session_it); 316 sessions_.erase(session_it);
417 } 317 }
418 318
419 void VideoCaptureManager::QueueStartDevice( 319 void VideoCaptureManager::QueueStartDevice(
420 media::VideoCaptureSessionId session_id, 320 media::VideoCaptureSessionId session_id,
421 DeviceEntry* entry, 321 VideoCaptureDeviceEntry* entry,
422 const media::VideoCaptureParams& params) { 322 const media::VideoCaptureParams& params) {
423 DCHECK_CURRENTLY_ON(BrowserThread::IO); 323 DCHECK_CURRENTLY_ON(BrowserThread::IO);
424 device_start_queue_.push_back( 324 device_start_queue_.push_back(
425 CaptureDeviceStartRequest(entry->serial_id, session_id, params)); 325 CaptureDeviceStartRequest(entry->serial_id(), session_id, params));
426 if (device_start_queue_.size() == 1) 326 if (device_start_queue_.size() == 1)
427 HandleQueuedStartRequest(); 327 HandleQueuedStartRequest();
428 } 328 }
429 329
430 void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) { 330 void VideoCaptureManager::DoStopDevice(VideoCaptureDeviceEntry* entry) {
431 DCHECK_CURRENTLY_ON(BrowserThread::IO); 331 DCHECK_CURRENTLY_ON(BrowserThread::IO);
432 // TODO(mcasas): use a helper function https://crbug.com/624854. 332 // TODO(mcasas): use a helper function https://crbug.com/624854.
433 DCHECK( 333 DCHECK(
434 std::find_if(devices_.begin(), devices_.end(), 334 std::find_if(
435 [entry](const std::unique_ptr<DeviceEntry>& device_entry) { 335 devices_.begin(), devices_.end(),
436 return device_entry.get() == entry; 336 [entry](const scoped_refptr<VideoCaptureDeviceEntry>& device_entry) {
437 }) != devices_.end()); 337 return device_entry.get() == entry;
338 }) != devices_.end());
438 339
439 // Find the matching start request. 340 // Find the matching start request.
440 for (DeviceStartQueue::reverse_iterator request = 341 for (DeviceStartQueue::reverse_iterator request =
441 device_start_queue_.rbegin(); 342 device_start_queue_.rbegin();
442 request != device_start_queue_.rend(); ++request) { 343 request != device_start_queue_.rend(); ++request) {
443 if (request->serial_id() == entry->serial_id) { 344 if (request->serial_id() == entry->serial_id()) {
444 request->set_abort_start(); 345 request->set_abort_start();
445 DVLOG(3) << "DoStopDevice, aborting start request for device " 346 DVLOG(3) << "DoStopDevice, aborting start request for device "
446 << entry->id << " serial_id = " << entry->serial_id; 347 << entry->id() << " serial_id = " << entry->serial_id();
447 return; 348 return;
448 } 349 }
449 } 350 }
450 351
451 const DeviceInfo* device_info = GetDeviceInfoById(entry->id); 352 const DeviceInfo* device_info = GetDeviceInfoById(entry->id());
452 if (device_info != nullptr) { 353 if (device_info != nullptr) {
453 for (auto& observer : capture_observers_) 354 for (auto& observer : capture_observers_)
454 observer.OnVideoCaptureStopped(device_info->descriptor.facing); 355 observer.OnVideoCaptureStopped(device_info->descriptor.facing);
455 } 356 }
456 357
457 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id 358 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id()
458 << " serial_id = " << entry->serial_id << "."; 359 << " serial_id = " << entry->serial_id() << ".";
459 entry->video_capture_controller.OnLog( 360 entry->OnLog(
460 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); 361 base::StringPrintf("Stopping device: id: %s", entry->id().c_str()));
461 entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr);
462 362
463 // |entry->video_capture_device| can be null if creating the device has 363 if (entry->HasDevice()) {
464 // failed. 364 // Since we may be removing |entry| from |devices_| while
465 if (entry->video_capture_device) { 365 // ReleaseDeviceAsnyc() is executing, we pass it shared ownership to
466 device_task_runner_->PostTask( 366 // |entry|.
467 FROM_HERE, 367 entry->ReleaseDeviceAsync(MakeScopedRefptrOwnership(
468 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, 368 GetDeviceEntrySharedRefBySerialId(entry->serial_id())));
469 base::Passed(&entry->video_capture_device)));
470 } 369 }
471 } 370 }
472 371
473 void VideoCaptureManager::HandleQueuedStartRequest() { 372 void VideoCaptureManager::HandleQueuedStartRequest() {
474 DCHECK_CURRENTLY_ON(BrowserThread::IO); 373 DCHECK_CURRENTLY_ON(BrowserThread::IO);
475 // Remove all start requests that have been aborted. 374 // Remove all start requests that have been aborted.
476 while (device_start_queue_.begin() != device_start_queue_.end() && 375 while (device_start_queue_.begin() != device_start_queue_.end() &&
477 device_start_queue_.begin()->abort_start()) { 376 device_start_queue_.begin()->abort_start()) {
478 device_start_queue_.pop_front(); 377 device_start_queue_.pop_front();
479 } 378 }
480 DeviceStartQueue::iterator request = device_start_queue_.begin(); 379 DeviceStartQueue::iterator request = device_start_queue_.begin();
481 if (request == device_start_queue_.end()) 380 if (request == device_start_queue_.end())
482 return; 381 return;
483 382
484 const int serial_id = request->serial_id(); 383 const int serial_id = request->serial_id();
485 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); 384 VideoCaptureDeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id);
486 DCHECK(entry); 385 DCHECK(entry);
487 386
488 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " 387 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = "
489 << entry->id << " start id = " << entry->serial_id; 388 << entry->id() << " start id = " << entry->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 entry while it is executing, we need to pass
493 392 // 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 auto context_reference = base::MakeUnique<OwnershipCollection>();
497 switch (entry->stream_type) { 396 context_reference->AttachOwnership(
498 case MEDIA_DEVICE_VIDEO_CAPTURE: { 397 MakeScopedRefptrOwnership(scoped_refptr<VideoCaptureManager>(this)));
499 // We look up the device id from the renderer in our local enumeration 398 context_reference->AttachOwnership(
500 // since the renderer does not have all the information that might be 399 MakeScopedRefptrOwnership(GetDeviceEntrySharedRefBySerialId(serial_id)));
miu 2017/03/11 01:13:22 Interesting. It feels like you're creating your ow
chfremer 2017/03/13 22:02:03 Interesting comparison of this mechanism to a base
501 // held in the browser-side VideoCaptureDevice::Name structure. 400 // TODO(chfremer): Check if request->params() can actually be different from
502 const DeviceInfo* found = GetDeviceInfoById(entry->id); 401 // entry->parameters, and simplify if this is not the case.
503 if (found) { 402 entry->CreateAndStartDeviceAsync(request->params(),
504 entry->video_capture_controller.OnLog( 403 static_cast<BuildableDeviceCallbacks*>(this),
505 base::StringPrintf("Starting device: id: %s, name: %s, api: %s", 404 std::move(context_reference));
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 } 405 }
558 406
559 void VideoCaptureManager::OnDeviceStarted( 407 void VideoCaptureManager::OnDeviceAboutToStart(
560 int serial_id, 408 media::VideoFacingMode facing_mode) {
561 std::unique_ptr<VideoCaptureDevice> device) { 409 for (auto& observer : capture_observers_)
410 observer.OnVideoCaptureStarted(facing_mode);
411 }
412
413 void VideoCaptureManager::OnDeviceStarted(VideoCaptureDeviceEntry* entry) {
562 DVLOG(3) << __func__; 414 DVLOG(3) << __func__;
563 DCHECK_CURRENTLY_ON(BrowserThread::IO); 415 DCHECK_CURRENTLY_ON(BrowserThread::IO);
564 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); 416 DCHECK(entry);
565 // |device| can be null if creation failed in 417 DCHECK_EQ(entry->serial_id(), device_start_queue_.begin()->serial_id());
566 // DoStartDeviceCaptureOnDeviceThread.
567 if (device_start_queue_.front().abort_start()) { 418 if (device_start_queue_.front().abort_start()) {
568 // The device is no longer wanted. Stop the device again. 419 // A request to release the device may have arrived during the asynchronous
569 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; 420 // device startup.
570 media::VideoCaptureDevice* device_ptr = device.get(); 421 DVLOG(3) << "Device release request has been issued while device was "
571 base::Closure closure = 422 << "starting up asynchronously.";
572 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, 423 entry->ReleaseDeviceAsync(MakeScopedRefptrOwnership(
miu 2017/03/11 01:13:22 ditto here: Feels like a done callback would work
chfremer 2017/03/13 22:02:03 See other reply.
573 base::Passed(&device)); 424 GetDeviceEntrySharedRefBySerialId(entry->serial_id())));
574 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) {
575 // PostTask failed. The device must be stopped anyway.
576 device_ptr->StopAndDeAllocate();
577 }
578 } else { 425 } else {
579 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); 426 if (entry->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 = 427 const media::VideoCaptureSessionId session_id =
595 device_start_queue_.front().session_id(); 428 device_start_queue_.front().session_id();
596 DCHECK(session_id != kFakeSessionId); 429 DCHECK(session_id != kFakeSessionId);
597 MaybePostDesktopCaptureWindowId(session_id); 430 MaybePostDesktopCaptureWindowId(session_id);
598 } 431 }
599 432
600 auto it = photo_request_queue_.begin(); 433 auto it = photo_request_queue_.begin();
601 while (it != photo_request_queue_.end()) { 434 while (it != photo_request_queue_.end()) {
602 auto request = it++; 435 auto request = it++;
603 DeviceEntry* maybe_entry = GetDeviceEntryBySessionId(request->first); 436 VideoCaptureDeviceEntry* maybe_entry =
604 if (maybe_entry && maybe_entry->video_capture_device) { 437 GetDeviceEntryBySessionId(request->first);
605 request->second.Run(maybe_entry->video_capture_device.get()); 438 if (maybe_entry && maybe_entry->HasDevice()) {
439 request->second.Run();
606 photo_request_queue_.erase(request); 440 photo_request_queue_.erase(request);
607 } 441 }
608 } 442 }
609 } 443 }
610 444
611 device_start_queue_.pop_front(); 445 device_start_queue_.pop_front();
612 HandleQueuedStartRequest(); 446 HandleQueuedStartRequest();
613 } 447 }
614 448
615 std::unique_ptr<media::VideoCaptureDevice> 449 void VideoCaptureManager::OnDeviceStartFailed(VideoCaptureDeviceEntry* entry) {
616 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( 450 const std::string log_message = base::StringPrintf(
617 const VideoCaptureDeviceDescriptor& descriptor, 451 "Starting device %s has failed. Maybe recently disconnected?",
618 const media::VideoCaptureParams& params, 452 entry->id().c_str());
619 std::unique_ptr<VideoCaptureDevice::Client> device_client) { 453 DLOG(ERROR) << log_message;
620 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); 454 entry->OnLog(log_message);
621 DCHECK(IsOnDeviceThread()); 455 entry->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 VideoCaptureDeviceEntry* entry = GetOrCreateDeviceEntry(session_id, params);
719 if (!entry) { 472 if (!entry) {
720 done_cb.Run(base::WeakPtr<VideoCaptureController>()); 473 done_cb.Run(base::WeakPtr<VideoCaptureController>());
721 return; 474 return;
722 } 475 }
723 476
724 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); 477 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE);
725 478
726 // First client starts the device. 479 // First client starts the device.
727 if (!entry->video_capture_controller.HasActiveClient() && 480 if (!entry->HasActiveClient() && !entry->HasPausedClient()) {
728 !entry->video_capture_controller.HasPausedClient()) { 481 DVLOG(1) << "VideoCaptureManager starting device (id = " << entry->id()
729 DVLOG(1) << "VideoCaptureManager starting device (type = " 482 << ")";
730 << entry->stream_type << ", id = " << entry->id << ")";
731 QueueStartDevice(session_id, entry, params); 483 QueueStartDevice(session_id, entry, params);
732 } 484 }
733 // Run the callback first, as AddClient() may trigger OnFrameInfo(). 485 // Run the callback first, as AddClient() may trigger OnFrameInfo().
734 done_cb.Run(entry->video_capture_controller.GetWeakPtrForIOThread()); 486 done_cb.Run(entry->GetControllerWeakPtrForIOThread());
735 entry->video_capture_controller.AddClient(client_id, client_handler, 487 entry->AddClient(client_id, client_handler, session_id, params);
736 session_id, params);
737 } 488 }
738 489
739 void VideoCaptureManager::StopCaptureForClient( 490 void VideoCaptureManager::StopCaptureForClient(
740 VideoCaptureController* controller, 491 VideoCaptureController* controller,
741 VideoCaptureControllerID client_id, 492 VideoCaptureControllerID client_id,
742 VideoCaptureControllerEventHandler* client_handler, 493 VideoCaptureControllerEventHandler* client_handler,
743 bool aborted_due_to_error) { 494 bool aborted_due_to_error) {
744 DCHECK_CURRENTLY_ON(BrowserThread::IO); 495 DCHECK_CURRENTLY_ON(BrowserThread::IO);
745 DCHECK(controller); 496 DCHECK(controller);
746 DCHECK(client_handler); 497 DCHECK(client_handler);
747 498
748 DeviceEntry* entry = GetDeviceEntryByController(controller); 499 VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller);
749 if (!entry) { 500 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 (entry->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 == entry->stream_type() &&
518 it.second.id == entry->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 |entry|, recheck.
770 entry = GetDeviceEntryByController(controller); 522 entry = GetDeviceEntryByController(controller);
771 if (!entry) 523 if (!entry)
772 return; 524 return;
773 break; 525 break;
774 } 526 }
775 } 527 }
776 } 528 }
777 529
778 // Detach client from controller. 530 // Detach client from controller.
779 const media::VideoCaptureSessionId session_id = 531 const media::VideoCaptureSessionId session_id =
780 controller->RemoveClient(client_id, client_handler); 532 controller->RemoveClient(client_id, client_handler);
781 DVLOG(1) << __func__ << ", session_id = " << session_id; 533 DVLOG(1) << __func__ << ", session_id = " << session_id;
782 534
783 // If controller has no more clients, delete controller and device. 535 // If controller has no more clients, delete controller and device.
784 DestroyDeviceEntryIfNoClients(entry); 536 DestroyDeviceEntryIfNoClients(entry);
785 } 537 }
786 538
787 void VideoCaptureManager::PauseCaptureForClient( 539 void VideoCaptureManager::PauseCaptureForClient(
788 VideoCaptureController* controller, 540 VideoCaptureController* controller,
789 VideoCaptureControllerID client_id, 541 VideoCaptureControllerID client_id,
790 VideoCaptureControllerEventHandler* client_handler) { 542 VideoCaptureControllerEventHandler* client_handler) {
791 DCHECK_CURRENTLY_ON(BrowserThread::IO); 543 DCHECK_CURRENTLY_ON(BrowserThread::IO);
792 DCHECK(controller); 544 DCHECK(controller);
793 DCHECK(client_handler); 545 DCHECK(client_handler);
794 DeviceEntry* entry = GetDeviceEntryByController(controller); 546 VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller);
795 if (!entry) 547 if (!entry)
796 NOTREACHED() << "Got Null entry while pausing capture"; 548 NOTREACHED() << "Got Null entry while pausing capture";
797 549
798 const bool had_active_client = controller->HasActiveClient(); 550 const bool had_active_client = controller->HasActiveClient();
799 controller->PauseClient(client_id, client_handler); 551 controller->PauseClient(client_id, client_handler);
800 if (!had_active_client || controller->HasActiveClient()) 552 if (!had_active_client || controller->HasActiveClient())
801 return; 553 return;
802 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { 554 if (entry->HasDevice() == false)
miu 2017/03/11 01:13:22 nit: if (!entry->HasDevice()) (and in multiple
chfremer 2017/03/13 22:02:03 Done.
803 device_task_runner_->PostTask( 555 return;
804 FROM_HERE, 556 entry->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 } 557 }
813 558
814 void VideoCaptureManager::ResumeCaptureForClient( 559 void VideoCaptureManager::ResumeCaptureForClient(
815 media::VideoCaptureSessionId session_id, 560 media::VideoCaptureSessionId session_id,
816 const media::VideoCaptureParams& params, 561 const media::VideoCaptureParams& params,
817 VideoCaptureController* controller, 562 VideoCaptureController* controller,
818 VideoCaptureControllerID client_id, 563 VideoCaptureControllerID client_id,
819 VideoCaptureControllerEventHandler* client_handler) { 564 VideoCaptureControllerEventHandler* client_handler) {
820 DCHECK_CURRENTLY_ON(BrowserThread::IO); 565 DCHECK_CURRENTLY_ON(BrowserThread::IO);
821 DCHECK(controller); 566 DCHECK(controller);
822 DCHECK(client_handler); 567 DCHECK(client_handler);
823 568
824 DeviceEntry* entry = GetDeviceEntryByController(controller); 569 VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller);
825 if (!entry) 570 if (!entry)
826 NOTREACHED() << "Got Null entry while resuming capture"; 571 NOTREACHED() << "Got Null entry while resuming capture";
827 572
828 const bool had_active_client = controller->HasActiveClient(); 573 const bool had_active_client = controller->HasActiveClient();
829 controller->ResumeClient(client_id, client_handler); 574 controller->ResumeClient(client_id, client_handler);
830 if (had_active_client || !controller->HasActiveClient()) 575 if (had_active_client || !controller->HasActiveClient())
831 return; 576 return;
832 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { 577 if (entry->HasDevice() == false)
833 device_task_runner_->PostTask( 578 return;
834 FROM_HERE, 579 entry->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 } 580 }
843 581
844 void VideoCaptureManager::RequestRefreshFrameForClient( 582 void VideoCaptureManager::RequestRefreshFrameForClient(
845 VideoCaptureController* controller) { 583 VideoCaptureController* controller) {
846 DCHECK_CURRENTLY_ON(BrowserThread::IO); 584 DCHECK_CURRENTLY_ON(BrowserThread::IO);
847 585
848 if (DeviceEntry* entry = GetDeviceEntryByController(controller)) { 586 if (VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller)) {
849 if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { 587 if (entry->HasDevice() == false)
850 device_task_runner_->PostTask( 588 return;
851 FROM_HERE, 589 entry->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 } 590 }
860 } 591 }
861 592
862 bool VideoCaptureManager::GetDeviceSupportedFormats( 593 bool VideoCaptureManager::GetDeviceSupportedFormats(
863 media::VideoCaptureSessionId capture_session_id, 594 media::VideoCaptureSessionId capture_session_id,
864 media::VideoCaptureFormats* supported_formats) { 595 media::VideoCaptureFormats* supported_formats) {
865 DCHECK_CURRENTLY_ON(BrowserThread::IO); 596 DCHECK_CURRENTLY_ON(BrowserThread::IO);
866 DCHECK(supported_formats->empty()); 597 DCHECK(supported_formats->empty());
867 598
868 SessionMap::iterator it = sessions_.find(capture_session_id); 599 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); 631 return GetDeviceFormatsInUse(it->second.type, it->second.id, formats_in_use);
901 } 632 }
902 633
903 bool VideoCaptureManager::GetDeviceFormatsInUse( 634 bool VideoCaptureManager::GetDeviceFormatsInUse(
904 MediaStreamType stream_type, 635 MediaStreamType stream_type,
905 const std::string& device_id, 636 const std::string& device_id,
906 media::VideoCaptureFormats* formats_in_use) { 637 media::VideoCaptureFormats* formats_in_use) {
907 DCHECK_CURRENTLY_ON(BrowserThread::IO); 638 DCHECK_CURRENTLY_ON(BrowserThread::IO);
908 DCHECK(formats_in_use->empty()); 639 DCHECK(formats_in_use->empty());
909 // Return the currently in-use format(s) of the device, if it's started. 640 // Return the currently in-use format(s) of the device, if it's started.
910 DeviceEntry* device_in_use = 641 VideoCaptureDeviceEntry* device_in_use =
911 GetDeviceEntryByTypeAndId(stream_type, device_id); 642 GetDeviceEntryByTypeAndId(stream_type, device_id);
912 if (device_in_use) { 643 if (device_in_use) {
913 // Currently only one format-in-use is supported at the VCC level. 644 // Currently only one format-in-use is supported at the VCC level.
914 formats_in_use->push_back( 645 formats_in_use->push_back(device_in_use->GetVideoCaptureFormat());
915 device_in_use->video_capture_controller.GetVideoCaptureFormat());
916 } 646 }
917 return true; 647 return true;
918 } 648 }
919 649
920 void VideoCaptureManager::SetDesktopCaptureWindowId( 650 void VideoCaptureManager::SetDesktopCaptureWindowId(
921 media::VideoCaptureSessionId session_id, 651 media::VideoCaptureSessionId session_id,
922 gfx::NativeViewId window_id) { 652 gfx::NativeViewId window_id) {
923 DCHECK_CURRENTLY_ON(BrowserThread::IO); 653 DCHECK_CURRENTLY_ON(BrowserThread::IO);
924 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; 654 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id;
925 655
926 notification_window_ids_[session_id] = window_id; 656 notification_window_ids_[session_id] = window_id;
927 MaybePostDesktopCaptureWindowId(session_id); 657 MaybePostDesktopCaptureWindowId(session_id);
928 } 658 }
929 659
930 void VideoCaptureManager::MaybePostDesktopCaptureWindowId( 660 void VideoCaptureManager::MaybePostDesktopCaptureWindowId(
931 media::VideoCaptureSessionId session_id) { 661 media::VideoCaptureSessionId session_id) {
932 SessionMap::iterator session_it = sessions_.find(session_id); 662 SessionMap::iterator session_it = sessions_.find(session_id);
933 if (session_it == sessions_.end()) 663 if (session_it == sessions_.end())
934 return; 664 return;
935 665
936 DeviceEntry* const existing_device = 666 VideoCaptureDeviceEntry* const existing_device =
937 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); 667 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id);
938 if (!existing_device) { 668 if (!existing_device) {
939 DVLOG(2) << "Failed to find an existing screen capture device."; 669 DVLOG(2) << "Failed to find an existing screen capture device.";
940 return; 670 return;
941 } 671 }
942 672
943 if (!existing_device->video_capture_device) { 673 if (!existing_device->HasDevice()) {
944 DVLOG(2) << "Screen capture device not yet started."; 674 DVLOG(2) << "Screen capture device not yet started.";
945 return; 675 return;
946 } 676 }
947 677
948 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); 678 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type());
949 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); 679 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id());
950 if (id.is_null()) 680 if (id.is_null())
951 return; 681 return;
952 682
953 auto window_id_it = notification_window_ids_.find(session_id); 683 auto window_id_it = notification_window_ids_.find(session_id);
954 if (window_id_it == notification_window_ids_.end()) { 684 if (window_id_it == notification_window_ids_.end()) {
955 DVLOG(2) << "Notification window id not set for screen capture."; 685 DVLOG(2) << "Notification window id not set for screen capture.";
956 return; 686 return;
957 } 687 }
958 688
959 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to 689 existing_device->SetDesktopCaptureWindowIdAsync(
960 // the device_task_runner_. This is safe since the device is destroyed on the 690 window_id_it->second,
961 // device_task_runner_. 691 MakeScopedRefptrOwnership(scoped_refptr<VideoCaptureManager>(this)));
962 device_task_runner_->PostTask(
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); 692 notification_window_ids_.erase(window_id_it);
969 } 693 }
970 694
971 void VideoCaptureManager::GetPhotoCapabilities( 695 void VideoCaptureManager::GetPhotoCapabilities(
972 int session_id, 696 int session_id,
973 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { 697 media::VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
974 DCHECK_CURRENTLY_ON(BrowserThread::IO); 698 DCHECK_CURRENTLY_ON(BrowserThread::IO);
975 699
976 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); 700 const VideoCaptureDeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
977 if (!entry) 701 if (!entry)
978 return; 702 return;
979 VideoCaptureDevice* device = entry->video_capture_device.get(); 703 if (entry->HasDevice()) {
980 if (device) { 704 entry->GetPhotoCapabilities(std::move(callback));
981 VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device);
982 return; 705 return;
983 } 706 }
984 // |entry| is known but |device| is nullptr, queue up a request for later. 707 // |entry| is known but |device| is nullptr, queue up a request for later.
985 photo_request_queue_.emplace_back( 708 photo_request_queue_.emplace_back(
986 session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this, 709 session_id, base::Bind(&VideoCaptureDeviceEntry::GetPhotoCapabilities,
987 base::Passed(&callback))); 710 base::Unretained(entry), 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 VideoCaptureDeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
997 if (!entry) 720 if (!entry)
998 return; 721 return;
999 VideoCaptureDevice* device = entry->video_capture_device.get(); 722 if (entry->HasDevice()) {
1000 if (device) { 723 entry->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 // |entry| is known but |device| is nullptr, 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(&VideoCaptureDeviceEntry::SetPhotoOptions,
1008 base::Passed(&callback), base::Passed(&settings))); 729 base::Unretained(entry), base::Passed(&settings),
730 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 VideoCaptureDeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
1017 if (!entry) 739 if (!entry)
1018 return; 740 return;
1019 VideoCaptureDevice* device = entry->video_capture_device.get(); 741 if (entry->HasDevice()) {
1020 if (device) { 742 entry->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 // |entry| is known but |device| is nullptr, 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, base::Bind(&VideoCaptureDeviceEntry::TakePhoto,
1027 base::Passed(&callback))); 748 base::Unretained(entry), base::Passed(&callback)));
1028 }
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 } 749 }
1037 750
1038 void VideoCaptureManager::OnOpened( 751 void VideoCaptureManager::OnOpened(
1039 MediaStreamType stream_type, 752 MediaStreamType stream_type,
1040 media::VideoCaptureSessionId capture_session_id) { 753 media::VideoCaptureSessionId capture_session_id) {
1041 DCHECK_CURRENTLY_ON(BrowserThread::IO); 754 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1042 for (auto& listener : listeners_) 755 for (auto& listener : listeners_)
1043 listener.Opened(stream_type, capture_session_id); 756 listener.Opened(stream_type, capture_session_id);
1044 } 757 }
1045 758
(...skipping 17 matching lines...) Expand all
1063 776
1064 // Walk the |devices_info_cache_| and produce a 777 // Walk the |devices_info_cache_| and produce a
1065 // media::VideoCaptureDeviceDescriptors for return purposes. 778 // media::VideoCaptureDeviceDescriptors for return purposes.
1066 media::VideoCaptureDeviceDescriptors devices; 779 media::VideoCaptureDeviceDescriptors devices;
1067 std::vector<std::tuple<media::VideoCaptureDeviceDescriptor, 780 std::vector<std::tuple<media::VideoCaptureDeviceDescriptor,
1068 media::VideoCaptureFormats>> 781 media::VideoCaptureFormats>>
1069 descriptors_and_formats; 782 descriptors_and_formats;
1070 for (const auto& it : devices_info_cache_) { 783 for (const auto& it : devices_info_cache_) {
1071 devices.emplace_back(it.descriptor); 784 devices.emplace_back(it.descriptor);
1072 descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats); 785 descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats);
1073 }
1074
1075 if (!descriptors_and_formats.empty()) {
1076 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities( 786 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities(
1077 descriptors_and_formats); 787 descriptors_and_formats);
1078 } 788 }
1079 789
1080 client_callback.Run(devices); 790 client_callback.Run(devices);
1081 } 791 }
1082 792
1083 bool VideoCaptureManager::IsOnDeviceThread() const { 793 bool VideoCaptureManager::IsOnDeviceThread() const {
1084 return device_task_runner_->BelongsToCurrentThread(); 794 return device_task_runner_->BelongsToCurrentThread();
1085 } 795 }
(...skipping 25 matching lines...) Expand all
1111 DeviceInfo device_info(it); 821 DeviceInfo device_info(it);
1112 video_capture_device_factory_->GetSupportedFormats( 822 video_capture_device_factory_->GetSupportedFormats(
1113 it, &device_info.supported_formats); 823 it, &device_info.supported_formats);
1114 ConsolidateCaptureFormats(&device_info.supported_formats); 824 ConsolidateCaptureFormats(&device_info.supported_formats);
1115 new_devices_info_cache.push_back(device_info); 825 new_devices_info_cache.push_back(device_info);
1116 } 826 }
1117 827
1118 on_devices_enumerated_callback.Run(new_devices_info_cache); 828 on_devices_enumerated_callback.Run(new_devices_info_cache);
1119 } 829 }
1120 830
1121 void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { 831 void VideoCaptureManager::DestroyDeviceEntryIfNoClients(
832 VideoCaptureDeviceEntry* entry) {
1122 DCHECK_CURRENTLY_ON(BrowserThread::IO); 833 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1123 // Removal of the last client stops the device. 834 // Removal of the last client stops the device.
1124 if (!entry->video_capture_controller.HasActiveClient() && 835 if (!entry->HasActiveClient() && !entry->HasPausedClient()) {
1125 !entry->video_capture_controller.HasPausedClient()) {
1126 DVLOG(1) << "VideoCaptureManager stopping device (type = " 836 DVLOG(1) << "VideoCaptureManager stopping device (type = "
1127 << entry->stream_type << ", id = " << entry->id << ")"; 837 << entry->stream_type() << ", id = " << entry->id() << ")";
1128 838
1129 // The DeviceEntry is removed from |devices_| immediately. The controller is 839 // The VideoCaptureDeviceEntry is removed from |devices_| immediately. The
1130 // deleted immediately, and the device is freed asynchronously. After this 840 // controller is deleted immediately, and the device is freed
1131 // point, subsequent requests to open this same device ID will create a new 841 // asynchronously. After this point, subsequent requests to open this same
1132 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. 842 // device ID will create a new VideoCaptureDeviceEntry,
843 // VideoCaptureController, and VideoCaptureDevice.
1133 DoStopDevice(entry); 844 DoStopDevice(entry);
1134 // TODO(mcasas): use a helper function https://crbug.com/624854. 845 // TODO(mcasas): use a helper function https://crbug.com/624854.
1135 DeviceEntries::iterator device_it = 846 DeviceEntries::iterator device_it = std::find_if(
1136 std::find_if(devices_.begin(), devices_.end(), 847 devices_.begin(), devices_.end(),
1137 [entry](const std::unique_ptr<DeviceEntry>& device_entry) { 848 [entry](const scoped_refptr<VideoCaptureDeviceEntry>& device_entry) {
1138 return device_entry.get() == entry; 849 return device_entry.get() == entry;
1139 }); 850 });
1140 devices_.erase(device_it); 851 devices_.erase(device_it);
1141 } 852 }
1142 } 853 }
1143 854
1144 VideoCaptureManager::DeviceEntry* 855 VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryBySessionId(
1145 VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) { 856 int session_id) {
1146 DCHECK_CURRENTLY_ON(BrowserThread::IO); 857 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1147 SessionMap::const_iterator session_it = sessions_.find(session_id); 858 SessionMap::const_iterator session_it = sessions_.find(session_id);
1148 if (session_it == sessions_.end()) 859 if (session_it == sessions_.end())
1149 return nullptr; 860 return nullptr;
1150 861
1151 return GetDeviceEntryByTypeAndId(session_it->second.type, 862 return GetDeviceEntryByTypeAndId(session_it->second.type,
1152 session_it->second.id); 863 session_it->second.id);
1153 } 864 }
1154 865
1155 VideoCaptureManager::DeviceEntry* 866 VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryByTypeAndId(
1156 VideoCaptureManager::GetDeviceEntryByTypeAndId(
1157 MediaStreamType type, 867 MediaStreamType type,
1158 const std::string& device_id) const { 868 const std::string& device_id) const {
1159 DCHECK_CURRENTLY_ON(BrowserThread::IO); 869 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1160 870
1161 for (const std::unique_ptr<DeviceEntry>& device : devices_) { 871 for (const auto& device : devices_) {
1162 if (type == device->stream_type && device_id == device->id) 872 if (type == device->stream_type() && device_id == device->id())
1163 return device.get(); 873 return device.get();
1164 } 874 }
1165 return nullptr; 875 return nullptr;
1166 } 876 }
1167 877
1168 VideoCaptureManager::DeviceEntry* 878 VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryByController(
1169 VideoCaptureManager::GetDeviceEntryByController(
1170 const VideoCaptureController* controller) const { 879 const VideoCaptureController* controller) const {
1171 DCHECK_CURRENTLY_ON(BrowserThread::IO); 880 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1172 881
1173 // Look up |controller| in |devices_|. 882 // Look up |controller| in |devices_|.
1174 for (const std::unique_ptr<DeviceEntry>& device : devices_) { 883 for (const auto& device : devices_) {
1175 if (&device->video_capture_controller == controller) 884 if (device->CorrespondsToController(controller))
1176 return device.get(); 885 return device.get();
1177 } 886 }
1178 return nullptr; 887 return nullptr;
1179 } 888 }
1180 889
1181 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId( 890 VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId(
1182 int serial_id) const { 891 int serial_id) const {
1183 DCHECK_CURRENTLY_ON(BrowserThread::IO); 892 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1184 893
1185 for (const std::unique_ptr<DeviceEntry>& device : devices_) { 894 for (const auto& device : devices_) {
1186 if (device->serial_id == serial_id) 895 if (device->serial_id() == serial_id)
1187 return device.get(); 896 return device.get();
1188 } 897 }
1189 return nullptr; 898 return nullptr;
1190 } 899 }
1191 900
901 scoped_refptr<VideoCaptureDeviceEntry>
902 VideoCaptureManager::GetDeviceEntrySharedRefBySerialId(int serial_id) const {
903 DCHECK_CURRENTLY_ON(BrowserThread::IO);
904
905 for (const auto& device : devices_) {
906 if (device->serial_id() == serial_id)
907 return device;
908 }
909 return nullptr;
910 }
911
1192 VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById( 912 VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById(
1193 const std::string& id) { 913 const std::string& id) {
1194 for (auto& it : devices_info_cache_) { 914 for (auto& it : devices_info_cache_) {
1195 if (it.descriptor.device_id == id) 915 if (it.descriptor.device_id == id)
1196 return &it; 916 return &it;
1197 } 917 }
1198 return nullptr; 918 return nullptr;
1199 } 919 }
1200 920
1201 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( 921 VideoCaptureDeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
1202 media::VideoCaptureSessionId capture_session_id, 922 media::VideoCaptureSessionId capture_session_id,
1203 const media::VideoCaptureParams& params) { 923 const media::VideoCaptureParams& params) {
1204 DCHECK_CURRENTLY_ON(BrowserThread::IO); 924 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1205 925
1206 SessionMap::iterator session_it = sessions_.find(capture_session_id); 926 SessionMap::iterator session_it = sessions_.find(capture_session_id);
1207 if (session_it == sessions_.end()) 927 if (session_it == sessions_.end())
1208 return nullptr; 928 return nullptr;
1209 const MediaStreamDevice& device_info = session_it->second; 929 const MediaStreamDevice& device_info = session_it->second;
1210 930
1211 // Check if another session has already opened this device. If so, just 931 // Check if another session has already opened this device. If so, just
1212 // use that opened device. 932 // use that opened device.
1213 DeviceEntry* const existing_device = 933 VideoCaptureDeviceEntry* const existing_device =
1214 GetDeviceEntryByTypeAndId(device_info.type, device_info.id); 934 GetDeviceEntryByTypeAndId(device_info.type, device_info.id);
1215 if (existing_device) { 935 if (existing_device) {
1216 DCHECK_EQ(device_info.type, existing_device->stream_type); 936 DCHECK_EQ(device_info.type, existing_device->stream_type());
1217 return existing_device; 937 return existing_device;
1218 } 938 }
1219 939
1220 devices_.emplace_back( 940 VideoCaptureDeviceEntry* new_device_entry = new VideoCaptureDeviceEntry(
1221 new DeviceEntry(device_info.type, device_info.id, params)); 941 device_info.id, device_info.type, params,
1222 return devices_.back().get(); 942 base::MakeUnique<InProcessBuildableVideoCaptureDevice>(
1223 } 943 device_task_runner_, video_capture_device_factory_.get()));
1224 944 devices_.emplace_back(new_device_entry);
1225 void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread( 945 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 } 946 }
1271 947
1272 base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration( 948 base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration(
1273 const std::string& device_id) { 949 const std::string& device_id) {
1274 VideoCaptureManager::DeviceInfo* info = GetDeviceInfoById(device_id); 950 VideoCaptureManager::DeviceInfo* info = GetDeviceInfoById(device_id);
1275 if (!info) 951 if (!info)
1276 return base::Optional<CameraCalibration>(); 952 return base::Optional<CameraCalibration>();
1277 return info->descriptor.camera_calibration; 953 return info->descriptor.camera_calibration;
1278 } 954 }
1279 955
(...skipping 12 matching lines...) Expand all
1292 ReleaseDevices(); 968 ReleaseDevices();
1293 application_state_has_running_activities_ = false; 969 application_state_has_running_activities_ = false;
1294 } 970 }
1295 } 971 }
1296 972
1297 void VideoCaptureManager::ReleaseDevices() { 973 void VideoCaptureManager::ReleaseDevices() {
1298 DCHECK_CURRENTLY_ON(BrowserThread::IO); 974 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1299 975
1300 for (auto& entry : devices_) { 976 for (auto& entry : devices_) {
1301 // Do not stop Content Video Capture devices, e.g. Tab or Screen capture. 977 // Do not stop Content Video Capture devices, e.g. Tab or Screen capture.
1302 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) 978 if (entry->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE)
1303 continue; 979 continue;
1304 980
1305 DoStopDevice(entry.get()); 981 DoStopDevice(entry.get());
1306 } 982 }
1307 } 983 }
1308 984
1309 void VideoCaptureManager::ResumeDevices() { 985 void VideoCaptureManager::ResumeDevices() {
1310 DCHECK_CURRENTLY_ON(BrowserThread::IO); 986 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1311 987
1312 for (auto& entry : devices_) { 988 for (auto& entry : devices_) {
1313 // Do not resume Content Video Capture devices, e.g. Tab or Screen capture. 989 // Do not resume Content Video Capture devices, e.g. Tab or Screen capture.
1314 // Do not try to restart already running devices. 990 // Do not try to restart already running devices.
1315 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE || 991 if (entry->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE ||
1316 entry->video_capture_device) 992 entry->HasDevice())
1317 continue; 993 continue;
1318 994
1319 // Check if the device is already in the start queue. 995 // Check if the device is already in the start queue.
1320 bool device_in_queue = false; 996 bool device_in_queue = false;
1321 for (auto& request : device_start_queue_) { 997 for (auto& request : device_start_queue_) {
1322 if (request.serial_id() == entry->serial_id) { 998 if (request.serial_id() == entry->serial_id()) {
1323 device_in_queue = true; 999 device_in_queue = true;
1324 break; 1000 break;
1325 } 1001 }
1326 } 1002 }
1327 1003
1328 if (!device_in_queue) { 1004 if (!device_in_queue) {
1329 // Session ID is only valid for Screen capture. So we can fake it to 1005 // Session ID is only valid for Screen capture. So we can fake it to
1330 // resume video capture devices here. 1006 // resume video capture devices here.
1331 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); 1007 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters());
1332 } 1008 }
1333 } 1009 }
1334 } 1010 }
1335 #endif // defined(OS_ANDROID) 1011 #endif // defined(OS_ANDROID)
1336 1012
1337 } // namespace content 1013 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698