Bug 1443886 - Bounce dispatches to the main thread on another thread. f?pehrsons
MozReview-Commit-ID: Lnujy5kdvo2
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -1481,16 +1481,17 @@ public:
{
MonitorAutoLock mon(mGraph->mMonitor);
mGraph->SetCurrentDriver(nullptr);
}
// Do not hold on our threadpool, global shutdown will hang otherwise as
// it waits for all thread pools to shutdown.
mGraph->mThreadPool = nullptr;
+ mGraph->mDispatchBounceThread = nullptr;
// Safe to access these without the monitor since the graph isn't running.
// We may be one of several graphs. Drop ticket to eventually unblock shutdown.
if (mGraph->mShutdownTimer && !mGraph->mForceShutdownTicket) {
MOZ_ASSERT(false,
"AudioCallbackDriver took too long to shut down and we let shutdown"
" continue - freezing and leaking");
@@ -1761,17 +1762,17 @@ MediaStreamGraphImpl::EnsureStableStateE
{
MOZ_ASSERT(OnGraphThread());
mMonitor.AssertCurrentThreadOwns();
if (mPostedRunInStableStateEvent)
return;
mPostedRunInStableStateEvent = true;
nsCOMPtr<nsIRunnable> event = new MediaStreamGraphStableStateRunnable(this, true);
- mAbstractMainThread->Dispatch(event.forget());
+ Dispatch(event.forget());
}
void
MediaStreamGraphImpl::SignalMainThreadCleanup()
{
MOZ_ASSERT(mDriver->OnThread());
MonitorAutoLock lock(mMonitor);
@@ -1827,17 +1828,46 @@ MediaStreamGraphImpl::AppendMessage(Uniq
mCurrentTaskMessageQueue.AppendElement(Move(aMessage));
EnsureRunInStableState();
}
void
MediaStreamGraphImpl::Dispatch(already_AddRefed<nsIRunnable>&& aRunnable)
{
- mAbstractMainThread->Dispatch(Move(aRunnable));
+ if (!mDispatchBounceThread) {
+ mAbstractMainThread->Dispatch(Move(aRunnable));
+ return;
+ }
+
+ class BounceRunnable : public Runnable
+ {
+ public:
+ explicit BounceRunnable(AbstractThread* aThread,
+ already_AddRefed<nsIRunnable>&& aRunnable)
+ : Runnable("MediaStreamGraphImpl::BounceRunnable")
+ , mMainThread(aThread)
+ , mRunnable(aRunnable)
+ {
+
+ }
+
+ NS_IMETHOD Run() override
+ {
+ return mMainThread->Dispatch(mRunnable.forget());
+ }
+ private:
+ ~BounceRunnable() {}
+
+ RefPtr<AbstractThread> mMainThread;
+ nsCOMPtr<nsIRunnable> mRunnable;
+ };
+
+ nsCOMPtr<nsIRunnable> r = new BounceRunnable(mAbstractMainThread, Move(aRunnable));
+ mDispatchBounceThread->Dispatch(r.forget());
}
MediaStream::MediaStream()
: mTracksStartTime(0)
, mStartBlocking(GRAPH_TIME_MAX)
, mSuspendedCount(0)
, mFinished(false)
, mNotifiedFinished(false)
@@ -3596,29 +3626,35 @@ MediaStreamGraphImpl::MediaStreamGraphIm
, mDetectedNotRunning(false)
, mPostedRunInStableState(false)
, mRealtime(aDriverRequested != OFFLINE_THREAD_DRIVER)
, mNonRealtimeProcessing(false)
, mStreamOrderDirty(false)
, mLatencyLog(AsyncLatencyLogger::Get())
, mAbstractMainThread(aMainThread)
, mThreadPool(GetMediaThreadPool(MediaThreadType::MSG_CONTROL))
+ , mDispatchBounceThread(nullptr)
, mSelfRef(this)
, mOutputChannels(std::min<uint32_t>(8, CubebUtils::MaxNumberOfChannels()))
#ifdef DEBUG
, mCanRunMessagesSynchronously(false)
#endif
{
if (mRealtime) {
if (aDriverRequested == AUDIO_THREAD_DRIVER) {
AudioCallbackDriver* driver = new AudioCallbackDriver(this);
mDriver = driver;
} else {
mDriver = new SystemClockDriver(this);
}
+ nsresult rv = NS_NewNamedThread("MSG Dispatch", getter_AddRefs(mDispatchBounceThread));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Could not create dispatch bounce thread for the MSG, falling back to direct dispatch");
+ mDispatchBounceThread = nullptr;
+ }
} else {
mDriver = new OfflineClockDriver(this, MEDIA_GRAPH_TARGET_PERIOD_MS);
}
mLastMainThreadUpdate = TimeStamp::Now();
RegisterWeakAsyncMemoryReporter(this);
}
--- a/dom/media/MediaStreamGraphImpl.h
+++ b/dom/media/MediaStreamGraphImpl.h
@@ -815,16 +815,17 @@ public:
bool mStreamOrderDirty;
/**
* Hold a ref to the Latency logger
*/
RefPtr<AsyncLatencyLogger> mLatencyLog;
AudioMixer mMixer;
const RefPtr<AbstractThread> mAbstractMainThread;
RefPtr<SharedThreadPool> mThreadPool;
+ RefPtr<nsIThread> mDispatchBounceThread;
// used to limit graph shutdown time
// Only accessed on the main thread.
nsCOMPtr<nsITimer> mShutdownTimer;
private:
virtual ~MediaStreamGraphImpl();
--- a/dom/media/MediaStreamVideoSink.cpp
+++ b/dom/media/MediaStreamVideoSink.cpp
@@ -9,13 +9,21 @@
namespace mozilla {
void
MediaStreamVideoSink::NotifyRealtimeTrackData(MediaStreamGraph* aGraph,
StreamTime aTrackOffset,
const MediaSegment& aMedia)
{
if (aMedia.GetType() == MediaSegment::VIDEO) {
- SetCurrentFrames(static_cast<const VideoSegment&>(aMedia));
+ RefPtr<MediaStreamVideoSink> self = this;
+ VideoSegment copy;
+ copy.AppendSlice(aMedia, 0, aMedia.GetDuration());
+ static_cast<MediaStreamGraphImpl*>(aGraph)->Dispatch(
+ NewRunnableMethod<StoreCopyPassByRRef<VideoSegment>>(
+ "MediaStreamVideoSink::SetCurrentFrame",
+ this,
+ &MediaStreamVideoSink::SetCurrentFrames,
+ Move(copy)));
}
}
} // namespace mozilla