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

Commit 3a005b3b authored by Robert Shih's avatar Robert Shih Committed by Android (Google) Code Review
Browse files

Merge "LiveSession refactor"

parents 3197ce82 8ca002ee
Loading
Loading
Loading
Loading
+68 −118
Original line number Diff line number Diff line
@@ -61,14 +61,14 @@ LiveSession::LiveSession(
      mRealTimeBaseUs(0ll),
      mReconfigurationInProgress(false),
      mDisconnectReplyID(0) {
    mPacketSources.add(
            STREAMTYPE_AUDIO, new AnotherPacketSource(NULL /* meta */));

    mPacketSources.add(
            STREAMTYPE_VIDEO, new AnotherPacketSource(NULL /* meta */));
    mStreams[kAudioIndex] = StreamItem("audio");
    mStreams[kVideoIndex] = StreamItem("video");
    mStreams[kSubtitleIndex] = StreamItem("subtitle");

    mPacketSources.add(
            STREAMTYPE_SUBTITLES, new AnotherPacketSource(NULL /* meta */));
    for (size_t i = 0; i < kMaxStreams; ++i) {
        mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
    }
}

LiveSession::~LiveSession() {
@@ -369,6 +369,12 @@ int LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b)
    return 1;
}

// static
LiveSession::StreamType LiveSession::indexToType(int idx) {
    CHECK(idx >= 0 && idx < kMaxStreams);
    return (StreamType)(1 << idx);
}

void LiveSession::onConnect(const sp<AMessage> &msg) {
    AString url;
    CHECK(msg->findString("url", &url));
@@ -858,19 +864,11 @@ void LiveSession::changeConfiguration(

    uint32_t streamMask = 0;

    AString audioURI;
    if (mPlaylist->getAudioURI(item.mPlaylistIndex, &audioURI)) {
        streamMask |= STREAMTYPE_AUDIO;
    AString URIs[kMaxStreams];
    for (size_t i = 0; i < kMaxStreams; ++i) {
        if (mPlaylist->getTypeURI(item.mPlaylistIndex, mStreams[i].mType, &URIs[i])) {
            streamMask |= indexToType(i);
        }

    AString videoURI;
    if (mPlaylist->getVideoURI(item.mPlaylistIndex, &videoURI)) {
        streamMask |= STREAMTYPE_VIDEO;
    }

    AString subtitleURI;
    if (mPlaylist->getSubtitleURI(item.mPlaylistIndex, &subtitleURI)) {
        streamMask |= STREAMTYPE_SUBTITLES;
    }

    // Step 1, stop and discard fetchers that are no longer needed.
@@ -882,12 +880,12 @@ void LiveSession::changeConfiguration(

        // If we're seeking all current fetchers are discarded.
        if (timeUs < 0ll) {
            if (((streamMask & STREAMTYPE_AUDIO) && uri == audioURI)
                    || ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI)
                    || ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI)) {
            for (size_t j = 0; j < kMaxStreams; ++j) {
                if ((streamMask & indexToType(j)) && uri == URIs[j]) {
                    discardFetcher = false;
                }
            }
        }

        if (discardFetcher) {
            mFetcherInfos.valueAt(i).mFetcher->stopAsync();
@@ -899,14 +897,10 @@ void LiveSession::changeConfiguration(
    sp<AMessage> msg = new AMessage(kWhatChangeConfiguration2, id());
    msg->setInt32("streamMask", streamMask);
    msg->setInt64("timeUs", timeUs);
    if (streamMask & STREAMTYPE_AUDIO) {
        msg->setString("audioURI", audioURI.c_str());
    for (size_t i = 0; i < kMaxStreams; ++i) {
        if (streamMask & indexToType(i)) {
            msg->setString(mStreams[i].uriKey().c_str(), URIs[i].c_str());
        }
    if (streamMask & STREAMTYPE_VIDEO) {
        msg->setString("videoURI", videoURI.c_str());
    }
    if (streamMask & STREAMTYPE_SUBTITLES) {
        msg->setString("subtitleURI", subtitleURI.c_str());
    }

    // Every time a fetcher acknowledges the stopAsync or pauseAsync request
@@ -937,18 +931,13 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
    uint32_t streamMask;
    CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));

    AString audioURI, videoURI, subtitleURI;
    if (streamMask & STREAMTYPE_AUDIO) {
        CHECK(msg->findString("audioURI", &audioURI));
        ALOGV("audioURI = '%s'", audioURI.c_str());
    }
    if (streamMask & STREAMTYPE_VIDEO) {
        CHECK(msg->findString("videoURI", &videoURI));
        ALOGV("videoURI = '%s'", videoURI.c_str());
    AString URIs[kMaxStreams];
    for (size_t i = 0; i < kMaxStreams; ++i) {
        if (streamMask & indexToType(i)) {
            const AString &uriKey = mStreams[i].uriKey();
            CHECK(msg->findString(uriKey.c_str(), &URIs[i]));
            ALOGV("%s = '%s'", uriKey.c_str(), URIs[i].c_str());
        }
    if (streamMask & STREAMTYPE_SUBTITLES) {
        CHECK(msg->findString("subtitleURI", &subtitleURI));
        ALOGV("subtitleURI = '%s'", subtitleURI.c_str());
    }

    // Determine which decoders to shutdown on the player side,
@@ -958,15 +947,12 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
    // 2) its streamtype was already active and still is but the URI
    //    has changed.
    uint32_t changedMask = 0;
    if (((mStreamMask & streamMask & STREAMTYPE_AUDIO)
                && !(audioURI == mAudioURI))
        || (mStreamMask & ~streamMask & STREAMTYPE_AUDIO)) {
        changedMask |= STREAMTYPE_AUDIO;
    for (size_t i = 0; i < kMaxStreams && i != kSubtitleIndex; ++i) {
        if (((mStreamMask & streamMask & indexToType(i))
                && !(URIs[i] == mStreams[i].mUri))
                || (mStreamMask & ~streamMask & indexToType(i))) {
            changedMask |= indexToType(i);
        }
    if (((mStreamMask & streamMask & STREAMTYPE_VIDEO)
                && !(videoURI == mVideoURI))
        || (mStreamMask & ~streamMask & STREAMTYPE_VIDEO)) {
        changedMask |= STREAMTYPE_VIDEO;
    }

    if (changedMask == 0) {
@@ -998,15 +984,10 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
    uint32_t streamMask;
    CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));

    AString audioURI, videoURI, subtitleURI;
    if (streamMask & STREAMTYPE_AUDIO) {
        CHECK(msg->findString("audioURI", &audioURI));
    for (size_t i = 0; i < kMaxStreams; ++i) {
        if (streamMask & indexToType(i)) {
            CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mUri));
        }
    if (streamMask & STREAMTYPE_VIDEO) {
        CHECK(msg->findString("videoURI", &videoURI));
    }
    if (streamMask & STREAMTYPE_SUBTITLES) {
        CHECK(msg->findString("subtitleURI", &subtitleURI));
    }

    int64_t timeUs;
@@ -1018,9 +999,6 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
    mRealTimeBaseUs = ALooper::GetNowUs() - timeUs;

    mStreamMask = streamMask;
    mAudioURI = audioURI;
    mVideoURI = videoURI;
    mSubtitleURI = subtitleURI;

    // Resume all existing fetchers and assign them packet sources.
    for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
@@ -1028,22 +1006,13 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {

        uint32_t resumeMask = 0;

        sp<AnotherPacketSource> audioSource;
        if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
            audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
            resumeMask |= STREAMTYPE_AUDIO;
        sp<AnotherPacketSource> sources[kMaxStreams];
        // TRICKY: looping from i as earlier streams are already removed from streamMask
        for (size_t j = i; j < kMaxStreams; ++j) {
            if ((streamMask & indexToType(j)) && uri == mStreams[j].mUri) {
                sources[j] = mPacketSources.valueFor(indexToType(j));
                resumeMask |= indexToType(j);
            }

        sp<AnotherPacketSource> videoSource;
        if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
            videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
            resumeMask |= STREAMTYPE_VIDEO;
        }

        sp<AnotherPacketSource> subtitleSource;
        if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
            subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
            resumeMask |= STREAMTYPE_SUBTITLES;
        }

        CHECK_NE(resumeMask, 0u);
@@ -1053,7 +1022,7 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
        streamMask &= ~resumeMask;

        mFetcherInfos.valueAt(i).mFetcher->startAsync(
                audioSource, videoSource, subtitleSource);
                sources[kAudioIndex], sources[kVideoIndex], sources[kSubtitleIndex]);
    }

    // streamMask now only contains the types that need a new fetcher created.
@@ -1062,52 +1031,33 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
        ALOGV("creating new fetchers for mask 0x%08x", streamMask);
    }

    while (streamMask != 0) {
        StreamType streamType = (StreamType)(streamMask & ~(streamMask - 1));
    for (size_t i = 0; i < kMaxStreams; i++) {
        if (!(indexToType(i) & streamMask)) {
            continue;
        }

        AString uri;
        switch (streamType) {
            case STREAMTYPE_AUDIO:
                uri = audioURI;
                break;
            case STREAMTYPE_VIDEO:
                uri = videoURI;
                break;
            case STREAMTYPE_SUBTITLES:
                uri = subtitleURI;
                break;
            default:
                TRESPASS();
        }
        uri = mStreams[i].mUri;

        sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str());
        CHECK(fetcher != NULL);

        sp<AnotherPacketSource> audioSource;
        if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
            audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
            audioSource->clear();
        sp<AnotherPacketSource> sources[kMaxStreams];
        // TRICKY: looping from i as earlier streams are already removed from streamMask
        for (size_t j = i; j < kMaxStreams; ++j) {
            if ((streamMask & indexToType(j)) && uri == mStreams[j].mUri) {
                sources[j] = mPacketSources.valueFor(indexToType(j));
                sources[j]->clear();

            streamMask &= ~STREAMTYPE_AUDIO;
                streamMask &= ~indexToType(j);
            }

        sp<AnotherPacketSource> videoSource;
        if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
            videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
            videoSource->clear();

            streamMask &= ~STREAMTYPE_VIDEO;
        }

        sp<AnotherPacketSource> subtitleSource;
        if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
            subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
            subtitleSource->clear();

            streamMask &= ~STREAMTYPE_SUBTITLES;
        }

        fetcher->startAsync(audioSource, videoSource, subtitleSource, timeUs);
        fetcher->startAsync(
                sources[kAudioIndex],
                sources[kVideoIndex],
                sources[kSubtitleIndex],
                timeUs);
    }

    // All fetchers have now been started, the configuration change
+24 −4
Original line number Diff line number Diff line
@@ -44,10 +44,17 @@ struct LiveSession : public AHandler {
            uint32_t flags,
            const sp<IMediaHTTPService> &httpService);

    enum StreamIndex {
        kAudioIndex    = 0,
        kVideoIndex    = 1,
        kSubtitleIndex = 2,
        kMaxStreams    = 3,
    };

    enum StreamType {
        STREAMTYPE_AUDIO        = 1,
        STREAMTYPE_VIDEO        = 2,
        STREAMTYPE_SUBTITLES    = 4,
        STREAMTYPE_AUDIO        = 1 << kAudioIndex,
        STREAMTYPE_VIDEO        = 1 << kVideoIndex,
        STREAMTYPE_SUBTITLES    = 1 << kSubtitleIndex,
    };
    status_t dequeueAccessUnit(StreamType stream, sp<ABuffer> *accessUnit);

@@ -107,6 +114,19 @@ private:
        bool mIsPrepared;
    };

    struct StreamItem {
        const char *mType;
        AString mUri;
        StreamItem() : mType("") {}
        StreamItem(const char *type) : mType(type) {}
        AString uriKey() {
            AString key(mType);
            key.append("URI");
            return key;
        }
    };
    StreamItem mStreams[kMaxStreams];

    sp<AMessage> mNotify;
    uint32_t mFlags;
    sp<IMediaHTTPService> mHTTPService;
@@ -124,7 +144,6 @@ private:
    sp<M3UParser> mPlaylist;

    KeyedVector<AString, FetcherInfo> mFetcherInfos;
    AString mAudioURI, mVideoURI, mSubtitleURI;
    uint32_t mStreamMask;

    KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources;
@@ -173,6 +192,7 @@ private:
    size_t getBandwidthIndex();

    static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *);
    static StreamType indexToType(int idx);

    void changeConfiguration(
            int64_t timeUs, size_t bandwidthIndex, bool pickTrack = false);
+0 −12
Original line number Diff line number Diff line
@@ -369,18 +369,6 @@ bool M3UParser::getTypeURI(size_t index, const char *key, AString *uri) const {
    return true;
}

bool M3UParser::getAudioURI(size_t index, AString *uri) const {
    return getTypeURI(index, "audio", uri);
}

bool M3UParser::getVideoURI(size_t index, AString *uri) const {
    return getTypeURI(index, "video", uri);
}

bool M3UParser::getSubtitleURI(size_t index, AString *uri) const {
    return getTypeURI(index, "subtitles", uri);
}

static bool MakeURL(const char *baseURL, const char *url, AString *out) {
    out->clear();

+1 −5
Original line number Diff line number Diff line
@@ -45,9 +45,7 @@ struct M3UParser : public RefBase {
    status_t getTrackInfo(Parcel* reply) const;
    ssize_t getSelectedIndex() const;

    bool getAudioURI(size_t index, AString *uri) const;
    bool getVideoURI(size_t index, AString *uri) const;
    bool getSubtitleURI(size_t index, AString *uri) const;
    bool getTypeURI(size_t index, const char *key, AString *uri) const;

protected:
    virtual ~M3UParser();
@@ -95,8 +93,6 @@ private:

    status_t parseMedia(const AString &line);

    bool getTypeURI(size_t index, const char *key, AString *uri) const;

    static status_t ParseInt32(const char *s, int32_t *x);
    static status_t ParseDouble(const char *s, double *x);