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

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

Issue 29423003: Added video capture capabilities retrieval and caching to VideoCaptureManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: perkj@'s comments Created 7 years, 1 month 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 <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 21 matching lines...) Expand all
32 VideoCaptureManager::DeviceEntry::DeviceEntry( 32 VideoCaptureManager::DeviceEntry::DeviceEntry(
33 MediaStreamType stream_type, 33 MediaStreamType stream_type,
34 const std::string& id, 34 const std::string& id,
35 scoped_ptr<VideoCaptureController> controller) 35 scoped_ptr<VideoCaptureController> controller)
36 : stream_type(stream_type), 36 : stream_type(stream_type),
37 id(id), 37 id(id),
38 video_capture_controller(controller.Pass()) {} 38 video_capture_controller(controller.Pass()) {}
39 39
40 VideoCaptureManager::DeviceEntry::~DeviceEntry() {} 40 VideoCaptureManager::DeviceEntry::~DeviceEntry() {}
41 41
42 VideoCaptureManager::DeviceInfo::DeviceInfo() {}
43
44 VideoCaptureManager::DeviceInfo::DeviceInfo(
45 const media::VideoCaptureDevice::Name& name,
46 const media::VideoCaptureCapabilities& capabilities)
47 : device_in_use_(false),
48 capability_in_use_(),
49 name_(name),
50 capabilities_(capabilities) {}
51
52 VideoCaptureManager::DeviceInfo::~DeviceInfo() {}
53
42 VideoCaptureManager::VideoCaptureManager() 54 VideoCaptureManager::VideoCaptureManager()
43 : listener_(NULL), 55 : listener_(NULL),
44 new_capture_session_id_(1), 56 new_capture_session_id_(1),
45 use_fake_device_(false) { 57 use_fake_device_(false) {
46 } 58 }
47 59
48 VideoCaptureManager::~VideoCaptureManager() { 60 VideoCaptureManager::~VideoCaptureManager() {
49 DCHECK(devices_.empty()); 61 DCHECK(devices_.empty());
50 } 62 }
51 63
52 void VideoCaptureManager::Register(MediaStreamProviderListener* listener, 64 void VideoCaptureManager::Register(MediaStreamProviderListener* listener,
53 base::MessageLoopProxy* device_thread_loop) { 65 base::MessageLoopProxy* device_thread_loop) {
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
55 DCHECK(!listener_); 67 DCHECK(!listener_);
56 DCHECK(!device_loop_.get()); 68 DCHECK(!device_loop_.get());
57 listener_ = listener; 69 listener_ = listener;
58 device_loop_ = device_thread_loop; 70 device_loop_ = device_thread_loop;
59 } 71 }
60 72
61 void VideoCaptureManager::Unregister() { 73 void VideoCaptureManager::Unregister() {
62 DCHECK(listener_); 74 DCHECK(listener_);
63 listener_ = NULL; 75 listener_ = NULL;
64 } 76 }
65 77
66 void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) { 78 void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) {
67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
68 DVLOG(1) << "VideoCaptureManager::EnumerateDevices, type " << stream_type; 80 DVLOG(1) << "VideoCaptureManager::EnumerateDevices, type " << stream_type;
69 DCHECK(listener_); 81 DCHECK(listener_);
70 base::PostTaskAndReplyWithResult( 82 base::PostTaskAndReplyWithResult(
71 device_loop_, FROM_HERE, 83 device_loop_,
72 base::Bind(&VideoCaptureManager::GetAvailableDevicesOnDeviceThread, this, 84 FROM_HERE,
85 base::Bind(&VideoCaptureManager::GetAvailableDevicesOnDeviceThread,
86 this,
73 stream_type), 87 stream_type),
74 base::Bind(&VideoCaptureManager::OnDevicesEnumerated, this, stream_type)); 88 base::Bind(
89 &VideoCaptureManager::OnDeviceNamesEnumerated, this, stream_type));
75 } 90 }
76 91
77 int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) { 92 int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
79 DCHECK(listener_); 94 DCHECK(listener_);
80 95
81 // Generate a new id for the session being opened. 96 // Generate a new id for the session being opened.
82 const int capture_session_id = new_capture_session_id_++; 97 const int capture_session_id = new_capture_session_id_++;
83 98
84 DCHECK(sessions_.find(capture_session_id) == sessions_.end()); 99 DCHECK(sessions_.find(capture_session_id) == sessions_.end());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 capture_session_id)); 141 capture_session_id));
127 sessions_.erase(session_it); 142 sessions_.erase(session_it);
128 } 143 }
129 144
130 void VideoCaptureManager::UseFakeDevice() { 145 void VideoCaptureManager::UseFakeDevice() {
131 use_fake_device_ = true; 146 use_fake_device_ = true;
132 } 147 }
133 148
134 void VideoCaptureManager::DoStartDeviceOnDeviceThread( 149 void VideoCaptureManager::DoStartDeviceOnDeviceThread(
135 DeviceEntry* entry, 150 DeviceEntry* entry,
151 const media::VideoCaptureDevice::Name* device_name,
136 const media::VideoCaptureCapability& capture_params, 152 const media::VideoCaptureCapability& capture_params,
137 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { 153 scoped_ptr<media::VideoCaptureDevice::Client> device_client) {
138 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); 154 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
139 DCHECK(IsOnDeviceThread()); 155 DCHECK(IsOnDeviceThread());
140 156
141 scoped_ptr<media::VideoCaptureDevice> video_capture_device; 157 scoped_ptr<media::VideoCaptureDevice> video_capture_device;
142 switch (entry->stream_type) { 158 switch (entry->stream_type) {
143 case MEDIA_DEVICE_VIDEO_CAPTURE: { 159 case MEDIA_DEVICE_VIDEO_CAPTURE: {
144 // We look up the device id from the renderer in our local enumeration 160 // We look up the device id from the renderer in our local enumeration
145 // since the renderer does not have all the information that might be 161 // since the renderer does not have all the information that might be
146 // held in the browser-side VideoCaptureDevice::Name structure. 162 // held in the browser-side VideoCaptureDevice::Name structure.
147 media::VideoCaptureDevice::Name* found = 163 if (device_name) {
148 video_capture_devices_.FindById(entry->id); 164 video_capture_device.reset(use_fake_device_
149 if (found) { 165 ? media::FakeVideoCaptureDevice::Create(*device_name)
150 video_capture_device.reset(use_fake_device_ ? 166 : media::VideoCaptureDevice::Create(*device_name));
151 media::FakeVideoCaptureDevice::Create(*found) :
152 media::VideoCaptureDevice::Create(*found));
153 } 167 }
154 break; 168 break;
155 } 169 }
156 case MEDIA_TAB_VIDEO_CAPTURE: { 170 case MEDIA_TAB_VIDEO_CAPTURE: {
157 video_capture_device.reset( 171 video_capture_device.reset(
158 WebContentsVideoCaptureDevice::Create(entry->id)); 172 WebContentsVideoCaptureDevice::Create(entry->id));
159 break; 173 break;
160 } 174 }
161 case MEDIA_DESKTOP_VIDEO_CAPTURE: { 175 case MEDIA_DESKTOP_VIDEO_CAPTURE: {
162 #if defined(ENABLE_SCREEN_CAPTURE) 176 #if defined(ENABLE_SCREEN_CAPTURE)
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 DVLOG(1) << "VideoCaptureManager starting device (type = " 223 DVLOG(1) << "VideoCaptureManager starting device (type = "
210 << entry->stream_type << ", id = " << entry->id << ")"; 224 << entry->stream_type << ", id = " << entry->id << ")";
211 225
212 media::VideoCaptureCapability params_as_capability; 226 media::VideoCaptureCapability params_as_capability;
213 params_as_capability.width = params.requested_format.width; 227 params_as_capability.width = params.requested_format.width;
214 params_as_capability.height = params.requested_format.height; 228 params_as_capability.height = params.requested_format.height;
215 params_as_capability.frame_rate = params.requested_format.frame_rate; 229 params_as_capability.frame_rate = params.requested_format.frame_rate;
216 params_as_capability.frame_size_type = 230 params_as_capability.frame_size_type =
217 params.requested_format.frame_size_type; 231 params.requested_format.frame_size_type;
218 232
233 DeviceInfo* found = FindDeviceInfoById(entry->id);
234 if (found) {
235 found->device_in_use_ = true;
ncarter (slow) 2013/11/07 22:43:01 The VideoCaptureManager already knows whether a pa
mcasas 2013/11/08 02:45:21 That's true. It implies an extra search, but that'
236 found->capability_in_use_ = params_as_capability;
ncarter (slow) 2013/11/07 22:43:01 Would it be better to just cache the Capability in
mcasas 2013/11/08 02:45:21 Struct DeviceEntry and struct DeviceInfo actually
237 }
219 device_loop_->PostTask(FROM_HERE, base::Bind( 238 device_loop_->PostTask(FROM_HERE, base::Bind(
220 &VideoCaptureManager::DoStartDeviceOnDeviceThread, this, 239 &VideoCaptureManager::DoStartDeviceOnDeviceThread, this,
221 entry, params_as_capability, 240 entry,
241 (found ? & found->name_ : NULL),
242 params_as_capability,
222 base::Passed(entry->video_capture_controller->NewDeviceClient()))); 243 base::Passed(entry->video_capture_controller->NewDeviceClient())));
223 } 244 }
224 // Run the callback first, as AddClient() may trigger OnFrameInfo(). 245 // Run the callback first, as AddClient() may trigger OnFrameInfo().
225 done_cb.Run(entry->video_capture_controller->GetWeakPtr()); 246 done_cb.Run(entry->video_capture_controller->GetWeakPtr());
226 entry->video_capture_controller->AddClient(client_id, 247 entry->video_capture_controller->AddClient(client_id,
227 client_handler, 248 client_handler,
228 client_render_process, 249 client_render_process,
229 params); 250 params);
230 } 251 }
231 252
(...skipping 13 matching lines...) Expand all
245 266
246 // Detach client from controller. 267 // Detach client from controller.
247 int session_id = controller->RemoveClient(client_id, client_handler); 268 int session_id = controller->RemoveClient(client_id, client_handler);
248 DVLOG(1) << "VideoCaptureManager::StopCaptureForClient, session_id = " 269 DVLOG(1) << "VideoCaptureManager::StopCaptureForClient, session_id = "
249 << session_id; 270 << session_id;
250 271
251 // If controller has no more clients, delete controller and device. 272 // If controller has no more clients, delete controller and device.
252 DestroyDeviceEntryIfNoClients(entry); 273 DestroyDeviceEntryIfNoClients(entry);
253 } 274 }
254 275
276 void VideoCaptureManager::GetDeviceCapabilities(
ncarter (slow) 2013/11/07 22:43:01 How does the client of this API know when to call
mcasas 2013/11/08 02:45:21 Yes exactly. There's a comment in the header file:
277 int capture_session_id,
278 media::VideoCaptureCapabilities* capabilities) {
279 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
280 capabilities->clear();
281
282 std::map<int, MediaStreamDevice>::iterator it =
283 sessions_.find(capture_session_id);
284 DCHECK(it != sessions_.end());
285 DVLOG(1) << "GetDeviceCapabilities for device: " << it->second.name;
286
287 DeviceInfo* device = FindDeviceInfoById(it->second.id);
288 if (device) {
289 if (device->device_in_use_)
290 capabilities->push_back(device->capability_in_use_);
291 else
292 *capabilities = device->capabilities_;
293 }
294 }
295
255 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) { 296 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) {
256 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); 297 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
257 DCHECK(IsOnDeviceThread()); 298 DCHECK(IsOnDeviceThread());
258 if (entry->video_capture_device) { 299 if (entry->video_capture_device) {
259 entry->video_capture_device->StopAndDeAllocate(); 300 entry->video_capture_device->StopAndDeAllocate();
260 } 301 }
261 entry->video_capture_device.reset(); 302 entry->video_capture_device.reset();
262 } 303 }
263 304
264 void VideoCaptureManager::OnOpened(MediaStreamType stream_type, 305 void VideoCaptureManager::OnOpened(MediaStreamType stream_type,
265 int capture_session_id) { 306 int capture_session_id) {
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
267 if (!listener_) { 308 if (!listener_) {
268 // Listener has been removed. 309 // Listener has been removed.
269 return; 310 return;
270 } 311 }
271 listener_->Opened(stream_type, capture_session_id); 312 listener_->Opened(stream_type, capture_session_id);
272 } 313 }
273 314
274 void VideoCaptureManager::OnClosed(MediaStreamType stream_type, 315 void VideoCaptureManager::OnClosed(MediaStreamType stream_type,
275 int capture_session_id) { 316 int capture_session_id) {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
277 if (!listener_) { 318 if (!listener_) {
278 // Listener has been removed. 319 // Listener has been removed.
279 return; 320 return;
280 } 321 }
281 listener_->Closed(stream_type, capture_session_id); 322 listener_->Closed(stream_type, capture_session_id);
282 } 323 }
283 324
284 void VideoCaptureManager::OnDevicesEnumerated( 325 void VideoCaptureManager::OnDeviceNamesEnumerated(
285 MediaStreamType stream_type, 326 MediaStreamType stream_type,
286 const media::VideoCaptureDevice::Names& device_names) { 327 const media::VideoCaptureDevice::Names& names_snapshot) {
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
288
289 if (!listener_) { 329 if (!listener_) {
ncarter (slow) 2013/11/07 22:43:01 Why do we check the listener_, if we're not invoki
mcasas 2013/11/08 02:45:21 It's used in OnDeviceNameAndCapabilitiesEnumerated
290 // Listener has been removed. 330 // Listener has been removed.
291 return; 331 return;
292 } 332 }
293 333
294 // Transform from VCD::Name to StreamDeviceInfo. 334 // Eliminate from |devices_info_cache_| all devices not in the snapshot.
295 StreamDeviceInfoArray devices; 335 ScopedVector<DeviceInfo>::iterator it_device_info =
296 for (media::VideoCaptureDevice::Names::const_iterator it = 336 devices_info_cache_.begin();
297 device_names.begin(); it != device_names.end(); ++it) { 337 while(it_device_info != devices_info_cache_.end()) {
ncarter (slow) 2013/11/07 22:43:01 space after while
mcasas 2013/11/08 02:45:21 Done.
298 devices.push_back(StreamDeviceInfo( 338 media::VideoCaptureDevice::Names::const_iterator it;
299 stream_type, it->GetNameAndModel(), it->id())); 339 for (it = names_snapshot.begin(); it != names_snapshot.end(); ++it) {
340 if ((*it_device_info)->name_.id() == it->id())
341 break;
342 }
343 if (it == names_snapshot.end())
344 devices_info_cache_.erase(it_device_info++);
345 else
346 ++it_device_info;
300 } 347 }
301 348
302 listener_->DevicesEnumerated(stream_type, devices); 349 // Truly new devices are put in |new_device_names|, and we need to retrieve
350 // their capabilities.
351 media::VideoCaptureDevice::Names new_device_names;
352 for (media::VideoCaptureDevice::Names::const_iterator it =
353 names_snapshot.begin(); it != names_snapshot.end(); ++it) {
354 DeviceInfo* device_info = FindDeviceInfoById(it->id());
355 if (!device_info)
356 new_device_names.push_back(*it);
357 }
358 base::PostTaskAndReplyWithResult(
359 device_loop_, FROM_HERE,
360 base::Bind(&VideoCaptureManager::GetDevicesCapabilitiesOnDeviceThread,
361 this, new_device_names),
362 base::Bind(&VideoCaptureManager::OnDeviceNameAndCapabilitiesEnumerated,
363 this, stream_type));
364 }
365
366 void VideoCaptureManager::OnDeviceNameAndCapabilitiesEnumerated(
367 MediaStreamType stream_type,
368 ScopedVector<DeviceInfo> new_devices_info) {
369 DVLOG(1) << "OnDeviceNameAndCapabilitiesEnumerated, #new devices: "
370 << new_devices_info.size();
371
372 ScopedVector<DeviceInfo>::iterator it = new_devices_info.begin();
373 while (it != new_devices_info.end()) {
374 devices_info_cache_.push_back(*it);
375 it = new_devices_info.weak_erase(it);
376 }
377
378 // Walk the |devices_info_cache_|| and transform from VCD::Name to
ncarter (slow) 2013/11/07 22:43:01 || -> |
mcasas 2013/11/08 02:45:21 Done.
379 // StreamDeviceInfo for return purposes.
380 StreamDeviceInfoArray devices;
381 for (ScopedVector<DeviceInfo>::const_iterator it =
382 devices_info_cache_.begin();
383 it != devices_info_cache_.end(); ++it) {
perkj_chrome 2013/11/07 10:49:11 nit: indentation
mcasas 2013/11/07 17:14:30 Ok, clang-format for Chromium style, and we leave
384 devices.push_back(StreamDeviceInfo(
385 stream_type, (*it)->name_.GetNameAndModel(), (*it)->name_.id()));
386 }
387 // |listener_| might have disappeared while we were scanning the devices.
388 if(listener_)
ncarter (slow) 2013/11/07 22:43:01 space after the if
mcasas 2013/11/08 02:45:21 Done.
389 listener_->DevicesEnumerated(stream_type, devices);
303 } 390 }
304 391
305 bool VideoCaptureManager::IsOnDeviceThread() const { 392 bool VideoCaptureManager::IsOnDeviceThread() const {
306 return device_loop_->BelongsToCurrentThread(); 393 return device_loop_->BelongsToCurrentThread();
307 } 394 }
308 395
309 media::VideoCaptureDevice::Names 396 media::VideoCaptureDevice::Names
310 VideoCaptureManager::GetAvailableDevicesOnDeviceThread( 397 VideoCaptureManager::GetAvailableDevicesOnDeviceThread(
311 MediaStreamType stream_type) { 398 MediaStreamType stream_type) {
312 SCOPED_UMA_HISTOGRAM_TIMER( 399 SCOPED_UMA_HISTOGRAM_TIMER(
313 "Media.VideoCaptureManager.GetAvailableDevicesTime"); 400 "Media.VideoCaptureManager.GetAvailableDevicesTime");
314 DCHECK(IsOnDeviceThread()); 401 DCHECK(IsOnDeviceThread());
315 media::VideoCaptureDevice::Names result; 402 media::VideoCaptureDevice::Names names;
316 403
317 switch (stream_type) { 404 switch (stream_type) {
318 case MEDIA_DEVICE_VIDEO_CAPTURE: 405 case MEDIA_DEVICE_VIDEO_CAPTURE:
319 // Cache the latest enumeration of video capture devices. 406 if (!use_fake_device_)
320 // We'll refer to this list again in OnOpen to avoid having to 407 media::VideoCaptureDevice::GetDeviceNames(&names);
321 // enumerate the devices again. 408 else
322 if (!use_fake_device_) { 409 media::FakeVideoCaptureDevice::GetDeviceNames(&names);
323 media::VideoCaptureDevice::GetDeviceNames(&result);
324 } else {
325 media::FakeVideoCaptureDevice::GetDeviceNames(&result);
326 }
327
328 // TODO(nick): The correctness of device start depends on this cache being
329 // maintained, but it seems a little odd to keep a cache here. Can we
330 // eliminate it?
331 video_capture_devices_ = result;
332 break; 410 break;
333 411
334 case MEDIA_DESKTOP_VIDEO_CAPTURE: 412 case MEDIA_DESKTOP_VIDEO_CAPTURE:
335 // Do nothing. 413 // Do nothing.
336 break; 414 break;
337 415
338 default: 416 default:
339 NOTREACHED(); 417 NOTREACHED();
340 break; 418 break;
341 } 419 }
342 return result; 420 return names;
421 }
422
423 ScopedVector<VideoCaptureManager::DeviceInfo>
424 VideoCaptureManager::GetDevicesCapabilitiesOnDeviceThread(
425 const media::VideoCaptureDevice::Names& device_names) {
426 DCHECK(IsOnDeviceThread());
427 DVLOG(1) << "GetDevicesCapabilitiesOnDeviceThread";
428
429 ScopedVector<DeviceInfo> device_info_vector;
430 for (media::VideoCaptureDevice::Names::const_iterator it =
431 device_names.begin(); it != device_names.end(); ++it) {
432 media::VideoCaptureCapabilities capabilities;
433 DeviceInfo* device_info = new DeviceInfo((*it),
434 media::VideoCaptureCapabilities());
435 if (!use_fake_device_) {
436 media::VideoCaptureDevice::GetDeviceSupportedFormats(*it,
437 &(device_info->capabilities_));
438 } else {
439 media::FakeVideoCaptureDevice::GetDeviceSupportedFormats(*it,
440 &(device_info->capabilities_));
441 }
442 device_info_vector.push_back(device_info);
443 }
444 return device_info_vector.Pass();
343 } 445 }
344 446
345 VideoCaptureManager::DeviceEntry* 447 VideoCaptureManager::DeviceEntry*
346 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice( 448 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice(
347 const MediaStreamDevice& device_info) { 449 const MediaStreamDevice& device_info) {
348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 450 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
349 451
350 for (DeviceEntries::iterator it = devices_.begin(); 452 for (DeviceEntries::iterator it = devices_.begin();
351 it != devices_.end(); ++it) { 453 it != devices_.end(); ++it) {
352 DeviceEntry* device = *it; 454 DeviceEntry* device = *it;
(...skipping 26 matching lines...) Expand all
379 << entry->stream_type << ", id = " << entry->id << ")"; 481 << entry->stream_type << ", id = " << entry->id << ")";
380 482
381 // The DeviceEntry is removed from |devices_| immediately. The controller is 483 // The DeviceEntry is removed from |devices_| immediately. The controller is
382 // deleted immediately, and the device is freed asynchronously. After this 484 // deleted immediately, and the device is freed asynchronously. After this
383 // point, subsequent requests to open this same device ID will create a new 485 // point, subsequent requests to open this same device ID will create a new
384 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. 486 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice.
385 devices_.erase(entry); 487 devices_.erase(entry);
386 entry->video_capture_controller.reset(); 488 entry->video_capture_controller.reset();
387 device_loop_->PostTask( 489 device_loop_->PostTask(
388 FROM_HERE, 490 FROM_HERE,
389 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, 491 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread,
492 this,
390 base::Owned(entry))); 493 base::Owned(entry)));
494 DeviceInfo* device_info = FindDeviceInfoById(entry->id);
495 if (device_info)
496 device_info->device_in_use_ = false;
391 } 497 }
392 } 498 }
393 499
394 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( 500 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
395 int capture_session_id) { 501 int capture_session_id) {
396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 502 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
397 503
398 std::map<int, MediaStreamDevice>::iterator session_it = 504 std::map<int, MediaStreamDevice>::iterator session_it =
399 sessions_.find(capture_session_id); 505 sessions_.find(capture_session_id);
400 if (session_it == sessions_.end()) { 506 if (session_it == sessions_.end()) {
(...skipping 12 matching lines...) Expand all
413 519
414 scoped_ptr<VideoCaptureController> video_capture_controller( 520 scoped_ptr<VideoCaptureController> video_capture_controller(
415 new VideoCaptureController()); 521 new VideoCaptureController());
416 DeviceEntry* new_device = new DeviceEntry(device_info.type, 522 DeviceEntry* new_device = new DeviceEntry(device_info.type,
417 device_info.id, 523 device_info.id,
418 video_capture_controller.Pass()); 524 video_capture_controller.Pass());
419 devices_.insert(new_device); 525 devices_.insert(new_device);
420 return new_device; 526 return new_device;
421 } 527 }
422 528
529 VideoCaptureManager::DeviceInfo* VideoCaptureManager::FindDeviceInfoById(
530 const std::string& id) {
531 for (ScopedVector<DeviceInfo>::iterator it = devices_info_cache_.begin();
532 it != devices_info_cache_.end(); ++it) {
533 if ((*it)->name_.id() == id)
534 return *it;
535 }
536 return NULL;
537 }
538
423 } // namespace content 539 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698