OLD | NEW |
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 // | 4 // |
5 // Implementation notes about interactions with VideoCaptureImpl. | 5 // Implementation notes about interactions with VideoCaptureImpl. |
6 // | 6 // |
7 // How is VideoCaptureImpl used: | 7 // How is VideoCaptureImpl used: |
8 // | 8 // |
9 // VideoCaptureImpl is an IO thread object while VideoCaptureImplManager | 9 // VideoCaptureImpl is an IO thread object while VideoCaptureImplManager |
10 // lives only on the render thread. It is only possible to access an | 10 // lives only on the render thread. It is only possible to access an |
(...skipping 29 matching lines...) Expand all Loading... |
40 weak_factory_(this) { | 40 weak_factory_(this) { |
41 } | 41 } |
42 | 42 |
43 VideoCaptureImplManager::~VideoCaptureImplManager() { | 43 VideoCaptureImplManager::~VideoCaptureImplManager() { |
44 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 44 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
45 if (devices_.empty()) | 45 if (devices_.empty()) |
46 return; | 46 return; |
47 // Forcibly release all video capture resources. | 47 // Forcibly release all video capture resources. |
48 for (const auto& device : devices_) { | 48 for (const auto& device : devices_) { |
49 VideoCaptureImpl* const impl = device.second.second; | 49 VideoCaptureImpl* const impl = device.second.second; |
50 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 50 ChildProcess::current()->io_task_runner()->PostTask( |
51 FROM_HERE, | 51 FROM_HERE, |
52 base::Bind(&VideoCaptureImpl::DeInit, | 52 base::Bind(&VideoCaptureImpl::DeInit, base::Unretained(impl))); |
53 base::Unretained(impl))); | 53 ChildProcess::current()->io_task_runner()->DeleteSoon(FROM_HERE, impl); |
54 ChildProcess::current()->io_message_loop_proxy()->DeleteSoon(FROM_HERE, | |
55 impl); | |
56 } | 54 } |
57 devices_.clear(); | 55 devices_.clear(); |
58 } | 56 } |
59 | 57 |
60 base::Closure VideoCaptureImplManager::UseDevice( | 58 base::Closure VideoCaptureImplManager::UseDevice( |
61 media::VideoCaptureSessionId id) { | 59 media::VideoCaptureSessionId id) { |
62 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 60 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
63 | 61 |
64 VideoCaptureImpl* impl = NULL; | 62 VideoCaptureImpl* impl = NULL; |
65 const VideoCaptureDeviceMap::iterator it = devices_.find(id); | 63 const VideoCaptureDeviceMap::iterator it = devices_.find(id); |
66 if (it == devices_.end()) { | 64 if (it == devices_.end()) { |
67 impl = CreateVideoCaptureImplForTesting(id, filter_.get()); | 65 impl = CreateVideoCaptureImplForTesting(id, filter_.get()); |
68 if (!impl) | 66 if (!impl) |
69 impl = new VideoCaptureImpl(id, filter_.get()); | 67 impl = new VideoCaptureImpl(id, filter_.get()); |
70 devices_[id] = std::make_pair(1, impl); | 68 devices_[id] = std::make_pair(1, impl); |
71 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 69 ChildProcess::current()->io_task_runner()->PostTask( |
72 FROM_HERE, | 70 FROM_HERE, base::Bind(&VideoCaptureImpl::Init, base::Unretained(impl))); |
73 base::Bind(&VideoCaptureImpl::Init, | |
74 base::Unretained(impl))); | |
75 } else { | 71 } else { |
76 ++it->second.first; | 72 ++it->second.first; |
77 } | 73 } |
78 return base::Bind(&VideoCaptureImplManager::UnrefDevice, | 74 return base::Bind(&VideoCaptureImplManager::UnrefDevice, |
79 weak_factory_.GetWeakPtr(), id); | 75 weak_factory_.GetWeakPtr(), id); |
80 } | 76 } |
81 | 77 |
82 base::Closure VideoCaptureImplManager::StartCapture( | 78 base::Closure VideoCaptureImplManager::StartCapture( |
83 media::VideoCaptureSessionId id, | 79 media::VideoCaptureSessionId id, |
84 const media::VideoCaptureParams& params, | 80 const media::VideoCaptureParams& params, |
85 const VideoCaptureStateUpdateCB& state_update_cb, | 81 const VideoCaptureStateUpdateCB& state_update_cb, |
86 const VideoCaptureDeliverFrameCB& deliver_frame_cb) { | 82 const VideoCaptureDeliverFrameCB& deliver_frame_cb) { |
87 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 83 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
88 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 84 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
89 DCHECK(it != devices_.end()); | 85 DCHECK(it != devices_.end()); |
90 VideoCaptureImpl* const impl = it->second.second; | 86 VideoCaptureImpl* const impl = it->second.second; |
91 | 87 |
92 // This ID is used to identify a client of VideoCaptureImpl. | 88 // This ID is used to identify a client of VideoCaptureImpl. |
93 const int client_id = ++next_client_id_; | 89 const int client_id = ++next_client_id_; |
94 | 90 |
95 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 91 ChildProcess::current()->io_task_runner()->PostTask( |
96 FROM_HERE, | 92 FROM_HERE, |
97 base::Bind(&VideoCaptureImpl::StartCapture, | 93 base::Bind(&VideoCaptureImpl::StartCapture, base::Unretained(impl), |
98 base::Unretained(impl), | 94 client_id, params, state_update_cb, deliver_frame_cb)); |
99 client_id, | |
100 params, | |
101 state_update_cb, | |
102 deliver_frame_cb)); | |
103 return base::Bind(&VideoCaptureImplManager::StopCapture, | 95 return base::Bind(&VideoCaptureImplManager::StopCapture, |
104 weak_factory_.GetWeakPtr(), | 96 weak_factory_.GetWeakPtr(), |
105 client_id, id); | 97 client_id, id); |
106 } | 98 } |
107 | 99 |
108 void VideoCaptureImplManager::GetDeviceSupportedFormats( | 100 void VideoCaptureImplManager::GetDeviceSupportedFormats( |
109 media::VideoCaptureSessionId id, | 101 media::VideoCaptureSessionId id, |
110 const VideoCaptureDeviceFormatsCB& callback) { | 102 const VideoCaptureDeviceFormatsCB& callback) { |
111 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 103 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
112 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 104 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
113 DCHECK(it != devices_.end()); | 105 DCHECK(it != devices_.end()); |
114 VideoCaptureImpl* const impl = it->second.second; | 106 VideoCaptureImpl* const impl = it->second.second; |
115 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 107 ChildProcess::current()->io_task_runner()->PostTask( |
116 FROM_HERE, | 108 FROM_HERE, base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormats, |
117 base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormats, | 109 base::Unretained(impl), callback)); |
118 base::Unretained(impl), callback)); | |
119 } | 110 } |
120 | 111 |
121 void VideoCaptureImplManager::GetDeviceFormatsInUse( | 112 void VideoCaptureImplManager::GetDeviceFormatsInUse( |
122 media::VideoCaptureSessionId id, | 113 media::VideoCaptureSessionId id, |
123 const VideoCaptureDeviceFormatsCB& callback) { | 114 const VideoCaptureDeviceFormatsCB& callback) { |
124 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 115 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
125 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 116 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
126 DCHECK(it != devices_.end()); | 117 DCHECK(it != devices_.end()); |
127 VideoCaptureImpl* const impl = it->second.second; | 118 VideoCaptureImpl* const impl = it->second.second; |
128 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 119 ChildProcess::current()->io_task_runner()->PostTask( |
129 FROM_HERE, | 120 FROM_HERE, base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUse, |
130 base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUse, | 121 base::Unretained(impl), callback)); |
131 base::Unretained(impl), callback)); | |
132 } | 122 } |
133 | 123 |
134 VideoCaptureImpl* | 124 VideoCaptureImpl* |
135 VideoCaptureImplManager::CreateVideoCaptureImplForTesting( | 125 VideoCaptureImplManager::CreateVideoCaptureImplForTesting( |
136 media::VideoCaptureSessionId id, | 126 media::VideoCaptureSessionId id, |
137 VideoCaptureMessageFilter* filter) const { | 127 VideoCaptureMessageFilter* filter) const { |
138 return NULL; | 128 return NULL; |
139 } | 129 } |
140 | 130 |
141 void VideoCaptureImplManager::StopCapture(int client_id, | 131 void VideoCaptureImplManager::StopCapture(int client_id, |
142 media::VideoCaptureSessionId id) { | 132 media::VideoCaptureSessionId id) { |
143 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 133 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
144 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 134 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
145 DCHECK(it != devices_.end()); | 135 DCHECK(it != devices_.end()); |
146 VideoCaptureImpl* const impl = it->second.second; | 136 VideoCaptureImpl* const impl = it->second.second; |
147 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 137 ChildProcess::current()->io_task_runner()->PostTask( |
148 FROM_HERE, | 138 FROM_HERE, base::Bind(&VideoCaptureImpl::StopCapture, |
149 base::Bind(&VideoCaptureImpl::StopCapture, | 139 base::Unretained(impl), client_id)); |
150 base::Unretained(impl), client_id)); | |
151 } | 140 } |
152 | 141 |
153 void VideoCaptureImplManager::UnrefDevice( | 142 void VideoCaptureImplManager::UnrefDevice( |
154 media::VideoCaptureSessionId id) { | 143 media::VideoCaptureSessionId id) { |
155 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 144 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
156 const VideoCaptureDeviceMap::iterator it = devices_.find(id); | 145 const VideoCaptureDeviceMap::iterator it = devices_.find(id); |
157 DCHECK(it != devices_.end()); | 146 DCHECK(it != devices_.end()); |
158 VideoCaptureImpl* const impl = it->second.second; | 147 VideoCaptureImpl* const impl = it->second.second; |
159 | 148 |
160 // Unref and destroy on the IO thread if there's no more client. | 149 // Unref and destroy on the IO thread if there's no more client. |
161 DCHECK(it->second.first); | 150 DCHECK(it->second.first); |
162 --it->second.first; | 151 --it->second.first; |
163 if (!it->second.first) { | 152 if (!it->second.first) { |
164 devices_.erase(id); | 153 devices_.erase(id); |
165 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 154 ChildProcess::current()->io_task_runner()->PostTask( |
166 FROM_HERE, | 155 FROM_HERE, |
167 base::Bind(&VideoCaptureImpl::DeInit, | 156 base::Bind(&VideoCaptureImpl::DeInit, base::Unretained(impl))); |
168 base::Unretained(impl))); | 157 ChildProcess::current()->io_task_runner()->DeleteSoon(FROM_HERE, impl); |
169 ChildProcess::current()->io_message_loop_proxy()->DeleteSoon(FROM_HERE, | |
170 impl); | |
171 } | 158 } |
172 } | 159 } |
173 | 160 |
174 void VideoCaptureImplManager::SuspendDevices(bool suspend) { | 161 void VideoCaptureImplManager::SuspendDevices(bool suspend) { |
175 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); | 162 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
176 for (const auto& device : devices_) { | 163 for (const auto& device : devices_) { |
177 VideoCaptureImpl* const impl = device.second.second; | 164 VideoCaptureImpl* const impl = device.second.second; |
178 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 165 ChildProcess::current()->io_task_runner()->PostTask( |
179 FROM_HERE, base::Bind(&VideoCaptureImpl::SuspendCapture, | 166 FROM_HERE, base::Bind(&VideoCaptureImpl::SuspendCapture, |
180 base::Unretained(impl), suspend)); | 167 base::Unretained(impl), suspend)); |
181 } | 168 } |
182 } | 169 } |
183 | 170 |
184 } // namespace content | 171 } // namespace content |
OLD | NEW |