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

Commit 4adcede0 authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Reduce video frame drop rate

The video playback engine depends on having relatively precise audio
progress updates for its A/V sync and frame drop calculations.  For small
audio HAL buffer sizes, this was not a problem, but when the HAL buffer
size was > 12 ms, the normal mix buffer size became > 24 ms and this
then caused video problems.  The new formula tries to keep the normal
mix buffer size within a closer tolerance of 20 ms to 24 ms.

Also use consistent term: multiplier instead of multiple.

Bug: 6479613
Change-Id: I903bad74461908e8c8f0a61e99ab5e24d5c44433
parent 09474df6
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -142,6 +142,8 @@ static const uint32_t kMaxThreadSleepTimeShift = 2;

// minimum normal mix buffer size, expressed in milliseconds rather than frames
static const uint32_t kMinNormalMixBufferSizeMs = 20;
// maximum normal mix buffer size
static const uint32_t kMaxNormalMixBufferSizeMs = 24;

nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;

@@ -151,9 +153,9 @@ static const enum {
    FastMixer_Always,   // always initialize and use, even if not needed: for debugging only
                        // normal mixer multiplier is 1
    FastMixer_Static,   // initialize if needed, then use all the time if initialized,
                        // multipler is calculated based on minimum normal mixer buffer size
                        // multiplier is calculated based on min & max normal mixer buffer size
    FastMixer_Dynamic,  // initialize if needed, then use dynamically depending on track load,
                        // multipler is calculated based on minimum normal mixer buffer size
                        // multiplier is calculated based on min & max normal mixer buffer size
    // FIXME for FastMixer_Dynamic:
    //  Supporting this option will require fixing HALs that can't handle large writes.
    //  For example, one HAL implementation returns an error from a large write,
@@ -1950,18 +1952,42 @@ void AudioFlinger::PlaybackThread::readOutputParameters()
    }

    // Calculate size of normal mix buffer relative to the HAL output buffer size
    uint32_t multiple = 1;
    double multiplier = 1.0;
    if (mType == MIXER && (kUseFastMixer == FastMixer_Static || kUseFastMixer == FastMixer_Dynamic)) {
        size_t minNormalFrameCount = (kMinNormalMixBufferSizeMs * mSampleRate) / 1000;
        multiple = (minNormalFrameCount + mFrameCount - 1) / mFrameCount;
        // force multiple to be even, for compatibility with doubling of fast tracks due to HAL SRC
        // (it would be unusual for the normal mix buffer size to not be a multiple of fast track)
        size_t maxNormalFrameCount = (kMaxNormalMixBufferSizeMs * mSampleRate) / 1000;
        // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer
        minNormalFrameCount = (minNormalFrameCount + 15) & ~15;
        maxNormalFrameCount = maxNormalFrameCount & ~15;
        if (maxNormalFrameCount < minNormalFrameCount) {
            maxNormalFrameCount = minNormalFrameCount;
        }
        multiplier = (double) minNormalFrameCount / (double) mFrameCount;
        if (multiplier <= 1.0) {
            multiplier = 1.0;
        } else if (multiplier <= 2.0) {
            if (2 * mFrameCount <= maxNormalFrameCount) {
                multiplier = 2.0;
            } else {
                multiplier = (double) maxNormalFrameCount / (double) mFrameCount;
            }
        } else {
            // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL SRC
            // (it would be unusual for the normal mix buffer size to not be a multiple of fast
            // track, but we sometimes have to do this to satisfy the maximum frame count constraint)
            // FIXME this rounding up should not be done if no HAL SRC
        if ((multiple > 2) && (multiple & 1)) {
            ++multiple;
            uint32_t truncMult = (uint32_t) multiplier;
            if ((truncMult & 1)) {
                if ((truncMult + 1) * mFrameCount <= maxNormalFrameCount) {
                    ++truncMult;
                }
            }
            multiplier = (double) truncMult;
        }
    }
    mNormalFrameCount = multiple * mFrameCount;
    mNormalFrameCount = multiplier * mFrameCount;
    // round up to nearest 16 frames to satisfy AudioMixer
    mNormalFrameCount = (mNormalFrameCount + 15) & ~15;
    ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount, mNormalFrameCount);

    // FIXME - Current mixer implementation only supports stereo output: Always