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

Commit f580806d authored by Robert Shih's avatar Robert Shih
Browse files

HLS: QCom enhancements

This commit consists of:

http://go/pag/c/188753 Add NULL check for empty playlist
http://go/pag/c/188754 Fix deadlock for low duration clips
http://go/pag/c/188757 Create a copy of last enqueued metadata
http://go/pag/c/188755 Propagate target duration to LiveSession
http://go/pag/c/188762 Decouple block size from bandwidth estimate
http://go/pag/c/188756 Reduce memcpy calls for chunked content
http://go/pag/c/188758 Dont resume if we have almost fetched till stop time

Bug: 18821145
Change-Id: I7fd650999c6c50bbadffd65adee9020e669dfe62
parent 5886252a
Loading
Loading
Loading
Loading
+7 −2
Original line number Original line Diff line number Diff line
@@ -36,7 +36,8 @@ HTTPBase::HTTPBase()
      mTotalTransferBytes(0),
      mTotalTransferBytes(0),
      mPrevBandwidthMeasureTimeUs(0),
      mPrevBandwidthMeasureTimeUs(0),
      mPrevEstimatedBandWidthKbps(0),
      mPrevEstimatedBandWidthKbps(0),
      mBandWidthCollectFreqMs(5000) {
      mBandWidthCollectFreqMs(5000),
      mMaxBandwidthHistoryItems(100) {
}
}


void HTTPBase::addBandwidthMeasurement(
void HTTPBase::addBandwidthMeasurement(
@@ -50,7 +51,7 @@ void HTTPBase::addBandwidthMeasurement(
    mTotalTransferBytes += numBytes;
    mTotalTransferBytes += numBytes;


    mBandwidthHistory.push_back(entry);
    mBandwidthHistory.push_back(entry);
    if (++mNumBandwidthHistoryItems > 100) {
    if (++mNumBandwidthHistoryItems > mMaxBandwidthHistoryItems) {
        BandwidthEntry *entry = &*mBandwidthHistory.begin();
        BandwidthEntry *entry = &*mBandwidthHistory.begin();
        mTotalTransferTimeUs -= entry->mDelayUs;
        mTotalTransferTimeUs -= entry->mDelayUs;
        mTotalTransferBytes -= entry->mNumBytes;
        mTotalTransferBytes -= entry->mNumBytes;
@@ -104,6 +105,10 @@ status_t HTTPBase::setBandwidthStatCollectFreq(int32_t freqMs) {
    return OK;
    return OK;
}
}


void HTTPBase::setBandwidthHistorySize(size_t numHistoryItems) {
    mMaxBandwidthHistoryItems = numHistoryItems;
}

// static
// static
void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
void HTTPBase::RegisterSocketUserTag(int sockfd, uid_t uid, uint32_t kTag) {
    int res = qtaguid_tagSocket(sockfd, kTag, uid);
    int res = qtaguid_tagSocket(sockfd, kTag, uid);
+30 −2
Original line number Original line Diff line number Diff line
@@ -49,6 +49,9 @@


namespace android {
namespace android {


// Number of recently-read bytes to use for bandwidth estimation
const size_t LiveSession::kBandwidthHistoryBytes = 200 * 1024;

LiveSession::LiveSession(
LiveSession::LiveSession(
        const sp<AMessage> &notify, uint32_t flags,
        const sp<AMessage> &notify, uint32_t flags,
        const sp<IMediaHTTPService> &httpService)
        const sp<IMediaHTTPService> &httpService)
@@ -84,6 +87,13 @@ LiveSession::LiveSession(
        mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
        mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
        mBuffering[i] = false;
        mBuffering[i] = false;
    }
    }

    size_t numHistoryItems = kBandwidthHistoryBytes /
            PlaylistFetcher::kDownloadBlockSize + 1;
    if (numHistoryItems < 5) {
        numHistoryItems = 5;
    }
    mHTTPDataSource->setBandwidthHistorySize(numHistoryItems);
}
}


LiveSession::~LiveSession() {
LiveSession::~LiveSession() {
@@ -145,10 +155,24 @@ status_t LiveSession::dequeueAccessUnit(
        }
        }
    }
    }


    int32_t targetDuration = 0;
    sp<AMessage> meta = packetSource->getLatestEnqueuedMeta();
    if (meta != NULL) {
        meta->findInt32("targetDuration", &targetDuration);
    }

    int64_t targetDurationUs = targetDuration * 1000000ll;
    if (targetDurationUs == 0 ||
            targetDurationUs > PlaylistFetcher::kMinBufferedDurationUs) {
        // Fetchers limit buffering to
        // min(3 * targetDuration, kMinBufferedDurationUs)
        targetDurationUs = PlaylistFetcher::kMinBufferedDurationUs;
    }

    if (mBuffering[idx]) {
    if (mBuffering[idx]) {
        if (mSwitchInProgress
        if (mSwitchInProgress
                || packetSource->isFinished(0)
                || packetSource->isFinished(0)
                || packetSource->getEstimatedDurationUs() > 10000000ll) {
                || packetSource->getEstimatedDurationUs() > targetDurationUs) {
            mBuffering[idx] = false;
            mBuffering[idx] = false;
        }
        }
    }
    }
@@ -859,7 +883,11 @@ ssize_t LiveSession::fetchFile(
        // Only resize when we don't know the size.
        // Only resize when we don't know the size.
        size_t bufferRemaining = buffer->capacity() - buffer->size();
        size_t bufferRemaining = buffer->capacity() - buffer->size();
        if (bufferRemaining == 0 && getSizeErr != OK) {
        if (bufferRemaining == 0 && getSizeErr != OK) {
            bufferRemaining = 32768;
            size_t bufferIncrement = buffer->size() / 2;
            if (bufferIncrement < 32768) {
                bufferIncrement = 32768;
            }
            bufferRemaining = bufferIncrement;


            ALOGV("increasing download buffer to %zu bytes",
            ALOGV("increasing download buffer to %zu bytes",
                 buffer->size() + bufferRemaining);
                 buffer->size() + bufferRemaining);
+2 −0
Original line number Original line Diff line number Diff line
@@ -114,6 +114,8 @@ private:
        kWhatSwitchDown                 = 'sDwn',
        kWhatSwitchDown                 = 'sDwn',
    };
    };


    static const size_t kBandwidthHistoryBytes;

    struct BandwidthItem {
    struct BandwidthItem {
        size_t mPlaylistIndex;
        size_t mPlaylistIndex;
        unsigned long mBandwidth;
        unsigned long mBandwidth;
+16 −5
Original line number Original line Diff line number Diff line
@@ -49,8 +49,9 @@ namespace android {
// static
// static
const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
const int32_t PlaylistFetcher::kDownloadBlockSize = 2048;
// LCM of 188 (size of a TS packet) & 1k works well
const int32_t PlaylistFetcher::kNumSkipFrames = 10;
const int32_t PlaylistFetcher::kDownloadBlockSize = 47 * 1024;
const int32_t PlaylistFetcher::kNumSkipFrames = 5;


PlaylistFetcher::PlaylistFetcher(
PlaylistFetcher::PlaylistFetcher(
        const sp<AMessage> &notify,
        const sp<AMessage> &notify,
@@ -561,7 +562,7 @@ status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {
        // Don't resume if we would stop within a resume threshold.
        // Don't resume if we would stop within a resume threshold.
        int32_t discontinuitySeq;
        int32_t discontinuitySeq;
        int64_t latestTimeUs = 0, stopTimeUs = 0;
        int64_t latestTimeUs = 0, stopTimeUs = 0;
        sp<AMessage> latestMeta = packetSource->getLatestDequeuedMeta();
        sp<AMessage> latestMeta = packetSource->getLatestEnqueuedMeta();
        if (latestMeta != NULL
        if (latestMeta != NULL
                && latestMeta->findInt32("discontinuitySeq", &discontinuitySeq)
                && latestMeta->findInt32("discontinuitySeq", &discontinuitySeq)
                && discontinuitySeq == mDiscontinuitySeq
                && discontinuitySeq == mDiscontinuitySeq
@@ -610,7 +611,12 @@ void PlaylistFetcher::onMonitorQueue() {
    int32_t targetDurationSecs;
    int32_t targetDurationSecs;
    int64_t targetDurationUs = kMinBufferedDurationUs;
    int64_t targetDurationUs = kMinBufferedDurationUs;
    if (mPlaylist != NULL) {
    if (mPlaylist != NULL) {
        CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
        if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
                "target-duration", &targetDurationSecs)) {
            ALOGE("Playlist is missing required EXT-X-TARGETDURATION tag");
            notifyError(ERROR_MALFORMED);
            return;
        }
        targetDurationUs = targetDurationSecs * 1000000ll;
        targetDurationUs = targetDurationSecs * 1000000ll;
    }
    }


@@ -1159,6 +1165,11 @@ const sp<ABuffer> &PlaylistFetcher::setAccessUnitProperties(
        accessUnit->meta()->setInt32("discard", discard);
        accessUnit->meta()->setInt32("discard", discard);
    }
    }


    int32_t targetDurationSecs;
    if (mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs)) {
        accessUnit->meta()->setInt32("targetDuration", targetDurationSecs);
    }

    accessUnit->meta()->setInt32("discontinuitySeq", mDiscontinuitySeq);
    accessUnit->meta()->setInt32("discontinuitySeq", mDiscontinuitySeq);
    accessUnit->meta()->setInt64("segmentStartTimeUs", getSegmentStartTimeUs(mSeqNumber));
    accessUnit->meta()->setInt64("segmentStartTimeUs", getSegmentStartTimeUs(mSeqNumber));
    return accessUnit;
    return accessUnit;
@@ -1668,7 +1679,7 @@ void PlaylistFetcher::updateDuration() {


int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {
int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {
    int64_t durationUs, threshold;
    int64_t durationUs, threshold;
    if (msg->findInt64("durationUs", &durationUs)) {
    if (msg->findInt64("durationUs", &durationUs) && durationUs > 0) {
        return kNumSkipFrames * durationUs;
        return kNumSkipFrames * durationUs;
    }
    }


+3 −2
Original line number Original line Diff line number Diff line
@@ -34,6 +34,9 @@ struct M3UParser;
struct String8;
struct String8;


struct PlaylistFetcher : public AHandler {
struct PlaylistFetcher : public AHandler {
    static const int64_t kMinBufferedDurationUs;
    static const int32_t kDownloadBlockSize;

    enum {
    enum {
        kWhatStarted,
        kWhatStarted,
        kWhatPaused,
        kWhatPaused,
@@ -92,9 +95,7 @@ private:
        kWhatDownloadNext   = 'dlnx',
        kWhatDownloadNext   = 'dlnx',
    };
    };


    static const int64_t kMinBufferedDurationUs;
    static const int64_t kMaxMonitorDelayUs;
    static const int64_t kMaxMonitorDelayUs;
    static const int32_t kDownloadBlockSize;
    static const int32_t kNumSkipFrames;
    static const int32_t kNumSkipFrames;


    static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer);
    static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer);
Loading