Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_manager.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc |
| index a1fcad7b6a6071a1b8b23349ffee9ce728dcde02..614a06c9b4df4585cc717e20a55969d9c885126e 100644 |
| --- a/content/browser/renderer_host/media/video_capture_manager.cc |
| +++ b/content/browser/renderer_host/media/video_capture_manager.cc |
| @@ -39,6 +39,15 @@ VideoCaptureManager::DeviceEntry::DeviceEntry( |
| VideoCaptureManager::DeviceEntry::~DeviceEntry() {} |
| +VideoCaptureManager::DeviceInfo::DeviceInfo() {} |
| + |
| +VideoCaptureManager::DeviceInfo::DeviceInfo( |
| + const media::VideoCaptureDevice::Name& name, |
| + const media::VideoCaptureCapabilities& capabilities) |
| + : name_(name), capabilities_(capabilities) {} |
| + |
| +VideoCaptureManager::DeviceInfo::~DeviceInfo() {} |
| + |
| VideoCaptureManager::VideoCaptureManager() |
| : listener_(NULL), |
| new_capture_session_id_(1), |
| @@ -144,12 +153,16 @@ void VideoCaptureManager::DoStartDeviceOnDeviceThread( |
| // We look up the device id from the renderer in our local enumeration |
| // since the renderer does not have all the information that might be |
| // held in the browser-side VideoCaptureDevice::Name structure. |
| - media::VideoCaptureDevice::Name* found = |
| - video_capture_devices_.FindById(entry->id); |
| + class DeviceInfo* found = FindDeviceInfoById(entry->id); |
| if (found) { |
| video_capture_device.reset(use_fake_device_ ? |
| - media::FakeVideoCaptureDevice::Create(*found) : |
| - media::VideoCaptureDevice::Create(*found)); |
| + media::FakeVideoCaptureDevice::Create(found->name_) : |
| + media::VideoCaptureDevice::Create(found->name_)); |
| + |
| + // After opening a device, we currently assume that it cannot be opened |
| + // in any other format than the actual, so we clear the capabilities. |
| + found->capabilities_.clear(); |
| + found->capabilities_.push_back(capture_params); |
| } |
| break; |
| } |
| @@ -252,11 +265,39 @@ void VideoCaptureManager::StopCaptureForClient( |
| DestroyDeviceEntryIfNoClients(entry); |
| } |
| +void VideoCaptureManager::EnumerateDeviceCapabilities( |
| + const StreamDeviceInfo& device_info) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + DVLOG(1) << "EnumerateDeviceCapabilites for: " << device_info.device.name; |
| + DCHECK(listener_); |
| + base::PostTaskAndReplyWithResult( |
| + device_loop_, |
| + FROM_HERE, |
| + base::Bind(&VideoCaptureManager::GetDeviceCapabilitiesOnDeviceThread, |
| + this, |
| + device_info), |
| + base::Bind(&VideoCaptureManager::OnDeviceCapabilitiesEnumerated, |
| + this, |
| + device_info)); |
| +} |
| + |
| void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) { |
| SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
| DCHECK(IsOnDeviceThread()); |
| if (entry->video_capture_device) { |
| entry->video_capture_device->StopAndDeAllocate(); |
| + // When the device is closed, its capabilities are reread from the device |
| + // to reflect that all are possible. |
| + class DeviceInfo* device_info = FindDeviceInfoById(entry->id); |
| + if (device_info) { |
| + if (!use_fake_device_) { |
| + media::VideoCaptureDevice::GetDeviceSupportedFormats( |
| + device_info->name_, &(device_info->capabilities_)); |
| + } else { |
| + media::FakeVideoCaptureDevice::GetDeviceSupportedFormats( |
| + device_info->name_, &(device_info->capabilities_)); |
| + } |
| + } |
| } |
| entry->video_capture_device.reset(); |
| } |
| @@ -285,7 +326,6 @@ void VideoCaptureManager::OnDevicesEnumerated( |
| MediaStreamType stream_type, |
| const media::VideoCaptureDevice::Names& device_names) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| - |
| if (!listener_) { |
| // Listener has been removed. |
| return; |
| @@ -302,6 +342,17 @@ void VideoCaptureManager::OnDevicesEnumerated( |
| listener_->DevicesEnumerated(stream_type, devices); |
| } |
| +void VideoCaptureManager::OnDeviceCapabilitiesEnumerated( |
| + const StreamDeviceInfo& device_info, |
| + const media::VideoCaptureCapabilities& capabilities) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + if (!listener_) { |
| + // Listener has been removed. |
| + return; |
| + } |
| + listener_->DeviceCapabilitiesEnumerated(device_info, capabilities); |
| +} |
| + |
| bool VideoCaptureManager::IsOnDeviceThread() const { |
| return device_loop_->BelongsToCurrentThread(); |
| } |
| @@ -312,7 +363,7 @@ VideoCaptureManager::GetAvailableDevicesOnDeviceThread( |
| SCOPED_UMA_HISTOGRAM_TIMER( |
| "Media.VideoCaptureManager.GetAvailableDevicesTime"); |
| DCHECK(IsOnDeviceThread()); |
| - media::VideoCaptureDevice::Names result; |
| + media::VideoCaptureDevice::Names names; |
| switch (stream_type) { |
| case MEDIA_DEVICE_VIDEO_CAPTURE: |
| @@ -320,15 +371,32 @@ VideoCaptureManager::GetAvailableDevicesOnDeviceThread( |
| // We'll refer to this list again in OnOpen to avoid having to |
| // enumerate the devices again. |
| if (!use_fake_device_) { |
| - media::VideoCaptureDevice::GetDeviceNames(&result); |
| + media::VideoCaptureDevice::GetDeviceNames(&names); |
| + // Walk the |names|, retrieve the capabilities and add all information |
| + // to the local device info cache. |
| + media::VideoCaptureCapabilities capabilities; |
| + media::VideoCaptureDevice::Names::iterator name_it; |
| + for (name_it = names.begin(); name_it != names.end(); ++name_it) { |
| + media::VideoCaptureDevice::GetDeviceSupportedFormats(*name_it, |
|
perkj_chrome
2013/10/29 12:13:36
In the previous Cl we said that media::VideoCaptur
|
| + &capabilities); |
| + devices_info_cache_.push_back(DeviceInfo(*name_it, capabilities)); |
| + } |
| } else { |
| - media::FakeVideoCaptureDevice::GetDeviceNames(&result); |
| + media::FakeVideoCaptureDevice::GetDeviceNames(&names); |
| + // Walk the |names|, retrieve the capabilities and add all information |
| + // to the local device info cache. |
| + media::VideoCaptureCapabilities capabilities; |
| + media::VideoCaptureDevice::Names::iterator name_it; |
| + for (name_it = names.begin(); name_it != names.end(); ++name_it) { |
| + media::FakeVideoCaptureDevice::GetDeviceSupportedFormats( |
| + *name_it, &capabilities); |
| + devices_info_cache_.push_back(DeviceInfo(*name_it, capabilities)); |
| + } |
| } |
| - // TODO(nick): The correctness of device start depends on this cache being |
| + // TODO(nick): The correctness of device start depends on the cache being |
| // maintained, but it seems a little odd to keep a cache here. Can we |
| // eliminate it? |
| - video_capture_devices_ = result; |
| break; |
| case MEDIA_DESKTOP_VIDEO_CAPTURE: |
| @@ -339,7 +407,19 @@ VideoCaptureManager::GetAvailableDevicesOnDeviceThread( |
| NOTREACHED(); |
| break; |
| } |
| - return result; |
| + return names; |
| +} |
| + |
| +media::VideoCaptureCapabilities |
| +VideoCaptureManager::GetDeviceCapabilitiesOnDeviceThread( |
| + const StreamDeviceInfo& device_info) { |
| + DCHECK(IsOnDeviceThread()); |
| + |
| + // Find the device we are looking for and return its associated capabilities. |
| + class DeviceInfo* device = FindDeviceInfoById(device_info.device.id); |
| + if (device) |
| + return device->capabilities_; |
| + return media::VideoCaptureCapabilities(); |
| } |
| VideoCaptureManager::DeviceEntry* |
| @@ -420,4 +500,16 @@ VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( |
| return new_device; |
| } |
| +class VideoCaptureManager::DeviceInfo* |
|
perkj_chrome
2013/10/29 12:13:36
remove class
|
| +VideoCaptureManager::FindDeviceInfoById(const std::string& id) { |
| + std::vector<class DeviceInfo>::iterator it; |
| + for (it = devices_info_cache_.begin(); |
| + it != devices_info_cache_.end(); |
| + ++it) { |
| + if (it->name_.id() == id) |
| + return &(*it); |
| + } |
| + return NULL; |
| +} |
| + |
| } // namespace content |