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 #include "content/renderer/media/video_capture_impl.h" | 5 #include "content/renderer/media/video_capture_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "content/common/child_process.h" | 9 #include "content/common/child_process.h" |
10 #include "content/common/media/video_capture_messages.h" | 10 #include "content/common/media/video_capture_messages.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 return current_params_.frame_per_second; | 43 return current_params_.frame_per_second; |
44 } | 44 } |
45 | 45 |
46 VideoCaptureImpl::VideoCaptureImpl( | 46 VideoCaptureImpl::VideoCaptureImpl( |
47 const media::VideoCaptureSessionId id, | 47 const media::VideoCaptureSessionId id, |
48 base::MessageLoopProxy* capture_message_loop_proxy, | 48 base::MessageLoopProxy* capture_message_loop_proxy, |
49 VideoCaptureMessageFilter* filter) | 49 VideoCaptureMessageFilter* filter) |
50 : VideoCapture(), | 50 : VideoCapture(), |
51 message_filter_(filter), | 51 message_filter_(filter), |
52 capture_message_loop_proxy_(capture_message_loop_proxy), | 52 capture_message_loop_proxy_(capture_message_loop_proxy), |
| 53 io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), |
53 device_id_(0), | 54 device_id_(0), |
54 video_type_(media::VideoCaptureCapability::kI420), | 55 video_type_(media::VideoCaptureCapability::kI420), |
55 device_info_available_(false), | 56 device_info_available_(false), |
56 state_(video_capture::kStopped) { | 57 state_(video_capture::kStopped) { |
57 DCHECK(filter); | 58 DCHECK(filter); |
58 memset(¤t_params_, 0, sizeof(current_params_)); | 59 memset(¤t_params_, 0, sizeof(current_params_)); |
59 memset(&device_info_, 0, sizeof(device_info_)); | 60 memset(&device_info_, 0, sizeof(device_info_)); |
60 current_params_.session_id = id; | 61 current_params_.session_id = id; |
61 } | 62 } |
62 | 63 |
63 VideoCaptureImpl::~VideoCaptureImpl() { | 64 VideoCaptureImpl::~VideoCaptureImpl() { |
64 STLDeleteContainerPairSecondPointers(cached_dibs_.begin(), | 65 STLDeleteValues(&cached_dibs_); |
65 cached_dibs_.end()); | |
66 } | 66 } |
67 | 67 |
68 void VideoCaptureImpl::Init() { | 68 void VideoCaptureImpl::Init() { |
69 io_message_loop_proxy_ = ChildProcess::current()->io_message_loop_proxy(); | |
70 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { | 69 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { |
71 io_message_loop_proxy_->PostTask(FROM_HERE, | 70 io_message_loop_proxy_->PostTask(FROM_HERE, |
72 base::Bind(&VideoCaptureImpl::AddDelegateOnIOThread, | 71 base::Bind(&VideoCaptureImpl::AddDelegateOnIOThread, |
73 base::Unretained(this))); | 72 base::Unretained(this))); |
74 return; | 73 } else { |
| 74 AddDelegateOnIOThread(); |
75 } | 75 } |
76 | |
77 AddDelegateOnIOThread(); | |
78 } | 76 } |
79 | 77 |
80 void VideoCaptureImpl::DeInit(base::Closure task) { | 78 void VideoCaptureImpl::DeInit(base::Closure task) { |
81 capture_message_loop_proxy_->PostTask(FROM_HERE, | 79 capture_message_loop_proxy_->PostTask(FROM_HERE, |
82 base::Bind(&VideoCaptureImpl::DoDeInit, | 80 base::Bind(&VideoCaptureImpl::DoDeInitOnCaptureThread, |
83 base::Unretained(this), task)); | |
84 } | |
85 | |
86 void VideoCaptureImpl::DoDeInit(base::Closure task) { | |
87 if (state_ == video_capture::kStarted) | |
88 Send(new VideoCaptureHostMsg_Stop(device_id_)); | |
89 | |
90 io_message_loop_proxy_->PostTask(FROM_HERE, | |
91 base::Bind(&VideoCaptureImpl::RemoveDelegateOnIOThread, | |
92 base::Unretained(this), task)); | 81 base::Unretained(this), task)); |
93 } | 82 } |
94 | 83 |
95 void VideoCaptureImpl::StartCapture( | 84 void VideoCaptureImpl::StartCapture( |
96 media::VideoCapture::EventHandler* handler, | 85 media::VideoCapture::EventHandler* handler, |
97 const media::VideoCaptureCapability& capability) { | 86 const media::VideoCaptureCapability& capability) { |
98 DCHECK_EQ(capability.color, media::VideoCaptureCapability::kI420); | 87 DCHECK_EQ(capability.color, media::VideoCaptureCapability::kI420); |
99 | 88 |
100 capture_message_loop_proxy_->PostTask(FROM_HERE, | 89 capture_message_loop_proxy_->PostTask(FROM_HERE, |
101 base::Bind(&VideoCaptureImpl::DoStartCapture, | 90 base::Bind(&VideoCaptureImpl::DoStartCaptureOnCaptureThread, |
102 base::Unretained(this), handler, capability)); | 91 base::Unretained(this), handler, capability)); |
103 } | 92 } |
104 | 93 |
105 void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { | 94 void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { |
106 capture_message_loop_proxy_->PostTask(FROM_HERE, | 95 capture_message_loop_proxy_->PostTask(FROM_HERE, |
107 base::Bind(&VideoCaptureImpl::DoStopCapture, | 96 base::Bind(&VideoCaptureImpl::DoStopCaptureOnCaptureThread, |
108 base::Unretained(this), handler)); | 97 base::Unretained(this), handler)); |
109 } | 98 } |
110 | 99 |
111 void VideoCaptureImpl::FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { | 100 void VideoCaptureImpl::FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { |
112 capture_message_loop_proxy_->PostTask(FROM_HERE, | 101 capture_message_loop_proxy_->PostTask(FROM_HERE, |
113 base::Bind(&VideoCaptureImpl::DoFeedBuffer, | 102 base::Bind(&VideoCaptureImpl::DoFeedBufferOnCaptureThread, |
114 base::Unretained(this), buffer)); | 103 base::Unretained(this), buffer)); |
115 } | 104 } |
116 | 105 |
117 void VideoCaptureImpl::OnBufferCreated( | 106 void VideoCaptureImpl::OnBufferCreated( |
118 base::SharedMemoryHandle handle, | 107 base::SharedMemoryHandle handle, |
119 int length, int buffer_id) { | 108 int length, int buffer_id) { |
120 capture_message_loop_proxy_->PostTask(FROM_HERE, | 109 capture_message_loop_proxy_->PostTask(FROM_HERE, |
121 base::Bind(&VideoCaptureImpl::DoBufferCreated, | 110 base::Bind(&VideoCaptureImpl::DoBufferCreatedOnCaptureThread, |
122 base::Unretained(this), handle, length, buffer_id)); | 111 base::Unretained(this), handle, length, buffer_id)); |
123 } | 112 } |
124 | 113 |
125 void VideoCaptureImpl::OnBufferReceived(int buffer_id, base::Time timestamp) { | 114 void VideoCaptureImpl::OnBufferReceived(int buffer_id, base::Time timestamp) { |
126 capture_message_loop_proxy_->PostTask(FROM_HERE, | 115 capture_message_loop_proxy_->PostTask(FROM_HERE, |
127 base::Bind(&VideoCaptureImpl::DoBufferReceived, | 116 base::Bind(&VideoCaptureImpl::DoBufferReceivedOnCaptureThread, |
128 base::Unretained(this), buffer_id, timestamp)); | 117 base::Unretained(this), buffer_id, timestamp)); |
129 } | 118 } |
130 | 119 |
131 void VideoCaptureImpl::OnStateChanged(video_capture::State state) { | 120 void VideoCaptureImpl::OnStateChanged(video_capture::State state) { |
132 capture_message_loop_proxy_->PostTask(FROM_HERE, | 121 capture_message_loop_proxy_->PostTask(FROM_HERE, |
133 base::Bind(&VideoCaptureImpl::DoStateChanged, | 122 base::Bind(&VideoCaptureImpl::DoStateChangedOnCaptureThread, |
134 base::Unretained(this), state)); | 123 base::Unretained(this), state)); |
135 } | 124 } |
136 | 125 |
137 void VideoCaptureImpl::OnDeviceInfoReceived( | 126 void VideoCaptureImpl::OnDeviceInfoReceived( |
138 const media::VideoCaptureParams& device_info) { | 127 const media::VideoCaptureParams& device_info) { |
139 capture_message_loop_proxy_->PostTask(FROM_HERE, | 128 capture_message_loop_proxy_->PostTask(FROM_HERE, |
140 base::Bind(&VideoCaptureImpl::DoDeviceInfoReceived, | 129 base::Bind(&VideoCaptureImpl::DoDeviceInfoReceivedOnCaptureThread, |
141 base::Unretained(this), device_info)); | 130 base::Unretained(this), device_info)); |
142 } | 131 } |
143 | 132 |
144 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { | 133 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { |
145 capture_message_loop_proxy_->PostTask(FROM_HERE, | 134 capture_message_loop_proxy_->PostTask(FROM_HERE, |
146 base::Bind(&VideoCaptureImpl::DoDelegateAdded, | 135 base::Bind(&VideoCaptureImpl::DoDelegateAddedOnCaptureThread, |
147 base::Unretained(this), device_id)); | 136 base::Unretained(this), device_id)); |
148 } | 137 } |
149 | 138 |
150 void VideoCaptureImpl::DoStartCapture( | 139 void VideoCaptureImpl::DoDeInitOnCaptureThread(base::Closure task) { |
| 140 if (state_ == video_capture::kStarted) |
| 141 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
| 142 |
| 143 io_message_loop_proxy_->PostTask(FROM_HERE, |
| 144 base::Bind(&VideoCaptureImpl::RemoveDelegateOnIOThread, |
| 145 base::Unretained(this), task)); |
| 146 } |
| 147 |
| 148 void VideoCaptureImpl::DoStartCaptureOnCaptureThread( |
151 media::VideoCapture::EventHandler* handler, | 149 media::VideoCapture::EventHandler* handler, |
152 const media::VideoCaptureCapability& capability) { | 150 const media::VideoCaptureCapability& capability) { |
153 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 151 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
154 | 152 |
155 if (state_ == video_capture::kError) { | 153 if (state_ == video_capture::kError) { |
156 handler->OnError(this, 1); | 154 handler->OnError(this, 1); |
157 handler->OnRemoved(this); | 155 handler->OnRemoved(this); |
158 return; | 156 } else if ((clients_pending_on_filter_.find(handler) != |
| 157 clients_pending_on_filter_.end()) || |
| 158 (clients_pending_on_restart_.find(handler) != |
| 159 clients_pending_on_restart_.end()) || |
| 160 clients_.find(handler) != clients_.end() ) { |
| 161 // This client has started. |
| 162 } else if (!device_id_) { |
| 163 clients_pending_on_filter_[handler] = capability; |
| 164 } else { |
| 165 handler->OnStarted(this); |
| 166 if (state_ == video_capture::kStarted) { |
| 167 if (capability.width > current_params_.width || |
| 168 capability.height > current_params_.height) { |
| 169 StopDevice(); |
| 170 DVLOG(1) << "StartCapture: Got client with higher resolution (" |
| 171 << capability.width << ", " << capability.height << ") " |
| 172 << "after started, try to restart."; |
| 173 clients_pending_on_restart_[handler] = capability; |
| 174 } else { |
| 175 if (device_info_available_) { |
| 176 handler->OnDeviceInfoReceived(this, device_info_); |
| 177 } |
| 178 |
| 179 clients_[handler] = capability; |
| 180 } |
| 181 } else if (state_ == video_capture::kStopping) { |
| 182 clients_pending_on_restart_[handler] = capability; |
| 183 DVLOG(1) << "StartCapture: Got new resolution (" |
| 184 << capability.width << ", " << capability.height << ") " |
| 185 << ", during stopping."; |
| 186 } else { |
| 187 clients_[handler] = capability; |
| 188 DCHECK_EQ(1ul, clients_.size()); |
| 189 video_type_ = capability.color; |
| 190 current_params_.width = capability.width; |
| 191 current_params_.height = capability.height; |
| 192 current_params_.frame_per_second = capability.frame_rate; |
| 193 DVLOG(1) << "StartCapture: starting with first resolution (" |
| 194 << current_params_.width << "," << current_params_.height << ")"; |
| 195 |
| 196 StartCaptureInternal(); |
| 197 } |
159 } | 198 } |
160 | |
161 ClientInfo::iterator it1 = clients_pending_on_filter_.find(handler); | |
162 ClientInfo::iterator it2 = clients_pending_on_restart_.find(handler); | |
163 if (it1 != clients_pending_on_filter_.end() || | |
164 it2 != clients_pending_on_restart_.end() || | |
165 clients_.find(handler) != clients_.end() ) { | |
166 // This client has started. | |
167 return; | |
168 } | |
169 | |
170 if (!device_id_) { | |
171 clients_pending_on_filter_[handler] = capability; | |
172 return; | |
173 } | |
174 | |
175 handler->OnStarted(this); | |
176 if (state_ == video_capture::kStarted) { | |
177 if (capability.width > current_params_.width || | |
178 capability.height > current_params_.height) { | |
179 StopDevice(); | |
180 DVLOG(1) << "StartCapture: Got client with higher resolution (" | |
181 << capability.width << ", " << capability.height << ") " | |
182 << "after started, try to restart."; | |
183 clients_pending_on_restart_[handler] = capability; | |
184 return; | |
185 } | |
186 | |
187 if (device_info_available_) { | |
188 handler->OnDeviceInfoReceived(this, device_info_); | |
189 } | |
190 | |
191 clients_[handler] = capability; | |
192 return; | |
193 } | |
194 | |
195 if (state_ == video_capture::kStopping) { | |
196 clients_pending_on_restart_[handler] = capability; | |
197 DVLOG(1) << "StartCapture: Got new resolution (" | |
198 << capability.width << ", " << capability.height << ") " | |
199 << ", during stopping."; | |
200 return; | |
201 } | |
202 | |
203 clients_[handler] = capability; | |
204 DCHECK_EQ(clients_.size(), 1ul); | |
205 video_type_ = capability.color; | |
206 current_params_.width = capability.width; | |
207 current_params_.height = capability.height; | |
208 current_params_.frame_per_second = capability.frame_rate; | |
209 DVLOG(1) << "StartCapture: starting with first resolution (" | |
210 << current_params_.width << ", " << current_params_.height << ")"; | |
211 | |
212 StartCaptureInternal(); | |
213 } | 199 } |
214 | 200 |
215 void VideoCaptureImpl::DoStopCapture( | 201 void VideoCaptureImpl::DoStopCaptureOnCaptureThread( |
216 media::VideoCapture::EventHandler* handler) { | 202 media::VideoCapture::EventHandler* handler) { |
217 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 203 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
218 | 204 |
219 ClientInfo::iterator it = clients_pending_on_filter_.find(handler); | 205 // A handler can be in only one client list. |
220 if (it != clients_pending_on_filter_.end()) { | 206 // If this handler is in any client list, we can just remove it from |
221 handler->OnStopped(this); | 207 // that client list and don't have to run the other following RemoveClient(). |
222 handler->OnRemoved(this); | 208 RemoveClient(handler, &clients_pending_on_filter_) || |
223 clients_pending_on_filter_.erase(it); | 209 RemoveClient(handler, &clients_pending_on_restart_) || |
224 return; | 210 RemoveClient(handler, &clients_); |
225 } | |
226 it = clients_pending_on_restart_.find(handler); | |
227 if (it != clients_pending_on_restart_.end()) { | |
228 handler->OnStopped(this); | |
229 handler->OnRemoved(this); | |
230 clients_pending_on_filter_.erase(it); | |
231 return; | |
232 } | |
233 | |
234 if (clients_.find(handler) == clients_.end()) | |
235 return; | |
236 | |
237 clients_.erase(handler); | |
238 | 211 |
239 if (clients_.empty()) { | 212 if (clients_.empty()) { |
240 DVLOG(1) << "StopCapture: No more client, stopping ..."; | 213 DVLOG(1) << "StopCapture: No more client, stopping ..."; |
241 StopDevice(); | 214 StopDevice(); |
242 } | 215 } |
243 handler->OnStopped(this); | |
244 handler->OnRemoved(this); | |
245 } | 216 } |
246 | 217 |
247 void VideoCaptureImpl::DoFeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { | 218 void VideoCaptureImpl::DoFeedBufferOnCaptureThread( |
| 219 scoped_refptr<VideoFrameBuffer> buffer) { |
248 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 220 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
249 | 221 |
250 CachedDIB::iterator it; | 222 CachedDIB::iterator it; |
251 for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) { | 223 for (it = cached_dibs_.begin(); it != cached_dibs_.end(); ++it) { |
252 if (buffer == it->second->mapped_memory) | 224 if (buffer == it->second->mapped_memory) |
253 break; | 225 break; |
254 } | 226 } |
255 | 227 |
256 DCHECK(it != cached_dibs_.end()); | 228 if (it != cached_dibs_.end() && it->second) { |
257 DCHECK_GT(it->second->references, 0); | 229 DCHECK_GT(it->second->references, 0); |
258 it->second->references--; | 230 --it->second->references; |
259 if (it->second->references == 0) { | 231 if (it->second->references == 0) { |
260 Send(new VideoCaptureHostMsg_BufferReady(device_id_, it->first)); | 232 Send(new VideoCaptureHostMsg_BufferReady(device_id_, it->first)); |
| 233 } |
261 } | 234 } |
262 } | 235 } |
263 | 236 |
264 void VideoCaptureImpl::DoBufferCreated( | 237 void VideoCaptureImpl::DoBufferCreatedOnCaptureThread( |
265 base::SharedMemoryHandle handle, | 238 base::SharedMemoryHandle handle, |
266 int length, int buffer_id) { | 239 int length, int buffer_id) { |
267 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 240 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
268 DCHECK(device_info_available_); | 241 DCHECK(device_info_available_); |
269 | 242 |
270 media::VideoCapture::VideoFrameBuffer* buffer; | 243 media::VideoCapture::VideoFrameBuffer* buffer; |
271 DCHECK(cached_dibs_.find(buffer_id) == cached_dibs_.end()); | 244 DCHECK(cached_dibs_.find(buffer_id) == cached_dibs_.end()); |
272 | 245 |
273 base::SharedMemory* dib = new base::SharedMemory(handle, false); | 246 base::SharedMemory* dib = new base::SharedMemory(handle, false); |
274 dib->Map(length); | 247 dib->Map(length); |
275 buffer = new VideoFrameBuffer(); | 248 buffer = new VideoFrameBuffer(); |
276 buffer->memory_pointer = static_cast<uint8*>(dib->memory()); | 249 buffer->memory_pointer = static_cast<uint8*>(dib->memory()); |
277 buffer->buffer_size = length; | 250 buffer->buffer_size = length; |
278 buffer->width = device_info_.width; | 251 buffer->width = device_info_.width; |
279 buffer->height = device_info_.height; | 252 buffer->height = device_info_.height; |
280 buffer->stride = device_info_.width; | 253 buffer->stride = device_info_.width; |
281 | 254 |
282 DIBBuffer* dib_buffer = new DIBBuffer(dib, buffer); | 255 DIBBuffer* dib_buffer = new DIBBuffer(dib, buffer); |
283 cached_dibs_[buffer_id] = dib_buffer; | 256 cached_dibs_[buffer_id] = dib_buffer; |
284 } | 257 } |
285 | 258 |
286 void VideoCaptureImpl::DoBufferReceived(int buffer_id, base::Time timestamp) { | 259 void VideoCaptureImpl::DoBufferReceivedOnCaptureThread( |
| 260 int buffer_id, base::Time timestamp) { |
287 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 261 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
288 | 262 |
289 if (state_ != video_capture::kStarted) { | 263 if (state_ != video_capture::kStarted) { |
290 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); | 264 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); |
291 return; | 265 return; |
292 } | 266 } |
293 | 267 |
294 media::VideoCapture::VideoFrameBuffer* buffer; | 268 media::VideoCapture::VideoFrameBuffer* buffer; |
295 DCHECK(cached_dibs_.find(buffer_id) != cached_dibs_.end()); | 269 DCHECK(cached_dibs_.find(buffer_id) != cached_dibs_.end()); |
296 buffer = cached_dibs_[buffer_id]->mapped_memory; | 270 buffer = cached_dibs_[buffer_id]->mapped_memory; |
297 buffer->timestamp = timestamp; | 271 buffer->timestamp = timestamp; |
298 | 272 |
299 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { | 273 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) { |
300 it->first->OnBufferReady(this, buffer); | 274 it->first->OnBufferReady(this, buffer); |
301 } | 275 } |
302 cached_dibs_[buffer_id]->references = clients_.size(); | 276 cached_dibs_[buffer_id]->references = clients_.size(); |
303 } | 277 } |
304 | 278 |
305 void VideoCaptureImpl::DoStateChanged(video_capture::State state) { | 279 void VideoCaptureImpl::DoStateChangedOnCaptureThread( |
| 280 video_capture::State state) { |
306 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 281 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
307 | 282 |
308 switch (state) { | 283 switch (state) { |
309 case video_capture::kStarted: | 284 case video_capture::kStarted: |
310 break; | 285 break; |
311 case video_capture::kStopped: | 286 case video_capture::kStopped: |
312 state_ = video_capture::kStopped; | 287 state_ = video_capture::kStopped; |
313 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; | 288 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; |
314 STLDeleteValues(&cached_dibs_); | 289 STLDeleteValues(&cached_dibs_); |
315 if (!clients_.empty() || !clients_pending_on_restart_.empty()) | 290 if (!clients_.empty() || !clients_pending_on_restart_.empty()) |
316 RestartCapture(); | 291 RestartCapture(); |
317 break; | 292 break; |
318 case video_capture::kPaused: | 293 case video_capture::kPaused: |
319 for (ClientInfo::iterator it = clients_.begin(); | 294 for (ClientInfo::iterator it = clients_.begin(); |
320 it != clients_.end(); it++) { | 295 it != clients_.end(); ++it) { |
321 it->first->OnPaused(this); | 296 it->first->OnPaused(this); |
322 } | 297 } |
323 break; | 298 break; |
324 case video_capture::kError: | 299 case video_capture::kError: |
325 DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; | 300 DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; |
326 for (ClientInfo::iterator it = clients_.begin(); | 301 for (ClientInfo::iterator it = clients_.begin(); |
327 it != clients_.end(); it++) { | 302 it != clients_.end(); ++it) { |
328 // TODO(wjia): browser process would send error code. | 303 // TODO(wjia): browser process would send error code. |
329 it->first->OnError(this, 1); | 304 it->first->OnError(this, 1); |
330 it->first->OnRemoved(this); | 305 it->first->OnRemoved(this); |
331 } | 306 } |
332 clients_.clear(); | 307 clients_.clear(); |
333 state_ = video_capture::kError; | 308 state_ = video_capture::kError; |
334 break; | 309 break; |
335 default: | 310 default: |
336 break; | 311 break; |
337 } | 312 } |
338 } | 313 } |
339 | 314 |
340 void VideoCaptureImpl::DoDeviceInfoReceived( | 315 void VideoCaptureImpl::DoDeviceInfoReceivedOnCaptureThread( |
341 const media::VideoCaptureParams& device_info) { | 316 const media::VideoCaptureParams& device_info) { |
342 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 317 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
343 DCHECK(!ClientHasDIB()); | 318 DCHECK(!ClientHasDIB()); |
344 | 319 |
345 STLDeleteValues(&cached_dibs_); | 320 STLDeleteValues(&cached_dibs_); |
346 | 321 |
347 device_info_ = device_info; | 322 device_info_ = device_info; |
348 device_info_available_ = true; | 323 device_info_available_ = true; |
349 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { | 324 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) { |
350 it->first->OnDeviceInfoReceived(this, device_info); | 325 it->first->OnDeviceInfoReceived(this, device_info); |
351 } | 326 } |
352 } | 327 } |
353 | 328 |
354 void VideoCaptureImpl::DoDelegateAdded(int32 device_id) { | 329 void VideoCaptureImpl::DoDelegateAddedOnCaptureThread(int32 device_id) { |
355 DVLOG(1) << "DoDelegateAdded: device_id " << device_id; | 330 DVLOG(1) << "DoDelegateAdded: device_id " << device_id; |
356 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 331 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
357 | 332 |
358 device_id_ = device_id; | 333 device_id_ = device_id; |
359 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); | 334 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); |
360 it != clients_pending_on_filter_.end(); ) { | 335 it != clients_pending_on_filter_.end(); ) { |
361 media::VideoCapture::EventHandler* handler = it->first; | 336 media::VideoCapture::EventHandler* handler = it->first; |
362 const media::VideoCaptureCapability capability = it->second; | 337 const media::VideoCaptureCapability capability = it->second; |
363 clients_pending_on_filter_.erase(it++); | 338 clients_pending_on_filter_.erase(it++); |
364 StartCapture(handler, capability); | 339 StartCapture(handler, capability); |
(...skipping 11 matching lines...) Expand all Loading... |
376 } | 351 } |
377 } | 352 } |
378 | 353 |
379 void VideoCaptureImpl::RestartCapture() { | 354 void VideoCaptureImpl::RestartCapture() { |
380 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 355 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
381 DCHECK_EQ(state_, video_capture::kStopped); | 356 DCHECK_EQ(state_, video_capture::kStopped); |
382 | 357 |
383 int width = 0; | 358 int width = 0; |
384 int height = 0; | 359 int height = 0; |
385 for (ClientInfo::iterator it = clients_.begin(); | 360 for (ClientInfo::iterator it = clients_.begin(); |
386 it != clients_.end(); it++) { | 361 it != clients_.end(); ++it) { |
387 if (it->second.width > width) | 362 width = std::max(width, it->second.width); |
388 width = it->second.width; | 363 height = std::max(height, it->second.height); |
389 if (it->second.height > height) | |
390 height = it->second.height; | |
391 } | 364 } |
392 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); | 365 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); |
393 it != clients_pending_on_restart_.end(); ) { | 366 it != clients_pending_on_restart_.end(); ) { |
394 if (it->second.width > width) | 367 width = std::max(width, it->second.width); |
395 width = it->second.width; | 368 height = std::max(height, it->second.height); |
396 if (it->second.height > height) | |
397 height = it->second.height; | |
398 clients_[it->first] = it->second; | 369 clients_[it->first] = it->second; |
399 clients_pending_on_restart_.erase(it++); | 370 clients_pending_on_restart_.erase(it++); |
400 } | 371 } |
401 current_params_.width = width; | 372 current_params_.width = width; |
402 current_params_.height = height; | 373 current_params_.height = height; |
403 DVLOG(1) << "RestartCapture, " << current_params_.width << ", " | 374 DVLOG(1) << "RestartCapture, " << current_params_.width << ", " |
404 << current_params_.height; | 375 << current_params_.height; |
405 StartCaptureInternal(); | 376 StartCaptureInternal(); |
406 } | 377 } |
407 | 378 |
(...skipping 15 matching lines...) Expand all Loading... |
423 message_filter_->RemoveDelegate(this); | 394 message_filter_->RemoveDelegate(this); |
424 capture_message_loop_proxy_->PostTask(FROM_HERE, task); | 395 capture_message_loop_proxy_->PostTask(FROM_HERE, task); |
425 } | 396 } |
426 | 397 |
427 void VideoCaptureImpl::Send(IPC::Message* message) { | 398 void VideoCaptureImpl::Send(IPC::Message* message) { |
428 io_message_loop_proxy_->PostTask(FROM_HERE, | 399 io_message_loop_proxy_->PostTask(FROM_HERE, |
429 base::Bind(base::IgnoreResult(&VideoCaptureMessageFilter::Send), | 400 base::Bind(base::IgnoreResult(&VideoCaptureMessageFilter::Send), |
430 message_filter_.get(), message)); | 401 message_filter_.get(), message)); |
431 } | 402 } |
432 | 403 |
433 bool VideoCaptureImpl::ClientHasDIB() { | 404 bool VideoCaptureImpl::ClientHasDIB() const { |
434 CachedDIB::iterator it; | 405 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
435 for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) { | 406 for (CachedDIB::const_iterator it = cached_dibs_.begin(); |
| 407 it != cached_dibs_.end(); ++it) { |
436 if (it->second->references > 0) | 408 if (it->second->references > 0) |
437 return true; | 409 return true; |
438 } | 410 } |
439 return false; | 411 return false; |
440 } | 412 } |
| 413 |
| 414 bool VideoCaptureImpl::RemoveClient( |
| 415 media::VideoCapture::EventHandler* handler, |
| 416 ClientInfo* clients) { |
| 417 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 418 bool found = false; |
| 419 |
| 420 ClientInfo::iterator it = clients->find(handler); |
| 421 if (it != clients->end()) { |
| 422 handler->OnStopped(this); |
| 423 handler->OnRemoved(this); |
| 424 clients->erase(it); |
| 425 found = true; |
| 426 } |
| 427 return found; |
| 428 } |
OLD | NEW |