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

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: tommi@'s round of comments addressed. More UT. Capabilities reset on closing device. 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 : name_(name), capabilities_(capabilities) {}
48
49 VideoCaptureManager::DeviceInfo::~DeviceInfo() {}
50
42 VideoCaptureManager::VideoCaptureManager() 51 VideoCaptureManager::VideoCaptureManager()
43 : listener_(NULL), 52 : listener_(NULL),
44 new_capture_session_id_(1), 53 new_capture_session_id_(1),
45 use_fake_device_(false) { 54 use_fake_device_(false) {
46 } 55 }
47 56
48 VideoCaptureManager::~VideoCaptureManager() { 57 VideoCaptureManager::~VideoCaptureManager() {
49 DCHECK(devices_.empty()); 58 DCHECK(devices_.empty());
50 } 59 }
51 60
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { 146 scoped_ptr<media::VideoCaptureDevice::Client> device_client) {
138 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); 147 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
139 DCHECK(IsOnDeviceThread()); 148 DCHECK(IsOnDeviceThread());
140 149
141 scoped_ptr<media::VideoCaptureDevice> video_capture_device; 150 scoped_ptr<media::VideoCaptureDevice> video_capture_device;
142 switch (entry->stream_type) { 151 switch (entry->stream_type) {
143 case MEDIA_DEVICE_VIDEO_CAPTURE: { 152 case MEDIA_DEVICE_VIDEO_CAPTURE: {
144 // We look up the device id from the renderer in our local enumeration 153 // 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 154 // since the renderer does not have all the information that might be
146 // held in the browser-side VideoCaptureDevice::Name structure. 155 // held in the browser-side VideoCaptureDevice::Name structure.
147 media::VideoCaptureDevice::Name* found = 156 class DeviceInfo* found = FindDeviceInfoById(entry->id);
148 video_capture_devices_.FindById(entry->id);
149 if (found) { 157 if (found) {
150 video_capture_device.reset(use_fake_device_ ? 158 video_capture_device.reset(use_fake_device_ ?
151 media::FakeVideoCaptureDevice::Create(*found) : 159 media::FakeVideoCaptureDevice::Create(found->name_) :
152 media::VideoCaptureDevice::Create(*found)); 160 media::VideoCaptureDevice::Create(found->name_));
161
162 // After opening a device, we currently assume that it cannot be opened
163 // in any other format than the actual, so we clear the capabilities.
164 found->capabilities_.clear();
165 found->capabilities_.push_back(capture_params);
153 } 166 }
154 break; 167 break;
155 } 168 }
156 case MEDIA_TAB_VIDEO_CAPTURE: { 169 case MEDIA_TAB_VIDEO_CAPTURE: {
157 video_capture_device.reset( 170 video_capture_device.reset(
158 WebContentsVideoCaptureDevice::Create(entry->id)); 171 WebContentsVideoCaptureDevice::Create(entry->id));
159 break; 172 break;
160 } 173 }
161 case MEDIA_DESKTOP_VIDEO_CAPTURE: { 174 case MEDIA_DESKTOP_VIDEO_CAPTURE: {
162 #if defined(ENABLE_SCREEN_CAPTURE) 175 #if defined(ENABLE_SCREEN_CAPTURE)
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 258
246 // Detach client from controller. 259 // Detach client from controller.
247 int session_id = controller->RemoveClient(client_id, client_handler); 260 int session_id = controller->RemoveClient(client_id, client_handler);
248 DVLOG(1) << "VideoCaptureManager::StopCaptureForClient, session_id = " 261 DVLOG(1) << "VideoCaptureManager::StopCaptureForClient, session_id = "
249 << session_id; 262 << session_id;
250 263
251 // If controller has no more clients, delete controller and device. 264 // If controller has no more clients, delete controller and device.
252 DestroyDeviceEntryIfNoClients(entry); 265 DestroyDeviceEntryIfNoClients(entry);
253 } 266 }
254 267
268 void VideoCaptureManager::EnumerateDeviceCapabilities(
269 const StreamDeviceInfo& device_info) {
270 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
271 DVLOG(1) << "EnumerateDeviceCapabilites for: " << device_info.device.name;
272 DCHECK(listener_);
273 base::PostTaskAndReplyWithResult(
274 device_loop_,
275 FROM_HERE,
276 base::Bind(&VideoCaptureManager::GetDeviceCapabilitiesOnDeviceThread,
277 this,
278 device_info),
279 base::Bind(&VideoCaptureManager::OnDeviceCapabilitiesEnumerated,
280 this,
281 device_info));
282 }
283
255 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) { 284 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) {
256 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); 285 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
257 DCHECK(IsOnDeviceThread()); 286 DCHECK(IsOnDeviceThread());
258 if (entry->video_capture_device) { 287 if (entry->video_capture_device) {
259 entry->video_capture_device->StopAndDeAllocate(); 288 entry->video_capture_device->StopAndDeAllocate();
289 // When the device is closed, its capabilities are reread from the device
290 // to reflect that all are possible.
291 class DeviceInfo* device_info = FindDeviceInfoById(entry->id);
292 if (device_info) {
293 if (!use_fake_device_) {
294 media::VideoCaptureDevice::GetDeviceSupportedFormats(
295 device_info->name_, &(device_info->capabilities_));
296 } else {
297 media::FakeVideoCaptureDevice::GetDeviceSupportedFormats(
298 device_info->name_, &(device_info->capabilities_));
299 }
300 }
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::OnDevicesEnumerated(
285 MediaStreamType stream_type, 326 MediaStreamType stream_type,
286 const media::VideoCaptureDevice::Names& device_names) { 327 const media::VideoCaptureDevice::Names& device_names) {
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
288
289 if (!listener_) { 329 if (!listener_) {
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 // Transform from VCD::Name to StreamDeviceInfo.
295 StreamDeviceInfoArray devices; 335 StreamDeviceInfoArray devices;
296 for (media::VideoCaptureDevice::Names::const_iterator it = 336 for (media::VideoCaptureDevice::Names::const_iterator it =
297 device_names.begin(); it != device_names.end(); ++it) { 337 device_names.begin(); it != device_names.end(); ++it) {
298 devices.push_back(StreamDeviceInfo( 338 devices.push_back(StreamDeviceInfo(
299 stream_type, it->GetNameAndModel(), it->id())); 339 stream_type, it->GetNameAndModel(), it->id()));
300 } 340 }
301 341
302 listener_->DevicesEnumerated(stream_type, devices); 342 listener_->DevicesEnumerated(stream_type, devices);
303 } 343 }
304 344
345 void VideoCaptureManager::OnDeviceCapabilitiesEnumerated(
346 const StreamDeviceInfo& device_info,
347 const media::VideoCaptureCapabilities& capabilities) {
348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
349 if (!listener_) {
350 // Listener has been removed.
351 return;
352 }
353 listener_->DeviceCapabilitiesEnumerated(device_info, capabilities);
354 }
355
305 bool VideoCaptureManager::IsOnDeviceThread() const { 356 bool VideoCaptureManager::IsOnDeviceThread() const {
306 return device_loop_->BelongsToCurrentThread(); 357 return device_loop_->BelongsToCurrentThread();
307 } 358 }
308 359
309 media::VideoCaptureDevice::Names 360 media::VideoCaptureDevice::Names
310 VideoCaptureManager::GetAvailableDevicesOnDeviceThread( 361 VideoCaptureManager::GetAvailableDevicesOnDeviceThread(
311 MediaStreamType stream_type) { 362 MediaStreamType stream_type) {
312 SCOPED_UMA_HISTOGRAM_TIMER( 363 SCOPED_UMA_HISTOGRAM_TIMER(
313 "Media.VideoCaptureManager.GetAvailableDevicesTime"); 364 "Media.VideoCaptureManager.GetAvailableDevicesTime");
314 DCHECK(IsOnDeviceThread()); 365 DCHECK(IsOnDeviceThread());
315 media::VideoCaptureDevice::Names result; 366 media::VideoCaptureDevice::Names names;
316 367
317 switch (stream_type) { 368 switch (stream_type) {
318 case MEDIA_DEVICE_VIDEO_CAPTURE: 369 case MEDIA_DEVICE_VIDEO_CAPTURE:
319 // Cache the latest enumeration of video capture devices. 370 // Cache the latest enumeration of video capture devices.
320 // We'll refer to this list again in OnOpen to avoid having to 371 // We'll refer to this list again in OnOpen to avoid having to
321 // enumerate the devices again. 372 // enumerate the devices again.
322 if (!use_fake_device_) { 373 if (!use_fake_device_) {
323 media::VideoCaptureDevice::GetDeviceNames(&result); 374 media::VideoCaptureDevice::GetDeviceNames(&names);
375 // Walk the |names|, retrieve the capabilities and add all information
376 // to the local device info cache.
377 media::VideoCaptureCapabilities capabilities;
378 media::VideoCaptureDevice::Names::iterator name_it;
379 for (name_it = names.begin(); name_it != names.end(); ++name_it) {
380 media::VideoCaptureDevice::GetDeviceSupportedFormats(*name_it,
perkj_chrome 2013/10/29 12:13:36 In the previous Cl we said that media::VideoCaptur
381 &capabilities);
382 devices_info_cache_.push_back(DeviceInfo(*name_it, capabilities));
383 }
324 } else { 384 } else {
325 media::FakeVideoCaptureDevice::GetDeviceNames(&result); 385 media::FakeVideoCaptureDevice::GetDeviceNames(&names);
386 // Walk the |names|, retrieve the capabilities and add all information
387 // to the local device info cache.
388 media::VideoCaptureCapabilities capabilities;
389 media::VideoCaptureDevice::Names::iterator name_it;
390 for (name_it = names.begin(); name_it != names.end(); ++name_it) {
391 media::FakeVideoCaptureDevice::GetDeviceSupportedFormats(
392 *name_it, &capabilities);
393 devices_info_cache_.push_back(DeviceInfo(*name_it, capabilities));
394 }
326 } 395 }
327 396
328 // TODO(nick): The correctness of device start depends on this cache being 397 // TODO(nick): The correctness of device start depends on the cache being
329 // maintained, but it seems a little odd to keep a cache here. Can we 398 // maintained, but it seems a little odd to keep a cache here. Can we
330 // eliminate it? 399 // eliminate it?
331 video_capture_devices_ = result;
332 break; 400 break;
333 401
334 case MEDIA_DESKTOP_VIDEO_CAPTURE: 402 case MEDIA_DESKTOP_VIDEO_CAPTURE:
335 // Do nothing. 403 // Do nothing.
336 break; 404 break;
337 405
338 default: 406 default:
339 NOTREACHED(); 407 NOTREACHED();
340 break; 408 break;
341 } 409 }
342 return result; 410 return names;
411 }
412
413 media::VideoCaptureCapabilities
414 VideoCaptureManager::GetDeviceCapabilitiesOnDeviceThread(
415 const StreamDeviceInfo& device_info) {
416 DCHECK(IsOnDeviceThread());
417
418 // Find the device we are looking for and return its associated capabilities.
419 class DeviceInfo* device = FindDeviceInfoById(device_info.device.id);
420 if (device)
421 return device->capabilities_;
422 return media::VideoCaptureCapabilities();
343 } 423 }
344 424
345 VideoCaptureManager::DeviceEntry* 425 VideoCaptureManager::DeviceEntry*
346 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice( 426 VideoCaptureManager::GetDeviceEntryForMediaStreamDevice(
347 const MediaStreamDevice& device_info) { 427 const MediaStreamDevice& device_info) {
348 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
349 429
350 for (DeviceEntries::iterator it = devices_.begin(); 430 for (DeviceEntries::iterator it = devices_.begin();
351 it != devices_.end(); ++it) { 431 it != devices_.end(); ++it) {
352 DeviceEntry* device = *it; 432 DeviceEntry* device = *it;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 493
414 scoped_ptr<VideoCaptureController> video_capture_controller( 494 scoped_ptr<VideoCaptureController> video_capture_controller(
415 new VideoCaptureController()); 495 new VideoCaptureController());
416 DeviceEntry* new_device = new DeviceEntry(device_info.type, 496 DeviceEntry* new_device = new DeviceEntry(device_info.type,
417 device_info.id, 497 device_info.id,
418 video_capture_controller.Pass()); 498 video_capture_controller.Pass());
419 devices_.insert(new_device); 499 devices_.insert(new_device);
420 return new_device; 500 return new_device;
421 } 501 }
422 502
503 class VideoCaptureManager::DeviceInfo*
perkj_chrome 2013/10/29 12:13:36 remove class
504 VideoCaptureManager::FindDeviceInfoById(const std::string& id) {
505 std::vector<class DeviceInfo>::iterator it;
506 for (it = devices_info_cache_.begin();
507 it != devices_info_cache_.end();
508 ++it) {
509 if (it->name_.id() == id)
510 return &(*it);
511 }
512 return NULL;
513 }
514
423 } // namespace content 515 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698