From 1a447be0cf1abc7564ae2afe7b4d2240c875de54 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 3 Dec 2012 11:18:00 -0800 Subject: setVideoSurfaceTexture is now synchronous and applied dynamically while playing. Change-Id: If9f08659a01bdc7dac0999730368e9dfa5e58d36 related-to-bug: 5666482 --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 77 +++++++++++++++++++--- media/libmediaplayerservice/nuplayer/NuPlayer.h | 8 ++- .../nuplayer/NuPlayerDriver.cpp | 22 ++++++- .../nuplayer/NuPlayerDriver.h | 2 + 4 files changed, 97 insertions(+), 12 deletions(-) (limited to 'media') diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index f363568..f9c3283 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -74,6 +74,21 @@ private: DISALLOW_EVIL_CONSTRUCTORS(SeekAction); }; +struct NuPlayer::SetSurfaceAction : public Action { + SetSurfaceAction(const sp &wrapper) + : mWrapper(wrapper) { + } + + virtual void execute(NuPlayer *player) { + player->performSetSurface(mWrapper); + } + +private: + sp mWrapper; + + DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction); +}; + // Use this if there's no state necessary to save in order to execute // the action. struct NuPlayer::SimpleAction : public Action { @@ -111,7 +126,8 @@ NuPlayer::NuPlayer() mVideoLateByUs(0ll), mNumFramesTotal(0ll), mNumFramesDropped(0ll), - mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW) { + mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), + mStarted(false) { } NuPlayer::~NuPlayer() { @@ -181,11 +197,19 @@ void NuPlayer::setDataSource(int fd, int64_t offset, int64_t length) { msg->post(); } -void NuPlayer::setVideoSurfaceTexture(const sp &surfaceTexture) { +void NuPlayer::setVideoSurfaceTextureAsync( + const sp &surfaceTexture) { sp msg = new AMessage(kWhatSetVideoNativeWindow, id()); - sp surfaceTextureClient(surfaceTexture != NULL ? - new SurfaceTextureClient(surfaceTexture) : NULL); - msg->setObject("native-window", new NativeWindowWrapper(surfaceTextureClient)); + + if (surfaceTexture == NULL) { + msg->setObject("native-window", NULL); + } else { + msg->setObject( + "native-window", + new NativeWindowWrapper( + new SurfaceTextureClient(surfaceTexture))); + } + msg->post(); } @@ -278,13 +302,24 @@ void NuPlayer::onMessageReceived(const sp &msg) { { ALOGV("kWhatSetVideoNativeWindow"); + mDeferredActions.push_back( + new SimpleAction(&NuPlayer::performDecoderShutdown)); + sp obj; CHECK(msg->findObject("native-window", &obj)); - mNativeWindow = static_cast(obj.get()); + mDeferredActions.push_back( + new SetSurfaceAction( + static_cast(obj.get()))); + + if (obj != NULL) { + // If there is a new surface texture, instantiate decoders + // again if possible. + mDeferredActions.push_back( + new SimpleAction(&NuPlayer::performScanSources)); + } - // XXX - ignore error from setVideoScalingMode for now - setVideoScalingMode(mVideoScalingMode); + processDeferredActions(); break; } @@ -311,6 +346,7 @@ void NuPlayer::onMessageReceived(const sp &msg) { mVideoLateByUs = 0; mNumFramesTotal = 0; mNumFramesDropped = 0; + mStarted = true; mSource->start(); @@ -986,8 +1022,7 @@ sp NuPlayer::Source::getFormat(bool audio) { status_t NuPlayer::setVideoScalingMode(int32_t mode) { mVideoScalingMode = mode; - if (mNativeWindow != NULL - && mNativeWindow->getNativeWindow() != NULL) { + if (mNativeWindow != NULL) { status_t ret = native_window_set_scaling_mode( mNativeWindow->getNativeWindow().get(), mVideoScalingMode); if (ret != OK) { @@ -1122,14 +1157,36 @@ void NuPlayer::performReset() { driver->notifyResetComplete(); } } + + mStarted = false; } void NuPlayer::performScanSources() { ALOGV("performScanSources"); + if (!mStarted) { + return; + } + if (mAudioDecoder == NULL || mVideoDecoder == NULL) { postScanSources(); } } +void NuPlayer::performSetSurface(const sp &wrapper) { + ALOGV("performSetSurface"); + + mNativeWindow = wrapper; + + // XXX - ignore error from setVideoScalingMode for now + setVideoScalingMode(mVideoScalingMode); + + if (mDriver != NULL) { + sp driver = mDriver.promote(); + if (driver != NULL) { + driver->notifySetSurfaceComplete(); + } + } +} + } // namespace android diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index 6e174e0..ca87be9 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -42,7 +42,9 @@ struct NuPlayer : public AHandler { void setDataSource(int fd, int64_t offset, int64_t length); - void setVideoSurfaceTexture(const sp &surfaceTexture); + void setVideoSurfaceTextureAsync( + const sp &surfaceTexture); + void setAudioSink(const sp &sink); void start(); @@ -75,6 +77,7 @@ private: struct StreamingSource; struct Action; struct SeekAction; + struct SetSurfaceAction; struct SimpleAction; enum { @@ -140,6 +143,8 @@ private: int32_t mVideoScalingMode; + bool mStarted; + status_t instantiateDecoder(bool audio, sp *decoder); status_t feedDecoderInputData(bool audio, const sp &msg); @@ -165,6 +170,7 @@ private: void performDecoderShutdown(); void performReset(); void performScanSources(); + void performSetSurface(const sp &wrapper); DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp index d03601f..a485dda 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp @@ -29,6 +29,7 @@ namespace android { NuPlayerDriver::NuPlayerDriver() : mResetInProgress(false), + mSetSurfaceInProgress(false), mDurationUs(-1), mPositionUs(-1), mNumFramesTotal(0), @@ -97,7 +98,19 @@ status_t NuPlayerDriver::setDataSource(const sp &source) { status_t NuPlayerDriver::setVideoSurfaceTexture( const sp &surfaceTexture) { - mPlayer->setVideoSurfaceTexture(surfaceTexture); + Mutex::Autolock autoLock(mLock); + + if (mResetInProgress) { + return INVALID_OPERATION; + } + + mSetSurfaceInProgress = true; + + mPlayer->setVideoSurfaceTextureAsync(surfaceTexture); + + while (mSetSurfaceInProgress) { + mCondition.wait(mLock); + } return OK; } @@ -308,6 +321,13 @@ void NuPlayerDriver::notifyResetComplete() { mCondition.broadcast(); } +void NuPlayerDriver::notifySetSurfaceComplete() { + Mutex::Autolock autoLock(mLock); + CHECK(mSetSurfaceInProgress); + mSetSurfaceInProgress = false; + mCondition.broadcast(); +} + void NuPlayerDriver::notifyDuration(int64_t durationUs) { Mutex::Autolock autoLock(mLock); mDurationUs = durationUs; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h index 4a0026c..d551bf1 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h @@ -62,6 +62,7 @@ struct NuPlayerDriver : public MediaPlayerInterface { virtual status_t dump(int fd, const Vector &args) const; void notifyResetComplete(); + void notifySetSurfaceComplete(); void notifyDuration(int64_t durationUs); void notifyPosition(int64_t positionUs); void notifySeekComplete(); @@ -78,6 +79,7 @@ private: // The following are protected through "mLock" // >>> bool mResetInProgress; + bool mSetSurfaceInProgress; int64_t mDurationUs; int64_t mPositionUs; int64_t mNumFramesTotal; -- cgit v1.1