Bug 1161946 - MainThreadMediaStreamListener should be notified just when the stream is finished - patch 2, r=padenot

This commit is contained in:
Andrea Marchesini 2015-05-11 15:07:38 +01:00
parent 4122c43374
commit 604d24bede
2 changed files with 62 additions and 10 deletions

View File

@ -1548,9 +1548,7 @@ MediaStreamGraphImpl::ApplyStreamUpdate(StreamUpdate* aUpdate)
stream->mWrapper->NotifyStreamFinished();
}
for (int32_t i = stream->mMainThreadListeners.Length() - 1; i >= 0; --i) {
stream->mMainThreadListeners[i]->NotifyMainThreadStreamFinished();
}
stream->NotifyMainThreadListeners();
}
}
@ -2408,6 +2406,50 @@ MediaStream::ApplyTrackDisabling(TrackID aTrackID, MediaSegment* aSegment, Media
}
}
void
MediaStream::AddMainThreadListener(MainThreadMediaStreamListener* aListener)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aListener);
MOZ_ASSERT(!mMainThreadListeners.Contains(aListener));
mMainThreadListeners.AppendElement(aListener);
// If we have to send the notification or we have a runnable that will do it,
// let finish here.
if (!mFinishedNotificationSent || mNotificationMainThreadRunnable) {
return;
}
class NotifyRunnable final : public nsRunnable
{
public:
NotifyRunnable(MediaStream* aStream)
: mStream(aStream)
{}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread());
mStream->mNotificationMainThreadRunnable = nullptr;
mStream->NotifyMainThreadListeners();
return NS_OK;
}
private:
~NotifyRunnable() {}
nsRefPtr<MediaStream> mStream;
};
nsRefPtr<nsRunnable> runnable = new NotifyRunnable(this);
if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable)))) {
return;
}
mNotificationMainThreadRunnable = runnable;
}
void
SourceMediaStream::DestroyImpl()
{

View File

@ -373,20 +373,19 @@ public:
// A disabled track has video replaced by black, and audio replaced by
// silence.
void SetTrackEnabled(TrackID aTrackID, bool aEnabled);
// Events will be dispatched by calling methods of aListener. It is the
// Finish event will be notified by calling methods of aListener. It is the
// responsibility of the caller to remove aListener before it is destroyed.
void AddMainThreadListener(MainThreadMediaStreamListener* aListener)
{
NS_ASSERTION(NS_IsMainThread(), "Call only on main thread");
mMainThreadListeners.AppendElement(aListener);
}
void AddMainThreadListener(MainThreadMediaStreamListener* aListener);
// It's safe to call this even if aListener is not currently a listener;
// the call will be ignored.
void RemoveMainThreadListener(MainThreadMediaStreamListener* aListener)
{
NS_ASSERTION(NS_IsMainThread(), "Call only on main thread");
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aListener);
mMainThreadListeners.RemoveElement(aListener);
}
/**
* Ensure a runnable will run on the main thread after running all pending
* updates that were sent from the graph thread or will be sent before the
@ -597,6 +596,16 @@ protected:
mBuffer.ForgetUpTo(aCurrentTime - mBufferStartTime);
}
void NotifyMainThreadListeners()
{
NS_ASSERTION(NS_IsMainThread(), "Call only on main thread");
for (int32_t i = mMainThreadListeners.Length() - 1; i >= 0; --i) {
mMainThreadListeners[i]->NotifyMainThreadStreamFinished();
}
mMainThreadListeners.Clear();
}
bool ShouldNotifyStreamFinished()
{
NS_ASSERTION(NS_IsMainThread(), "Call only on main thread");
@ -636,6 +645,7 @@ protected:
TimeVarying<GraphTime,uint32_t,0> mExplicitBlockerCount;
nsTArray<nsRefPtr<MediaStreamListener> > mListeners;
nsTArray<MainThreadMediaStreamListener*> mMainThreadListeners;
nsRefPtr<nsRunnable> mNotificationMainThreadRunnable;
nsTArray<TrackID> mDisabledTrackIDs;
// Precomputed blocking status (over GraphTime).