Loading media/libstagefright/httplive/LiveSession.cpp +68 −118 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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)); Loading Loading @@ -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. Loading @@ -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(); Loading @@ -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 Loading Loading @@ -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, Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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) { Loading @@ -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); Loading @@ -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. Loading @@ -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 Loading media/libstagefright/httplive/LiveSession.h +24 −4 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -124,7 +144,6 @@ private: sp<M3UParser> mPlaylist; KeyedVector<AString, FetcherInfo> mFetcherInfos; AString mAudioURI, mVideoURI, mSubtitleURI; uint32_t mStreamMask; KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources; Loading Loading @@ -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); Loading media/libstagefright/httplive/M3UParser.cpp +0 −12 Original line number Diff line number Diff line Loading @@ -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(); Loading media/libstagefright/httplive/M3UParser.h +1 −5 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading Loading
media/libstagefright/httplive/LiveSession.cpp +68 −118 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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)); Loading Loading @@ -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. Loading @@ -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(); Loading @@ -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 Loading Loading @@ -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, Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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) { Loading @@ -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); Loading @@ -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. Loading @@ -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 Loading
media/libstagefright/httplive/LiveSession.h +24 −4 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading @@ -124,7 +144,6 @@ private: sp<M3UParser> mPlaylist; KeyedVector<AString, FetcherInfo> mFetcherInfos; AString mAudioURI, mVideoURI, mSubtitleURI; uint32_t mStreamMask; KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources; Loading Loading @@ -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); Loading
media/libstagefright/httplive/M3UParser.cpp +0 −12 Original line number Diff line number Diff line Loading @@ -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(); Loading
media/libstagefright/httplive/M3UParser.h +1 −5 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading