void AudioCaptureStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) { uint32_t inputCount = mInputs.Length(); StreamBuffer::Track* track = EnsureTrack(mTrackId); // Notify the DOM everything is in order. if (!mTrackCreated) { for (uint32_t i = 0; i < mListeners.Length(); i++) { MediaStreamListener* l = mListeners[i]; AudioSegment tmp; l->NotifyQueuedTrackChanges( Graph(), mTrackId, 0, MediaStreamListener::TRACK_EVENT_CREATED, tmp); l->NotifyFinishedTrackCreation(Graph()); } mTrackCreated = true; } // If the captured stream is connected back to a object on the page (be it an // HTMLMediaElement with a stream as source, or an AudioContext), a cycle // situation occur. This can work if it's an AudioContext with at least one // DelayNode, but the MSG will mute the whole cycle otherwise. if (mFinished || InMutedCycle() || inputCount == 0) { track->Get<AudioSegment>()->AppendNullData(aTo - aFrom); } else { // We mix down all the tracks of all inputs, to a stereo track. Everything // is {up,down}-mixed to stereo. mMixer.StartMixing(); AudioSegment output; for (uint32_t i = 0; i < inputCount; i++) { MediaStream* s = mInputs[i]->GetSource(); StreamBuffer::TrackIter tracks(s->GetStreamBuffer(), MediaSegment::AUDIO); while (!tracks.IsEnded()) { AudioSegment* inputSegment = tracks->Get<AudioSegment>(); StreamTime inputStart = s->GraphTimeToStreamTimeWithBlocking(aFrom); StreamTime inputEnd = s->GraphTimeToStreamTimeWithBlocking(aTo); AudioSegment toMix; toMix.AppendSlice(*inputSegment, inputStart, inputEnd); // Care for streams blocked in the [aTo, aFrom] range. if (inputEnd - inputStart < aTo - aFrom) { toMix.AppendNullData((aTo - aFrom) - (inputEnd - inputStart)); } toMix.Mix(mMixer, MONO, Graph()->GraphRate()); tracks.Next(); } } // This calls MixerCallback below mMixer.FinishMixing(); } // Regardless of the status of the input tracks, we go foward. mBuffer.AdvanceKnownTracksTime(GraphTimeToStreamTimeWithBlocking((aTo))); }
void CameraPreviewMediaStream::OnPreviewStateChange(bool aActive) { if (aActive) { MutexAutoLock lock(mMutex); if (!mTrackCreated) { mTrackCreated = true; VideoSegment tmpSegment; for (uint32_t j = 0; j < mListeners.Length(); ++j) { MediaStreamListener* l = mListeners[j]; l->NotifyQueuedTrackChanges(mFakeMediaStreamGraph, TRACK_VIDEO, 0, MediaStreamListener::TRACK_EVENT_CREATED, tmpSegment); l->NotifyFinishedTrackCreation(mFakeMediaStreamGraph); } } } }