--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -49,52 +49,55 @@ void GraphDriver::SetGraphTime(GraphDriv
mIterationStart = aLastSwitchNextIterationStart;
mIterationEnd = aLastSwitchNextIterationEnd;
MOZ_ASSERT(!PreviousDriver());
MOZ_ASSERT(aPreviousDriver);
MOZ_DIAGNOSTIC_ASSERT(GraphImpl()->CurrentDriver() == aPreviousDriver);
LOG(LogLevel::Debug,
- ("Setting previous driver: %p (%s)",
+ ("%p: Setting previous driver: %p (%s)",
+ GraphImpl(),
aPreviousDriver,
aPreviousDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver"
: "SystemClockDriver"));
SetPreviousDriver(aPreviousDriver);
}
void GraphDriver::SwitchAtNextIteration(GraphDriver* aNextDriver)
{
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
LOG(LogLevel::Debug,
- ("Switching to new driver: %p (%s)",
+ ("%p: Switching to new driver: %p (%s)",
+ GraphImpl(),
aNextDriver,
aNextDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver"
: "SystemClockDriver"));
if (mNextDriver &&
mNextDriver != GraphImpl()->CurrentDriver()) {
LOG(LogLevel::Debug,
- ("Discarding previous next driver: %p (%s)",
+ ("%p: Discarding previous next driver: %p (%s)",
+ GraphImpl(),
mNextDriver.get(),
mNextDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver"
: "SystemClockDriver"));
}
SetNextDriver(aNextDriver);
}
GraphTime
GraphDriver::StateComputedTime() const
{
return mGraphImpl->mStateComputedTime;
}
void GraphDriver::EnsureNextIteration()
{
- mGraphImpl->EnsureNextIteration();
+ GraphImpl()->EnsureNextIteration();
}
bool GraphDriver::Switching()
{
GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
return mNextDriver || mPreviousDriver;
}
@@ -171,91 +174,93 @@ public:
explicit MediaStreamGraphInitThreadRunnable(ThreadedDriver* aDriver)
: Runnable("MediaStreamGraphInitThreadRunnable")
, mDriver(aDriver)
{
}
NS_IMETHOD Run() override
{
LOG(LogLevel::Debug,
- ("Starting a new system driver for graph %p", mDriver->mGraphImpl));
+ ("%p: Starting a new system thread driver for graph", mDriver->GraphImpl()));
RefPtr<GraphDriver> previousDriver;
{
- MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(mDriver->GraphImpl()->GetMonitor());
previousDriver = mDriver->PreviousDriver();
}
if (previousDriver) {
LOG(LogLevel::Debug,
- ("%p releasing an AudioCallbackDriver(%p), for graph %p",
+ ("%p: Driver %p releasing an AudioCallbackDriver(%p)",
+ mDriver->GraphImpl(),
mDriver.get(),
- previousDriver.get(),
- mDriver->GraphImpl()));
+ previousDriver.get()));
MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
RefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(previousDriver->AsAudioCallbackDriver(), AsyncCubebOperation::SHUTDOWN);
releaseEvent->Dispatch();
- MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(mDriver->GraphImpl()->GetMonitor());
mDriver->SetPreviousDriver(nullptr);
} else {
- MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
- MOZ_ASSERT(mDriver->mGraphImpl->MessagesQueued() ||
- mDriver->mGraphImpl->mForceShutDown, "Don't start a graph without messages queued.");
- mDriver->mGraphImpl->SwapMessageQueues();
+ MonitorAutoLock mon(mDriver->GraphImpl()->GetMonitor());
+ MOZ_ASSERT(mDriver->GraphImpl()->MessagesQueued() ||
+ mDriver->GraphImpl()->mForceShutDown, "Don't start a graph without messages queued.");
+ mDriver->GraphImpl()->SwapMessageQueues();
}
mDriver->RunThread();
return NS_OK;
}
private:
RefPtr<ThreadedDriver> mDriver;
};
void
ThreadedDriver::Start()
{
LOG(LogLevel::Debug,
- ("Starting thread for a SystemClockDriver %p", mGraphImpl));
+ ("%p: Starting thread for a SystemClockDriver %p", GraphImpl(), this));
Unused << NS_WARN_IF(mThread);
if (!mThread) { // Ensure we haven't already started it
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
// Note: mThread may be null during event->Run() if we pass to NewNamedThread! See AudioInitTask
nsresult rv = NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread));
if (NS_SUCCEEDED(rv)) {
mThread->EventTarget()->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
}
}
}
void
ThreadedDriver::Revive()
{
// Note: only called on MainThread, without monitor
// We know were weren't in a running state
- LOG(LogLevel::Debug, ("AudioCallbackDriver reviving."));
+ LOG(LogLevel::Debug, ("%p: AudioCallbackDriver %p reviving.", GraphImpl(), this));
// If we were switching, switch now. Otherwise, tell thread to run the main
// loop again.
- MonitorAutoLock mon(mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(GraphImpl()->GetMonitor());
if (NextDriver()) {
SwitchToNextDriver();
} else {
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
mThread->EventTarget()->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
}
}
void
ThreadedDriver::Shutdown()
{
NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
// mGraph's thread is not running so it's OK to do whatever here
- LOG(LogLevel::Debug, ("Stopping threads for MediaStreamGraph %p", this));
+
+ LOG(LogLevel::Debug, ("%p: ThreadedDriver(%p)::Shutdown", GraphImpl(), this));
if (mThread) {
+ LOG(LogLevel::Debug, ("%p: Stopping ThreadedDriver's %p thread", GraphImpl(), this));
mThread->Shutdown();
mThread = nullptr;
}
}
SystemClockDriver::SystemClockDriver(MediaStreamGraphImpl* aGraphImpl)
: ThreadedDriver(aGraphImpl),
mInitialTimeStamp(TimeStamp::Now()),
@@ -283,168 +288,173 @@ void
ThreadedDriver::RunThread()
{
while (true) {
mIterationStart = IterationEnd();
mIterationEnd += GetIntervalForIteration();
GraphTime stateComputedTime = StateComputedTime();
if (stateComputedTime < mIterationEnd) {
- LOG(LogLevel::Warning, ("Media graph global underrun detected"));
+ LOG(LogLevel::Warning, ("%p: Global underrun detected", GraphImpl()));
mIterationEnd = stateComputedTime;
}
if (mIterationStart >= mIterationEnd) {
NS_ASSERTION(mIterationStart == mIterationEnd ,
"Time can't go backwards!");
// This could happen due to low clock resolution, maybe?
- LOG(LogLevel::Debug, ("Time did not advance"));
+ LOG(LogLevel::Debug, ("%p: Time did not advance", GraphImpl()));
}
GraphTime nextStateComputedTime =
- mGraphImpl->RoundUpToEndOfAudioBlock(
- mIterationEnd + mGraphImpl->MillisecondsToMediaTime(AUDIO_TARGET_MS));
+ GraphImpl()->RoundUpToEndOfAudioBlock(
+ mIterationEnd + GraphImpl()->MillisecondsToMediaTime(AUDIO_TARGET_MS));
if (nextStateComputedTime < stateComputedTime) {
// A previous driver may have been processing further ahead of
// iterationEnd.
LOG(LogLevel::Warning,
- ("Prevent state from going backwards. interval[%ld; %ld] state[%ld; "
+ ("%p: Prevent state from going backwards. interval[%ld; %ld] state[%ld; "
"%ld]",
+ GraphImpl(),
(long)mIterationStart,
(long)mIterationEnd,
(long)stateComputedTime,
(long)nextStateComputedTime));
nextStateComputedTime = stateComputedTime;
}
LOG(LogLevel::Verbose,
- ("interval[%ld; %ld] state[%ld; %ld]",
+ ("%p: interval[%ld; %ld] state[%ld; %ld]",
+ GraphImpl(),
(long)mIterationStart,
(long)mIterationEnd,
(long)stateComputedTime,
(long)nextStateComputedTime));
- bool stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
+ bool stillProcessing = GraphImpl()->OneIteration(nextStateComputedTime);
if (!stillProcessing) {
// Enter shutdown mode. The stable-state handler will detect this
// and complete shutdown if the graph does not get restarted.
- mGraphImpl->SignalMainThreadCleanup();
+ GraphImpl()->SignalMainThreadCleanup();
return;
}
MonitorAutoLock lock(GraphImpl()->GetMonitor());
if (NextDriver()) {
- LOG(LogLevel::Debug, ("Switching to AudioCallbackDriver"));
+ LOG(LogLevel::Debug, ("%p: Switching to AudioCallbackDriver", GraphImpl()));
SwitchToNextDriver();
return;
}
}
}
MediaTime
SystemClockDriver::GetIntervalForIteration()
{
TimeStamp now = TimeStamp::Now();
MediaTime interval =
- mGraphImpl->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds());
+ GraphImpl()->SecondsToMediaTime((now - mCurrentTimeStamp).ToSeconds());
mCurrentTimeStamp = now;
MOZ_LOG(gMediaStreamGraphLog, LogLevel::Verbose,
- ("Updating current time to %f (real %f, StateComputedTime() %f)",
- mGraphImpl->MediaTimeToSeconds(IterationEnd() + interval),
+ ("%p: Updating current time to %f (real %f, StateComputedTime() %f)",
+ GraphImpl(),
+ GraphImpl()->MediaTimeToSeconds(IterationEnd() + interval),
(now - mInitialTimeStamp).ToSeconds(),
- mGraphImpl->MediaTimeToSeconds(StateComputedTime())));
+ GraphImpl()->MediaTimeToSeconds(StateComputedTime())));
return interval;
}
TimeStamp
OfflineClockDriver::GetCurrentTimeStamp()
{
MOZ_CRASH("This driver does not support getting the current timestamp.");
return TimeStamp();
}
void
SystemClockDriver::WaitForNextIteration()
{
- mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
+ GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
TimeDuration timeout = TimeDuration::Forever();
TimeStamp now = TimeStamp::Now();
// This lets us avoid hitting the Atomic twice when we know we won't sleep
- bool another = mGraphImpl->mNeedAnotherIteration; // atomic
+ bool another = GraphImpl()->mNeedAnotherIteration; // atomic
if (!another) {
- mGraphImpl->mGraphDriverAsleep = true; // atomic
+ GraphImpl()->mGraphDriverAsleep = true; // atomic
mWaitState = WAITSTATE_WAITING_INDEFINITELY;
}
// NOTE: mNeedAnotherIteration while also atomic may have changed before
// we could set mGraphDriverAsleep, so we must re-test it.
// (EnsureNextIteration sets mNeedAnotherIteration, then tests
// mGraphDriverAsleep
- if (another || mGraphImpl->mNeedAnotherIteration) { // atomic
+ if (another || GraphImpl()->mNeedAnotherIteration) { // atomic
int64_t timeoutMS = MEDIA_GRAPH_TARGET_PERIOD_MS -
int64_t((now - mCurrentTimeStamp).ToMilliseconds());
// Make sure timeoutMS doesn't overflow 32 bits by waking up at
// 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));
timeout = TimeDuration::FromMilliseconds(timeoutMS);
LOG(LogLevel::Verbose,
- ("Waiting for next iteration; at %f, timeout=%f",
+ ("%p: Waiting for next iteration; at %f, timeout=%f",
+ GraphImpl(),
(now - mInitialTimeStamp).ToSeconds(),
timeoutMS / 1000.0));
if (mWaitState == WAITSTATE_WAITING_INDEFINITELY) {
- mGraphImpl->mGraphDriverAsleep = false; // atomic
+ GraphImpl()->mGraphDriverAsleep = false; // atomic
}
mWaitState = WAITSTATE_WAITING_FOR_NEXT_ITERATION;
}
if (!timeout.IsZero()) {
- mGraphImpl->GetMonitor().Wait(timeout);
+ GraphImpl()->GetMonitor().Wait(timeout);
LOG(LogLevel::Verbose,
- ("Resuming after timeout; at %f, elapsed=%f",
+ ("%p: Resuming after timeout; at %f, elapsed=%f",
+ GraphImpl(),
(TimeStamp::Now() - mInitialTimeStamp).ToSeconds(),
(TimeStamp::Now() - now).ToSeconds()));
}
if (mWaitState == WAITSTATE_WAITING_INDEFINITELY) {
- mGraphImpl->mGraphDriverAsleep = false; // atomic
+ GraphImpl()->mGraphDriverAsleep = false; // atomic
}
// Note: this can race against the EnsureNextIteration setting
// WAITSTATE_RUNNING and setting mGraphDriverAsleep to false, so you can
// have an iteration with WAITSTATE_WAKING_UP instead of RUNNING.
mWaitState = WAITSTATE_RUNNING;
- mGraphImpl->mNeedAnotherIteration = false; // atomic
+ GraphImpl()->mNeedAnotherIteration = false; // atomic
}
void SystemClockDriver::WakeUp()
{
- mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
+ GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
// Note: this can race against the thread setting WAITSTATE_RUNNING and
// setting mGraphDriverAsleep to false, so you can have an iteration
// with WAITSTATE_WAKING_UP instead of RUNNING.
mWaitState = WAITSTATE_WAKING_UP;
- mGraphImpl->mGraphDriverAsleep = false; // atomic
- mGraphImpl->GetMonitor().Notify();
+ GraphImpl()->mGraphDriverAsleep = false; // atomic
+ GraphImpl()->GetMonitor().Notify();
}
OfflineClockDriver::OfflineClockDriver(MediaStreamGraphImpl* aGraphImpl, GraphTime aSlice)
: ThreadedDriver(aGraphImpl),
mSlice(aSlice)
{
}
OfflineClockDriver::~OfflineClockDriver()
{
}
MediaTime
OfflineClockDriver::GetIntervalForIteration()
{
- return mGraphImpl->MillisecondsToMediaTime(mSlice);
+ return GraphImpl()->MillisecondsToMediaTime(mSlice);
}
void
OfflineClockDriver::WaitForNextIteration()
{
// No op: we want to go as fast as possible when we are offline
}
@@ -488,28 +498,28 @@ AudioCallbackDriver::GetInitShutdownThre
NS_IMETHODIMP
AsyncCubebTask::Run()
{
MOZ_ASSERT(mDriver);
switch(mOperation) {
case AsyncCubebOperation::INIT: {
LOG(LogLevel::Debug,
- ("AsyncCubebOperation::INIT driver=%p", mDriver.get()));
+ ("%p: AsyncCubebOperation::INIT driver=%p", mDriver->GraphImpl(), mDriver.get()));
if (!mDriver->Init()) {
LOG(LogLevel::Warning,
("AsyncCubebOperation::INIT failed for driver=%p", mDriver.get()));
return NS_ERROR_FAILURE;
}
mDriver->CompleteAudioContextOperations(mOperation);
break;
}
case AsyncCubebOperation::SHUTDOWN: {
LOG(LogLevel::Debug,
- ("AsyncCubebOperation::SHUTDOWN driver=%p", mDriver.get()));
+ ("%p: AsyncCubebOperation::SHUTDOWN driver=%p", mDriver->GraphImpl(), mDriver.get()));
mDriver->Stop();
mDriver->CompleteAudioContextOperations(mOperation);
mDriver = nullptr;
mShutdownGrip = nullptr;
break;
}
@@ -538,17 +548,17 @@ AudioCallbackDriver::AudioCallbackDriver
, mInputChannelCount(aInputChannelCount)
, mIterationDurationMS(MEDIA_GRAPH_TARGET_PERIOD_MS)
, mStarted(false)
, mAddedMixer(false)
, mAudioThreadId(std::thread::id())
, mShouldFallbackIfError(false)
, mFromFallback(false)
{
- LOG(LogLevel::Debug, ("AudioCallbackDriver ctor for graph %p", aGraphImpl));
+ LOG(LogLevel::Debug, ("%p: AudioCallbackDriver ctor", GraphImpl()));
#if defined(XP_WIN)
if (XRE_IsContentProcess()) {
audio::AudioNotificationReceiver::Register(this);
}
#endif
}
AudioCallbackDriver::~AudioCallbackDriver()
@@ -619,28 +629,28 @@ AudioCallbackDriver::Init()
cubeb_stream_params output;
cubeb_stream_params input;
bool firstStream = CubebUtils::GetFirstStream();
MOZ_ASSERT(!NS_IsMainThread(),
"This is blocking and should never run on the main thread.");
- mSampleRate = output.rate = mGraphImpl->GraphRate();
+ mSampleRate = output.rate = GraphImpl()->GraphRate();
if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
output.format = CUBEB_SAMPLE_S16NE;
} else {
output.format = CUBEB_SAMPLE_FLOAT32NE;
}
// Query and set the number of channels this AudioCallbackDriver will use.
mOutputChannels = GraphImpl()->AudioOutputChannelCount();
if (!mOutputChannels) {
- LOG(LogLevel::Warning, ("Output number of channels is 0."));
+ LOG(LogLevel::Warning, ("%p: Output number of channels is 0.", GraphImpl()));
MonitorAutoLock lock(GraphImpl()->GetMonitor());
FallbackToSystemClockDriver();
return true;
}
mBuffer = AudioCallbackBufferWrapper<AudioDataValue>(mOutputChannels);
mScratchBuffer = SpillBuffer<AudioDataValue, WEBAUDIO_BLOCK_SIZE * 2>(mOutputChannels);
@@ -721,50 +731,50 @@ cubeb_stream_register_device_changed_cal
return true;
}
void
AudioCallbackDriver::Start()
{
if (mPreviousDriver) {
if (mPreviousDriver->AsAudioCallbackDriver()) {
- LOG(LogLevel::Debug, ("Releasing audio driver off main thread."));
+ LOG(LogLevel::Debug, ("%p: Releasing audio driver off main thread.", GraphImpl()));
RefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(mPreviousDriver->AsAudioCallbackDriver(),
AsyncCubebOperation::SHUTDOWN);
releaseEvent->Dispatch();
mPreviousDriver = nullptr;
} else {
LOG(LogLevel::Debug,
- ("Dropping driver reference for SystemClockDriver."));
+ ("%p: Dropping driver reference for SystemClockDriver.", GraphImpl()));
MOZ_ASSERT(mPreviousDriver->AsSystemClockDriver());
mFromFallback = mPreviousDriver->AsSystemClockDriver()->IsFallback();
mPreviousDriver = nullptr;
}
}
LOG(LogLevel::Debug,
- ("Starting new audio driver off main thread, "
- "to ensure it runs after previous shutdown."));
+ ("%p: Starting new audio driver off main thread, "
+ "to ensure it runs after previous shutdown.", GraphImpl()));
RefPtr<AsyncCubebTask> initEvent =
new AsyncCubebTask(AsAudioCallbackDriver(), AsyncCubebOperation::INIT);
initEvent->Dispatch();
}
bool
AudioCallbackDriver::StartStream()
{
mShouldFallbackIfError = true;
if (cubeb_stream_start(mAudioStream) != CUBEB_OK) {
NS_WARNING("Could not start cubeb stream for MSG.");
return false;
}
{
- MonitorAutoLock mon(mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(GraphImpl()->GetMonitor());
mStarted = true;
}
return true;
}
void
AudioCallbackDriver::Stop()
{
@@ -773,58 +783,58 @@ AudioCallbackDriver::Stop()
}
}
void
AudioCallbackDriver::Revive()
{
// Note: only called on MainThread, without monitor
// We know were weren't in a running state
- LOG(LogLevel::Debug, ("AudioCallbackDriver reviving."));
+ LOG(LogLevel::Debug, ("%p: AudioCallbackDriver reviving.", GraphImpl()));
// If we were switching, switch now. Otherwise, start the audio thread again.
- MonitorAutoLock mon(mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(GraphImpl()->GetMonitor());
if (NextDriver()) {
RemoveCallback();
SwitchToNextDriver();
} else {
LOG(LogLevel::Debug,
- ("Starting audio threads for MediaStreamGraph %p from a new thread.",
- mGraphImpl));
+ ("%p: Starting audio threads for MediaStreamGraph from a new thread.",
+ GraphImpl()));
RefPtr<AsyncCubebTask> initEvent =
new AsyncCubebTask(this, AsyncCubebOperation::INIT);
initEvent->Dispatch();
}
}
void
AudioCallbackDriver::RemoveCallback()
{
if (mAddedMixer) {
- mGraphImpl->mMixer.RemoveCallback(this);
+ GraphImpl()->mMixer.RemoveCallback(this);
mAddedMixer = false;
}
}
void
AudioCallbackDriver::WaitForNextIteration()
{
}
void
AudioCallbackDriver::WakeUp()
{
- mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
- mGraphImpl->GetMonitor().Notify();
+ GraphImpl()->GetMonitor().AssertCurrentThreadOwns();
+ GraphImpl()->GetMonitor().Notify();
}
void
AudioCallbackDriver::Shutdown()
{
LOG(LogLevel::Debug,
- ("Releasing audio driver off main thread (GraphDriver::Shutdown)."));
+ ("%p: Releasing audio driver off main thread (GraphDriver::Shutdown).", GraphImpl()));
RefPtr<AsyncCubebTask> releaseEvent =
new AsyncCubebTask(this, AsyncCubebOperation::SHUTDOWN);
releaseEvent->Dispatch(NS_DISPATCH_SYNC);
}
#if defined(XP_WIN)
void
AudioCallbackDriver::ResetDefaultDevice()
@@ -880,32 +890,32 @@ AudioCallbackDriver::DataCallback(const
TRACE_AUDIO_CALLBACK();
#ifdef DEBUG
AutoInCallback aic(this);
#endif
// Don't add the callback until we're inited and ready
if (!mAddedMixer) {
- mGraphImpl->mMixer.AddCallback(this);
+ GraphImpl()->mMixer.AddCallback(this);
mAddedMixer = true;
}
GraphTime stateComputedTime = StateComputedTime();
if (stateComputedTime == 0) {
- MonitorAutoLock mon(mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(GraphImpl()->GetMonitor());
// Because this function is called during cubeb_stream_init (to prefill the
// audio buffers), it can be that we don't have a message here (because this
// driver is the first one for this graph), and the graph would exit. Simply
// return here until we have messages.
- if (!mGraphImpl->MessagesQueued()) {
+ if (!GraphImpl()->MessagesQueued()) {
PodZero(aOutputBuffer, aFrames * mOutputChannels);
return aFrames;
}
- mGraphImpl->SwapMessageQueues();
+ GraphImpl()->SwapMessageQueues();
}
uint32_t durationMS = aFrames * 1000 / mSampleRate;
// For now, simply average the duration with the previous
// duration so there is some damping against sudden changes.
if (!mIterationDurationMS) {
mIterationDurationMS = durationMS;
@@ -918,105 +928,106 @@ AudioCallbackDriver::DataCallback(const
// fill part or all with leftover data from last iteration (since we
// align to Audio blocks)
mScratchBuffer.Empty(mBuffer);
// State computed time is decided by the audio callback's buffer length. We
// compute the iteration start and end from there, trying to keep the amount
// of buffering in the graph constant.
GraphTime nextStateComputedTime =
- mGraphImpl->RoundUpToEndOfAudioBlock(
+ GraphImpl()->RoundUpToEndOfAudioBlock(
stateComputedTime + mBuffer.Available());
mIterationStart = mIterationEnd;
// inGraph is the number of audio frames there is between the state time and
// the current time, i.e. the maximum theoretical length of the interval we
// could use as [mIterationStart; mIterationEnd].
GraphTime inGraph = stateComputedTime - mIterationStart;
// We want the interval [mIterationStart; mIterationEnd] to be before the
// interval [stateComputedTime; nextStateComputedTime]. We also want
// the distance between these intervals to be roughly equivalent each time, to
// ensure there is no clock drift between current time and state time. Since
// we can't act on the state time because we have to fill the audio buffer, we
// reclock the current time against the state time, here.
mIterationEnd = mIterationStart + 0.8 * inGraph;
LOG(LogLevel::Verbose,
- ("interval[%ld; %ld] state[%ld; %ld] (frames: %ld) (durationMS: %u) "
+ ("%p: interval[%ld; %ld] state[%ld; %ld] (frames: %ld) (durationMS: %u) "
"(duration ticks: %ld)",
+ GraphImpl(),
(long)mIterationStart,
(long)mIterationEnd,
(long)stateComputedTime,
(long)nextStateComputedTime,
(long)aFrames,
(uint32_t)durationMS,
(long)(nextStateComputedTime - stateComputedTime)));
mCurrentTimeStamp = TimeStamp::Now();
if (stateComputedTime < mIterationEnd) {
- LOG(LogLevel::Error, ("Media graph global underrun detected"));
+ LOG(LogLevel::Error, ("%p: Media graph global underrun detected", GraphImpl()));
MOZ_ASSERT_UNREACHABLE("We should not underrun in full duplex");
mIterationEnd = stateComputedTime;
}
// Process mic data if any/needed
if (aInputBuffer && mInputChannelCount) {
GraphImpl()->NotifyInputData(aInputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mInputChannelCount);
}
bool stillProcessing;
if (mBuffer.Available()) {
// We totally filled the buffer (and mScratchBuffer isn't empty).
// We don't need to run an iteration and if we do so we may overflow.
- stillProcessing = mGraphImpl->OneIteration(nextStateComputedTime);
+ stillProcessing = GraphImpl()->OneIteration(nextStateComputedTime);
} else {
LOG(LogLevel::Verbose,
- ("DataCallback buffer filled entirely from scratch "
- "buffer, skipping iteration."));
+ ("%p: DataCallback buffer filled entirely from scratch "
+ "buffer, skipping iteration.", GraphImpl()));
stillProcessing = true;
}
mBuffer.BufferFilled();
// Callback any observers for the AEC speaker data. Note that one
// (maybe) of these will be full-duplex, the others will get their input
// 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.
- mGraphImpl->NotifyOutputData(aOutputBuffer, static_cast<size_t>(aFrames),
+ GraphImpl()->NotifyOutputData(aOutputBuffer, static_cast<size_t>(aFrames),
mSampleRate, mOutputChannels);
if (!stillProcessing) {
// About to hand over control of the graph. Do not start a new driver if
// StateCallback() receives an error for this stream while the main thread
// or another driver has control of the graph.
mShouldFallbackIfError = false;
// Enter shutdown mode. The stable-state handler will detect this
// and complete shutdown if the graph does not get restarted.
- mGraphImpl->SignalMainThreadCleanup();
+ GraphImpl()->SignalMainThreadCleanup();
return aFrames - 1;
}
bool switching = false;
{
- MonitorAutoLock mon(mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(GraphImpl()->GetMonitor());
switching = !!NextDriver();
}
if (switching) {
mShouldFallbackIfError = false;
// If the audio stream has not been started by the previous driver or
// the graph itself, keep it alive.
- MonitorAutoLock mon(mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(GraphImpl()->GetMonitor());
if (!IsStarted()) {
return aFrames;
}
- LOG(LogLevel::Debug, ("Switching to system driver."));
+ LOG(LogLevel::Debug, ("%p: Switching to system driver.", GraphImpl()));
RemoveCallback();
SwitchToNextDriver();
// Returning less than aFrames starts the draining and eventually stops the
// audio thread. This function will never get called again.
return aFrames - 1;
}
return aFrames;
@@ -1119,17 +1130,17 @@ AudioCallbackDriver::IsStarted() {
return mStarted;
}
void
AudioCallbackDriver::EnqueueStreamAndPromiseForOperation(MediaStream* aStream,
void* aPromise,
dom::AudioContextOperation aOperation)
{
- MonitorAutoLock mon(mGraphImpl->GetMonitor());
+ MonitorAutoLock mon(GraphImpl()->GetMonitor());
mPromisesForOperation.AppendElement(StreamAndPromiseForOperation(aStream,
aPromise,
aOperation));
}
void AudioCallbackDriver::CompleteAudioContextOperations(AsyncCubebOperation aOperation)
{
AutoTArray<StreamAndPromiseForOperation, 1> array;
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -67,16 +67,17 @@ static nsDataHashtable<nsUint32HashKey,
MediaStreamGraphImpl::~MediaStreamGraphImpl()
{
MOZ_ASSERT(mStreams.IsEmpty() && mSuspendedStreams.IsEmpty(),
"All streams should have been destroyed by messages from the main thread");
LOG(LogLevel::Debug, ("MediaStreamGraph %p destroyed", this));
LOG(LogLevel::Debug, ("MediaStreamGraphImpl::~MediaStreamGraphImpl"));
+
#ifdef TRACING
gMSGTraceLogger.Stop();
#endif
}
void
MediaStreamGraphImpl::AddStreamGraphThread(MediaStream* aStream)
{
@@ -89,29 +90,29 @@ MediaStreamGraphImpl::AddStreamGraphThre
TimeStamp processedTimeStamp = currentTimeStamp +
TimeDuration::FromSeconds(MediaTimeToSeconds(mProcessedTime - IterationEnd()));
source->SetStreamTracksStartTimeStamp(processedTimeStamp);
}
if (aStream->IsSuspended()) {
mSuspendedStreams.AppendElement(aStream);
LOG(LogLevel::Debug,
- ("Adding media stream %p to the graph, in the suspended stream array",
- aStream));
+ ("%p: Adding media stream %p, in the suspended stream array",
+ this, aStream));
} else {
mStreams.AppendElement(aStream);
LOG(LogLevel::Debug,
- ("Adding media stream %p to graph %p, count %zu",
+ ("%p: Adding media stream %p, count %zu",
+ this,
aStream,
- this,
mStreams.Length()));
LOG(LogLevel::Debug,
- ("Adding media stream %p to graph %p, count %zu",
+ ("%p: Adding media stream %p, count %zu",
+ this,
aStream,
- this,
mStreams.Length()));
}
SetStreamOrderDirty();
}
void
MediaStreamGraphImpl::RemoveStreamGraphThread(MediaStream* aStream)
@@ -134,24 +135,24 @@ MediaStreamGraphImpl::RemoveStreamGraphT
if (aStream->IsSuspended()) {
mSuspendedStreams.RemoveElement(aStream);
} else {
mStreams.RemoveElement(aStream);
}
LOG(LogLevel::Debug,
- ("Removed media stream %p from graph %p, count %zu",
+ ("%p: Removed media stream %p, count %zu",
+ this,
aStream,
- this,
mStreams.Length()));
LOG(LogLevel::Debug,
- ("Removed media stream %p from graph %p, count %zu",
+ ("%p: Removed media stream %p, count %zu",
+ this,
aStream,
- this,
mStreams.Length()));
NS_RELEASE(aStream); // probably destroying it
}
StreamTime
MediaStreamGraphImpl::GraphTimeToStreamTimeWithBlocking(const MediaStream* aStream,
GraphTime aTime) const
@@ -178,17 +179,18 @@ MediaStreamGraphImpl::UpdateCurrentTimeF
bool isAnyUnblocked = stream->mStartBlocking > aPrevCurrentTime;
// Calculate blocked time and fire Blocked/Unblocked events
GraphTime blockedTime = mStateComputedTime - stream->mStartBlocking;
NS_ASSERTION(blockedTime >= 0, "Error in blocking time");
stream->AdvanceTimeVaryingValuesToCurrentTime(mStateComputedTime,
blockedTime);
LOG(LogLevel::Verbose,
- ("MediaStream %p bufferStartTime=%f blockedTime=%f",
+ ("%p: MediaStream %p bufferStartTime=%f blockedTime=%f",
+ this,
stream,
MediaTimeToSeconds(stream->mTracksStartTime),
MediaTimeToSeconds(blockedTime)));
stream->mStartBlocking = mStateComputedTime;
if (isAnyUnblocked && stream->mNotifiedBlocked) {
for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) {
MediaStreamListener* l = stream->mListeners[j];
@@ -249,18 +251,19 @@ MediaStreamGraphImpl::ProcessChunkMetada
offset += chunk->GetDuration();
if (chunk->IsNull() || offset < aStart) {
continue;
}
const PrincipalHandle& principalHandle = chunk->GetPrincipalHandle();
if (principalHandle != aSegment.GetLastPrincipalHandle()) {
aSegment.SetLastPrincipalHandle(principalHandle);
LOG(LogLevel::Debug,
- ("MediaStream %p track %d, principalHandle "
+ ("%p: MediaStream %p track %d, principalHandle "
"changed in %sChunk with duration %lld",
+ this,
aStream,
aTrackID,
aSegment.GetType() == MediaSegment::AUDIO ? "Audio" : "Video",
(long long)chunk->GetDuration()));
for (const TrackBound<MediaStreamTrackListener>& listener :
aStream->mTrackListeners) {
if (listener.mTrackID == aTrackID) {
listener.mListener->NotifyPrincipalHandleChanged(this, principalHandle);
@@ -310,19 +313,20 @@ MediaStreamGraphImpl::WillUnderrun(Media
}
// This stream isn't finished or suspended. We don't need to call
// StreamTimeToGraphTime since an underrun is the only thing that can block
// it.
GraphTime bufferEnd = aStream->GetTracksEnd() + aStream->mTracksStartTime;
#ifdef DEBUG
if (bufferEnd < mProcessedTime) {
LOG(LogLevel::Error,
- ("MediaStream %p underrun, "
+ ("%p: MediaStream %p underrun, "
"bufferEnd %f < mProcessedTime %f (%" PRId64 " < %" PRId64
"), Streamtime %" PRId64,
+ this,
aStream,
MediaTimeToSeconds(bufferEnd),
MediaTimeToSeconds(mProcessedTime),
bufferEnd,
mProcessedTime,
aStream->GetTracksEnd()));
aStream->DumpTrackInfo();
NS_ASSERTION(bufferEnd >= mProcessedTime, "Buffer underran");
@@ -625,17 +629,17 @@ MediaStreamGraphImpl::CreateOrDestroyAud
}
if (!aStream->GetStreamTracks().GetAndResetTracksDirty() &&
!aStream->mAudioOutputStreams.IsEmpty()) {
return;
}
LOG(LogLevel::Debug,
- ("Updating AudioOutputStreams for MediaStream %p", aStream));
+ ("%p: Updating AudioOutputStreams for MediaStream %p", this, aStream));
AutoTArray<bool,2> audioOutputStreamsFound;
for (uint32_t i = 0; i < aStream->mAudioOutputStreams.Length(); ++i) {
audioOutputStreamsFound.AppendElement(false);
}
for (StreamTracks::TrackIter tracks(aStream->GetStreamTracks(), MediaSegment::AUDIO);
!tracks.IsEnded(); tracks.Next()) {
@@ -717,32 +721,34 @@ MediaStreamGraphImpl::PlayAudio(MediaStr
// Check how many ticks of sound we can provide if we are blocked some
// time in the middle of this cycle.
StreamTime toWrite = end - t;
if (blocked) {
output.InsertNullDataAtStart(toWrite);
ticksWritten += toWrite;
LOG(LogLevel::Verbose,
- ("MediaStream %p writing %" PRId64 " blocking-silence samples for "
+ ("%p: MediaStream %p writing %" PRId64 " blocking-silence samples for "
"%f to %f (%" PRId64 " to %" PRId64 ")",
+ this,
aStream,
toWrite,
MediaTimeToSeconds(t),
MediaTimeToSeconds(end),
offset,
offset + toWrite));
} else {
StreamTime endTicksNeeded = offset + toWrite;
StreamTime endTicksAvailable = audio->GetDuration();
if (endTicksNeeded <= endTicksAvailable) {
LOG(LogLevel::Verbose,
- ("MediaStream %p writing %" PRId64 " samples for %f to %f "
+ ("%p: MediaStream %p writing %" PRId64 " samples for %f to %f "
"(samples %" PRId64 " to %" PRId64 ")",
+ this,
aStream,
toWrite,
MediaTimeToSeconds(t),
MediaTimeToSeconds(end),
offset,
endTicksNeeded));
output.AppendSlice(*audio, offset, endTicksNeeded);
ticksWritten += toWrite;
@@ -750,33 +756,35 @@ MediaStreamGraphImpl::PlayAudio(MediaStr
} else {
// MOZ_ASSERT(track->IsEnded(), "Not enough data, and track not ended.");
// If we are at the end of the track, maybe write the remaining
// samples, and pad with/output silence.
if (endTicksNeeded > endTicksAvailable &&
offset < endTicksAvailable) {
output.AppendSlice(*audio, offset, endTicksAvailable);
LOG(LogLevel::Verbose,
- ("MediaStream %p writing %" PRId64 " samples for %f to %f "
+ ("%p: MediaStream %p writing %" PRId64 " samples for %f to %f "
"(samples %" PRId64 " to %" PRId64 ")",
+ this,
aStream,
toWrite,
MediaTimeToSeconds(t),
MediaTimeToSeconds(end),
offset,
endTicksNeeded));
uint32_t available = endTicksAvailable - offset;
ticksWritten += available;
toWrite -= available;
offset = endTicksAvailable;
}
output.AppendNullData(toWrite);
LOG(LogLevel::Verbose,
- ("MediaStream %p writing %" PRId64 " padding slsamples for %f to "
+ ("%p MediaStream %p writing %" PRId64 " padding slsamples for %f to "
"%f (samples %" PRId64 " to %" PRId64 ")",
+ this,
aStream,
toWrite,
MediaTimeToSeconds(t),
MediaTimeToSeconds(end),
offset,
endTicksNeeded));
ticksWritten += toWrite;
}
@@ -784,17 +792,17 @@ MediaStreamGraphImpl::PlayAudio(MediaStr
}
t = end;
}
audioOutput.mLastTickWritten = offset;
// Need unique id for stream & track - and we want it to match the inserter
output.WriteTo(LATENCY_STREAM_ID(aStream, track->GetID()),
mMixer,
- AudioChannelCount(),
+ AudioOutputChannelCount(),
mSampleRate);
}
return ticksWritten;
}
void
MediaStreamGraphImpl::OpenAudioInputImpl(CubebUtils::AudioDeviceID aID,
AudioDataListener *aListener)
@@ -816,21 +824,17 @@ MediaStreamGraphImpl::OpenAudioInputImpl
if (listeners.Length() == 1) { // first open for this device
mInputDeviceID = aID;
// Switch Drivers since we're adding input (to input-only or full-duplex)
MonitorAutoLock mon(mMonitor);
if (LifecycleStateRef() == LIFECYCLE_RUNNING) {
AudioCallbackDriver* driver = new AudioCallbackDriver(this, AudioInputChannelCount());
LOG(
LogLevel::Debug,
- ("OpenAudioInput: starting new AudioCallbackDriver(input) %p", driver));
- LOG(
- LogLevel::Debug,
- ("OpenAudioInput: starting new AudioCallbackDriver(input) %p", driver));
- driver->SetInputListener(aListener);
+ ("%p OpenAudioInput: starting new AudioCallbackDriver(input) %p", this, driver));
CurrentDriver()->SwitchAtNextIteration(driver);
} else {
LOG(LogLevel::Error, ("OpenAudioInput in shutdown!"));
MOZ_ASSERT(false, "Can't open cubeb inputs in shutdown");
}
}
}
@@ -902,17 +906,17 @@ MediaStreamGraphImpl::CloseAudioInputImp
if (audioTrackPresent) {
// We still have audio output
LOG(LogLevel::Debug, ("%p: CloseInput: output present (AudioCallback)", this));
driver = new AudioCallbackDriver(this, AudioInputChannelCount());
CurrentDriver()->SwitchAtNextIteration(driver);
} else if (CurrentDriver()->AsAudioCallbackDriver()) {
LOG(LogLevel::Debug,
- ("CloseInput: no output present (SystemClockCallback)"));
+ ("%p: CloseInput: no output present (SystemClockCallback)", this));
driver = new SystemClockDriver(this);
CurrentDriver()->SwitchAtNextIteration(driver);
} // else SystemClockDriver->SystemClockDriver, no switch
}
}
void
@@ -1171,17 +1175,16 @@ MediaStreamGraphImpl::RunMessageAfterPro
// Only one block is used for messages from the graph thread.
MOZ_ASSERT(mFrontMessageQueue.Length() == 1);
mFrontMessageQueue[0].mMessages.AppendElement(Move(aMessage));
}
void
MediaStreamGraphImpl::RunMessagesInQueue()
{
- TRACE_AUDIO_CALLBACK();
MOZ_ASSERT(OnGraphThread());
// Calculate independent action times for each batch of messages (each
// batch corresponding to an event loop task). This isolates the performance
// of different scripts to some extent.
for (uint32_t i = 0; i < mFrontMessageQueue.Length(); ++i) {
nsTArray<UniquePtr<ControlMessage>>& messages = mFrontMessageQueue[i].mMessages;
for (uint32_t j = 0; j < messages.Length(); ++j) {
@@ -1214,22 +1217,23 @@ MediaStreamGraphImpl::UpdateGraph(GraphT
if (stream->mFinished) {
// The stream's not suspended, and since it's finished, underruns won't
// stop it playing out. So there's no blocking other than what we impose
// here.
GraphTime endTime = stream->GetStreamTracks().GetAllTracksEnd() +
stream->mTracksStartTime;
if (endTime <= mStateComputedTime) {
LOG(LogLevel::Verbose,
- ("MediaStream %p is blocked due to being finished", stream));
+ ("%p: MediaStream %p is blocked due to being finished", this, stream));
stream->mStartBlocking = mStateComputedTime;
} else {
LOG(LogLevel::Verbose,
- ("MediaStream %p is finished, but not blocked yet (end at %f, with "
+ ("%p: MediaStream %p is finished, but not blocked yet (end at %f, with "
"blocking at %f)",
+ this,
stream,
MediaTimeToSeconds(stream->GetTracksEnd()),
MediaTimeToSeconds(endTime)));
// Data can't be added to a finished stream, so underruns are irrelevant.
stream->mStartBlocking = std::min(endTime, aEndBlockingDecisions);
}
} else {
stream->mStartBlocking = WillUnderrun(stream, aEndBlockingDecisions);
@@ -1237,18 +1241,19 @@ MediaStreamGraphImpl::UpdateGraph(GraphT
SourceMediaStream* s = stream->AsSourceStream();
if (s && s->mPullEnabled) {
for (StreamTracks::TrackIter i(s->mTracks); !i.IsEnded(); i.Next()) {
if (i->IsEnded()) {
continue;
}
if (i->GetEnd() < stream->GraphTimeToStreamTime(aEndBlockingDecisions)) {
LOG(LogLevel::Error,
- ("SourceMediaStream %p track %u (%s) is live and pulled, but wasn't fed "
+ ("%p: SourceMediaStream %p track %u (%s) is live and pulled, but wasn't fed "
"enough data. Listeners=%zu. Track-end=%f, Iteration-end=%f",
+ this,
stream,
i->GetID(),
(i->GetType() == MediaSegment::AUDIO ? "audio" : "video"),
stream->mListeners.Length(),
MediaTimeToSeconds(i->GetEnd()),
MediaTimeToSeconds(stream->GraphTimeToStreamTime(aEndBlockingDecisions))));
MOZ_DIAGNOSTIC_ASSERT(false,
"A non-finished SourceMediaStream wasn't fed "
@@ -1432,17 +1437,17 @@ MediaStreamGraphImpl::ApplyStreamUpdate(
stream->NotifyMainThreadListeners();
}
}
void
MediaStreamGraphImpl::ForceShutDown(media::ShutdownTicket* aShutdownTicket)
{
MOZ_ASSERT(NS_IsMainThread(), "Must be called on main thread");
- LOG(LogLevel::Debug, ("MediaStreamGraph %p ForceShutdown", this));
+ LOG(LogLevel::Debug, ("%p: MediaStreamGraph::ForceShutdown", this));
if (aShutdownTicket) {
MOZ_ASSERT(!mForceShutdownTicket);
// Avoid waiting forever for a graph to shut down
// synchronously. Reports are that some 3rd-party audio drivers
// occasionally hang in shutdown (both for us and Chrome).
NS_NewTimerWithCallback(getter_AddRefs(mShutdownTimer),
this,
@@ -1492,17 +1497,17 @@ public:
, mGraph(aGraph)
{}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mGraph->mDetectedNotRunning && mGraph->mDriver,
"We should know the graph thread control loop isn't running!");
- LOG(LogLevel::Debug, ("Shutting down graph %p", mGraph.get()));
+ LOG(LogLevel::Debug, ("%p: Shutting down graph", mGraph.get()));
// We've asserted the graph isn't running. Use mDriver instead of CurrentDriver
// to avoid thread-safety checks
#if 0 // AudioCallbackDrivers are released asynchronously anyways
// XXX a better test would be have setting mDetectedNotRunning make sure
// any current callback has finished and block future ones -- or just
// handle it all in Shutdown()!
if (mGraph->mDriver->AsAudioCallbackDriver()) {
@@ -1643,17 +1648,17 @@ MediaStreamGraphImpl::RunInStableState(b
"LIFECYCLE_RUNNING",
"LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP",
"LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN",
"LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION"
};
if (LifecycleStateRef() != LIFECYCLE_RUNNING) {
LOG(LogLevel::Debug,
- ("Running %p in stable state. Current state: %s",
+ ("%p: Running stable state callback. Current state: %s",
this,
LifecycleState_str[LifecycleStateRef()]));
}
runnables.SwapElements(mUpdateRunnables);
for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
StreamUpdate* update = &mStreamUpdates[i];
if (update->mStream) {
@@ -1666,21 +1671,21 @@ MediaStreamGraphImpl::RunInStableState(b
if (LifecycleStateRef() == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP && IsEmpty()) {
// Complete shutdown. First, ensure that this graph is no longer used.
// A new graph graph will be created if one is needed.
// Asynchronously clean up old graph. We don't want to do this
// synchronously because it spins the event loop waiting for threads
// to shut down, and we don't want to do that in a stable state handler.
LifecycleStateRef() = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
LOG(LogLevel::Debug,
- ("Sending MediaStreamGraphShutDownRunnable %p", this));
+ ("%p: Sending MediaStreamGraphShutDownRunnable", this));
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutDownRunnable(this );
mAbstractMainThread->Dispatch(event.forget());
- LOG(LogLevel::Debug, ("Disconnecting MediaStreamGraph %p", this));
+ LOG(LogLevel::Debug, ("%p: Disconnecting MediaStreamGraph", this));
// Find the graph in the hash table and remove it.
for (auto iter = gGraphs.Iter(); !iter.Done(); iter.Next()) {
if (iter.UserData() == this) {
iter.Remove();
break;
}
}
@@ -1699,20 +1704,20 @@ MediaStreamGraphImpl::RunInStableState(b
if (LifecycleStateRef() == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP &&
mRealtime && !mForceShutDown) {
LifecycleStateRef() = LIFECYCLE_RUNNING;
// Revive the MediaStreamGraph since we have more messages going to it.
// Note that we need to put messages into its queue before reviving it,
// or it might exit immediately.
{
LOG(LogLevel::Debug,
- ("Reviving a graph (%p) ! %s",
+ ("%p: Reviving this graph! %s",
this,
- CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver"
- : "SystemDriver"));
+ CurrentDriver()->AsAudioCallbackDriver() ? "AudioCallbackDriver"
+ : "SystemClockDriver"));
RefPtr<GraphDriver> driver = CurrentDriver();
MonitorAutoUnlock unlock(mMonitor);
driver->Revive();
}
}
}
// Don't start the thread for a non-realtime graph until it has been
@@ -1722,20 +1727,20 @@ MediaStreamGraphImpl::RunInStableState(b
LifecycleStateRef() = LIFECYCLE_RUNNING;
// Start the thread now. We couldn't start it earlier because
// the graph might exit immediately on finding it has no streams. The
// first message for a new graph must create a stream.
{
// We should exit the monitor for now, because starting a stream might
// take locks, and we don't want to deadlock.
LOG(LogLevel::Debug,
- ("Starting a graph (%p) ! %s",
+ ("%p: Starting a graph with a %s",
this,
- CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver"
- : "SystemDriver"));
+ CurrentDriver()->AsAudioCallbackDriver() ? "AudioCallbackDriver"
+ : "SystemClockDriver"));
RefPtr<GraphDriver> driver = CurrentDriver();
MonitorAutoUnlock unlock(mMonitor);
driver->Start();
// It's not safe to Shutdown() a thread from StableState, and
// releasing this may shutdown a SystemClockDriver thread.
// Proxy the release to outside of StableState.
NS_ReleaseOnMainThreadSystemGroup(
"MediaStreamGraphImpl::CurrentDriver", driver.forget(),
@@ -1813,17 +1818,17 @@ MediaStreamGraphImpl::SignalMainThreadCl
{
MOZ_ASSERT(mDriver->OnThread());
MonitorAutoLock lock(mMonitor);
// LIFECYCLE_THREAD_NOT_STARTED is possible when shutting down offline
// graphs that have not started.
MOZ_DIAGNOSTIC_ASSERT(mLifecycleState <= LIFECYCLE_RUNNING);
LOG(LogLevel::Debug,
- ("MediaStreamGraph %p waiting for main thread cleanup", this));
+ ("%p: MediaStreamGraph waiting for main thread cleanup", this));
LifecycleStateRef() =
MediaStreamGraphImpl::LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
EnsureStableStateEventPosted();
}
void
MediaStreamGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage)
{
@@ -2814,17 +2819,18 @@ SourceMediaStream::PullNewData(StreamTim
if (!mPullEnabled || mFinished) {
return false;
}
// Compute how much stream time we'll need assuming we don't block
// the stream at all.
StreamTime t = GraphTimeToStreamTime(aDesiredUpToTime);
StreamTime current = mTracks.GetEnd();
LOG(LogLevel::Verbose,
- ("Calling NotifyPull aStream=%p t=%f current end=%f",
+ ("%p: Calling NotifyPull aStream=%p t=%f current end=%f",
+ GraphImpl(),
this,
GraphImpl()->MediaTimeToSeconds(t),
GraphImpl()->MediaTimeToSeconds(current)));
if (t <= current) {
return false;
}
for (uint32_t j = 0; j < mListeners.Length(); ++j) {
MediaStreamListener* l = mListeners[j];
@@ -2915,35 +2921,37 @@ SourceMediaStream::ExtractPendingInput()
b.mListener->NotifyQueuedChanges(GraphImpl(), offset, *data->mData);
if (data->mCommands & SourceMediaStream::TRACK_END) {
b.mListener->NotifyEnded();
}
}
if (data->mCommands & SourceMediaStream::TRACK_CREATE) {
MediaSegment* segment = data->mData.forget();
LOG(LogLevel::Debug,
- ("SourceMediaStream %p creating track %d, start %" PRId64
+ ("%p: SourceMediaStream %p creating track %d, start %" PRId64
", initial end %" PRId64,
+ GraphImpl(),
this,
data->mID,
int64_t(data->mStart),
int64_t(segment->GetDuration())));
data->mEndOfFlushedData += segment->GetDuration();
mTracks.AddTrack(data->mID, data->mStart, segment);
// The track has taken ownership of data->mData, so let's replace
// data->mData with an empty clone.
data->mData = segment->CreateEmptyClone();
data->mCommands &= ~SourceMediaStream::TRACK_CREATE;
shouldNotifyTrackCreated = true;
} else if (data->mData->GetDuration() > 0) {
MediaSegment* dest = mTracks.FindTrack(data->mID)->GetSegment();
LOG(LogLevel::Verbose,
- ("SourceMediaStream %p track %d, advancing end from %" PRId64
+ ("%p: SourceMediaStream %p track %d, advancing end from %" PRId64
" to %" PRId64,
+ GraphImpl(),
this,
data->mID,
int64_t(dest->GetDuration()),
int64_t(dest->GetDuration() + data->mData->GetDuration())));
data->mEndOfFlushedData += data->mData->GetDuration();
dest->AppendFrom(data->mData);
}
if (data->mCommands & SourceMediaStream::TRACK_END) {
@@ -2973,17 +2981,18 @@ void
SourceMediaStream::AddTrackInternal(TrackID aID, TrackRate aRate, StreamTime aStart,
MediaSegment* aSegment, uint32_t aFlags)
{
MutexAutoLock lock(mMutex);
nsTArray<TrackData> *track_data = (aFlags & ADDTRACK_QUEUED) ?
&mPendingTracks : &mUpdateTracks;
TrackData* data = track_data->AppendElement();
LOG(LogLevel::Debug,
- ("AddTrackInternal: %lu/%lu",
+ ("%p: AddTrackInternal: %lu/%lu",
+ GraphImpl(),
(long)mPendingTracks.Length(),
(long)mUpdateTracks.Length()));
data->mID = aID;
data->mInputRate = aRate;
data->mResamplerChannelCount = 0;
data->mStart = aStart;
data->mEndOfFlushedData = aStart;
data->mCommands = TRACK_CREATE;
@@ -3002,17 +3011,18 @@ SourceMediaStream::AddAudioTrack(TrackID
}
void
SourceMediaStream::FinishAddTracks()
{
MutexAutoLock lock(mMutex);
mUpdateTracks.AppendElements(Move(mPendingTracks));
LOG(LogLevel::Debug,
- ("FinishAddTracks: %lu/%lu",
+ ("%p: FinishAddTracks: %lu/%lu",
+ GraphImpl(),
(long)mPendingTracks.Length(),
(long)mUpdateTracks.Length()));
if (GraphImpl()) {
GraphImpl()->EnsureNextIteration();
}
}
void
@@ -3133,38 +3143,40 @@ void
SourceMediaStream::AddDirectTrackListenerImpl(already_AddRefed<DirectMediaStreamTrackListener> aListener,
TrackID aTrackID)
{
MOZ_ASSERT(IsTrackIDExplicit(aTrackID));
MutexAutoLock lock(mMutex);
RefPtr<DirectMediaStreamTrackListener> listener = aListener;
LOG(LogLevel::Debug,
- ("Adding direct track listener %p bound to track %d to source stream %p",
+ ("%p: Adding direct track listener %p bound to track %d to source stream %p",
+ GraphImpl(),
listener.get(),
aTrackID,
this));
StreamTracks::Track* track = FindTrack(aTrackID);
if (!track) {
LOG(LogLevel::Warning,
- ("Couldn't find source track for direct track listener %p",
+ ("%p: Couldn't find source track for direct track listener %p",
+ GraphImpl(),
listener.get()));
listener->NotifyDirectListenerInstalled(
DirectMediaStreamTrackListener::InstallationResult::TRACK_NOT_FOUND_AT_SOURCE);
return;
}
bool isAudio = track->GetType() == MediaSegment::AUDIO;
bool isVideo = track->GetType() == MediaSegment::VIDEO;
if (!isAudio && !isVideo) {
LOG(
LogLevel::Warning,
- ("Source track for direct track listener %p is unknown", listener.get()));
+ ("%p: Source track for direct track listener %p is unknown", GraphImpl(), listener.get()));
MOZ_ASSERT(false);
return;
}
for (auto entry : mDirectTrackListeners) {
if (entry.mListener == listener &&
(entry.mTrackID == TRACK_ANY || entry.mTrackID == aTrackID)) {
listener->NotifyDirectListenerInstalled(
@@ -3173,17 +3185,17 @@ SourceMediaStream::AddDirectTrackListene
}
}
TrackBound<DirectMediaStreamTrackListener>* sourceListener =
mDirectTrackListeners.AppendElement();
sourceListener->mListener = listener;
sourceListener->mTrackID = aTrackID;
- LOG(LogLevel::Debug, ("Added direct track listener %p", listener.get()));
+ LOG(LogLevel::Debug, ("%p: Added direct track listener %p", GraphImpl(), listener.get()));
listener->NotifyDirectListenerInstalled(
DirectMediaStreamTrackListener::InstallationResult::SUCCESS);
// Pass buffered data to the listener
AudioSegment bufferedAudio;
VideoSegment bufferedVideo;
MediaSegment& bufferedData =
isAudio ? static_cast<MediaSegment&>(bufferedAudio)
@@ -3274,25 +3286,27 @@ SourceMediaStream::SetTrackEnabledImpl(T
for (TrackBound<DirectMediaStreamTrackListener>& l: mDirectTrackListeners) {
if (l.mTrackID != aTrackID) {
continue;
}
DisabledTrackMode oldMode = GetDisabledTrackMode(aTrackID);
bool oldEnabled = oldMode == DisabledTrackMode::ENABLED;
if (!oldEnabled && aMode == DisabledTrackMode::ENABLED) {
LOG(LogLevel::Debug,
- ("SourceMediaStream %p track %d setting "
+ ("%p: SourceMediaStream %p track %d setting "
"direct listener enabled",
+ GraphImpl(),
this,
aTrackID));
l.mListener->DecreaseDisabled(oldMode);
} else if (oldEnabled && aMode != DisabledTrackMode::ENABLED) {
LOG(LogLevel::Debug,
- ("SourceMediaStream %p track %d setting "
+ ("%p: SourceMediaStream %p track %d setting "
"direct listener disabled",
+ GraphImpl(),
this,
aTrackID));
l.mListener->IncreaseDisabled(aMode);
}
}
}
MediaStream::SetTrackEnabledImpl(aTrackID, aMode);
}
@@ -3355,17 +3369,18 @@ SourceMediaStream::HasPendingAudioTrack(
return audioTrackPresent;
}
void
MediaInputPort::Init()
{
LOG(LogLevel::Debug,
- ("Adding MediaInputPort %p (from %p to %p) to the graph",
+ ("%p: Adding MediaInputPort %p (from %p to %p)",
+ mSource->GraphImpl(),
this,
mSource,
mDest));
mSource->AddConsumer(this);
mDest->AddInput(this);
// mPortCount decremented via MediaInputPort::Destroy's message
++mDest->GraphImpl()->mPortCount;
}
@@ -3756,17 +3771,17 @@ MediaStreamGraph::GetInstance(MediaStrea
graph = new MediaStreamGraphImpl(aGraphDriverRequested,
sampleRate,
mainThread);
uint32_t hashkey = WindowToHash(aWindow, sampleRate);
gGraphs.Put(hashkey, graph);
LOG(LogLevel::Debug,
- ("Starting up MediaStreamGraph %p for window %p for sample rate %d", graph, aWindow, sampleRate));
+ ("Starting up MediaStreamGraph %p for window %p", graph, aWindow));
}
return graph;
}
MediaStreamGraph*
MediaStreamGraph::CreateNonRealtimeInstance(TrackRate aSampleRate,
nsPIDOMWindowInner* aWindow)