Bug 1303419: Audio gUM allocate/free improvements and nullptr crash fix r=drno

This commit is contained in:
Randell Jesup 2016-09-17 04:13:00 -04:00
Родитель 97aceec5a3
Коммит 94c164b386
1 изменённых файлов: 83 добавлений и 86 удалений

Просмотреть файл

@ -300,21 +300,13 @@ MediaEngineWebRTCMicrophoneSource::UpdateSingleSource(
} }
} }
if (!AllocChannel()) { if (!AllocChannel()) {
if (sChannelsOpen == 0) {
DeInitEngine();
}
LOG(("Audio device is not initalized")); LOG(("Audio device is not initalized"));
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (mAudioInput->SetRecordingDevice(mCapIndex)) { if (mAudioInput->SetRecordingDevice(mCapIndex)) {
FreeChannel(); FreeChannel();
if (sChannelsOpen == 0) {
DeInitEngine();
}
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
sChannelsOpen++;
mState = kAllocated;
LOG(("Audio device %d allocated", mCapIndex)); LOG(("Audio device %d allocated", mCapIndex));
break; break;
@ -401,12 +393,7 @@ MediaEngineWebRTCMicrophoneSource::Deallocate(AllocationHandle* aHandle)
} }
FreeChannel(); FreeChannel();
mState = kReleased;
LOG(("Audio device %d deallocated", mCapIndex)); LOG(("Audio device %d deallocated", mCapIndex));
MOZ_ASSERT(sChannelsOpen > 0);
if (--sChannelsOpen == 0) {
DeInitEngine();
}
} else { } else {
LOG(("Audio device %d deallocated but still in use", mCapIndex)); LOG(("Audio device %d deallocated but still in use", mCapIndex));
} }
@ -682,71 +669,17 @@ MediaEngineWebRTCMicrophoneSource::InitEngine()
mVoEBase->Init(); mVoEBase->Init();
mVoERender = webrtc::VoEExternalMedia::GetInterface(mVoiceEngine); mVoERender = webrtc::VoEExternalMedia::GetInterface(mVoiceEngine);
if (!mVoERender) { if (mVoERender) {
return false; mVoENetwork = webrtc::VoENetwork::GetInterface(mVoiceEngine);
} if (mVoENetwork) {
mVoENetwork = webrtc::VoENetwork::GetInterface(mVoiceEngine); mVoEProcessing = webrtc::VoEAudioProcessing::GetInterface(mVoiceEngine);
if (!mVoENetwork) { if (mVoEProcessing) {
return false; mNullTransport = new NullTransport();
} return true;
}
mVoEProcessing = webrtc::VoEAudioProcessing::GetInterface(mVoiceEngine); }
if (!mVoEProcessing) {
return false;
}
mNullTransport = new NullTransport();
return true;
}
bool
MediaEngineWebRTCMicrophoneSource::AllocChannel()
{
MOZ_ASSERT(mVoEBase);
mChannel = mVoEBase->CreateChannel();
if (mChannel < 0) {
return false;
}
if (mVoENetwork->RegisterExternalTransport(mChannel, *mNullTransport)) {
return false;
}
mSampleFrequency = MediaEngine::DEFAULT_SAMPLE_RATE;
LOG(("%s: sampling rate %u", __FUNCTION__, mSampleFrequency));
// Check for availability.
if (mAudioInput->SetRecordingDevice(mCapIndex)) {
return false;
}
#ifndef MOZ_B2G
// Because of the permission mechanism of B2G, we need to skip the status
// check here.
bool avail = false;
mAudioInput->GetRecordingDeviceStatus(avail);
if (!avail) {
return false;
}
#endif // MOZ_B2G
// Set "codec" to PCM, 32kHz on 1 channel
ScopedCustomReleasePtr<webrtc::VoECodec> ptrVoECodec(webrtc::VoECodec::GetInterface(mVoiceEngine));
if (!ptrVoECodec) {
return false;
}
webrtc::CodecInst codec;
strcpy(codec.plname, ENCODING);
codec.channels = CHANNELS;
MOZ_ASSERT(mSampleFrequency == 16000 || mSampleFrequency == 32000);
codec.rate = SAMPLE_RATE(mSampleFrequency);
codec.plfreq = mSampleFrequency;
codec.pacsize = SAMPLE_LENGTH(mSampleFrequency);
codec.pltype = 0; // Default payload type
if (!ptrVoECodec->SetSendCodec(mChannel, codec)) {
return true;
} }
DeInitEngine();
return false; return false;
} }
@ -766,18 +699,84 @@ MediaEngineWebRTCMicrophoneSource::DeInitEngine()
} }
} }
// This shuts down the engine when no channel is open // This shuts down the engine when no channel is open.
// mState records if a channel is allocated (slightly redundantly to mChannel)
void void
MediaEngineWebRTCMicrophoneSource::FreeChannel() MediaEngineWebRTCMicrophoneSource::FreeChannel()
{ {
if (mChannel != -1) { if (mState != kReleased) {
if (mVoENetwork) { if (mChannel != -1) {
mVoENetwork->DeRegisterExternalTransport(mChannel); MOZ_ASSERT(mVoENetwork && mVoEBase);
if (mVoENetwork) {
mVoENetwork->DeRegisterExternalTransport(mChannel);
}
if (mVoEBase) {
mVoEBase->DeleteChannel(mChannel);
}
mChannel = -1;
}
mState = kReleased;
MOZ_ASSERT(sChannelsOpen > 0);
if (--sChannelsOpen == 0) {
DeInitEngine();
} }
mVoEBase->DeleteChannel(mChannel);
mChannel = -1;
} }
mState = kReleased; }
bool
MediaEngineWebRTCMicrophoneSource::AllocChannel()
{
MOZ_ASSERT(mVoEBase);
mChannel = mVoEBase->CreateChannel();
if (mChannel >= 0) {
if (!mVoENetwork->RegisterExternalTransport(mChannel, *mNullTransport)) {
mSampleFrequency = MediaEngine::DEFAULT_SAMPLE_RATE;
LOG(("%s: sampling rate %u", __FUNCTION__, mSampleFrequency));
// Check for availability.
if (!mAudioInput->SetRecordingDevice(mCapIndex)) {
#ifndef MOZ_B2G
// Because of the permission mechanism of B2G, we need to skip the status
// check here.
bool avail = false;
mAudioInput->GetRecordingDeviceStatus(avail);
if (!avail) {
if (sChannelsOpen == 0) {
DeInitEngine();
}
return false;
}
#endif // MOZ_B2G
// Set "codec" to PCM, 32kHz on 1 channel
ScopedCustomReleasePtr<webrtc::VoECodec> ptrVoECodec(webrtc::VoECodec::GetInterface(mVoiceEngine));
if (ptrVoECodec) {
webrtc::CodecInst codec;
strcpy(codec.plname, ENCODING);
codec.channels = CHANNELS;
MOZ_ASSERT(mSampleFrequency == 16000 || mSampleFrequency == 32000);
codec.rate = SAMPLE_RATE(mSampleFrequency);
codec.plfreq = mSampleFrequency;
codec.pacsize = SAMPLE_LENGTH(mSampleFrequency);
codec.pltype = 0; // Default payload type
if (!ptrVoECodec->SetSendCodec(mChannel, codec)) {
mState = kAllocated;
sChannelsOpen++;
return true;
}
}
}
}
}
mVoEBase->DeleteChannel(mChannel);
mChannel = -1;
if (sChannelsOpen == 0) {
DeInitEngine();
}
return false;
} }
void void
@ -815,8 +814,6 @@ MediaEngineWebRTCMicrophoneSource::Shutdown()
} }
FreeChannel(); FreeChannel();
DeInitEngine();
mAudioInput = nullptr; mAudioInput = nullptr;
} }