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

Side by Side Diff: content/renderer/media/video_capture_impl_manager.cc

Issue 242013002: Refactor video capturing code in the render process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged again :( Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 //
5 // Implementation notes about interactions with VideoCaptureImpl.
6 //
7 // VideoCaptureImpl is an IO thread object while VideoCaptureImplManager
8 // lives only on the render thread. It is only possible to access an
9 // object of VideoCaptureImpl via a task on the IO thread.
10 // It is accessed with Unretained() because it is deleted only after
11 // there is no reference to it.
Ami GONE FROM CHROMIUM 2014/04/24 21:04:31 This sentence makes me wonder what sort of "refere
Alpha Left Google 2014/04/24 22:50:34 Done.
12 // An object of VideoCaptureImpl is deleted when VideoCaptureImplManager
13 // is destroyed or there is no client using it.
4 14
5 #include "content/renderer/media/video_capture_impl_manager.h" 15 #include "content/renderer/media/video_capture_impl_manager.h"
6 16
7 #include "base/bind.h" 17 #include "base/bind.h"
8 #include "base/bind_helpers.h" 18 #include "base/bind_helpers.h"
9 #include "content/public/renderer/render_thread.h" 19 #include "content/child/child_process.h"
10 #include "content/renderer/media/video_capture_impl.h" 20 #include "content/renderer/media/video_capture_impl.h"
11 #include "content/renderer/media/video_capture_message_filter.h" 21 #include "content/renderer/media/video_capture_message_filter.h"
12 #include "media/base/bind_to_current_loop.h" 22 #include "media/base/bind_to_current_loop.h"
13 23
14 namespace content { 24 namespace content {
15 25
16 VideoCaptureHandle::VideoCaptureHandle(
17 media::VideoCapture* impl, base::Closure destruction_cb)
18 : impl_(impl), destruction_cb_(destruction_cb) {
19 }
20
21 VideoCaptureHandle::~VideoCaptureHandle() {
22 destruction_cb_.Run();
23 }
24
25 void VideoCaptureHandle::StartCapture(
26 EventHandler* handler,
27 const media::VideoCaptureParams& params) {
28 impl_->StartCapture(handler, params);
29 }
30
31 void VideoCaptureHandle::StopCapture(EventHandler* handler) {
32 impl_->StopCapture(handler);
33 }
34
35 bool VideoCaptureHandle::CaptureStarted() {
36 return impl_->CaptureStarted();
37 }
38
39 int VideoCaptureHandle::CaptureFrameRate() {
40 return impl_->CaptureFrameRate();
41 }
42
43 void VideoCaptureHandle::GetDeviceSupportedFormats(
44 const DeviceFormatsCallback& callback) {
45 impl_->GetDeviceSupportedFormats(callback);
46 }
47
48 void VideoCaptureHandle::GetDeviceFormatsInUse(
49 const DeviceFormatsInUseCallback& callback) {
50 impl_->GetDeviceFormatsInUse(callback);
51 }
52
53 VideoCaptureImplManager::VideoCaptureImplManager() 26 VideoCaptureImplManager::VideoCaptureImplManager()
54 : filter_(new VideoCaptureMessageFilter()), 27 : next_client_id_(0),
28 filter_(new VideoCaptureMessageFilter()),
55 weak_factory_(this) { 29 weak_factory_(this) {
56 } 30 }
57 31
58 VideoCaptureImplManager::~VideoCaptureImplManager() { 32 VideoCaptureImplManager::~VideoCaptureImplManager() {
59 DCHECK(thread_checker_.CalledOnValidThread()); 33 DCHECK(thread_checker_.CalledOnValidThread());
34 if (devices_.empty())
35 return;
36 // Forcibly release all video capture resources.
37 for (VideoCaptureDeviceMap::iterator it = devices_.begin();
38 it != devices_.end(); ++it) {
39 VideoCaptureImpl* impl = it->second.second;
40 ChildProcess::current()->io_message_loop_proxy()->PostTask(
Ami GONE FROM CHROMIUM 2014/04/24 21:04:31 I don't follow. I said that the construct you're u
Alpha Left Google 2014/04/24 22:50:34 You said:
41 FROM_HERE,
42 base::Bind(&VideoCaptureImpl::DeInit,
43 base::Unretained(impl)));
44 ChildProcess::current()->io_message_loop_proxy()->PostTask(
45 FROM_HERE,
46 base::Bind(&base::DeletePointer<VideoCaptureImpl>,
47 base::Unretained(impl)));
48 }
49 devices_.clear();
60 } 50 }
61 51
62 scoped_ptr<VideoCaptureHandle> VideoCaptureImplManager::UseDevice( 52 base::Closure VideoCaptureImplManager::UseDevice(
63 media::VideoCaptureSessionId id) { 53 media::VideoCaptureSessionId id) {
64 DCHECK(thread_checker_.CalledOnValidThread()); 54 DCHECK(thread_checker_.CalledOnValidThread());
65 55
66 VideoCaptureImpl* video_capture_device = NULL; 56 VideoCaptureImpl* impl = NULL;
67 VideoCaptureDeviceMap::iterator it = devices_.find(id); 57 VideoCaptureDeviceMap::iterator it = devices_.find(id);
68 if (it == devices_.end()) { 58 if (it == devices_.end()) {
69 video_capture_device = CreateVideoCaptureImpl(id, filter_.get()); 59 impl = CreateVideoCaptureImplForTesting(id, filter_.get());
70 devices_[id] = 60 if (!impl)
71 std::make_pair(1, linked_ptr<VideoCaptureImpl>(video_capture_device)); 61 impl = new VideoCaptureImpl(id, filter_.get());
72 video_capture_device->Init(); 62 devices_[id] = std::make_pair(1, impl);
63 ChildProcess::current()->io_message_loop_proxy()->PostTask(
64 FROM_HERE,
65 base::Bind(&VideoCaptureImpl::Init,
66 base::Unretained(impl)));
73 } else { 67 } else {
74 ++it->second.first; 68 ++it->second.first;
75 video_capture_device = it->second.second.get();
76 } 69 }
77 70 return base::Bind(&VideoCaptureImplManager::UnrefDevice,
78 // This callback ensures UnrefDevice() happens on the render thread. 71 weak_factory_.GetWeakPtr(), id);
79 return scoped_ptr<VideoCaptureHandle>(
80 new VideoCaptureHandle(
81 video_capture_device,
82 media::BindToCurrentLoop(
83 base::Bind(
84 &VideoCaptureImplManager::UnrefDevice,
85 weak_factory_.GetWeakPtr(),
86 id))));
87 } 72 }
88 73
89 VideoCaptureImpl* VideoCaptureImplManager::CreateVideoCaptureImpl( 74 base::Closure VideoCaptureImplManager::StartCapture(
75 media::VideoCaptureSessionId id,
76 const media::VideoCaptureParams& params,
77 const VideoCaptureStateUpdateCB& state_update_cb,
78 const VideoCaptureDeliverFrameCB& deliver_frame_cb) {
79 DCHECK(thread_checker_.CalledOnValidThread());
80 VideoCaptureDeviceMap::iterator it = devices_.find(id);
81 DCHECK(it != devices_.end());
82 VideoCaptureImpl* impl = it->second.second;
83
84 // This ID is used to identify a client of VideoCaptureImpl.
85 const int client_id = ++next_client_id_;
86
87 ChildProcess::current()->io_message_loop_proxy()->PostTask(
88 FROM_HERE,
89 base::Bind(&VideoCaptureImpl::StartCapture,
90 base::Unretained(impl),
91 client_id,
92 params,
93 state_update_cb,
94 deliver_frame_cb));
95 return base::Bind(&VideoCaptureImplManager::StopCapture,
96 weak_factory_.GetWeakPtr(),
97 client_id, id);
98 }
99
100 void VideoCaptureImplManager::GetDeviceSupportedFormats(
101 media::VideoCaptureSessionId id,
102 const VideoCaptureDeviceFormatsCB& callback) {
103 DCHECK(thread_checker_.CalledOnValidThread());
104 VideoCaptureDeviceMap::iterator it = devices_.find(id);
105 DCHECK(it != devices_.end());
106 VideoCaptureImpl* impl = it->second.second;
107 ChildProcess::current()->io_message_loop_proxy()->PostTask(
108 FROM_HERE,
109 base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormats,
110 base::Unretained(impl), callback));
111 }
112
113 void VideoCaptureImplManager::GetDeviceFormatsInUse(
114 media::VideoCaptureSessionId id,
115 const VideoCaptureDeviceFormatsCB& callback) {
116 DCHECK(thread_checker_.CalledOnValidThread());
117 VideoCaptureDeviceMap::iterator it = devices_.find(id);
118 DCHECK(it != devices_.end());
119 VideoCaptureImpl* impl = it->second.second;
120 ChildProcess::current()->io_message_loop_proxy()->PostTask(
121 FROM_HERE,
122 base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUse,
123 base::Unretained(impl), callback));
124 }
125
126 VideoCaptureImpl*
127 VideoCaptureImplManager::CreateVideoCaptureImplForTesting(
90 media::VideoCaptureSessionId id, 128 media::VideoCaptureSessionId id,
91 VideoCaptureMessageFilter* filter) const { 129 VideoCaptureMessageFilter* filter) const {
92 return new VideoCaptureImpl(id, filter); 130 return NULL;
131 }
132
133 void VideoCaptureImplManager::StopCapture(
134 int client_id, media::VideoCaptureSessionId id) {
135 DCHECK(thread_checker_.CalledOnValidThread());
136 VideoCaptureDeviceMap::iterator it = devices_.find(id);
137 DCHECK(it != devices_.end());
138 VideoCaptureImpl* impl = it->second.second;
139 ChildProcess::current()->io_message_loop_proxy()->PostTask(
140 FROM_HERE,
141 base::Bind(&VideoCaptureImpl::StopCapture,
142 base::Unretained(impl), client_id));
93 } 143 }
94 144
95 void VideoCaptureImplManager::UnrefDevice( 145 void VideoCaptureImplManager::UnrefDevice(
96 media::VideoCaptureSessionId id) { 146 media::VideoCaptureSessionId id) {
97 DCHECK(thread_checker_.CalledOnValidThread()); 147 DCHECK(thread_checker_.CalledOnValidThread());
98 VideoCaptureDeviceMap::iterator it = devices_.find(id); 148 VideoCaptureDeviceMap::iterator it = devices_.find(id);
99 DCHECK(it != devices_.end()); 149 DCHECK(it != devices_.end());
150 VideoCaptureImpl* impl = it->second.second;
100 151
152 // Unref and destroy on the IO thread if there's no more client.
101 DCHECK(it->second.first); 153 DCHECK(it->second.first);
102 --it->second.first; 154 --it->second.first;
103 if (!it->second.first) { 155 if (!it->second.first) {
104 VideoCaptureImpl* impl = it->second.second.release();
105 devices_.erase(id); 156 devices_.erase(id);
106 impl->DeInit(base::Bind(&base::DeletePointer<VideoCaptureImpl>, impl)); 157 ChildProcess::current()->io_message_loop_proxy()->PostTask(
158 FROM_HERE,
159 base::Bind(&VideoCaptureImpl::DeInit,
160 base::Unretained(impl)));
161 ChildProcess::current()->io_message_loop_proxy()->PostTask(
162 FROM_HERE,
163 base::Bind(&base::DeletePointer<VideoCaptureImpl>,
164 base::Unretained(impl)));
107 } 165 }
108 } 166 }
109 167
110 void VideoCaptureImplManager::SuspendDevices(bool suspend) { 168 void VideoCaptureImplManager::SuspendDevices(bool suspend) {
111 DCHECK(thread_checker_.CalledOnValidThread()); 169 DCHECK(thread_checker_.CalledOnValidThread());
112 for (VideoCaptureDeviceMap::iterator it = devices_.begin(); 170 for (VideoCaptureDeviceMap::iterator it = devices_.begin();
113 it != devices_.end(); ++it) 171 it != devices_.end(); ++it) {
114 it->second.second->SuspendCapture(suspend); 172 VideoCaptureImpl* impl = it->second.second;
173 ChildProcess::current()->io_message_loop_proxy()->PostTask(
174 FROM_HERE,
175 base::Bind(&VideoCaptureImpl::SuspendCapture,
176 base::Unretained(impl), suspend));
177 }
115 } 178 }
116 179
117 } // namespace content 180 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698