Bug 1289678 - Don't count audio stream creation failures when retrying on Telemetry. r?kinetik
When failing to create an audio stream, we fallback to a SystemClockDriver
marked as being a "fallback driver". When failing again to open an audio stream
after re-trying, we can check whether we came from a fallback driver, and not
report the failure again to telemetry.
MozReview-Commit-ID: FAdQ0pCtC3m
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -289,23 +289,36 @@ ThreadedDriver::Stop()
mThread->Shutdown();
mThread = nullptr;
}
}
SystemClockDriver::SystemClockDriver(MediaStreamGraphImpl* aGraphImpl)
: ThreadedDriver(aGraphImpl),
mInitialTimeStamp(TimeStamp::Now()),
- mLastTimeStamp(TimeStamp::Now())
+ mLastTimeStamp(TimeStamp::Now()),
+ mIsFallback(false)
{}
SystemClockDriver::~SystemClockDriver()
{ }
void
+SystemClockDriver::MarkAsFallback()
+{
+ mIsFallback = true;
+}
+
+bool
+SystemClockDriver::IsFallback()
+{
+ return mIsFallback;
+}
+
+void
ThreadedDriver::RunThread()
{
AutoProfilerUnregisterThread autoUnregister;
bool stillProcessing = true;
while (stillProcessing) {
mIterationStart = IterationEnd();
mIterationEnd += GetIntervalForIteration();
@@ -540,16 +553,17 @@ AudioCallbackDriver::AudioCallbackDriver
, mInputChannels(1)
, mIterationDurationMS(MEDIA_GRAPH_TARGET_PERIOD_MS)
, mStarted(false)
, mAudioInput(nullptr)
, mAudioChannel(aGraphImpl->AudioChannel())
, mAddedMixer(false)
, mInCallback(false)
, mMicrophoneActive(false)
+ , mFromFallback(false)
{
STREAM_LOG(LogLevel::Debug, ("AudioCallbackDriver ctor for graph %p", aGraphImpl));
}
AudioCallbackDriver::~AudioCallbackDriver()
{
MOZ_ASSERT(mPromisesForOperation.IsEmpty());
}
@@ -631,23 +645,30 @@ AudioCallbackDriver::Init()
NS_WARN_IF_FALSE(rv == CUBEB_OK,
"Could not set the audio stream volume in GraphDriver.cpp");
CubebUtils::ReportCubebBackendUsed();
} else {
#ifdef MOZ_WEBRTC
StaticMutexAutoUnlock unlock(AudioInputCubeb::Mutex());
#endif
NS_WARNING("Could not create a cubeb stream for MediaStreamGraph, falling back to a SystemClockDriver");
- CubebUtils::ReportCubebStreamInitFailure(firstStream);
+ // Only report failures when we're not coming from a driver that was
+ // created itself as a fallback driver because of a previous audio driver
+ // failure.
+ if (!mFromFallback) {
+ CubebUtils::ReportCubebStreamInitFailure(firstStream);
+ }
// Fall back to a driver using a normal thread.
MonitorAutoLock lock(GraphImpl()->GetMonitor());
- SetNextDriver(new SystemClockDriver(GraphImpl()));
- NextDriver()->SetGraphTime(this, mIterationStart, mIterationEnd);
- mGraphImpl->SetCurrentDriver(NextDriver());
- NextDriver()->Start();
+ SystemClockDriver* nextDriver = new SystemClockDriver(GraphImpl());
+ SetNextDriver(nextDriver);
+ nextDriver->MarkAsFallback();
+ nextDriver->SetGraphTime(this, mIterationStart, mIterationEnd);
+ mGraphImpl->SetCurrentDriver(nextDriver);
+ nextDriver->Start();
return;
}
}
bool aec;
Unused << mGraphImpl->AudioTrackPresent(aec);
SetMicrophoneActive(aec);
cubeb_stream_register_device_changed_callback(mAudioStream,
@@ -684,16 +705,18 @@ AudioCallbackDriver::Start()
LIFECYCLE_LOG("Releasing audio driver off main thread.");
RefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(mPreviousDriver->AsAudioCallbackDriver(),
AsyncCubebOperation::SHUTDOWN);
releaseEvent->Dispatch();
mPreviousDriver = nullptr;
} else {
LIFECYCLE_LOG("Dropping driver reference for SystemClockDriver.");
+ MOZ_ASSERT(mPreviousDriver->AsSystemClockDriver());
+ mFromFallback = mPreviousDriver->AsSystemClockDriver()->IsFallback();
mPreviousDriver = nullptr;
}
}
LIFECYCLE_LOG("Starting new audio driver off main thread, "
"to ensure it runs after previous shutdown.");
RefPtr<AsyncCubebTask> initEvent =
new AsyncCubebTask(AsAudioCallbackDriver(), AsyncCubebOperation::INIT);
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -49,16 +49,17 @@ static const int SCHEDULE_SAFETY_MARGIN_
*/
static const int AUDIO_TARGET_MS = 2*MEDIA_GRAPH_TARGET_PERIOD_MS +
SCHEDULE_SAFETY_MARGIN_MS;
class MediaStreamGraphImpl;
class AudioCallbackDriver;
class OfflineClockDriver;
+class SystemClockDriver;
/**
* A driver is responsible for the scheduling of the processing, the thread
* management, and give the different clocks to a MediaStreamGraph. This is an
* abstract base class. A MediaStreamGraph can be driven by an
* OfflineClockDriver, if the graph is offline, or a SystemClockDriver, if the
* graph is real time.
* A MediaStreamGraph holds an owning reference to its driver.
@@ -160,16 +161,20 @@ public:
virtual AudioCallbackDriver* AsAudioCallbackDriver() {
return nullptr;
}
virtual OfflineClockDriver* AsOfflineClockDriver() {
return nullptr;
}
+ virtual SystemClockDriver* AsSystemClockDriver() {
+ return nullptr;
+ }
+
/**
* Tell the driver it has to stop and return the current time of the graph, so
* another driver can start from the right point in time.
*/
virtual void SwitchAtNextIteration(GraphDriver* aDriver);
/**
* Set the time for a graph, on a driver. This is used so a new driver just
@@ -291,23 +296,30 @@ protected:
class SystemClockDriver : public ThreadedDriver
{
public:
explicit SystemClockDriver(MediaStreamGraphImpl* aGraphImpl);
virtual ~SystemClockDriver();
MediaTime GetIntervalForIteration() override;
void WaitForNextIteration() override;
void WakeUp() override;
-
+ void MarkAsFallback();
+ bool IsFallback();
+ SystemClockDriver* AsSystemClockDriver() {
+ return this;
+ }
private:
// Those are only modified (after initialization) on the graph thread. The
// graph thread does not run during the initialization.
TimeStamp mInitialTimeStamp;
TimeStamp mLastTimeStamp;
+ // This is true if this SystemClockDriver runs the graph because we could not
+ // open an audio stream.
+ bool mIsFallback;
};
/**
* An OfflineClockDriver runs the graph as fast as possible, without waiting
* between iteration.
*/
class OfflineClockDriver : public ThreadedDriver
{
@@ -520,16 +532,19 @@ private:
/* This is atomic and is set by the audio callback thread. It can be read by
* any thread safely. */
Atomic<bool> mInCallback;
/**
* True if microphone is being used by this process. This is synchronized by
* the graph's monitor. */
bool mMicrophoneActive;
+ /* True if this driver was created from a driver created because of a previous
+ * AudioCallbackDriver failure. */
+ bool mFromFallback;
};
class AsyncCubebTask : public Runnable
{
public:
AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation);