| 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 WEBRTC_TRACE(level, module, id, "%s: %.4s", msg, err); | 86 WEBRTC_TRACE(level, module, id, "%s: %.4s", msg, err); |
| 87 #else | 87 #else |
| 88 // We need to flip the characters in this case. | 88 // We need to flip the characters in this case. |
| 89 WEBRTC_TRACE(level, module, id, "%s: %.1s%.1s%.1s%.1s", msg, err + 3, err + 2, | 89 WEBRTC_TRACE(level, module, id, "%s: %.1s%.1s%.1s%.1s", msg, err + 3, err + 2, |
| 90 err + 1, err); | 90 err + 1, err); |
| 91 #endif | 91 #endif |
| 92 } | 92 } |
| 93 | 93 |
| 94 AudioDeviceMac::AudioDeviceMac(const int32_t id) | 94 AudioDeviceMac::AudioDeviceMac(const int32_t id) |
| 95 : _ptrAudioBuffer(NULL), | 95 : _ptrAudioBuffer(NULL), |
| 96 _critSect(*CriticalSectionWrapper::CreateCriticalSection()), | |
| 97 _stopEventRec(*EventWrapper::Create()), | 96 _stopEventRec(*EventWrapper::Create()), |
| 98 _stopEvent(*EventWrapper::Create()), | 97 _stopEvent(*EventWrapper::Create()), |
| 99 _id(id), | 98 _id(id), |
| 100 _mixerManager(id), | 99 _mixerManager(id), |
| 101 _inputDeviceIndex(0), | 100 _inputDeviceIndex(0), |
| 102 _outputDeviceIndex(0), | 101 _outputDeviceIndex(0), |
| 103 _inputDeviceID(kAudioObjectUnknown), | 102 _inputDeviceID(kAudioObjectUnknown), |
| 104 _outputDeviceID(kAudioObjectUnknown), | 103 _outputDeviceID(kAudioObjectUnknown), |
| 105 _inputDeviceIsSpecified(false), | 104 _inputDeviceIsSpecified(false), |
| 106 _outputDeviceIsSpecified(false), | 105 _outputDeviceIsSpecified(false), |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 } | 189 } |
| 191 | 190 |
| 192 kernErr = semaphore_destroy(mach_task_self(), _captureSemaphore); | 191 kernErr = semaphore_destroy(mach_task_self(), _captureSemaphore); |
| 193 if (kernErr != KERN_SUCCESS) { | 192 if (kernErr != KERN_SUCCESS) { |
| 194 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, | 193 WEBRTC_TRACE(kTraceError, kTraceAudioDevice, _id, |
| 195 " semaphore_destroy() error: %d", kernErr); | 194 " semaphore_destroy() error: %d", kernErr); |
| 196 } | 195 } |
| 197 | 196 |
| 198 delete &_stopEvent; | 197 delete &_stopEvent; |
| 199 delete &_stopEventRec; | 198 delete &_stopEventRec; |
| 200 delete &_critSect; | |
| 201 } | 199 } |
| 202 | 200 |
| 203 // ============================================================================ | 201 // ============================================================================ |
| 204 // API | 202 // API |
| 205 // ============================================================================ | 203 // ============================================================================ |
| 206 | 204 |
| 207 void AudioDeviceMac::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) { | 205 void AudioDeviceMac::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) { |
| 208 CriticalSectionScoped lock(&_critSect); | 206 rtc::CritScope lock(&_critSect); |
| 209 | 207 |
| 210 _ptrAudioBuffer = audioBuffer; | 208 _ptrAudioBuffer = audioBuffer; |
| 211 | 209 |
| 212 // inform the AudioBuffer about default settings for this implementation | 210 // inform the AudioBuffer about default settings for this implementation |
| 213 _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC); | 211 _ptrAudioBuffer->SetRecordingSampleRate(N_REC_SAMPLES_PER_SEC); |
| 214 _ptrAudioBuffer->SetPlayoutSampleRate(N_PLAY_SAMPLES_PER_SEC); | 212 _ptrAudioBuffer->SetPlayoutSampleRate(N_PLAY_SAMPLES_PER_SEC); |
| 215 _ptrAudioBuffer->SetRecordingChannels(N_REC_CHANNELS); | 213 _ptrAudioBuffer->SetRecordingChannels(N_REC_CHANNELS); |
| 216 _ptrAudioBuffer->SetPlayoutChannels(N_PLAY_CHANNELS); | 214 _ptrAudioBuffer->SetPlayoutChannels(N_PLAY_CHANNELS); |
| 217 } | 215 } |
| 218 | 216 |
| 219 int32_t AudioDeviceMac::ActiveAudioLayer( | 217 int32_t AudioDeviceMac::ActiveAudioLayer( |
| 220 AudioDeviceModule::AudioLayer& audioLayer) const { | 218 AudioDeviceModule::AudioLayer& audioLayer) const { |
| 221 audioLayer = AudioDeviceModule::kPlatformDefaultAudio; | 219 audioLayer = AudioDeviceModule::kPlatformDefaultAudio; |
| 222 return 0; | 220 return 0; |
| 223 } | 221 } |
| 224 | 222 |
| 225 AudioDeviceGeneric::InitStatus AudioDeviceMac::Init() { | 223 AudioDeviceGeneric::InitStatus AudioDeviceMac::Init() { |
| 226 CriticalSectionScoped lock(&_critSect); | 224 rtc::CritScope lock(&_critSect); |
| 227 | 225 |
| 228 if (_initialized) { | 226 if (_initialized) { |
| 229 return InitStatus::OK; | 227 return InitStatus::OK; |
| 230 } | 228 } |
| 231 | 229 |
| 232 OSStatus err = noErr; | 230 OSStatus err = noErr; |
| 233 | 231 |
| 234 _isShutDown = false; | 232 _isShutDown = false; |
| 235 | 233 |
| 236 // PortAudio ring buffers require an elementCount which is a power of two. | 234 // PortAudio ring buffers require an elementCount which is a power of two. |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 // Close the initialized output mixer | 414 // Close the initialized output mixer |
| 417 // | 415 // |
| 418 if (!wasInitialized) { | 416 if (!wasInitialized) { |
| 419 _mixerManager.CloseSpeaker(); | 417 _mixerManager.CloseSpeaker(); |
| 420 } | 418 } |
| 421 | 419 |
| 422 return 0; | 420 return 0; |
| 423 } | 421 } |
| 424 | 422 |
| 425 int32_t AudioDeviceMac::InitSpeaker() { | 423 int32_t AudioDeviceMac::InitSpeaker() { |
| 426 CriticalSectionScoped lock(&_critSect); | 424 rtc::CritScope lock(&_critSect); |
| 427 | 425 |
| 428 if (_playing) { | 426 if (_playing) { |
| 429 return -1; | 427 return -1; |
| 430 } | 428 } |
| 431 | 429 |
| 432 if (InitDevice(_outputDeviceIndex, _outputDeviceID, false) == -1) { | 430 if (InitDevice(_outputDeviceIndex, _outputDeviceID, false) == -1) { |
| 433 return -1; | 431 return -1; |
| 434 } | 432 } |
| 435 | 433 |
| 436 if (_inputDeviceID == _outputDeviceID) { | 434 if (_inputDeviceID == _outputDeviceID) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 464 // Close the initialized input mixer | 462 // Close the initialized input mixer |
| 465 // | 463 // |
| 466 if (!wasInitialized) { | 464 if (!wasInitialized) { |
| 467 _mixerManager.CloseMicrophone(); | 465 _mixerManager.CloseMicrophone(); |
| 468 } | 466 } |
| 469 | 467 |
| 470 return 0; | 468 return 0; |
| 471 } | 469 } |
| 472 | 470 |
| 473 int32_t AudioDeviceMac::InitMicrophone() { | 471 int32_t AudioDeviceMac::InitMicrophone() { |
| 474 CriticalSectionScoped lock(&_critSect); | 472 rtc::CritScope lock(&_critSect); |
| 475 | 473 |
| 476 if (_recording) { | 474 if (_recording) { |
| 477 return -1; | 475 return -1; |
| 478 } | 476 } |
| 479 | 477 |
| 480 if (InitDevice(_inputDeviceIndex, _inputDeviceID, true) == -1) { | 478 if (InitDevice(_inputDeviceIndex, _inputDeviceID, true) == -1) { |
| 481 return -1; | 479 return -1; |
| 482 } | 480 } |
| 483 | 481 |
| 484 if (_inputDeviceID == _outputDeviceID) { | 482 if (_inputDeviceID == _outputDeviceID) { |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 return 0; | 892 return 0; |
| 895 } | 893 } |
| 896 | 894 |
| 897 int16_t AudioDeviceMac::PlayoutDevices() { | 895 int16_t AudioDeviceMac::PlayoutDevices() { |
| 898 AudioDeviceID playDevices[MaxNumberDevices]; | 896 AudioDeviceID playDevices[MaxNumberDevices]; |
| 899 return GetNumberDevices(kAudioDevicePropertyScopeOutput, playDevices, | 897 return GetNumberDevices(kAudioDevicePropertyScopeOutput, playDevices, |
| 900 MaxNumberDevices); | 898 MaxNumberDevices); |
| 901 } | 899 } |
| 902 | 900 |
| 903 int32_t AudioDeviceMac::SetPlayoutDevice(uint16_t index) { | 901 int32_t AudioDeviceMac::SetPlayoutDevice(uint16_t index) { |
| 904 CriticalSectionScoped lock(&_critSect); | 902 rtc::CritScope lock(&_critSect); |
| 905 | 903 |
| 906 if (_playIsInitialized) { | 904 if (_playIsInitialized) { |
| 907 return -1; | 905 return -1; |
| 908 } | 906 } |
| 909 | 907 |
| 910 AudioDeviceID playDevices[MaxNumberDevices]; | 908 AudioDeviceID playDevices[MaxNumberDevices]; |
| 911 uint32_t nDevices = GetNumberDevices(kAudioDevicePropertyScopeOutput, | 909 uint32_t nDevices = GetNumberDevices(kAudioDevicePropertyScopeOutput, |
| 912 playDevices, MaxNumberDevices); | 910 playDevices, MaxNumberDevices); |
| 913 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, | 911 WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, |
| 914 " number of availiable waveform-audio output devices is %u", | 912 " number of availiable waveform-audio output devices is %u", |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 | 1044 |
| 1047 // Cancel effect of initialization | 1045 // Cancel effect of initialization |
| 1048 if (StopRecording() == -1) { | 1046 if (StopRecording() == -1) { |
| 1049 available = false; | 1047 available = false; |
| 1050 } | 1048 } |
| 1051 | 1049 |
| 1052 return 0; | 1050 return 0; |
| 1053 } | 1051 } |
| 1054 | 1052 |
| 1055 int32_t AudioDeviceMac::InitPlayout() { | 1053 int32_t AudioDeviceMac::InitPlayout() { |
| 1056 CriticalSectionScoped lock(&_critSect); | 1054 rtc::CritScope lock(&_critSect); |
| 1057 | 1055 |
| 1058 if (_playing) { | 1056 if (_playing) { |
| 1059 return -1; | 1057 return -1; |
| 1060 } | 1058 } |
| 1061 | 1059 |
| 1062 if (!_outputDeviceIsSpecified) { | 1060 if (!_outputDeviceIsSpecified) { |
| 1063 return -1; | 1061 return -1; |
| 1064 } | 1062 } |
| 1065 | 1063 |
| 1066 if (_playIsInitialized) { | 1064 if (_playIsInitialized) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID( | 1191 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceCreateIOProcID( |
| 1194 _outputDeviceID, deviceIOProc, this, &_deviceIOProcID)); | 1192 _outputDeviceID, deviceIOProc, this, &_deviceIOProcID)); |
| 1195 } | 1193 } |
| 1196 | 1194 |
| 1197 _playIsInitialized = true; | 1195 _playIsInitialized = true; |
| 1198 | 1196 |
| 1199 return 0; | 1197 return 0; |
| 1200 } | 1198 } |
| 1201 | 1199 |
| 1202 int32_t AudioDeviceMac::InitRecording() { | 1200 int32_t AudioDeviceMac::InitRecording() { |
| 1203 CriticalSectionScoped lock(&_critSect); | 1201 rtc::CritScope lock(&_critSect); |
| 1204 | 1202 |
| 1205 if (_recording) { | 1203 if (_recording) { |
| 1206 return -1; | 1204 return -1; |
| 1207 } | 1205 } |
| 1208 | 1206 |
| 1209 if (!_inputDeviceIsSpecified) { | 1207 if (!_inputDeviceIsSpecified) { |
| 1210 return -1; | 1208 return -1; |
| 1211 } | 1209 } |
| 1212 | 1210 |
| 1213 if (_recIsInitialized) { | 1211 if (_recIsInitialized) { |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 _inputDeviceID, deviceIOProc, this, &_deviceIOProcID)); | 1393 _inputDeviceID, deviceIOProc, this, &_deviceIOProcID)); |
| 1396 } | 1394 } |
| 1397 | 1395 |
| 1398 // Mark recording side as initialized | 1396 // Mark recording side as initialized |
| 1399 _recIsInitialized = true; | 1397 _recIsInitialized = true; |
| 1400 | 1398 |
| 1401 return 0; | 1399 return 0; |
| 1402 } | 1400 } |
| 1403 | 1401 |
| 1404 int32_t AudioDeviceMac::StartRecording() { | 1402 int32_t AudioDeviceMac::StartRecording() { |
| 1405 CriticalSectionScoped lock(&_critSect); | 1403 rtc::CritScope lock(&_critSect); |
| 1406 | 1404 |
| 1407 if (!_recIsInitialized) { | 1405 if (!_recIsInitialized) { |
| 1408 return -1; | 1406 return -1; |
| 1409 } | 1407 } |
| 1410 | 1408 |
| 1411 if (_recording) { | 1409 if (_recording) { |
| 1412 return 0; | 1410 return 0; |
| 1413 } | 1411 } |
| 1414 | 1412 |
| 1415 if (!_initialized) { | 1413 if (!_initialized) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1432 } else if (!_playing) { | 1430 } else if (!_playing) { |
| 1433 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _deviceIOProcID)); | 1431 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_inputDeviceID, _deviceIOProcID)); |
| 1434 } | 1432 } |
| 1435 | 1433 |
| 1436 _recording = true; | 1434 _recording = true; |
| 1437 | 1435 |
| 1438 return 0; | 1436 return 0; |
| 1439 } | 1437 } |
| 1440 | 1438 |
| 1441 int32_t AudioDeviceMac::StopRecording() { | 1439 int32_t AudioDeviceMac::StopRecording() { |
| 1442 CriticalSectionScoped lock(&_critSect); | 1440 rtc::CritScope lock(&_critSect); |
| 1443 | 1441 |
| 1444 if (!_recIsInitialized) { | 1442 if (!_recIsInitialized) { |
| 1445 return 0; | 1443 return 0; |
| 1446 } | 1444 } |
| 1447 | 1445 |
| 1448 OSStatus err = noErr; | 1446 OSStatus err = noErr; |
| 1449 | 1447 |
| 1450 // Stop device | 1448 // Stop device |
| 1451 int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive); | 1449 int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive); |
| 1452 if (_twoDevices) { | 1450 if (_twoDevices) { |
| 1453 if (_recording && captureDeviceIsAlive == 1) { | 1451 if (_recording && captureDeviceIsAlive == 1) { |
| 1454 _recording = false; | 1452 _recording = false; |
| 1455 _doStopRec = true; // Signal to io proc to stop audio device | 1453 _doStopRec = true; // Signal to io proc to stop audio device |
| 1456 _critSect.Leave(); // Cannot be under lock, risk of deadlock | 1454 _critSect.Leave(); // Cannot be under lock, risk of deadlock |
| 1457 if (kEventTimeout == _stopEventRec.Wait(2000)) { | 1455 if (kEventTimeout == _stopEventRec.Wait(2000)) { |
| 1458 CriticalSectionScoped critScoped(&_critSect); | 1456 rtc::CritScope critScoped(&_critSect); |
| 1459 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1457 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 1460 " Timed out stopping the capture IOProc. " | 1458 " Timed out stopping the capture IOProc. " |
| 1461 "We may have failed to detect a device removal."); | 1459 "We may have failed to detect a device removal."); |
| 1462 | 1460 |
| 1463 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID)); | 1461 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID)); |
| 1464 WEBRTC_CA_LOG_WARN( | 1462 WEBRTC_CA_LOG_WARN( |
| 1465 AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID)); | 1463 AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID)); |
| 1466 } | 1464 } |
| 1467 _critSect.Enter(); | 1465 _critSect.Enter(); |
| 1468 _doStopRec = false; | 1466 _doStopRec = false; |
| 1469 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, " Recording stopped"); | 1467 WEBRTC_TRACE(kTraceDebug, kTraceAudioDevice, _id, " Recording stopped"); |
| 1470 } | 1468 } |
| 1471 } else { | 1469 } else { |
| 1472 // We signal a stop for a shared device even when rendering has | 1470 // We signal a stop for a shared device even when rendering has |
| 1473 // not yet ended. This is to ensure the IOProc will return early as | 1471 // not yet ended. This is to ensure the IOProc will return early as |
| 1474 // intended (by checking |_recording|) before accessing | 1472 // intended (by checking |_recording|) before accessing |
| 1475 // resources we free below (e.g. the capture converter). | 1473 // resources we free below (e.g. the capture converter). |
| 1476 // | 1474 // |
| 1477 // In the case of a shared devcie, the IOProc will verify | 1475 // In the case of a shared devcie, the IOProc will verify |
| 1478 // rendering has ended before stopping itself. | 1476 // rendering has ended before stopping itself. |
| 1479 if (_recording && captureDeviceIsAlive == 1) { | 1477 if (_recording && captureDeviceIsAlive == 1) { |
| 1480 _recording = false; | 1478 _recording = false; |
| 1481 _doStop = true; // Signal to io proc to stop audio device | 1479 _doStop = true; // Signal to io proc to stop audio device |
| 1482 _critSect.Leave(); // Cannot be under lock, risk of deadlock | 1480 _critSect.Leave(); // Cannot be under lock, risk of deadlock |
| 1483 if (kEventTimeout == _stopEvent.Wait(2000)) { | 1481 if (kEventTimeout == _stopEvent.Wait(2000)) { |
| 1484 CriticalSectionScoped critScoped(&_critSect); | 1482 rtc::CritScope critScoped(&_critSect); |
| 1485 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1483 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 1486 " Timed out stopping the shared IOProc. " | 1484 " Timed out stopping the shared IOProc. " |
| 1487 "We may have failed to detect a device removal."); | 1485 "We may have failed to detect a device removal."); |
| 1488 | 1486 |
| 1489 // We assume rendering on a shared device has stopped as well if | 1487 // We assume rendering on a shared device has stopped as well if |
| 1490 // the IOProc times out. | 1488 // the IOProc times out. |
| 1491 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); | 1489 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); |
| 1492 WEBRTC_CA_LOG_WARN( | 1490 WEBRTC_CA_LOG_WARN( |
| 1493 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); | 1491 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); |
| 1494 } | 1492 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1533 | 1531 |
| 1534 bool AudioDeviceMac::Recording() const { | 1532 bool AudioDeviceMac::Recording() const { |
| 1535 return (_recording); | 1533 return (_recording); |
| 1536 } | 1534 } |
| 1537 | 1535 |
| 1538 bool AudioDeviceMac::PlayoutIsInitialized() const { | 1536 bool AudioDeviceMac::PlayoutIsInitialized() const { |
| 1539 return (_playIsInitialized); | 1537 return (_playIsInitialized); |
| 1540 } | 1538 } |
| 1541 | 1539 |
| 1542 int32_t AudioDeviceMac::StartPlayout() { | 1540 int32_t AudioDeviceMac::StartPlayout() { |
| 1543 CriticalSectionScoped lock(&_critSect); | 1541 rtc::CritScope lock(&_critSect); |
| 1544 | 1542 |
| 1545 if (!_playIsInitialized) { | 1543 if (!_playIsInitialized) { |
| 1546 return -1; | 1544 return -1; |
| 1547 } | 1545 } |
| 1548 | 1546 |
| 1549 if (_playing) { | 1547 if (_playing) { |
| 1550 return 0; | 1548 return 0; |
| 1551 } | 1549 } |
| 1552 | 1550 |
| 1553 RTC_DCHECK(!render_worker_thread_.get()); | 1551 RTC_DCHECK(!render_worker_thread_.get()); |
| 1554 render_worker_thread_.reset( | 1552 render_worker_thread_.reset( |
| 1555 new rtc::PlatformThread(RunRender, this, "RenderWorkerThread")); | 1553 new rtc::PlatformThread(RunRender, this, "RenderWorkerThread")); |
| 1556 render_worker_thread_->Start(); | 1554 render_worker_thread_->Start(); |
| 1557 render_worker_thread_->SetPriority(rtc::kRealtimePriority); | 1555 render_worker_thread_->SetPriority(rtc::kRealtimePriority); |
| 1558 | 1556 |
| 1559 if (_twoDevices || !_recording) { | 1557 if (_twoDevices || !_recording) { |
| 1560 OSStatus err = noErr; | 1558 OSStatus err = noErr; |
| 1561 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_outputDeviceID, _deviceIOProcID)); | 1559 WEBRTC_CA_RETURN_ON_ERR(AudioDeviceStart(_outputDeviceID, _deviceIOProcID)); |
| 1562 } | 1560 } |
| 1563 _playing = true; | 1561 _playing = true; |
| 1564 | 1562 |
| 1565 return 0; | 1563 return 0; |
| 1566 } | 1564 } |
| 1567 | 1565 |
| 1568 int32_t AudioDeviceMac::StopPlayout() { | 1566 int32_t AudioDeviceMac::StopPlayout() { |
| 1569 CriticalSectionScoped lock(&_critSect); | 1567 rtc::CritScope lock(&_critSect); |
| 1570 | 1568 |
| 1571 if (!_playIsInitialized) { | 1569 if (!_playIsInitialized) { |
| 1572 return 0; | 1570 return 0; |
| 1573 } | 1571 } |
| 1574 | 1572 |
| 1575 OSStatus err = noErr; | 1573 OSStatus err = noErr; |
| 1576 | 1574 |
| 1577 int32_t renderDeviceIsAlive = AtomicGet32(&_renderDeviceIsAlive); | 1575 int32_t renderDeviceIsAlive = AtomicGet32(&_renderDeviceIsAlive); |
| 1578 if (_playing && renderDeviceIsAlive == 1) { | 1576 if (_playing && renderDeviceIsAlive == 1) { |
| 1579 // We signal a stop for a shared device even when capturing has not | 1577 // We signal a stop for a shared device even when capturing has not |
| 1580 // yet ended. This is to ensure the IOProc will return early as | 1578 // yet ended. This is to ensure the IOProc will return early as |
| 1581 // intended (by checking |_playing|) before accessing resources we | 1579 // intended (by checking |_playing|) before accessing resources we |
| 1582 // free below (e.g. the render converter). | 1580 // free below (e.g. the render converter). |
| 1583 // | 1581 // |
| 1584 // In the case of a shared device, the IOProc will verify capturing | 1582 // In the case of a shared device, the IOProc will verify capturing |
| 1585 // has ended before stopping itself. | 1583 // has ended before stopping itself. |
| 1586 _playing = false; | 1584 _playing = false; |
| 1587 _doStop = true; // Signal to io proc to stop audio device | 1585 _doStop = true; // Signal to io proc to stop audio device |
| 1588 _critSect.Leave(); // Cannot be under lock, risk of deadlock | 1586 _critSect.Leave(); // Cannot be under lock, risk of deadlock |
| 1589 if (kEventTimeout == _stopEvent.Wait(2000)) { | 1587 if (kEventTimeout == _stopEvent.Wait(2000)) { |
| 1590 CriticalSectionScoped critScoped(&_critSect); | 1588 rtc::CritScope critScoped(&_critSect); |
| 1591 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, | 1589 WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id, |
| 1592 " Timed out stopping the render IOProc. " | 1590 " Timed out stopping the render IOProc. " |
| 1593 "We may have failed to detect a device removal."); | 1591 "We may have failed to detect a device removal."); |
| 1594 | 1592 |
| 1595 // We assume capturing on a shared device has stopped as well if the | 1593 // We assume capturing on a shared device has stopped as well if the |
| 1596 // IOProc times out. | 1594 // IOProc times out. |
| 1597 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); | 1595 WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID)); |
| 1598 WEBRTC_CA_LOG_WARN( | 1596 WEBRTC_CA_LOG_WARN( |
| 1599 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); | 1597 AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID)); |
| 1600 } | 1598 } |
| (...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2769 bool keyState = | 2767 bool keyState = |
| 2770 CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key_index); | 2768 CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, key_index); |
| 2771 // A false -> true change in keymap means a key is pressed. | 2769 // A false -> true change in keymap means a key is pressed. |
| 2772 key_down |= (keyState && !prev_key_state_[key_index]); | 2770 key_down |= (keyState && !prev_key_state_[key_index]); |
| 2773 // Save current state. | 2771 // Save current state. |
| 2774 prev_key_state_[key_index] = keyState; | 2772 prev_key_state_[key_index] = keyState; |
| 2775 } | 2773 } |
| 2776 return key_down; | 2774 return key_down; |
| 2777 } | 2775 } |
| 2778 } // namespace webrtc | 2776 } // namespace webrtc |
| OLD | NEW |