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

Commit e449fcea authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am 28b93967: am 165c6579: Merge "HTTP Live content that are tagged as complete...

am 28b93967: am 165c6579: Merge "HTTP Live content that are tagged as complete are now seekable." into gingerbread

Merge commit '28b93967'

* commit '28b93967':
  HTTP Live content that are tagged as complete are now seekable.
parents af95d12b 28b93967
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ public:
    enum Flags {
        kWantsPrefetching      = 1,
        kStreamedFromLocalHost = 2,
        kIsCachingDataSource   = 4,
    };

    static sp<DataSource> CreateFromURI(
+8 −4
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "include/SoftwareRenderer.h"
#include "include/NuCachedSource2.h"
#include "include/ThrottledSource.h"
#include "include/MPEG2TSExtractor.h"

#include "ARTPSession.h"
#include "APacketSource.h"
@@ -509,8 +510,8 @@ void AwesomePlayer::onBufferingUpdate() {
                // We don't know the bitrate of the stream, use absolute size
                // limits to maintain the cache.

                const size_t kLowWaterMarkBytes = 400000;
                const size_t kHighWaterMarkBytes = 1000000;
                const size_t kLowWaterMarkBytes = 40000;
                const size_t kHighWaterMarkBytes = 200000;

                if ((mFlags & PLAYING) && !eos
                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
@@ -1365,14 +1366,17 @@ status_t AwesomePlayer::finishSetDataSource_l() {
        String8 uri("http://");
        uri.append(mUri.string() + 11);

        dataSource = new LiveSource(uri.string());
        sp<LiveSource> liveSource = new LiveSource(uri.string());

        mCachedSource = new NuCachedSource2(dataSource);
        mCachedSource = new NuCachedSource2(liveSource);
        dataSource = mCachedSource;

        sp<MediaExtractor> extractor =
            MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);

        static_cast<MPEG2TSExtractor *>(extractor.get())
            ->setLiveSource(liveSource);

        return setDataSource_l(extractor);
    } else if (!strncmp("rtsp://gtalk/", mUri.string(), 13)) {
        if (mLooper == NULL) {
+45 −3
Original line number Diff line number Diff line
@@ -179,7 +179,8 @@ NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
      mFinalStatus(OK),
      mLastAccessPos(0),
      mFetching(true),
      mLastFetchTimeUs(-1) {
      mLastFetchTimeUs(-1),
      mSuspended(false) {
    mLooper->setName("NuCachedSource2");
    mLooper->registerHandler(mReflector);
    mLooper->start();
@@ -205,7 +206,7 @@ status_t NuCachedSource2::getSize(off_t *size) {
}

uint32_t NuCachedSource2::flags() {
    return mSource->flags();
    return (mSource->flags() & ~kWantsPrefetching) | kIsCachingDataSource;
}

void NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) {
@@ -222,6 +223,12 @@ void NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }

        case kWhatSuspend:
        {
            onSuspend();
            break;
        }

        default:
            TRESPASS();
    }
@@ -263,6 +270,7 @@ void NuCachedSource2::onFetch() {

    bool keepAlive =
        !mFetching
            && !mSuspended
            && mFinalStatus == OK
            && ALooper::GetNowUs() >= mLastFetchTimeUs + kKeepAliveIntervalUs;

@@ -279,7 +287,7 @@ void NuCachedSource2::onFetch() {
            LOGI("Cache full, done prefetching for now");
            mFetching = false;
        }
    } else {
    } else if (!mSuspended) {
        Mutex::Autolock autoLock(mLock);
        restartPrefetcherIfNecessary_l();
    }
@@ -468,5 +476,39 @@ status_t NuCachedSource2::seekInternal_l(off_t offset) {
    return OK;
}

void NuCachedSource2::clearCacheAndResume() {
    LOGV("clearCacheAndResume");

    Mutex::Autolock autoLock(mLock);

    CHECK(mSuspended);

    mCacheOffset = 0;
    mFinalStatus = OK;
    mLastAccessPos = 0;
    mLastFetchTimeUs = -1;

    size_t totalSize = mCache->totalSize();
    CHECK_EQ(mCache->releaseFromStart(totalSize), totalSize);

    mFetching = true;
    mSuspended = false;
}

void NuCachedSource2::suspend() {
    (new AMessage(kWhatSuspend, mReflector->id()))->post();

    while (!mSuspended) {
        usleep(10000);
    }
}

void NuCachedSource2::onSuspend() {
    Mutex::Autolock autoLock(mLock);

    mFetching = false;
    mSuspended = true;
}

}  // namespace android
+69 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ namespace android {
LiveSource::LiveSource(const char *url)
    : mMasterURL(url),
      mInitCheck(NO_INIT),
      mDurationUs(-1),
      mPlaylistIndex(0),
      mLastFetchTimeUs(-1),
      mSource(new NuHTTPDataSource),
@@ -40,6 +41,8 @@ LiveSource::LiveSource(const char *url)
      mPrevBandwidthIndex(-1) {
    if (switchToNext()) {
        mInitCheck = OK;

        determineSeekability();
    }
}

@@ -139,7 +142,7 @@ bool LiveSource::loadPlaylist(bool fetchMaster) {
        }
#else
        // Stay on the lowest bandwidth available.
        size_t index = 0;  // Lowest bandwidth stream
        size_t index = mBandwidthItems.size() - 1;  // Highest bandwidth stream
#endif

        mURL = mBandwidthItems.editItemAt(index).mURI;
@@ -336,4 +339,69 @@ status_t LiveSource::fetchM3U(const char *url, sp<ABuffer> *out) {
    return OK;
}

bool LiveSource::seekTo(int64_t seekTimeUs) {
    LOGV("seek to %lld us", seekTimeUs);

    if (!mPlaylist->isComplete()) {
        return false;
    }

    int32_t targetDuration;
    if (!mPlaylist->meta()->findInt32("target-duration", &targetDuration)) {
        return false;
    }

    int64_t seekTimeSecs = (seekTimeUs + 500000ll) / 1000000ll;

    int64_t index = seekTimeSecs / targetDuration;

    if (index < 0 || index >= mPlaylist->size()) {
        return false;
    }

    size_t newPlaylistIndex = mFirstItemSequenceNumber + index;

    if (newPlaylistIndex == mPlaylistIndex) {
        return false;
    }

    mPlaylistIndex = newPlaylistIndex;

    switchToNext();
    mOffsetBias = 0;

    LOGV("seeking to index %lld", index);

    return true;
}

bool LiveSource::getDuration(int64_t *durationUs) const {
    if (mDurationUs >= 0) {
        *durationUs = mDurationUs;
        return true;
    }

    *durationUs = 0;
    return false;
}

bool LiveSource::isSeekable() const {
    return mDurationUs >= 0;
}

void LiveSource::determineSeekability() {
    mDurationUs = -1;

    if (!mPlaylist->isComplete()) {
        return;
    }

    int32_t targetDuration;
    if (!mPlaylist->meta()->findInt32("target-duration", &targetDuration)) {
        return;
    }

    mDurationUs = targetDuration * 1000000ll * mPlaylist->size();
}

}  // namespace android
+8 −1
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@ M3UParser::M3UParser(
    : mInitCheck(NO_INIT),
      mBaseURI(baseURI),
      mIsExtM3U(false),
      mIsVariantPlaylist(false) {
      mIsVariantPlaylist(false),
      mIsComplete(false) {
    mInitCheck = parse(data, size);
}

@@ -46,6 +47,10 @@ bool M3UParser::isVariantPlaylist() const {
    return mIsVariantPlaylist;
}

bool M3UParser::isComplete() const {
    return mIsComplete;
}

sp<AMessage> M3UParser::meta() {
    return mMeta;
}
@@ -153,6 +158,8 @@ status_t M3UParser::parse(const void *_data, size_t size) {
                    return ERROR_MALFORMED;
                }
                err = parseMetaData(line, &mMeta, "media-sequence");
            } else if (line.startsWith("#EXT-X-ENDLIST")) {
                mIsComplete = true;
            } else if (line.startsWith("#EXTINF")) {
                if (mIsVariantPlaylist) {
                    return ERROR_MALFORMED;
Loading