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

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

Issue 2738763002: [Mojo Video Capture] Introduce abstraction BuildableVideoCaptureDevice (Closed)
Patch Set: Rebase to March 30 Created 3 years, 9 months 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
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2118857ecee7866c2e984854298eaee4c37e217e..641bb6fd35329d4ae3bf9444219c1ba4e0061f3c 100644
--- a/content/browser/renderer_host/media/video_capture_manager.cc
+++ b/content/browser/renderer_host/media/video_capture_manager.cc
@@ -25,10 +25,9 @@
#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
#include "content/browser/media/capture/web_contents_video_capture_device.h"
#include "content/browser/media/media_internals.h"
+#include "content/browser/renderer_host/media/in_process_buildable_video_capture_device.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
-#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
-#include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "content/public/common/media_stream_request.h"
@@ -59,27 +58,6 @@
namespace {
-class VideoFrameConsumerFeedbackObserverOnTaskRunner
- : public media::VideoFrameConsumerFeedbackObserver {
- public:
- VideoFrameConsumerFeedbackObserverOnTaskRunner(
- media::VideoFrameConsumerFeedbackObserver* observer,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : observer_(observer), task_runner_(std::move(task_runner)) {}
-
- void OnUtilizationReport(int frame_feedback_id, double utilization) override {
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(
- &media::VideoFrameConsumerFeedbackObserver::OnUtilizationReport,
- base::Unretained(observer_), frame_feedback_id, utilization));
- }
-
- private:
- media::VideoFrameConsumerFeedbackObserver* const observer_;
- const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-};
-
// Compares two VideoCaptureFormat by checking smallest frame_size area, then
// by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that
// the first entry for a given resolution has the largest frame rate, as needed
@@ -125,16 +103,6 @@ void ConsolidateCaptureFormats(media::VideoCaptureFormats* formats) {
}
}
-// The maximum number of video frame buffers in-flight at any one time. This
-// value should be based on the logical capacity of the capture pipeline, and
-// not on hardware performance. For example, tab capture requires more buffers
-// than webcam capture because the pipeline is longer (it includes read-backs
-// pending in the GPU pipeline).
-const int kMaxNumberOfBuffers = 3;
-// TODO(miu): The value for tab capture should be determined programmatically.
-// http://crbug.com/460318
-const int kMaxNumberOfBuffersForTabCapture = 10;
-
// Used for logging capture events.
// Elements in this enum should not be deleted or rearranged; the only
// permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT.
@@ -148,56 +116,16 @@ enum VideoCaptureEvent {
};
void LogVideoCaptureEvent(VideoCaptureEvent event) {
- UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event",
- event,
+ UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", event,
NUM_VIDEO_CAPTURE_EVENT);
}
-// Counter used for identifying a DeviceRequest to start a capture device.
-static int g_device_start_id = 0;
-
const media::VideoCaptureSessionId kFakeSessionId = -1;
-std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
- const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) {
- return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb);
-}
-
} // namespace
namespace content {
-// Instances of this struct go through several different phases during their
-// lifetime.
-// Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of
-// only the |video_capture_controller|. Clients can already connect to the
-// controller, but there is no |video_capture_device| present.
-// Phase 2: When a request to "start" the entry comes in (via
-// HandleQueuedStartRequest()), creation of |video_capture_device| is scheduled
-// to run asynchronously on the Device Thread.
-// Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this
-// newly created VideoCaptureDevice instance is connected to the
-// VideoCaptureController via SetConsumerFeedbackObserver().
-// Phase 4: This phase can only be reached on Android. When the application goes
-// to the background, the |video_capture_device| is asynchronously stopped and
-// released on the Device Thread. When the application is resumed, we
-// transition to Phase 2.
-struct VideoCaptureManager::DeviceEntry {
- public:
- DeviceEntry(MediaStreamType stream_type,
- const std::string& id,
- const media::VideoCaptureParams& params);
- ~DeviceEntry();
- std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient();
-
- const int serial_id;
- const MediaStreamType stream_type;
- const std::string id;
- const media::VideoCaptureParams parameters;
- VideoCaptureController video_capture_controller;
- std::unique_ptr<media::VideoCaptureDevice> video_capture_device;
-};
-
// Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported
// video formats.
struct VideoCaptureManager::DeviceInfo {
@@ -235,44 +163,6 @@ class VideoCaptureManager::CaptureDeviceStartRequest {
bool abort_start_;
};
-VideoCaptureManager::DeviceEntry::DeviceEntry(
- MediaStreamType stream_type,
- const std::string& id,
- const media::VideoCaptureParams& params)
- : serial_id(g_device_start_id++),
- stream_type(stream_type),
- id(id),
- parameters(params) {}
-
-VideoCaptureManager::DeviceEntry::~DeviceEntry() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- // DCHECK that this DeviceEntry does not still own a
- // media::VideoCaptureDevice. media::VideoCaptureDevice must be deleted on
- // the device thread.
- DCHECK(video_capture_device == nullptr);
-}
-
-std::unique_ptr<media::VideoCaptureDevice::Client>
-VideoCaptureManager::DeviceEntry::CreateDeviceClient() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE
- ? kMaxNumberOfBuffersForTabCapture
- : kMaxNumberOfBuffers;
- scoped_refptr<media::VideoCaptureBufferPool> buffer_pool =
- new media::VideoCaptureBufferPoolImpl(
- base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(),
- max_buffers);
-
- return base::MakeUnique<media::VideoCaptureDeviceClient>(
- base::MakeUnique<VideoFrameReceiverOnIOThread>(
- video_capture_controller.GetWeakPtrForIOThread()),
- std::move(buffer_pool),
- base::Bind(&CreateGpuJpegDecoder,
- base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer,
- video_capture_controller.GetWeakPtrForIOThread())));
-}
-
VideoCaptureManager::DeviceInfo::DeviceInfo() = default;
VideoCaptureManager::DeviceInfo::DeviceInfo(
@@ -294,8 +184,7 @@ VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest(
: serial_id_(serial_id),
session_id_(session_id),
params_(params),
- abort_start_(false) {
-}
+ abort_start_(false) {}
VideoCaptureManager::VideoCaptureManager(
std::unique_ptr<media::VideoCaptureDeviceFactory> factory,
@@ -305,7 +194,7 @@ VideoCaptureManager::VideoCaptureManager(
video_capture_device_factory_(std::move(factory)) {}
VideoCaptureManager::~VideoCaptureManager() {
- DCHECK(devices_.empty());
+ DCHECK(controllers_.empty());
DCHECK(device_start_queue_.empty());
}
@@ -365,6 +254,12 @@ void VideoCaptureManager::EnumerateDevices(
devices_enumerated_callback));
}
+const media::VideoCaptureDeviceDescriptor*
+VideoCaptureManager::LookupDeviceDescriptor(const std::string& id) {
+ const DeviceInfo* info = GetDeviceInfoById(id);
+ return info ? (&info->descriptor) : nullptr;
+}
+
int VideoCaptureManager::Open(const MediaStreamDevice& device) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -397,16 +292,16 @@ void VideoCaptureManager::Close(int capture_session_id) {
return;
}
- DeviceEntry* const existing_device =
- GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id);
+ VideoCaptureController* const existing_device = LookupControllerByTypeAndId(
+ session_it->second.type, session_it->second.id);
if (existing_device) {
// Remove any client that is still using the session. This is safe to call
// even if there are no clients using the session.
- existing_device->video_capture_controller.StopSession(capture_session_id);
+ existing_device->StopSession(capture_session_id);
// StopSession() may have removed the last client, so we might need to
// close the device.
- DestroyDeviceEntryIfNoClients(existing_device);
+ DestroyControllerIfNoClients(existing_device);
}
// Notify listeners asynchronously, and forget the session.
@@ -418,55 +313,57 @@ void VideoCaptureManager::Close(int capture_session_id) {
void VideoCaptureManager::QueueStartDevice(
media::VideoCaptureSessionId session_id,
- DeviceEntry* entry,
+ VideoCaptureController* controller,
const media::VideoCaptureParams& params) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
device_start_queue_.push_back(
- CaptureDeviceStartRequest(entry->serial_id, session_id, params));
+ CaptureDeviceStartRequest(controller->serial_id(), session_id, params));
if (device_start_queue_.size() == 1)
HandleQueuedStartRequest();
}
-void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) {
+void VideoCaptureManager::DoStopDevice(VideoCaptureController* controller) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(mcasas): use a helper function https://crbug.com/624854.
- DCHECK(
- std::find_if(devices_.begin(), devices_.end(),
- [entry](const std::unique_ptr<DeviceEntry>& device_entry) {
- return device_entry.get() == entry;
- }) != devices_.end());
+ DCHECK(std::find_if(
+ controllers_.begin(), controllers_.end(),
+ [controller](
+ const scoped_refptr<VideoCaptureController>& device_entry) {
+ return device_entry.get() == controller;
+ }) != controllers_.end());
// Find the matching start request.
for (DeviceStartQueue::reverse_iterator request =
device_start_queue_.rbegin();
request != device_start_queue_.rend(); ++request) {
- if (request->serial_id() == entry->serial_id) {
+ if (request->serial_id() == controller->serial_id()) {
request->set_abort_start();
DVLOG(3) << "DoStopDevice, aborting start request for device "
- << entry->id << " serial_id = " << entry->serial_id;
+ << controller->device_id()
+ << " serial_id = " << controller->serial_id();
return;
}
}
- const DeviceInfo* device_info = GetDeviceInfoById(entry->id);
+ const DeviceInfo* device_info = GetDeviceInfoById(controller->device_id());
if (device_info != nullptr) {
for (auto& observer : capture_observers_)
observer.OnVideoCaptureStopped(device_info->descriptor.facing);
}
- DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id
- << " serial_id = " << entry->serial_id << ".";
- entry->video_capture_controller.OnLog(
- base::StringPrintf("Stopping device: id: %s", entry->id.c_str()));
- entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr);
-
- // |entry->video_capture_device| can be null if creating the device has
- // failed.
- if (entry->video_capture_device) {
- device_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
- base::Passed(&entry->video_capture_device)));
+ DVLOG(3) << "DoStopDevice. Send stop request for device = "
+ << controller->device_id()
+ << " serial_id = " << controller->serial_id() << ".";
+ controller->OnLog(base::StringPrintf("Stopping device: id: %s",
+ controller->device_id().c_str()));
+
+ if (controller->IsDeviceAlive()) {
+ // Since we may be removing |controller| from |controllers_| while
+ // ReleaseDeviceAsnyc() is executing, we pass it shared ownership to
+ // |controller|.
+ controller->ReleaseDeviceAsync(base::Bind(
+ [](scoped_refptr<VideoCaptureController>) {},
+ GetControllerSharedRefFromSerialId(controller->serial_id())));
}
}
@@ -474,7 +371,7 @@ void VideoCaptureManager::HandleQueuedStartRequest() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Remove all start requests that have been aborted.
while (device_start_queue_.begin() != device_start_queue_.end() &&
- device_start_queue_.begin()->abort_start()) {
+ device_start_queue_.begin()->abort_start()) {
device_start_queue_.pop_front();
}
DeviceStartQueue::iterator request = device_start_queue_.begin();
@@ -482,115 +379,50 @@ void VideoCaptureManager::HandleQueuedStartRequest() {
return;
const int serial_id = request->serial_id();
- DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id);
- DCHECK(entry);
+ VideoCaptureController* const controller =
+ LookupControllerBySerialId(serial_id);
+ DCHECK(controller);
DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = "
- << entry->id << " start id = " << entry->serial_id;
-
- std::unique_ptr<media::VideoCaptureDevice::Client> device_client =
- entry->CreateDeviceClient();
-
- base::Callback<std::unique_ptr<VideoCaptureDevice>(void)>
- start_capture_function;
-
- switch (entry->stream_type) {
- case MEDIA_DEVICE_VIDEO_CAPTURE: {
- // 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.
- const DeviceInfo* found = GetDeviceInfoById(entry->id);
- if (found) {
- entry->video_capture_controller.OnLog(
- base::StringPrintf("Starting device: id: %s, name: %s, api: %s",
- found->descriptor.device_id.c_str(),
- found->descriptor.GetNameAndModel().c_str(),
- found->descriptor.GetCaptureApiTypeString()));
-
- for (auto& observer : capture_observers_)
- observer.OnVideoCaptureStarted(found->descriptor.facing);
-
- start_capture_function =
- base::Bind(&VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread,
- this, found->descriptor, request->params(),
- base::Passed(std::move(device_client)));
- } else {
- // Errors from DoStartDeviceCaptureOnDeviceThread go via
- // VideoCaptureDeviceClient::OnError, which needs some thread
- // dancing to get errors processed on the IO thread. But since
- // we're on that thread, we call VideoCaptureController
- // methods directly.
- const std::string log_message = base::StringPrintf(
- "Error on %s:%d: device %s unknown. Maybe recently disconnected?",
- __FILE__, __LINE__, entry->id.c_str());
- DLOG(ERROR) << log_message;
- entry->video_capture_controller.OnLog(log_message);
- entry->video_capture_controller.OnError();
- // Drop the failed start request.
- device_start_queue_.pop_front();
-
- return;
- }
- break;
- }
- case MEDIA_TAB_VIDEO_CAPTURE:
- start_capture_function = base::Bind(
- &VideoCaptureManager::DoStartTabCaptureOnDeviceThread, this,
- entry->id, request->params(), base::Passed(std::move(device_client)));
- break;
-
- case MEDIA_DESKTOP_VIDEO_CAPTURE:
- start_capture_function = base::Bind(
- &VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, this,
- entry->id, request->params(), base::Passed(std::move(device_client)));
- break;
-
- default: {
- NOTIMPLEMENTED();
- return;
- }
- }
- base::PostTaskAndReplyWithResult(
- device_task_runner_.get(), FROM_HERE, start_capture_function,
- base::Bind(&VideoCaptureManager::OnDeviceStarted, this,
- request->serial_id()));
-}
-
-void VideoCaptureManager::OnDeviceStarted(
- int serial_id,
- std::unique_ptr<VideoCaptureDevice> device) {
+ << controller->device_id()
+ << " start id = " << controller->serial_id();
+
+ // The method CreateAndStartDeviceAsync() is going to run asynchronously.
+ // Since we may be removing the controller while it is executing, we need to
+ // pass it shared ownership to itself so that it stays alive while executing.
+ // And since the execution may make callbacks into |this|, we also need
+ // to pass it shared ownership to |this|.
+ // TODO(chfremer): Check if request->params() can actually be different from
+ // controller->parameters, and simplify if this is not the case.
+ controller->CreateAndStartDeviceAsync(
+ request->params(),
+ static_cast<BuildableVideoCaptureDevice::Callbacks*>(this),
+ base::Bind([](scoped_refptr<VideoCaptureManager>,
+ scoped_refptr<VideoCaptureController>) {},
+ scoped_refptr<VideoCaptureManager>(this),
+ GetControllerSharedRefFromSerialId(serial_id)));
+}
+
+void VideoCaptureManager::WillStartDevice(media::VideoFacingMode facing_mode) {
+ for (auto& observer : capture_observers_)
+ observer.OnVideoCaptureStarted(facing_mode);
+}
+
+void VideoCaptureManager::DidStartDevice(VideoCaptureController* controller) {
DVLOG(3) << __func__;
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id());
- // |device| can be null if creation failed in
- // DoStartDeviceCaptureOnDeviceThread.
+ DCHECK(controller);
+ DCHECK_EQ(controller->serial_id(), device_start_queue_.begin()->serial_id());
if (device_start_queue_.front().abort_start()) {
- // The device is no longer wanted. Stop the device again.
- DVLOG(3) << "OnDeviceStarted but start request have been aborted.";
- media::VideoCaptureDevice* device_ptr = device.get();
- base::Closure closure =
- base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
- base::Passed(&device));
- if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) {
- // PostTask failed. The device must be stopped anyway.
- device_ptr->StopAndDeAllocate();
- }
+ // A request to release the device may have arrived during the asynchronous
+ // device startup.
+ DVLOG(3) << "Device release request has been issued while device was "
+ << "starting up asynchronously.";
+ controller->ReleaseDeviceAsync(base::Bind(
+ [](scoped_refptr<VideoCaptureController>) {},
+ GetControllerSharedRefFromSerialId(controller->serial_id())));
} else {
- DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id);
- DCHECK(entry);
- DCHECK(!entry->video_capture_device);
- if (device) {
- // Passing raw pointer |device.get()| to the controller is safe,
- // because we transfer ownership of it to |entry|. We are calling
- // SetConsumerFeedbackObserver(nullptr) before releasing
- // |entry->video_capture_device_| on the |device_task_runner_|.
- entry->video_capture_controller.SetConsumerFeedbackObserver(
- base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>(
- device.get(), device_task_runner_));
- }
- entry->video_capture_device = std::move(device);
-
- if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
+ if (controller->stream_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) {
const media::VideoCaptureSessionId session_id =
device_start_queue_.front().session_id();
DCHECK(session_id != kFakeSessionId);
@@ -600,9 +432,10 @@ void VideoCaptureManager::OnDeviceStarted(
auto it = photo_request_queue_.begin();
while (it != photo_request_queue_.end()) {
auto request = it++;
- DeviceEntry* maybe_entry = GetDeviceEntryBySessionId(request->first);
- if (maybe_entry && maybe_entry->video_capture_device) {
- request->second.Run(maybe_entry->video_capture_device.get());
+ VideoCaptureController* maybe_entry =
+ LookupControllerBySessionId(request->first);
+ if (maybe_entry && maybe_entry->IsDeviceAlive()) {
+ request->second.Run();
photo_request_queue_.erase(request);
}
}
@@ -612,97 +445,17 @@ void VideoCaptureManager::OnDeviceStarted(
HandleQueuedStartRequest();
}
-std::unique_ptr<media::VideoCaptureDevice>
-VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread(
- const VideoCaptureDeviceDescriptor& descriptor,
- const media::VideoCaptureParams& params,
- std::unique_ptr<VideoCaptureDevice::Client> device_client) {
- SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
- DCHECK(IsOnDeviceThread());
-
- std::unique_ptr<VideoCaptureDevice> video_capture_device;
- video_capture_device =
- video_capture_device_factory_->CreateDevice(descriptor);
-
- if (!video_capture_device) {
- device_client->OnError(FROM_HERE, "Could not create capture device");
- return nullptr;
- }
-
- video_capture_device->AllocateAndStart(params, std::move(device_client));
- return video_capture_device;
-}
-
-std::unique_ptr<media::VideoCaptureDevice>
-VideoCaptureManager::DoStartTabCaptureOnDeviceThread(
- const std::string& id,
- const media::VideoCaptureParams& params,
- std::unique_ptr<VideoCaptureDevice::Client> device_client) {
- SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
- DCHECK(IsOnDeviceThread());
-
- std::unique_ptr<VideoCaptureDevice> video_capture_device;
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
- video_capture_device = WebContentsVideoCaptureDevice::Create(id);
-#endif
-
- if (!video_capture_device) {
- device_client->OnError(FROM_HERE, "Could not create capture device");
- return nullptr;
- }
-
- video_capture_device->AllocateAndStart(params, std::move(device_client));
- return video_capture_device;
-}
-
-std::unique_ptr<media::VideoCaptureDevice>
-VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread(
- const std::string& id,
- const media::VideoCaptureParams& params,
- std::unique_ptr<VideoCaptureDevice::Client> device_client) {
- SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
- DCHECK(IsOnDeviceThread());
-
- std::unique_ptr<VideoCaptureDevice> video_capture_device;
-#if defined(ENABLE_SCREEN_CAPTURE)
- DesktopMediaID desktop_id = DesktopMediaID::Parse(id);
- if (desktop_id.is_null()) {
- device_client->OnError(FROM_HERE, "Desktop media ID is null");
- return nullptr;
- }
-
- if (desktop_id.type == DesktopMediaID::TYPE_WEB_CONTENTS) {
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
- video_capture_device = WebContentsVideoCaptureDevice::Create(id);
- IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED);
- if (desktop_id.audio_share) {
- IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITH_AUDIO);
- } else {
- IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITHOUT_AUDIO);
- }
-#endif
- } else {
-#if defined(OS_ANDROID)
- video_capture_device = base::MakeUnique<ScreenCaptureDeviceAndroid>();
-#else
-#if defined(USE_AURA)
- video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id);
-#endif // defined(USE_AURA)
-#if BUILDFLAG(ENABLE_WEBRTC)
- if (!video_capture_device)
- video_capture_device = DesktopCaptureDevice::Create(desktop_id);
-#endif // BUILDFLAG(ENABLE_WEBRTC)
-#endif // defined (OS_ANDROID)
- }
-#endif // defined(ENABLE_SCREEN_CAPTURE)
-
- if (!video_capture_device) {
- device_client->OnError(FROM_HERE, "Could not create capture device");
- return nullptr;
- }
+void VideoCaptureManager::OnDeviceStartFailed(
+ VideoCaptureController* controller) {
+ const std::string log_message = base::StringPrintf(
+ "Starting device %s has failed. Maybe recently disconnected?",
+ controller->device_id().c_str());
+ DLOG(ERROR) << log_message;
+ controller->OnLog(log_message);
+ controller->OnError();
- video_capture_device->AllocateAndStart(params, std::move(device_client));
- return video_capture_device;
+ device_start_queue_.pop_front();
+ HandleQueuedStartRequest();
}
void VideoCaptureManager::StartCaptureForClient(
@@ -715,8 +468,9 @@ void VideoCaptureManager::StartCaptureForClient(
DVLOG(1) << __func__ << ", session_id = " << session_id << ", request: "
<< media::VideoCaptureFormat::ToString(params.requested_format);
- DeviceEntry* entry = GetOrCreateDeviceEntry(session_id, params);
- if (!entry) {
+ VideoCaptureController* controller =
+ GetOrCreateController(session_id, params);
+ if (!controller) {
done_cb.Run(base::WeakPtr<VideoCaptureController>());
return;
}
@@ -724,16 +478,14 @@ void VideoCaptureManager::StartCaptureForClient(
LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE);
// First client starts the device.
- if (!entry->video_capture_controller.HasActiveClient() &&
- !entry->video_capture_controller.HasPausedClient()) {
- DVLOG(1) << "VideoCaptureManager starting device (type = "
- << entry->stream_type << ", id = " << entry->id << ")";
- QueueStartDevice(session_id, entry, params);
+ if (!controller->HasActiveClient() && !controller->HasPausedClient()) {
+ DVLOG(1) << "VideoCaptureManager starting device (id = "
+ << controller->device_id() << ")";
+ QueueStartDevice(session_id, controller, params);
}
// Run the callback first, as AddClient() may trigger OnFrameInfo().
- done_cb.Run(entry->video_capture_controller.GetWeakPtrForIOThread());
- entry->video_capture_controller.AddClient(client_id, client_handler,
- session_id, params);
+ done_cb.Run(controller->GetWeakPtrForIOThread());
+ controller->AddClient(client_id, client_handler, session_id, params);
}
void VideoCaptureManager::StopCaptureForClient(
@@ -745,15 +497,14 @@ void VideoCaptureManager::StopCaptureForClient(
DCHECK(controller);
DCHECK(client_handler);
- DeviceEntry* entry = GetDeviceEntryByController(controller);
- if (!entry) {
+ if (!IsControllerPointerValid(controller)) {
NOTREACHED();
return;
}
if (!aborted_due_to_error) {
if (controller->has_received_frames()) {
LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_OK);
- } else if (entry->stream_type == MEDIA_DEVICE_VIDEO_CAPTURE) {
+ } else if (controller->stream_type() == MEDIA_DEVICE_VIDEO_CAPTURE) {
LogVideoCaptureEvent(
VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE);
} else {
@@ -763,12 +514,12 @@ void VideoCaptureManager::StopCaptureForClient(
} else {
LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR);
for (auto it : sessions_) {
- if (it.second.type == entry->stream_type && it.second.id == entry->id) {
+ if (it.second.type == controller->stream_type() &&
+ it.second.id == controller->device_id()) {
for (auto& listener : listeners_)
listener.Aborted(it.second.type, it.first);
- // Aborted() call might synchronously destroy |entry|, recheck.
- entry = GetDeviceEntryByController(controller);
- if (!entry)
+ // Aborted() call might synchronously destroy |controller|, recheck.
+ if (!IsControllerPointerValid(controller))
return;
break;
}
@@ -781,7 +532,7 @@ void VideoCaptureManager::StopCaptureForClient(
DVLOG(1) << __func__ << ", session_id = " << session_id;
// If controller has no more clients, delete controller and device.
- DestroyDeviceEntryIfNoClients(entry);
+ DestroyControllerIfNoClients(controller);
}
void VideoCaptureManager::PauseCaptureForClient(
@@ -791,24 +542,16 @@ void VideoCaptureManager::PauseCaptureForClient(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(controller);
DCHECK(client_handler);
- DeviceEntry* entry = GetDeviceEntryByController(controller);
- if (!entry)
- NOTREACHED() << "Got Null entry while pausing capture";
+ if (!IsControllerPointerValid(controller))
+ NOTREACHED() << "Got Null controller while pausing capture";
const bool had_active_client = controller->HasActiveClient();
controller->PauseClient(client_id, client_handler);
if (!had_active_client || controller->HasActiveClient())
return;
- if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) {
- device_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&VideoCaptureDevice::MaybeSuspend,
- // Unretained is safe to use here because |device| would be
- // null if it was scheduled for shutdown and destruction, and
- // because this task is guaranteed to run before the task
- // that destroys the |device|.
- base::Unretained(device)));
- }
+ if (!controller->IsDeviceAlive())
+ return;
+ controller->MaybeSuspend();
}
void VideoCaptureManager::ResumeCaptureForClient(
@@ -821,41 +564,26 @@ void VideoCaptureManager::ResumeCaptureForClient(
DCHECK(controller);
DCHECK(client_handler);
- DeviceEntry* entry = GetDeviceEntryByController(controller);
- if (!entry)
- NOTREACHED() << "Got Null entry while resuming capture";
+ if (!IsControllerPointerValid(controller))
+ NOTREACHED() << "Got Null controller while resuming capture";
const bool had_active_client = controller->HasActiveClient();
controller->ResumeClient(client_id, client_handler);
if (had_active_client || !controller->HasActiveClient())
return;
- if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) {
- device_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&VideoCaptureDevice::Resume,
- // Unretained is safe to use here because |device| would be
- // null if it was scheduled for shutdown and destruction, and
- // because this task is guaranteed to run before the task
- // that destroys the |device|.
- base::Unretained(device)));
- }
+ if (!controller->IsDeviceAlive())
+ return;
+ controller->Resume();
}
void VideoCaptureManager::RequestRefreshFrameForClient(
VideoCaptureController* controller) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (DeviceEntry* entry = GetDeviceEntryByController(controller)) {
- if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) {
- device_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&VideoCaptureDevice::RequestRefreshFrame,
- // Unretained is safe to use here because |device| would be
- // null if it was scheduled for shutdown and destruction,
- // and because this task is guaranteed to run before the
- // task that destroys the |device|.
- base::Unretained(device)));
- }
+ if (IsControllerPointerValid(controller)) {
+ if (!controller->IsDeviceAlive())
+ return;
+ controller->RequestRefreshFrame();
}
}
@@ -907,12 +635,11 @@ bool VideoCaptureManager::GetDeviceFormatsInUse(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(formats_in_use->empty());
// Return the currently in-use format(s) of the device, if it's started.
- DeviceEntry* device_in_use =
- GetDeviceEntryByTypeAndId(stream_type, device_id);
+ VideoCaptureController* device_in_use =
+ LookupControllerByTypeAndId(stream_type, device_id);
if (device_in_use) {
// Currently only one format-in-use is supported at the VCC level.
- formats_in_use->push_back(
- device_in_use->video_capture_controller.GetVideoCaptureFormat());
+ formats_in_use->push_back(device_in_use->GetVideoCaptureFormat());
}
return true;
}
@@ -933,20 +660,20 @@ void VideoCaptureManager::MaybePostDesktopCaptureWindowId(
if (session_it == sessions_.end())
return;
- DeviceEntry* const existing_device =
- GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id);
+ VideoCaptureController* const existing_device = LookupControllerByTypeAndId(
+ session_it->second.type, session_it->second.id);
if (!existing_device) {
DVLOG(2) << "Failed to find an existing screen capture device.";
return;
}
- if (!existing_device->video_capture_device) {
+ if (!existing_device->IsDeviceAlive()) {
DVLOG(2) << "Screen capture device not yet started.";
return;
}
- DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type);
- DesktopMediaID id = DesktopMediaID::Parse(existing_device->id);
+ DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type());
+ DesktopMediaID id = DesktopMediaID::Parse(existing_device->device_id());
if (id.is_null())
return;
@@ -956,83 +683,70 @@ void VideoCaptureManager::MaybePostDesktopCaptureWindowId(
return;
}
- // Post |existing_device->video_capture_device| to the VideoCaptureDevice to
- // the device_task_runner_. This is safe since the device is destroyed on the
- // device_task_runner_.
- device_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread,
- this, existing_device->video_capture_device.get(),
- window_id_it->second));
-
+ existing_device->SetDesktopCaptureWindowIdAsync(
+ window_id_it->second,
+ base::Bind([](scoped_refptr<VideoCaptureManager>) {},
+ scoped_refptr<VideoCaptureManager>(this)));
notification_window_ids_.erase(window_id_it);
}
void VideoCaptureManager::GetPhotoCapabilities(
int session_id,
- VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
+ media::VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
- if (!entry)
+ const VideoCaptureController* controller =
+ LookupControllerBySessionId(session_id);
+ if (!controller)
return;
- VideoCaptureDevice* device = entry->video_capture_device.get();
- if (device) {
- VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device);
+ if (controller->IsDeviceAlive()) {
+ controller->GetPhotoCapabilities(std::move(callback));
return;
}
- // |entry| is known but |device| is nullptr, queue up a request for later.
+ // Queue up a request for later.
photo_request_queue_.emplace_back(
- session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this,
- base::Passed(&callback)));
+ session_id,
+ base::Bind(&VideoCaptureController::GetPhotoCapabilities,
+ base::Unretained(controller), base::Passed(&callback)));
}
void VideoCaptureManager::SetPhotoOptions(
int session_id,
media::mojom::PhotoSettingsPtr settings,
- VideoCaptureDevice::SetPhotoOptionsCallback callback) {
+ media::VideoCaptureDevice::SetPhotoOptionsCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
- if (!entry)
+ VideoCaptureController* controller = LookupControllerBySessionId(session_id);
+ if (!controller)
return;
- VideoCaptureDevice* device = entry->video_capture_device.get();
- if (device) {
- VideoCaptureManager::DoSetPhotoOptions(std::move(callback),
- std::move(settings), device);
+ if (controller->IsDeviceAlive()) {
+ controller->SetPhotoOptions(std::move(settings), std::move(callback));
return;
}
- // |entry| is known but |device| is nullptr, queue up a request for later.
+ // Queue up a request for later.
photo_request_queue_.emplace_back(
- session_id, base::Bind(&VideoCaptureManager::DoSetPhotoOptions, this,
- base::Passed(&callback), base::Passed(&settings)));
+ session_id, base::Bind(&VideoCaptureController::SetPhotoOptions,
+ base::Unretained(controller),
+ base::Passed(&settings), base::Passed(&callback)));
}
void VideoCaptureManager::TakePhoto(
int session_id,
- VideoCaptureDevice::TakePhotoCallback callback) {
+ media::VideoCaptureDevice::TakePhotoCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
- if (!entry)
+ VideoCaptureController* controller = LookupControllerBySessionId(session_id);
+ if (!controller)
return;
- VideoCaptureDevice* device = entry->video_capture_device.get();
- if (device) {
- VideoCaptureManager::DoTakePhoto(std::move(callback), device);
+ if (controller->IsDeviceAlive()) {
+ controller->TakePhoto(std::move(callback));
return;
}
- // |entry| is known but |device| is nullptr, queue up a request for later.
+ // Queue up a request for later.
photo_request_queue_.emplace_back(
- session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this,
- base::Passed(&callback)));
-}
-
-void VideoCaptureManager::DoStopDeviceOnDeviceThread(
- std::unique_ptr<VideoCaptureDevice> device) {
- SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
- DCHECK(IsOnDeviceThread());
- device->StopAndDeAllocate();
- DVLOG(3) << "DoStopDeviceOnDeviceThread";
+ session_id,
+ base::Bind(&VideoCaptureController::TakePhoto,
+ base::Unretained(controller), base::Passed(&callback)));
}
void VideoCaptureManager::OnOpened(
@@ -1070,9 +784,6 @@ void VideoCaptureManager::OnDevicesInfoEnumerated(
for (const auto& it : devices_info_cache_) {
devices.emplace_back(it.descriptor);
descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats);
- }
-
- if (!descriptors_and_formats.empty()) {
MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities(
descriptors_and_formats);
}
@@ -1080,16 +791,12 @@ void VideoCaptureManager::OnDevicesInfoEnumerated(
client_callback.Run(devices);
}
-bool VideoCaptureManager::IsOnDeviceThread() const {
- return device_task_runner_->BelongsToCurrentThread();
-}
-
void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread(
base::Callback<void(const VideoCaptureManager::DeviceInfos&)>
on_devices_enumerated_callback,
const VideoCaptureManager::DeviceInfos& old_device_info_cache,
std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors_snapshot) {
- DCHECK(IsOnDeviceThread());
+ DCHECK(device_task_runner_->BelongsToCurrentThread());
// 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.
@@ -1118,73 +825,79 @@ void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread(
on_devices_enumerated_callback.Run(new_devices_info_cache);
}
-void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) {
+void VideoCaptureManager::DestroyControllerIfNoClients(
+ VideoCaptureController* controller) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Removal of the last client stops the device.
- if (!entry->video_capture_controller.HasActiveClient() &&
- !entry->video_capture_controller.HasPausedClient()) {
+ if (!controller->HasActiveClient() && !controller->HasPausedClient()) {
DVLOG(1) << "VideoCaptureManager stopping device (type = "
- << entry->stream_type << ", id = " << entry->id << ")";
-
- // The DeviceEntry is removed from |devices_| immediately. The controller is
- // deleted immediately, and the device is freed asynchronously. After this
- // point, subsequent requests to open this same device ID will create a new
- // DeviceEntry, VideoCaptureController, and VideoCaptureDevice.
- DoStopDevice(entry);
+ << controller->stream_type()
+ << ", id = " << controller->device_id() << ")";
+
+ // The VideoCaptureController is removed from |controllers_| immediately.
+ // The controller is deleted immediately, and the device is freed
+ // asynchronously. After this point, subsequent requests to open this same
+ // device ID will create a new VideoCaptureController,
+ // VideoCaptureController, and VideoCaptureDevice.
+ DoStopDevice(controller);
// TODO(mcasas): use a helper function https://crbug.com/624854.
- DeviceEntries::iterator device_it =
- std::find_if(devices_.begin(), devices_.end(),
- [entry](const std::unique_ptr<DeviceEntry>& device_entry) {
- return device_entry.get() == entry;
- });
- devices_.erase(device_it);
+ auto controller_iter = std::find_if(
+ controllers_.begin(), controllers_.end(),
+ [controller](
+ const scoped_refptr<VideoCaptureController>& device_entry) {
+ return device_entry.get() == controller;
+ });
+ controllers_.erase(controller_iter);
}
}
-VideoCaptureManager::DeviceEntry*
-VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) {
+VideoCaptureController* VideoCaptureManager::LookupControllerBySessionId(
+ int session_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
SessionMap::const_iterator session_it = sessions_.find(session_id);
if (session_it == sessions_.end())
return nullptr;
- return GetDeviceEntryByTypeAndId(session_it->second.type,
- session_it->second.id);
+ return LookupControllerByTypeAndId(session_it->second.type,
+ session_it->second.id);
}
-VideoCaptureManager::DeviceEntry*
-VideoCaptureManager::GetDeviceEntryByTypeAndId(
+VideoCaptureController* VideoCaptureManager::LookupControllerByTypeAndId(
MediaStreamType type,
const std::string& device_id) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- for (const std::unique_ptr<DeviceEntry>& device : devices_) {
- if (type == device->stream_type && device_id == device->id)
- return device.get();
+ for (const auto& entry : controllers_) {
+ if (type == entry->stream_type() && device_id == entry->device_id())
+ return entry.get();
}
return nullptr;
}
-VideoCaptureManager::DeviceEntry*
-VideoCaptureManager::GetDeviceEntryByController(
+bool VideoCaptureManager::IsControllerPointerValid(
const VideoCaptureController* controller) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ return base::ContainsValue(controllers_, controller);
+}
- // Look up |controller| in |devices_|.
- for (const std::unique_ptr<DeviceEntry>& device : devices_) {
- if (&device->video_capture_controller == controller)
- return device.get();
+VideoCaptureController* VideoCaptureManager::LookupControllerBySerialId(
+ int serial_id) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ for (const auto& entry : controllers_) {
+ if (entry->serial_id() == serial_id)
+ return entry.get();
}
return nullptr;
}
-VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId(
- int serial_id) const {
+scoped_refptr<VideoCaptureController>
+VideoCaptureManager::GetControllerSharedRefFromSerialId(int serial_id) const {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- for (const std::unique_ptr<DeviceEntry>& device : devices_) {
- if (device->serial_id == serial_id)
- return device.get();
+ for (const auto& entry : controllers_) {
+ if (entry->serial_id() == serial_id)
+ return entry;
}
return nullptr;
}
@@ -1198,7 +911,7 @@ VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById(
return nullptr;
}
-VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
+VideoCaptureController* VideoCaptureManager::GetOrCreateController(
media::VideoCaptureSessionId capture_session_id,
const media::VideoCaptureParams& params) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -1210,63 +923,19 @@ VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
// Check if another session has already opened this device. If so, just
// use that opened device.
- DeviceEntry* const existing_device =
- GetDeviceEntryByTypeAndId(device_info.type, device_info.id);
+ VideoCaptureController* const existing_device =
+ LookupControllerByTypeAndId(device_info.type, device_info.id);
if (existing_device) {
- DCHECK_EQ(device_info.type, existing_device->stream_type);
+ DCHECK_EQ(device_info.type, existing_device->stream_type());
return existing_device;
}
- devices_.emplace_back(
- new DeviceEntry(device_info.type, device_info.id, params));
- return devices_.back().get();
-}
-
-void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread(
- media::VideoCaptureDevice* device,
- gfx::NativeViewId window_id) {
- DCHECK(IsOnDeviceThread());
-#if defined(ENABLE_SCREEN_CAPTURE) && BUILDFLAG(ENABLE_WEBRTC) && !defined(OS_ANDROID)
- DesktopCaptureDevice* desktop_device =
- static_cast<DesktopCaptureDevice*>(device);
- desktop_device->SetNotificationWindowId(window_id);
- VLOG(2) << "Screen capture notification window passed on device thread.";
-#endif
-}
-
-void VideoCaptureManager::DoGetPhotoCapabilities(
- VideoCaptureDevice::GetPhotoCapabilitiesCallback callback,
- VideoCaptureDevice* device) {
- // Unretained() is safe to use here because |device| would be null if it
- // was scheduled for shutdown and destruction, and because this task is
- // guaranteed to run before the task that destroys the |device|.
- device_task_runner_->PostTask(
- FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities,
- base::Unretained(device), base::Passed(&callback)));
-}
-
-void VideoCaptureManager::DoSetPhotoOptions(
- VideoCaptureDevice::SetPhotoOptionsCallback callback,
- media::mojom::PhotoSettingsPtr settings,
- VideoCaptureDevice* device) {
- // Unretained() is safe to use here because |device| would be null if it
- // was scheduled for shutdown and destruction, and because this task is
- // guaranteed to run before the task that destroys the |device|.
- device_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device),
- base::Passed(&settings), base::Passed(&callback)));
-}
-
-void VideoCaptureManager::DoTakePhoto(
- VideoCaptureDevice::TakePhotoCallback callback,
- VideoCaptureDevice* device) {
- // Unretained() is safe to use here because |device| would be null if it
- // was scheduled for shutdown and destruction, and because this task is
- // guaranteed to run before the task that destroys the |device|.
- device_task_runner_->PostTask(
- FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto,
- base::Unretained(device), base::Passed(&callback)));
+ VideoCaptureController* new_device_entry = new VideoCaptureController(
+ device_info.id, device_info.type, params,
+ base::MakeUnique<InProcessBuildableVideoCaptureDevice>(
+ device_task_runner_, video_capture_device_factory_.get()));
+ controllers_.emplace_back(new_device_entry);
+ return new_device_entry;
}
base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration(
@@ -1297,29 +966,29 @@ void VideoCaptureManager::OnApplicationStateChange(
void VideoCaptureManager::ReleaseDevices() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- for (auto& entry : devices_) {
+ for (auto& controller : controllers_) {
// Do not stop Content Video Capture devices, e.g. Tab or Screen capture.
- if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE)
+ if (controller->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE)
continue;
- DoStopDevice(entry.get());
+ DoStopDevice(controller.get());
}
}
void VideoCaptureManager::ResumeDevices() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- for (auto& entry : devices_) {
+ for (auto& controller : controllers_) {
// Do not resume Content Video Capture devices, e.g. Tab or Screen capture.
// Do not try to restart already running devices.
- if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE ||
- entry->video_capture_device)
+ if (controller->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE ||
+ controller->IsDeviceAlive())
continue;
// Check if the device is already in the start queue.
bool device_in_queue = false;
for (auto& request : device_start_queue_) {
- if (request.serial_id() == entry->serial_id) {
+ if (request.serial_id() == controller->serial_id()) {
device_in_queue = true;
break;
}
@@ -1328,7 +997,8 @@ void VideoCaptureManager::ResumeDevices() {
if (!device_in_queue) {
// Session ID is only valid for Screen capture. So we can fake it to
// resume video capture devices here.
- QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters);
+ QueueStartDevice(kFakeSessionId, controller.get(),
+ controller->parameters());
}
}
}
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698