Bug 1306813 - Don't puslish events to mOnOutput after DecodedStream::Stop() is called.
Because the TaskQueue of MDSM will shut down soon and TaskQueue::Dispatch() will fail (via mOnOutput.Notify()).
We reset mStream in Forget() on the TaskQueue thread of MDSM so NotifyOutput() can check it
and ensure mOnOutput.Notify() always happen before DecodedStream::Stop().
MozReview-Commit-ID: 4sCXk1KAfCC
--- a/dom/media/mediasink/DecodedStream.cpp
+++ b/dom/media/mediasink/DecodedStream.cpp
@@ -56,23 +56,26 @@ public:
nsCOMPtr<nsIRunnable> event =
NewRunnableMethod(this, &DecodedStreamGraphListener::DoNotifyFinished);
aGraph->DispatchToMainThreadAfterStreamStateUpdate(event.forget());
}
}
void DoNotifyFinished()
{
+ MOZ_ASSERT(NS_IsMainThread());
mFinishPromise.ResolveIfExists(true, __func__);
}
void Forget()
{
- MOZ_ASSERT(NS_IsMainThread());
- mFinishPromise.ResolveIfExists(true, __func__);
+ AbstractThread::MainThread()->Dispatch(NS_NewRunnableFunction([this] () {
+ MOZ_ASSERT(NS_IsMainThread());
+ mFinishPromise.ResolveIfExists(true, __func__);
+ }));
MutexAutoLock lock(mMutex);
mStream = nullptr;
}
MediaEventSource<int64_t>& OnOutput()
{
return mOnOutput;
}
@@ -118,16 +121,17 @@ UpdateStreamSuspended(MediaStream* aStre
class DecodedStreamData {
public:
DecodedStreamData(OutputStreamManager* aOutputStreamManager,
PlaybackInfoInit&& aInit,
MozPromiseHolder<GenericPromise>&& aPromise);
~DecodedStreamData();
void SetPlaying(bool aPlaying);
MediaEventSource<int64_t>& OnOutput();
+ void Forget();
/* The following group of fields are protected by the decoder's monitor
* and can be read or written on any thread.
*/
// Count of audio frames written to the stream
int64_t mAudioFramesWritten;
// mNextVideoTime is the end timestamp for the last packet sent to the stream.
// Therefore video packets starting at or after this time need to be copied
@@ -183,17 +187,16 @@ DecodedStreamData::DecodedStreamData(Out
if (aInit.mInfo.HasVideo()) {
mStream->AddTrack(aInit.mInfo.mVideo.mTrackId, 0, new VideoSegment());
}
}
DecodedStreamData::~DecodedStreamData()
{
mOutputStreamManager->Disconnect();
- mListener->Forget();
mStream->Destroy();
}
MediaEventSource<int64_t>&
DecodedStreamData::OnOutput()
{
return mListener->OnOutput();
}
@@ -202,16 +205,22 @@ void
DecodedStreamData::SetPlaying(bool aPlaying)
{
if (mPlaying != aPlaying) {
mPlaying = aPlaying;
UpdateStreamSuspended(mStream, !mPlaying);
}
}
+void
+DecodedStreamData::Forget()
+{
+ mListener->Forget();
+}
+
DecodedStream::DecodedStream(AbstractThread* aOwnerThread,
MediaQueue<MediaData>& aAudioQueue,
MediaQueue<MediaData>& aVideoQueue,
OutputStreamManager* aOutputStreamManager,
const bool& aSameOrigin,
const PrincipalHandle& aPrincipalHandle)
: mOwnerThread(aOwnerThread)
, mOutputStreamManager(aOutputStreamManager)
@@ -358,16 +367,17 @@ DecodedStream::DestroyData(UniquePtr<Dec
if (!aData) {
return;
}
mOutputListener.Disconnect();
DecodedStreamData* data = aData.release();
+ data->Forget();
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
delete data;
});
AbstractThread::MainThread()->Dispatch(r.forget());
}
void
DecodedStream::SetPlaying(bool aPlaying)