Bug 1586370 - Make GraphDriver iterate the Graph through an interface instead of directly. r=padenot

This lets us iterate more things than MediaTrackGraphImpl, e.g., audio drivers
(from the fallback driver) and unit test classes.

Differential Revision: https://phabricator.services.mozilla.com/D56082

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andreas Pehrson 2019-12-18 22:51:57 +00:00
Родитель 7502376eec
Коммит 638c69d019
4 изменённых файлов: 138 добавлений и 117 удалений

Просмотреть файл

@ -4,7 +4,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <MediaTrackGraphImpl.h>
#include "mozilla/dom/AudioContext.h"
#include "mozilla/dom/AudioDeviceInfo.h"
#include "mozilla/dom/BaseAudioContextBinding.h"
@ -32,9 +31,9 @@ extern mozilla::LazyLogModule gMediaTrackGraphLog;
namespace mozilla {
GraphDriver::GraphDriver(MediaTrackGraphImpl* aGraphImpl,
GraphDriver::GraphDriver(GraphInterface* aGraphInterface,
GraphDriver* aPreviousDriver, uint32_t aSampleRate)
: mGraphImpl(aGraphImpl),
: mGraphInterface(aGraphInterface),
mSampleRate(aSampleRate),
mPreviousDriver(aPreviousDriver) {}
@ -48,7 +47,7 @@ void GraphDriver::SetState(GraphTime aIterationStart, GraphTime aIterationEnd,
}
#ifdef DEBUG
bool GraphDriver::InIteration() { return GraphImpl()->InDriverIteration(this); }
bool GraphDriver::InIteration() { return Graph()->InDriverIteration(this); }
#endif
GraphDriver* GraphDriver::PreviousDriver() {
@ -61,10 +60,10 @@ void GraphDriver::SetPreviousDriver(GraphDriver* aPreviousDriver) {
mPreviousDriver = aPreviousDriver;
}
ThreadedDriver::ThreadedDriver(MediaTrackGraphImpl* aGraphImpl,
ThreadedDriver::ThreadedDriver(GraphInterface* aGraphInterface,
GraphDriver* aPreviousDriver,
uint32_t aSampleRate)
: GraphDriver(aGraphImpl, aPreviousDriver, aSampleRate),
: GraphDriver(aGraphInterface, aPreviousDriver, aSampleRate),
mThreadRunning(false) {}
class MediaTrackGraphShutdownThreadRunnable : public Runnable {
@ -100,12 +99,12 @@ class MediaTrackGraphInitThreadRunnable : public Runnable {
NS_IMETHOD Run() override {
MOZ_ASSERT(!mDriver->ThreadRunning());
LOG(LogLevel::Debug, ("Starting a new system driver for graph %p",
mDriver->mGraphImpl.get()));
mDriver->mGraphInterface.get()));
if (GraphDriver* previousDriver = mDriver->PreviousDriver()) {
LOG(LogLevel::Debug,
("%p releasing an AudioCallbackDriver(%p), for graph %p",
mDriver.get(), previousDriver, mDriver->GraphImpl()));
mDriver.get(), previousDriver, mDriver->Graph()));
MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
RefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(previousDriver->AsAudioCallbackDriver(),
@ -125,7 +124,7 @@ class MediaTrackGraphInitThreadRunnable : public Runnable {
void ThreadedDriver::Start() {
MOZ_ASSERT(!ThreadRunning());
LOG(LogLevel::Debug,
("Starting thread for a SystemClockDriver %p", mGraphImpl.get()));
("Starting thread for a SystemClockDriver %p", mGraphInterface.get()));
Unused << NS_WARN_IF(mThread);
MOZ_ASSERT(!mThread); // Ensure we haven't already started it
@ -145,17 +144,17 @@ void ThreadedDriver::Shutdown() {
if (mThread) {
LOG(LogLevel::Debug,
("%p: Stopping ThreadedDriver's %p thread", GraphImpl(), this));
("%p: Stopping ThreadedDriver's %p thread", Graph(), this));
mThread->Shutdown();
mThread = nullptr;
}
}
SystemClockDriver::SystemClockDriver(MediaTrackGraphImpl* aGraphImpl,
SystemClockDriver::SystemClockDriver(GraphInterface* aGraphInterface,
GraphDriver* aPreviousDriver,
uint32_t aSampleRate,
FallbackMode aFallback)
: ThreadedDriver(aGraphImpl, aPreviousDriver, aSampleRate),
: ThreadedDriver(aGraphInterface, aPreviousDriver, aSampleRate),
mInitialTimeStamp(TimeStamp::Now()),
mCurrentTimeStamp(TimeStamp::Now()),
mLastTimeStamp(TimeStamp::Now()),
@ -172,7 +171,7 @@ void ThreadedDriver::RunThread() {
mIterationEnd += GetIntervalForIteration();
if (mStateComputedTime < mIterationEnd) {
LOG(LogLevel::Warning, ("%p: Global underrun detected", GraphImpl()));
LOG(LogLevel::Warning, ("%p: Global underrun detected", Graph()));
mIterationEnd = mStateComputedTime;
}
@ -180,7 +179,7 @@ void ThreadedDriver::RunThread() {
NS_ASSERTION(mIterationStart == mIterationEnd,
"Time can't go backwards!");
// This could happen due to low clock resolution, maybe?
LOG(LogLevel::Debug, ("%p: Time did not advance", GraphImpl()));
LOG(LogLevel::Debug, ("%p: Time did not advance", Graph()));
}
GraphTime nextStateComputedTime =
@ -193,18 +192,17 @@ void ThreadedDriver::RunThread() {
("%p: Prevent state from going backwards. interval[%ld; %ld] "
"state[%ld; "
"%ld]",
GraphImpl(), (long)mIterationStart, (long)mIterationEnd,
Graph(), (long)mIterationStart, (long)mIterationEnd,
(long)mStateComputedTime, (long)nextStateComputedTime));
nextStateComputedTime = mStateComputedTime;
}
LOG(LogLevel::Verbose,
("%p: interval[%ld; %ld] state[%ld; %ld]", GraphImpl(),
("%p: interval[%ld; %ld] state[%ld; %ld]", Graph(),
(long)mIterationStart, (long)mIterationEnd, (long)mStateComputedTime,
(long)nextStateComputedTime));
mStateComputedTime = nextStateComputedTime;
IterationResult result =
GraphImpl()->OneIteration(mStateComputedTime, nullptr);
IterationResult result = Graph()->OneIteration(mStateComputedTime, nullptr);
if (result.IsStop()) {
// Signal that we're done stopping.
@ -214,8 +212,7 @@ void ThreadedDriver::RunThread() {
}
WaitForNextIteration();
if (GraphDriver* nextDriver = result.NextDriver()) {
LOG(LogLevel::Debug,
("%p: Switching to AudioCallbackDriver", GraphImpl()));
LOG(LogLevel::Debug, ("%p: Switching to AudioCallbackDriver", Graph()));
result.Switched();
nextDriver->SetState(mIterationStart, mIterationEnd, mStateComputedTime);
nextDriver->Start();
@ -234,7 +231,7 @@ MediaTime SystemClockDriver::GetIntervalForIteration() {
MOZ_LOG(gMediaTrackGraphLog, LogLevel::Verbose,
("%p: Updating current time to %f (real %f, StateComputedTime() %f)",
GraphImpl(), MediaTimeToSeconds(IterationEnd() + interval),
Graph(), MediaTimeToSeconds(IterationEnd() + interval),
(now - mInitialTimeStamp).ToSeconds(),
MediaTimeToSeconds(mStateComputedTime)));
@ -261,15 +258,15 @@ TimeDuration SystemClockDriver::WaitInterval() {
// least once a minute, if we need to wake up at all
timeoutMS = std::max<int64_t>(0, std::min<int64_t>(timeoutMS, 60 * 1000));
LOG(LogLevel::Verbose,
("%p: Waiting for next iteration; at %f, timeout=%f", GraphImpl(),
("%p: Waiting for next iteration; at %f, timeout=%f", Graph(),
(now - mInitialTimeStamp).ToSeconds(), timeoutMS / 1000.0));
return TimeDuration::FromMilliseconds(timeoutMS);
}
OfflineClockDriver::OfflineClockDriver(MediaTrackGraphImpl* aGraphImpl,
OfflineClockDriver::OfflineClockDriver(GraphInterface* aGraphInterface,
uint32_t aSampleRate, GraphTime aSlice)
: ThreadedDriver(aGraphImpl, nullptr, aSampleRate), mSlice(aSlice) {}
: ThreadedDriver(aGraphInterface, nullptr, aSampleRate), mSlice(aSlice) {}
OfflineClockDriver::~OfflineClockDriver() {}
@ -282,7 +279,7 @@ AsyncCubebTask::AsyncCubebTask(AudioCallbackDriver* aDriver,
: Runnable("AsyncCubebTask"),
mDriver(aDriver),
mOperation(aOperation),
mShutdownGrip(aDriver->GraphImpl()) {
mShutdownGrip(aDriver->Graph()) {
NS_WARNING_ASSERTION(
mDriver->mAudioStream || aOperation == AsyncCubebOperation::INIT,
"No audio stream!");
@ -297,7 +294,7 @@ AsyncCubebTask::Run() {
switch (mOperation) {
case AsyncCubebOperation::INIT: {
LOG(LogLevel::Debug, ("%p: AsyncCubebOperation::INIT driver=%p",
mDriver->GraphImpl(), mDriver.get()));
mDriver->Graph(), mDriver.get()));
if (!mDriver->Init()) {
LOG(LogLevel::Warning,
("AsyncCubebOperation::INIT failed for driver=%p", mDriver.get()));
@ -308,7 +305,7 @@ AsyncCubebTask::Run() {
}
case AsyncCubebOperation::SHUTDOWN: {
LOG(LogLevel::Debug, ("%p: AsyncCubebOperation::SHUTDOWN driver=%p",
mDriver->GraphImpl(), mDriver.get()));
mDriver->Graph(), mDriver.get()));
mDriver->Stop();
mDriver->CompleteAudioContextOperations(mOperation);
@ -342,11 +339,11 @@ TrackAndPromiseForOperation::TrackAndPromiseForOperation(
mHolder(std::move(aOther.mHolder)) {}
AudioCallbackDriver::AudioCallbackDriver(
MediaTrackGraphImpl* aGraphImpl, GraphDriver* aPreviousDriver,
GraphInterface* aGraphInterface, GraphDriver* aPreviousDriver,
uint32_t aSampleRate, uint32_t aOutputChannelCount,
uint32_t aInputChannelCount, CubebUtils::AudioDeviceID aOutputDeviceID,
CubebUtils::AudioDeviceID aInputDeviceID, AudioInputType aAudioInputType)
: GraphDriver(aGraphImpl, aPreviousDriver, aSampleRate),
: GraphDriver(aGraphInterface, aPreviousDriver, aSampleRate),
mOutputChannels(aOutputChannelCount),
mInputChannelCount(aInputChannelCount),
mOutputDeviceID(aOutputDeviceID),
@ -360,7 +357,7 @@ AudioCallbackDriver::AudioCallbackDriver(
mAudioThreadRunning(false),
mShouldFallbackIfError(false),
mFromFallback(false) {
LOG(LogLevel::Debug, ("%p: AudioCallbackDriver ctor", GraphImpl()));
LOG(LogLevel::Debug, ("%p: AudioCallbackDriver ctor", Graph()));
const uint32_t kIdleThreadTimeoutMs = 2000;
mInitShutdownThread->SetIdleThreadTimeout(
@ -551,12 +548,11 @@ bool AudioCallbackDriver::Init() {
if (!StartStream()) {
LOG(LogLevel::Warning,
("%p: AudioCallbackDriver couldn't start a cubeb stream.",
GraphImpl()));
("%p: AudioCallbackDriver couldn't start a cubeb stream.", Graph()));
return false;
}
LOG(LogLevel::Debug, ("%p: AudioCallbackDriver started.", GraphImpl()));
LOG(LogLevel::Debug, ("%p: AudioCallbackDriver started.", Graph()));
return true;
}
@ -615,7 +611,7 @@ void AudioCallbackDriver::Shutdown() {
MOZ_ASSERT(NS_IsMainThread());
LOG(LogLevel::Debug,
("%p: Releasing audio driver off main thread (GraphDriver::Shutdown).",
GraphImpl()));
Graph()));
RefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(this, AsyncCubebOperation::SHUTDOWN);
releaseEvent->Dispatch(NS_DISPATCH_SYNC);
@ -711,27 +707,26 @@ long AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
LOG(LogLevel::Verbose,
("%p: interval[%ld; %ld] state[%ld; %ld] (frames: %ld) (durationMS: %u) "
"(duration ticks: %ld)",
GraphImpl(), (long)mIterationStart, (long)mIterationEnd,
Graph(), (long)mIterationStart, (long)mIterationEnd,
(long)mStateComputedTime, (long)nextStateComputedTime, (long)aFrames,
(uint32_t)durationMS,
(long)(nextStateComputedTime - mStateComputedTime)));
if (mStateComputedTime < mIterationEnd) {
LOG(LogLevel::Error,
("%p: Media graph global underrun detected", GraphImpl()));
LOG(LogLevel::Error, ("%p: Media graph global underrun detected", Graph()));
MOZ_ASSERT_UNREACHABLE("We should not underrun in full duplex");
mIterationEnd = mStateComputedTime;
}
// Process mic data if any/needed
if (aInputBuffer && mInputChannelCount > 0) {
GraphImpl()->NotifyInputData(aInputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mInputChannelCount);
Graph()->NotifyInputData(aInputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mInputChannelCount);
}
bool iterate = mBuffer.Available();
IterationResult result =
iterate ? GraphImpl()->OneIteration(nextStateComputedTime, &mMixer)
iterate ? Graph()->OneIteration(nextStateComputedTime, &mMixer)
: IterationResult::CreateStillProcessing();
if (iterate) {
// We totally filled the buffer (and mScratchBuffer isn't empty).
@ -741,7 +736,7 @@ long AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
LOG(LogLevel::Verbose,
("%p: DataCallback buffer filled entirely from scratch "
"buffer, skipping iteration.",
GraphImpl()));
Graph()));
result = IterationResult::CreateStillProcessing();
}
@ -752,8 +747,8 @@ long AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
// data off separate cubeb callbacks. Take care with how stuff is
// removed/added to this list and TSAN issues, but input and output will
// use separate callback methods.
GraphImpl()->NotifyOutputData(aOutputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mOutputChannels);
Graph()->NotifyOutputData(aOutputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mOutputChannels);
#ifdef XP_MACOSX
// This only happens when the output is on a macbookpro's external speaker,
@ -780,7 +775,7 @@ long AudioCallbackDriver::DataCallback(const AudioDataValue* aInputBuffer,
}
if (GraphDriver* nextDriver = result.NextDriver()) {
LOG(LogLevel::Debug, ("%p: Switching to system driver.", GraphImpl()));
LOG(LogLevel::Debug, ("%p: Switching to system driver.", Graph()));
result.Switched();
mShouldFallbackIfError = false;
mAudioThreadRunning = false;
@ -885,8 +880,7 @@ void AudioCallbackDriver::DeviceChangedCallback() {
MOZ_ASSERT(!InIteration());
// Tell the audio engine the device has changed, it might want to reset some
// state.
MonitorAutoLock mon(mGraphImpl->GetMonitor());
GraphImpl()->DeviceChanged();
Graph()->DeviceChanged();
#ifdef XP_MACOSX
RefPtr<AudioCallbackDriver> self(this);
bool hasInput = mInputChannelCount;

Просмотреть файл

@ -57,10 +57,9 @@ static const int SCHEDULE_SAFETY_MARGIN_MS = 10;
static const int AUDIO_TARGET_MS =
2 * MEDIA_GRAPH_TARGET_PERIOD_MS + SCHEDULE_SAFETY_MARGIN_MS;
class MediaTrack;
class MediaTrackGraphImpl;
class AudioCallbackDriver;
class GraphDriver;
class MediaTrack;
class OfflineClockDriver;
class SystemClockDriver;
@ -68,56 +67,7 @@ namespace dom {
enum class AudioContextOperation;
}
/**
* A driver is responsible for the scheduling of the processing, the thread
* management, and give the different clocks to a MediaTrackGraph. This is an
* abstract base class. A MediaTrackGraph can be driven by an
* OfflineClockDriver, if the graph is offline, or a SystemClockDriver, if the
* graph is real time.
* A MediaTrackGraph holds an owning reference to its driver.
*
* The lifetime of drivers is a complicated affair. Here are the different
* scenarii that can happen:
*
* Starting a MediaTrackGraph with an AudioCallbackDriver
* - A new thread T is created, from the main thread.
* - On this thread T, cubeb is initialized if needed, and a cubeb_stream is
* created and started
* - The thread T posts a message to the main thread to terminate itself.
* - The graph runs off the audio thread
*
* Starting a MediaTrackGraph with a SystemClockDriver:
* - A new thread T is created from the main thread.
* - The graph runs off this thread.
*
* Switching from a SystemClockDriver to an AudioCallbackDriver:
* - A new AudioCallabackDriver is created and initialized on the graph thread
* - At the end of the MTG iteration, the SystemClockDriver transfers its timing
* info and a reference to itself to the AudioCallbackDriver. It then starts
* the AudioCallbackDriver.
* - When the AudioCallbackDriver starts, it checks if it has been switched from
* a SystemClockDriver, and if that is the case, sends a message to the main
* thread to shut the SystemClockDriver thread down.
* - The graph now runs off an audio callback
*
* Switching from an AudioCallbackDriver to a SystemClockDriver:
* - A new SystemClockDriver is created, and set as mNextDriver.
* - At the end of the MTG iteration, the AudioCallbackDriver transfers its
* timing info and a reference to itself to the SystemClockDriver. A new
* SystemClockDriver is started from the current audio thread.
* - When starting, the SystemClockDriver checks if it has been switched from an
* AudioCallbackDriver. If yes, it creates a new temporary thread to release
* the cubeb_streams. This temporary thread closes the cubeb_stream, and
* then dispatches a message to the main thread to be terminated.
* - The graph now runs off a normal thread.
*
* Two drivers cannot run at the same time for the same graph. The thread safety
* of the different attributes of drivers, and they access pattern is documented
* next to the members themselves.
*
*/
class GraphDriver {
public:
struct GraphInterface {
/**
* Object returned from OneIteration() instructing the iterating GraphDriver
* what to do.
@ -212,7 +162,84 @@ class GraphDriver {
}
};
GraphDriver(MediaTrackGraphImpl* aGraphImpl, GraphDriver* aPreviousDriver,
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
/* Called on the graph thread when there is new output data for listeners.
* This is the mixed audio output of this MediaTrackGraph. */
virtual void NotifyOutputData(AudioDataValue* aBuffer, size_t aFrames,
TrackRate aRate, uint32_t aChannels) = 0;
/* Called on the graph thread when there is new input data for listeners. This
* is the raw audio input for this MediaTrackGraph. */
virtual void NotifyInputData(const AudioDataValue* aBuffer, size_t aFrames,
TrackRate aRate, uint32_t aChannels) = 0;
/* Called every time there are changes to input/output audio devices like
* plug/unplug etc. This can be called on any thread, and posts a message to
* the main thread so that it can post a message to the graph thread. */
virtual void DeviceChanged() = 0;
/* Called by GraphDriver to iterate the graph. Output from the graph gets
* mixed into aMixer, if it is non-null. */
virtual IterationResult OneIteration(GraphTime aStateEnd,
AudioMixer* aMixer) = 0;
#ifdef DEBUG
/* True if we're on aDriver's thread, or if we're on mGraphRunner's thread
* and mGraphRunner is currently run by aDriver. */
virtual bool InDriverIteration(GraphDriver* aDriver) = 0;
#endif
};
/**
* A driver is responsible for the scheduling of the processing, the thread
* management, and give the different clocks to a MediaTrackGraph. This is an
* abstract base class. A MediaTrackGraph can be driven by an
* OfflineClockDriver, if the graph is offline, or a SystemClockDriver, if the
* graph is real time.
* A MediaTrackGraph holds an owning reference to its driver.
*
* The lifetime of drivers is a complicated affair. Here are the different
* scenarii that can happen:
*
* Starting a MediaTrackGraph with an AudioCallbackDriver
* - A new thread T is created, from the main thread.
* - On this thread T, cubeb is initialized if needed, and a cubeb_stream is
* created and started
* - The thread T posts a message to the main thread to terminate itself.
* - The graph runs off the audio thread
*
* Starting a MediaTrackGraph with a SystemClockDriver:
* - A new thread T is created from the main thread.
* - The graph runs off this thread.
*
* Switching from a SystemClockDriver to an AudioCallbackDriver:
* - A new AudioCallabackDriver is created and initialized on the graph thread
* - At the end of the MTG iteration, the SystemClockDriver transfers its timing
* info and a reference to itself to the AudioCallbackDriver. It then starts
* the AudioCallbackDriver.
* - When the AudioCallbackDriver starts, it checks if it has been switched from
* a SystemClockDriver, and if that is the case, sends a message to the main
* thread to shut the SystemClockDriver thread down.
* - The graph now runs off an audio callback
*
* Switching from an AudioCallbackDriver to a SystemClockDriver:
* - A new SystemClockDriver is created, and set as mNextDriver.
* - At the end of the MTG iteration, the AudioCallbackDriver transfers its
* timing info and a reference to itself to the SystemClockDriver. A new
* SystemClockDriver is started from the current audio thread.
* - When starting, the SystemClockDriver checks if it has been switched from an
* AudioCallbackDriver. If yes, it creates a new temporary thread to release
* the cubeb_streams. This temporary thread closes the cubeb_stream, and
* then dispatches a message to the main thread to be terminated.
* - The graph now runs off a normal thread.
*
* Two drivers cannot run at the same time for the same graph. The thread safety
* of the different attributes of drivers, and they access pattern is documented
* next to the members themselves.
*
*/
class GraphDriver {
public:
using IterationResult = GraphInterface::IterationResult;
GraphDriver(GraphInterface* aGraphInterface, GraphDriver* aPreviousDriver,
uint32_t aSampleRate);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphDriver);
@ -259,7 +286,7 @@ class GraphDriver {
void SetState(GraphTime aIterationStart, GraphTime aIterationEnd,
GraphTime aStateComputedTime);
MediaTrackGraphImpl* GraphImpl() const { return mGraphImpl; }
GraphInterface* Graph() const { return mGraphInterface; }
#ifdef DEBUG
// True if the current thread is currently iterating the MTG.
@ -295,8 +322,8 @@ class GraphDriver {
GraphTime mIterationEnd = 0;
// Time until which the graph has processed data.
GraphTime mStateComputedTime = 0;
// The MediaTrackGraphImpl associated with this driver.
const RefPtr<MediaTrackGraphImpl> mGraphImpl;
// The GraphInterface this driver is currently iterating.
const RefPtr<GraphInterface> mGraphInterface;
// The sample rate for the graph, and in case of an audio driver, also for the
// cubeb stream.
const uint32_t mSampleRate;
@ -366,7 +393,7 @@ class ThreadedDriver : public GraphDriver {
};
public:
ThreadedDriver(MediaTrackGraphImpl* aGraphImpl, GraphDriver* aPreviousDriver,
ThreadedDriver(GraphInterface* aGraphInterface, GraphDriver* aPreviousDriver,
uint32_t aSampleRate);
virtual ~ThreadedDriver();
@ -413,13 +440,13 @@ class ThreadedDriver : public GraphDriver {
};
/**
* A SystemClockDriver drives a MediaTrackGraph using a system clock, and waits
* A SystemClockDriver drives a GraphInterface using a system clock, and waits
* using a monitor, between each iteration.
*/
enum class FallbackMode { Regular, Fallback };
class SystemClockDriver : public ThreadedDriver {
public:
SystemClockDriver(MediaTrackGraphImpl* aGraphImpl,
SystemClockDriver(GraphInterface* aGraphInterface,
GraphDriver* aPreviousDriver, uint32_t aSampleRate,
FallbackMode aFallback = FallbackMode::Regular);
virtual ~SystemClockDriver();
@ -449,7 +476,7 @@ class SystemClockDriver : public ThreadedDriver {
*/
class OfflineClockDriver : public ThreadedDriver {
public:
OfflineClockDriver(MediaTrackGraphImpl* aGraphImpl, uint32_t aSampleRate,
OfflineClockDriver(GraphInterface* aGraphInterface, uint32_t aSampleRate,
GraphTime aSlice);
virtual ~OfflineClockDriver();
OfflineClockDriver* AsOfflineClockDriver() override { return this; }
@ -508,7 +535,7 @@ class AudioCallbackDriver : public GraphDriver,
{
public:
/** If aInputChannelCount is zero, then this driver is output-only. */
AudioCallbackDriver(MediaTrackGraphImpl* aGraphImpl,
AudioCallbackDriver(GraphInterface* aGraphInterface,
GraphDriver* aPreviousDriver, uint32_t aSampleRate,
uint32_t aOutputChannelCount, uint32_t aInputChannelCount,
CubebUtils::AudioDeviceID aOutputDeviceID,
@ -712,7 +739,7 @@ class AsyncCubebTask : public Runnable {
RefPtr<AudioCallbackDriver> mDriver;
AsyncCubebOperation mOperation;
RefPtr<MediaTrackGraphImpl> mShutdownGrip;
RefPtr<GraphInterface> mShutdownGrip;
};
} // namespace mozilla

Просмотреть файл

@ -21,7 +21,7 @@ class AudioMixer;
class MediaTrackGraphImpl;
class GraphRunner final : public Runnable {
using IterationResult = GraphDriver::IterationResult;
using IterationResult = GraphInterface::IterationResult;
public:
static already_AddRefed<GraphRunner> Create(MediaTrackGraphImpl* aGraph);

Просмотреть файл

@ -91,11 +91,10 @@ class MessageBlock {
* object too.
*/
class MediaTrackGraphImpl : public MediaTrackGraph,
public GraphInterface,
public nsIMemoryReporter,
public nsITimerCallback,
public nsINamed {
using IterationResult = GraphDriver::IterationResult;
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIMEMORYREPORTER
@ -127,7 +126,7 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
* True if we're on aDriver's thread, or if we're on mGraphRunner's thread
* and mGraphRunner is currently run by aDriver.
*/
bool InDriverIteration(GraphDriver* aDriver);
bool InDriverIteration(GraphDriver* aDriver) override;
#endif
/**
@ -217,7 +216,8 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
* OneIterationImpl is called directly. Output from the graph gets mixed into
* aMixer, if it is non-null.
*/
IterationResult OneIteration(GraphTime aStateEnd, AudioMixer* aMixer);
IterationResult OneIteration(GraphTime aStateEnd,
AudioMixer* aMixer) override;
/**
* Returns true if this MediaTrackGraph should keep running
@ -428,15 +428,15 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
/* Called on the graph thread when there is new output data for listeners.
* This is the mixed audio output of this MediaTrackGraph. */
void NotifyOutputData(AudioDataValue* aBuffer, size_t aFrames,
TrackRate aRate, uint32_t aChannels);
TrackRate aRate, uint32_t aChannels) override;
/* Called on the graph thread when there is new input data for listeners. This
* is the raw audio input for this MediaTrackGraph. */
void NotifyInputData(const AudioDataValue* aBuffer, size_t aFrames,
TrackRate aRate, uint32_t aChannels);
TrackRate aRate, uint32_t aChannels) override;
/* Called every time there are changes to input/output audio devices like
* plug/unplug etc. This can be called on any thread, and posts a message to
* the main thread so that it can post a message to the graph thread. */
void DeviceChanged();
void DeviceChanged() override;
/* Called every time there are changes to input/output audio devices. This is
* called on the graph thread. */
void DeviceChangedImpl();