summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-05-17 14:18:50 -0700
committerAndreas Huber <andih@google.com>2012-05-17 14:18:50 -0700
commitbfd4d0d9fe0033abf3f55b94f30f6a58846a875e (patch)
tree9b8a16246cce7e86b6dcc4e5af147d264d4eb4b9
parentcd28dc10d49c359566c69d48a29a6f0d3eefa6d9 (diff)
downloadframeworks_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
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.cpp39
-rw-r--r--media/libmediaplayerservice/nuplayer/RTSPSource.h3
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.cpp34
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.h4
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);