| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 | 964 |
| 965 // Cancel effect of initialization | 965 // Cancel effect of initialization |
| 966 if (StopRecording() == -1) { | 966 if (StopRecording() == -1) { |
| 967 available = false; | 967 available = false; |
| 968 } | 968 } |
| 969 | 969 |
| 970 return 0; | 970 return 0; |
| 971 } | 971 } |
| 972 | 972 |
| 973 int32_t AudioDeviceMac::InitPlayout() { | 973 int32_t AudioDeviceMac::InitPlayout() { |
| 974 LOG(LS_INFO) << "InitPlayout"; |
| 974 rtc::CritScope lock(&_critSect); | 975 rtc::CritScope lock(&_critSect); |
| 975 | 976 |
| 976 if (_playing) { | 977 if (_playing) { |
| 977 return -1; | 978 return -1; |
| 978 } | 979 } |
| 979 | 980 |
| 980 if (!_outputDeviceIsSpecified) { | 981 if (!_outputDeviceIsSpecified) { |
| 981 return -1; | 982 return -1; |
| 982 } | 983 } |
| 983 | 984 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID( | 1100 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID( |
| 1100 _outputDeviceID, deviceIOProc, this, &_deviceIOProcID)); | 1101 _outputDeviceID, deviceIOProc, this, &_deviceIOProcID)); |
| 1101 } | 1102 } |
| 1102 | 1103 |
| 1103 _playIsInitialized = true; | 1104 _playIsInitialized = true; |
| 1104 | 1105 |
| 1105 return 0; | 1106 return 0; |
| 1106 } | 1107 } |
| 1107 | 1108 |
| 1108 int32_t AudioDeviceMac::InitRecording() { | 1109 int32_t AudioDeviceMac::InitRecording() { |
| 1110 LOG(LS_INFO) << "InitRecording"; |
| 1109 rtc::CritScope lock(&_critSect); | 1111 rtc::CritScope lock(&_critSect); |
| 1110 | 1112 |
| 1111 if (_recording) { | 1113 if (_recording) { |
| 1112 return -1; | 1114 return -1; |
| 1113 } | 1115 } |
| 1114 | 1116 |
| 1115 if (!_inputDeviceIsSpecified) { | 1117 if (!_inputDeviceIsSpecified) { |
| 1116 return -1; | 1118 return -1; |
| 1117 } | 1119 } |
| 1118 | 1120 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 _inputDeviceID, deviceIOProc, this, &_deviceIOProcID)); | 1296 _inputDeviceID, deviceIOProc, this, &_deviceIOProcID)); |
| 1295 } | 1297 } |
| 1296 | 1298 |
| 1297 // Mark recording side as initialized | 1299 // Mark recording side as initialized |
| 1298 _recIsInitialized = true; | 1300 _recIsInitialized = true; |
| 1299 | 1301 |
| 1300 return 0; | 1302 return 0; |
| 1301 } | 1303 } |
| 1302 | 1304 |
| 1303 int32_t AudioDeviceMac::StartRecording() { | 1305 int32_t AudioDeviceMac::StartRecording() { |
| 1306 LOG(LS_INFO) << "StartRecording"; |
| 1304 rtc::CritScope lock(&_critSect); | 1307 rtc::CritScope lock(&_critSect); |
| 1305 | 1308 |
| 1306 if (!_recIsInitialized) { | 1309 if (!_recIsInitialized) { |
| 1307 return -1; | 1310 return -1; |
| 1308 } | 1311 } |
| 1309 | 1312 |
| 1310 if (_recording) { | 1313 if (_recording) { |
| 1311 return 0; | 1314 return 0; |
| 1312 } | 1315 } |
| 1313 | 1316 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1330 } else if (!_playing) { | 1333 } else if (!_playing) { |
| 1331 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _deviceIOProcID)); | 1334 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _deviceIOProcID)); |
| 1332 } | 1335 } |
| 1333 | 1336 |
| 1334 _recording = true; | 1337 _recording = true; |
| 1335 | 1338 |
| 1336 return 0; | 1339 return 0; |
| 1337 } | 1340 } |
| 1338 | 1341 |
| 1339 int32_t AudioDeviceMac::StopRecording() { | 1342 int32_t AudioDeviceMac::StopRecording() { |
| 1343 LOG(LS_INFO) << "StopRecording"; |
| 1340 rtc::CritScope lock(&_critSect); | 1344 rtc::CritScope lock(&_critSect); |
| 1341 | 1345 |
| 1342 if (!_recIsInitialized) { | 1346 if (!_recIsInitialized) { |
| 1343 return 0; | 1347 return 0; |
| 1344 } | 1348 } |
| 1345 | 1349 |
| 1346 OSStatus err = noErr; | 1350 OSStatus err = noErr; |
| 1347 | |
| 1348 // Stop device | |
| 1349 int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive); | 1351 int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive); |
| 1350 if (_twoDevices) { | 1352 if (_twoDevices && captureDeviceIsAlive == 1) { |
| 1351 if (_recording && captureDeviceIsAlive == 1) { | 1353 // Recording side uses its own dedicated device and IOProc. |
| 1354 if (_recording) { |
| 1352 _recording = false; | 1355 _recording = false; |
| 1353 _doStopRec = true; // Signal to io proc to stop audio device | 1356 _doStopRec = true; // Signal to io proc to stop audio device |
| 1354 _critSect.Leave(); // Cannot be under lock, risk of deadlock | 1357 _critSect.Leave(); // Cannot be under lock, risk of deadlock |
| 1355 if (kEventTimeout == _stopEventRec.Wait(2000)) { | 1358 if (kEventTimeout == _stopEventRec.Wait(2000)) { |
| 1356 rtc::CritScope critScoped(&_critSect); | 1359 rtc::CritScope critScoped(&_critSect); |
| 1357 LOG(LS_WARNING) | 1360 LOG(LS_WARNING) |
| 1358 << "Timed out stopping the capture IOProc." | 1361 << "Timed out stopping the capture IOProc." |
| 1359 << "We may have failed to detect a device removal."; | 1362 << "We may have failed to detect a device removal."; |
| 1360 | |
| 1361 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID)); | 1363 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID)); |
| 1362 WEBRTC_CA_LOG_WARN( | 1364 WEBRTC_CA_LOG_WARN( |
| 1363 AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID)); | 1365 AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID)); |
| 1364 } | 1366 } |
| 1365 _critSect.Enter(); | 1367 _critSect.Enter(); |
| 1366 _doStopRec = false; | 1368 _doStopRec = false; |
| 1367 LOG(LS_VERBOSE) << "Recording stopped"; | 1369 LOG(LS_INFO) << "Recording stopped (input device)"; |
| 1370 } else if (_recIsInitialized) { |
| 1371 WEBRTC_CA_LOG_WARN( |
| 1372 AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID)); |
| 1373 LOG(LS_INFO) << "Recording uninitialized (input device)"; |
| 1368 } | 1374 } |
| 1369 } else { | 1375 } else { |
| 1370 // We signal a stop for a shared device even when rendering has | 1376 // We signal a stop for a shared device even when rendering has |
| 1371 // not yet ended. This is to ensure the IOProc will return early as | 1377 // not yet ended. This is to ensure the IOProc will return early as |
| 1372 // intended (by checking |_recording|) before accessing | 1378 // intended (by checking |_recording|) before accessing |
| 1373 // resources we free below (e.g. the capture converter). | 1379 // resources we free below (e.g. the capture converter). |
| 1374 // | 1380 // |
| 1375 // In the case of a shared devcie, the IOProc will verify | 1381 // In the case of a shared devcie, the IOProc will verify |
| 1376 // rendering has ended before stopping itself. | 1382 // rendering has ended before stopping itself. |
| 1377 if (_recording && captureDeviceIsAlive == 1) { | 1383 if (_recording && captureDeviceIsAlive == 1) { |
| 1378 _recording = false; | 1384 _recording = false; |
| 1379 _doStop = true; // Signal to io proc to stop audio device | 1385 _doStop = true; // Signal to io proc to stop audio device |
| 1380 _critSect.Leave(); // Cannot be under lock, risk of deadlock | 1386 _critSect.Leave(); // Cannot be under lock, risk of deadlock |
| 1381 if (kEventTimeout == _stopEvent.Wait(2000)) { | 1387 if (kEventTimeout == _stopEvent.Wait(2000)) { |
| 1382 rtc::CritScope critScoped(&_critSect); | 1388 rtc::CritScope critScoped(&_critSect); |
| 1383 LOG(LS_WARNING) | 1389 LOG(LS_WARNING) |
| 1384 << "Timed out stopping the shared IOProc." | 1390 << "Timed out stopping the shared IOProc." |
| 1385 << "We may have failed to detect a device removal."; | 1391 << "We may have failed to detect a device removal."; |
| 1386 | |
| 1387 // We assume rendering on a shared device has stopped as well if | 1392 // We assume rendering on a shared device has stopped as well if |
| 1388 // the IOProc times out. | 1393 // the IOProc times out. |
| 1389 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); | 1394 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); |
| 1390 WEBRTC_CA_LOG_WARN( | 1395 WEBRTC_CA_LOG_WARN( |
| 1391 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); | 1396 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); |
| 1392 } | 1397 } |
| 1393 _critSect.Enter(); | 1398 _critSect.Enter(); |
| 1394 _doStop = false; | 1399 _doStop = false; |
| 1395 LOG(LS_VERBOSE) << "Recording stopped (shared)"; | 1400 LOG(LS_INFO) << "Recording stopped (shared device)"; |
| 1401 } else if (_recIsInitialized && !_playing && !_playIsInitialized) { |
| 1402 WEBRTC_CA_LOG_WARN( |
| 1403 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); |
| 1404 LOG(LS_INFO) << "Recording uninitialized (shared device)"; |
| 1396 } | 1405 } |
| 1397 } | 1406 } |
| 1398 | 1407 |
| 1399 // Setting this signal will allow the worker thread to be stopped. | 1408 // Setting this signal will allow the worker thread to be stopped. |
| 1400 AtomicSet32(&_captureDeviceIsAlive, 0); | 1409 AtomicSet32(&_captureDeviceIsAlive, 0); |
| 1401 | 1410 |
| 1402 if (capture_worker_thread_.get()) { | 1411 if (capture_worker_thread_.get()) { |
| 1403 _critSect.Leave(); | 1412 _critSect.Leave(); |
| 1404 capture_worker_thread_->Stop(); | 1413 capture_worker_thread_->Stop(); |
| 1405 capture_worker_thread_.reset(); | 1414 capture_worker_thread_.reset(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1430 | 1439 |
| 1431 bool AudioDeviceMac::Recording() const { | 1440 bool AudioDeviceMac::Recording() const { |
| 1432 return (_recording); | 1441 return (_recording); |
| 1433 } | 1442 } |
| 1434 | 1443 |
| 1435 bool AudioDeviceMac::PlayoutIsInitialized() const { | 1444 bool AudioDeviceMac::PlayoutIsInitialized() const { |
| 1436 return (_playIsInitialized); | 1445 return (_playIsInitialized); |
| 1437 } | 1446 } |
| 1438 | 1447 |
| 1439 int32_t AudioDeviceMac::StartPlayout() { | 1448 int32_t AudioDeviceMac::StartPlayout() { |
| 1449 LOG(LS_INFO) << "StartPlayout"; |
| 1440 rtc::CritScope lock(&_critSect); | 1450 rtc::CritScope lock(&_critSect); |
| 1441 | 1451 |
| 1442 if (!_playIsInitialized) { | 1452 if (!_playIsInitialized) { |
| 1443 return -1; | 1453 return -1; |
| 1444 } | 1454 } |
| 1445 | 1455 |
| 1446 if (_playing) { | 1456 if (_playing) { |
| 1447 return 0; | 1457 return 0; |
| 1448 } | 1458 } |
| 1449 | 1459 |
| 1450 RTC_DCHECK(!render_worker_thread_.get()); | 1460 RTC_DCHECK(!render_worker_thread_.get()); |
| 1451 render_worker_thread_.reset( | 1461 render_worker_thread_.reset( |
| 1452 new rtc::PlatformThread(RunRender, this, "RenderWorkerThread")); | 1462 new rtc::PlatformThread(RunRender, this, "RenderWorkerThread")); |
| 1453 render_worker_thread_->Start(); | 1463 render_worker_thread_->Start(); |
| 1454 render_worker_thread_->SetPriority(rtc::kRealtimePriority); | 1464 render_worker_thread_->SetPriority(rtc::kRealtimePriority); |
| 1455 | 1465 |
| 1456 if (_twoDevices || !_recording) { | 1466 if (_twoDevices || !_recording) { |
| 1457 OSStatus err = noErr; | 1467 OSStatus err = noErr; |
| 1458 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_outputDeviceID, _deviceIOProcID)); | 1468 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_outputDeviceID, _deviceIOProcID)); |
| 1459 } | 1469 } |
| 1460 _playing = true; | 1470 _playing = true; |
| 1461 | 1471 |
| 1462 return 0; | 1472 return 0; |
| 1463 } | 1473 } |
| 1464 | 1474 |
| 1465 int32_t AudioDeviceMac::StopPlayout() { | 1475 int32_t AudioDeviceMac::StopPlayout() { |
| 1476 LOG(LS_INFO) << "StopPlayout"; |
| 1466 rtc::CritScope lock(&_critSect); | 1477 rtc::CritScope lock(&_critSect); |
| 1467 | 1478 |
| 1468 if (!_playIsInitialized) { | 1479 if (!_playIsInitialized) { |
| 1469 return 0; | 1480 return 0; |
| 1470 } | 1481 } |
| 1471 | 1482 |
| 1472 OSStatus err = noErr; | 1483 OSStatus err = noErr; |
| 1473 | |
| 1474 int32_t renderDeviceIsAlive = AtomicGet32(&_renderDeviceIsAlive); | 1484 int32_t renderDeviceIsAlive = AtomicGet32(&_renderDeviceIsAlive); |
| 1475 if (_playing && renderDeviceIsAlive == 1) { | 1485 if (_playing && renderDeviceIsAlive == 1) { |
| 1476 // We signal a stop for a shared device even when capturing has not | 1486 // We signal a stop for a shared device even when capturing has not |
| 1477 // yet ended. This is to ensure the IOProc will return early as | 1487 // yet ended. This is to ensure the IOProc will return early as |
| 1478 // intended (by checking |_playing|) before accessing resources we | 1488 // intended (by checking |_playing|) before accessing resources we |
| 1479 // free below (e.g. the render converter). | 1489 // free below (e.g. the render converter). |
| 1480 // | 1490 // |
| 1481 // In the case of a shared device, the IOProc will verify capturing | 1491 // In the case of a shared device, the IOProc will verify capturing |
| 1482 // has ended before stopping itself. | 1492 // has ended before stopping itself. |
| 1483 _playing = false; | 1493 _playing = false; |
| 1484 _doStop = true; // Signal to io proc to stop audio device | 1494 _doStop = true; // Signal to io proc to stop audio device |
| 1485 _critSect.Leave(); // Cannot be under lock, risk of deadlock | 1495 _critSect.Leave(); // Cannot be under lock, risk of deadlock |
| 1486 if (kEventTimeout == _stopEvent.Wait(2000)) { | 1496 if (kEventTimeout == _stopEvent.Wait(2000)) { |
| 1487 rtc::CritScope critScoped(&_critSect); | 1497 rtc::CritScope critScoped(&_critSect); |
| 1488 LOG(LS_WARNING) | 1498 LOG(LS_WARNING) |
| 1489 << "Timed out stopping the render IOProc." | 1499 << "Timed out stopping the render IOProc." |
| 1490 << "We may have failed to detect a device removal."; | 1500 << "We may have failed to detect a device removal."; |
| 1491 | 1501 |
| 1492 // We assume capturing on a shared device has stopped as well if the | 1502 // We assume capturing on a shared device has stopped as well if the |
| 1493 // IOProc times out. | 1503 // IOProc times out. |
| 1494 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); | 1504 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); |
| 1495 WEBRTC_CA_LOG_WARN( | 1505 WEBRTC_CA_LOG_WARN( |
| 1496 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); | 1506 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); |
| 1497 } | 1507 } |
| 1498 _critSect.Enter(); | 1508 _critSect.Enter(); |
| 1499 _doStop = false; | 1509 _doStop = false; |
| 1500 LOG(LS_VERBOSE) << "Playout stopped"; | 1510 LOG(LS_INFO) << "Playout stopped"; |
| 1511 } else if (_twoDevices && _playIsInitialized) { |
| 1512 WEBRTC_CA_LOG_WARN( |
| 1513 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); |
| 1514 LOG(LS_INFO) << "Playout uninitialized (output device)"; |
| 1515 } else if (!_twoDevices && _playIsInitialized && !_recIsInitialized) { |
| 1516 WEBRTC_CA_LOG_WARN( |
| 1517 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); |
| 1518 LOG(LS_INFO) << "Playout uninitialized (shared device)"; |
| 1501 } | 1519 } |
| 1502 | 1520 |
| 1503 // Setting this signal will allow the worker thread to be stopped. | 1521 // Setting this signal will allow the worker thread to be stopped. |
| 1504 AtomicSet32(&_renderDeviceIsAlive, 0); | 1522 AtomicSet32(&_renderDeviceIsAlive, 0); |
| 1505 if (render_worker_thread_.get()) { | 1523 if (render_worker_thread_.get()) { |
| 1506 _critSect.Leave(); | 1524 _critSect.Leave(); |
| 1507 render_worker_thread_->Stop(); | 1525 render_worker_thread_->Stop(); |
| 1508 render_worker_thread_.reset(); | 1526 render_worker_thread_.reset(); |
| 1509 _critSect.Enter(); | 1527 _critSect.Enter(); |
| 1510 } | 1528 } |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 size = sizeof(devName); | 1851 size = sizeof(devName); |
| 1834 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress, | 1852 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress, |
| 1835 0, NULL, &size, devName)); | 1853 0, NULL, &size, devName)); |
| 1836 | 1854 |
| 1837 propertyAddress.mSelector = kAudioDevicePropertyDeviceManufacturer; | 1855 propertyAddress.mSelector = kAudioDevicePropertyDeviceManufacturer; |
| 1838 size = sizeof(devManf); | 1856 size = sizeof(devManf); |
| 1839 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress, | 1857 WEBRTC_CA_RETURN_ON_ERR(AudioObjectGetPropertyData(deviceId, &propertyAddress, |
| 1840 0, NULL, &size, devManf)); | 1858 0, NULL, &size, devManf)); |
| 1841 | 1859 |
| 1842 if (isInput) { | 1860 if (isInput) { |
| 1843 LOG(LS_VERBOSE) << "Input device: " << devManf << " " << devName; | 1861 LOG(LS_INFO) << "Input device: " << devManf << " " << devName; |
| 1844 } else { | 1862 } else { |
| 1845 LOG(LS_VERBOSE) << "Output device: " << devManf << " " << devName; | 1863 LOG(LS_INFO) << "Output device: " << devManf << " " << devName; |
| 1846 } | 1864 } |
| 1847 | 1865 |
| 1848 return 0; | 1866 return 0; |
| 1849 } | 1867 } |
| 1850 | 1868 |
| 1851 OSStatus AudioDeviceMac::SetDesiredPlayoutFormat() { | 1869 OSStatus AudioDeviceMac::SetDesiredPlayoutFormat() { |
| 1852 // Our preferred format to work with. | 1870 // Our preferred format to work with. |
| 1853 _outDesiredFormat.mSampleRate = N_PLAY_SAMPLES_PER_SEC; | 1871 _outDesiredFormat.mSampleRate = N_PLAY_SAMPLES_PER_SEC; |
| 1854 _outDesiredFormat.mChannelsPerFrame = _playChannels; | 1872 _outDesiredFormat.mChannelsPerFrame = _playChannels; |
| 1855 | 1873 |
| (...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2602 bool keyState = | 2620 bool keyState = |
| 2603 CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key_index); | 2621 CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key_index); |
| 2604 // A false -> true change in keymap means a key is pressed. | 2622 // A false -> true change in keymap means a key is pressed. |
| 2605 key_down |= (keyState && !prev_key_state_[key_index]); | 2623 key_down |= (keyState && !prev_key_state_[key_index]); |
| 2606 // Save current state. | 2624 // Save current state. |
| 2607 prev_key_state_[key_index] = keyState; | 2625 prev_key_state_[key_index] = keyState; |
| 2608 } | 2626 } |
| 2609 return key_down; | 2627 return key_down; |
| 2610 } | 2628 } |
| 2611 } // namespace webrtc | 2629 } // namespace webrtc |
| OLD | NEW |