From 54993c50e945b3bef1b3d2aadf36d20c4f308c4c Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Mon, 1 Oct 2012 13:08:11 -0700 Subject: [PATCH] [WVDRM] Fix for stuttering on low bandwidth Reintroduces the play/pause rebuffering logic we eliminated in JB zero day to fix double spins and slow startup - but activates that logic only based on a comparison of the current bandwidth measurement and the lowest bitrate track in the movie. Needs to be submitted with related changes in /frameworks/av bug: 7230071 Change-Id: Ib3859a961bd3901a9c4df01eeab2b8b75f49aefe --- proprietary/wvm/WVMExtractorImpl.cpp | 31 ++++++++++++++++++------ proprietary/wvm/WVMMediaSource.cpp | 8 ------ proprietary/wvm/include/WVMMediaSource.h | 2 -- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/proprietary/wvm/WVMExtractorImpl.cpp b/proprietary/wvm/WVMExtractorImpl.cpp index 3670ed0b..c8aae5fd 100644 --- a/proprietary/wvm/WVMExtractorImpl.cpp +++ b/proprietary/wvm/WVMExtractorImpl.cpp @@ -524,19 +524,26 @@ int64_t WVMExtractorImpl::getCachedDurationUs(status_t *finalStatus) { const size_t kMaxEncodedRates = 32; unsigned long encodedRates[kMaxEncodedRates]; size_t ratesReturned, currentTrack; + unsigned long minRate = ULONG_MAX; + unsigned long bandwidth = ULONG_MAX; WVStatus status = WV_Info_GetAdaptiveBitrates(mSession, encodedRates, kMaxEncodedRates, &ratesReturned, ¤tTrack); if (status == WV_Status_OK) { if (currentTrack != kMaxEncodedRates && ratesReturned != 0) { + for (size_t i = 0; i < ratesReturned; i++) { + if (encodedRates[i] < minRate) { + minRate = encodedRates[i]; + } + } + + WV_Info_CurrentBandwidth(mSession, &bandwidth); + // Log the current adaptive rate every 5 seconds time_t now = time(0); static time_t lastLogTime = now; if (now > lastLogTime + 5) { lastLogTime = now; - unsigned long bandwidth = -1; - WV_Info_CurrentBandwidth(mSession, &bandwidth); - ALOGI("using adaptive track #%d, rate=%ld, bandwidth=%ld\n", currentTrack, encodedRates[currentTrack], bandwidth); } @@ -544,12 +551,22 @@ int64_t WVMExtractorImpl::getCachedDurationUs(status_t *finalStatus) { } uint64_t durationUs = 0; + float secondsBuffered; + status = WV_Info_TimeBuffered(mSession, &secondsBuffered); - if (!mVideoSource->isStalled() && !mAudioSource->isStalled()) { - // Data is buffered as long as the pull isn't stalled. - // The amount indicated doesn't matter as long as it - // is more than the high water mark. + // + // As long as the bandwidth is greater than the min bitrate, don't + // need to consider rebuffering so return a buffered time greater + // than the low water mark. This provides fast startup when the + // network speed is good and rebuffering when it is not. + // + if (bandwidth != ULONG_MAX && minRate != ULONG_MAX && bandwidth >= minRate) { + //ALOGD("Bandwidth %ld is sufficient for lowest rate %ld, override buffered time", bandwidth, minRate); durationUs = 10000000LL; + } else { + unsigned long kScaleFactor = 2; // scale to cached duration to tune watermark levels + durationUs = (uint64_t)(secondsBuffered * 1000000LL * kScaleFactor); + //ALOGD("Bandwidth %ld is too low for lowest rate %ld, use buffered time %lld", bandwidth, minRate, durationUs); } if (status == WV_Status_End_Of_Media) { diff --git a/proprietary/wvm/WVMMediaSource.cpp b/proprietary/wvm/WVMMediaSource.cpp index 434de1f6..3715c9cd 100644 --- a/proprietary/wvm/WVMMediaSource.cpp +++ b/proprietary/wvm/WVMMediaSource.cpp @@ -37,7 +37,6 @@ WVMMediaSource::WVMMediaSource(WVSession *session, WVEsSelector esSelector, mIsLiveStream(isLive), mNewSegment(false), mCryptoInitialized(false), - mIsStalled(false), mStripADTS(false), mGroup(NULL), mKeyTime(0), @@ -214,8 +213,6 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) { Mutex::Autolock autoLock(mLock); - mIsStalled = false; - CHECK(mStarted); *buffer = NULL; @@ -351,8 +348,6 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) return ERROR_IO; } else { // Didn't get anything, sleep a bit so we don't hog the CPU then try again - if (retryCount > 10) - mIsStalled = true; usleep(10000); continue; } @@ -364,15 +359,12 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) if (seekNextSync && ((mKeyTime < seekTimeUs) || !syncFrame)) { // drop frames up to next sync if requested - mIsStalled = true; usleep(10000); mDecryptContext.Initialize(mediaBuf); mEncryptedSizes.clear(); continue; } - mIsStalled = false; - if (offset + bytesRead < mediaBuf->size()) break; diff --git a/proprietary/wvm/include/WVMMediaSource.h b/proprietary/wvm/include/WVMMediaSource.h index 44305b36..66b2f242 100644 --- a/proprietary/wvm/include/WVMMediaSource.h +++ b/proprietary/wvm/include/WVMMediaSource.h @@ -41,7 +41,6 @@ public: virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL); void addEncryptedSize(size_t size) { mEncryptedSizes.push_back(size); } - bool isStalled() const { return mIsStalled; } static int sLastError; @@ -87,7 +86,6 @@ private: bool mIsLiveStream; bool mNewSegment; bool mCryptoInitialized; - bool mIsStalled; bool mStripADTS; MediaBufferGroup *mGroup;