Bug 843214. Make SourceMediaStream::AddTrack/AppendToTrack/HaveEnoughBuffered/DispatchWhenNotEnoughBuffered/EndTrack smoothly handle cases where track does not exist. r=jesup

--HG--
extra : rebase_source : adcfa0e92b5e498c597e16e013fdcba2dae4b8e5
This commit is contained in:
Robert O'Callahan 2013-02-25 22:25:07 +13:00
parent bffb159b08
commit 4dd110ae0a
4 changed files with 32 additions and 13 deletions

View File

@ -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:

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}
}
}