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

Side by Side Diff: content/browser/renderer_host/media/video_capture_manager.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, 2 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) 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_manager.h" 5 #include "content/browser/renderer_host/media/video_capture_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.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/video_capture_controller.h"
11 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h"
10 #include "media/video/capture/fake_video_capture_device.h" 12 #include "media/video/capture/fake_video_capture_device.h"
11 #include "media/video/capture/video_capture_device.h" 13 #include "media/video/capture/video_capture_device.h"
12 14
13 namespace media_stream { 15 namespace media_stream {
14 16
15 // Starting id for the first capture session. 17 // Starting id for the first capture session.
16 // VideoCaptureManager::kStartOpenSessionId is used as default id without 18 // VideoCaptureManager::kStartOpenSessionId is used as default id without
17 // explicitly calling open device. 19 // explicitly calling open device.
18 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 }; 20 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 };
19 21
(...skipping 11 matching lines...) Expand all
31 // resolved, i.e. all code below this comment. 33 // resolved, i.e. all code below this comment.
32 // Temporary solution: close all open devices and delete them, after the 34 // Temporary solution: close all open devices and delete them, after the
33 // thread is stopped. 35 // thread is stopped.
34 DLOG_IF(ERROR, !devices_.empty()) << "VideoCaptureManager: Open devices!"; 36 DLOG_IF(ERROR, !devices_.empty()) << "VideoCaptureManager: Open devices!";
35 for (VideoCaptureDevices::iterator it = devices_.begin(); 37 for (VideoCaptureDevices::iterator it = devices_.begin();
36 it != devices_.end(); 38 it != devices_.end();
37 ++it) { 39 ++it) {
38 it->second->DeAllocate(); 40 it->second->DeAllocate();
39 delete it->second; 41 delete it->second;
40 } 42 }
43 STLDeleteContainerPairSecondPointers(controllers_.begin(),
scherkus (not reviewing) 2011/10/19 18:02:21 nit: STLDeleteValues() works here
wjia(left Chromium) 2011/10/21 00:56:13 Done.
44 controllers_.end());
41 } 45 }
42 46
43 void VideoCaptureManager::Register(MediaStreamProviderListener* listener) { 47 void VideoCaptureManager::Register(MediaStreamProviderListener* listener) {
44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
45 DCHECK(!listener_); 49 DCHECK(!listener_);
46 listener_ = listener; 50 listener_ = listener;
47 } 51 }
48 52
49 void VideoCaptureManager::Unregister() { 53 void VideoCaptureManager::Unregister() {
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 190
187 PostOnClosed(capture_session_id); 191 PostOnClosed(capture_session_id);
188 } 192 }
189 193
190 void VideoCaptureManager::OnStart( 194 void VideoCaptureManager::OnStart(
191 const media::VideoCaptureParams capture_params, 195 const media::VideoCaptureParams capture_params,
192 media::VideoCaptureDevice::EventHandler* video_capture_receiver) { 196 media::VideoCaptureDevice::EventHandler* video_capture_receiver) {
193 DCHECK(IsOnCaptureDeviceThread()); 197 DCHECK(IsOnCaptureDeviceThread());
194 DCHECK(video_capture_receiver != NULL); 198 DCHECK(video_capture_receiver != NULL);
195 199
196 // Solution for not using MediaStreamManager. 200 media::VideoCaptureDevice* video_capture_device =
197 // This session id won't be returned by Open(). 201 GetDeviceInternal(capture_params.session_id);
198 if (capture_params.session_id == kStartOpenSessionId) { 202 if (!video_capture_device) {
199 // Start() is called without using Open(), we need to open a device.
200 media::VideoCaptureDevice::Names device_names;
201 GetAvailableDevices(&device_names);
202 if (device_names.empty()) {
203 // No devices available.
204 video_capture_receiver->OnError();
205 return;
206 }
207 StreamDeviceInfo device(kVideoCapture,
208 device_names.front().device_name,
209 device_names.front().unique_id, false);
210
211 // Call OnOpen to open using the first device in the list.
212 OnOpen(capture_params.session_id, device);
213 }
214
215 VideoCaptureDevices::iterator it = devices_.find(capture_params.session_id);
216 if (it == devices_.end()) {
217 // Invalid session id. 203 // Invalid session id.
218 video_capture_receiver->OnError(); 204 video_capture_receiver->OnError();
219 return; 205 return;
220 } 206 }
221 media::VideoCaptureDevice* video_capture_device = it->second;
222 207
223 // Possible errors are signaled to video_capture_receiver by 208 // Possible errors are signaled to video_capture_receiver by
224 // video_capture_device. video_capture_receiver to perform actions. 209 // video_capture_device. video_capture_receiver to perform actions.
225 video_capture_device->Allocate(capture_params.width, capture_params.height, 210 video_capture_device->Allocate(capture_params.width, capture_params.height,
226 capture_params.frame_per_second, 211 capture_params.frame_per_second,
227 video_capture_receiver); 212 video_capture_receiver);
228 video_capture_device->Start(); 213 video_capture_device->Start();
229 } 214 }
230 215
231 void VideoCaptureManager::OnStop( 216 void VideoCaptureManager::OnStop(
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 for (VideoCaptureDevices::iterator it = devices_.begin(); 348 for (VideoCaptureDevices::iterator it = devices_.begin();
364 it != devices_.end(); 349 it != devices_.end();
365 it++) { 350 it++) {
366 if (device_info.device_id == it->second->device_name().unique_id) { 351 if (device_info.device_id == it->second->device_name().unique_id) {
367 return true; 352 return true;
368 } 353 }
369 } 354 }
370 return false; 355 return false;
371 } 356 }
372 357
358 void VideoCaptureManager::AddController(
359 const media::VideoCaptureParams& capture_params,
360 VideoCaptureControllerEventHandler* handler,
361 base::Callback<void(VideoCaptureController*)> added_cb) {
362 DCHECK(handler);
363 vc_device_thread_.message_loop()->PostTask(
364 FROM_HERE,
365 base::Bind(&VideoCaptureManager::DoAddControllerOnDeviceThread,
366 base::Unretained(this), capture_params, handler, added_cb));
367 }
368
369 void VideoCaptureManager::DoAddControllerOnDeviceThread(
370 const media::VideoCaptureParams capture_params,
371 VideoCaptureControllerEventHandler* handler,
372 base::Callback<void(VideoCaptureController*)> added_cb) {
373 DCHECK(IsOnCaptureDeviceThread());
374
375 media::VideoCaptureDevice* video_capture_device =
376 GetDeviceInternal(capture_params.session_id);
377 scoped_refptr<VideoCaptureController> ctrller = NULL;
378 if (video_capture_device) {
379 Controllers::iterator cit = controllers_.find(video_capture_device);
380 if (cit == controllers_.end()) {
381 ctrller = new VideoCaptureController(this);
382 controllers_[video_capture_device] = new Controller(ctrller, handler);
383 } else {
384 controllers_[video_capture_device]->handlers.push_front(handler);
385 ctrller = controllers_[video_capture_device]->controller;
386 }
387 }
388 added_cb.Run(ctrller);
389 }
390
391 void VideoCaptureManager::RemoveController(
392 VideoCaptureController* controller,
393 VideoCaptureControllerEventHandler* handler) {
394 DCHECK(handler);
395 vc_device_thread_.message_loop()->PostTask(
396 FROM_HERE,
397 base::Bind(&VideoCaptureManager::DoRemoveControllerOnDeviceThread,
398 base::Unretained(this),
399 make_scoped_refptr(controller),
400 handler));
401 }
402
403 void VideoCaptureManager::DoRemoveControllerOnDeviceThread(
404 VideoCaptureController* controller,
405 VideoCaptureControllerEventHandler* handler) {
406 DCHECK(IsOnCaptureDeviceThread());
407
408 for (Controllers::iterator cit = controllers_.begin();
409 cit != controllers_.end(); ++cit) {
410 if (controller == cit->second->controller) {
411 Handlers& handlers = cit->second->handlers;
412 for (Handlers::iterator hit = handlers.begin();
413 hit != handlers.end(); ++hit) {
414 if ((*hit) == handler) {
415 handlers.erase(hit);
416 break;
417 }
418 }
419 if (handlers.size() == 0 && cit->second->ready_to_delete) {
420 delete cit->second;
421 controllers_.erase(cit);
422 }
423 return;
424 }
425 }
426 }
427
428 void VideoCaptureManager::DeviceStatusFromController(
429 VideoCaptureController* controller, bool in_use) {
430 DCHECK(controller);
431 vc_device_thread_.message_loop()->PostTask(
432 FROM_HERE, base::Bind(
433 &VideoCaptureManager::DoDeviceStatusFromControllerOnDeviceThread,
434 base::Unretained(this),
435 make_scoped_refptr(controller),
436 in_use));
437 }
438
439 void VideoCaptureManager::DoDeviceStatusFromControllerOnDeviceThread(
440 VideoCaptureController* controller, bool in_use) {
441 DCHECK(IsOnCaptureDeviceThread());
442 for (Controllers::iterator cit = controllers_.begin();
443 cit != controllers_.end(); ++cit) {
444 if (controller == cit->second->controller) {
445 if (in_use) {
446 cit->second->ready_to_delete = false;
447 } else {
448 cit->second->ready_to_delete = true;
449 if (cit->second->handlers.size() == 0) {
450 delete cit->second;
451 controllers_.erase(cit);
452 }
453 }
454 return;
455 }
456 }
457 }
458
459 media::VideoCaptureDevice* VideoCaptureManager::GetDeviceInternal(
460 int capture_session_id) {
461 DCHECK(IsOnCaptureDeviceThread());
462 VideoCaptureDevices::iterator dit = devices_.find(capture_session_id);
463 if (dit != devices_.end()) {
464 return dit->second;
465 }
466
467 // Solution for not using MediaStreamManager.
468 // This session id won't be returned by Open().
469 if (capture_session_id == kStartOpenSessionId) {
470 media::VideoCaptureDevice::Names device_names;
471 GetAvailableDevices(&device_names);
472 if (device_names.empty()) {
473 // No devices available.
474 return NULL;
475 }
476 StreamDeviceInfo device(kVideoCapture,
477 device_names.front().device_name,
478 device_names.front().unique_id, false);
479
480 // Call OnOpen to open using the first device in the list.
481 OnOpen(capture_session_id, device);
482
483 VideoCaptureDevices::iterator dit = devices_.find(capture_session_id);
484 if (dit != devices_.end()) {
485 return dit->second;
486 }
487 }
488 return NULL;
489 }
490
491 VideoCaptureManager::Controller::Controller(
492 VideoCaptureController* ctrller,
perkj_chrome 2011/10/17 08:39:43 nit: name?
wjia(left Chromium) 2011/10/21 00:56:13 Done.
493 VideoCaptureControllerEventHandler* handler)
494 : controller(ctrller),
495 ready_to_delete(false) {
496 handlers.push_front(handler);
497 }
498
499 VideoCaptureManager::Controller::~Controller() {}
500
373 } // namespace media_stream 501 } // namespace media_stream
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698