OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" |
11 | 11 |
12 VideoCaptureImpl::DIBBuffer::DIBBuffer( | 12 struct VideoCaptureImpl::DIBBuffer { |
13 base::SharedMemory* d, media::VideoCapture::VideoFrameBuffer* ptr) | 13 public: |
14 : dib(d), | 14 DIBBuffer( |
15 mapped_memory(ptr) {} | 15 base::SharedMemory* d, |
16 media::VideoCapture::VideoFrameBuffer* ptr) | |
17 : dib(d), | |
18 mapped_memory(ptr), | |
19 references(0) { | |
20 } | |
21 ~DIBBuffer() {} | |
16 | 22 |
17 VideoCaptureImpl::DIBBuffer::~DIBBuffer() { | 23 scoped_ptr<base::SharedMemory> dib; |
18 delete dib; | 24 scoped_refptr<media::VideoCapture::VideoFrameBuffer> mapped_memory; |
19 } | 25 |
26 // Number of clients which hold this dib. | |
scherkus (not reviewing)
2011/11/01 02:26:56
dib -> DIB
wjia(left Chromium)
2011/11/01 17:24:29
Done.
| |
27 int references; | |
28 }; | |
20 | 29 |
21 bool VideoCaptureImpl::CaptureStarted() { | 30 bool VideoCaptureImpl::CaptureStarted() { |
22 return state_ == kStarted; | 31 return state_ == kStarted; |
23 } | 32 } |
24 | 33 |
25 int VideoCaptureImpl::CaptureWidth() { | 34 int VideoCaptureImpl::CaptureWidth() { |
26 return current_params_.width; | 35 return current_params_.width; |
27 } | 36 } |
28 | 37 |
29 int VideoCaptureImpl::CaptureHeight() { | 38 int VideoCaptureImpl::CaptureHeight() { |
(...skipping 10 matching lines...) Expand all Loading... | |
40 VideoCaptureMessageFilter* filter) | 49 VideoCaptureMessageFilter* filter) |
41 : VideoCapture(), | 50 : VideoCapture(), |
42 message_filter_(filter), | 51 message_filter_(filter), |
43 ml_proxy_(ml_proxy), | 52 ml_proxy_(ml_proxy), |
44 device_id_(0), | 53 device_id_(0), |
45 video_type_(media::VideoFrame::I420), | 54 video_type_(media::VideoFrame::I420), |
46 device_info_available_(false), | 55 device_info_available_(false), |
47 state_(kStopped) { | 56 state_(kStopped) { |
48 DCHECK(filter); | 57 DCHECK(filter); |
49 memset(¤t_params_, 0, sizeof(current_params_)); | 58 memset(¤t_params_, 0, sizeof(current_params_)); |
50 memset(&new_params_, 0, sizeof(new_params_)); | 59 current_params_.session_id = id; |
51 current_params_.session_id = new_params_.session_id = id; | |
52 } | 60 } |
53 | 61 |
54 VideoCaptureImpl::~VideoCaptureImpl() { | 62 VideoCaptureImpl::~VideoCaptureImpl() { |
55 STLDeleteContainerPairSecondPointers(cached_dibs_.begin(), | 63 STLDeleteContainerPairSecondPointers(cached_dibs_.begin(), |
56 cached_dibs_.end()); | 64 cached_dibs_.end()); |
57 } | 65 } |
58 | 66 |
59 void VideoCaptureImpl::Init() { | 67 void VideoCaptureImpl::Init() { |
60 base::MessageLoopProxy* io_message_loop_proxy = | 68 base::MessageLoopProxy* io_message_loop_proxy = |
61 ChildProcess::current()->io_message_loop_proxy(); | 69 ChildProcess::current()->io_message_loop_proxy(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 ml_proxy_->PostTask(FROM_HERE, | 148 ml_proxy_->PostTask(FROM_HERE, |
141 base::Bind(&VideoCaptureImpl::DoDelegateAdded, | 149 base::Bind(&VideoCaptureImpl::DoDelegateAdded, |
142 base::Unretained(this), device_id)); | 150 base::Unretained(this), device_id)); |
143 } | 151 } |
144 | 152 |
145 void VideoCaptureImpl::DoStartCapture( | 153 void VideoCaptureImpl::DoStartCapture( |
146 media::VideoCapture::EventHandler* handler, | 154 media::VideoCapture::EventHandler* handler, |
147 const VideoCaptureCapability& capability) { | 155 const VideoCaptureCapability& capability) { |
148 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 156 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
149 | 157 |
150 if (pending_clients_.find(handler) != pending_clients_.end() || | 158 if (state_ == kError) { |
159 handler->OnError(this, 1); | |
160 handler->OnRemoved(this); | |
161 return; | |
162 } | |
163 | |
164 ClientInfo::iterator it1 = clients_pending_on_filter_.find(handler); | |
165 ClientInfo::iterator it2 = clients_pending_on_restart_.find(handler); | |
166 if (it1 != clients_pending_on_filter_.end() || | |
167 it2 != clients_pending_on_restart_.end() || | |
151 clients_.find(handler) != clients_.end() ) { | 168 clients_.find(handler) != clients_.end() ) { |
152 // This client has started. | 169 // This client has started. |
153 return; | 170 return; |
154 } | 171 } |
155 | 172 |
156 if (!device_id_) { | 173 if (!device_id_) { |
157 pending_clients_[handler] = capability; | 174 clients_pending_on_filter_[handler] = capability; |
158 return; | 175 return; |
159 } | 176 } |
160 | 177 |
161 if (capability.resolution_fixed && master_clients_.size()) { | 178 handler->OnStarted(this); |
162 bool matches_current_params = | 179 if (state_ == kStarted) { |
163 CapabilityMatchesParameters(capability, current_params_); | 180 if (capability.width > current_params_.width || |
164 bool matches_new_params = | 181 capability.height > current_params_.height) { |
165 CapabilityMatchesParameters(capability, new_params_); | 182 StopDevice(); |
166 if ((state_ == kStarted && !matches_current_params) || | 183 DVLOG(1) << "StartCapture: Got client with higher resolution (" |
167 (state_ == kStopping && !matches_new_params)) { | 184 << capability.width << ", " << capability.height << ") " |
168 // Can't have 2 master clients with different resolutions. | 185 << "after started, try to restart."; |
169 handler->OnError(this, 1); | 186 clients_pending_on_restart_[handler] = capability; |
170 handler->OnRemoved(this); | |
171 return; | 187 return; |
172 } | 188 } |
173 } | |
174 | 189 |
175 handler->OnStarted(this); | 190 if (device_info_available_) { |
176 clients_[handler] = capability; | |
177 if (capability.resolution_fixed) { | |
178 master_clients_.push_back(handler); | |
179 if (master_clients_.size() > 1) { | |
180 if (device_info_available_) | |
181 handler->OnDeviceInfoReceived(this, device_info_); | |
182 return; | |
183 } | |
184 } | |
185 | |
186 if (state_ == kStarted) { | |
187 // Take the resolution of master client. | |
188 if (capability.resolution_fixed && | |
189 !CapabilityMatchesParameters(capability, current_params_)) { | |
190 new_params_.width = capability.width; | |
191 new_params_.height = capability.height; | |
192 new_params_.frame_per_second = capability.max_fps; | |
193 DLOG(INFO) << "StartCapture: Got master client with new resolution (" | |
194 << new_params_.width << ", " << new_params_.height << ") " | |
195 << "during started, try to restart."; | |
196 StopDevice(); | |
197 } else if (device_info_available_) { | |
198 handler->OnDeviceInfoReceived(this, device_info_); | 191 handler->OnDeviceInfoReceived(this, device_info_); |
199 } | 192 } |
193 | |
194 clients_[handler] = capability; | |
200 return; | 195 return; |
201 } | 196 } |
202 | 197 |
203 if (state_ == kStopping) { | 198 if (state_ == kStopping) { |
204 if (capability.resolution_fixed || !pending_start()) { | 199 clients_pending_on_restart_[handler] = capability; |
205 new_params_.width = capability.width; | 200 DVLOG(1) << "StartCapture: Got new resolution (" |
206 new_params_.height = capability.height; | 201 << capability.width << ", " << capability.height << ") " |
207 new_params_.frame_per_second = capability.max_fps; | 202 << ", during stopping."; |
208 DLOG(INFO) << "StartCapture: Got new resolution (" | |
209 << new_params_.width << ", " << new_params_.height << ") " | |
210 << ", already in stopping."; | |
211 } | |
212 return; | 203 return; |
213 } | 204 } |
214 | 205 |
206 clients_[handler] = capability; | |
215 DCHECK_EQ(clients_.size(), 1ul); | 207 DCHECK_EQ(clients_.size(), 1ul); |
216 video_type_ = capability.raw_type; | 208 video_type_ = capability.raw_type; |
217 new_params_.width = 0; | |
218 new_params_.height = 0; | |
219 new_params_.frame_per_second = 0; | |
220 current_params_.width = capability.width; | 209 current_params_.width = capability.width; |
221 current_params_.height = capability.height; | 210 current_params_.height = capability.height; |
222 current_params_.frame_per_second = capability.max_fps; | 211 current_params_.frame_per_second = capability.max_fps; |
223 DLOG(INFO) << "StartCapture: resolution (" | 212 DVLOG(1) << "StartCapture: starting with first resolution (" |
224 << current_params_.width << ", " << current_params_.height << ")"; | 213 << current_params_.width << ", " << current_params_.height << ")"; |
225 | 214 |
226 StartCaptureInternal(); | 215 StartCaptureInternal(); |
227 } | 216 } |
228 | 217 |
229 void VideoCaptureImpl::DoStopCapture( | 218 void VideoCaptureImpl::DoStopCapture( |
230 media::VideoCapture::EventHandler* handler) { | 219 media::VideoCapture::EventHandler* handler) { |
231 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 220 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
232 | 221 |
233 ClientInfo::iterator it = pending_clients_.find(handler); | 222 ClientInfo::iterator it = clients_pending_on_filter_.find(handler); |
234 if (it != pending_clients_.end()) { | 223 if (it != clients_pending_on_filter_.end()) { |
235 handler->OnStopped(this); | 224 handler->OnStopped(this); |
236 handler->OnRemoved(this); | 225 handler->OnRemoved(this); |
237 pending_clients_.erase(it); | 226 clients_pending_on_filter_.erase(it); |
227 return; | |
228 } | |
229 it = clients_pending_on_restart_.find(handler); | |
230 if (it != clients_pending_on_restart_.end()) { | |
231 handler->OnStopped(this); | |
232 handler->OnRemoved(this); | |
233 clients_pending_on_filter_.erase(it); | |
238 return; | 234 return; |
239 } | 235 } |
240 | 236 |
241 if (clients_.find(handler) == clients_.end()) | 237 if (clients_.find(handler) == clients_.end()) |
242 return; | 238 return; |
243 | 239 |
244 handler->OnStopped(this); | 240 handler->OnStopped(this); |
245 handler->OnRemoved(this); | 241 handler->OnRemoved(this); |
246 clients_.erase(handler); | 242 clients_.erase(handler); |
247 master_clients_.remove(handler); | |
248 | 243 |
249 // Still have at least one master client. | 244 if (clients_.empty()) { |
250 if (master_clients_.size() > 0) | 245 DVLOG(1) << "StopCapture: No more client, stopping ..."; |
251 return; | |
252 | |
253 // TODO(wjia): Is it really needed to handle resolution change for non-master | |
254 // clients, except no client case? | |
255 if (clients_.size() > 0) { | |
256 DLOG(INFO) << "StopCapture: No master client."; | |
257 int max_width = 0; | |
258 int max_height = 0; | |
259 int frame_rate = 0; | |
260 for (ClientInfo::iterator it = clients_.begin(); | |
261 it != clients_.end(); it++) { | |
262 if (it->second.width > max_width && it->second.height > max_height) { | |
263 max_width = it->second.width; | |
264 max_height = it->second.height; | |
265 frame_rate = it->second.max_fps; | |
266 } | |
267 } | |
268 | |
269 if (state_ == kStarted) { | |
270 // Only handle resolution reduction. | |
271 if (max_width < current_params_.width && | |
272 max_height < current_params_.height) { | |
273 new_params_.width = max_width; | |
274 new_params_.height = max_height; | |
275 new_params_.frame_per_second = frame_rate; | |
276 DLOG(INFO) << "StopCapture: New smaller resolution (" | |
277 << new_params_.width << ", " << new_params_.height << ") " | |
278 << "), stopping ..."; | |
279 StopDevice(); | |
280 } | |
281 return; | |
282 } | |
283 | |
284 if (state_ == kStopping) { | |
285 new_params_.width = max_width; | |
286 new_params_.height = max_height; | |
287 new_params_.frame_per_second = frame_rate; | |
288 DLOG(INFO) << "StopCapture: New resolution (" | |
289 << new_params_.width << ", " << new_params_.height << ") " | |
290 << "), during stopping."; | |
291 return; | |
292 } | |
293 } else { | |
294 new_params_.width = current_params_.width = 0; | |
295 new_params_.height = current_params_.height = 0; | |
296 new_params_.frame_per_second = current_params_.frame_per_second = 0; | |
297 DLOG(INFO) << "StopCapture: No more client, stopping ..."; | |
298 StopDevice(); | 246 StopDevice(); |
299 } | 247 } |
300 } | 248 } |
301 | 249 |
302 void VideoCaptureImpl::DoFeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { | 250 void VideoCaptureImpl::DoFeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { |
303 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 251 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
304 DCHECK(client_side_dibs_.find(buffer) != client_side_dibs_.end()); | |
305 | 252 |
306 CachedDIB::iterator it; | 253 CachedDIB::iterator it; |
307 for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) { | 254 for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) { |
308 if (buffer == it->second->mapped_memory) | 255 if (buffer == it->second->mapped_memory) |
309 break; | 256 break; |
310 } | 257 } |
311 | 258 |
312 DCHECK(it != cached_dibs_.end()); | 259 DCHECK(it != cached_dibs_.end()); |
313 if (client_side_dibs_[buffer] <= 1) { | 260 DCHECK_GT(it->second->references, 0); |
314 client_side_dibs_.erase(buffer); | 261 it->second->references--; |
262 if (it->second->references == 0) { | |
315 Send(new VideoCaptureHostMsg_BufferReady(device_id_, it->first)); | 263 Send(new VideoCaptureHostMsg_BufferReady(device_id_, it->first)); |
316 } else { | |
317 client_side_dibs_[buffer]--; | |
318 } | 264 } |
319 } | 265 } |
320 | 266 |
321 void VideoCaptureImpl::DoBufferCreated( | 267 void VideoCaptureImpl::DoBufferCreated( |
322 base::SharedMemoryHandle handle, | 268 base::SharedMemoryHandle handle, |
323 int length, int buffer_id) { | 269 int length, int buffer_id) { |
324 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 270 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
271 DCHECK(device_info_available_); | |
325 | 272 |
326 media::VideoCapture::VideoFrameBuffer* buffer; | 273 media::VideoCapture::VideoFrameBuffer* buffer; |
327 DCHECK(cached_dibs_.find(buffer_id) == cached_dibs_.end()); | 274 DCHECK(cached_dibs_.find(buffer_id) == cached_dibs_.end()); |
328 | 275 |
329 base::SharedMemory* dib = new base::SharedMemory(handle, false); | 276 base::SharedMemory* dib = new base::SharedMemory(handle, false); |
330 dib->Map(length); | 277 dib->Map(length); |
331 buffer = new VideoFrameBuffer(); | 278 buffer = new VideoFrameBuffer(); |
332 buffer->memory_pointer = static_cast<uint8*>(dib->memory()); | 279 buffer->memory_pointer = static_cast<uint8*>(dib->memory()); |
333 buffer->buffer_size = length; | 280 buffer->buffer_size = length; |
334 buffer->width = current_params_.width; | 281 buffer->width = device_info_.width; |
335 buffer->height = current_params_.height; | 282 buffer->height = device_info_.height; |
283 buffer->stride = device_info_.width; | |
336 | 284 |
337 DIBBuffer* dib_buffer = new DIBBuffer(dib, buffer); | 285 DIBBuffer* dib_buffer = new DIBBuffer(dib, buffer); |
338 cached_dibs_[buffer_id] = dib_buffer; | 286 cached_dibs_[buffer_id] = dib_buffer; |
339 } | 287 } |
340 | 288 |
341 void VideoCaptureImpl::DoBufferReceived(int buffer_id, base::Time timestamp) { | 289 void VideoCaptureImpl::DoBufferReceived(int buffer_id, base::Time timestamp) { |
342 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 290 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
343 | 291 |
344 if (state_ != kStarted) { | 292 if (state_ != kStarted) { |
345 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); | 293 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); |
346 return; | 294 return; |
347 } | 295 } |
348 | 296 |
349 media::VideoCapture::VideoFrameBuffer* buffer; | 297 media::VideoCapture::VideoFrameBuffer* buffer; |
350 DCHECK(cached_dibs_.find(buffer_id) != cached_dibs_.end()); | 298 DCHECK(cached_dibs_.find(buffer_id) != cached_dibs_.end()); |
351 buffer = cached_dibs_[buffer_id]->mapped_memory; | 299 buffer = cached_dibs_[buffer_id]->mapped_memory; |
352 | 300 |
353 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { | 301 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { |
354 it->first->OnBufferReady(this, buffer); | 302 it->first->OnBufferReady(this, buffer); |
355 } | 303 } |
356 client_side_dibs_[buffer] = clients_.size(); | 304 cached_dibs_[buffer_id]->references = clients_.size(); |
357 } | 305 } |
358 | 306 |
359 void VideoCaptureImpl::DoStateChanged(const media::VideoCapture::State& state) { | 307 void VideoCaptureImpl::DoStateChanged(const media::VideoCapture::State& state) { |
360 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 308 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
361 | 309 |
362 switch (state) { | 310 switch (state) { |
363 case media::VideoCapture::kStarted: | 311 case media::VideoCapture::kStarted: |
364 break; | 312 break; |
365 case media::VideoCapture::kStopped: | 313 case media::VideoCapture::kStopped: |
366 state_ = kStopped; | 314 state_ = kStopped; |
367 DLOG(INFO) << "OnStateChanged: stopped!, device_id = " << device_id_; | 315 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; |
368 STLDeleteValues(&cached_dibs_); | 316 STLDeleteValues(&cached_dibs_); |
369 if (pending_start()) | 317 if (!clients_.empty() || !clients_pending_on_restart_.empty()) |
370 RestartCapture(); | 318 RestartCapture(); |
371 break; | 319 break; |
372 case media::VideoCapture::kPaused: | 320 case media::VideoCapture::kPaused: |
perkj_chrome
2011/11/01 09:45:44
What is paused? Ever used?
wjia(left Chromium)
2011/11/01 17:24:29
"Paused" is a state similar to "started" except th
| |
373 for (ClientInfo::iterator it = clients_.begin(); | 321 for (ClientInfo::iterator it = clients_.begin(); |
374 it != clients_.end(); it++) { | 322 it != clients_.end(); it++) { |
375 it->first->OnPaused(this); | 323 it->first->OnPaused(this); |
376 } | 324 } |
377 break; | 325 break; |
378 case media::VideoCapture::kError: | 326 case media::VideoCapture::kError: |
327 DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; | |
379 for (ClientInfo::iterator it = clients_.begin(); | 328 for (ClientInfo::iterator it = clients_.begin(); |
380 it != clients_.end(); it++) { | 329 it != clients_.end(); it++) { |
381 // TODO(wjia): browser process would send error code. | 330 // TODO(wjia): browser process would send error code. |
382 it->first->OnError(this, 1); | 331 it->first->OnError(this, 1); |
383 it->first->OnRemoved(this); | 332 it->first->OnRemoved(this); |
384 } | 333 } |
385 clients_.clear(); | 334 clients_.clear(); |
386 master_clients_.clear(); | 335 state_ = kError; |
387 state_ = kStopped; | |
388 current_params_.width = current_params_.height = 0; | |
389 break; | 336 break; |
390 default: | 337 default: |
391 break; | 338 break; |
392 } | 339 } |
393 } | 340 } |
394 | 341 |
395 void VideoCaptureImpl::DoDeviceInfoReceived( | 342 void VideoCaptureImpl::DoDeviceInfoReceived( |
396 const media::VideoCaptureParams& device_info) { | 343 const media::VideoCaptureParams& device_info) { |
397 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 344 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
398 if (state_ != kStarted) | 345 DCHECK(!ClientHasDIB()); |
399 return; | 346 |
347 STLDeleteValues(&cached_dibs_); | |
400 | 348 |
401 device_info_ = device_info; | 349 device_info_ = device_info; |
402 device_info_available_ = true; | 350 device_info_available_ = true; |
403 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { | 351 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { |
404 it->first->OnDeviceInfoReceived(this, device_info); | 352 it->first->OnDeviceInfoReceived(this, device_info); |
405 } | 353 } |
406 } | 354 } |
407 | 355 |
408 void VideoCaptureImpl::DoDelegateAdded(int32 device_id) { | 356 void VideoCaptureImpl::DoDelegateAdded(int32 device_id) { |
409 DLOG(INFO) << "DoDelegateAdded: device_id " << device_id; | 357 DVLOG(1) << "DoDelegateAdded: device_id " << device_id; |
410 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 358 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
411 | 359 |
412 device_id_ = device_id; | 360 device_id_ = device_id; |
413 for (ClientInfo::iterator it = pending_clients_.begin(); | 361 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); |
414 it != pending_clients_.end(); ) { | 362 it != clients_pending_on_filter_.end(); ) { |
415 media::VideoCapture::EventHandler* handler = it->first; | 363 media::VideoCapture::EventHandler* handler = it->first; |
416 const VideoCaptureCapability capability = it->second; | 364 const VideoCaptureCapability capability = it->second; |
417 pending_clients_.erase(it++); | 365 clients_pending_on_filter_.erase(it++); |
418 StartCapture(handler, capability); | 366 StartCapture(handler, capability); |
419 } | 367 } |
420 } | 368 } |
421 | 369 |
422 void VideoCaptureImpl::StopDevice() { | 370 void VideoCaptureImpl::StopDevice() { |
423 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 371 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
424 | 372 |
425 device_info_available_ = false; | 373 device_info_available_ = false; |
426 if (state_ == kStarted) { | 374 if (state_ == kStarted) { |
427 state_ = kStopping; | 375 state_ = kStopping; |
428 Send(new VideoCaptureHostMsg_Stop(device_id_)); | 376 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
429 current_params_.width = current_params_.height = 0; | 377 current_params_.width = current_params_.height = 0; |
430 } | 378 } |
431 } | 379 } |
432 | 380 |
433 void VideoCaptureImpl::RestartCapture() { | 381 void VideoCaptureImpl::RestartCapture() { |
434 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 382 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
435 DCHECK_EQ(state_, kStopped); | 383 DCHECK_EQ(state_, kStopped); |
436 | 384 |
437 current_params_.width = new_params_.width; | 385 int width = 0; |
438 current_params_.height = new_params_.height; | 386 int height = 0; |
439 current_params_.frame_per_second = new_params_.frame_per_second; | 387 for (ClientInfo::iterator it = clients_.begin(); |
440 | 388 it != clients_.end(); it++) { |
441 new_params_.width = 0; | 389 if (it->second.width > width) |
442 new_params_.height = 0; | 390 width = it->second.width; |
443 new_params_.frame_per_second = 0; | 391 if (it->second.height > height) |
444 | 392 height = it->second.height; |
445 DLOG(INFO) << "RestartCapture, " << current_params_.width << ", " | 393 } |
446 << current_params_.height; | 394 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); |
395 it != clients_pending_on_restart_.end(); ) { | |
396 if (it->second.width > width) | |
397 width = it->second.width; | |
398 if (it->second.height > height) | |
399 height = it->second.height; | |
400 clients_[it->first] = it->second; | |
401 clients_pending_on_restart_.erase(it++); | |
402 } | |
403 current_params_.width = width; | |
404 current_params_.height = height; | |
405 DVLOG(1) << "RestartCapture, " << current_params_.width << ", " | |
406 << current_params_.height; | |
447 StartCaptureInternal(); | 407 StartCaptureInternal(); |
448 } | 408 } |
449 | 409 |
450 void VideoCaptureImpl::StartCaptureInternal() { | 410 void VideoCaptureImpl::StartCaptureInternal() { |
451 DCHECK(ml_proxy_->BelongsToCurrentThread()); | 411 DCHECK(ml_proxy_->BelongsToCurrentThread()); |
452 DCHECK(device_id_); | 412 DCHECK(device_id_); |
453 | 413 |
454 Send(new VideoCaptureHostMsg_Start(device_id_, current_params_)); | 414 Send(new VideoCaptureHostMsg_Start(device_id_, current_params_)); |
455 state_ = kStarted; | 415 state_ = kStarted; |
456 } | 416 } |
457 | 417 |
458 void VideoCaptureImpl::AddDelegateOnIOThread() { | 418 void VideoCaptureImpl::AddDelegateOnIOThread() { |
459 message_filter_->AddDelegate(this); | 419 message_filter_->AddDelegate(this); |
460 } | 420 } |
461 | 421 |
462 void VideoCaptureImpl::RemoveDelegateOnIOThread(base::Closure task) { | 422 void VideoCaptureImpl::RemoveDelegateOnIOThread(base::Closure task) { |
463 base::ScopedClosureRunner task_runner(task); | 423 base::ScopedClosureRunner task_runner(task); |
464 message_filter_->RemoveDelegate(this); | 424 message_filter_->RemoveDelegate(this); |
465 } | 425 } |
466 | 426 |
467 void VideoCaptureImpl::Send(IPC::Message* message) { | 427 void VideoCaptureImpl::Send(IPC::Message* message) { |
468 base::MessageLoopProxy* io_message_loop_proxy = | 428 base::MessageLoopProxy* io_message_loop_proxy = |
469 ChildProcess::current()->io_message_loop_proxy(); | 429 ChildProcess::current()->io_message_loop_proxy(); |
470 | 430 |
471 io_message_loop_proxy->PostTask(FROM_HERE, | 431 io_message_loop_proxy->PostTask(FROM_HERE, |
472 base::IgnoreReturn<bool>(base::Bind(&VideoCaptureMessageFilter::Send, | 432 base::IgnoreReturn<bool>(base::Bind(&VideoCaptureMessageFilter::Send, |
473 message_filter_.get(), message))); | 433 message_filter_.get(), message))); |
474 } | 434 } |
475 | 435 |
476 bool VideoCaptureImpl::CapabilityMatchesParameters( | 436 bool VideoCaptureImpl::ClientHasDIB() { |
477 const VideoCaptureCapability& capability, | 437 CachedDIB::iterator it; |
478 const media::VideoCaptureParams& params) { | 438 for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) { |
479 return (capability.width == params.width && | 439 if (it->second->references > 0) |
480 capability.height == params.height && | 440 return true; |
481 capability.max_fps == params.frame_per_second); | 441 } |
442 return false; | |
482 } | 443 } |
OLD | NEW |