From 0b7d0f3fe37d83d798727503a902146f33911a9f Mon Sep 17 00:00:00 2001 From: Fred Gylys-Colwell Date: Wed, 23 May 2012 14:33:04 -0700 Subject: [PATCH] Fix pause at end of movie. The function WVMExtractorImpl::getCachedDurationUs returns the cached buffer size in microseconds, and sets a status to ERROR_END_OF_STREAM at the end of the movie. The AwesomePlayer will pause if the cache is too small and the status is not EOS. In bug 6277231, the player would pause just before the EOS marker would have been seen by the Widevine library. This change checks the current play time against the total movie duration. If there is less than 10 seconds left in the movie, the EOS flag is set. related-to-bug: 6277231 Change-Id: I8dbf60c82c41df485185f85e72452aab0a6a9686 --- proprietary/wvm/WVMExtractorImpl.cpp | 32 +++++++++++++++++----- proprietary/wvm/WVMMediaSource.cpp | 10 +++---- proprietary/wvm/include/WVMExtractorImpl.h | 2 ++ proprietary/wvm/include/WVMMediaSource.h | 3 ++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/proprietary/wvm/WVMExtractorImpl.cpp b/proprietary/wvm/WVMExtractorImpl.cpp index 98bc3a72..b1f4a2f0 100644 --- a/proprietary/wvm/WVMExtractorImpl.cpp +++ b/proprietary/wvm/WVMExtractorImpl.cpp @@ -98,6 +98,7 @@ WVMExtractorImpl::WVMExtractorImpl(sp dataSource) mUseAdaptiveStreaming(false), mIsLiveStream(false), mSession(NULL), + mDuration(0), mSetupStatus(OK) { dataSource->getDrmInfo(sDecryptHandle, &sDrmManagerClient); @@ -272,13 +273,13 @@ status_t WVMExtractorImpl::readMetaData() return ERROR_MALFORMED; } - int64_t duration = (int64_t)(strtod(durationString.c_str(), NULL) * 1000000); + mDuration = (int64_t)(strtod(durationString.c_str(), NULL) * 1000000); sp audioMetaData = new MetaData(); sp videoMetaData = new MetaData(); - audioMetaData->setInt64(kKeyDuration, duration); - videoMetaData->setInt64(kKeyDuration, duration); + audioMetaData->setInt64(kKeyDuration, mDuration); + videoMetaData->setInt64(kKeyDuration, mDuration); audioMetaData->setInt32(kKeyBitRate, audioBitRate); videoMetaData->setInt32(kKeyBitRate, videoBitRate); @@ -505,11 +506,28 @@ int64_t WVMExtractorImpl::getCachedDurationUs(status_t *finalStatus) { } else if (status != WV_Status_OK) { *finalStatus = ERROR_IO; } else { - if (mIsLiveStream) - *finalStatus = ERROR_END_OF_STREAM; - else - *finalStatus = OK; durationUs = (uint64_t)(secondsBuffered * 1000000LL); + + if (mIsLiveStream) { + *finalStatus = ERROR_END_OF_STREAM; + } else { + *finalStatus = OK; + int64_t current_time = 0; // usec. + if (mVideoSource != NULL) { + current_time = mVideoSource->getTime(); + } else { + ALOGV("getCachedDurationUs: current_time not yet valid."); + } + + // ALOGD("current_time=%.2f, duration %.2f, delta = %.2f, buffered=%.2f", + // current_time/1e6, mDuration/1e6, + // (mDuration - current_time )/1e6, time_buffered); + + // If we are less than 10 seconds from end, report we are at the end. + if (mDuration > 0 && mDuration - current_time < 10000000) { + *finalStatus = ERROR_END_OF_STREAM; + } + } } // Scale the duration to account for Stagefright's conservative buffering. diff --git a/proprietary/wvm/WVMMediaSource.cpp b/proprietary/wvm/WVMMediaSource.cpp index 47fa6a11..2c3ae2c2 100644 --- a/proprietary/wvm/WVMMediaSource.cpp +++ b/proprietary/wvm/WVMMediaSource.cpp @@ -36,6 +36,7 @@ WVMMediaSource::WVMMediaSource(WVSession *session, WVEsSelector esSelector, mNewSegment(false), mCryptoInitialized(false), mGroup(NULL), + mKeyTime(0), mDts(0), mPts(0) { @@ -263,7 +264,6 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) size_t bytesRead; bool auStart; size_t offset = 0; - int64_t keyTime; bool syncFrame; int retryCount = 0; @@ -338,9 +338,9 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) } #define PCR_HZ 90000 - keyTime = (int64_t)mPts * 1000000 / PCR_HZ; + mKeyTime = (int64_t)mPts * 1000000 / PCR_HZ; - if (seekNextSync && ((keyTime < seekTimeUs) || !syncFrame)) { + if (seekNextSync && ((mKeyTime < seekTimeUs) || !syncFrame)) { // drop frames up to next sync if requested usleep(10000); #ifdef REQUIRE_SECURE_BUFFERS @@ -380,7 +380,7 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) } mediaBuf->meta_data()->clear(); - mediaBuf->meta_data()->setInt64(kKeyTime, keyTime); + mediaBuf->meta_data()->setInt64(kKeyTime, mKeyTime); mediaBuf->set_range(0, bytesRead + offset); @@ -414,7 +414,7 @@ status_t WVMMediaSource::read(MediaBuffer **buffer, const ReadOptions *options) #if 0 ALOGD("[%p] %s packet length=%d kKeyTime=%lld %s\n", mediaBuf, (mESSelector == WV_EsSelector_Video ? "video" : "audio"), - bytesRead + offset, keyTime, syncFrame ? "sync" : ""); + bytesRead + offset, mKeyTime, syncFrame ? "sync" : ""); #endif *buffer = mediaBuf; diff --git a/proprietary/wvm/include/WVMExtractorImpl.h b/proprietary/wvm/include/WVMExtractorImpl.h index 531b1d53..7a48e1e0 100644 --- a/proprietary/wvm/include/WVMExtractorImpl.h +++ b/proprietary/wvm/include/WVMExtractorImpl.h @@ -74,6 +74,8 @@ private: WVSession *mSession; + int64_t mDuration; // usec. + status_t mSetupStatus; status_t readMetaData(); diff --git a/proprietary/wvm/include/WVMMediaSource.h b/proprietary/wvm/include/WVMMediaSource.h index 3170e2cc..57d4b287 100644 --- a/proprietary/wvm/include/WVMMediaSource.h +++ b/proprietary/wvm/include/WVMMediaSource.h @@ -44,6 +44,8 @@ public: static int sLastError; + int64_t getTime() { return mKeyTime; }; // usec. + #ifdef REQUIRE_SECURE_BUFFERS class DecryptContext { public: @@ -84,6 +86,7 @@ private: MediaBufferGroup *mGroup; + int64_t mKeyTime; unsigned long long mDts; unsigned long long mPts;