| 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/browser/renderer_host/media/video_capture_manager.h" | 5 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 11 #include "content/browser/renderer_host/media/video_capture_controller.h" | 12 #include "content/browser/renderer_host/media/video_capture_controller.h" |
| 12 #include "content/browser/renderer_host/media/video_capture_controller_event_han
dler.h" | 13 #include "content/browser/renderer_host/media/video_capture_controller_event_han
dler.h" |
| 13 #include "content/public/browser/browser_thread.h" | 14 #include "content/public/browser/browser_thread.h" |
| 15 #include "content/public/common/media_stream_request.h" |
| 14 #include "media/video/capture/fake_video_capture_device.h" | 16 #include "media/video/capture/fake_video_capture_device.h" |
| 15 #include "media/video/capture/video_capture_device.h" | 17 #include "media/video/capture/video_capture_device.h" |
| 16 | 18 |
| 17 using content::BrowserThread; | 19 using content::BrowserThread; |
| 18 | 20 |
| 19 namespace media_stream { | 21 namespace media_stream { |
| 20 | 22 |
| 21 // Starting id for the first capture session. | 23 // Starting id for the first capture session. |
| 22 // VideoCaptureManager::kStartOpenSessionId is used as default id without | 24 // VideoCaptureManager::kStartOpenSessionId is used as default id without |
| 23 // explicitly calling open device. | 25 // explicitly calling open device. |
| 24 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 }; | 26 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 }; |
| 25 | 27 |
| 26 struct VideoCaptureManager::Controller { | 28 struct VideoCaptureManager::Controller { |
| 27 Controller( | 29 Controller( |
| 28 VideoCaptureController* vc_controller, | 30 VideoCaptureController* vc_controller, |
| 29 VideoCaptureControllerEventHandler* handler) | 31 VideoCaptureControllerEventHandler* handler) |
| 30 : controller(vc_controller), | 32 : controller(vc_controller), |
| 31 ready_to_delete(false) { | 33 ready_to_delete(false) { |
| 32 handlers.push_front(handler); | 34 handlers.push_front(handler); |
| 33 } | 35 } |
| 34 ~Controller() {} | 36 ~Controller() {} |
| 35 | 37 |
| 36 scoped_refptr<VideoCaptureController> controller; | 38 scoped_refptr<VideoCaptureController> controller; |
| 37 bool ready_to_delete; | 39 bool ready_to_delete; |
| 38 Handlers handlers; | 40 Handlers handlers; |
| 39 }; | 41 }; |
| 40 | 42 |
| 41 VideoCaptureManager::VideoCaptureManager() | 43 VideoCaptureManager::VideoCaptureManager( |
| 42 : listener_(NULL), | 44 media_stream::MediaStreamType device_type) |
| 45 : device_type_(device_type), |
| 46 listener_(NULL), |
| 43 new_capture_session_id_(kFirstSessionId), | 47 new_capture_session_id_(kFirstSessionId), |
| 44 use_fake_device_(false) { | 48 use_fake_device_(false) { |
| 49 DCHECK(content::IsVideoMediaStreamDeviceType(device_type_)); |
| 45 } | 50 } |
| 46 | 51 |
| 47 VideoCaptureManager::~VideoCaptureManager() { | 52 VideoCaptureManager::~VideoCaptureManager() { |
| 48 DCHECK(devices_.empty()); | 53 DCHECK(devices_.empty()); |
| 49 DCHECK(controllers_.empty()); | 54 DCHECK(controllers_.empty()); |
| 50 } | 55 } |
| 51 | 56 |
| 52 void VideoCaptureManager::Register(MediaStreamProviderListener* listener, | 57 void VideoCaptureManager::Register(MediaStreamProviderListener* listener, |
| 53 base::MessageLoopProxy* device_thread_loop) { | 58 base::MessageLoopProxy* device_thread_loop) { |
| 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 DCHECK(IsOnDeviceThread()); | 132 DCHECK(IsOnDeviceThread()); |
| 128 | 133 |
| 129 media::VideoCaptureDevice::Names device_names; | 134 media::VideoCaptureDevice::Names device_names; |
| 130 GetAvailableDevices(&device_names); | 135 GetAvailableDevices(&device_names); |
| 131 | 136 |
| 132 StreamDeviceInfoArray devices; | 137 StreamDeviceInfoArray devices; |
| 133 for (media::VideoCaptureDevice::Names::iterator it = | 138 for (media::VideoCaptureDevice::Names::iterator it = |
| 134 device_names.begin(); it != device_names.end(); ++it) { | 139 device_names.begin(); it != device_names.end(); ++it) { |
| 135 bool opened = DeviceOpened(*it); | 140 bool opened = DeviceOpened(*it); |
| 136 devices.push_back(StreamDeviceInfo( | 141 devices.push_back(StreamDeviceInfo( |
| 137 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, it->device_name, | 142 device_type_, it->device_name, it->unique_id, opened)); |
| 138 it->unique_id, opened)); | |
| 139 } | 143 } |
| 140 | 144 |
| 141 PostOnDevicesEnumerated(devices); | 145 PostOnDevicesEnumerated(devices); |
| 142 } | 146 } |
| 143 | 147 |
| 144 void VideoCaptureManager::OnOpen(int capture_session_id, | 148 void VideoCaptureManager::OnOpen(int capture_session_id, |
| 145 const StreamDeviceInfo& device) { | 149 const StreamDeviceInfo& device) { |
| 146 DCHECK(IsOnDeviceThread()); | 150 DCHECK(IsOnDeviceThread()); |
| 147 DCHECK(devices_.find(capture_session_id) == devices_.end()); | 151 DCHECK(devices_.find(capture_session_id) == devices_.end()); |
| 148 DVLOG(1) << "VideoCaptureManager::OnOpen, id " << capture_session_id; | 152 DVLOG(1) << "VideoCaptureManager::OnOpen, id " << capture_session_id; |
| 149 | 153 |
| 150 // Check if another session has already opened this device. If so, just | 154 // Check if another session has already opened this device. If so, just |
| 151 // use that opened device. | 155 // use that opened device. |
| 152 media::VideoCaptureDevice* video_capture_device = GetOpenedDevice(device); | 156 media::VideoCaptureDevice* video_capture_device = GetOpenedDevice(device); |
| 153 if (video_capture_device) { | 157 if (video_capture_device) { |
| 154 devices_[capture_session_id] = video_capture_device; | 158 devices_[capture_session_id] = video_capture_device; |
| 155 PostOnOpened(capture_session_id); | 159 PostOnOpened(capture_session_id); |
| 156 return; | 160 return; |
| 157 } | 161 } |
| 158 | 162 |
| 159 // Open the device. | 163 // Open the device. |
| 160 media::VideoCaptureDevice::Name vc_device_name; | 164 media::VideoCaptureDevice::Name vc_device_name; |
| 161 vc_device_name.device_name = device.name; | 165 vc_device_name.device_name = device.name; |
| 162 vc_device_name.unique_id = device.device_id; | 166 vc_device_name.unique_id = device.device_id; |
| 163 | 167 |
| 164 if (!use_fake_device_) { | 168 if (use_fake_device_) { |
| 165 video_capture_device = media::VideoCaptureDevice::Create(vc_device_name); | |
| 166 } else { | |
| 167 video_capture_device = | 169 video_capture_device = |
| 168 media::FakeVideoCaptureDevice::Create(vc_device_name); | 170 media::FakeVideoCaptureDevice::Create(vc_device_name); |
| 171 } else { |
| 172 switch (device_type_) { |
| 173 case content::MEDIA_STREAM_DEVICE_TYPE_USER_VIDEO_CAPTURE: |
| 174 video_capture_device = |
| 175 media::VideoCaptureDevice::Create(vc_device_name); |
| 176 break; |
| 177 case content::MEDIA_STREAM_DEVICE_TYPE_TAB_VIDEO_CAPTURE: |
| 178 // TODO(miu): Replace this stub with the actual implementation. |
| 179 video_capture_device = |
| 180 media::FakeVideoCaptureDevice::Create(vc_device_name); |
| 181 break; |
| 182 default: |
| 183 NOTIMPLEMENTED(); |
| 184 break; |
| 185 } |
| 169 } | 186 } |
| 170 if (!video_capture_device) { | 187 if (!video_capture_device) { |
| 171 PostOnError(capture_session_id, kDeviceNotAvailable); | 188 PostOnError(capture_session_id, kDeviceNotAvailable); |
| 172 return; | 189 return; |
| 173 } | 190 } |
| 174 | 191 |
| 175 devices_[capture_session_id] = video_capture_device; | 192 devices_[capture_session_id] = video_capture_device; |
| 176 PostOnOpened(capture_session_id); | 193 PostOnOpened(capture_session_id); |
| 177 } | 194 } |
| 178 | 195 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 OnClose(capture_session_id); | 289 OnClose(capture_session_id); |
| 273 } | 290 } |
| 274 } | 291 } |
| 275 | 292 |
| 276 void VideoCaptureManager::OnOpened(int capture_session_id) { | 293 void VideoCaptureManager::OnOpened(int capture_session_id) { |
| 277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 278 if (!listener_) { | 295 if (!listener_) { |
| 279 // Listener has been removed. | 296 // Listener has been removed. |
| 280 return; | 297 return; |
| 281 } | 298 } |
| 282 listener_->Opened(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 299 listener_->Opened(device_type_, capture_session_id); |
| 283 capture_session_id); | |
| 284 } | 300 } |
| 285 | 301 |
| 286 void VideoCaptureManager::OnClosed(int capture_session_id) { | 302 void VideoCaptureManager::OnClosed(int capture_session_id) { |
| 287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 288 if (!listener_) { | 304 if (!listener_) { |
| 289 // Listener has been removed. | 305 // Listener has been removed. |
| 290 return; | 306 return; |
| 291 } | 307 } |
| 292 listener_->Closed(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 308 listener_->Closed(device_type_, capture_session_id); |
| 293 capture_session_id); | |
| 294 } | 309 } |
| 295 | 310 |
| 296 void VideoCaptureManager::OnDevicesEnumerated( | 311 void VideoCaptureManager::OnDevicesEnumerated( |
| 297 const StreamDeviceInfoArray& devices) { | 312 const StreamDeviceInfoArray& devices) { |
| 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 313 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 299 if (!listener_) { | 314 if (!listener_) { |
| 300 // Listener has been removed. | 315 // Listener has been removed. |
| 301 return; | 316 return; |
| 302 } | 317 } |
| 303 listener_->DevicesEnumerated(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 318 listener_->DevicesEnumerated(device_type_, devices); |
| 304 devices); | |
| 305 } | 319 } |
| 306 | 320 |
| 307 void VideoCaptureManager::OnError(int capture_session_id, | 321 void VideoCaptureManager::OnError(int capture_session_id, |
| 308 MediaStreamProviderError error) { | 322 MediaStreamProviderError error) { |
| 309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 310 if (!listener_) { | 324 if (!listener_) { |
| 311 // Listener has been removed. | 325 // Listener has been removed. |
| 312 return; | 326 return; |
| 313 } | 327 } |
| 314 listener_->Error(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 328 listener_->Error(device_type_, capture_session_id, error); |
| 315 capture_session_id, error); | |
| 316 } | 329 } |
| 317 | 330 |
| 318 void VideoCaptureManager::PostOnOpened(int capture_session_id) { | 331 void VideoCaptureManager::PostOnOpened(int capture_session_id) { |
| 319 DCHECK(IsOnDeviceThread()); | 332 DCHECK(IsOnDeviceThread()); |
| 320 BrowserThread::PostTask(BrowserThread::IO, | 333 BrowserThread::PostTask(BrowserThread::IO, |
| 321 FROM_HERE, | 334 FROM_HERE, |
| 322 base::Bind(&VideoCaptureManager::OnOpened, this, | 335 base::Bind(&VideoCaptureManager::OnOpened, this, |
| 323 capture_session_id)); | 336 capture_session_id)); |
| 324 } | 337 } |
| 325 | 338 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 351 } | 364 } |
| 352 | 365 |
| 353 bool VideoCaptureManager::IsOnDeviceThread() const { | 366 bool VideoCaptureManager::IsOnDeviceThread() const { |
| 354 return device_loop_->BelongsToCurrentThread(); | 367 return device_loop_->BelongsToCurrentThread(); |
| 355 } | 368 } |
| 356 | 369 |
| 357 void VideoCaptureManager::GetAvailableDevices( | 370 void VideoCaptureManager::GetAvailableDevices( |
| 358 media::VideoCaptureDevice::Names* device_names) { | 371 media::VideoCaptureDevice::Names* device_names) { |
| 359 DCHECK(IsOnDeviceThread()); | 372 DCHECK(IsOnDeviceThread()); |
| 360 | 373 |
| 361 if (!use_fake_device_) { | 374 if (use_fake_device_) { |
| 362 media::VideoCaptureDevice::GetDeviceNames(device_names); | 375 media::FakeVideoCaptureDevice::GetDeviceNames(device_names); |
| 363 } else { | 376 } else { |
| 364 media::FakeVideoCaptureDevice::GetDeviceNames(device_names); | 377 switch (device_type_) { |
| 378 case content::MEDIA_STREAM_DEVICE_TYPE_USER_VIDEO_CAPTURE: |
| 379 media::VideoCaptureDevice::GetDeviceNames(device_names); |
| 380 break; |
| 381 case content::MEDIA_STREAM_DEVICE_TYPE_TAB_VIDEO_CAPTURE: { |
| 382 // TODO(miu): Replace this stub with the actual implementation. |
| 383 media::VideoCaptureDevice::Name name; |
| 384 name.unique_id = "/dev/video0"; |
| 385 name.device_name = "Stub Tab Video Capture"; |
| 386 device_names->push_back(name); |
| 387 break; |
| 388 } |
| 389 default: |
| 390 NOTIMPLEMENTED(); |
| 391 break; |
| 392 } |
| 365 } | 393 } |
| 366 } | 394 } |
| 367 | 395 |
| 368 bool VideoCaptureManager::DeviceOpened( | 396 bool VideoCaptureManager::DeviceOpened( |
| 369 const media::VideoCaptureDevice::Name& device_name) { | 397 const media::VideoCaptureDevice::Name& device_name) { |
| 370 DCHECK(IsOnDeviceThread()); | 398 DCHECK(IsOnDeviceThread()); |
| 371 | 399 |
| 372 for (VideoCaptureDevices::iterator it = devices_.begin(); | 400 for (VideoCaptureDevices::iterator it = devices_.begin(); |
| 373 it != devices_.end(); ++it) { | 401 it != devices_.end(); ++it) { |
| 374 if (device_name.unique_id == it->second->device_name().unique_id) { | 402 if (device_name.unique_id == it->second->device_name().unique_id) { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 | 512 |
| 485 // Solution for not using MediaStreamManager. | 513 // Solution for not using MediaStreamManager. |
| 486 // This session id won't be returned by Open(). | 514 // This session id won't be returned by Open(). |
| 487 if (capture_session_id == kStartOpenSessionId) { | 515 if (capture_session_id == kStartOpenSessionId) { |
| 488 media::VideoCaptureDevice::Names device_names; | 516 media::VideoCaptureDevice::Names device_names; |
| 489 GetAvailableDevices(&device_names); | 517 GetAvailableDevices(&device_names); |
| 490 if (device_names.empty()) { | 518 if (device_names.empty()) { |
| 491 // No devices available. | 519 // No devices available. |
| 492 return NULL; | 520 return NULL; |
| 493 } | 521 } |
| 494 StreamDeviceInfo device(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, | 522 StreamDeviceInfo device( |
| 495 device_names.front().device_name, | 523 device_type_, device_names.front().device_name, |
| 496 device_names.front().unique_id, false); | 524 device_names.front().unique_id, false); |
| 497 | 525 |
| 498 // Call OnOpen to open using the first device in the list. | 526 // Call OnOpen to open using the first device in the list. |
| 499 OnOpen(capture_session_id, device); | 527 OnOpen(capture_session_id, device); |
| 500 | 528 |
| 501 VideoCaptureDevices::iterator dit = devices_.find(capture_session_id); | 529 VideoCaptureDevices::iterator dit = devices_.find(capture_session_id); |
| 502 if (dit != devices_.end()) { | 530 if (dit != devices_.end()) { |
| 503 return dit->second; | 531 return dit->second; |
| 504 } | 532 } |
| 505 } | 533 } |
| 506 return NULL; | 534 return NULL; |
| 507 } | 535 } |
| 508 | 536 |
| 509 } // namespace media_stream | 537 } // namespace media_stream |
| OLD | NEW |