Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abc9af07 authored by Jitendra Singh Naruka's avatar Jitendra Singh Naruka Committed by Steve Kondik
Browse files

media, audioflinger: check for divide by zero possibilities and err

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: Ic13cb51facb8497e68ab596abb027b44f496b907
CRs-Fixed: 478480
parent a3602971
Loading
Loading
Loading
Loading
+22 −8
Original line number Diff line number Diff line
@@ -69,25 +69,30 @@ status_t AudioTrack::getMinFrameCount(
    //          audio_format_t format
    //          audio_channel_mask_t channelMask
    //          audio_output_flags_t flags
    int afSampleRate;
    int afSampleRate = 0;
    if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) {
        return NO_INIT;
    }
    int afFrameCount;
    int 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) minBufCount = 2;

    *frameCount = (sampleRate == 0) ? afFrameCount * minBufCount :
                afFrameCount * minBufCount * sampleRate / afSampleRate;

    ALOGV("getMinFrameCount=%d: afFrameCount=%d, minBufCount=%d, afSampleRate=%d, afLatency=%d",
            *frameCount, afFrameCount, minBufCount, afSampleRate, afLatency);
    return NO_ERROR;
@@ -988,20 +993,26 @@ status_t AudioTrack::createTrack_l(
    } else if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {

        // FIXME move these calculations and associated checks to server
        int afSampleRate;
        int afSampleRate = 0;
        if (AudioSystem::getSamplingRate(output, streamType, &afSampleRate) != NO_ERROR) {
            return NO_INIT;
        }
        int afFrameCount;
        int afFrameCount = 0;
        if (AudioSystem::getFrameCount(output, streamType, &afFrameCount) != NO_ERROR) {
            return NO_INIT;
        }

        if(!afSampleRate && !afFrameCount) {
            ALOGW("samplerate or framecount zero");
            return NO_INIT;
        }

        // Ensure that buffer depth covers at least audio hardware latency
        uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate);
        if (minBufCount < 2) minBufCount = 2;

        int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;
        uint32_t minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate;

        ALOGV("minFrameCount: %d, afFrameCount=%d, minBufCount=%d, sampleRate=%d, afSampleRate=%d"
                ", afLatency=%d",
                minFrameCount, afFrameCount, minBufCount, sampleRate, afSampleRate, afLatency);
@@ -1096,7 +1107,10 @@ status_t AudioTrack::createTrack_l(
    mCblk->waitTimeMs = 0;
    mRemainingFrames = mNotificationFramesAct;
    // FIXME don't believe this lie
    if(sampleRate)
        mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate;
    else
        mLatency = afLatency;
    // If IAudioTrack is re-created, don't let the requested frameCount
    // decrease.  This can confuse clients that cache frameCount().
    if (mCblk->frameCount > mFrameCount) {
+17 −4
Original line number Diff line number Diff line
@@ -2176,7 +2176,9 @@ 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;
        }
@@ -2279,7 +2281,10 @@ uint32_t AudioFlinger::MixerThread::correctLatency(uint32_t latency) const
{
    if (mFastMixer != NULL) {
        MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
        if(mSampleRate)
            latency += (pipe->getAvgFrames() * 1000) / mSampleRate;
        else
            ALOGW("SampleRate is 0");
    }
    return latency;
}
@@ -3521,7 +3526,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
                minFrames = mNormalFrameCount;
            } else {
                // +1 for rounding and +1 for additional sample needed for interpolation
                if(mSampleRate)
                    minFrames = (mNormalFrameCount * t->sampleRate()) / mSampleRate + 1 + 1;
                else {
                    minFrames = 2;
                    ALOGW("SampleRate is 0");
                }
                // add frames already consumed but not yet released by the resampler
                // because cblk->framesReady() will include these frames
                minFrames += mAudioMixer->getUnreleasedFrames(track->name());
@@ -4467,7 +4477,10 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
{
    Mutex::Autolock _l(mLock);
    // FIXME explain this formula
    int frameCount = (3 * mNormalFrameCount * mSampleRate) / thread->sampleRate();
    int sampleRate = thread->sampleRate();
    int frameCount = 0;
    if (sampleRate)
        frameCount = (3 * mNormalFrameCount * mSampleRate) / sampleRate;
    OutputTrack *outputTrack = new OutputTrack(thread,
                                            this,
                                            mSampleRate,