void TrackUnionStream::EndTrack(uint32_t aIndex) { StreamBuffer::Track* outputTrack = mBuffer.FindTrack(mTrackMap[aIndex].mOutputTrackID); if (!outputTrack || outputTrack->IsEnded()) return; for (uint32_t j = 0; j < mListeners.Length(); ++j) { MediaStreamListener* l = mListeners[j]; StreamTime offset = outputTrack->GetSegment()->GetDuration(); nsAutoPtr<MediaSegment> segment; segment = outputTrack->GetSegment()->CreateEmptyClone(); l->NotifyQueuedTrackChanges(Graph(), outputTrack->GetID(), offset, MediaStreamListener::TRACK_EVENT_ENDED, *segment); } outputTrack->SetEnded(); }
void TrackUnionStream::CopyTrackData(StreamBuffer::Track* aInputTrack, uint32_t aMapIndex, GraphTime aFrom, GraphTime aTo, bool* aOutputTrackFinished) { TrackMapEntry* map = &mTrackMap[aMapIndex]; StreamBuffer::Track* outputTrack = mBuffer.FindTrack(map->mOutputTrackID); MOZ_ASSERT(outputTrack && !outputTrack->IsEnded(), "Can't copy to ended track"); MediaSegment* segment = map->mSegment; MediaStream* source = map->mInputPort->GetSource(); GraphTime next; *aOutputTrackFinished = false; for (GraphTime t = aFrom; t < aTo; t = next) { MediaInputPort::InputInterval interval = map->mInputPort->GetNextInputInterval(t); interval.mEnd = std::min(interval.mEnd, aTo); StreamTime inputEnd = source->GraphTimeToStreamTime(interval.mEnd); StreamTime inputTrackEndPoint = STREAM_TIME_MAX; if (aInputTrack->IsEnded() && aInputTrack->GetEnd() <= inputEnd) { inputTrackEndPoint = aInputTrack->GetEnd(); *aOutputTrackFinished = true; } if (interval.mStart >= interval.mEnd) { break; } StreamTime ticks = interval.mEnd - interval.mStart; next = interval.mEnd; StreamTime outputStart = outputTrack->GetEnd(); if (interval.mInputIsBlocked) { // Maybe the input track ended? segment->AppendNullData(ticks); STREAM_LOG(PR_LOG_DEBUG+1, ("TrackUnionStream %p appending %lld ticks of null data to track %d", this, (long long)ticks, outputTrack->GetID())); } else if (InMutedCycle()) { segment->AppendNullData(ticks); } else { MOZ_ASSERT(outputTrack->GetEnd() == GraphTimeToStreamTime(interval.mStart), "Samples missing"); StreamTime inputStart = source->GraphTimeToStreamTime(interval.mStart); segment->AppendSlice(*aInputTrack->GetSegment(), std::min(inputTrackEndPoint, inputStart), std::min(inputTrackEndPoint, inputEnd)); } ApplyTrackDisabling(outputTrack->GetID(), segment); for (uint32_t j = 0; j < mListeners.Length(); ++j) { MediaStreamListener* l = mListeners[j]; l->NotifyQueuedTrackChanges(Graph(), outputTrack->GetID(), outputStart, 0, *segment); } outputTrack->GetSegment()->AppendFrom(segment); } }
void AudioNodeStream::FinishOutput() { StreamBuffer::Track* track = EnsureTrack(AUDIO_TRACK); track->SetEnded(); for (uint32_t j = 0; j < mListeners.Length(); ++j) { MediaStreamListener* l = mListeners[j]; AudioSegment emptySegment; l->NotifyQueuedTrackChanges(Graph(), AUDIO_TRACK, track->GetSegment()->GetDuration(), MediaStreamListener::TRACK_EVENT_ENDED, emptySegment); } }
void DOMHwMediaStream::SetImageSize(uint32_t width, uint32_t height) { #ifdef MOZ_WIDGET_GONK OverlayImage::Data imgData; imgData.mOverlayId = mOverlayImage->GetOverlayId(); imgData.mSize = IntSize(width, height); mOverlayImage->SetData(imgData); #endif SourceMediaStream* srcStream = GetInputStream()->AsSourceStream(); StreamBuffer::Track* track = srcStream->FindTrack(TRACK_VIDEO_PRIMARY); if (!track || !track->GetSegment()) { return; } #ifdef MOZ_WIDGET_GONK // Clear the old segment. // Changing the existing content of segment is a Very BAD thing, and this way will // confuse consumers of MediaStreams. // It is only acceptable for DOMHwMediaStream // because DOMHwMediaStream doesn't have consumers of TV streams currently. track->GetSegment()->Clear(); // Change the image size. const StreamTime delta = STREAM_TIME_MAX; RefPtr<Image> image = static_cast<Image*>(mOverlayImage.get()); mozilla::gfx::IntSize size = image->GetSize(); VideoSegment segment; segment.AppendFrame(image.forget(), delta, size); srcStream->AppendToTrack(TRACK_VIDEO_PRIMARY, &segment); #endif }
void TrackUnionStream::EndTrack(uint32_t aIndex) { StreamBuffer::Track* outputTrack = mBuffer.FindTrack(mTrackMap[aIndex].mOutputTrackID); if (!outputTrack || outputTrack->IsEnded()) return; STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p ending track %d", this, outputTrack->GetID())); for (uint32_t j = 0; j < mListeners.Length(); ++j) { MediaStreamListener* l = mListeners[j]; StreamTime offset = outputTrack->GetSegment()->GetDuration(); nsAutoPtr<MediaSegment> segment; segment = outputTrack->GetSegment()->CreateEmptyClone(); l->NotifyQueuedTrackChanges(Graph(), outputTrack->GetID(), offset, MediaStreamListener::TRACK_EVENT_ENDED, *segment, mTrackMap[aIndex].mInputPort->GetSource(), mTrackMap[aIndex].mInputTrackID); } for (TrackBound<MediaStreamTrackListener>& b : mTrackListeners) { if (b.mTrackID == outputTrack->GetID()) { b.mListener->NotifyEnded(); } } outputTrack->SetEnded(); }
void AudioNodeStream::FinishOutput() { if (IsFinishedOnGraphThread()) { return; } StreamBuffer::Track* track = EnsureTrack(); track->SetEnded(); FinishOnGraphThread(); for (uint32_t j = 0; j < mListeners.Length(); ++j) { MediaStreamListener* l = mListeners[j]; AudioSegment emptySegment; l->NotifyQueuedTrackChanges(Graph(), AUDIO_NODE_STREAM_TRACK_ID, IdealAudioRate(), track->GetSegment()->GetDuration(), MediaStreamListener::TRACK_EVENT_ENDED, emptySegment); } }