status_t AudioOffloadPlayer::Play() { MOZ_ASSERT(NS_IsMainThread()); if (mResetTimer) { mResetTimer->Cancel(); mResetTimer = nullptr; WakeLockRelease(); } status_t err = OK; if (!mStarted) { // Last pause timed out and offloaded audio sink was reset. Start it again err = Start(false); if (err != OK) { return err; } // Seek to last play position only when there was no seek during last pause if (!mSeeking) { SeekTo(mPositionTimeMediaUs); } } if (!mPlaying) { CHECK(mAudioSink.get()); err = mAudioSink->Start(); if (err == OK) { mPlaying = true; } } return err; }
void AudioOffloadPlayer::Reset() { MOZ_ASSERT(NS_IsMainThread()); if (!mStarted) { return; } CHECK(mAudioSink.get()); AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("reset: mPlaying=%d mReachedEOS=%d", mPlaying, mReachedEOS)); mAudioSink->Stop(); // If we're closing and have reached EOS, we don't want to flush // the track because if it is offloaded there could be a small // amount of residual data in the hardware buffer which we must // play to give gapless playback. // But if we're resetting when paused or before we've reached EOS // we can't be doing a gapless playback and there could be a large // amount of data queued in the hardware if the track is offloaded, // so we must flush to prevent a track switch being delayed playing // the buffered data that we don't want now if (!mPlaying || !mReachedEOS) { mAudioSink->Flush(); } mAudioSink->Close(); // Make sure to release any buffer we hold onto so that the // source is able to stop(). if (mInputBuffer) { AUDIO_OFFLOAD_LOG(PR_LOG_DEBUG, ("Releasing input buffer")); mInputBuffer->release(); mInputBuffer = nullptr; } mSource->stop(); IPCThreadState::self()->flushCommands(); StopTimeUpdate(); mReachedEOS = false; mStarted = false; mPlaying = false; mStartPosUs = 0; WakeLockRelease(); }
status_t AudioOffloadPlayer::Play() { MOZ_ASSERT(NS_IsMainThread()); if (mResetTimer) { mResetTimer->Cancel(); mResetTimer = nullptr; WakeLockRelease(); } status_t err = OK; if (!mStarted) { // Last pause timed out and offloaded audio sink was reset. Start it again err = Start(false); if (err != OK) { return err; } // Seek to last play position only when there was no seek during last pause android::Mutex::Autolock autoLock(mLock); if (!mSeekTarget.IsValid()) { mSeekTarget = SeekTarget(mPositionTimeMediaUs, SeekTarget::Accurate, MediaDecoderEventVisibility::Suppressed); DoSeek(); } } if (!mPlaying) { CHECK(mAudioSink.get()); err = mAudioSink->Start(); if (err == OK) { mPlaying = true; } } return err; }