Fixes issue in ADM on Mac OSX when audio is renegotiated
Moved from https://codereview.webrtc.org/3009093002/ TBR=hlundin-webrtc Bug: webrtc:8041 Change-Id: I33485629a6f1dcb86fd4242468841605e7d8a72a Reviewed-on: https://webrtc-review.googlesource.com/3440 Reviewed-by: Henrik Andreassson <henrika@webrtc.org> Commit-Queue: Henrik Andreassson <henrika@webrtc.org> Cr-Commit-Position: refs/heads/master@{#19949}
This commit is contained in:
@ -574,6 +574,52 @@ TEST_F(AudioDeviceTest, StartStopRecording) {
|
||||
StopRecording();
|
||||
}
|
||||
|
||||
// Tests Init/Stop/Init recording without any registered audio callback.
|
||||
// See https://bugs.chromium.org/p/webrtc/issues/detail?id=8041 for details
|
||||
// on why this test is useful.
|
||||
TEST_F(AudioDeviceTest, InitStopInitRecording) {
|
||||
SKIP_TEST_IF_NOT(requirements_satisfied());
|
||||
EXPECT_EQ(0, audio_device()->InitRecording());
|
||||
EXPECT_TRUE(audio_device()->RecordingIsInitialized());
|
||||
StopRecording();
|
||||
EXPECT_EQ(0, audio_device()->InitRecording());
|
||||
StopRecording();
|
||||
}
|
||||
|
||||
// Tests Init/Stop/Init recording while playout is active.
|
||||
TEST_F(AudioDeviceTest, InitStopInitRecordingWhilePlaying) {
|
||||
SKIP_TEST_IF_NOT(requirements_satisfied());
|
||||
StartPlayout();
|
||||
EXPECT_EQ(0, audio_device()->InitRecording());
|
||||
EXPECT_TRUE(audio_device()->RecordingIsInitialized());
|
||||
StopRecording();
|
||||
EXPECT_EQ(0, audio_device()->InitRecording());
|
||||
StopRecording();
|
||||
StopPlayout();
|
||||
}
|
||||
|
||||
// Tests Init/Stop/Init playout without any registered audio callback.
|
||||
TEST_F(AudioDeviceTest, InitStopInitPlayout) {
|
||||
SKIP_TEST_IF_NOT(requirements_satisfied());
|
||||
EXPECT_EQ(0, audio_device()->InitPlayout());
|
||||
EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
|
||||
StopPlayout();
|
||||
EXPECT_EQ(0, audio_device()->InitPlayout());
|
||||
StopPlayout();
|
||||
}
|
||||
|
||||
// Tests Init/Stop/Init playout while recording is active.
|
||||
TEST_F(AudioDeviceTest, InitStopInitPlayoutWhileRecording) {
|
||||
SKIP_TEST_IF_NOT(requirements_satisfied());
|
||||
StartRecording();
|
||||
EXPECT_EQ(0, audio_device()->InitPlayout());
|
||||
EXPECT_TRUE(audio_device()->PlayoutIsInitialized());
|
||||
StopPlayout();
|
||||
EXPECT_EQ(0, audio_device()->InitPlayout());
|
||||
StopPlayout();
|
||||
StopRecording();
|
||||
}
|
||||
|
||||
// Start playout and verify that the native audio layer starts asking for real
|
||||
// audio samples to play out using the NeedMorePlayData() callback.
|
||||
// Note that we can't add expectations on audio parameters in EXPECT_CALL
|
||||
|
||||
@ -971,6 +971,7 @@ int32_t AudioDeviceMac::RecordingIsAvailable(bool& available) {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceMac::InitPlayout() {
|
||||
LOG(LS_INFO) << "InitPlayout";
|
||||
rtc::CritScope lock(&_critSect);
|
||||
|
||||
if (_playing) {
|
||||
@ -1106,6 +1107,7 @@ int32_t AudioDeviceMac::InitPlayout() {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceMac::InitRecording() {
|
||||
LOG(LS_INFO) << "InitRecording";
|
||||
rtc::CritScope lock(&_critSect);
|
||||
|
||||
if (_recording) {
|
||||
@ -1301,6 +1303,7 @@ int32_t AudioDeviceMac::InitRecording() {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceMac::StartRecording() {
|
||||
LOG(LS_INFO) << "StartRecording";
|
||||
rtc::CritScope lock(&_critSect);
|
||||
|
||||
if (!_recIsInitialized) {
|
||||
@ -1337,6 +1340,7 @@ int32_t AudioDeviceMac::StartRecording() {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceMac::StopRecording() {
|
||||
LOG(LS_INFO) << "StopRecording";
|
||||
rtc::CritScope lock(&_critSect);
|
||||
|
||||
if (!_recIsInitialized) {
|
||||
@ -1344,11 +1348,10 @@ int32_t AudioDeviceMac::StopRecording() {
|
||||
}
|
||||
|
||||
OSStatus err = noErr;
|
||||
|
||||
// Stop device
|
||||
int32_t captureDeviceIsAlive = AtomicGet32(&_captureDeviceIsAlive);
|
||||
if (_twoDevices) {
|
||||
if (_recording && captureDeviceIsAlive == 1) {
|
||||
if (_twoDevices && captureDeviceIsAlive == 1) {
|
||||
// Recording side uses its own dedicated device and IOProc.
|
||||
if (_recording) {
|
||||
_recording = false;
|
||||
_doStopRec = true; // Signal to io proc to stop audio device
|
||||
_critSect.Leave(); // Cannot be under lock, risk of deadlock
|
||||
@ -1357,14 +1360,17 @@ int32_t AudioDeviceMac::StopRecording() {
|
||||
LOG(LS_WARNING)
|
||||
<< "Timed out stopping the capture IOProc."
|
||||
<< "We may have failed to detect a device removal.";
|
||||
|
||||
WEBRTC_CA_LOG_WARN(AudioDeviceStop(_inputDeviceID, _inDeviceIOProcID));
|
||||
WEBRTC_CA_LOG_WARN(
|
||||
AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID));
|
||||
AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID));
|
||||
}
|
||||
_critSect.Enter();
|
||||
_doStopRec = false;
|
||||
LOG(LS_VERBOSE) << "Recording stopped";
|
||||
LOG(LS_INFO) << "Recording stopped (input device)";
|
||||
} else if (_recIsInitialized) {
|
||||
WEBRTC_CA_LOG_WARN(
|
||||
AudioDeviceDestroyIOProcID(_inputDeviceID, _inDeviceIOProcID));
|
||||
LOG(LS_INFO) << "Recording uninitialized (input device)";
|
||||
}
|
||||
} else {
|
||||
// We signal a stop for a shared device even when rendering has
|
||||
@ -1383,7 +1389,6 @@ int32_t AudioDeviceMac::StopRecording() {
|
||||
LOG(LS_WARNING)
|
||||
<< "Timed out stopping the shared IOProc."
|
||||
<< "We may have failed to detect a device removal.";
|
||||
|
||||
// We assume rendering on a shared device has stopped as well if
|
||||
// the IOProc times out.
|
||||
WEBRTC_CA_LOG_WARN(AudioDeviceStop(_outputDeviceID, _deviceIOProcID));
|
||||
@ -1392,7 +1397,11 @@ int32_t AudioDeviceMac::StopRecording() {
|
||||
}
|
||||
_critSect.Enter();
|
||||
_doStop = false;
|
||||
LOG(LS_VERBOSE) << "Recording stopped (shared)";
|
||||
LOG(LS_INFO) << "Recording stopped (shared device)";
|
||||
} else if (_recIsInitialized && !_playing && !_playIsInitialized) {
|
||||
WEBRTC_CA_LOG_WARN(
|
||||
AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
|
||||
LOG(LS_INFO) << "Recording uninitialized (shared device)";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1437,6 +1446,7 @@ bool AudioDeviceMac::PlayoutIsInitialized() const {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceMac::StartPlayout() {
|
||||
LOG(LS_INFO) << "StartPlayout";
|
||||
rtc::CritScope lock(&_critSect);
|
||||
|
||||
if (!_playIsInitialized) {
|
||||
@ -1463,6 +1473,7 @@ int32_t AudioDeviceMac::StartPlayout() {
|
||||
}
|
||||
|
||||
int32_t AudioDeviceMac::StopPlayout() {
|
||||
LOG(LS_INFO) << "StopPlayout";
|
||||
rtc::CritScope lock(&_critSect);
|
||||
|
||||
if (!_playIsInitialized) {
|
||||
@ -1470,7 +1481,6 @@ int32_t AudioDeviceMac::StopPlayout() {
|
||||
}
|
||||
|
||||
OSStatus err = noErr;
|
||||
|
||||
int32_t renderDeviceIsAlive = AtomicGet32(&_renderDeviceIsAlive);
|
||||
if (_playing && renderDeviceIsAlive == 1) {
|
||||
// We signal a stop for a shared device even when capturing has not
|
||||
@ -1497,7 +1507,15 @@ int32_t AudioDeviceMac::StopPlayout() {
|
||||
}
|
||||
_critSect.Enter();
|
||||
_doStop = false;
|
||||
LOG(LS_VERBOSE) << "Playout stopped";
|
||||
LOG(LS_INFO) << "Playout stopped";
|
||||
} else if (_twoDevices && _playIsInitialized) {
|
||||
WEBRTC_CA_LOG_WARN(
|
||||
AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
|
||||
LOG(LS_INFO) << "Playout uninitialized (output device)";
|
||||
} else if (!_twoDevices && _playIsInitialized && !_recIsInitialized) {
|
||||
WEBRTC_CA_LOG_WARN(
|
||||
AudioDeviceDestroyIOProcID(_outputDeviceID, _deviceIOProcID));
|
||||
LOG(LS_INFO) << "Playout uninitialized (shared device)";
|
||||
}
|
||||
|
||||
// Setting this signal will allow the worker thread to be stopped.
|
||||
@ -1840,9 +1858,9 @@ int32_t AudioDeviceMac::InitDevice(const uint16_t userDeviceIndex,
|
||||
0, NULL, &size, devManf));
|
||||
|
||||
if (isInput) {
|
||||
LOG(LS_VERBOSE) << "Input device: " << devManf << " " << devName;
|
||||
LOG(LS_INFO) << "Input device: " << devManf << " " << devName;
|
||||
} else {
|
||||
LOG(LS_VERBOSE) << "Output device: " << devManf << " " << devName;
|
||||
LOG(LS_INFO) << "Output device: " << devManf << " " << devName;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user