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 |