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

Side by Side Diff: content/browser/renderer_host/media/video_capture_controller.cc

Issue 8304017: enable video capture to support sharing across multiple renderer processes (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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) 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/browser/renderer_host/media/video_capture_controller.h" 5 #include "content/browser/renderer_host/media/video_capture_controller.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/browser/browser_thread.h" 9 #include "content/browser/browser_thread.h"
10 #include "content/browser/renderer_host/media/media_stream_manager.h" 10 #include "content/browser/renderer_host/media/media_stream_manager.h"
11 #include "content/browser/renderer_host/media/video_capture_manager.h" 11 #include "content/browser/renderer_host/media/video_capture_manager.h"
12 #include "media/base/yuv_convert.h" 12 #include "media/base/yuv_convert.h"
13 13
14 // The number of TransportDIBs VideoCaptureController allocate. 14 // The number of DIBs VideoCaptureController allocate.
15 static const size_t kNoOfDIBS = 3; 15 static const size_t kNoOfDIBS = 3;
16 16
17 struct VideoCaptureController::ControllerClient {
18 ControllerClient(
19 const VideoCaptureControllerID& id,
20 VideoCaptureControllerEventHandler* handler,
21 base::ProcessHandle render_process,
22 const media::VideoCaptureParams& params)
23 : controller_id(id),
24 event_handler(handler),
25 render_process_handle(render_process),
26 parameters(params),
27 report_ready_to_delete(false) {
28 }
29
30 ~ControllerClient() {}
31
32 // ID used for identifying this object.
33 VideoCaptureControllerID controller_id;
34 VideoCaptureControllerEventHandler* event_handler;
35 // Handle to the render process that will receive the DIBs.
36 base::ProcessHandle render_process_handle;
37 const media::VideoCaptureParams parameters;
38 // Buffers used by this client.
39 std::list<int> buffers;
40 bool report_ready_to_delete;
41 };
42
17 VideoCaptureController::VideoCaptureController( 43 VideoCaptureController::VideoCaptureController(
18 const VideoCaptureControllerID& id,
19 base::ProcessHandle render_process,
20 VideoCaptureControllerEventHandler* event_handler,
21 media_stream::VideoCaptureManager* video_capture_manager) 44 media_stream::VideoCaptureManager* video_capture_manager)
22 : render_handle_(render_process), 45 : frame_info_available_(false),
23 report_ready_to_delete_(false), 46 video_capture_manager_(video_capture_manager),
24 event_handler_(event_handler), 47 device_in_use_(false),
25 id_(id), 48 state_(media::VideoCapture::kStopped) {
26 video_capture_manager_(video_capture_manager) { 49 memset(&current_params_, 0, sizeof(current_params_));
27 memset(&params_, 0, sizeof(params_));
28 } 50 }
29 51
30 VideoCaptureController::~VideoCaptureController() { 52 VideoCaptureController::~VideoCaptureController() {
31 // Delete all TransportDIBs. 53 // Delete all DIBs.
32 STLDeleteContainerPairSecondPointers(owned_dibs_.begin(), 54 STLDeleteContainerPairSecondPointers(owned_dibs_.begin(),
33 owned_dibs_.end()); 55 owned_dibs_.end());
56 STLDeleteContainerPointers(controller_clients_.begin(),
57 controller_clients_.end());
34 } 58 }
35 59
36 void VideoCaptureController::StartCapture( 60 void VideoCaptureController::StartCapture(
61 const VideoCaptureControllerID& id,
62 VideoCaptureControllerEventHandler* event_handler,
63 base::ProcessHandle render_process,
37 const media::VideoCaptureParams& params) { 64 const media::VideoCaptureParams& params) {
38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 65 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
39 66 // Signal error in case device is already in error state.
40 params_ = params; 67 if (state_ == media::VideoCapture::kError) {
68 event_handler->OnError(id);
69 return;
70 }
71
72 // Do nothing if this client has called StartCapture before.
73 if (FindClient(id, event_handler, controller_clients_) !=
74 controller_clients_.end() ||
75 FindClient(id, event_handler, pending_clients_) !=
76 pending_clients_.end())
77 return;
78
79 ControllerClient* client = new ControllerClient(id, event_handler,
80 render_process, params);
81 // In case capture has been started, need to check different condtions.
82 if (state_ == media::VideoCapture::kStarted) {
83 // When frame_info has not been returned by device, just wait in pending
84 // queue.
85 if (!frame_info_available_) {
86 pending_clients_.push_back(client);
87 return;
88 }
89
90 // This client has higher resolution than what is currently delivered.
91 // Need restart catpuring.
perkj_chrome 2011/10/27 14:30:30 nit: catpuring- capturing.
wjia(left Chromium) 2011/10/28 01:27:40 Done.
92 // TODO(wjia): Query the max capability of device. If request is larger
perkj_chrome 2011/10/27 14:30:30 Don't query the device. (it does not work on Mac a
wjia(left Chromium) 2011/10/28 01:27:40 Done. For now, we don't decrease resolution. In th
93 // than max, there is no need to restart.
94 if (params.width > frame_info_.width ||
95 params.height > frame_info_.height) {
96 video_capture_manager_->Stop(current_params_.session_id, base::Closure());
perkj_chrome 2011/10/27 14:30:30 Use base::Closure instead of your callback.
wjia(left Chromium) 2011/10/28 01:27:40 Done. I assume you mean "Use your callback, instea
97 frame_info_available_ = false;
98 state_ = media::VideoCapture::kStopping;
99 pending_clients_.push_back(client);
100 return;
101 }
102
103 // This client's resolution is no larger than what's currently delivered.
104 // Send frame_info and initial buffers to the client.
105 SendFrameInfoAndBuffers(client);
106 controller_clients_.push_back(client);
107 return;
108 }
109
110 // In case the device is in the middle of stopping, put the client in
111 // pending queue.
112 if (state_ == media::VideoCapture::kStopping) {
113 pending_clients_.push_back(client);
114 return;
115 }
116
117 // Fresh start.
118 controller_clients_.push_back(client);
119 current_params_ = params;
41 // Order the manager to start the actual capture. 120 // Order the manager to start the actual capture.
42 video_capture_manager_->Start(params, this); 121 video_capture_manager_->Start(params, this);
43 } 122 state_ = media::VideoCapture::kStarted;
44 123 }
45 void VideoCaptureController::StopCapture(base::Closure stopped_cb) { 124
125 void VideoCaptureController::StopCapture(
126 const VideoCaptureControllerID& id,
127 VideoCaptureControllerEventHandler* event_handler,
128 bool force_buffer_return) {
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
47 130
48 video_capture_manager_->Stop(params_.session_id, 131 ControllerClients::iterator cit;
49 base::Bind(&VideoCaptureController::OnDeviceStopped, this, stopped_cb)); 132 cit = FindClient(id, event_handler, pending_clients_);
50 } 133 // If the client is still in pending queue, just remove it.
51 134 if (cit != pending_clients_.end()) {
52 void VideoCaptureController::ReturnBuffer(int buffer_id) { 135 (*cit)->event_handler->OnReadyToDelete((*cit)->controller_id);
136 pending_clients_.erase(cit);
137 return;
138 }
139
140 cit = FindClient(id, event_handler, controller_clients_);
141 // The client should have called StartCapture.
142 DCHECK(cit != controller_clients_.end());
143
144 if (force_buffer_return) {
145 // The client requests to return buffers which means it can't return
146 // buffers normally. After buffers are returned, client is free to
147 // delete itself. No need to call OnReadyToDelete.
148
149 // Return all buffers held by the clients.
150 for (std::list<int>::iterator bit = (*cit)->buffers.begin();
151 bit != (*cit)->buffers.end(); ++bit) {
152 int buffer_id = *bit;
153 ClientSideDIBCount::iterator dit = client_side_dib_count_.find(buffer_id);
154 if (dit == client_side_dib_count_.end())
155 continue;
156
157 if (--dit->second > 0)
158 continue;
159
160 // Now this |buffer_id| is not used by any client.
161 client_side_dib_count_.erase(buffer_id);
162 {
163 base::AutoLock lock(lock_);
164 free_dibs_.push_back(buffer_id);
165 }
166 }
167 (*cit)->buffers.clear();
168 } else {
169 // Normal way to stop capture.
170 if ((*cit)->buffers.size() > 0) {
171 // There are still some buffers held by the client.
172 (*cit)->report_ready_to_delete = true;
173 return;
174 }
175 // No buffer is held by the client. Ready to delete.
176 (*cit)->event_handler->OnReadyToDelete((*cit)->controller_id);
177 }
178
179 controller_clients_.erase(cit);
180
181 // No more clients. Stop device.
182 if (controller_clients_.size() == 0) {
183 video_capture_manager_->Stop(current_params_.session_id, base::Closure());
184 frame_info_available_ = false;
185 state_ = media::VideoCapture::kStopping;
186 }
187 }
188
189 void VideoCaptureController::ReturnBuffer(
190 const VideoCaptureControllerID& id,
191 VideoCaptureControllerEventHandler* event_handler,
192 int buffer_id) {
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
54 194
55 bool ready_to_delete; 195 ControllerClients::iterator cit = FindClient(id, event_handler,
196 controller_clients_);
197 ClientSideDIBCount::iterator dit = client_side_dib_count_.find(buffer_id);
198 // If this buffer is not held by this client, or this client doesn't exist
199 // in controller, do nothing.
200 if (cit == controller_clients_.end() || dit == client_side_dib_count_.end())
201 return;
202
203 (*cit)->buffers.remove(buffer_id);
204 // If this client has called StopCapture and doesn't hold any buffer after
205 // after this return, ready to delet this client.
206 if ((*cit)->report_ready_to_delete && (*cit)->buffers.size() == 0) {
207 (*cit)->event_handler->OnReadyToDelete((*cit)->controller_id);
208 controller_clients_.erase(cit);
209 }
210 if (--dit->second > 0)
211 return;
212
213 // Now this |buffer_id| is not used by any client.
214 client_side_dib_count_.erase(buffer_id);
56 { 215 {
57 base::AutoLock lock(lock_); 216 base::AutoLock lock(lock_);
58 free_dibs_.push_back(buffer_id); 217 free_dibs_.push_back(buffer_id);
59 ready_to_delete = (free_dibs_.size() == owned_dibs_.size()) && 218 }
60 report_ready_to_delete_; 219
61 } 220 // When all buffers have been returned by clients and device has been
62 if (ready_to_delete) { 221 // called to stop, check if restart is needed. This could happen when
63 event_handler_->OnReadyToDelete(id_); 222 // some clients call StopCapture before returning all buffers.
64 } 223 if (!ClientHasDIB() && state_ == media::VideoCapture::kStopping) {
65 } 224 PostStopping();
66 225 }
226 }
227
67 /////////////////////////////////////////////////////////////////////////////// 228 ///////////////////////////////////////////////////////////////////////////////
68 // Implements VideoCaptureDevice::EventHandler. 229 // Implements VideoCaptureDevice::EventHandler.
69 // OnIncomingCapturedFrame is called the thread running the capture device. 230 // OnIncomingCapturedFrame is called the thread running the capture device.
70 // I.e.- DirectShow thread on windows and v4l2_thread on Linux. 231 // I.e.- DirectShow thread on windows and v4l2_thread on Linux.
71 void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data, 232 void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
72 int length, 233 int length,
73 base::Time timestamp) { 234 base::Time timestamp) {
74 int buffer_id = 0; 235 int buffer_id = 0;
75 base::SharedMemory* dib = NULL; 236 base::SharedMemory* dib = NULL;
76 // Check if there is a TransportDIB to fill. 237 // Check if there is a DIB to fill.
77 bool buffer_exist = false; 238 bool buffer_exist = false;
78 { 239 {
79 base::AutoLock lock(lock_); 240 base::AutoLock lock(lock_);
80 if (!report_ready_to_delete_ && free_dibs_.size() > 0) { 241 if (free_dibs_.size() > 0) {
81 buffer_id = free_dibs_.front(); 242 buffer_id = free_dibs_.front();
82 free_dibs_.pop_front(); 243 free_dibs_.pop_front();
83 DIBMap::iterator it = owned_dibs_.find(buffer_id); 244 DIBMap::iterator it = owned_dibs_.find(buffer_id);
84 if (it != owned_dibs_.end()) { 245 if (it != owned_dibs_.end()) {
85 dib = it->second; 246 dib = it->second;
86 buffer_exist = true; 247 buffer_exist = true;
87 } 248 }
88 } 249 }
89 } 250 }
90 251
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 uint8* vplane = uplane + (frame_info_.width * frame_info_.height) / 4; 304 uint8* vplane = uplane + (frame_info_.width * frame_info_.height) / 4;
144 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width, 305 media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width,
145 frame_info_.height, frame_info_.width * 4, 306 frame_info_.height, frame_info_.width * 4,
146 frame_info_.width, frame_info_.width / 2); 307 frame_info_.width, frame_info_.width / 2);
147 break; 308 break;
148 } 309 }
149 default: 310 default:
150 NOTREACHED(); 311 NOTREACHED();
151 } 312 }
152 313
153 event_handler_->OnBufferReady(id_, buffer_id, timestamp); 314 BrowserThread::PostTask(BrowserThread::IO,
315 FROM_HERE,
316 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
317 this, buffer_id, timestamp));
154 } 318 }
155 319
156 void VideoCaptureController::OnError() { 320 void VideoCaptureController::OnError() {
157 event_handler_->OnError(id_); 321 video_capture_manager_->Error(current_params_.session_id);
158 video_capture_manager_->Error(params_.session_id); 322 BrowserThread::PostTask(BrowserThread::IO,
323 FROM_HERE,
324 base::Bind(&VideoCaptureController::DoErrorOnIOThread, this));
159 } 325 }
160 326
161 void VideoCaptureController::OnFrameInfo( 327 void VideoCaptureController::OnFrameInfo(
162 const media::VideoCaptureDevice::Capability& info) { 328 const media::VideoCaptureDevice::Capability& info) {
329 BrowserThread::PostTask(BrowserThread::IO,
330 FROM_HERE,
331 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread,
332 this, info));
333 }
334
335 void VideoCaptureController::OnDeviceState(bool in_use) {
336 BrowserThread::PostTask(BrowserThread::IO,
337 FROM_HERE,
338 base::Bind(&VideoCaptureController::DoDeviceStateOnIOThread, this,
339 in_use));
340 }
341
342 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread(
343 int buffer_id, base::Time timestamp) {
344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
345
346 if (state_ != media::VideoCapture::kStarted) {
347 base::AutoLock lock(lock_);
348 free_dibs_.push_back(buffer_id);
349 return;
350 }
351
352 int count = 0;
353 for (ControllerClients::iterator cit = controller_clients_.begin();
354 cit != controller_clients_.end(); cit++) {
355 if ((*cit)->report_ready_to_delete)
356 continue;
357
358 (*cit)->event_handler->OnBufferReady((*cit)->controller_id,
359 buffer_id, timestamp);
360 (*cit)->buffers.push_back(buffer_id);
361 count++;
362 }
363 if (count > 0) {
364 client_side_dib_count_[buffer_id] = count;
365 } else {
366 base::AutoLock lock(lock_);
367 free_dibs_.push_back(buffer_id);
368 }
369 }
370
371 void VideoCaptureController::DoErrorOnIOThread() {
372 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
373 state_ = media::VideoCapture::kError;
374 ControllerClients::iterator cit;
375 for (cit = controller_clients_.begin();
376 cit != controller_clients_.end(); cit++) {
377 (*cit)->event_handler->OnError((*cit)->controller_id);
378 }
379 for (cit = pending_clients_.begin();
380 cit != pending_clients_.end(); cit++) {
381 (*cit)->event_handler->OnError((*cit)->controller_id);
382 }
383 }
384
385 void VideoCaptureController::DoDeviceStateOnIOThread(bool device_in_use) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
387 device_in_use_ = device_in_use;
388 video_capture_manager_->DeviceStatusFromController(this, device_in_use);
389 if (!device_in_use && state_ == media::VideoCapture::kStopping) {
390 PostStopping();
391 }
392 }
393
394 void VideoCaptureController::DoFrameInfoOnIOThread(
395 const media::VideoCaptureDevice::Capability info) {
396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
163 DCHECK(owned_dibs_.empty()); 397 DCHECK(owned_dibs_.empty());
398
399 // Check if pending clients request higher resolution.
400 current_params_.width = info.width;
401 current_params_.height = info.height;
402 current_params_.frame_per_second = info.frame_rate;
403 ControllerClients::iterator cit;
404 for (cit = pending_clients_.begin();
405 cit != pending_clients_.end(); ) {
406 if (current_params_.width < (*cit)->parameters.width)
407 current_params_.width = (*cit)->parameters.width;
408 if (current_params_.height < (*cit)->parameters.height)
409 current_params_.height = (*cit)->parameters.height;
410 controller_clients_.push_back((*cit));
411 pending_clients_.erase(cit++);
412 }
413 // Take care of the case where a new client calls StartCapture with higher
414 // resolution before DoFrameInfoOnIOThread (of previous client) is called.
415 if (current_params_.width > info.width ||
perkj_chrome 2011/10/27 14:30:30 You should not trust that the camera give you what
wjia(left Chromium) 2011/10/28 01:27:40 Done.
416 current_params_.height > info.height) {
417 video_capture_manager_->Stop(current_params_.session_id, base::Closure());
418 frame_info_available_ = false;
419 state_ = media::VideoCapture::kStopping;
420 return;
421 }
422
164 bool frames_created = true; 423 bool frames_created = true;
165 const size_t needed_size = (info.width * info.height * 3) / 2; 424 const size_t needed_size = (info.width * info.height * 3) / 2;
425 base::AutoLock lock(lock_);
166 for (size_t i = 1; i <= kNoOfDIBS; ++i) { 426 for (size_t i = 1; i <= kNoOfDIBS; ++i) {
167 base::SharedMemory* shared_memory = new base::SharedMemory(); 427 base::SharedMemory* shared_memory = new base::SharedMemory();
168 if (!shared_memory->CreateAndMapAnonymous(needed_size)) { 428 if (!shared_memory->CreateAndMapAnonymous(needed_size)) {
169 frames_created = false; 429 frames_created = false;
170 break; 430 break;
171 } 431 }
172 base::SharedMemoryHandle remote_handle;
173 shared_memory->ShareToProcess(render_handle_, &remote_handle);
174
175 base::AutoLock lock(lock_);
176 owned_dibs_.insert(std::make_pair(i, shared_memory)); 432 owned_dibs_.insert(std::make_pair(i, shared_memory));
177 free_dibs_.push_back(i); 433 free_dibs_.push_back(i);
178 event_handler_->OnBufferCreated(id_, remote_handle, 434 }
179 static_cast<int>(needed_size), 435 // Check whether all DIBs were created successfully.
180 static_cast<int>(i)); 436 if (!frames_created) {
437 state_ = media::VideoCapture::kError;
438 for (ControllerClients::iterator it = controller_clients_.begin();
439 it != controller_clients_.end(); it++) {
440 (*it)->event_handler->OnError((*it)->controller_id);
441 }
442 return;
181 } 443 }
182 frame_info_= info; 444 frame_info_= info;
183 445 frame_info_available_ = true;
184 // Check that all DIBs where created successfully. 446
185 if (!frames_created) { 447 for (cit = controller_clients_.begin();
186 event_handler_->OnError(id_); 448 cit != controller_clients_.end(); cit++) {
187 } 449 SendFrameInfoAndBuffersWithLock((*cit), static_cast<int>(needed_size));
188 event_handler_->OnFrameInfo(id_, info.width, info.height, info.frame_rate); 450 }
189 } 451 }
190 452
191 /////////////////////////////////////////////////////////////////////////////// 453 void VideoCaptureController::SendFrameInfoAndBuffers(ControllerClient* client) {
192 // Called by VideoCaptureManager when a device have been stopped. 454 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
193 // This will report to the event handler that this object is ready to be deleted 455 DCHECK(frame_info_available_);
194 // if all DIBS have been returned. 456 const size_t needed_size = (frame_info_.width * frame_info_.height * 3) / 2;
195 void VideoCaptureController::OnDeviceStopped(base::Closure stopped_cb) { 457 base::AutoLock lock(lock_);
196 bool ready_to_delete_now; 458 SendFrameInfoAndBuffersWithLock(client, static_cast<int>(needed_size));
197 459 }
198 { 460
199 base::AutoLock lock(lock_); 461 void VideoCaptureController::SendFrameInfoAndBuffersWithLock(
200 // Set flag to indicate we need to report when all DIBs have been returned. 462 ControllerClient* client, int needed_size) {
201 report_ready_to_delete_ = true; 463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
202 ready_to_delete_now = (free_dibs_.size() == owned_dibs_.size()); 464 DCHECK(frame_info_available_);
203 } 465 client->event_handler->OnFrameInfo(client->controller_id,
204 466 frame_info_.width, frame_info_.height,
205 if (ready_to_delete_now) { 467 frame_info_.frame_rate);
206 event_handler_->OnReadyToDelete(id_); 468 for (DIBMap::iterator dit = owned_dibs_.begin();
207 } 469 dit != owned_dibs_.end(); dit++) {
208 470 base::SharedMemory* shared_memory = dit->second;
209 if (!stopped_cb.is_null()) 471 int index = dit->first;
210 stopped_cb.Run(); 472 base::SharedMemoryHandle remote_handle;
211 } 473 shared_memory->ShareToProcess(client->render_process_handle,
474 &remote_handle);
475 client->event_handler->OnBufferCreated(client->controller_id,
476 remote_handle,
477 needed_size,
478 index);
479 }
480 }
481
482 void VideoCaptureController::PostStopping() {
483 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
484 DCHECK_EQ(state_, media::VideoCapture::kStopping);
485
486 if (ClientHasDIB() || device_in_use_)
487 return;
488
489 // It's safe to free all DIB's on IO thread since device won't send
490 // buffer over.
491 free_dibs_.clear();
492 STLDeleteValues(&owned_dibs_);
493
494 if (controller_clients_.size() + pending_clients_.size() == 0) {
495 state_ = media::VideoCapture::kStopped;
496 return;
497 }
498
499 // Restart the device.
500 current_params_.width = 0;
501 current_params_.height = 0;
502 ControllerClients::iterator cit;
503 for (cit = controller_clients_.begin();
504 cit != controller_clients_.end(); cit++) {
505 if (current_params_.width < (*cit)->parameters.width)
506 current_params_.width = (*cit)->parameters.width;
507 if (current_params_.height < (*cit)->parameters.height)
508 current_params_.height = (*cit)->parameters.height;
509 }
510 for (cit = pending_clients_.begin();
511 cit != pending_clients_.end(); ) {
512 if (current_params_.width < (*cit)->parameters.width)
513 current_params_.width = (*cit)->parameters.width;
514 if (current_params_.height < (*cit)->parameters.height)
515 current_params_.height = (*cit)->parameters.height;
516 controller_clients_.push_back((*cit));
517 pending_clients_.erase(cit++);
518 }
519 // Request the manager to start the actual capture.
520 video_capture_manager_->Start(current_params_, this);
521 state_ = media::VideoCapture::kStarted;
522 }
523
524 bool VideoCaptureController::ClientHasDIB() {
525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
526 for (ClientSideDIBCount::iterator dit = client_side_dib_count_.begin();
527 dit != client_side_dib_count_.end(); dit++) {
528 if (dit->second > 0)
529 return true;
530 }
531 return false;
532 }
533
534 VideoCaptureController::ControllerClients::iterator
535 VideoCaptureController::FindClient(
536 const VideoCaptureControllerID& id,
537 VideoCaptureControllerEventHandler* handler,
538 ControllerClients& clients) {
539 for (ControllerClients::iterator cit = clients.begin();
540 cit != clients.end(); cit++) {
541 if ((*cit)->controller_id == id && (*cit)->event_handler == handler) {
542 return cit;
543 }
544 }
545 return clients.end();
546 }
547
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698