diff options
author | Chong Zhang <chz@google.com> | 2014-08-21 17:48:26 -0700 |
---|---|---|
committer | Chong Zhang <chz@google.com> | 2014-08-22 12:21:00 -0700 |
commit | 2a3cc9a64330dd36e466fe5e1b634146f2d641c1 (patch) | |
tree | 39ca1aa496287a49bd09cc4a8f7ac283cb974eb7 /media | |
parent | d354d8d1b09503c0166c1f3e626cda72a3eeb83c (diff) | |
download | frameworks_av-2a3cc9a64330dd36e466fe5e1b634146f2d641c1.zip frameworks_av-2a3cc9a64330dd36e466fe5e1b634146f2d641c1.tar.gz frameworks_av-2a3cc9a64330dd36e466fe5e1b634146f2d641c1.tar.bz2 |
add buffering update to GenericSource
Bug: 17182378
Change-Id: Ib86f3f522d7ea635489edd2b512adb7f4b27e381
Diffstat (limited to 'media')
4 files changed, 112 insertions, 6 deletions
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index 3706117..cdb7e69 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -49,7 +49,9 @@ NuPlayer::GenericSource::GenericSource( mIsWidevine(false), mUIDValid(uidValid), mUID(uid), - mMetaDataSize(-1ll) { + mMetaDataSize(-1ll), + mBitrate(-1ll), + mPollBufferingGeneration(0) { resetDataSource(); DataSource::RegisterDefaultSniffers(); } @@ -113,12 +115,12 @@ status_t NuPlayer::GenericSource::initFromDataSource() { return UNKNOWN_ERROR; } - sp<WVMExtractor> wvmExtractor = new WVMExtractor(mDataSource); - wvmExtractor->setAdaptiveStreamingMode(true); + mWVMExtractor = new WVMExtractor(mDataSource); + mWVMExtractor->setAdaptiveStreamingMode(true); if (mUIDValid) { - wvmExtractor->setUID(mUID); + mWVMExtractor->setUID(mUID); } - extractor = wvmExtractor; + extractor = mWVMExtractor; } else { extractor = MediaExtractor::Create(mDataSource, mSniffedMIME.empty() ? NULL: mSniffedMIME.c_str()); @@ -136,6 +138,8 @@ status_t NuPlayer::GenericSource::initFromDataSource() { } } + int32_t totalBitrate = 0; + for (size_t i = 0; i < extractor->countTracks(); ++i) { sp<MetaData> meta = extractor->getTrackMetaData(i); @@ -180,9 +184,18 @@ status_t NuPlayer::GenericSource::initFromDataSource() { mDurationUs = durationUs; } } + + int32_t bitrate; + if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) { + totalBitrate += bitrate; + } else { + totalBitrate = -1; + } } } + mBitrate = totalBitrate; + return OK; } @@ -239,6 +252,10 @@ void NuPlayer::GenericSource::onPrepareAsync() { if (mDataSource->flags() & DataSource::kIsCachingDataSource) { mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get()); } + + if (mIsWidevine || mCachedSource != NULL) { + schedulePollBuffering(); + } } // check initial caching status @@ -283,6 +300,8 @@ void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) { mSniffedMIME = ""; mDataSource.clear(); mCachedSource.clear(); + + cancelPollBuffering(); } notifyPrepared(err); } @@ -381,6 +400,65 @@ status_t NuPlayer::GenericSource::feedMoreTSData() { return OK; } +void NuPlayer::GenericSource::schedulePollBuffering() { + sp<AMessage> msg = new AMessage(kWhatPollBuffering, id()); + msg->setInt32("generation", mPollBufferingGeneration); + msg->post(1000000ll); +} + +void NuPlayer::GenericSource::cancelPollBuffering() { + ++mPollBufferingGeneration; +} + +void NuPlayer::GenericSource::notifyBufferingUpdate(int percentage) { + sp<AMessage> msg = dupNotify(); + msg->setInt32("what", kWhatBufferingUpdate); + msg->setInt32("percentage", percentage); + msg->post(); +} + +void NuPlayer::GenericSource::onPollBuffering() { + status_t finalStatus = UNKNOWN_ERROR; + int64_t cachedDurationUs = 0ll; + + if (mCachedSource != NULL) { + size_t cachedDataRemaining = + mCachedSource->approxDataRemaining(&finalStatus); + + if (finalStatus == OK) { + off64_t size; + int64_t bitrate = 0ll; + if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) { + bitrate = size * 8000000ll / mDurationUs; + } else if (mBitrate > 0) { + bitrate = mBitrate; + } + if (bitrate > 0) { + cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate; + } + } + } else if (mWVMExtractor != NULL) { + cachedDurationUs + = mWVMExtractor->getCachedDurationUs(&finalStatus); + } + + if (finalStatus == ERROR_END_OF_STREAM) { + notifyBufferingUpdate(100); + cancelPollBuffering(); + return; + } else if (cachedDurationUs > 0ll && mDurationUs > 0ll) { + int percentage = 100.0 * cachedDurationUs / mDurationUs; + if (percentage > 100) { + percentage = 100; + } + + notifyBufferingUpdate(percentage); + } + + schedulePollBuffering(); +} + + void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatPrepareAsync: @@ -463,7 +541,15 @@ void NuPlayer::GenericSource::onMessageReceived(const sp<AMessage> &msg) { break; } - + case kWhatPollBuffering: + { + int32_t generation; + CHECK(msg->findInt32("generation", &generation)); + if (generation == mPollBufferingGeneration) { + onPollBuffering(); + } + break; + } default: Source::onMessageReceived(msg); break; diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h index 946307c..663bfae 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.h +++ b/media/libmediaplayerservice/nuplayer/GenericSource.h @@ -34,6 +34,7 @@ struct IMediaHTTPService; struct MediaSource; class MediaBuffer; struct NuCachedSource2; +struct WVMExtractor; struct NuPlayer::GenericSource : public NuPlayer::Source { GenericSource(const sp<AMessage> ¬ify, bool uidValid, uid_t uid); @@ -77,6 +78,7 @@ private: kWhatSendSubtitleData, kWhatSendTimedTextData, kWhatChangeAVSource, + kWhatPollBuffering, }; Vector<sp<MediaSource> > mSources; @@ -108,9 +110,12 @@ private: sp<DataSource> mDataSource; sp<NuCachedSource2> mCachedSource; + sp<WVMExtractor> mWVMExtractor; String8 mContentType; AString mSniffedMIME; off64_t mMetaDataSize; + int64_t mBitrate; + int32_t mPollBufferingGeneration; sp<ALooper> mLooper; @@ -141,6 +146,11 @@ private: media_track_type trackType, int64_t seekTimeUs = -1ll, int64_t *actualTimeUs = NULL, bool formatChange = false); + void schedulePollBuffering(); + void cancelPollBuffering(); + void onPollBuffering(); + void notifyBufferingUpdate(int percentage); + DISALLOW_EVIL_CONSTRUCTORS(GenericSource); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 0a9b65c..60f0b8c 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1797,6 +1797,15 @@ void NuPlayer::onSourceNotify(const sp<AMessage> &msg) { break; } + case Source::kWhatBufferingUpdate: + { + int32_t percentage; + CHECK(msg->findInt32("percentage", &percentage)); + + notifyListener(MEDIA_BUFFERING_UPDATE, percentage, 0); + break; + } + case Source::kWhatBufferingStart: { notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0); diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h index 74892b6..45657c2 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h @@ -45,6 +45,7 @@ struct NuPlayer::Source : public AHandler { kWhatPrepared, kWhatFlagsChanged, kWhatVideoSizeChanged, + kWhatBufferingUpdate, kWhatBufferingStart, kWhatBufferingEnd, kWhatSubtitleData, |