зеркало из https://github.com/mozilla/gecko-dev.git
Bug 843214. Make SourceMediaStream::AddTrack/AppendToTrack/HaveEnoughBuffered/DispatchWhenNotEnoughBuffered/EndTrack smoothly handle cases where track does not exist. r=jesup
This commit is contained in:
Родитель
260d9da13c
Коммит
2a0a9d9363
|
@ -100,6 +100,10 @@ public:
|
||||||
* Insert aDuration of null data at the end of the segment.
|
* Insert aDuration of null data at the end of the segment.
|
||||||
*/
|
*/
|
||||||
virtual void AppendNullData(TrackTicks aDuration) = 0;
|
virtual void AppendNullData(TrackTicks aDuration) = 0;
|
||||||
|
/**
|
||||||
|
* Remove all contents, setting duration to 0.
|
||||||
|
*/
|
||||||
|
virtual void Clear() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MediaSegment(Type aType) : mDuration(0), mType(aType)
|
MediaSegment(Type aType) : mDuration(0), mType(aType)
|
||||||
|
@ -186,6 +190,11 @@ public:
|
||||||
}
|
}
|
||||||
mDuration += aDuration;
|
mDuration += aDuration;
|
||||||
}
|
}
|
||||||
|
virtual void Clear()
|
||||||
|
{
|
||||||
|
mDuration = 0;
|
||||||
|
mChunks.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
class ChunkIterator {
|
class ChunkIterator {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -118,6 +118,9 @@ MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
|
||||||
StreamTime t =
|
StreamTime t =
|
||||||
GraphTimeToStreamTime(aStream, mStateComputedTime) +
|
GraphTimeToStreamTime(aStream, mStateComputedTime) +
|
||||||
(aDesiredUpToTime - 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()) {
|
if (t > aStream->mBuffer.GetEnd()) {
|
||||||
*aEnsureNextIteration = true;
|
*aEnsureNextIteration = true;
|
||||||
for (uint32_t j = 0; j < aStream->mListeners.Length(); ++j) {
|
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)
|
SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment)
|
||||||
{
|
{
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
// ::EndAllTrackAndFinished() can end these before the sources notice
|
// ::EndAllTrackAndFinished() can end these before the sources notice
|
||||||
|
bool appended = false;
|
||||||
if (!mFinished) {
|
if (!mFinished) {
|
||||||
TrackData *track = FindDataForTrack(aID);
|
TrackData *track = FindDataForTrack(aID);
|
||||||
if (track) {
|
if (track) {
|
||||||
track->mData->AppendFrom(aSegment);
|
track->mData->AppendFrom(aSegment);
|
||||||
|
appended = true;
|
||||||
} else {
|
} else {
|
||||||
NS_ERROR("Append to non-existent track!");
|
aSegment->Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mDestroyed) {
|
if (!mDestroyed) {
|
||||||
GraphImpl()->EnsureNextIteration();
|
GraphImpl()->EnsureNextIteration();
|
||||||
}
|
}
|
||||||
|
return appended;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1663,8 +1669,7 @@ SourceMediaStream::HaveEnoughBuffered(TrackID aID)
|
||||||
if (track) {
|
if (track) {
|
||||||
return track->mHaveEnough;
|
return track->mHaveEnough;
|
||||||
}
|
}
|
||||||
NS_ERROR("No track in HaveEnoughBuffered!");
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1674,7 +1679,7 @@ SourceMediaStream::DispatchWhenNotEnoughBuffered(TrackID aID,
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
TrackData* data = FindDataForTrack(aID);
|
TrackData* data = FindDataForTrack(aID);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
NS_ERROR("No track in DispatchWhenNotEnoughBuffered");
|
aSignalThread->Dispatch(aSignalRunnable, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1694,8 +1699,6 @@ SourceMediaStream::EndTrack(TrackID aID)
|
||||||
TrackData *track = FindDataForTrack(aID);
|
TrackData *track = FindDataForTrack(aID);
|
||||||
if (track) {
|
if (track) {
|
||||||
track->mCommands |= TRACK_END;
|
track->mCommands |= TRACK_END;
|
||||||
} else {
|
|
||||||
NS_ERROR("End of non-existant track");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mDestroyed) {
|
if (!mDestroyed) {
|
||||||
|
|
|
@ -567,22 +567,27 @@ public:
|
||||||
/**
|
/**
|
||||||
* Append media data to a track. Ownership of aSegment remains with the caller,
|
* Append media data to a track. Ownership of aSegment remains with the caller,
|
||||||
* but aSegment is emptied.
|
* 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 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);
|
bool HaveEnoughBuffered(TrackID aID);
|
||||||
/**
|
/**
|
||||||
* Ensures that aSignalRunnable will be dispatched to aSignalThread
|
* Ensures that aSignalRunnable will be dispatched to aSignalThread
|
||||||
* when we don't have enough buffered data in the track (which could be
|
* 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,
|
void DispatchWhenNotEnoughBuffered(TrackID aID,
|
||||||
nsIThread* aSignalThread, nsIRunnable* aSignalRunnable);
|
nsIThread* aSignalThread, nsIRunnable* aSignalRunnable);
|
||||||
/**
|
/**
|
||||||
* Indicate that a track has ended. Do not do any more API calls
|
* Indicate that a track has ended. Do not do any more API calls
|
||||||
* affecting this track.
|
* affecting this track.
|
||||||
|
* Ignored if the track does not exist.
|
||||||
*/
|
*/
|
||||||
void EndTrack(TrackID aID);
|
void EndTrack(TrackID aID);
|
||||||
/**
|
/**
|
||||||
|
@ -653,7 +658,6 @@ protected:
|
||||||
return &mUpdateTracks[i];
|
return &mUpdateTracks[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NS_ERROR("Bad track ID!");
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,12 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph,
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
// NULL images are allowed
|
// NULL images are allowed
|
||||||
segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
|
segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
|
||||||
aSource->AppendToTrack(aID, &(segment));
|
// 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;
|
aLastEndTime = target;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Загрузка…
Ссылка в новой задаче