Loading include/media/stagefright/NuMediaExtractor.h +11 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ namespace android { struct ABuffer; struct AMessage; struct DataSource; struct MediaBuffer; struct MediaExtractor; struct MediaSource; Loading Loading @@ -60,6 +61,8 @@ struct NuMediaExtractor : public RefBase { status_t getSampleTime(int64_t *sampleTimeUs); status_t getSampleMeta(sp<MetaData> *sampleMeta); bool getCachedDuration(int64_t *durationUs, bool *eos) const; protected: virtual ~NuMediaExtractor(); Loading @@ -78,13 +81,21 @@ private: uint32_t mTrackFlags; // bitmask of "TrackFlags" }; sp<DataSource> mDataSource; sp<MediaExtractor> mImpl; bool mIsWidevineExtractor; Vector<TrackInfo> mSelectedTracks; int64_t mTotalBitrate; // in bits/sec int64_t mDurationUs; ssize_t fetchTrackSamples(int64_t seekTimeUs = -1ll); void releaseTrackSamples(); bool getTotalBitrate(int64_t *bitRate) const; void updateDurationAndBitrate(); DISALLOW_EVIL_CONSTRUCTORS(NuMediaExtractor); }; Loading media/libstagefright/NuCachedSource2.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -501,12 +501,12 @@ size_t NuCachedSource2::cachedSize() { return mCacheOffset + mCache->totalSize(); } size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) { size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const { Mutex::Autolock autoLock(mLock); return approxDataRemaining_l(finalStatus); } size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) { size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const { *finalStatus = mFinalStatus; if (mFinalStatus != OK && mNumRetriesLeft > 0) { Loading media/libstagefright/NuMediaExtractor.cpp +85 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <media/stagefright/NuMediaExtractor.h> #include "include/ESDS.h" #include "include/NuCachedSource2.h" #include "include/WVMExtractor.h" #include <media/stagefright/foundation/ABuffer.h> Loading @@ -38,7 +39,10 @@ namespace android { NuMediaExtractor::NuMediaExtractor() { NuMediaExtractor::NuMediaExtractor() : mIsWidevineExtractor(false), mTotalBitrate(-1ll), mDurationUs(-1ll) { } NuMediaExtractor::~NuMediaExtractor() { Loading Loading @@ -66,6 +70,7 @@ status_t NuMediaExtractor::setDataSource( return -ENOENT; } mIsWidevineExtractor = false; if (!strncasecmp("widevine://", path, 11)) { String8 mimeType; float confidence; Loading @@ -82,6 +87,7 @@ status_t NuMediaExtractor::setDataSource( extractor->setAdaptiveStreamingMode(true); mImpl = extractor; mIsWidevineExtractor = true; } else { mImpl = MediaExtractor::Create(dataSource); } Loading @@ -90,6 +96,10 @@ status_t NuMediaExtractor::setDataSource( return ERROR_UNSUPPORTED; } mDataSource = dataSource; updateDurationAndBitrate(); return OK; } Loading @@ -111,9 +121,39 @@ status_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) { return ERROR_UNSUPPORTED; } mDataSource = fileSource; updateDurationAndBitrate(); return OK; } void NuMediaExtractor::updateDurationAndBitrate() { mTotalBitrate = 0ll; mDurationUs = -1ll; for (size_t i = 0; i < mImpl->countTracks(); ++i) { sp<MetaData> meta = mImpl->getTrackMetaData(i); int32_t bitrate; if (!meta->findInt32(kKeyBitRate, &bitrate)) { const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); ALOGV("track of type '%s' does not publish bitrate", mime); mTotalBitrate = -1ll; } else if (mTotalBitrate >= 0ll) { mTotalBitrate += bitrate; } int64_t durationUs; if (meta->findInt64(kKeyDuration, &durationUs) && durationUs > mDurationUs) { mDurationUs = durationUs; } } } size_t NuMediaExtractor::countTracks() const { return mImpl == NULL ? 0 : mImpl->countTracks(); } Loading Loading @@ -508,4 +548,48 @@ status_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) { return OK; } bool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const { if (mTotalBitrate >= 0) { *bitrate = mTotalBitrate; return true; } off64_t size; if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) { *bitrate = size * 8000000ll / mDurationUs; // in bits/sec return true; } return false; } // Returns true iff cached duration is available/applicable. bool NuMediaExtractor::getCachedDuration( int64_t *durationUs, bool *eos) const { int64_t bitrate; if (mIsWidevineExtractor) { sp<WVMExtractor> wvmExtractor = static_cast<WVMExtractor *>(mImpl.get()); status_t finalStatus; *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus); *eos = (finalStatus != OK); return true; } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource) && getTotalBitrate(&bitrate)) { sp<NuCachedSource2> cachedSource = static_cast<NuCachedSource2 *>(mDataSource.get()); status_t finalStatus; size_t cachedDataRemaining = cachedSource->approxDataRemaining(&finalStatus); *durationUs = cachedDataRemaining * 8000000ll / bitrate; *eos = (finalStatus != OK); return true; } return false; } } // namespace android media/libstagefright/include/NuCachedSource2.h +3 −3 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ struct NuCachedSource2 : public DataSource { //////////////////////////////////////////////////////////////////////////// size_t cachedSize(); size_t approxDataRemaining(status_t *finalStatus); size_t approxDataRemaining(status_t *finalStatus) const; void resumeFetchingIfNecessary(); Loading Loading @@ -94,7 +94,7 @@ private: sp<ALooper> mLooper; Mutex mSerializer; Mutex mLock; mutable Mutex mLock; Condition mCondition; PageCache *mCache; Loading Loading @@ -123,7 +123,7 @@ private: ssize_t readInternal(off64_t offset, void *data, size_t size); status_t seekInternal_l(off64_t offset); size_t approxDataRemaining_l(status_t *finalStatus); size_t approxDataRemaining_l(status_t *finalStatus) const; void restartPrefetcherIfNecessary_l( bool ignoreLowWaterThreshold = false, bool force = false); Loading Loading
include/media/stagefright/NuMediaExtractor.h +11 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ namespace android { struct ABuffer; struct AMessage; struct DataSource; struct MediaBuffer; struct MediaExtractor; struct MediaSource; Loading Loading @@ -60,6 +61,8 @@ struct NuMediaExtractor : public RefBase { status_t getSampleTime(int64_t *sampleTimeUs); status_t getSampleMeta(sp<MetaData> *sampleMeta); bool getCachedDuration(int64_t *durationUs, bool *eos) const; protected: virtual ~NuMediaExtractor(); Loading @@ -78,13 +81,21 @@ private: uint32_t mTrackFlags; // bitmask of "TrackFlags" }; sp<DataSource> mDataSource; sp<MediaExtractor> mImpl; bool mIsWidevineExtractor; Vector<TrackInfo> mSelectedTracks; int64_t mTotalBitrate; // in bits/sec int64_t mDurationUs; ssize_t fetchTrackSamples(int64_t seekTimeUs = -1ll); void releaseTrackSamples(); bool getTotalBitrate(int64_t *bitRate) const; void updateDurationAndBitrate(); DISALLOW_EVIL_CONSTRUCTORS(NuMediaExtractor); }; Loading
media/libstagefright/NuCachedSource2.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -501,12 +501,12 @@ size_t NuCachedSource2::cachedSize() { return mCacheOffset + mCache->totalSize(); } size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) { size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) const { Mutex::Autolock autoLock(mLock); return approxDataRemaining_l(finalStatus); } size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) { size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) const { *finalStatus = mFinalStatus; if (mFinalStatus != OK && mNumRetriesLeft > 0) { Loading
media/libstagefright/NuMediaExtractor.cpp +85 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <media/stagefright/NuMediaExtractor.h> #include "include/ESDS.h" #include "include/NuCachedSource2.h" #include "include/WVMExtractor.h" #include <media/stagefright/foundation/ABuffer.h> Loading @@ -38,7 +39,10 @@ namespace android { NuMediaExtractor::NuMediaExtractor() { NuMediaExtractor::NuMediaExtractor() : mIsWidevineExtractor(false), mTotalBitrate(-1ll), mDurationUs(-1ll) { } NuMediaExtractor::~NuMediaExtractor() { Loading Loading @@ -66,6 +70,7 @@ status_t NuMediaExtractor::setDataSource( return -ENOENT; } mIsWidevineExtractor = false; if (!strncasecmp("widevine://", path, 11)) { String8 mimeType; float confidence; Loading @@ -82,6 +87,7 @@ status_t NuMediaExtractor::setDataSource( extractor->setAdaptiveStreamingMode(true); mImpl = extractor; mIsWidevineExtractor = true; } else { mImpl = MediaExtractor::Create(dataSource); } Loading @@ -90,6 +96,10 @@ status_t NuMediaExtractor::setDataSource( return ERROR_UNSUPPORTED; } mDataSource = dataSource; updateDurationAndBitrate(); return OK; } Loading @@ -111,9 +121,39 @@ status_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) { return ERROR_UNSUPPORTED; } mDataSource = fileSource; updateDurationAndBitrate(); return OK; } void NuMediaExtractor::updateDurationAndBitrate() { mTotalBitrate = 0ll; mDurationUs = -1ll; for (size_t i = 0; i < mImpl->countTracks(); ++i) { sp<MetaData> meta = mImpl->getTrackMetaData(i); int32_t bitrate; if (!meta->findInt32(kKeyBitRate, &bitrate)) { const char *mime; CHECK(meta->findCString(kKeyMIMEType, &mime)); ALOGV("track of type '%s' does not publish bitrate", mime); mTotalBitrate = -1ll; } else if (mTotalBitrate >= 0ll) { mTotalBitrate += bitrate; } int64_t durationUs; if (meta->findInt64(kKeyDuration, &durationUs) && durationUs > mDurationUs) { mDurationUs = durationUs; } } } size_t NuMediaExtractor::countTracks() const { return mImpl == NULL ? 0 : mImpl->countTracks(); } Loading Loading @@ -508,4 +548,48 @@ status_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) { return OK; } bool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const { if (mTotalBitrate >= 0) { *bitrate = mTotalBitrate; return true; } off64_t size; if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) { *bitrate = size * 8000000ll / mDurationUs; // in bits/sec return true; } return false; } // Returns true iff cached duration is available/applicable. bool NuMediaExtractor::getCachedDuration( int64_t *durationUs, bool *eos) const { int64_t bitrate; if (mIsWidevineExtractor) { sp<WVMExtractor> wvmExtractor = static_cast<WVMExtractor *>(mImpl.get()); status_t finalStatus; *durationUs = wvmExtractor->getCachedDurationUs(&finalStatus); *eos = (finalStatus != OK); return true; } else if ((mDataSource->flags() & DataSource::kIsCachingDataSource) && getTotalBitrate(&bitrate)) { sp<NuCachedSource2> cachedSource = static_cast<NuCachedSource2 *>(mDataSource.get()); status_t finalStatus; size_t cachedDataRemaining = cachedSource->approxDataRemaining(&finalStatus); *durationUs = cachedDataRemaining * 8000000ll / bitrate; *eos = (finalStatus != OK); return true; } return false; } } // namespace android
media/libstagefright/include/NuCachedSource2.h +3 −3 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ struct NuCachedSource2 : public DataSource { //////////////////////////////////////////////////////////////////////////// size_t cachedSize(); size_t approxDataRemaining(status_t *finalStatus); size_t approxDataRemaining(status_t *finalStatus) const; void resumeFetchingIfNecessary(); Loading Loading @@ -94,7 +94,7 @@ private: sp<ALooper> mLooper; Mutex mSerializer; Mutex mLock; mutable Mutex mLock; Condition mCondition; PageCache *mCache; Loading Loading @@ -123,7 +123,7 @@ private: ssize_t readInternal(off64_t offset, void *data, size_t size); status_t seekInternal_l(off64_t offset); size_t approxDataRemaining_l(status_t *finalStatus); size_t approxDataRemaining_l(status_t *finalStatus) const; void restartPrefetcherIfNecessary_l( bool ignoreLowWaterThreshold = false, bool force = false); Loading