Chromium Code Reviews| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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_system.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_system.h" | 53 #include "media/capture/video/video_capture_system.h" |
| 53 #include "url/gurl.h" | 54 #include "url/gurl.h" |
| 54 #include "url/origin.h" | 55 #include "url/origin.h" |
| 55 | 56 |
| 56 #if defined(OS_WIN) | 57 #if defined(OS_WIN) |
| 57 #include "base/win/scoped_com_initializer.h" | 58 #include "base/win/scoped_com_initializer.h" |
| 58 #endif | 59 #endif |
| 59 | 60 |
| 60 #if defined(OS_CHROMEOS) | 61 #if defined(OS_CHROMEOS) |
| 61 #include "chromeos/audio/cras_audio_handler.h" | 62 #include "chromeos/audio/cras_audio_handler.h" |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 | 395 |
| 395 MediaStreamManager::MediaStreamManager(media::AudioSystem* audio_system) | 396 MediaStreamManager::MediaStreamManager(media::AudioSystem* audio_system) |
| 396 : audio_system_(audio_system), | 397 : audio_system_(audio_system), |
| 397 #if defined(OS_WIN) | 398 #if defined(OS_WIN) |
| 398 video_capture_thread_("VideoCaptureThread"), | 399 video_capture_thread_("VideoCaptureThread"), |
| 399 #endif | 400 #endif |
| 400 use_fake_ui_(base::CommandLine::ForCurrentProcess()->HasSwitch( | 401 use_fake_ui_(base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 401 switches::kUseFakeUIForMediaStream)) { | 402 switches::kUseFakeUIForMediaStream)) { |
| 402 DCHECK(audio_system_); | 403 DCHECK(audio_system_); |
| 403 | 404 |
| 404 // Some unit tests create the MSM in the IO thread and assumes the | |
| 405 // initialization is done synchronously. | |
| 406 if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { | |
| 407 InitializeDeviceManagersOnIOThread(); | |
| 408 } else { | |
| 409 BrowserThread::PostTask( | |
| 410 BrowserThread::IO, FROM_HERE, | |
| 411 base::Bind(&MediaStreamManager::InitializeDeviceManagersOnIOThread, | |
| 412 base::Unretained(this))); | |
| 413 } | |
| 414 | |
| 415 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); | 405 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); |
| 416 // BrowserMainLoop always creates the PowerMonitor instance before creating | 406 // BrowserMainLoop always creates the PowerMonitor instance before creating |
| 417 // MediaStreamManager, but power_monitor may be NULL in unit tests. | 407 // MediaStreamManager, but power_monitor may be NULL in unit tests. |
| 418 if (power_monitor) | 408 if (power_monitor) |
| 419 power_monitor->AddObserver(this); | 409 power_monitor->AddObserver(this); |
| 420 } | 410 } |
| 421 | 411 |
| 422 MediaStreamManager::~MediaStreamManager() { | 412 MediaStreamManager::~MediaStreamManager() { |
| 423 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::IO)); | 413 DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::IO)); |
| 424 DVLOG(1) << "~MediaStreamManager"; | 414 DVLOG(1) << "~MediaStreamManager"; |
| 425 DCHECK(requests_.empty()); | 415 DCHECK(requests_.empty()); |
| 426 | 416 |
| 427 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); | 417 base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); |
| 428 // The PowerMonitor instance owned by BrowserMainLoops always outlives the | 418 // The PowerMonitor instance owned by BrowserMainLoops always outlives the |
| 429 // MediaStreamManager, but it may be NULL in unit tests. | 419 // MediaStreamManager, but it may be NULL in unit tests. |
| 430 if (power_monitor) | 420 if (power_monitor) |
| 431 power_monitor->RemoveObserver(this); | 421 power_monitor->RemoveObserver(this); |
| 432 } | 422 } |
| 433 | 423 |
| 424 // static | |
| 425 std::unique_ptr<MediaStreamManager> MediaStreamManager::CreateWithDefaults( | |
| 426 media::AudioSystem* audio_system) { | |
| 427 std::unique_ptr<MediaStreamManager> result( | |
| 428 new MediaStreamManager(audio_system)); | |
| 429 result->InitializeWithDefaults(); | |
| 430 return result; | |
| 431 } | |
| 432 | |
| 433 // static | |
| 434 std::unique_ptr<MediaStreamManager> | |
| 435 MediaStreamManager::CreateWithCustomVideoCaptureDeviceTaskRunner( | |
| 436 media::AudioSystem* audio_system, | |
| 437 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) { | |
| 438 std::unique_ptr<MediaStreamManager> result( | |
| 439 new MediaStreamManager(audio_system)); | |
| 440 result->InitializeWithCustomVideoCaptureDeviceTaskRunner( | |
| 441 std::move(device_task_runner)); | |
| 442 return result; | |
| 443 } | |
| 444 | |
| 445 // static | |
| 446 std::unique_ptr<MediaStreamManager> | |
| 447 MediaStreamManager::CreateWithCustomVideoCaptureSystem( | |
| 448 media::AudioSystem* audio_system, | |
| 449 std::unique_ptr<media::VideoCaptureSystem> video_capture_system, | |
| 450 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) { | |
| 451 std::unique_ptr<MediaStreamManager> result( | |
| 452 new MediaStreamManager(audio_system)); | |
| 453 result->InitializeWithCustomVideoCaptureSystem( | |
| 454 std::move(video_capture_system), std::move(device_task_runner)); | |
| 455 return result; | |
| 456 } | |
| 457 | |
| 434 VideoCaptureManager* MediaStreamManager::video_capture_manager() { | 458 VideoCaptureManager* MediaStreamManager::video_capture_manager() { |
| 435 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 459 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 436 DCHECK(video_capture_manager_.get()); | 460 DCHECK(video_capture_manager_.get()); |
| 437 return video_capture_manager_.get(); | 461 return video_capture_manager_.get(); |
| 438 } | 462 } |
| 439 | 463 |
| 440 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { | 464 AudioInputDeviceManager* MediaStreamManager::audio_input_device_manager() { |
| 441 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 465 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 442 DCHECK(audio_input_device_manager_.get()); | 466 DCHECK(audio_input_device_manager_.get()); |
| 443 return audio_input_device_manager_.get(); | 467 return audio_input_device_manager_.get(); |
| (...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1207 const std::string& label, | 1231 const std::string& label, |
| 1208 DeviceRequest* request, | 1232 DeviceRequest* request, |
| 1209 const MediaStreamDevices& devices) { | 1233 const MediaStreamDevices& devices) { |
| 1210 if (!request->callback.is_null()) | 1234 if (!request->callback.is_null()) |
| 1211 request->callback.Run(devices, std::move(request->ui_proxy)); | 1235 request->callback.Run(devices, std::move(request->ui_proxy)); |
| 1212 | 1236 |
| 1213 // Delete the request since it is done. | 1237 // Delete the request since it is done. |
| 1214 DeleteRequest(label); | 1238 DeleteRequest(label); |
| 1215 } | 1239 } |
| 1216 | 1240 |
| 1217 void MediaStreamManager::InitializeDeviceManagersOnIOThread() { | 1241 void MediaStreamManager::InitializeWithDefaults() { |
| 1218 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1242 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner = |
| 1243 audio_system_->GetTaskRunner(); | |
| 1244 #if defined(OS_WIN) | |
| 1245 // Use an STA Video Capture Thread to try to avoid crashes on enumeration of | |
| 1246 // buggy third party Direct Show modules, http://crbug.com/428958. | |
| 1247 video_capture_thread_.init_com_with_mta(false); | |
| 1248 CHECK(video_capture_thread_.Start()); | |
| 1249 device_task_runner = video_capture_thread_.task_runner(); | |
| 1250 #endif | |
| 1251 InitializeWithCustomVideoCaptureDeviceTaskRunner( | |
| 1252 std::move(device_task_runner)); | |
| 1253 } | |
| 1254 | |
| 1255 void MediaStreamManager::InitializeWithCustomVideoCaptureDeviceTaskRunner( | |
| 1256 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) { | |
| 1257 // Some unit tests initialize the MSM in the IO thread and assume the | |
| 1258 // initialization is done synchronously. Other clients call this from a | |
| 1259 // different thread and expect initialization to run asynchronously. | |
| 1260 if (BrowserThread::CurrentlyOn(BrowserThread::IO) == false) { | |
|
miu
2017/04/03 21:31:23
Usually, the style is:
if (!BrowserThread::Curr
chfremer
2017/04/04 21:59:32
Done.
| |
| 1261 BrowserThread::PostTask( | |
| 1262 BrowserThread::IO, FROM_HERE, | |
| 1263 base::Bind(&MediaStreamManager:: | |
| 1264 InitializeWithCustomVideoCaptureDeviceTaskRunner, | |
| 1265 base::Unretained(this), base::Passed(&device_task_runner))); | |
| 1266 return; | |
| 1267 } | |
| 1268 | |
| 1269 PerformCommonInitializationRoutines(); | |
| 1270 | |
| 1271 auto video_capture_system = base::MakeUnique<media::VideoCaptureSystemImpl>( | |
| 1272 media::VideoCaptureDeviceFactory::CreateFactory( | |
| 1273 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); | |
| 1274 video_capture_manager_ = new VideoCaptureManager( | |
| 1275 std::move(video_capture_system), std::move(device_task_runner)); | |
| 1276 video_capture_manager_->RegisterListener(this); | |
| 1277 | |
| 1278 media_devices_manager_.reset( | |
| 1279 new MediaDevicesManager(audio_system_, video_capture_manager_, this)); | |
| 1280 } | |
| 1281 | |
| 1282 void MediaStreamManager::InitializeWithCustomVideoCaptureSystem( | |
| 1283 std::unique_ptr<media::VideoCaptureSystem> video_capture_system, | |
| 1284 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) { | |
| 1285 // Some unit tests initialize the MSM in the IO thread and assume the | |
| 1286 // initialization is done synchronously. Other clients call this from a | |
| 1287 // different thread and expect initialization to run asynchronously. | |
| 1288 if (BrowserThread::CurrentlyOn(BrowserThread::IO) == false) { | |
| 1289 BrowserThread::PostTask( | |
| 1290 BrowserThread::IO, FROM_HERE, | |
| 1291 base::Bind(&MediaStreamManager::InitializeWithCustomVideoCaptureSystem, | |
| 1292 base::Unretained(this), base::Passed(&video_capture_system), | |
| 1293 std::move(device_task_runner))); | |
| 1294 return; | |
| 1295 } | |
| 1296 | |
| 1297 PerformCommonInitializationRoutines(); | |
| 1298 | |
| 1299 video_capture_manager_ = new VideoCaptureManager( | |
| 1300 std::move(video_capture_system), std::move(device_task_runner)); | |
| 1301 video_capture_manager_->RegisterListener(this); | |
| 1302 | |
| 1303 media_devices_manager_.reset( | |
| 1304 new MediaDevicesManager(audio_system_, video_capture_manager_, this)); | |
| 1305 } | |
| 1306 | |
| 1307 void MediaStreamManager::PerformCommonInitializationRoutines() { | |
|
miu
2017/04/03 21:31:23
After reviewing all these CreateXXX() and Initiali
chfremer
2017/04/04 21:59:32
Thanks. That allows eliminating a lot of ugliness
| |
| 1308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 1219 // Store a pointer to |this| on the IO thread to avoid having to jump to the | 1309 // Store a pointer to |this| on the IO thread to avoid having to jump to the |
| 1220 // UI thread to fetch a pointer to the MSM. In particular on Android, it can | 1310 // UI thread to fetch a pointer to the MSM. In particular on Android, it can |
| 1221 // be problematic to post to a UI thread from arbitrary worker threads since | 1311 // be problematic to post to a UI thread from arbitrary worker threads since |
| 1222 // attaching to the VM is required and we may have to access the MSM from | 1312 // attaching to the VM is required and we may have to access the MSM from |
| 1223 // callback threads that we don't own and don't want to attach. | 1313 // callback threads that we don't own and don't want to attach. |
| 1224 g_media_stream_manager_tls_ptr.Pointer()->Set(this); | 1314 g_media_stream_manager_tls_ptr.Pointer()->Set(this); |
| 1225 | 1315 |
| 1226 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1316 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1227 // fixed. | 1317 // fixed. |
| 1228 tracked_objects::ScopedTracker tracking_profile1( | 1318 tracked_objects::ScopedTracker tracking_profile1( |
| 1229 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1319 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1230 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 1")); | 1320 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 1")); |
| 1231 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 1232 | 1321 |
| 1233 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1322 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1234 // fixed. | 1323 // fixed. |
| 1235 tracked_objects::ScopedTracker tracking_profile2( | 1324 tracked_objects::ScopedTracker tracking_profile2( |
| 1236 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1325 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1237 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 2")); | 1326 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 2")); |
| 1238 audio_input_device_manager_ = | 1327 audio_input_device_manager_ = |
| 1239 new AudioInputDeviceManager(audio_system_->GetAudioManager()); | 1328 new AudioInputDeviceManager(audio_system_->GetAudioManager()); |
| 1240 audio_input_device_manager_->RegisterListener(this); | 1329 audio_input_device_manager_->RegisterListener(this); |
| 1241 | 1330 |
| 1242 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1331 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1243 // fixed. | 1332 // fixed. |
| 1244 tracked_objects::ScopedTracker tracking_profile3( | 1333 tracked_objects::ScopedTracker tracking_profile3( |
| 1245 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1334 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1246 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 3")); | 1335 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 3")); |
| 1247 // We want to be notified of IO message loop destruction to delete the thread | 1336 // We want to be notified of IO message loop destruction to delete the thread |
| 1248 // and the device managers. | 1337 // and the device managers. |
| 1249 base::MessageLoop::current()->AddDestructionObserver(this); | 1338 base::MessageLoop::current()->AddDestructionObserver(this); |
| 1250 | 1339 |
| 1251 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is | 1340 // TODO(dalecurtis): Remove ScopedTracker below once crbug.com/457525 is |
| 1252 // fixed. | 1341 // fixed. |
| 1253 tracked_objects::ScopedTracker tracking_profile4( | 1342 tracked_objects::ScopedTracker tracking_profile4( |
| 1254 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 1343 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 1255 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 4")); | 1344 "457525 MediaStreamManager::InitializeDeviceManagersOnIOThread 4")); |
| 1256 auto video_capture_system = base::MakeUnique<media::VideoCaptureSystem>( | |
| 1257 media::VideoCaptureDeviceFactory::CreateFactory( | |
| 1258 BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))); | |
| 1259 #if defined(OS_WIN) | |
| 1260 // Use an STA Video Capture Thread to try to avoid crashes on enumeration of | |
| 1261 // buggy third party Direct Show modules, http://crbug.com/428958. | |
| 1262 video_capture_thread_.init_com_with_mta(false); | |
| 1263 CHECK(video_capture_thread_.Start()); | |
| 1264 video_capture_manager_ = new VideoCaptureManager( | |
| 1265 std::move(video_capture_system), video_capture_thread_.task_runner()); | |
| 1266 #else | |
| 1267 video_capture_manager_ = new VideoCaptureManager( | |
| 1268 std::move(video_capture_system), audio_system_->GetTaskRunner()); | |
| 1269 #endif | |
| 1270 | |
| 1271 video_capture_manager_->RegisterListener(this); | |
| 1272 | |
| 1273 media_devices_manager_.reset( | |
| 1274 new MediaDevicesManager(audio_system_, video_capture_manager_, this)); | |
| 1275 } | 1345 } |
| 1276 | 1346 |
| 1277 void MediaStreamManager::Opened(MediaStreamType stream_type, | 1347 void MediaStreamManager::Opened(MediaStreamType stream_type, |
| 1278 int capture_session_id) { | 1348 int capture_session_id) { |
| 1279 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1349 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1280 DVLOG(1) << "Opened({stream_type = " << stream_type << "} " | 1350 DVLOG(1) << "Opened({stream_type = " << stream_type << "} " |
| 1281 << "{capture_session_id = " << capture_session_id << "})"; | 1351 << "{capture_session_id = " << capture_session_id << "})"; |
| 1282 // Find the request(s) containing this device and mark it as used. | 1352 // Find the request(s) containing this device and mark it as used. |
| 1283 // It can be used in several requests since the same device can be | 1353 // It can be used in several requests since the same device can be |
| 1284 // requested from the same web page. | 1354 // requested from the same web page. |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1767 request->ui_proxy->OnStarted( | 1837 request->ui_proxy->OnStarted( |
| 1768 base::Bind(&MediaStreamManager::StopMediaStreamFromBrowser, | 1838 base::Bind(&MediaStreamManager::StopMediaStreamFromBrowser, |
| 1769 base::Unretained(this), label), | 1839 base::Unretained(this), label), |
| 1770 base::Bind(&MediaStreamManager::OnMediaStreamUIWindowId, | 1840 base::Bind(&MediaStreamManager::OnMediaStreamUIWindowId, |
| 1771 base::Unretained(this), request->video_type(), | 1841 base::Unretained(this), request->video_type(), |
| 1772 request->devices)); | 1842 request->devices)); |
| 1773 } | 1843 } |
| 1774 } | 1844 } |
| 1775 | 1845 |
| 1776 } // namespace content | 1846 } // namespace content |
| OLD | NEW |