diff options
author | Andreas Huber <andih@google.com> | 2012-05-17 14:18:50 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2012-05-17 14:18:50 -0700 |
commit | bfd4d0d9fe0033abf3f55b94f30f6a58846a875e (patch) | |
tree | 9b8a16246cce7e86b6dcc4e5af147d264d4eb4b9 | |
parent | cd28dc10d49c359566c69d48a29a6f0d3eefa6d9 (diff) | |
download | frameworks_av-bfd4d0d9fe0033abf3f55b94f30f6a58846a875e.zip frameworks_av-bfd4d0d9fe0033abf3f55b94f30f6a58846a875e.tar.gz frameworks_av-bfd4d0d9fe0033abf3f55b94f30f6a58846a875e.tar.bz2 |
Buffer at least 2 secs worth of data at startup of after a seek before
resuming starting RTSP playback.
Change-Id: I060c6c7fd627ab7ebd5c095ddcfdb4cc0f637aad
related-to-bug: 6364126
4 files changed, 80 insertions, 0 deletions
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index 4c65b65..a138be8 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -39,6 +39,7 @@ NuPlayer::RTSPSource::RTSPSource( mState(DISCONNECTED), mFinalResult(OK), mDisconnectReplyID(0), + mStartingUp(true), mSeekGeneration(0) { if (headers) { mExtraHeaders = *headers; @@ -104,8 +105,45 @@ sp<MetaData> NuPlayer::RTSPSource::getFormat(bool audio) { return source->getFormat(); } +bool NuPlayer::RTSPSource::haveSufficientDataOnAllTracks() { + // We're going to buffer at least 2 secs worth data on all tracks before + // starting playback (both at startup and after a seek). + + static const int64_t kMinDurationUs = 2000000ll; + + status_t err; + int64_t durationUs; + if (mAudioTrack != NULL + && (durationUs = mAudioTrack->getBufferedDurationUs(&err)) + < kMinDurationUs + && err == OK) { + ALOGV("audio track doesn't have enough data yet. (%.2f secs buffered)", + durationUs / 1E6); + return false; + } + + if (mVideoTrack != NULL + && (durationUs = mVideoTrack->getBufferedDurationUs(&err)) + < kMinDurationUs + && err == OK) { + ALOGV("video track doesn't have enough data yet. (%.2f secs buffered)", + durationUs / 1E6); + return false; + } + + return true; +} + status_t NuPlayer::RTSPSource::dequeueAccessUnit( bool audio, sp<ABuffer> *accessUnit) { + if (mStartingUp) { + if (!haveSufficientDataOnAllTracks()) { + return -EWOULDBLOCK; + } + + mStartingUp = false; + } + sp<AnotherPacketSource> source = getSource(audio); if (source == NULL) { @@ -209,6 +247,7 @@ void NuPlayer::RTSPSource::onMessageReceived(const sp<AMessage> &msg) { case MyHandler::kWhatSeekDone: { mState = CONNECTED; + mStartingUp = true; break; } diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index 59d06ad..e11e304 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -88,6 +88,7 @@ private: State mState; status_t mFinalResult; uint32_t mDisconnectReplyID; + bool mStartingUp; sp<ALooper> mLooper; sp<AHandlerReflector<RTSPSource> > mReflector; @@ -107,6 +108,8 @@ private: void performSeek(int64_t seekTimeUs); + bool haveSufficientDataOnAllTracks(); + DISALLOW_EVIL_CONSTRUCTORS(RTSPSource); }; diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp index d708ba6..a605a05 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp @@ -198,6 +198,40 @@ bool AnotherPacketSource::hasBufferAvailable(status_t *finalResult) { return false; } +int64_t AnotherPacketSource::getBufferedDurationUs(status_t *finalResult) { + Mutex::Autolock autoLock(mLock); + + *finalResult = mEOSResult; + + if (mBuffers.empty()) { + return 0; + } + + int64_t time1 = -1; + int64_t time2 = -1; + + List<sp<ABuffer> >::iterator it = mBuffers.begin(); + while (it != mBuffers.end()) { + const sp<ABuffer> &buffer = *it; + + int64_t timeUs; + if (buffer->meta()->findInt64("timeUs", &timeUs)) { + if (time1 < 0) { + time1 = timeUs; + } + + time2 = timeUs; + } else { + // This is a discontinuity, reset everything. + time1 = time2 = -1; + } + + ++it; + } + + return time2 - time1; +} + status_t AnotherPacketSource::nextBufferTime(int64_t *timeUs) { *timeUs = 0; diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h index c99f7f2..d685b98 100644 --- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h +++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h @@ -43,6 +43,10 @@ struct AnotherPacketSource : public MediaSource { bool hasBufferAvailable(status_t *finalResult); + // Returns the difference between the last and the first queued + // presentation timestamps since the last discontinuity (if any). + int64_t getBufferedDurationUs(status_t *finalResult); + status_t nextBufferTime(int64_t *timeUs); void queueAccessUnit(const sp<ABuffer> &buffer); |