Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |