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

Commit 49fb89d3 authored by Robert Shih's avatar Robert Shih
Browse files

nuplayer2: remove NuCachedSource2 reference from GenericSource

Bug: 63934228
Change-Id: I6862ca94327df88dddd7afaa125622c64d61516b
parent cab10da0
Loading
Loading
Loading
Loading
+7 −25
Original line number Diff line number Diff line
@@ -1244,37 +1244,15 @@ sp<AMediaCodecCryptoInfoWrapper> AMediaExtractorWrapper::getSampleCryptoInfo() {
    return new AMediaCodecCryptoInfoWrapper(AMediaExtractor_getSampleCryptoInfo(mAMediaExtractor));
}

ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_getSize(void *userdata) {
    DataSource *source = static_cast<DataSource *>(userdata);
    off64_t size = -1;
    source->getSize(&size);
    return size;
}

ssize_t AMediaDataSourceWrapper::AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size) {
    DataSource *source = static_cast<DataSource *>(userdata);
    return source->readAt(offset, buf, size);
}

void AMediaDataSourceWrapper::AMediaDataSourceWrapper_close(void *userdata) {
    DataSource *source = static_cast<DataSource *>(userdata);
    source->close();
}

AMediaDataSourceWrapper::AMediaDataSourceWrapper(const sp<DataSource> &dataSource)
    : mDataSource(dataSource),
      mAMediaDataSource(AMediaDataSource_new()) {
    ALOGV("setDataSource (source: %p)", dataSource.get());
    AMediaDataSource_setUserdata(mAMediaDataSource, dataSource.get());
    AMediaDataSource_setReadAt(mAMediaDataSource, AMediaDataSourceWrapper_readAt);
    AMediaDataSource_setGetSize(mAMediaDataSource, AMediaDataSourceWrapper_getSize);
    AMediaDataSource_setClose(mAMediaDataSource, AMediaDataSourceWrapper_close);
AMediaDataSourceWrapper::AMediaDataSourceWrapper(AMediaDataSource *aDataSource)
    : mAMediaDataSource(aDataSource) {
}

AMediaDataSourceWrapper::~AMediaDataSourceWrapper() {
    if (mAMediaDataSource == NULL) {
        return;
    }
    AMediaDataSource_close(mAMediaDataSource);
    AMediaDataSource_delete(mAMediaDataSource);
    mAMediaDataSource = NULL;
}
@@ -1283,4 +1261,8 @@ AMediaDataSource* AMediaDataSourceWrapper::getAMediaDataSource() {
    return mAMediaDataSource;
}

void AMediaDataSourceWrapper::close() {
    AMediaDataSource_close(mAMediaDataSource);
}

}  // namespace android
+24 −25
Original line number Diff line number Diff line
@@ -278,6 +278,30 @@ private:
    DISALLOW_EVIL_CONSTRUCTORS(AMediaCodecWrapper);
};

struct AMediaDataSourceWrapper : public RefBase {

    AMediaDataSourceWrapper(AMediaDataSource*);
    AMediaDataSourceWrapper(int fd, int64_t offset, int64_t length);

    AMediaDataSource *getAMediaDataSource();
    int getFd() { return mFd; }
    int64_t getOffset() { return mOffset; }
    int64_t getLength() { return mLength; }

    void close();

protected:
    virtual ~AMediaDataSourceWrapper();

private:
    AMediaDataSource *mAMediaDataSource;
    int mFd;
    int64_t mOffset;
    int64_t mLength;

    DISALLOW_EVIL_CONSTRUCTORS(AMediaDataSourceWrapper);
};

struct AMediaExtractorWrapper : public RefBase {

    AMediaExtractorWrapper(AMediaExtractor *aMediaExtractor);
@@ -337,31 +361,6 @@ private:
    DISALLOW_EVIL_CONSTRUCTORS(AMediaExtractorWrapper);
};

struct AMediaDataSourceWrapper : public RefBase {

    static status_t translate_error(media_status_t err);

    static ssize_t AMediaDataSourceWrapper_getSize(void *userdata);

    static ssize_t AMediaDataSourceWrapper_readAt(void *userdata, off64_t offset, void * buf, size_t size);

    static void AMediaDataSourceWrapper_close(void *userdata);

    AMediaDataSourceWrapper(const sp<DataSource> &dataSource);

    AMediaDataSource *getAMediaDataSource();

protected:
    virtual ~AMediaDataSourceWrapper();

private:
    sp<DataSource> mDataSource;

    AMediaDataSource *mAMediaDataSource;

    DISALLOW_EVIL_CONSTRUCTORS(AMediaDataSourceWrapper);
};

}  // namespace android

#endif  // NDK_WRAPPER_H_
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ cc_library_static {
        "libcrypto",
        "libmediametrics",
        "libmediandk",
        "libmediandk_utils",
        "libmediautils",
        "libmemunreachable",
        "libnativewindow",
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ cc_library_static {
        "frameworks/av/media/libstagefright/mpeg2ts",
        "frameworks/av/media/libstagefright/rtsp",
        "frameworks/av/media/libstagefright/timedtext",
        "frameworks/av/media/ndk",
    ],

    cflags: [
@@ -49,6 +50,7 @@ cc_library_static {
        "libgui",
        "libmedia",
        "libmediandk",
        "libmediandk_utils",
        "libpowermanager",
    ],

+56 −144
Original line number Diff line number Diff line
@@ -21,29 +21,20 @@
#include "NuPlayer2Drm.h"

#include "AnotherPacketSource.h"
#include <binder/IServiceManager.h>
#include <cutils/properties.h>
#include <media/DataSource.h>
#include <media/MediaBufferHolder.h>
#include <media/IMediaExtractorService.h>
#include <media/IMediaSource.h>
#include <media/MediaHTTPService.h>
#include <media/MediaSource.h>
#include <media/NdkWrapper.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/ClearDataSourceFactory.h>
#include <media/stagefright/InterfaceUtils.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaClock.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractorFactory.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/NdkUtils.h>
#include <media/stagefright/Utils.h>
#include "../../libstagefright/include/NuCachedSource2.h"
#include "../../libstagefright/include/HTTPBase.h"
#include "NdkMediaDataSourceCallbacksPriv.h"

namespace android {

@@ -88,9 +79,6 @@ NuPlayer2::GenericSource2::GenericSource2(
void NuPlayer2::GenericSource2::resetDataSource() {
    ALOGV("resetDataSource");

    mHTTPService.clear();
    mHttpSource.clear();
    mDisconnected = false;
    mUri.clear();
    mUriHeaders.clear();
    if (mFd >= 0) {
@@ -109,7 +97,6 @@ void NuPlayer2::GenericSource2::resetDataSource() {
}

status_t NuPlayer2::GenericSource2::setDataSource(
        const sp<MediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers) {
    Mutex::Autolock _l(mLock);
@@ -117,7 +104,6 @@ status_t NuPlayer2::GenericSource2::setDataSource(

    resetDataSource();

    mHTTPService = httpService;
    mUri = url;

    if (headers) {
@@ -150,7 +136,8 @@ status_t NuPlayer2::GenericSource2::setDataSource(const sp<DataSource>& source)
    ALOGV("setDataSource (source: %p)", source.get());

    resetDataSource();
    mDataSource = source;
    AMediaDataSource *aSource = convertDataSourceToAMediaDataSource(source);
    mDataSourceWrapper = new AMediaDataSourceWrapper(aSource);
    return OK;
}

@@ -161,24 +148,21 @@ sp<MetaData> NuPlayer2::GenericSource2::getFileFormatMeta() const {

status_t NuPlayer2::GenericSource2::initFromDataSource() {
    mExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
    CHECK(mDataSource != NULL || mFd != -1);
    sp<DataSource> dataSource = mDataSource;
    CHECK(mFd >=0 || mDataSourceWrapper != NULL);
    sp<AMediaDataSourceWrapper> aSourceWrapper = mDataSourceWrapper;
    const int fd = mFd;
    const int64_t offset = mOffset;
    const int64_t length = mLength;

    mLock.unlock();
    // This might take long time if data source is not reliable.
    status_t err;
    if (dataSource != nullptr) {
        mDataSourceWrapper = new AMediaDataSourceWrapper(dataSource);
        err = mExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());
    if (aSourceWrapper != NULL) {
        err = mExtractor->setDataSource(aSourceWrapper->getAMediaDataSource());
    } else {
        err = mExtractor->setDataSource(fd, offset, length);
        err = mExtractor->setDataSource(fd, mOffset, mLength);
    }

    if (err != OK) {
        ALOGE("initFromDataSource, failed to create data source!");
        ALOGE("initFromDataSource, failed to set extractor data source!");
        mLock.lock();
        return UNKNOWN_ERROR;
    }
@@ -190,10 +174,8 @@ status_t NuPlayer2::GenericSource2::initFromDataSource() {
        return UNKNOWN_ERROR;
    }

    mLock.lock();
    mFd = -1;
    mDataSource = dataSource;
    mFileMeta = convertMediaFormatWrapperToMetaData(mExtractor->getFormat());
    mLock.lock();
    if (mFileMeta != NULL) {
        int64_t duration;
        if (mFileMeta->findInt64(kKeyDuration, &duration)) {
@@ -214,11 +196,7 @@ status_t NuPlayer2::GenericSource2::initFromDataSource() {
        }

        sp<AMediaExtractorWrapper> trackExtractor = new AMediaExtractorWrapper(AMediaExtractor_new());
        if (mDataSourceWrapper != nullptr) {
            err = trackExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());
        } else {
            err = trackExtractor->setDataSource(fd, offset, length);
        }
        trackExtractor->setDataSource(mDataSourceWrapper->getAMediaDataSource());

        const char *mime;
        sp<MetaData> meta = convertMediaFormatWrapperToMetaData(trackFormat);
@@ -329,8 +307,8 @@ NuPlayer2::GenericSource2::~GenericSource2() {
        mLooper->unregisterHandler(id());
        mLooper->stop();
    }
    if (mDataSource != NULL) {
        mDataSource->close();
    if (mDataSourceWrapper != NULL) {
        mDataSourceWrapper->close();
    }
    resetDataSource();
}
@@ -356,55 +334,39 @@ void NuPlayer2::GenericSource2::prepareAsync(int64_t startTimeUs) {
}

void NuPlayer2::GenericSource2::onPrepareAsync(int64_t startTimeUs) {
    ALOGV("onPrepareAsync: mDataSource: %d", (mDataSource != NULL));

    // delayed data source creation
    if (mDataSource == NULL) {
        // set to false first, if the extractor
        // comes back as secure, set it to true then.
        mIsSecure = false;
    ALOGV("onPrepareAsync: mFd %d mUri %s mDataSourceWrapper: %p",
            mFd, mUri.c_str(), mDataSourceWrapper.get());

    if (!mUri.empty()) {
        const char* uri = mUri.c_str();
            String8 contentType;

            if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
                mHttpSource = ClearDataSourceFactory::CreateMediaHTTP(mHTTPService);
                if (mHttpSource == NULL) {
                    ALOGE("Failed to create http source!");
                    notifyPreparedAndCleanup(UNKNOWN_ERROR);
                    return;
                }
        size_t numheaders = mUriHeaders.size();
        const char **key_values = numheaders ? new const char *[numheaders * 2] : NULL;
        for (size_t i = 0; i < numheaders; ++i) {
            key_values[i * 2] = mUriHeaders.keyAt(i).c_str();
            key_values[i * 2 + 1] =  mUriHeaders.valueAt(i).c_str();
        }

        mLock.unlock();
            // This might take long time if connection has some issue.
            sp<DataSource> dataSource = ClearDataSourceFactory::CreateFromURI(
                   mHTTPService, uri, &mUriHeaders, &contentType,
                   static_cast<HTTPBase *>(mHttpSource.get()));
        AMediaDataSource *aSource = AMediaDataSource_newUri(uri, numheaders, key_values);
        mLock.lock();
            if (!mDisconnected) {
                mDataSource = dataSource;
            }
        mDataSourceWrapper = aSource ? new AMediaDataSourceWrapper(aSource) : NULL;
        delete[] key_values;
        // For cached streaming cases, we need to wait for enough
        // buffering before reporting prepared.
        mIsStreaming = !strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8);
    }

        if (mFd == -1 && mDataSource == NULL) {
            ALOGE("Failed to create data source!");
    if (mDisconnected || (mFd < 0 && mDataSourceWrapper == NULL)) {
        ALOGE("mDisconnected(%d) or Failed to create data source!", mDisconnected);
        notifyPreparedAndCleanup(UNKNOWN_ERROR);
        return;
    }
    }

    if (mDataSource != nullptr && mDataSource->flags() & DataSource::kIsCachingDataSource) {
        mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
    }

    // For cached streaming cases, we need to wait for enough
    // buffering before reporting prepared.
    mIsStreaming = (mCachedSource != NULL);

    // init extractor from data source
    status_t err = initFromDataSource();
    if (mFd >= 0) {
        close(mFd);
        mFd = -1;
    }

    if (err != OK) {
        ALOGE("Failed to init from data source!");
@@ -441,7 +403,6 @@ void NuPlayer2::GenericSource2::finishPrepareAsync() {
    ALOGV("finishPrepareAsync");

    if (mIsStreaming) {
        mCachedSource->resumeFetchingIfNecessary();
        mPreparing = true;
        ++mPollBufferingGeneration;
        schedulePollBuffering();
@@ -460,9 +421,7 @@ void NuPlayer2::GenericSource2::finishPrepareAsync() {

void NuPlayer2::GenericSource2::notifyPreparedAndCleanup(status_t err) {
    if (err != OK) {
        mDataSource.clear();
        mCachedSource.clear();
        mHttpSource.clear();
        mDataSourceWrapper.clear();

        mBitrate = -1;
        mPrevBufferPercentage = -1;
@@ -502,47 +461,19 @@ void NuPlayer2::GenericSource2::resume() {
}

void NuPlayer2::GenericSource2::disconnect() {
    sp<DataSource> dataSource, httpSource;
    {
        Mutex::Autolock _l(mLock);
        dataSource = mDataSource;
        httpSource = mHttpSource;
        mDisconnected = true;
    }

    if (dataSource != NULL) {
        // disconnect data source
        if (dataSource->flags() & DataSource::kIsCachingDataSource) {
            static_cast<NuCachedSource2 *>(dataSource.get())->disconnect();
    if (mDataSourceWrapper != NULL) {
        mDataSourceWrapper->close();
    }
    } else if (httpSource != NULL) {
        static_cast<HTTPBase *>(httpSource.get())->disconnect();
    }

    mDataSourceWrapper = NULL;

}

status_t NuPlayer2::GenericSource2::feedMoreTSData() {
    return OK;
}

void NuPlayer2::GenericSource2::sendCacheStats() {
    int32_t kbps = 0;
    status_t err = UNKNOWN_ERROR;

    if (mCachedSource != NULL) {
        err = mCachedSource->getEstimatedBandwidthKbps(&kbps);
    }

    if (err == OK) {
        sp<AMessage> notify = dupNotify();
        notify->setInt32("what", kWhatCacheStats);
        notify->setInt32("bandwidth", kbps);
        notify->post();
    }
}

void NuPlayer2::GenericSource2::onMessageReceived(const sp<AMessage> &msg) {
    Mutex::Autolock _l(mLock);
    switch (msg->what()) {
@@ -840,8 +771,6 @@ status_t NuPlayer2::GenericSource2::dequeueAccessUnit(
            }
            if (track->mPackets->getAvailableBufferCount(&finalResult) < 2
                && !mSentPauseOnBuffering && !mPreparing) {
                mCachedSource->resumeFetchingIfNecessary();
                sendCacheStats();
                mSentPauseOnBuffering = true;
                sp<AMessage> notify = dupNotify();
                notify->setInt32("what", kWhatPauseOnBufferingStart);
@@ -1397,7 +1326,6 @@ void NuPlayer2::GenericSource2::readBuffer(
                        notifyPrepared();
                        mPreparing = false;
                    } else {
                        sendCacheStats();
                        mSentPauseOnBuffering = false;
                        sp<AMessage> notify = dupNotify();
                        notify->setInt32("what", kWhatResumeOnBufferingEnd);
@@ -1458,40 +1386,22 @@ void NuPlayer2::GenericSource2::schedulePollBuffering() {
}

void NuPlayer2::GenericSource2::onPollBuffering() {
    status_t finalStatus = UNKNOWN_ERROR;
    int64_t cachedDurationUs = -1ll;
    ssize_t cachedDataRemaining = -1;

    if (mCachedSource != NULL) {
        cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);

        if (finalStatus == OK) {
            off64_t size;
            int64_t bitrate = 0ll;
            if (mDurationUs > 0 && mCachedSource->getSize(&size) == OK) {
                // |bitrate| uses bits/second unit, while size is number of bytes.
                bitrate = size * 8000000ll / mDurationUs;
            } else if (mBitrate > 0) {
                bitrate = mBitrate;
            }
            if (bitrate > 0) {
                cachedDurationUs = cachedDataRemaining * 8000000ll / bitrate;
            }
        }
    }

    if (finalStatus != OK) {
        ALOGV("onPollBuffering: EOS (finalStatus = %d)", finalStatus);

        if (finalStatus == ERROR_END_OF_STREAM) {
            notifyBufferingUpdate(100);
    sp<AMediaExtractorWrapper> extractor;
    if (mVideoTrack.mExtractor != NULL) {
        extractor = mVideoTrack.mExtractor;
    } else if (mAudioTrack.mExtractor != NULL) {
        extractor = mAudioTrack.mExtractor;
    }

        return;
    if (extractor != NULL) {
        cachedDurationUs = extractor->getCachedDuration();
    }

    if (cachedDurationUs >= 0ll) {
        if (mDurationUs > 0ll) {
        ssize_t sampleSize = extractor->getSampleSize();
        if (sampleSize >= 0ll) {
            int64_t cachedPosUs = getLastReadPosition() + cachedDurationUs;
            int percentage = 100.0 * cachedPosUs / mDurationUs;
            if (percentage > 100) {
@@ -1499,9 +1409,11 @@ void NuPlayer2::GenericSource2::onPollBuffering() {
            }

            notifyBufferingUpdate(percentage);
        }

            ALOGV("onPollBuffering: cachedDurationUs %.1f sec", cachedDurationUs / 1000000.0f);
        } else {
            notifyBufferingUpdate(100);
            ALOGV("onPollBuffering: EOS");
        }
    }

    schedulePollBuffering();
Loading