summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorChong Zhang <chz@google.com>2014-12-02 00:13:35 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-12-02 00:13:36 +0000
commitd8731629bed46ff573b1ef904e5366d28f23dc0a (patch)
treef3c869ddad9bb2fa62fb54d1b07aefd8d8a39e6c /media
parentf20c4356931ef72084b6b8e310f56b67715c6fb9 (diff)
parentf8d717772f6d185cb07720cd5091df9b7d612e0b (diff)
downloadframeworks_av-d8731629bed46ff573b1ef904e5366d28f23dc0a.zip
frameworks_av-d8731629bed46ff573b1ef904e5366d28f23dc0a.tar.gz
frameworks_av-d8731629bed46ff573b1ef904e5366d28f23dc0a.tar.bz2
Merge "notify seek complete upon first video output frame" into lmp-mr1-dev
Diffstat (limited to 'media')
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp71
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h8
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp25
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp11
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp8
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h2
8 files changed, 107 insertions, 28 deletions
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 @@ private:
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 @@ NuPlayer::NuPlayer()
mTimedTextGeneration(0),
mFlushingAudio(NONE),
mFlushingVideo(NONE),
+ mResumePending(false),
mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
mStarted(false) {
clearFlushComplete();
@@ -553,11 +569,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
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 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
}
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 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
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 @@ void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
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::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
}
}
-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();
+ }
+ }
}
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 6856af1..6be38a4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -93,6 +93,7 @@ private:
struct Action;
struct SeekAction;
struct SetSurfaceAction;
+ struct ResumeDecoderAction;
struct FlushDecoderAction;
struct PostMessageAction;
struct SimpleAction;
@@ -169,6 +170,9 @@ private:
FlushStatus mFlushingAudio;
FlushStatus mFlushingVideo;
+ // Status of flush responses from the decoder and renderer.
+ bool mResumePending;
+
int32_t mVideoScalingMode;
bool mStarted;
@@ -205,6 +209,8 @@ private:
void flushDecoder(bool audio, bool needShutdown);
+ void finishResume();
+
void postScanSources();
void schedulePollDuration();
@@ -217,7 +223,7 @@ private:
void performReset();
void performScanSources();
void performSetSurface(const sp<NativeWindowWrapper> &wrapper);
- void performResumeDecoders();
+ void performResumeDecoders(bool needNotify);
void onSourceNotify(const sp<AMessage> &msg);
void onClosedCaptionNotify(const sp<AMessage> &msg);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 0439a9a..012d33e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -58,6 +58,7 @@ NuPlayer::Decoder::Decoder(
mFormatChangePending(false),
mBufferGeneration(0),
mPaused(true),
+ mResumePending(false),
mComponentName("decoder") {
mCodecLooper = new ALooper;
mCodecLooper->setName("NPDecoder-CL");
@@ -208,6 +209,7 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
requestCodecNotification();
}
mPaused = false;
+ mResumePending = false;
}
void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
@@ -226,8 +228,12 @@ void NuPlayer::Decoder::onGetInputBuffers(
}
}
-void NuPlayer::Decoder::onResume() {
+void NuPlayer::Decoder::onResume(bool notifyComplete) {
mPaused = false;
+
+ if (notifyComplete) {
+ mResumePending = true;
+ }
}
void NuPlayer::Decoder::onFlush(bool notifyComplete) {
@@ -265,6 +271,10 @@ void NuPlayer::Decoder::onFlush(bool notifyComplete) {
void NuPlayer::Decoder::onShutdown(bool notifyComplete) {
status_t err = OK;
+
+ // if there is a pending resume request, notify complete now
+ notifyResumeCompleteIfNecessary();
+
if (mCodec != NULL) {
err = mCodec->release();
mCodec = NULL;
@@ -494,6 +504,9 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
mSkipRenderingUntilMediaTimeUs = -1;
}
+ // wait until 1st frame comes out to signal resume complete
+ notifyResumeCompleteIfNecessary();
+
if (mRenderer != NULL) {
// send the buffer to renderer.
mRenderer->queueBuffer(mIsAudio, buffer, reply);
@@ -884,5 +897,15 @@ void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
}
}
+void NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
+ if (mResumePending) {
+ mResumePending = false;
+
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatResumeCompleted);
+ notify->post();
+ }
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 07401b0..2c08f0d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -42,7 +42,7 @@ protected:
virtual void onConfigure(const sp<AMessage> &format);
virtual void onSetRenderer(const sp<Renderer> &renderer);
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
- virtual void onResume();
+ virtual void onResume(bool notifyComplete);
virtual void onFlush(bool notifyComplete);
virtual void onShutdown(bool notifyComplete);
virtual void doRequestBuffers();
@@ -85,6 +85,7 @@ private:
int32_t mBufferGeneration;
bool mPaused;
+ bool mResumePending;
AString mComponentName;
void handleError(int32_t err);
@@ -103,6 +104,8 @@ private:
bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const;
void rememberCodecSpecificData(const sp<AMessage> &format);
+ void notifyResumeCompleteIfNecessary();
+
DISALLOW_EVIL_CONSTRUCTORS(Decoder);
};
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
index 6941f77..4164350 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
@@ -86,8 +86,10 @@ void NuPlayer::DecoderBase::signalFlush() {
(new AMessage(kWhatFlush, id()))->post();
}
-void NuPlayer::DecoderBase::signalResume() {
- (new AMessage(kWhatResume, id()))->post();
+void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
+ sp<AMessage> msg = new AMessage(kWhatResume, id());
+ msg->setInt32("notifyComplete", notifyComplete);
+ msg->post();
}
void NuPlayer::DecoderBase::initiateShutdown() {
@@ -159,7 +161,10 @@ void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
case kWhatResume:
{
- onResume();
+ int32_t notifyComplete;
+ CHECK(msg->findInt32("notifyComplete", &notifyComplete));
+
+ onResume(notifyComplete);
break;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
index 1b24c4f..5feb6a1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
@@ -38,7 +38,7 @@ struct NuPlayer::DecoderBase : public AHandler {
status_t getInputBuffers(Vector<sp<ABuffer> > *dstBuffers) const;
void signalFlush();
- void signalResume();
+ void signalResume(bool notifyComplete);
void initiateShutdown();
virtual void getStats(
@@ -50,6 +50,7 @@ struct NuPlayer::DecoderBase : public AHandler {
kWhatVideoSizeChanged = 'viSC',
kWhatFlushCompleted = 'flsC',
kWhatShutdownCompleted = 'shDC',
+ kWhatResumeCompleted = 'resC',
kWhatEOS = 'eos ',
kWhatError = 'err ',
};
@@ -63,7 +64,7 @@ protected:
virtual void onConfigure(const sp<AMessage> &format) = 0;
virtual void onSetRenderer(const sp<Renderer> &renderer) = 0;
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers) = 0;
- virtual void onResume() = 0;
+ virtual void onResume(bool notifyComplete) = 0;
virtual void onFlush(bool notifyComplete) = 0;
virtual void onShutdown(bool notifyComplete) = 0;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index 3b4c0a7..8112e9f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -354,8 +354,14 @@ void NuPlayer::DecoderPassThrough::onBufferConsumed(int32_t size) {
onRequestInputBuffers();
}
-void NuPlayer::DecoderPassThrough::onResume() {
+void NuPlayer::DecoderPassThrough::onResume(bool notifyComplete) {
onRequestInputBuffers();
+
+ if (notifyComplete) {
+ sp<AMessage> notify = mNotify->dup();
+ notify->setInt32("what", kWhatResumeCompleted);
+ notify->post();
+ }
}
void NuPlayer::DecoderPassThrough::onFlush(bool notifyComplete) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
index 3fe32b6..d761b07 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
@@ -42,7 +42,7 @@ protected:
virtual void onConfigure(const sp<AMessage> &format);
virtual void onSetRenderer(const sp<Renderer> &renderer);
virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
- virtual void onResume();
+ virtual void onResume(bool notifyComplete);
virtual void onFlush(bool notifyComplete);
virtual void onShutdown(bool notifyComplete);
virtual void doRequestBuffers();