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

Commit c255757c authored by Chong Zhang's avatar Chong Zhang Committed by Android (Google) Code Review
Browse files

Merge "HLS: allow down switch during prepare"

parents de5e5d71 8464d7de
Loading
Loading
Loading
Loading
+43 −24
Original line number Diff line number Diff line
@@ -1455,6 +1455,10 @@ void LiveSession::changeConfiguration(
    if (bandwidthIndex >= 0) {
        mOrigBandwidthIndex = mCurBandwidthIndex;
        mCurBandwidthIndex = bandwidthIndex;
        if (mOrigBandwidthIndex != mCurBandwidthIndex) {
            ALOGI("#### Starting Bandwidth Switch: %zd => %zd",
                    mOrigBandwidthIndex, mCurBandwidthIndex);
        }
    }
    CHECK_LT(mCurBandwidthIndex, mBandwidthItems.size());
    const BandwidthItem &item = mBandwidthItems.itemAt(mCurBandwidthIndex);
@@ -1574,6 +1578,7 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {

    if (timeUs >= 0) {
        mLastSeekTimeUs = timeUs;
        mLastDequeuedTimeUs = timeUs;

        for (size_t i = 0; i < mPacketSources.size(); i++) {
            mPacketSources.editValueAt(i)->clear();
@@ -1626,9 +1631,11 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
            ALOGV("stream %zu changed: oldURI %s, newURI %s", i,
                    mStreams[i].mUri.c_str(), URIs[i].c_str());
            sp<AnotherPacketSource> source = mPacketSources.valueFor(indexToType(i));
            if (source->getLatestDequeuedMeta() != NULL) {
                source->queueDiscontinuity(
                        ATSParser::DISCONTINUITY_FORMATCHANGE, NULL, true);
            }
        }
        // Determine which decoders to shutdown on the player side,
        // a decoder has to be shutdown if its streamtype was active
        // before but now longer isn't.
@@ -1687,10 +1694,6 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
            // and resume audio.
            mSwapMask =  mNewStreamMask & mStreamMask & ~resumeMask;
            switching = (mSwapMask != 0);
            if (!switching) {
                ALOGV("#### Finishing Bandwidth Switch Early: %zd => %zd",
                        mOrigBandwidthIndex, mCurBandwidthIndex);
            }
        }
        mRealTimeBaseUs = ALooper::GetNowUs() - mLastDequeuedTimeUs;
    } else {
@@ -1843,8 +1846,12 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
        mSwitchInProgress = true;
    } else {
        mStreamMask = mNewStreamMask;
        if (mOrigBandwidthIndex != mCurBandwidthIndex) {
            ALOGV("#### Finished Bandwidth Switch Early: %zd => %zd",
                    mOrigBandwidthIndex, mCurBandwidthIndex);
            mOrigBandwidthIndex = mCurBandwidthIndex;
        }
    }

    ALOGV("onChangeConfiguration3: mSwitchInProgress %d, mStreamMask 0x%x",
            mSwitchInProgress, mStreamMask);
@@ -1970,11 +1977,19 @@ void LiveSession::onPollBuffering() {

    bool underflow, ready, down, up;
    if (checkBuffering(underflow, ready, down, up)) {
        if (mInPreparationPhase && ready) {
        if (mInPreparationPhase) {
            // Allow down switch even if we're still preparing.
            //
            // Some streams have a high bandwidth index as default,
            // when bandwidth is low, it takes a long time to buffer
            // to ready mark, then it immediately pauses after start
            // as we have to do a down switch. It's better experience
            // to restart from a lower index, if we detect low bw.
            if (!switchBandwidthIfNeeded(false /* up */, down) && ready) {
                postPrepared(OK);
            }
        }

        // don't switch before we report prepared
        if (!mInPreparationPhase) {
            if (ready) {
                stopBufferingIfNecessary();
@@ -1983,7 +1998,6 @@ void LiveSession::onPollBuffering() {
            }
            switchBandwidthIfNeeded(up, down);
        }

    }

    schedulePollBuffering();
@@ -2075,7 +2089,8 @@ bool LiveSession::checkBuffering(
            if (mPacketSources[i]->isFinished(0 /* duration */)) {
                percent = 100;
            } else {
                percent = (int32_t)(100.0 * (mLastDequeuedTimeUs + bufferedDurationUs) / durationUs);
                percent = (int32_t)(100.0 *
                        (mLastDequeuedTimeUs + bufferedDurationUs) / durationUs);
            }
            if (minBufferPercent < 0 || percent < minBufferPercent) {
                minBufferPercent = percent;
@@ -2158,10 +2173,14 @@ void LiveSession::notifyBufferingUpdate(int32_t percentage) {
    notify->post();
}

void LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) {
/*
 * returns true if a bandwidth switch is actually needed (and started),
 * returns false otherwise
 */
bool LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) {
    // no need to check bandwidth if we only have 1 bandwidth settings
    if (mSwitchInProgress || mBandwidthItems.size() < 2) {
        return;
        return false;
    }

    int32_t bandwidthBps;
@@ -2170,7 +2189,7 @@ void LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) {
        mLastBandwidthBps = bandwidthBps;
    } else {
        ALOGV("no bandwidth estimate.");
        return;
        return false;
    }

    int32_t curBandwidth = mBandwidthItems.itemAt(mCurBandwidthIndex).mBandwidth;
@@ -2189,16 +2208,16 @@ void LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) {
        // bandwidthIndex is < mCurBandwidthIndex, as getBandwidthIndex() only uses 70%
        // of measured bw. In that case we don't want to do anything, since we have
        // both enough buffer and enough bw.
        if (bandwidthIndex == mCurBandwidthIndex
                || (canSwitchUp && bandwidthIndex < mCurBandwidthIndex)
                || (canSwithDown && bandwidthIndex > mCurBandwidthIndex)) {
            return;
        if ((canSwitchUp && bandwidthIndex > mCurBandwidthIndex)
         || (canSwithDown && bandwidthIndex < mCurBandwidthIndex)) {
            // if not yet prepared, just restart again with new bw index.
            // this is faster and playback experience is cleaner.
            changeConfiguration(
                    mInPreparationPhase ? 0 : -1ll, bandwidthIndex);
            return true;
        }

        ALOGI("#### Starting Bandwidth Switch: %zd => %zd",
                mCurBandwidthIndex, bandwidthIndex);
        changeConfiguration(-1, bandwidthIndex, false);
    }
    return false;
}

void LiveSession::postError(status_t err) {
+1 −1
Original line number Diff line number Diff line
@@ -292,7 +292,7 @@ private:
    bool checkSwitchProgress(
            sp<AMessage> &msg, int64_t delayUs, bool *needResumeUntil);

    void switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow);
    bool switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow);

    void schedulePollBuffering();
    void cancelPollBuffering();
+19 −8
Original line number Diff line number Diff line
@@ -355,10 +355,15 @@ int64_t AnotherPacketSource::getBufferedDurationUs_l(status_t *finalResult) {
    int64_t time2 = -1;
    int64_t durationUs = 0;

    List<sp<ABuffer> >::iterator it = mBuffers.begin();
    while (it != mBuffers.end()) {
    List<sp<ABuffer> >::iterator it;
    for (it = mBuffers.begin(); it != mBuffers.end(); it++) {
        const sp<ABuffer> &buffer = *it;

        int32_t discard;
        if (buffer->meta()->findInt32("discard", &discard) && discard) {
            continue;
        }

        int64_t timeUs;
        if (buffer->meta()->findInt64("timeUs", &timeUs)) {
            if (time1 < 0 || timeUs < time1) {
@@ -373,8 +378,6 @@ int64_t AnotherPacketSource::getBufferedDurationUs_l(status_t *finalResult) {
            durationUs += time2 - time1;
            time1 = time2 = -1;
        }

        ++it;
    }

    return durationUs + (time2 - time1);
@@ -393,11 +396,19 @@ int64_t AnotherPacketSource::getEstimatedDurationUs() {
        return getBufferedDurationUs_l(&finalResult);
    }

    List<sp<ABuffer> >::iterator it = mBuffers.begin();
    sp<ABuffer> buffer = *it;

    int64_t startTimeUs;
    sp<ABuffer> buffer;
    int32_t discard;
    int64_t startTimeUs = -1ll;
    List<sp<ABuffer> >::iterator it;
    for (it = mBuffers.begin(); it != mBuffers.end(); it++) {
        buffer = *it;
        if (buffer->meta()->findInt32("discard", &discard) && discard) {
            continue;
        }
        buffer->meta()->findInt64("timeUs", &startTimeUs);
        break;
    }

    if (startTimeUs < 0) {
        return 0;
    }