diff --git a/dom/media/GraphDriver.cpp b/dom/media/GraphDriver.cpp index 4a3d2523cf9f..cbe166fbf3bd 100644 --- a/dom/media/GraphDriver.cpp +++ b/dom/media/GraphDriver.cpp @@ -1183,6 +1183,9 @@ void AudioCallbackDriver::FallbackToSystemClockDriver() { ("%p: AudioCallbackDriver %p Falling back to SystemClockDriver.", Graph(), this)); mFallbackDriverState = FallbackDriverState::Running; + mNextReInitBackoffStep = + TimeDuration::FromMilliseconds(AUDIO_INITIAL_FALLBACK_BACKOFF_STEP_MS); + mNextReInitAttempt = TimeStamp::Now() + mNextReInitBackoffStep; auto fallback = MakeRefPtr(Graph(), this, mSampleRate, mIterationStart, mIterationEnd, mStateComputedTime); @@ -1200,6 +1203,8 @@ void AudioCallbackDriver::FallbackDriverStopped(GraphTime aIterationStart, mIterationStart = aIterationStart; mIterationEnd = aIterationEnd; mStateComputedTime = aStateComputedTime; + mNextReInitAttempt = TimeStamp(); + mNextReInitBackoffStep = TimeDuration(); { auto fallback = mFallback.Lock(); MOZ_ASSERT(fallback.ref()->OnThread()); @@ -1216,12 +1221,26 @@ void AudioCallbackDriver::FallbackDriverStopped(GraphTime aIterationStart, void AudioCallbackDriver::MaybeStartAudioStream() { AudioStreamState streamState = mAudioStreamState; if (streamState != AudioStreamState::None) { + LOG(LogLevel::Verbose, + ("%p: AudioCallbackDriver %p Cannot re-init.", Graph(), this)); + return; + } + + TimeStamp now = TimeStamp::Now(); + if (now < mNextReInitAttempt) { + LOG(LogLevel::Verbose, + ("%p: AudioCallbackDriver %p Not time to re-init yet. %.3fs left.", + Graph(), this, (mNextReInitAttempt - now).ToSeconds())); return; } LOG(LogLevel::Debug, ("%p: AudioCallbackDriver %p Attempting to re-init " "audio stream from fallback driver.", Graph(), this)); + mNextReInitBackoffStep = std::min( + mNextReInitBackoffStep * 2, + TimeDuration::FromMilliseconds(AUDIO_MAX_FALLBACK_BACKOFF_STEP_MS)); + mNextReInitAttempt = now + mNextReInitBackoffStep; Start(); } diff --git a/dom/media/GraphDriver.h b/dom/media/GraphDriver.h index 05bae8931b8b..a62e19b6404d 100644 --- a/dom/media/GraphDriver.h +++ b/dom/media/GraphDriver.h @@ -57,6 +57,18 @@ static const int SCHEDULE_SAFETY_MARGIN_MS = 10; static const int AUDIO_TARGET_MS = 2 * MEDIA_GRAPH_TARGET_PERIOD_MS + SCHEDULE_SAFETY_MARGIN_MS; +/** + * After starting a fallback driver, wait this long before attempting to re-init + * the audio stream the first time. + */ +static const int AUDIO_INITIAL_FALLBACK_BACKOFF_STEP_MS = 10; + +/** + * The backoff step duration for when to next attempt to re-init the audio + * stream is capped at this value. + */ +static const int AUDIO_MAX_FALLBACK_BACKOFF_STEP_MS = 1000; + class AudioCallbackDriver; class GraphDriver; class MediaTrack; @@ -758,6 +770,12 @@ class AudioCallbackDriver : public GraphDriver, /* Set to true in the first iteration after starting. Accessed in data * callback while running, or in Start(). */ bool mRanFirstIteration = false; + /* If using a fallback driver, this is the duration to wait after failing to + * start it before attempting to start it again. */ + TimeDuration mNextReInitBackoffStep; + /* If using a fallback driver, this is the next time we'll try to start the + * audio stream. */ + TimeStamp mNextReInitAttempt; #ifdef XP_MACOSX /* When using the built-in speakers on macbook pro (13 and 15, all models), * it's best to hard pan the audio on the right, to avoid feedback into the