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

Commit a53d87c7 authored by Andreas Huber's avatar Andreas Huber
Browse files

Add the ability to query the amount of cached data to NuMediaExtractor.

Change-Id: I0966270a2bd36698330beaa03f47d02fc6a40c44
related-to-bug: 6364341
parent 8d608678
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ namespace android {

struct ABuffer;
struct AMessage;
struct DataSource;
struct MediaBuffer;
struct MediaExtractor;
struct MediaSource;
@@ -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();

@@ -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);
};

+2 −2
Original line number Diff line number Diff line
@@ -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) {
+85 −1
Original line number Diff line number Diff line
@@ -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>
@@ -38,7 +39,10 @@

namespace android {

NuMediaExtractor::NuMediaExtractor() {
NuMediaExtractor::NuMediaExtractor()
    : mIsWidevineExtractor(false),
      mTotalBitrate(-1ll),
      mDurationUs(-1ll) {
}

NuMediaExtractor::~NuMediaExtractor() {
@@ -66,6 +70,7 @@ status_t NuMediaExtractor::setDataSource(
        return -ENOENT;
    }

    mIsWidevineExtractor = false;
    if (!strncasecmp("widevine://", path, 11)) {
        String8 mimeType;
        float confidence;
@@ -82,6 +87,7 @@ status_t NuMediaExtractor::setDataSource(
        extractor->setAdaptiveStreamingMode(true);

        mImpl = extractor;
        mIsWidevineExtractor = true;
    } else {
        mImpl = MediaExtractor::Create(dataSource);
    }
@@ -90,6 +96,10 @@ status_t NuMediaExtractor::setDataSource(
        return ERROR_UNSUPPORTED;
    }

    mDataSource = dataSource;

    updateDurationAndBitrate();

    return OK;
}

@@ -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();
}
@@ -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
+3 −3
Original line number Diff line number Diff line
@@ -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();

@@ -94,7 +94,7 @@ private:
    sp<ALooper> mLooper;

    Mutex mSerializer;
    Mutex mLock;
    mutable Mutex mLock;
    Condition mCondition;

    PageCache *mCache;
@@ -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);