Bug 1256079 - Allow direct track listeners for tracks that don't exist yet. r?jesup
This will cover potential bugs where the direct track listener was added before
the track.
Worth noting also that we could end up in a limbo state if we add the listener
to a track that doesn't exist anymore (it ended!).
MozReview-Commit-ID: FpSwU2ReCpm
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -261,16 +261,28 @@ MediaStreamGraphImpl::ExtractPendingInpu
data->mEndOfFlushedData += segment->GetDuration();
aStream->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;
+
+ for (int32_t i = aStream->mPendingDirectTrackListeners.Length() - 1;
+ i >= 0; i--) {
+ if (aStream->mPendingDirectTrackListeners[i].mTrackID != data->mID) {
+ continue;
+ }
+
+ RefPtr<DirectMediaStreamTrackListener> l =
+ aStream->mPendingDirectTrackListeners[i].mListener;
+ aStream->mPendingDirectTrackListeners.RemoveElementAt(i);
+ aStream->AddDirectTrackListenerImpl(l.forget(), data->mID);
+ }
} else if (data->mData->GetDuration() > 0) {
MediaSegment* dest = aStream->mTracks.FindTrack(data->mID)->GetSegment();
STREAM_LOG(LogLevel::Verbose, ("SourceMediaStream %p track %d, advancing end from %lld to %lld",
aStream, data->mID,
int64_t(dest->GetDuration()),
int64_t(dest->GetDuration() + data->mData->GetDuration())));
data->mEndOfFlushedData += data->mData->GetDuration();
dest->AppendFrom(data->mData);
@@ -2923,20 +2935,23 @@ SourceMediaStream::AddDirectTrackListene
TrackBound<DirectMediaStreamTrackListener>* sourceListener =
mDirectTrackListeners.AppendElement();
sourceListener->mListener = listener;
sourceListener->mTrackID = aTrackID;
}
}
if (!found) {
- STREAM_LOG(LogLevel::Warning, ("Couldn't find source track for direct track listener %p",
- listener.get()));
- listener->NotifyDirectListenerInstalled(
- DirectMediaStreamTrackListener::InstallationResult::TRACK_NOT_FOUND_AT_SOURCE);
+ STREAM_LOG(LogLevel::Info, ("Couldn't find source track for direct track "
+ "listener %p. Waiting for the track to appear.",
+ listener.get()));
+ TrackBound<DirectMediaStreamTrackListener>* pendingListener =
+ mPendingDirectTrackListeners.AppendElement();
+ pendingListener->mListener = listener;
+ pendingListener->mTrackID = aTrackID;
return;
}
if (!isAudio && !isVideo) {
STREAM_LOG(LogLevel::Warning, ("Source track for direct track listener %p is unknown",
listener.get()));
// It is not a video or audio track.
MOZ_ASSERT(true);
return;
--- a/dom/media/MediaStreamGraph.h
+++ b/dom/media/MediaStreamGraph.h
@@ -921,16 +921,19 @@ protected:
// This time stamp will be updated in adding and blocked SourceMediaStream,
// |AddStreamGraphThread| and |AdvanceTimeVaryingValuesToCurrentTime| in
// particularly.
TimeStamp mStreamTracksStartTimeStamp;
nsTArray<TrackData> mUpdateTracks;
nsTArray<TrackData> mPendingTracks;
nsTArray<RefPtr<DirectMediaStreamListener>> mDirectListeners;
nsTArray<TrackBound<DirectMediaStreamTrackListener>> mDirectTrackListeners;
+ // Direct track listeners that we don't have a track for yet. We'll move them
+ // to mDirectTrackListeners when their corresponding track becomes available.
+ nsTArray<TrackBound<DirectMediaStreamTrackListener>> mPendingDirectTrackListeners;
bool mPullEnabled;
bool mUpdateFinished;
bool mNeedsMixing;
};
/**
* The blocking mode decides how a track should be blocked in a MediaInputPort.
*/
--- a/dom/media/MediaStreamListener.h
+++ b/dom/media/MediaStreamListener.h
@@ -234,32 +234,27 @@ public:
virtual void NotifyRealtimeTrackData(MediaStreamGraph* aGraph,
StreamTime aTrackOffset,
const MediaSegment& aMedia) {}
/**
* When a direct listener is processed for installation by the
* MediaStreamGraph it will be notified with whether the installation was
* successful or not. The results of this installation are the following:
- * TRACK_NOT_FOUND_AT_SOURCE
- * We found the source stream of media data for this track, but the track
- * didn't exist. This should only happen if you try to install the listener
- * directly to a SourceMediaStream that doesn't contain the given TrackID.
* STREAM_NOT_SUPPORTED
* While looking for the data source of this track, we found a MediaStream
* that is not a SourceMediaStream or a TrackUnionStream.
* ALREADY_EXIST
* This DirectMediaStreamTrackListener already exists in the
* SourceMediaStream.
* SUCCESS
* Installation was successful and this listener will start receiving
* NotifyRealtimeData on the next AppendToTrack().
*/
enum class InstallationResult {
- TRACK_NOT_FOUND_AT_SOURCE,
TRACK_TYPE_NOT_SUPPORTED,
STREAM_NOT_SUPPORTED,
ALREADY_EXISTS,
SUCCESS
};
virtual void NotifyDirectListenerInstalled(InstallationResult aResult) {}
virtual void NotifyDirectListenerUninstalled() {}