diff --git a/content/media/MediaSegment.h b/content/media/MediaSegment.h index b608ca758c36..be94cfb174f4 100644 --- a/content/media/MediaSegment.h +++ b/content/media/MediaSegment.h @@ -100,6 +100,10 @@ public: * Insert aDuration of null data at the end of the segment. */ virtual void AppendNullData(TrackTicks aDuration) = 0; + /** + * Remove all contents, setting duration to 0. + */ + virtual void Clear() = 0; protected: MediaSegment(Type aType) : mDuration(0), mType(aType) @@ -186,6 +190,11 @@ public: } mDuration += aDuration; } + virtual void Clear() + { + mDuration = 0; + mChunks.Clear(); + } class ChunkIterator { public: diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index a061affb4dc4..ba2370c05096 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -118,6 +118,9 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream, StreamTime t = GraphTimeToStreamTime(aStream, mStateComputedTime) + (aDesiredUpToTime - mStateComputedTime); + LOG(PR_LOG_DEBUG, ("Calling NotifyPull aStream=%p t=%f current end=%f", aStream, + MediaTimeToSeconds(t), + MediaTimeToSeconds(aStream->mBuffer.GetEnd()))); if (t > aStream->mBuffer.GetEnd()) { *aEnsureNextIteration = true; for (uint32_t j = 0; j < aStream->mListeners.Length(); ++j) { @@ -1637,22 +1640,25 @@ SourceMediaStream::AddTrack(TrackID aID, TrackRate aRate, TrackTicks aStart, } } -void +bool SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment) { MutexAutoLock lock(mMutex); // ::EndAllTrackAndFinished() can end these before the sources notice + bool appended = false; if (!mFinished) { TrackData *track = FindDataForTrack(aID); if (track) { track->mData->AppendFrom(aSegment); + appended = true; } else { - NS_ERROR("Append to non-existent track!"); + aSegment->Clear(); } } if (!mDestroyed) { GraphImpl()->EnsureNextIteration(); } + return appended; } bool @@ -1663,8 +1669,7 @@ SourceMediaStream::HaveEnoughBuffered(TrackID aID) if (track) { return track->mHaveEnough; } - NS_ERROR("No track in HaveEnoughBuffered!"); - return true; + return false; } void @@ -1674,7 +1679,7 @@ SourceMediaStream::DispatchWhenNotEnoughBuffered(TrackID aID, MutexAutoLock lock(mMutex); TrackData* data = FindDataForTrack(aID); if (!data) { - NS_ERROR("No track in DispatchWhenNotEnoughBuffered"); + aSignalThread->Dispatch(aSignalRunnable, 0); return; } @@ -1694,8 +1699,6 @@ SourceMediaStream::EndTrack(TrackID aID) TrackData *track = FindDataForTrack(aID); if (track) { track->mCommands |= TRACK_END; - } else { - NS_ERROR("End of non-existant track"); } } if (!mDestroyed) { diff --git a/content/media/MediaStreamGraph.h b/content/media/MediaStreamGraph.h index 7ecf1a4668a3..025405e51574 100644 --- a/content/media/MediaStreamGraph.h +++ b/content/media/MediaStreamGraph.h @@ -567,22 +567,27 @@ public: /** * Append media data to a track. Ownership of aSegment remains with the caller, * but aSegment is emptied. + * Returns false if the data was not appended because no such track exists + * or the stream was already finished. */ - void AppendToTrack(TrackID aID, MediaSegment* aSegment); + bool AppendToTrack(TrackID aID, MediaSegment* aSegment); /** * Returns true if the buffer currently has enough data. + * Returns false if there isn't enough data or if no such track exists. */ bool HaveEnoughBuffered(TrackID aID); /** * Ensures that aSignalRunnable will be dispatched to aSignalThread * when we don't have enough buffered data in the track (which could be - * immediately). + * immediately). Will dispatch the runnable immediately if the track + * does not exist. */ void DispatchWhenNotEnoughBuffered(TrackID aID, nsIThread* aSignalThread, nsIRunnable* aSignalRunnable); /** * Indicate that a track has ended. Do not do any more API calls * affecting this track. + * Ignored if the track does not exist. */ void EndTrack(TrackID aID); /** @@ -653,7 +658,6 @@ protected: return &mUpdateTracks[i]; } } - NS_ERROR("Bad track ID!"); return nullptr; } diff --git a/content/media/webrtc/MediaEngineWebRTCVideo.cpp b/content/media/webrtc/MediaEngineWebRTCVideo.cpp index 200def709386..ba0bb08fdaf9 100644 --- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp +++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp @@ -124,8 +124,11 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph, if (delta > 0) { // NULL images are allowed segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight)); - aSource->AppendToTrack(aID, &(segment)); - aLastEndTime = target; + // This can fail if either a) we haven't added the track yet, or b) + // we've removed or finished the track. + if (aSource->AppendToTrack(aID, &(segment))) { + aLastEndTime = target; + } } }