diff options
author | Chong Zhang <chz@google.com> | 2015-04-10 20:51:38 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-04-10 20:51:39 +0000 |
commit | c255757c795e5db87bafa6609c4ae052cf38b45b (patch) | |
tree | 01a61327343c90f434b5e85c6305aa2f7ac3ac7a /media | |
parent | de5e5d7141e7816a006e9a890bb68fc2d6581e0e (diff) | |
parent | 8464d7decb34a3044e92b4085f1bbaafb51410e8 (diff) | |
download | frameworks_av-c255757c795e5db87bafa6609c4ae052cf38b45b.zip frameworks_av-c255757c795e5db87bafa6609c4ae052cf38b45b.tar.gz frameworks_av-c255757c795e5db87bafa6609c4ae052cf38b45b.tar.bz2 |
Merge "HLS: allow down switch during prepare"
Diffstat (limited to 'media')
-rw-r--r-- | media/libstagefright/httplive/LiveSession.cpp | 67 | ||||
-rw-r--r-- | media/libstagefright/httplive/LiveSession.h | 2 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/AnotherPacketSource.cpp | 27 |
3 files changed, 63 insertions, 33 deletions
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index 26f8da1..74f58e9 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -1455,6 +1455,10 @@ void LiveSession::changeConfiguration( if (bandwidthIndex >= 0) { mOrigBandwidthIndex = mCurBandwidthIndex; mCurBandwidthIndex = bandwidthIndex; + if (mOrigBandwidthIndex != mCurBandwidthIndex) { + ALOGI("#### Starting Bandwidth Switch: %zd => %zd", + mOrigBandwidthIndex, mCurBandwidthIndex); + } } CHECK_LT(mCurBandwidthIndex, mBandwidthItems.size()); const BandwidthItem &item = mBandwidthItems.itemAt(mCurBandwidthIndex); @@ -1574,6 +1578,7 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) { if (timeUs >= 0) { mLastSeekTimeUs = timeUs; + mLastDequeuedTimeUs = timeUs; for (size_t i = 0; i < mPacketSources.size(); i++) { mPacketSources.editValueAt(i)->clear(); @@ -1626,8 +1631,10 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) { ALOGV("stream %zu changed: oldURI %s, newURI %s", i, mStreams[i].mUri.c_str(), URIs[i].c_str()); sp<AnotherPacketSource> source = mPacketSources.valueFor(indexToType(i)); - source->queueDiscontinuity( - ATSParser::DISCONTINUITY_FORMATCHANGE, NULL, true); + if (source->getLatestDequeuedMeta() != NULL) { + source->queueDiscontinuity( + ATSParser::DISCONTINUITY_FORMATCHANGE, NULL, true); + } } // Determine which decoders to shutdown on the player side, // a decoder has to be shutdown if its streamtype was active @@ -1687,10 +1694,6 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { // and resume audio. mSwapMask = mNewStreamMask & mStreamMask & ~resumeMask; switching = (mSwapMask != 0); - if (!switching) { - ALOGV("#### Finishing Bandwidth Switch Early: %zd => %zd", - mOrigBandwidthIndex, mCurBandwidthIndex); - } } mRealTimeBaseUs = ALooper::GetNowUs() - mLastDequeuedTimeUs; } else { @@ -1843,7 +1846,11 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) { mSwitchInProgress = true; } else { mStreamMask = mNewStreamMask; - mOrigBandwidthIndex = mCurBandwidthIndex; + if (mOrigBandwidthIndex != mCurBandwidthIndex) { + ALOGV("#### Finished Bandwidth Switch Early: %zd => %zd", + mOrigBandwidthIndex, mCurBandwidthIndex); + mOrigBandwidthIndex = mCurBandwidthIndex; + } } ALOGV("onChangeConfiguration3: mSwitchInProgress %d, mStreamMask 0x%x", @@ -1970,11 +1977,19 @@ void LiveSession::onPollBuffering() { bool underflow, ready, down, up; if (checkBuffering(underflow, ready, down, up)) { - if (mInPreparationPhase && ready) { - postPrepared(OK); + if (mInPreparationPhase) { + // Allow down switch even if we're still preparing. + // + // Some streams have a high bandwidth index as default, + // when bandwidth is low, it takes a long time to buffer + // to ready mark, then it immediately pauses after start + // as we have to do a down switch. It's better experience + // to restart from a lower index, if we detect low bw. + if (!switchBandwidthIfNeeded(false /* up */, down) && ready) { + postPrepared(OK); + } } - // don't switch before we report prepared if (!mInPreparationPhase) { if (ready) { stopBufferingIfNecessary(); @@ -1982,8 +1997,7 @@ void LiveSession::onPollBuffering() { startBufferingIfNecessary(); } switchBandwidthIfNeeded(up, down); - } - + } } schedulePollBuffering(); @@ -2075,7 +2089,8 @@ bool LiveSession::checkBuffering( if (mPacketSources[i]->isFinished(0 /* duration */)) { percent = 100; } else { - percent = (int32_t)(100.0 * (mLastDequeuedTimeUs + bufferedDurationUs) / durationUs); + percent = (int32_t)(100.0 * + (mLastDequeuedTimeUs + bufferedDurationUs) / durationUs); } if (minBufferPercent < 0 || percent < minBufferPercent) { minBufferPercent = percent; @@ -2158,10 +2173,14 @@ void LiveSession::notifyBufferingUpdate(int32_t percentage) { notify->post(); } -void LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) { +/* + * returns true if a bandwidth switch is actually needed (and started), + * returns false otherwise + */ +bool LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) { // no need to check bandwidth if we only have 1 bandwidth settings if (mSwitchInProgress || mBandwidthItems.size() < 2) { - return; + return false; } int32_t bandwidthBps; @@ -2170,7 +2189,7 @@ void LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) { mLastBandwidthBps = bandwidthBps; } else { ALOGV("no bandwidth estimate."); - return; + return false; } int32_t curBandwidth = mBandwidthItems.itemAt(mCurBandwidthIndex).mBandwidth; @@ -2189,16 +2208,16 @@ void LiveSession::switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow) { // bandwidthIndex is < mCurBandwidthIndex, as getBandwidthIndex() only uses 70% // of measured bw. In that case we don't want to do anything, since we have // both enough buffer and enough bw. - if (bandwidthIndex == mCurBandwidthIndex - || (canSwitchUp && bandwidthIndex < mCurBandwidthIndex) - || (canSwithDown && bandwidthIndex > mCurBandwidthIndex)) { - return; + if ((canSwitchUp && bandwidthIndex > mCurBandwidthIndex) + || (canSwithDown && bandwidthIndex < mCurBandwidthIndex)) { + // if not yet prepared, just restart again with new bw index. + // this is faster and playback experience is cleaner. + changeConfiguration( + mInPreparationPhase ? 0 : -1ll, bandwidthIndex); + return true; } - - ALOGI("#### Starting Bandwidth Switch: %zd => %zd", - mCurBandwidthIndex, bandwidthIndex); - changeConfiguration(-1, bandwidthIndex, false); } + return false; } void LiveSession::postError(status_t err) { diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h index c587f40..9117bb1 100644 --- a/media/libstagefright/httplive/LiveSession.h +++ b/media/libstagefright/httplive/LiveSession.h @@ -292,7 +292,7 @@ private: bool checkSwitchProgress( sp<AMessage> &msg, int64_t delayUs, bool *needResumeUntil); - void switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow); + bool switchBandwidthIfNeeded(bool bufferHigh, bool bufferLow); void schedulePollBuffering(); void cancelPollBuffering(); diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp index 0676a33..c7912c0 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp @@ -355,10 +355,15 @@ int64_t AnotherPacketSource::getBufferedDurationUs_l(status_t *finalResult) { int64_t time2 = -1; int64_t durationUs = 0; - List<sp<ABuffer> >::iterator it = mBuffers.begin(); - while (it != mBuffers.end()) { + List<sp<ABuffer> >::iterator it; + for (it = mBuffers.begin(); it != mBuffers.end(); it++) { const sp<ABuffer> &buffer = *it; + int32_t discard; + if (buffer->meta()->findInt32("discard", &discard) && discard) { + continue; + } + int64_t timeUs; if (buffer->meta()->findInt64("timeUs", &timeUs)) { if (time1 < 0 || timeUs < time1) { @@ -373,8 +378,6 @@ int64_t AnotherPacketSource::getBufferedDurationUs_l(status_t *finalResult) { durationUs += time2 - time1; time1 = time2 = -1; } - - ++it; } return durationUs + (time2 - time1); @@ -393,11 +396,19 @@ int64_t AnotherPacketSource::getEstimatedDurationUs() { return getBufferedDurationUs_l(&finalResult); } - List<sp<ABuffer> >::iterator it = mBuffers.begin(); - sp<ABuffer> buffer = *it; + sp<ABuffer> buffer; + int32_t discard; + int64_t startTimeUs = -1ll; + List<sp<ABuffer> >::iterator it; + for (it = mBuffers.begin(); it != mBuffers.end(); it++) { + buffer = *it; + if (buffer->meta()->findInt32("discard", &discard) && discard) { + continue; + } + buffer->meta()->findInt64("timeUs", &startTimeUs); + break; + } - int64_t startTimeUs; - buffer->meta()->findInt64("timeUs", &startTimeUs); if (startTimeUs < 0) { return 0; } |