summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorRobert Shih <robertshih@google.com>2014-09-17 03:23:34 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-09-17 03:23:34 +0000
commit90869c2bef1bc47394a9f603ccebb62b2592fd2b (patch)
tree2d0bc1784b9154b7a08f1c5903f35e2b1d63eabe /media/libstagefright
parent919b93473ebbba036f3934e92039f038c7f91a54 (diff)
parent73d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7 (diff)
downloadframeworks_av-90869c2bef1bc47394a9f603ccebb62b2592fd2b.zip
frameworks_av-90869c2bef1bc47394a9f603ccebb62b2592fd2b.tar.gz
frameworks_av-90869c2bef1bc47394a9f603ccebb62b2592fd2b.tar.bz2
Merge "HLS: fix freezes when toggling between a/v streams" into lmp-dev
Diffstat (limited to 'media/libstagefright')
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp11
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.cpp53
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.h4
3 files changed, 63 insertions, 5 deletions
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 3720085..7786c27 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -158,9 +158,16 @@ status_t LiveSession::dequeueAccessUnit(
// wait for counterpart
sp<AnotherPacketSource> otherSource;
- if (stream == STREAMTYPE_AUDIO && (mStreamMask & STREAMTYPE_VIDEO)) {
+ uint32_t mask = mNewStreamMask & mStreamMask;
+ uint32_t fetchersMask = 0;
+ for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
+ uint32_t fetcherMask = mFetcherInfos.valueAt(i).mFetcher->getStreamTypeMask();
+ fetchersMask |= fetcherMask;
+ }
+ mask &= fetchersMask;
+ if (stream == STREAMTYPE_AUDIO && (mask & STREAMTYPE_VIDEO)) {
otherSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
- } else if (stream == STREAMTYPE_VIDEO && (mStreamMask & STREAMTYPE_AUDIO)) {
+ } else if (stream == STREAMTYPE_VIDEO && (mask & STREAMTYPE_AUDIO)) {
otherSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
}
if (otherSource != NULL && !otherSource->hasBufferAvailable(&finalResult)) {
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 1166762..f78f8b4 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -1009,7 +1009,16 @@ void PlaylistFetcher::onDownloadNext() {
// bulk extract non-ts files
if (tsBuffer == NULL) {
- err = extractAndQueueAccessUnits(buffer, itemMeta);
+ err = extractAndQueueAccessUnits(buffer, itemMeta);
+ if (err == -EAGAIN) {
+ // starting sequence number too low/high
+ postMonitorQueue();
+ return;
+ } else if (err == ERROR_OUT_OF_RANGE) {
+ // reached stopping point
+ stopAsync(/* clear = */false);
+ return;
+ }
}
if (err != OK) {
@@ -1552,14 +1561,52 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits(
if (startTimeUs < mStartTimeUs) {
continue;
}
+
+ if (mStartTimeUsNotify != NULL) {
+ int32_t targetDurationSecs;
+ CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
+ int64_t targetDurationUs = targetDurationSecs * 1000000ll;
+
+ // Duplicated logic from how we handle .ts playlists.
+ if (mStartup && mSegmentStartTimeUs >= 0
+ && timeUs - mStartTimeUs > targetDurationUs) {
+ int32_t newSeqNumber = getSeqNumberWithAnchorTime(timeUs);
+ if (newSeqNumber >= mSeqNumber) {
+ --mSeqNumber;
+ } else {
+ mSeqNumber = newSeqNumber;
+ }
+ return -EAGAIN;
+ }
+
+ mStartTimeUsNotify->setInt64("timeUsAudio", timeUs);
+ mStartTimeUsNotify->setInt32("discontinuitySeq", mDiscontinuitySeq);
+ mStartTimeUsNotify->setInt32("streamMask", LiveSession::STREAMTYPE_AUDIO);
+ mStartTimeUsNotify->post();
+ mStartTimeUsNotify.clear();
+ }
+ }
+
+ if (mStopParams != NULL) {
+ // Queue discontinuity in original stream.
+ int32_t discontinuitySeq;
+ int64_t stopTimeUs;
+ if (!mStopParams->findInt32("discontinuitySeq", &discontinuitySeq)
+ || discontinuitySeq > mDiscontinuitySeq
+ || !mStopParams->findInt64("timeUsAudio", &stopTimeUs)
+ || (discontinuitySeq == mDiscontinuitySeq && unitTimeUs >= stopTimeUs)) {
+ packetSource->queueAccessUnit(mSession->createFormatChangeBuffer());
+ mStreamTypeMask = 0;
+ mPacketSources.clear();
+ return ERROR_OUT_OF_RANGE;
+ }
}
sp<ABuffer> unit = new ABuffer(aac_frame_length);
memcpy(unit->data(), adtsHeader, aac_frame_length);
unit->meta()->setInt64("timeUs", unitTimeUs);
- unit->meta()->setInt64("segmentStartTimeUs", getSegmentStartTimeUs(mSeqNumber));
- unit->meta()->setInt32("discontinuitySeq", mDiscontinuitySeq);
+ setAccessUnitProperties(unit, packetSource);
packetSource->queueAccessUnit(unit);
}
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 4ba37fa..4b09df1 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -69,6 +69,10 @@ struct PlaylistFetcher : public AHandler {
void resumeUntilAsync(const sp<AMessage> &params);
+ uint32_t getStreamTypeMask() const {
+ return mStreamTypeMask;
+ }
+
protected:
virtual ~PlaylistFetcher();
virtual void onMessageReceived(const sp<AMessage> &msg);