From b04aa975bec77198a37ca6facc2134f74d66d5df Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 28 Jul 2015 14:36:49 -0400 Subject: [PATCH] Backed out 5 changesets (bug 1187817) for making test_mediatrack_consuming_mediaresource.html extremely failure-prone on B2G. a=me Backed out changeset ae2e2dda1eec (bug 1187817) Backed out changeset 74386997e5fb (bug 1187817) Backed out changeset d31a0c93969f (bug 1187817) Backed out changeset cf38bd59eb44 (bug 1187817) Backed out changeset 264dad192c22 (bug 1187817) --- dom/media/AudioSink.cpp | 160 ++++++++++++++++++++++------------------ dom/media/AudioSink.h | 10 +++ 2 files changed, 99 insertions(+), 71 deletions(-) diff --git a/dom/media/AudioSink.cpp b/dom/media/AudioSink.cpp index 8be1516efc8c..1127d8bbae29 100644 --- a/dom/media/AudioSink.cpp +++ b/dom/media/AudioSink.cpp @@ -36,7 +36,13 @@ AudioSink::AudioSink(MediaQueue& aAudioQueue, , mLastGoodPosition(0) , mInfo(aInfo) , mChannel(aChannel) + , mVolume(1.0) + , mPlaybackRate(1.0) + , mPreservesPitch(false) , mStopAudioThread(false) + , mSetVolume(false) + , mSetPlaybackRate(false) + , mSetPreservesPitch(false) , mPlaying(true) { } @@ -127,21 +133,15 @@ AudioSink::HasUnplayedFrames() void AudioSink::Shutdown() { - { - ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); - if (mAudioStream) { - mAudioStream->Cancel(); - } + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + mStopAudioThread = true; + if (mAudioStream) { + mAudioStream->Cancel(); } - nsRefPtr self = this; - nsCOMPtr r = NS_NewRunnableFunction([=] () { - self->mStopAudioThread = true; - if (!self->mAudioLoopScheduled) { - self->AudioLoop(); - } - }); - DispatchTask(r.forget()); + ScheduleNextLoopCrossThread(); + // Exit the monitor so audio loop can enter the monitor and finish its job. + ReentrantMonitorAutoExit exit(GetReentrantMonitor()); mThread->Shutdown(); mThread = nullptr; if (mAudioStream) { @@ -159,66 +159,34 @@ AudioSink::Shutdown() void AudioSink::SetVolume(double aVolume) { - AssertNotOnAudioThread(); - nsRefPtr self = this; - nsCOMPtr r = NS_NewRunnableFunction([=] () { - if (self->mState == AUDIOSINK_STATE_PLAYING) { - self->mAudioStream->SetVolume(aVolume); - } - }); - DispatchTask(r.forget()); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + mVolume = aVolume; + mSetVolume = true; } void AudioSink::SetPlaybackRate(double aPlaybackRate) { - AssertNotOnAudioThread(); - MOZ_ASSERT(aPlaybackRate != 0, "Don't set the playbackRate to 0 on AudioStream"); - nsRefPtr self = this; - nsCOMPtr r = NS_NewRunnableFunction([=] () { - if (self->mState == AUDIOSINK_STATE_PLAYING) { - self->mAudioStream->SetPlaybackRate(aPlaybackRate); - } - }); - DispatchTask(r.forget()); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + NS_ASSERTION(mPlaybackRate != 0, "Don't set the playbackRate to 0 on AudioStream"); + mPlaybackRate = aPlaybackRate; + mSetPlaybackRate = true; } void AudioSink::SetPreservesPitch(bool aPreservesPitch) { - AssertNotOnAudioThread(); - nsRefPtr self = this; - nsCOMPtr r = NS_NewRunnableFunction([=] () { - if (self->mState == AUDIOSINK_STATE_PLAYING) { - self->mAudioStream->SetPreservesPitch(aPreservesPitch); - } - }); - DispatchTask(r.forget()); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + mPreservesPitch = aPreservesPitch; + mSetPreservesPitch = true; } void AudioSink::SetPlaying(bool aPlaying) { - AssertNotOnAudioThread(); - nsRefPtr self = this; - nsCOMPtr r = NS_NewRunnableFunction([=] () { - if (self->mState != AUDIOSINK_STATE_PLAYING || - self->mPlaying == aPlaying) { - return; - } - self->mPlaying = aPlaying; - // pause/resume AudioStream as necessary. - if (!aPlaying && !self->mAudioStream->IsPaused()) { - self->mAudioStream->Pause(); - } else if (aPlaying && self->mAudioStream->IsPaused()) { - self->mAudioStream->Resume(); - } - // Wake up the audio loop to play next sample. - if (aPlaying && !self->mAudioLoopScheduled) { - self->AudioLoop(); - } - }); - DispatchTask(r.forget()); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + mPlaying = aPlaying; + ScheduleNextLoopCrossThread(); } void @@ -243,6 +211,7 @@ AudioSink::InitializeAudioStream() ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); mAudioStream = audioStream; + UpdateStreamSettings(); return NS_OK; } @@ -250,18 +219,21 @@ AudioSink::InitializeAudioStream() void AudioSink::Drain() { - AssertOnAudioThread(); MOZ_ASSERT(mPlaying && !mAudioStream->IsPaused()); + AssertCurrentThreadInMonitor(); // If the media was too short to trigger the start of the audio stream, // start it now. mAudioStream->Start(); - mAudioStream->Drain(); + { + ReentrantMonitorAutoExit exit(GetReentrantMonitor()); + mAudioStream->Drain(); + } } void AudioSink::Cleanup() { - AssertOnAudioThread(); + AssertCurrentThreadInMonitor(); mEndPromise.Resolve(true, __func__); // Since the promise if resolved asynchronously, we don't shutdown // AudioStream here so MDSM::ResyncAudioClock can get the correct @@ -277,10 +249,13 @@ AudioSink::ExpectMoreAudioData() bool AudioSink::WaitingForAudioToPlay() { - AssertOnAudioThread(); // Return true if we're not playing, and we're not shutting down, or we're // playing and we've got no audio to play. + AssertCurrentThreadInMonitor(); if (!mStopAudioThread && (!mPlaying || ExpectMoreAudioData())) { + if (!mPlaying && !mAudioStream->IsPaused()) { + mAudioStream->Pause(); + } return true; } return false; @@ -289,13 +264,19 @@ AudioSink::WaitingForAudioToPlay() bool AudioSink::IsPlaybackContinuing() { - AssertOnAudioThread(); + AssertCurrentThreadInMonitor(); + if (mPlaying && mAudioStream->IsPaused()) { + mAudioStream->Resume(); + } + // If we're shutting down, captured, or at EOS, break out and exit the audio // thread. if (mStopAudioThread || AudioQueue().AtEndOfStream()) { return false; } + UpdateStreamSettings(); + return true; } @@ -320,13 +301,16 @@ AudioSink::AudioLoop() } case AUDIOSINK_STATE_PLAYING: { - if (WaitingForAudioToPlay()) { - // NotifyData() will schedule next loop. - break; - } - if (!IsPlaybackContinuing()) { - SetState(AUDIOSINK_STATE_COMPLETE); - break; + { + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); + if (WaitingForAudioToPlay()) { + // NotifyData() will schedule next loop. + break; + } + if (!IsPlaybackContinuing()) { + SetState(AUDIOSINK_STATE_COMPLETE); + break; + } } if (!PlayAudio()) { SetState(AUDIOSINK_STATE_COMPLETE); @@ -399,7 +383,7 @@ AudioSink::PlayAudio() void AudioSink::FinishAudioLoop() { - AssertOnAudioThread(); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); MOZ_ASSERT(mStopAudioThread || AudioQueue().AtEndOfStream()); if (!mStopAudioThread && mPlaying) { Drain(); @@ -450,6 +434,40 @@ AudioSink::PlayFromAudioQueue() return audio->mFrames; } +void +AudioSink::UpdateStreamSettings() +{ + AssertCurrentThreadInMonitor(); + + bool setVolume = mSetVolume; + bool setPlaybackRate = mSetPlaybackRate; + bool setPreservesPitch = mSetPreservesPitch; + double volume = mVolume; + double playbackRate = mPlaybackRate; + bool preservesPitch = mPreservesPitch; + + mSetVolume = false; + mSetPlaybackRate = false; + mSetPreservesPitch = false; + + { + ReentrantMonitorAutoExit exit(GetReentrantMonitor()); + if (setVolume) { + mAudioStream->SetVolume(volume); + } + + if (setPlaybackRate && + NS_FAILED(mAudioStream->SetPlaybackRate(playbackRate))) { + NS_WARNING("Setting the playback rate failed in AudioSink."); + } + + if (setPreservesPitch && + NS_FAILED(mAudioStream->SetPreservesPitch(preservesPitch))) { + NS_WARNING("Setting the pitch preservation failed in AudioSink."); + } + } +} + void AudioSink::StartAudioStreamPlaybackIfNeeded() { diff --git a/dom/media/AudioSink.h b/dom/media/AudioSink.h index cfea21e8c07c..7dcb76068ee9 100644 --- a/dom/media/AudioSink.h +++ b/dom/media/AudioSink.h @@ -114,6 +114,8 @@ private: // audio data to the audio hardware. Called on the audio thread. uint32_t PlayFromAudioQueue(); + void UpdateStreamSettings(); + // If we have already written enough frames to the AudioStream, start the // playback. void StartAudioStreamPlaybackIfNeeded(); @@ -170,8 +172,16 @@ private: dom::AudioChannel mChannel; + double mVolume; + double mPlaybackRate; + bool mPreservesPitch; + bool mStopAudioThread; + bool mSetVolume; + bool mSetPlaybackRate; + bool mSetPreservesPitch; + bool mPlaying; MozPromiseHolder mEndPromise;