From 3a785fe0799319004c234c9d259d1f9b74ca1214 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Mon, 14 Mar 2011 10:55:40 -0700 Subject: [PATCH] Experimental support for changing the video surface/texture on an active mediaplayer Change-Id: Ia7a5126e9311dc1c721ab2aef54bd698151c88cd --- media/libstagefright/AwesomePlayer.cpp | 75 +++++++++++++++----- media/libstagefright/include/AwesomePlayer.h | 5 ++ 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 0de19883f56b7..93d89c904a2a0 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -181,7 +181,8 @@ AwesomePlayer::AwesomePlayer() mFlags(0), mExtractorFlags(0), mVideoBuffer(NULL), - mDecryptHandle(NULL) { + mDecryptHandle(NULL), + mLastVideoTimeUs(-1) { CHECK_EQ(mClient.connect(), (status_t)OK); DataSource::RegisterDefaultSniffers(); @@ -467,28 +468,13 @@ void AwesomePlayer::reset_l() { mVideoRenderer.clear(); - if (mVideoBuffer) { - mVideoBuffer->release(); - mVideoBuffer = NULL; - } - if (mRTSPController != NULL) { mRTSPController->disconnect(); mRTSPController.clear(); } if (mVideoSource != NULL) { - mVideoSource->stop(); - - // The following hack is necessary to ensure that the OMX - // component is completely released by the time we may try - // to instantiate it again. - wp tmp = mVideoSource; - mVideoSource.clear(); - while (tmp.promote() != NULL) { - usleep(1000); - } - IPCThreadState::self()->flushCommands(); + shutdownVideoDecoder_l(); } mDurationUs = -1; @@ -507,6 +493,7 @@ void AwesomePlayer::reset_l() { mFileSource.clear(); mBitrate = -1; + mLastVideoTimeUs = -1; } void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) { @@ -1005,7 +992,7 @@ void AwesomePlayer::setSurface(const sp &surface) { Mutex::Autolock autoLock(mLock); mSurface = surface; - mNativeWindow = surface; + setNativeWindow_l(surface); } void AwesomePlayer::setSurfaceTexture(const sp &surfaceTexture) { @@ -1013,9 +1000,57 @@ void AwesomePlayer::setSurfaceTexture(const sp &surfaceTexture) mSurface.clear(); if (surfaceTexture != NULL) { - mNativeWindow = new SurfaceTextureClient(surfaceTexture); + setNativeWindow_l(new SurfaceTextureClient(surfaceTexture)); + } +} + +void AwesomePlayer::shutdownVideoDecoder_l() { + if (mVideoBuffer) { + mVideoBuffer->release(); + mVideoBuffer = NULL; } + mVideoSource->stop(); + + // The following hack is necessary to ensure that the OMX + // component is completely released by the time we may try + // to instantiate it again. + wp tmp = mVideoSource; + mVideoSource.clear(); + while (tmp.promote() != NULL) { + usleep(1000); + } + IPCThreadState::self()->flushCommands(); +} + +void AwesomePlayer::setNativeWindow_l(const sp &native) { + mNativeWindow = native; + + if (mVideoSource == NULL) { + return; + } + + LOGI("attempting to reconfigure to use new surface"); + + bool wasPlaying = (mFlags & PLAYING) != 0; + + pause_l(); + mVideoRenderer.clear(); + + shutdownVideoDecoder_l(); + + CHECK_EQ(initVideoDecoder(), (status_t)OK); + + if (mLastVideoTimeUs >= 0) { + mSeeking = SEEK; + mSeekNotificationSent = true; + mSeekTimeUs = mLastVideoTimeUs; + mFlags &= ~(AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS); + } + + if (wasPlaying) { + play_l(); + } } void AwesomePlayer::setAudioSink( @@ -1358,6 +1393,8 @@ void AwesomePlayer::onVideoEvent() { int64_t timeUs; CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs)); + mLastVideoTimeUs = timeUs; + if (mSeeking == SEEK_VIDEO_ONLY) { if (mSeekTimeUs > timeUs) { LOGI("XXX mSeekTimeUs = %lld us, timeUs = %lld us", diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index b26f2028eda4b..4e7712b088ee5 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -219,6 +219,8 @@ private: DrmManagerClient *mDrmManagerClient; sp mDecryptHandle; + int64_t mLastVideoTimeUs; + status_t setDataSource_l( const char *uri, const KeyedVector *headers = NULL); @@ -268,6 +270,9 @@ private: status_t startAudioPlayer_l(); + void shutdownVideoDecoder_l(); + void setNativeWindow_l(const sp &native); + AwesomePlayer(const AwesomePlayer &); AwesomePlayer &operator=(const AwesomePlayer &); };