Skip to content

Commit

Permalink
audio: check for divide by zero possibilities
Browse files Browse the repository at this point in the history
When output stream is not available to audioflinger
due to any reason, sampleRate and frameCount have
zero values when trying to create new Audiotrack.
This might result in divide by 0 situation.

Change-Id: If7fbcb6eb4cfcdba6d6bb3b4f758e46e4a57e37b
(cherry picked from commit d1576c1648a78354535fc9cd7130412f300864e5)
(cherry picked from commit 15b951bfcb2180f728669ab23ef0d6791fd790c2)
(cherry picked from commit c980dbea39f984a3c28e2694174e87b311e77308)
  • Loading branch information
Pavan Chikkala authored and Linux Build Service Account committed Oct 31, 2013
1 parent 3f5fc47 commit 79bb230
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 13 deletions.
27 changes: 19 additions & 8 deletions media/libmedia/AudioTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,22 @@ status_t AudioTrack::getMinFrameCount(
// audio_format_t format
// audio_channel_mask_t channelMask
// audio_output_flags_t flags
uint32_t afSampleRate;
uint32_t afSampleRate = 0;
if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
return NO_INIT;
}
size_t afFrameCount;
size_t afFrameCount = 0;
if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) {
return NO_INIT;
}
uint32_t afLatency;
uint32_t afLatency = 0;
if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) {
return NO_INIT;
}

if(!afSampleRate || !afFrameCount) {
ALOGW("samplerate or framecount 0");
return NO_INIT;
}
// Ensure that buffer depth covers at least audio hardware latency
uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate);
if (minBufCount < 2) {
Expand Down Expand Up @@ -883,21 +886,21 @@ status_t AudioTrack::createTrack_l(

// Not all of these values are needed under all conditions, but it is easier to get them all

uint32_t afLatency;
uint32_t afLatency = 0;
status = AudioSystem::getLatency(output, streamType, &afLatency);
if (status != NO_ERROR) {
ALOGE("getLatency(%d) failed status %d", output, status);
return NO_INIT;
}

size_t afFrameCount;
size_t afFrameCount = 0;
status = AudioSystem::getFrameCount(output, streamType, &afFrameCount);
if (status != NO_ERROR) {
ALOGE("getFrameCount(output=%d, streamType=%d) status %d", output, streamType, status);
return NO_INIT;
}

uint32_t afSampleRate;
uint32_t afSampleRate = 0;
status = AudioSystem::getSamplingRate(output, streamType, &afSampleRate);
if (status != NO_ERROR) {
ALOGE("getSamplingRate(output=%d, streamType=%d) status %d", output, streamType, status);
Expand Down Expand Up @@ -966,6 +969,10 @@ status_t AudioTrack::createTrack_l(
// FIXME move these calculations and associated checks to server

// Ensure that buffer depth covers at least audio hardware latency
if(!afSampleRate && !afFrameCount) {
ALOGW("samplerate or framecount zero");
return NO_INIT;
}
uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
ALOGV("afFrameCount=%d, minBufCount=%d, afSampleRate=%u, afLatency=%d",
afFrameCount, minBufCount, afSampleRate, afLatency);
Expand Down Expand Up @@ -1102,7 +1109,11 @@ status_t AudioTrack::createTrack_l(

mAudioTrack->attachAuxEffect(mAuxEffectId);
// FIXME don't believe this lie
mLatency = afLatency + (1000*frameCount) / sampleRate;
if(sampleRate){
mLatency = afLatency + (1000*frameCount) / sampleRate;
}else{
mLatency = afLatency;
}
mFrameCount = frameCount;
// If IAudioTrack is re-created, don't let the requested frameCount
// decrease. This can confuse clients that cache frameCount().
Expand Down
27 changes: 22 additions & 5 deletions services/audioflinger/Threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1248,7 +1248,10 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
// This is probably too conservative, but legacy application code may depend on it.
// If you change this calculation, also review the start threshold which is related.
uint32_t latencyMs = mOutput->stream->get_latency(mOutput->stream);
uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
uint32_t minBufCount = 0;
if (mSampleRate) {
minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
}
if (minBufCount < 2) {
minBufCount = 2;
}
Expand Down Expand Up @@ -2617,7 +2620,10 @@ uint32_t AudioFlinger::MixerThread::correctLatency_l(uint32_t latency) const
{
if (mFastMixer != NULL) {
MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
latency += (pipe->getAvgFrames() * 1000) / mSampleRate;
if(mSampleRate)
latency += (pipe->getAvgFrames() * 1000) / mSampleRate;
else
ALOGW("SampleRate is 0");
}
return latency;
}
Expand Down Expand Up @@ -3005,7 +3011,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
desiredFrames = mNormalFrameCount;
} else {
// +1 for rounding and +1 for additional sample needed for interpolation
desiredFrames = (mNormalFrameCount * sr) / mSampleRate + 1 + 1;
if (mSampleRate) {
desiredFrames = (mNormalFrameCount * sr) / mSampleRate + 1 + 1;
} else {
desiredFrames = 2;
ALOGW("SampleRate is 0");
}
// add frames already consumed but not yet released by the resampler
// because cblk->framesReady() will include these frames
desiredFrames += mAudioMixer->getUnreleasedFrames(track->name());
Expand Down Expand Up @@ -4237,7 +4248,10 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
{
Mutex::Autolock _l(mLock);
// FIXME explain this formula
size_t frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
int sampleRate = thread->sampleRate();
size_t frameCount = 0;
if (sampleRate)
frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
OutputTrack *outputTrack = new OutputTrack(thread,
this,
mSampleRate,
Expand Down Expand Up @@ -4664,7 +4678,10 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
// If you change this calculation, also review the start threshold which is related.
uint32_t latencyMs = 50; // FIXME mInput->stream->get_latency(mInput->stream);
size_t mNormalFrameCount = 2048; // FIXME
uint32_t minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
uint32_t minBufCount = 0;
if (mSampleRate) {
minBufCount = latencyMs / ((1000 * mNormalFrameCount) / mSampleRate);
}
if (minBufCount < 2) {
minBufCount = 2;
}
Expand Down

0 comments on commit 79bb230

Please sign in to comment.