Merge "Alternate patch for late video issue: seek only the video ahead to the next"
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index bcf5a12..4c744bd 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -50,7 +50,7 @@
#include <media/stagefright/foundation/AMessage.h>
#define USE_SURFACE_ALLOC 1
-#define FRAME_DROP_FREQ 7
+#define FRAME_DROP_FREQ 0
namespace android {
@@ -496,7 +496,7 @@
mTimeSourceDeltaUs = 0;
mVideoTimeUs = 0;
- mSeeking = false;
+ mSeeking = NO_SEEK;
mSeekNotificationSent = false;
mSeekTimeUs = 0;
@@ -1052,7 +1052,7 @@
if (mRTSPController != NULL) {
*positionUs = mRTSPController->getNormalPlayTimeUs();
}
- else if (mSeeking) {
+ else if (mSeeking != NO_SEEK) {
*positionUs = mSeekTimeUs;
} else if (mVideoSource != NULL) {
Mutex::Autolock autoLock(mMiscStateLock);
@@ -1096,7 +1096,7 @@
play_l();
}
- mSeeking = true;
+ mSeeking = SEEK;
mSeekNotificationSent = false;
mSeekTimeUs = timeUs;
mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
@@ -1120,7 +1120,7 @@
}
void AwesomePlayer::seekAudioIfNecessary_l() {
- if (mSeeking && mVideoSource == NULL && mAudioPlayer != NULL) {
+ if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
mAudioPlayer->seekTo(mSeekTimeUs);
mWatchForAudioSeekComplete = true;
@@ -1216,7 +1216,12 @@
}
void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
- if (!mSeeking || (mFlags & SEEK_PREVIEW)) {
+ if (mSeeking == SEEK_VIDEO_ONLY) {
+ mSeeking = NO_SEEK;
+ return;
+ }
+
+ if (mSeeking == NO_SEEK || (mFlags & SEEK_PREVIEW)) {
return;
}
@@ -1235,7 +1240,7 @@
}
mFlags |= FIRST_FRAME;
- mSeeking = false;
+ mSeeking = NO_SEEK;
mSeekNotificationSent = false;
if (mDecryptHandle != NULL) {
@@ -1255,13 +1260,13 @@
}
mVideoEventPending = false;
- if (mSeeking) {
+ if (mSeeking != NO_SEEK) {
if (mVideoBuffer) {
mVideoBuffer->release();
mVideoBuffer = NULL;
}
- if (mCachedSource != NULL && mAudioSource != NULL
+ if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
&& !(mFlags & SEEK_PREVIEW)) {
// We're going to seek the video source first, followed by
// the audio source.
@@ -1282,11 +1287,14 @@
if (!mVideoBuffer) {
MediaSource::ReadOptions options;
- if (mSeeking) {
+ if (mSeeking != NO_SEEK) {
LOGV("seeking to %lld us (%.2f secs)", mSeekTimeUs, mSeekTimeUs / 1E6);
options.setSeekTo(
- mSeekTimeUs, MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
+ mSeekTimeUs,
+ mSeeking == SEEK_VIDEO_ONLY
+ ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
+ : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
}
for (;;) {
status_t err = mVideoSource->read(&mVideoBuffer, &options);
@@ -1310,7 +1318,7 @@
// So video playback is complete, but we may still have
// a seek request pending that needs to be applied
// to the audio track.
- if (mSeeking) {
+ if (mSeeking != NO_SEEK) {
LOGV("video stream ended while seeking!");
}
finishSeekIfNecessary(-1);
@@ -1336,12 +1344,19 @@
int64_t timeUs;
CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
+ if (mSeeking == SEEK_VIDEO_ONLY) {
+ if (mSeekTimeUs > timeUs) {
+ LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us",
+ mSeekTimeUs, timeUs);
+ }
+ }
+
{
Mutex::Autolock autoLock(mMiscStateLock);
mVideoTimeUs = timeUs;
}
- bool wasSeeking = mSeeking;
+ SeekType wasSeeking = mSeeking;
finishSeekIfNecessary(timeUs);
if (mAudioPlayer != NULL && !(mFlags & (AUDIO_RUNNING | SEEK_PREVIEW))) {
@@ -1366,13 +1381,41 @@
mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
}
- if (!wasSeeking) {
+ if (wasSeeking == SEEK_VIDEO_ONLY) {
+ int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
+
+ int64_t latenessUs = nowUs - timeUs;
+
+ if (latenessUs > 0) {
+ LOGI("after SEEK_VIDEO_ONLY we're late by %.2f secs", latenessUs / 1E6);
+ }
+ }
+
+ if (wasSeeking == NO_SEEK) {
// Let's display the first frame after seeking right away.
int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
int64_t latenessUs = nowUs - timeUs;
+ if (latenessUs > 500000ll
+ && mRTSPController == NULL
+ && mAudioPlayer != NULL
+ && mAudioPlayer->getMediaTimeMapping(
+ &realTimeUs, &mediaTimeUs)) {
+ LOGI("we're much too late (%.2f secs), video skipping ahead",
+ latenessUs / 1E6);
+
+ mVideoBuffer->release();
+ mVideoBuffer = NULL;
+
+ mSeeking = SEEK_VIDEO_ONLY;
+ mSeekTimeUs = mediaTimeUs;
+
+ postVideoEvent_l();
+ return;
+ }
+
if (latenessUs > 40000) {
// We're more than 40ms late.
LOGV("we're late by %lld us (%.2f secs)", latenessUs, latenessUs / 1E6);
@@ -1410,7 +1453,7 @@
mVideoBuffer->release();
mVideoBuffer = NULL;
- if (wasSeeking && (mFlags & SEEK_PREVIEW)) {
+ if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
mFlags &= ~SEEK_PREVIEW;
return;
}
@@ -1479,7 +1522,7 @@
mSeekNotificationSent = true;
}
- mSeeking = false;
+ mSeeking = NO_SEEK;
}
status_t finalStatus;
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 5824b6c..4e6f75c 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -168,7 +168,13 @@
int64_t mTimeSourceDeltaUs;
int64_t mVideoTimeUs;
- bool mSeeking;
+ enum SeekType {
+ NO_SEEK,
+ SEEK,
+ SEEK_VIDEO_ONLY
+ };
+ SeekType mSeeking;
+
bool mSeekNotificationSent;
int64_t mSeekTimeUs;