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

Unified Diff: content/browser/renderer_host/media/video_capture_manager.cc

Issue 91343002: Added supported formats caching to VideoCaptureManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased FakeVCD. Reconnected VCManager unittest for all platforms. Created 7 years 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 side-by-side diff with in-line comments
Download patch
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 00fa52e43eb0e366848c675ecf7bd44a6559dfe9..4061ba68e2c9f1652f888435c4f93cf2bf1c7a95 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
+#include "base/task_runner_util.h"
#include "base/threading/sequenced_worker_pool.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
@@ -42,6 +43,16 @@ VideoCaptureManager::DeviceEntry::DeviceEntry(
VideoCaptureManager::DeviceEntry::~DeviceEntry() {}
+VideoCaptureManager::DeviceInfo::DeviceInfo() {}
+
+VideoCaptureManager::DeviceInfo::DeviceInfo(
+ const media::VideoCaptureDevice::Name& name,
+ const media::VideoCaptureFormats& supported_formats)
+ : name(name),
+ supported_formats(supported_formats) {}
+
+VideoCaptureManager::DeviceInfo::~DeviceInfo() {}
+
VideoCaptureManager::VideoCaptureManager()
: listener_(NULL),
new_capture_session_id_(1),
@@ -70,11 +81,17 @@ void VideoCaptureManager::EnumerateDevices(MediaStreamType stream_type) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << "VideoCaptureManager::EnumerateDevices, type " << stream_type;
DCHECK(listener_);
+
base::PostTaskAndReplyWithResult(
- device_loop_, FROM_HERE,
- base::Bind(&VideoCaptureManager::GetAvailableDevicesOnDeviceThread, this,
- stream_type),
- base::Bind(&VideoCaptureManager::OnDevicesEnumerated, this, stream_type));
+ device_loop_,
+ FROM_HERE,
+ base::Bind(&VideoCaptureManager::GetAvailableDevicesInfoOnDeviceThread,
+ this,
+ stream_type,
+ devices_info_cache_),
+ base::Bind(&VideoCaptureManager::OnDevicesInfoEnumerated,
+ this,
+ stream_type));
}
int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) {
@@ -147,12 +164,11 @@ 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);
+ DeviceInfo* found = FindDeviceInfoById(entry->id, devices_info_cache_);
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));
}
break;
}
@@ -214,7 +230,6 @@ void VideoCaptureManager::StartCaptureForClient(
if (entry->video_capture_controller->GetClientCount() == 0) {
DVLOG(1) << "VideoCaptureManager starting device (type = "
<< entry->stream_type << ", id = " << entry->id << ")";
-
device_loop_->PostTask(
FROM_HERE,
base::Bind(
@@ -253,6 +268,35 @@ void VideoCaptureManager::StopCaptureForClient(
DestroyDeviceEntryIfNoClients(entry);
}
+void VideoCaptureManager::GetDeviceSupportedFormats(
+ int capture_session_id,
+ media::VideoCaptureFormats* supported_formats) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ supported_formats->clear();
+
+ std::map<int, MediaStreamDevice>::iterator it =
+ sessions_.find(capture_session_id);
+ DCHECK(it != sessions_.end());
+ DVLOG(1) << "GetDeviceSupportedFormats for device: " << it->second.name;
+
+ DeviceInfo* device_in_use =
+ FindDeviceInfoById(it->second.id, devices_info_cache_);
+ DCHECK(device_in_use);
scherkus (not reviewing) 2013/12/03 22:04:48 if you're DCHECK'ing this is non-null ... but then
mcasas 2013/12/04 15:23:32 Done.
+ if (device_in_use) {
+ DeviceEntry* const existing_device =
+ GetDeviceEntryForMediaStreamDevice(it->second);
+ if (!existing_device) {
+ // If the device is not in use, return all its cached supported formats.
+ *supported_formats = device_in_use->supported_formats;
+ return;
+ }
+ // Otherwise, get the video capture parameters in use from the controller
+ // associated to the device.
+ supported_formats->push_back(
+ existing_device->video_capture_controller->GetVideoCaptureFormat());
+ }
+}
+
void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) {
SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
DCHECK(IsOnDeviceThread());
@@ -282,24 +326,26 @@ void VideoCaptureManager::OnClosed(MediaStreamType stream_type,
listener_->Closed(stream_type, capture_session_id);
}
-void VideoCaptureManager::OnDevicesEnumerated(
+void VideoCaptureManager::OnDevicesInfoEnumerated(
MediaStreamType stream_type,
- const media::VideoCaptureDevice::Names& device_names) {
+ const DeviceInfos& new_devices_info_cache) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
-
- if (!listener_) {
- // Listener has been removed.
+ DVLOG(1) << "OnDevicesInfoEnumerated, #new devices: "
+ << new_devices_info_cache.size();
+ if (!listener_) { // Listener has been removed.
return;
}
+ devices_info_cache_ = new_devices_info_cache;
- // Transform from VCD::Name to StreamDeviceInfo.
+ // Walk the |devices_info_cache_| and transform from VCD::Name to
+ // StreamDeviceInfo for return purposes.
StreamDeviceInfoArray devices;
- for (media::VideoCaptureDevice::Names::const_iterator it =
- device_names.begin(); it != device_names.end(); ++it) {
+ for (DeviceInfos::const_iterator it = devices_info_cache_.begin();
+ it != devices_info_cache_.end();
+ ++it) {
devices.push_back(StreamDeviceInfo(
- stream_type, it->GetNameAndModel(), it->id()));
+ stream_type, it->name.GetNameAndModel(), it->name.id()));
}
-
listener_->DevicesEnumerated(stream_type, devices);
}
@@ -307,40 +353,64 @@ bool VideoCaptureManager::IsOnDeviceThread() const {
return device_loop_->BelongsToCurrentThread();
}
-media::VideoCaptureDevice::Names
-VideoCaptureManager::GetAvailableDevicesOnDeviceThread(
- MediaStreamType stream_type) {
- SCOPED_UMA_HISTOGRAM_TIMER(
- "Media.VideoCaptureManager.GetAvailableDevicesTime");
+VideoCaptureManager::DeviceInfos
+VideoCaptureManager::GetAvailableDevicesInfoOnDeviceThread(
+ MediaStreamType stream_type,
+ const DeviceInfos& old_device_info_cache) {
+ SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager."
+ "GetAvailableDevicesInfoOnDeviceThreadTime");
DCHECK(IsOnDeviceThread());
- media::VideoCaptureDevice::Names result;
-
+ media::VideoCaptureDevice::Names names_snapshot;
switch (stream_type) {
case MEDIA_DEVICE_VIDEO_CAPTURE:
- // Cache the latest enumeration of video capture devices.
- // 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);
- } else {
- media::FakeVideoCaptureDevice::GetDeviceNames(&result);
- }
-
- // TODO(nick): The correctness of device start depends on this cache being
- // maintained, but it seems a little odd to keep a cache here. Can we
- // eliminate it?
- video_capture_devices_ = result;
+ if (!use_fake_device_)
+ media::VideoCaptureDevice::GetDeviceNames(&names_snapshot);
+ else
+ media::FakeVideoCaptureDevice::GetDeviceNames(&names_snapshot);
break;
-
case MEDIA_DESKTOP_VIDEO_CAPTURE:
// Do nothing.
break;
-
default:
NOTREACHED();
break;
}
- return result;
+
+ // Construct |new_devices_info_cache| with the cached devices that are still
+ // present in the system, and remove their names from |names_snapshot|, so we
+ // keep there the truly new devices.
+ DeviceInfos new_devices_info_cache;
+ for (DeviceInfos::const_iterator it_device_info =
+ old_device_info_cache.begin();
+ it_device_info != old_device_info_cache.end();
+ ++it_device_info) {
+ media::VideoCaptureDevice::Names::iterator it;
+ for (it = names_snapshot.begin(); it != names_snapshot.end(); ++it) {
+ if (it_device_info->name.id() == it->id()) {
+ new_devices_info_cache.push_back(*it_device_info);
+ names_snapshot.erase(it);
+ break;
+ }
+ }
+ }
+
+ // Get the supported capture formats for the new devices in |names_snapshot|.
+ for (media::VideoCaptureDevice::Names::const_iterator it =
+ names_snapshot.begin();
+ it != names_snapshot.end();
+ ++it) {
+ media::VideoCaptureFormats supported_formats;
+ DeviceInfo device_info(*it, media::VideoCaptureFormats());
+ if (!use_fake_device_) {
+ media::VideoCaptureDevice::GetDeviceSupportedFormats(
+ *it, &(device_info.supported_formats));
+ } else {
+ media::FakeVideoCaptureDevice::GetDeviceSupportedFormats(
+ *it, &(device_info.supported_formats));
+ }
+ new_devices_info_cache.push_back(device_info);
+ }
+ return new_devices_info_cache;
}
VideoCaptureManager::DeviceEntry*
@@ -387,7 +457,8 @@ void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) {
entry->video_capture_controller.reset();
device_loop_->PostTask(
FROM_HERE,
- base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
+ base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread,
+ this,
base::Owned(entry)));
}
}
@@ -421,4 +492,15 @@ VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
return new_device;
}
+VideoCaptureManager::DeviceInfo* VideoCaptureManager::FindDeviceInfoById(
+ const std::string& id,
+ DeviceInfos& device_vector) {
+ for (DeviceInfos::iterator it = device_vector.begin();
+ it != device_vector.end(); ++it) {
+ if (it->name.id() == id)
+ return &(*it);
+ }
+ return NULL;
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698