| 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/media_stream_manager.h" | 5 #include "content/browser/renderer_host/media/media_stream_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 #include "content/public/browser/content_browser_client.h" | 38 #include "content/public/browser/content_browser_client.h" |
| 39 #include "content/public/browser/desktop_media_id.h" | 39 #include "content/public/browser/desktop_media_id.h" |
| 40 #include "content/public/browser/media_observer.h" | 40 #include "content/public/browser/media_observer.h" |
| 41 #include "content/public/browser/render_process_host.h" | 41 #include "content/public/browser/render_process_host.h" |
| 42 #include "content/public/browser/web_contents_media_capture_id.h" | 42 #include "content/public/browser/web_contents_media_capture_id.h" |
| 43 #include "content/public/common/content_client.h" | 43 #include "content/public/common/content_client.h" |
| 44 #include "content/public/common/content_switches.h" | 44 #include "content/public/common/content_switches.h" |
| 45 #include "content/public/common/media_stream_request.h" | 45 #include "content/public/common/media_stream_request.h" |
| 46 #include "crypto/hmac.h" | 46 #include "crypto/hmac.h" |
| 47 #include "media/audio/audio_device_description.h" | 47 #include "media/audio/audio_device_description.h" |
| 48 #include "media/audio/audio_manager.h" | 48 #include "media/audio/audio_system.h" |
| 49 #include "media/base/audio_parameters.h" | 49 #include "media/base/audio_parameters.h" |
| 50 #include "media/base/channel_layout.h" | 50 #include "media/base/channel_layout.h" |
| 51 #include "media/base/media_switches.h" | 51 #include "media/base/media_switches.h" |
| 52 #include "media/capture/video/video_capture_device_factory.h" | 52 #include "media/capture/video/video_capture_device_factory.h" |
| 53 #include "url/gurl.h" | 53 #include "url/gurl.h" |
| 54 #include "url/origin.h" | 54 #include "url/origin.h" |
| 55 | 55 |
| 56 #if defined(OS_WIN) | 56 #if defined(OS_WIN) |
| 57 #include "base/win/scoped_com_initializer.h" | 57 #include "base/win/scoped_com_initializer.h" |
| 58 #endif | 58 #endif |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 | 385 |
| 386 MediaStreamManager* msm = g_media_stream_manager_tls_ptr.Pointer()->Get(); | 386 MediaStreamManager* msm = g_media_stream_manager_tls_ptr.Pointer()->Get(); |
| 387 if (!msm) { | 387 if (!msm) { |
| 388 DLOG(ERROR) << "No MediaStreamManager on the IO thread. " << message; | 388 DLOG(ERROR) << "No MediaStreamManager on the IO thread. " << message; |
| 389 return; | 389 return; |
| 390 } | 390 } |
| 391 | 391 |
| 392 msm->AddLogMessageOnIOThread(message); | 392 msm->AddLogMessageOnIOThread(message); |
| 393 } | 393 } |
| 394 | 394 |
| 395 MediaStreamManager::MediaStreamManager(media::AudioManager* audio_manager) | 395 MediaStreamManager::MediaStreamManager(media::AudioSystem* audio_system) |
| 396 : audio_manager_(audio_manager), | 396 : audio_system_(audio_system), |
| 397 #if defined(OS_WIN) | 397 #if defined(OS_WIN) |
| 398 video_capture_thread_("VideoCaptureThread"), | 398 video_capture_thread_("VideoCaptureThread"), |
| 399 #endif | 399 #endif |
| 400 use_fake_ui_(base::CommandLine::ForCurrentProcess()->HasSwitch( | 400 use_fake_ui_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 401 switches::kUseFakeUIForMediaStream)) { | 401 switches::kUseFakeUIForMediaStream)) { |
| 402 DCHECK(audio_manager_); | 402 DCHECK(audio_system_); |
| 403 | 403 |
| 404 // Some unit tests create the MSM in the IO thread and assumes the | 404 // Some unit tests create the MSM in the IO thread and assumes the |
| 405 // initialization is done synchronously. | 405 // initialization is done synchronously. |
| 406 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | 406 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { |
| 407 InitializeDeviceManagersOnIOThread(); | 407 InitializeDeviceManagersOnIOThread(); |
| 408 } else { | 408 } else { |
| 409 BrowserThread::PostTask( | 409 BrowserThread::PostTask( |
| 410 BrowserThread::IO, FROM_HERE, | 410 BrowserThread::IO, FROM_HERE, |
| 411 base::Bind(&MediaStreamManager::InitializeDeviceManagersOnIOThread, | 411 base::Bind(&MediaStreamManager::InitializeDeviceManagersOnIOThread, |
| 412 base::Unretained(this))); | 412 base::Unretained(this))); |
| 413 } | 413 } |
| 414 | 414 |
| 415 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); | 415 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); |
| 416 // BrowserMainLoop always creates the PowerMonitor instance before creating | 416 // BrowserMainLoop always creates the PowerMonitor instance before creating |
| 417 // MediaStreamManager, but power_monitor may be NULL in unit tests. | 417 // MediaStreamManager, but power_monitor may be NULL in unit tests. |
| 418 if (power_monitor) | 418 if (power_monitor) |
| 419 power_monitor->AddObserver(this); | 419 power_monitor->AddObserver(this); |
| 420 } | 420 } |
| 421 | 421 |
| 422 MediaStreamManager::~MediaStreamManager() { | 422 MediaStreamManager::~MediaStreamManager() { |
| 423 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::IO)); | 423 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::IO)); |
| 424 DVLOG(1) << "~MediaStreamManager"; | 424 DVLOG(1) << "~MediaStreamManager"; |
| 425 DCHECK(requests_.empty()); | 425 DCHECK(requests_.empty()); |
| 426 DCHECK(!device_task_runner_.get()); | |
| 427 | 426 |
| 428 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); | 427 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); |
| 429 // The PowerMonitor instance owned by BrowserMainLoops always outlives the | 428 // The PowerMonitor instance owned by BrowserMainLoops always outlives the |
| 430 // MediaStreamManager, but it may be NULL in unit tests. | 429 // MediaStreamManager, but it may be NULL in unit tests. |
| 431 if (power_monitor) | 430 if (power_monitor) |
| 432 power_monitor->RemoveObserver(this); | 431 power_monitor->RemoveObserver(this); |
| 433 } | 432 } |
| 434 | 433 |
| 435 VideoCaptureManager* MediaStreamManager::video_capture_manager() { | 434 VideoCaptureManager* MediaStreamManager::video_capture_manager() { |
| 436 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 435 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 void MediaStreamManager::ReadOutputParamsAndPostRequestToUI( | 901 void MediaStreamManager::ReadOutputParamsAndPostRequestToUI( |
| 903 const std::string& label, | 902 const std::string& label, |
| 904 DeviceRequest* request, | 903 DeviceRequest* request, |
| 905 const MediaDeviceEnumeration& enumeration) { | 904 const MediaDeviceEnumeration& enumeration) { |
| 906 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 905 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 907 | 906 |
| 908 // Actual audio parameters are required only for MEDIA_TAB_AUDIO_CAPTURE. | 907 // Actual audio parameters are required only for MEDIA_TAB_AUDIO_CAPTURE. |
| 909 // TODO(guidou): MEDIA_TAB_AUDIO_CAPTURE should not be a special case. See | 908 // TODO(guidou): MEDIA_TAB_AUDIO_CAPTURE should not be a special case. See |
| 910 // crbug.com/584287. | 909 // crbug.com/584287. |
| 911 if (request->audio_type() == MEDIA_TAB_AUDIO_CAPTURE) { | 910 if (request->audio_type() == MEDIA_TAB_AUDIO_CAPTURE) { |
| 912 // Read output parameters on the correct thread for native audio OS calls. | 911 // Using base::Unretained is safe: |audio_system_| will post |
| 913 // Using base::Unretained is safe since |audio_manager_| is deleted after | 912 // PostRequestToUI() to IO thread, and MediaStreamManager is deleted on the |
| 914 // its task runner, and MediaStreamManager is deleted on the UI thread, | 913 // UI thread, after the IO thread has been stopped. |
| 915 // after the IO thread has been stopped. | 914 audio_system_->GetOutputStreamParameters( |
| 916 base::PostTaskAndReplyWithResult( | 915 media::AudioDeviceDescription::kDefaultDeviceId, |
| 917 audio_manager_->GetTaskRunner(), FROM_HERE, | |
| 918 base::Bind(&media::AudioManager::GetDefaultOutputStreamParameters, | |
| 919 base::Unretained(audio_manager_)), | |
| 920 base::Bind(&MediaStreamManager::PostRequestToUI, base::Unretained(this), | 916 base::Bind(&MediaStreamManager::PostRequestToUI, base::Unretained(this), |
| 921 label, request, enumeration)); | 917 label, request, enumeration)); |
| 922 } else { | 918 } else { |
| 923 PostRequestToUI(label, request, enumeration, media::AudioParameters()); | 919 PostRequestToUI(label, request, enumeration, media::AudioParameters()); |
| 924 } | 920 } |
| 925 } | 921 } |
| 926 | 922 |
| 927 void MediaStreamManager::PostRequestToUI( | 923 void MediaStreamManager::PostRequestToUI( |
| 928 const std::string& label, | 924 const std::string& label, |
| 929 DeviceRequest* request, | 925 DeviceRequest* request, |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 // attaching to the VM is required and we may have to access the MSM from | 1222 // attaching to the VM is required and we may have to access the MSM from |
| 1227 // callback threads that we don't own and don't want to attach. | 1223 // callback threads that we don't own and don't want to attach. |
| 1228 g_media_stream_manager_tls_ptr.Pointer()->Set(this); | 1224 g_media_stream_manager_tls_ptr.Pointer()->Set(this); |
| 1229 | 1225 |
| 1230 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1226 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1231 // fixed. | 1227 // fixed. |
| 1232 tracked_objects::ScopedTracker tracking_profile1( | 1228 tracked_objects::ScopedTracker tracking_profile1( |
| 1233 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1229 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1234 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 1")); | 1230 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 1")); |
| 1235 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1231 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1236 DCHECK(!device_task_runner_.get()); | |
| 1237 device_task_runner_ = audio_manager_->GetTaskRunner(); | |
| 1238 | 1232 |
| 1239 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1233 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1240 // fixed. | 1234 // fixed. |
| 1241 tracked_objects::ScopedTracker tracking_profile2( | 1235 tracked_objects::ScopedTracker tracking_profile2( |
| 1242 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1236 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1243 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 2")); | 1237 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 2")); |
| 1244 audio_input_device_manager_ = new AudioInputDeviceManager(audio_manager_); | 1238 audio_input_device_manager_ = |
| 1239 new AudioInputDeviceManager(audio_system_->GetAudioManager()); |
| 1245 audio_input_device_manager_->RegisterListener(this); | 1240 audio_input_device_manager_->RegisterListener(this); |
| 1246 | 1241 |
| 1247 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1242 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1248 // fixed. | 1243 // fixed. |
| 1249 tracked_objects::ScopedTracker tracking_profile3( | 1244 tracked_objects::ScopedTracker tracking_profile3( |
| 1250 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1245 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1251 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 3")); | 1246 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 3")); |
| 1252 // We want to be notified of IO message loop destruction to delete the thread | 1247 // We want to be notified of IO message loop destruction to delete the thread |
| 1253 // and the device managers. | 1248 // and the device managers. |
| 1254 base::MessageLoop::current()->AddDestructionObserver(this); | 1249 base::MessageLoop::current()->AddDestructionObserver(this); |
| 1255 | 1250 |
| 1256 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1251 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1257 // fixed. | 1252 // fixed. |
| 1258 tracked_objects::ScopedTracker tracking_profile4( | 1253 tracked_objects::ScopedTracker tracking_profile4( |
| 1259 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1254 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1260 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 4")); | 1255 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 4")); |
| 1261 #if defined(OS_WIN) | 1256 #if defined(OS_WIN) |
| 1262 // Use an STA Video Capture Thread to try to avoid crashes on enumeration of | 1257 // Use an STA Video Capture Thread to try to avoid crashes on enumeration of |
| 1263 // buggy third party Direct Show modules, http://crbug.com/428958. | 1258 // buggy third party Direct Show modules, http://crbug.com/428958. |
| 1264 video_capture_thread_.init_com_with_mta(false); | 1259 video_capture_thread_.init_com_with_mta(false); |
| 1265 CHECK(video_capture_thread_.Start()); | 1260 CHECK(video_capture_thread_.Start()); |
| 1266 video_capture_manager_ = new VideoCaptureManager( | 1261 video_capture_manager_ = new VideoCaptureManager( |
| 1267 media::VideoCaptureDeviceFactory::CreateFactory( | 1262 media::VideoCaptureDeviceFactory::CreateFactory( |
| 1268 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)), | 1263 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)), |
| 1269 video_capture_thread_.task_runner()); | 1264 video_capture_thread_.task_runner()); |
| 1270 #else | 1265 #else |
| 1271 video_capture_manager_ = new VideoCaptureManager( | 1266 video_capture_manager_ = new VideoCaptureManager( |
| 1272 media::VideoCaptureDeviceFactory::CreateFactory( | 1267 media::VideoCaptureDeviceFactory::CreateFactory( |
| 1273 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)), | 1268 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)), |
| 1274 device_task_runner_); | 1269 audio_system_->GetTaskRunner()); |
| 1275 #endif | 1270 #endif |
| 1276 | 1271 |
| 1277 video_capture_manager_->RegisterListener(this); | 1272 video_capture_manager_->RegisterListener(this); |
| 1278 | 1273 |
| 1279 media_devices_manager_.reset( | 1274 media_devices_manager_.reset(new MediaDevicesManager( |
| 1280 new MediaDevicesManager(audio_manager_, video_capture_manager_, this)); | 1275 audio_system_->GetAudioManager(), video_capture_manager_, this)); |
| 1281 } | 1276 } |
| 1282 | 1277 |
| 1283 void MediaStreamManager::Opened(MediaStreamType stream_type, | 1278 void MediaStreamManager::Opened(MediaStreamType stream_type, |
| 1284 int capture_session_id) { | 1279 int capture_session_id) { |
| 1285 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1280 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1286 DVLOG(1) << "Opened({stream_type = " << stream_type << "} " | 1281 DVLOG(1) << "Opened({stream_type = " << stream_type << "} " |
| 1287 << "{capture_session_id = " << capture_session_id << "})"; | 1282 << "{capture_session_id = " << capture_session_id << "})"; |
| 1288 // Find the request(s) containing this device and mark it as used. | 1283 // Find the request(s) containing this device and mark it as used. |
| 1289 // It can be used in several requests since the same device can be | 1284 // It can be used in several requests since the same device can be |
| 1290 // requested from the same web page. | 1285 // requested from the same web page. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()"; | 1548 DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()"; |
| 1554 DCHECK(CalledOnIOThread()); | 1549 DCHECK(CalledOnIOThread()); |
| 1555 DCHECK(requests_.empty()); | 1550 DCHECK(requests_.empty()); |
| 1556 if (media_devices_manager_) | 1551 if (media_devices_manager_) |
| 1557 media_devices_manager_->StopMonitoring(); | 1552 media_devices_manager_->StopMonitoring(); |
| 1558 if (video_capture_manager_) | 1553 if (video_capture_manager_) |
| 1559 video_capture_manager_->UnregisterListener(this); | 1554 video_capture_manager_->UnregisterListener(this); |
| 1560 if (audio_input_device_manager_) | 1555 if (audio_input_device_manager_) |
| 1561 audio_input_device_manager_->UnregisterListener(this); | 1556 audio_input_device_manager_->UnregisterListener(this); |
| 1562 | 1557 |
| 1563 device_task_runner_ = nullptr; | |
| 1564 audio_input_device_manager_ = nullptr; | 1558 audio_input_device_manager_ = nullptr; |
| 1565 video_capture_manager_ = nullptr; | 1559 video_capture_manager_ = nullptr; |
| 1566 media_devices_manager_ = nullptr; | 1560 media_devices_manager_ = nullptr; |
| 1567 g_media_stream_manager_tls_ptr.Pointer()->Set(nullptr); | 1561 g_media_stream_manager_tls_ptr.Pointer()->Set(nullptr); |
| 1568 } | 1562 } |
| 1569 | 1563 |
| 1570 void MediaStreamManager::NotifyDevicesChanged( | 1564 void MediaStreamManager::NotifyDevicesChanged( |
| 1571 MediaDeviceType device_type, | 1565 MediaDeviceType device_type, |
| 1572 const MediaDeviceInfoArray& devices) { | 1566 const MediaDeviceInfoArray& devices) { |
| 1573 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1567 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1774 request->ui_proxy->OnStarted( | 1768 request->ui_proxy->OnStarted( |
| 1775 base::Bind(&MediaStreamManager::StopMediaStreamFromBrowser, | 1769 base::Bind(&MediaStreamManager::StopMediaStreamFromBrowser, |
| 1776 base::Unretained(this), label), | 1770 base::Unretained(this), label), |
| 1777 base::Bind(&MediaStreamManager::OnMediaStreamUIWindowId, | 1771 base::Bind(&MediaStreamManager::OnMediaStreamUIWindowId, |
| 1778 base::Unretained(this), request->video_type(), | 1772 base::Unretained(this), request->video_type(), |
| 1779 request->devices)); | 1773 request->devices)); |
| 1780 } | 1774 } |
| 1781 } | 1775 } |
| 1782 | 1776 |
| 1783 } // namespace content | 1777 } // namespace content |
| OLD | NEW |