From 6ab73dcdc410e873a585af3a0e0ffd1551c06f2e Mon Sep 17 00:00:00 2001 From: Ronghua Wu Date: Wed, 7 Oct 2015 16:52:19 -0700 Subject: nuplayer: don't resume if player is reseting. cherry-pick of AOSP commit b75de9d4ba6725104342b5376a1047ff1c9b2765 Bug: 24712426 Change-Id: I58cca0bde708a5c3b073ed77e18b62fe81d6c017 --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 7 ++++++- media/libmediaplayerservice/nuplayer/NuPlayer.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'media') diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index ec1ab79..1b31f19 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -206,6 +206,7 @@ NuPlayer::NuPlayer(pid_t pid) mPlaybackSettings(AUDIO_PLAYBACK_RATE_DEFAULT), mVideoFpsHint(-1.f), mStarted(false), + mResetting(false), mSourceStarted(false), mPaused(false), mPausedByClient(false), @@ -1163,6 +1164,8 @@ void NuPlayer::onMessageReceived(const sp &msg) { { ALOGV("kWhatReset"); + mResetting = true; + mDeferredActions.push_back( new FlushDecoderAction( FLUSH_CMD_SHUTDOWN /* audio */, @@ -1248,7 +1251,8 @@ void NuPlayer::onMessageReceived(const sp &msg) { } void NuPlayer::onResume() { - if (!mPaused) { + if (!mPaused || mResetting) { + ALOGD_IF(mResetting, "resetting, onResume discarded"); return; } mPaused = false; @@ -1969,6 +1973,7 @@ void NuPlayer::performReset() { } mStarted = false; + mResetting = false; mSourceStarted = false; } diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index c0aa782..32a3efe 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -202,6 +202,7 @@ protected: AVSyncSettings mSyncSettings; float mVideoFpsHint; bool mStarted; + bool mResetting; bool mSourceStarted; // Actual pause state, either as requested by client or due to buffering. -- cgit v1.1 From 767254cd47bbcaa5ad9e09a6f0bae4a703fbdf7e Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Wed, 4 Nov 2015 19:40:55 -0800 Subject: nuplayer: Perform proper shutdown sequence for offload teardown Extend shutdown sequence used for pcm offload to compress offload as well. The current tear down sequence for compress offload calls clear on the NuPlayerDecoderPassthrough object directly. This is not guaranteed to prevent an encoded buffer from getting queued into the Renderer. Going through a proper flush+shutdown sequence helps prevent this (rare) scenario. CRs-Fixed: 914308 Change-Id: Ie2040cbbd42b8c67bb53a7ef8a628faf1ab7acda --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 51 ++++------------------- media/libmediaplayerservice/nuplayer/NuPlayer.h | 2 +- 2 files changed, 10 insertions(+), 43 deletions(-) (limited to 'media') diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index ec1ab79..b2f86ce 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1110,46 +1110,7 @@ void NuPlayer::onMessageReceived(const sp &msg) { int32_t reason; CHECK(msg->findInt32("reason", &reason)); ALOGV("Tear down audio with reason %d.", reason); - - if (ifDecodedPCMOffload()) { - tearDownPCMOffload(msg); - break; - } - - mAudioDecoder.clear(); - ++mAudioDecoderGeneration; - bool needsToCreateAudioDecoder = true; - if (mFlushingAudio == FLUSHING_DECODER) { - mFlushComplete[1 /* audio */][1 /* isDecoder */] = true; - mFlushingAudio = FLUSHED; - finishFlushIfPossible(); - } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN - || mFlushingAudio == SHUTTING_DOWN_DECODER) { - mFlushComplete[1 /* audio */][1 /* isDecoder */] = true; - mFlushingAudio = SHUT_DOWN; - finishFlushIfPossible(); - needsToCreateAudioDecoder = false; - } - if (mRenderer == NULL) { - break; - } - closeAudioSink(); - mRenderer->flush( - true /* audio */, false /* notifyComplete */); - if (mVideoDecoder != NULL) { - mRenderer->flush( - false /* audio */, false /* notifyComplete */); - } - - int64_t positionUs; - if (!msg->findInt64("positionUs", &positionUs)) { - positionUs = mPreviousSeekTimeUs; - } - performSeek(positionUs); - - if (reason == Renderer::kDueToError && needsToCreateAudioDecoder) { - instantiateDecoder(true /* audio */, &mAudioDecoder); - } + performTearDown(msg); } break; } @@ -2414,7 +2375,12 @@ void NuPlayer::Source::onMessageReceived(const sp & /* msg */) { TRESPASS(); } -void NuPlayer::tearDownPCMOffload(const sp &msg) { +// +// There is a flush from within the decoder's onFlush handling. +// Without it, it is still possible that a buffer can be queueued +// after NuPlayer issues a flush on the renderer's audio queue. +// +void NuPlayer::performTearDown(const sp &msg) { int32_t reason; CHECK(msg->findInt32("reason", &reason)); @@ -2438,13 +2404,14 @@ void NuPlayer::tearDownPCMOffload(const sp &msg) { mDeferredActions.push_back(new SeekAction(positionUs)); break; default: - ALOGW("tearDownPCMOffload while flushing audio in %d", mFlushingAudio); + ALOGW("performTearDown while flushing audio in %d", mFlushingAudio); break; } } if (mRenderer != NULL) { closeAudioSink(); + // see comment at beginning of function mRenderer->flush( true /* audio */, false /* notifyComplete */); if (mVideoDecoder != NULL) { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index c0aa782..a939d23 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -280,7 +280,7 @@ protected: void writeTrackInfo(Parcel* reply, const sp format) const; - void tearDownPCMOffload(const sp &msg); + void performTearDown(const sp &msg); DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; -- cgit v1.1 From dfbec4717a42eb5f231799589ddd593af9ab3ec1 Mon Sep 17 00:00:00 2001 From: Alexy Joseph Date: Sun, 15 Nov 2015 23:52:02 -0800 Subject: AudioTrack: Handle timestamp queries for Track Offload Handle timestamp queries for Track offload session cleanly Change-Id: I93759c0e186e4286037837787057960ee52875d7 CRs-Fixed: 933740 --- media/libavextensions/media/AVMediaExtensions.h | 4 ++++ media/libmedia/AudioTrack.cpp | 15 ++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'media') diff --git a/media/libavextensions/media/AVMediaExtensions.h b/media/libavextensions/media/AVMediaExtensions.h index ae26143..9161fae 100644 --- a/media/libavextensions/media/AVMediaExtensions.h +++ b/media/libavextensions/media/AVMediaExtensions.h @@ -60,6 +60,10 @@ struct AVMediaUtils { return frameCount; } + virtual bool AudioTrackIsTrackOffloaded(audio_io_handle_t /*output*/) { + return false; + } + virtual sp createMediaRecorder(const String16& opPackageName); virtual void writeCustomData( Parcel * /* reply */, void * /* buffer_data */) {} diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 22c66db..3d9847c 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -849,10 +849,9 @@ status_t AudioTrack::setPlaybackRate(const AudioPlaybackRate &playbackRate) mProxy->setPlaybackRate(playbackRateTemp); mProxy->setSampleRate(effectiveRate); // FIXME: not quite "atomic" with setPlaybackRate - // fallback out of Direct PCM if setPlaybackRate is called on PCM track - if (property_get_bool("audio.offload.track.enable", false) && - (mFormat == AUDIO_FORMAT_PCM_16_BIT) && (mOffloadInfo == NULL) && - (mFlags == AUDIO_OUTPUT_FLAG_NONE)) { + // fallback out of Direct PCM if setPlaybackRate is called on a track offloaded + // session. Do this by setting mPlaybackRateSet to true + if (mTrackOffloaded) { mPlaybackRateSet = true; android_atomic_or(CBLK_INVALID, &mCblk->mFlags); } @@ -1165,6 +1164,7 @@ status_t AudioTrack::createTrack_l() mSessionId, streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags); return BAD_VALUE; } + mTrackOffloaded = AVMediaUtils::get()->AudioTrackIsTrackOffloaded(output); { // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger, // we must release it ourselves if anything goes wrong. @@ -2264,8 +2264,8 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) } status_t status = UNKNOWN_ERROR; - //do not call Timestamp if its PCM offloaded - if (!AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat)) { + //call Timestamp only if its NOT PCM offloaded and NOT Track Offloaded + if (!AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat) && !mTrackOffloaded) { // The presented frame count must always lag behind the consumed frame count. // To avoid a race, read the presented frames first. This ensures that presented <= consumed. @@ -2277,7 +2277,8 @@ status_t AudioTrack::getTimestamp(AudioTimestamp& timestamp) } - if (isOffloadedOrDirect_l() && !AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat)) { + if (isOffloadedOrDirect_l() && !AVMediaUtils::get()->AudioTrackIsPcmOffloaded(mFormat) + && !mTrackOffloaded) { if (isOffloaded_l() && (mState == STATE_PAUSED || mState == STATE_PAUSED_STOPPING)) { // use cached paused position in case another offloaded track is running. timestamp.mPosition = mPausedPosition; -- cgit v1.1