Commit 9bb41362 authored by xians's avatar xians Committed by Commit bot

Fixed NO_DATA_ERROR on Mac.

I wrote two unittests which open  the device, wait for the data callback, then close the device, ran the tests in an infinite loop, after several hours, it hits NO_MIC_DATA on the input side. The problem is that sometimes the audio unit gets corrupted, and our input code does not correctly dispose the unit component, so the broken audio unit can be leaked and prevent the OS pumping audio callback to all auido units.

This patch fixes two problems:
1, AUAudioInputStream::Close() is not completely correct, we need to call AudioComponentInstanceDispose()
2, It seems that we should setup the input callback before setting the formats, which might not be correct (I am not really sure, but the tests show that I was able to restart the stream after changing it)

BUG=411869

Review URL: https://codereview.chromium.org/554523002

Cr-Commit-Position: refs/heads/master@{#293725}
parent 6c0caa10
......@@ -165,23 +165,6 @@ bool AUAudioInputStream::Open() {
return false;
}
// Register the input procedure for the AUHAL.
// This procedure will be called when the AUHAL has received new data
// from the input device.
AURenderCallbackStruct callback;
callback.inputProc = InputProc;
callback.inputProcRefCon = this;
result = AudioUnitSetProperty(audio_unit_,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callback,
sizeof(callback));
if (result) {
HandleError(result);
return false;
}
// Set up the the desired (output) format.
// For obtaining input from a device, the device format is always expressed
// on the output scope of the AUHAL's Element 1.
......@@ -229,6 +212,23 @@ bool AUAudioInputStream::Open() {
}
}
// Register the input procedure for the AUHAL.
// This procedure will be called when the AUHAL has received new data
// from the input device.
AURenderCallbackStruct callback;
callback.inputProc = InputProc;
callback.inputProcRefCon = this;
result = AudioUnitSetProperty(audio_unit_,
kAudioOutputUnitProperty_SetInputCallback,
kAudioUnitScope_Global,
0,
&callback,
sizeof(callback));
if (result) {
HandleError(result);
return false;
}
// Finally, initialize the audio unit and ensure that it is ready to render.
// Allocates memory according to the maximum number of audio frames
// it can produce in response to a single render call.
......@@ -299,10 +299,14 @@ void AUAudioInputStream::Close() {
}
if (audio_unit_) {
// Deallocate the audio unit’s resources.
AudioUnitUninitialize(audio_unit_);
OSStatus result = AudioUnitUninitialize(audio_unit_);
OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
<< "AudioUnitUninitialize() failed.";
result = AudioComponentInstanceDispose(audio_unit_);
OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
<< "AudioComponentInstanceDispose() failed.";
// Terminates our connection to the AUHAL component.
CloseComponent(audio_unit_);
audio_unit_ = 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment