diff options
-rw-r--r-- | include/media/AudioTrack.h | 1 | ||||
-rw-r--r-- | media/libavextensions/media/AVMediaExtensions.h | 4 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 15 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 51 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/NuPlayer.h | 2 |
5 files changed, 23 insertions, 50 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 42fa3be..191802d 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -943,6 +943,7 @@ protected: // a value of AUDIO_PORT_HANDLE_NONE indicated default (AudioPolicyManager) routing. audio_port_handle_t mSelectedDeviceId; bool mPlaybackRateSet; + bool mTrackOffloaded; private: class DeathNotifier : public IBinder::DeathRecipient { 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<MediaRecorder> 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 3a8dc07..0541f21 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -858,10 +858,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); } @@ -1174,6 +1173,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. @@ -2273,8 +2273,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. @@ -2286,7 +2286,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; diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 8064781..a494e87 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -1111,46 +1111,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &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; } @@ -2419,7 +2380,12 @@ void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) { TRESPASS(); } -void NuPlayer::tearDownPCMOffload(const sp<AMessage> &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<AMessage> &msg) { int32_t reason; CHECK(msg->findInt32("reason", &reason)); @@ -2443,13 +2409,14 @@ void NuPlayer::tearDownPCMOffload(const sp<AMessage> &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 1f4dec8..ee0f3e6 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -281,7 +281,7 @@ protected: void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const; - void tearDownPCMOffload(const sp<AMessage> &msg); + void performTearDown(const sp<AMessage> &msg); DISALLOW_EVIL_CONSTRUCTORS(NuPlayer); }; |