Bug 1116925: queue track adds for getUserMedia and cleanup r=roc

This commit is contained in:
Randell Jesup 2015-02-19 12:04:26 -05:00
parent 48094b2951
commit d47c752c4b
8 changed files with 44 additions and 23 deletions

View File

@ -393,8 +393,6 @@ public:
NS_ASSERTION(!NS_IsMainThread(), "Never call on main thread");
nsresult rv;
source->SetPullEnabled(true);
DOMMediaStream::TrackTypeHints expectedTracks = 0;
if (mAudioSource) {
rv = mAudioSource->Start(source, kAudioTrack);
@ -414,9 +412,14 @@ public:
return;
}
}
// Start() queued the tracks to be added synchronously to avoid races
source->FinishAddTracks();
mOnTracksAvailableCallback->SetExpectedTracks(expectedTracks);
source->SetPullEnabled(true);
source->AdvanceKnownTracksTime(STREAM_TIME_MAX);
MM_LOG(("started all sources"));
// Forward mOnTracksAvailableCallback to GetUserMediaNotificationEvent,
// because mOnTracksAvailableCallback needs to be added to mStream

View File

@ -2275,10 +2275,12 @@ SourceMediaStream::SetPullEnabled(bool aEnabled)
void
SourceMediaStream::AddTrackInternal(TrackID aID, TrackRate aRate, StreamTime aStart,
MediaSegment* aSegment)
MediaSegment* aSegment, uint32_t aFlags)
{
MutexAutoLock lock(mMutex);
TrackData* data = mUpdateTracks.AppendElement();
nsTArray<TrackData> *track_data = (aFlags & ADDTRACK_QUEUED) ?
&mPendingTracks : &mUpdateTracks;
TrackData* data = track_data->AppendElement();
data->mID = aID;
data->mInputRate = aRate;
data->mStart = aStart;
@ -2286,6 +2288,16 @@ SourceMediaStream::AddTrackInternal(TrackID aID, TrackRate aRate, StreamTime aSt
data->mCommands = TRACK_CREATE;
data->mData = aSegment;
data->mHaveEnough = false;
if (!(aFlags & ADDTRACK_QUEUED) && GraphImpl()) {
GraphImpl()->EnsureNextIteration();
}
}
void
SourceMediaStream::FinishAddTracks()
{
MutexAutoLock lock(mMutex);
mUpdateTracks.MoveElementsFrom(mPendingTracks);
if (GraphImpl()) {
GraphImpl()->EnsureNextIteration();
}
@ -2515,6 +2527,7 @@ SourceMediaStream::EndAllTrackAndFinish()
SourceMediaStream::TrackData* data = &mUpdateTracks[i];
data->mCommands |= TRACK_END;
}
mPendingTracks.Clear();
FinishWithLockHeld();
// we will call NotifyEvent() to let GetUserMedia know
}

View File

@ -720,26 +720,36 @@ public:
void AddDirectListener(MediaStreamDirectListener* aListener);
void RemoveDirectListener(MediaStreamDirectListener* aListener);
enum {
ADDTRACK_QUEUED = 0x01 // Queue track add until FinishAddTracks()
};
/**
* Add a new track to the stream starting at the given base time (which
* must be greater than or equal to the last time passed to
* AdvanceKnownTracksTime). Takes ownership of aSegment. aSegment should
* contain data starting after aStart.
*/
void AddTrack(TrackID aID, StreamTime aStart, MediaSegment* aSegment)
void AddTrack(TrackID aID, StreamTime aStart, MediaSegment* aSegment,
uint32_t aFlags = 0)
{
AddTrackInternal(aID, GraphRate(), aStart, aSegment);
AddTrackInternal(aID, GraphRate(), aStart, aSegment, aFlags);
}
/**
* Like AddTrack, but resamples audio from aRate to the graph rate.
*/
void AddAudioTrack(TrackID aID, TrackRate aRate, StreamTime aStart,
AudioSegment* aSegment)
AudioSegment* aSegment, uint32_t aFlags = 0)
{
AddTrackInternal(aID, aRate, aStart, aSegment);
AddTrackInternal(aID, aRate, aStart, aSegment, aFlags);
}
/**
* Call after a series of AddTrack or AddAudioTrack calls to implement
* any pending track adds.
*/
void FinishAddTracks();
/**
* Append media data to a track. Ownership of aSegment remains with the caller,
* but aSegment is emptied.
@ -874,7 +884,8 @@ protected:
void ResampleAudioToGraphSampleRate(TrackData* aTrackData, MediaSegment* aSegment);
void AddTrackInternal(TrackID aID, TrackRate aRate,
StreamTime aStart, MediaSegment* aSegment);
StreamTime aStart, MediaSegment* aSegment,
uint32_t aFlags);
TrackData* FindDataForTrack(TrackID aID)
{
@ -905,6 +916,7 @@ protected:
// protected by mMutex
StreamTime mUpdateKnownTracksTime;
nsTArray<TrackData> mUpdateTracks;
nsTArray<TrackData> mPendingTracks;
nsTArray<nsRefPtr<MediaStreamDirectListener> > mDirectListeners;
bool mPullEnabled;
bool mUpdateFinished;

View File

@ -138,12 +138,11 @@ MediaEngineDefaultVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
return NS_ERROR_FAILURE;
}
aStream->AddTrack(aID, 0, new VideoSegment());
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
aStream->AddTrack(aID, 0, new VideoSegment(), SourceMediaStream::ADDTRACK_QUEUED);
if (mHasFakeTracks) {
for (int i = 0; i < kFakeVideoTrackCount; ++i) {
aStream->AddTrack(kTrackCount + i, 0, new VideoSegment());
aStream->AddTrack(kTrackCount + i, 0, new VideoSegment(), SourceMediaStream::ADDTRACK_QUEUED);
}
}
@ -389,18 +388,15 @@ MediaEngineDefaultAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
// AddTrack will take ownership of segment
AudioSegment* segment = new AudioSegment();
mSource->AddAudioTrack(aID, AUDIO_RATE, 0, segment);
mSource->AddAudioTrack(aID, AUDIO_RATE, 0, segment, SourceMediaStream::ADDTRACK_QUEUED);
if (mHasFakeTracks) {
for (int i = 0; i < kFakeAudioTrackCount; ++i) {
mSource->AddAudioTrack(kTrackCount + kFakeVideoTrackCount+i,
AUDIO_RATE, 0, new AudioSegment());
AUDIO_RATE, 0, new AudioSegment(), SourceMediaStream::ADDTRACK_QUEUED);
}
}
// We aren't going to add any more tracks
mSource->AdvanceKnownTracksTime(STREAM_TIME_MAX);
// Remember TrackID so we can finish later
mTrackID = aID;

View File

@ -182,7 +182,6 @@ MediaEngineGonkVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
}
aStream->AddTrack(aID, 0, new VideoSegment());
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
ReentrantMonitorAutoEnter sync(mCallbackMonitor);

View File

@ -174,7 +174,6 @@ MediaEngineTabVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
runnable = new StartRunnable(this);
NS_DispatchToMainThread(runnable);
aStream->AddTrack(aID, 0, new VideoSegment());
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
return NS_OK;
}

View File

@ -328,8 +328,8 @@ MediaEngineWebRTCAudioSource::Start(SourceMediaStream* aStream, TrackID aID)
}
AudioSegment* segment = new AudioSegment();
aStream->AddAudioTrack(aID, SAMPLE_FREQUENCY, 0, segment);
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
aStream->AddAudioTrack(aID, SAMPLE_FREQUENCY, 0, segment, SourceMediaStream::ADDTRACK_QUEUED);
// XXX Make this based on the pref.
aStream->RegisterForAudioMixing();
LOG(("Start audio for stream %p", aStream));

View File

@ -408,8 +408,7 @@ MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
mSources.AppendElement(aStream);
}
aStream->AddTrack(aID, 0, new VideoSegment());
aStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
aStream->AddTrack(aID, 0, new VideoSegment(), SourceMediaStream::ADDTRACK_QUEUED);
if (mState == kStarted) {
return NS_OK;