Alternate patch for late video issue: seek only the video ahead to the next

syncframe after the current audio media position, leave audio untouched.

Change-Id: Ia9fa8e205467e5460c8219afd396bddd09fcfb46
related-to-bug: 3375737
This commit is contained in:
Andreas Huber
2011-02-24 12:05:40 -08:00
parent 7b76c8d3fc
commit a2c29973e3
2 changed files with 66 additions and 17 deletions

View File

@@ -48,7 +48,7 @@
#include <media/stagefright/foundation/AMessage.h>
#define USE_SURFACE_ALLOC 1
#define FRAME_DROP_FREQ 7
#define FRAME_DROP_FREQ 0
namespace android {
@@ -478,7 +478,7 @@ void AwesomePlayer::reset_l() {
mTimeSourceDeltaUs = 0;
mVideoTimeUs = 0;
mSeeking = false;
mSeeking = NO_SEEK;
mSeekNotificationSent = false;
mSeekTimeUs = 0;
@@ -1023,7 +1023,7 @@ status_t AwesomePlayer::getPosition(int64_t *positionUs) {
if (mRTSPController != NULL) {
*positionUs = mRTSPController->getNormalPlayTimeUs();
}
else if (mSeeking) {
else if (mSeeking != NO_SEEK) {
*positionUs = mSeekTimeUs;
} else if (mVideoSource != NULL) {
Mutex::Autolock autoLock(mMiscStateLock);
@@ -1067,7 +1067,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
play_l();
}
mSeeking = true;
mSeeking = SEEK;
mSeekNotificationSent = false;
mSeekTimeUs = timeUs;
mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS);
@@ -1091,7 +1091,7 @@ status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
}
void AwesomePlayer::seekAudioIfNecessary_l() {
if (mSeeking && mVideoSource == NULL && mAudioPlayer != NULL) {
if (mSeeking != NO_SEEK && mVideoSource == NULL && mAudioPlayer != NULL) {
mAudioPlayer->seekTo(mSeekTimeUs);
mWatchForAudioSeekComplete = true;
@@ -1187,7 +1187,12 @@ status_t AwesomePlayer::initVideoDecoder(uint32_t flags) {
}
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;
}
@@ -1206,7 +1211,7 @@ void AwesomePlayer::finishSeekIfNecessary(int64_t videoTimeUs) {
}
mFlags |= FIRST_FRAME;
mSeeking = false;
mSeeking = NO_SEEK;
mSeekNotificationSent = false;
if (mDecryptHandle != NULL) {
@@ -1226,13 +1231,13 @@ void AwesomePlayer::onVideoEvent() {
}
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.
@@ -1253,11 +1258,14 @@ void AwesomePlayer::onVideoEvent() {
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);
@@ -1281,7 +1289,7 @@ void AwesomePlayer::onVideoEvent() {
// 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);
@@ -1307,12 +1315,19 @@ void AwesomePlayer::onVideoEvent() {
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))) {
@@ -1337,13 +1352,41 @@ void AwesomePlayer::onVideoEvent() {
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);
@@ -1381,7 +1424,7 @@ void AwesomePlayer::onVideoEvent() {
mVideoBuffer->release();
mVideoBuffer = NULL;
if (wasSeeking && (mFlags & SEEK_PREVIEW)) {
if (wasSeeking != NO_SEEK && (mFlags & SEEK_PREVIEW)) {
mFlags &= ~SEEK_PREVIEW;
return;
}
@@ -1450,7 +1493,7 @@ void AwesomePlayer::onCheckAudioStatus() {
mSeekNotificationSent = true;
}
mSeeking = false;
mSeeking = NO_SEEK;
}
status_t finalStatus;

View File

@@ -163,7 +163,13 @@ private:
int64_t mTimeSourceDeltaUs;
int64_t mVideoTimeUs;
bool mSeeking;
enum SeekType {
NO_SEEK,
SEEK,
SEEK_VIDEO_ONLY
};
SeekType mSeeking;
bool mSeekNotificationSent;
int64_t mSeekTimeUs;