notify seek complete upon first video output frame
Bug: 18541814
Change-Id: Ie4e0976885f26eb253460eab371cb181ea85f2db
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 405278c..c69f74b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -80,6 +80,21 @@
DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
};
+struct NuPlayer::ResumeDecoderAction : public Action {
+ ResumeDecoderAction(bool needNotify)
+ : mNeedNotify(needNotify) {
+ }
+
+ virtual void execute(NuPlayer *player) {
+ player->performResumeDecoders(mNeedNotify);
+ }
+
+private:
+ bool mNeedNotify;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
+};
+
struct NuPlayer::SetSurfaceAction : public Action {
SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
: mWrapper(wrapper) {
@@ -163,6 +178,7 @@
mTimedTextGeneration(0),
mFlushingAudio(NONE),
mFlushingVideo(NONE),
+ mResumePending(false),
mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
mStarted(false) {
clearFlushComplete();
@@ -553,11 +569,11 @@
new SimpleAction(&NuPlayer::performScanSources));
}
- // After a flush wihtout shutdown, decoder is paused.
- // Don't resume it until source is seeked, otherwise it could
+ // After a flush without shutdown, decoder is paused.
+ // Don't resume it until source seek is done, otherwise it could
// start pulling stale data too soon.
mDeferredActions.push_back(
- new SimpleAction(&NuPlayer::performResumeDecoders));
+ new ResumeDecoderAction(false /* needNotify */));
processDeferredActions();
break;
@@ -747,6 +763,8 @@
}
finishFlushIfPossible();
+ } else if (what == DecoderBase::kWhatResumeCompleted) {
+ finishResume();
} else if (what == DecoderBase::kWhatError) {
status_t err;
if (!msg->findInt32("err", &err) || err == OK) {
@@ -923,11 +941,11 @@
mDeferredActions.push_back(
new SeekAction(seekTimeUs, needNotify));
- // After a flush wihtout shutdown, decoder is paused.
- // Don't resume it until source is seeked, otherwise it could
+ // After a flush without shutdown, decoder is paused.
+ // Don't resume it until source seek is done, otherwise it could
// start pulling stale data too soon.
mDeferredActions.push_back(
- new SimpleAction(&NuPlayer::performResumeDecoders));
+ new ResumeDecoderAction(needNotify));
processDeferredActions();
break;
@@ -1499,15 +1517,6 @@
mSource->seekTo(seekTimeUs);
++mTimedTextGeneration;
- if (mDriver != NULL) {
- sp<NuPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- if (needNotify) {
- driver->notifySeekComplete();
- }
- }
- }
-
// everything's flushed, continue playback.
}
@@ -1593,13 +1602,39 @@
}
}
-void NuPlayer::performResumeDecoders() {
+void NuPlayer::performResumeDecoders(bool needNotify) {
+ if (needNotify) {
+ mResumePending = true;
+ if (mVideoDecoder == NULL) {
+ // if audio-only, we can notify seek complete now,
+ // as the resume operation will be relatively fast.
+ finishResume();
+ }
+ }
+
if (mVideoDecoder != NULL) {
- mVideoDecoder->signalResume();
+ // When there is continuous seek, MediaPlayer will cache the seek
+ // position, and send down new seek request when previous seek is
+ // complete. Let's wait for at least one video output frame before
+ // notifying seek complete, so that the video thumbnail gets updated
+ // when seekbar is dragged.
+ mVideoDecoder->signalResume(needNotify);
}
if (mAudioDecoder != NULL) {
- mAudioDecoder->signalResume();
+ mAudioDecoder->signalResume(false /* needNotify */);
+ }
+}
+
+void NuPlayer::finishResume() {
+ if (mResumePending) {
+ mResumePending = false;
+ if (mDriver != NULL) {
+ sp<NuPlayerDriver> driver = mDriver.promote();
+ if (driver != NULL) {
+ driver->notifySeekComplete();
+ }
+ }
}
}