Roll src/third_party/WebKit a452221:9ff6d11 (svn 202117:202119)
[chromium-blink-merge.git] / content / renderer / media / video_capture_impl_manager.cc
blobec102bc31510f38f262a78b73eedb610d1ed3d8e
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
3 // found in the LICENSE file.
4 //
5 // Implementation notes about interactions with VideoCaptureImpl.
6 //
7 // How is VideoCaptureImpl used:
8 //
9 // VideoCaptureImpl is an IO thread object while VideoCaptureImplManager
10 // lives only on the render thread. It is only possible to access an
11 // object of VideoCaptureImpl via a task on the IO thread.
13 // How is VideoCaptureImpl deleted:
15 // A task is posted to the IO thread to delete a VideoCaptureImpl.
16 // Immediately after that the pointer to it is dropped. This means no
17 // access to this VideoCaptureImpl object is possible on the render
18 // thread. Also note that VideoCaptureImpl does not post task to itself.
20 // The use of Unretained:
22 // We make sure deletion is the last task on the IO thread for a
23 // VideoCaptureImpl object. This allows the use of Unretained() binding.
25 #include "content/renderer/media/video_capture_impl_manager.h"
27 #include "base/bind.h"
28 #include "base/bind_helpers.h"
29 #include "base/location.h"
30 #include "base/thread_task_runner_handle.h"
31 #include "content/child/child_process.h"
32 #include "content/renderer/media/video_capture_impl.h"
33 #include "content/renderer/media/video_capture_message_filter.h"
34 #include "media/base/bind_to_current_loop.h"
36 namespace content {
38 VideoCaptureImplManager::VideoCaptureImplManager()
39 : filter_(new VideoCaptureMessageFilter()),
40 render_main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
41 weak_factory_(this) {}
43 VideoCaptureImplManager::~VideoCaptureImplManager() {
44 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
45 if (devices_.empty())
46 return;
47 // Forcibly release all video capture resources.
48 for (const auto& device : devices_) {
49 VideoCaptureImpl* const impl = device.second;
50 ChildProcess::current()->io_task_runner()->PostTask(
51 FROM_HERE,
52 base::Bind(&VideoCaptureImpl::DeInit, base::Unretained(impl)));
53 ChildProcess::current()->io_task_runner()->DeleteSoon(FROM_HERE, impl);
55 devices_.clear();
58 base::Closure VideoCaptureImplManager::UseDevice(
59 media::VideoCaptureSessionId id) {
60 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
61 VideoCaptureDeviceMap::const_iterator it = devices_.find(id);
62 DCHECK(it == devices_.end())
63 << "UseDevice: This VideoCaptureSessionId is already in use.";
64 if (it != devices_.end())
65 return base::Closure();
67 VideoCaptureImpl* impl = CreateVideoCaptureImplForTesting(id, filter_.get());
68 if (!impl)
69 impl = new VideoCaptureImpl(id, filter_.get());
70 devices_[id] = impl;
71 ChildProcess::current()->io_task_runner()->PostTask(
72 FROM_HERE, base::Bind(&VideoCaptureImpl::Init, base::Unretained(impl)));
74 return base::Bind(&VideoCaptureImplManager::UnrefDevice,
75 weak_factory_.GetWeakPtr(), id);
78 base::Closure VideoCaptureImplManager::StartCapture(
79 media::VideoCaptureSessionId id,
80 const media::VideoCaptureParams& params,
81 const VideoCaptureStateUpdateCB& state_update_cb,
82 const VideoCaptureDeliverFrameCB& deliver_frame_cb) {
83 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
84 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id);
85 DCHECK(it != devices_.end());
86 VideoCaptureImpl* const impl = it->second;
88 ChildProcess::current()->io_task_runner()->PostTask(
89 FROM_HERE,
90 base::Bind(&VideoCaptureImpl::StartCapture, base::Unretained(impl),
91 params, state_update_cb, deliver_frame_cb));
92 return base::Bind(&VideoCaptureImplManager::StopCapture,
93 weak_factory_.GetWeakPtr(), id);
96 void VideoCaptureImplManager::GetDeviceSupportedFormats(
97 media::VideoCaptureSessionId id,
98 const VideoCaptureDeviceFormatsCB& callback) {
99 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
100 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id);
101 DCHECK(it != devices_.end());
102 VideoCaptureImpl* const impl = it->second;
103 ChildProcess::current()->io_task_runner()->PostTask(
104 FROM_HERE, base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormats,
105 base::Unretained(impl), callback));
108 void VideoCaptureImplManager::GetDeviceFormatsInUse(
109 media::VideoCaptureSessionId id,
110 const VideoCaptureDeviceFormatsCB& callback) {
111 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
112 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id);
113 DCHECK(it != devices_.end());
114 VideoCaptureImpl* const impl = it->second;
115 ChildProcess::current()->io_task_runner()->PostTask(
116 FROM_HERE, base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUse,
117 base::Unretained(impl), callback));
120 VideoCaptureImpl*
121 VideoCaptureImplManager::CreateVideoCaptureImplForTesting(
122 media::VideoCaptureSessionId id,
123 VideoCaptureMessageFilter* filter) const {
124 return NULL;
127 void VideoCaptureImplManager::StopCapture(media::VideoCaptureSessionId id) {
128 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
129 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id);
130 DCHECK(it != devices_.end());
131 VideoCaptureImpl* const impl = it->second;
132 ChildProcess::current()->io_task_runner()->PostTask(
133 FROM_HERE,
134 base::Bind(&VideoCaptureImpl::StopCapture, base::Unretained(impl)));
137 void VideoCaptureImplManager::UnrefDevice(
138 media::VideoCaptureSessionId id) {
139 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
140 const VideoCaptureDeviceMap::iterator it = devices_.find(id);
141 DCHECK(it != devices_.end());
142 VideoCaptureImpl* const impl = it->second;
144 // Unref and destroy on the IO thread if there's no more client.
145 devices_.erase(id);
146 ChildProcess::current()->io_task_runner()->PostTask(
147 FROM_HERE, base::Bind(&VideoCaptureImpl::DeInit, base::Unretained(impl)));
148 ChildProcess::current()->io_task_runner()->DeleteSoon(FROM_HERE, impl);
151 void VideoCaptureImplManager::SuspendDevices(bool suspend) {
152 DCHECK(render_main_task_runner_->BelongsToCurrentThread());
153 for (const auto& device : devices_) {
154 VideoCaptureImpl* const impl = device.second;
155 ChildProcess::current()->io_task_runner()->PostTask(
156 FROM_HERE, base::Bind(&VideoCaptureImpl::SuspendCapture,
157 base::Unretained(impl), suspend));
161 } // namespace content