summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/httplive
diff options
context:
space:
mode:
authorRobert Shih <robertshih@google.com>2014-08-29 18:22:44 -0700
committerRobert Shih <robertshih@google.com>2014-09-16 01:41:36 +0000
commit73d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7 (patch)
treea0e4f84d1863de094323510643e47937b4c720a9 /media/libstagefright/httplive
parent9299a6873a4b909357e031361055a888843619da (diff)
downloadframeworks_av-73d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7.zip
frameworks_av-73d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7.tar.gz
frameworks_av-73d2847af14cdd5fdf8bd1ac80fb7ddf9ae7d9a7.tar.bz2
HLS: fix freezes when toggling between a/v streams
Bug: 17412740 Change-Id: Iacaf2fa1d20584056375803e1782ad6761c56fc5
Diffstat (limited to 'media/libstagefright/httplive')
-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);