зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1274221 - Ensure MediaStreamListeners are always notified of created and ended tracks. r=ctai, r=jesup
This means that when a MediaStreamListener is added to a stream, we'll call NotifyQueuedTrackChanges with TRACK_EVENT_CREATE for all tracks that already exist. Likewise, we'll call NotifyQueuedTrackChanges with TRACK_EVENT_ENDED for all tracks that exist and have ended. This fixes potential race conditions where a track was created and/or ended before the listener was asynchronously added. MozReview-Commit-ID: G3juhfiZMtg --HG-- extra : rebase_source : d2ca7cb24ce154c4aa342bb477aee455c9cfef92 extra : intermediate-source : 80443106b2636d8de3c3de44f2706e99d70c06ae extra : source : 70e8c5a785a9866e6205b54bd1c45faaf834717d
This commit is contained in:
Родитель
577b207b43
Коммит
be9d25eccb
|
@ -2375,6 +2375,31 @@ MediaStream::AddListenerImpl(already_AddRefed<MediaStreamListener> aListener)
|
|||
MediaStreamListener* listener = *mListeners.AppendElement() = aListener;
|
||||
listener->NotifyBlockingChanged(GraphImpl(),
|
||||
mNotifiedBlocked ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED);
|
||||
|
||||
for (StreamTracks::TrackIter it(mTracks); !it.IsEnded(); it.Next()) {
|
||||
MediaStream* inputStream = nullptr;
|
||||
TrackID inputTrackID = TRACK_INVALID;
|
||||
if (ProcessedMediaStream* ps = AsProcessedStream()) {
|
||||
// The only ProcessedMediaStream where we should have listeners is
|
||||
// TrackUnionStream - it's what's used as owned stream in DOMMediaStream,
|
||||
// the only main-thread exposed stream type.
|
||||
// TrackUnionStream guarantees that each of its tracks has an input track.
|
||||
// Other types do not implement GetInputStreamFor() and will return null.
|
||||
inputStream = ps->GetInputStreamFor(it->GetID());
|
||||
MOZ_ASSERT(inputStream);
|
||||
inputTrackID = ps->GetInputTrackIDFor(it->GetID());
|
||||
MOZ_ASSERT(IsTrackIDExplicit(inputTrackID));
|
||||
}
|
||||
|
||||
uint32_t flags = MediaStreamListener::TRACK_EVENT_CREATED;
|
||||
if (it->IsEnded()) {
|
||||
flags |= MediaStreamListener::TRACK_EVENT_ENDED;
|
||||
}
|
||||
nsAutoPtr<MediaSegment> segment(it->GetSegment()->CreateEmptyClone());
|
||||
listener->NotifyQueuedTrackChanges(Graph(), it->GetID(), it->GetEnd(),
|
||||
flags, *segment,
|
||||
inputStream, inputTrackID);
|
||||
}
|
||||
if (mNotifiedFinished) {
|
||||
listener->NotifyEvent(GraphImpl(), MediaStreamListener::EVENT_FINISHED);
|
||||
}
|
||||
|
|
|
@ -1447,6 +1447,8 @@ public:
|
|||
{
|
||||
return mInputs.Length();
|
||||
}
|
||||
virtual MediaStream* GetInputStreamFor(TrackID aTrackID) { return nullptr; }
|
||||
virtual TrackID GetInputTrackIDFor(TrackID aTrackID) { return TRACK_NONE; }
|
||||
void DestroyImpl() override;
|
||||
/**
|
||||
* This gets called after we've computed the blocking states for all
|
||||
|
|
|
@ -374,6 +374,30 @@ TrackUnionStream::SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled) {
|
|||
MediaStream::SetTrackEnabledImpl(aTrackID, aEnabled);
|
||||
}
|
||||
|
||||
MediaStream*
|
||||
TrackUnionStream::GetInputStreamFor(TrackID aTrackID)
|
||||
{
|
||||
for (TrackMapEntry& entry : mTrackMap) {
|
||||
if (entry.mOutputTrackID == aTrackID && entry.mInputPort) {
|
||||
return entry.mInputPort->GetSource();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TrackID
|
||||
TrackUnionStream::GetInputTrackIDFor(TrackID aTrackID)
|
||||
{
|
||||
for (TrackMapEntry& entry : mTrackMap) {
|
||||
if (entry.mOutputTrackID == aTrackID) {
|
||||
return entry.mInputTrackID;
|
||||
}
|
||||
}
|
||||
|
||||
return TRACK_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
TrackUnionStream::AddDirectTrackListenerImpl(already_AddRefed<MediaStreamTrackDirectListener> aListener,
|
||||
TrackID aTrackID)
|
||||
|
|
|
@ -24,6 +24,9 @@ public:
|
|||
|
||||
void SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled) override;
|
||||
|
||||
MediaStream* GetInputStreamFor(TrackID aTrackID) override;
|
||||
TrackID GetInputTrackIDFor(TrackID aTrackID) override;
|
||||
|
||||
protected:
|
||||
// Only non-ended tracks are allowed to persist in this map.
|
||||
struct TrackMapEntry {
|
||||
|
|
Загрузка…
Ссылка в новой задаче