Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: webrtc/modules/audio_device/mac/audio_device_mac.cc

Issue 3009093002: Fixes issue in ADM on Mac OSX when audio is renegotiated
Patch Set: nit Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/modules/audio_device/audio_device_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/modules/audio_device/audio_device_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698