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

Commit 48fa06d1 authored by Wei Jia's avatar Wei Jia
Browse files

BufferingSettings: hook up internal BufferingSettings API.

Test: compiles
Bug: 32524218

Change-Id: I4b3f1689681560f0c1af3bfc62adee1ce630e218
parent d0c3b930
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ struct BufferingSettings : public Parcelable {
    static const int kNoWatermark = -1;

    static bool IsValidBufferingMode(int mode);
    static bool IsTimeBasedBufferingMode(int mode);
    static bool IsSizeBasedBufferingMode(int mode);

    BufferingMode mInitialBufferingMode;  // for prepare
    BufferingMode mRebufferingMode;  // for playback
+4 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <system/audio.h>
#include <media/BufferingSettings.h>
#include <media/MediaPlayerInterface.h>

namespace android {
@@ -90,6 +91,9 @@ void writeToAMessage(const sp<AMessage> &msg, const AVSyncSettings &sync, float
void readFromAMessage(
        const sp<AMessage> &msg, AVSyncSettings *sync /* nonnull */, float *videoFps /* nonnull */);

void writeToAMessage(const sp<AMessage> &msg, const BufferingSettings &buffering);
void readFromAMessage(const sp<AMessage> &msg, BufferingSettings *buffering /* nonnull */);

AString nameForFd(int fd);

}  // namespace android
+10 −0
Original line number Diff line number Diff line
@@ -28,6 +28,16 @@ bool BufferingSettings::IsValidBufferingMode(int mode) {
    return (mode >= BUFFERING_MODE_NONE && mode < BUFFERING_MODE_COUNT);
}

// static
bool BufferingSettings::IsTimeBasedBufferingMode(int mode) {
    return (mode == BUFFERING_MODE_TIME_ONLY || mode == BUFFERING_MODE_TIME_THEN_SIZE);
}

// static
bool BufferingSettings::IsSizeBasedBufferingMode(int mode) {
    return (mode == BUFFERING_MODE_SIZE_ONLY || mode == BUFFERING_MODE_TIME_THEN_SIZE);
}

BufferingSettings::BufferingSettings()
        : mInitialBufferingMode(BUFFERING_MODE_NONE),
          mRebufferingMode(BUFFERING_MODE_NONE),
+81 −27
Original line number Diff line number Diff line
@@ -38,11 +38,12 @@

namespace android {

static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
static int64_t kHighWaterMarkUs = 5000000ll;  // 5secs
static int64_t kHighWaterMarkRebufferUs = 15000000ll;  // 15secs
static const ssize_t kLowWaterMarkBytes = 40000;
static const ssize_t kHighWaterMarkBytes = 200000;
static const int kLowWaterMarkMs          = 2000;  // 2secs
static const int kHighWaterMarkMs         = 5000;  // 5secs
static const int kHighWaterMarkRebufferMs = 15000;  // 15secs

static const int kLowWaterMarkKB  = 40;
static const int kHighWaterMarkKB = 200;

NuPlayer::GenericSource::GenericSource(
        const sp<AMessage> &notify,
@@ -241,6 +242,16 @@ status_t NuPlayer::GenericSource::initFromDataSource() {
    return OK;
}

status_t NuPlayer::GenericSource::getDefaultBufferingSettings(
        BufferingSettings* buffering /* nonnull */) {
    mBufferingMonitor->getDefaultBufferingSettings(buffering);
    return OK;
}

status_t NuPlayer::GenericSource::setBufferingSettings(const BufferingSettings& buffering) {
    return mBufferingMonitor->setBufferingSettings(buffering);
}

status_t NuPlayer::GenericSource::startSources() {
    // Start the selected A/V tracks now before we start buffering.
    // Widevine sources might re-initialize crypto when starting, if we delay
@@ -1451,11 +1462,48 @@ NuPlayer::GenericSource::BufferingMonitor::BufferingMonitor(const sp<AMessage> &
      mFirstDequeuedBufferRealUs(-1ll),
      mFirstDequeuedBufferMediaUs(-1ll),
      mlastDequeuedBufferMediaUs(-1ll) {
      getDefaultBufferingSettings(&mSettings);
}

NuPlayer::GenericSource::BufferingMonitor::~BufferingMonitor() {
}

void NuPlayer::GenericSource::BufferingMonitor::getDefaultBufferingSettings(
        BufferingSettings *buffering /* nonnull */) {
    buffering->mInitialBufferingMode = BUFFERING_MODE_TIME_ONLY;
    buffering->mRebufferingMode = BUFFERING_MODE_TIME_THEN_SIZE;
    buffering->mInitialWatermarkMs = kHighWaterMarkMs;
    buffering->mRebufferingWatermarkLowMs = kLowWaterMarkMs;
    buffering->mRebufferingWatermarkHighMs = kHighWaterMarkRebufferMs;
    buffering->mRebufferingWatermarkLowKB = kLowWaterMarkKB;
    buffering->mRebufferingWatermarkHighKB = kHighWaterMarkKB;
}

status_t NuPlayer::GenericSource::BufferingMonitor::setBufferingSettings(
        const BufferingSettings &buffering) {
    Mutex::Autolock _l(mLock);
    if (buffering.IsSizeBasedBufferingMode(buffering.mInitialBufferingMode)
            || (buffering.IsTimeBasedBufferingMode(buffering.mRebufferingMode)
                && buffering.mRebufferingWatermarkLowMs > buffering.mRebufferingWatermarkHighMs)
            || (buffering.IsSizeBasedBufferingMode(buffering.mRebufferingMode)
                && buffering.mRebufferingWatermarkLowKB > buffering.mRebufferingWatermarkHighKB)) {
        return BAD_VALUE;
    }
    mSettings = buffering;
    if (mSettings.mInitialBufferingMode == BUFFERING_MODE_NONE) {
        mSettings.mInitialWatermarkMs = BufferingSettings::kNoWatermark;
    }
    if (!mSettings.IsTimeBasedBufferingMode(mSettings.mRebufferingMode)) {
        mSettings.mRebufferingWatermarkLowMs = BufferingSettings::kNoWatermark;
        mSettings.mRebufferingWatermarkHighMs = INT32_MAX;
    }
    if (!mSettings.IsSizeBasedBufferingMode(mSettings.mRebufferingMode)) {
        mSettings.mRebufferingWatermarkLowKB = BufferingSettings::kNoWatermark;
        mSettings.mRebufferingWatermarkHighKB = INT32_MAX;
    }
    return OK;
}

void NuPlayer::GenericSource::BufferingMonitor::prepare(
        const sp<NuCachedSource2> &cachedSource,
        int64_t durationUs,
@@ -1684,7 +1732,9 @@ void NuPlayer::GenericSource::BufferingMonitor::onPollBuffering_l() {

        stopBufferingIfNecessary_l();
        return;
    } else if (cachedDurationUs >= 0ll) {
    }

    if (cachedDurationUs >= 0ll) {
        if (mDurationUs > 0ll) {
            int64_t cachedPosUs = getLastReadPosition_l() + cachedDurationUs;
            int percentage = 100.0 * cachedPosUs / mDurationUs;
@@ -1695,36 +1745,40 @@ void NuPlayer::GenericSource::BufferingMonitor::onPollBuffering_l() {
            notifyBufferingUpdate_l(percentage);
        }

        ALOGV("onPollBuffering_l: cachedDurationUs %.1f sec",
                cachedDurationUs / 1000000.0f);
        ALOGV("onPollBuffering_l: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);

        if (cachedDurationUs < kLowWaterMarkUs) {
        if (mPrepareBuffering) {
            if (cachedDurationUs > mSettings.mInitialWatermarkMs * 1000) {
                stopBufferingIfNecessary_l();
            }
        } else if (mSettings.IsTimeBasedBufferingMode(mSettings.mRebufferingMode)) {
            if (cachedDurationUs < mSettings.mRebufferingWatermarkLowMs * 1000) {
                // Take into account the data cached in downstream components to try to avoid
                // unnecessary pause.
                if (mOffloadAudio && mFirstDequeuedBufferRealUs >= 0) {
                int64_t downStreamCacheUs = mlastDequeuedBufferMediaUs - mFirstDequeuedBufferMediaUs
                    int64_t downStreamCacheUs =
                        mlastDequeuedBufferMediaUs - mFirstDequeuedBufferMediaUs
                            - (ALooper::GetNowUs() - mFirstDequeuedBufferRealUs);
                    if (downStreamCacheUs > 0) {
                        cachedDurationUs += downStreamCacheUs;
                    }
                }

            if (cachedDurationUs < kLowWaterMarkUs) {
                if (cachedDurationUs < mSettings.mRebufferingWatermarkLowMs * 1000) {
                    startBufferingIfNecessary_l();
                }
        } else {
            int64_t highWaterMark = mPrepareBuffering ? kHighWaterMarkUs : kHighWaterMarkRebufferUs;
            if (cachedDurationUs > highWaterMark) {
            } else if (cachedDurationUs > mSettings.mRebufferingWatermarkHighMs * 1000) {
                stopBufferingIfNecessary_l();
            }
        }
    } else if (cachedDataRemaining >= 0) {
    } else if (cachedDataRemaining >= 0
            && mSettings.IsSizeBasedBufferingMode(mSettings.mRebufferingMode)) {
        ALOGV("onPollBuffering_l: cachedDataRemaining %zd bytes",
                cachedDataRemaining);

        if (cachedDataRemaining < kLowWaterMarkBytes) {
        if (cachedDataRemaining < (mSettings.mRebufferingWatermarkLowKB << 10)) {
            startBufferingIfNecessary_l();
        } else if (cachedDataRemaining > kHighWaterMarkBytes) {
        } else if (cachedDataRemaining > (mSettings.mRebufferingWatermarkHighKB << 10)) {
            stopBufferingIfNecessary_l();
        }
    }
+8 −0
Original line number Diff line number Diff line
@@ -50,6 +50,10 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {

    status_t setDataSource(const sp<DataSource>& dataSource);

    virtual status_t getDefaultBufferingSettings(
            BufferingSettings* buffering /* nonnull */) override;
    virtual status_t setBufferingSettings(const BufferingSettings& buffering) override;

    virtual void prepareAsync();

    virtual void start();
@@ -119,6 +123,9 @@ private:
    public:
        explicit BufferingMonitor(const sp<AMessage> &notify);

        void getDefaultBufferingSettings(BufferingSettings *buffering /* nonnull */);
        status_t setBufferingSettings(const BufferingSettings &buffering);

        // Set up state.
        void prepare(const sp<NuCachedSource2> &cachedSource,
                int64_t durationUs,
@@ -167,6 +174,7 @@ private:

        mutable Mutex mLock;

        BufferingSettings mSettings;
        bool mOffloadAudio;
        int64_t mFirstDequeuedBufferRealUs;
        int64_t mFirstDequeuedBufferMediaUs;
Loading