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 |