MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder) : mAudioCompactor(mAudioQueue) , mDecoder(aDecoder) , mTaskQueue(new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK), /* aSupportsTailDispatch = */ true)) , mWatchManager(this, mTaskQueue) , mBuffered(mTaskQueue, TimeIntervals(), "MediaDecoderReader::mBuffered (Canonical)") , mDuration(mTaskQueue, NullableTimeUnit(), "MediaDecoderReader::mDuration (Mirror)") , mIgnoreAudioOutputFormat(false) , mHitAudioDecodeError(false) , mShutdown(false) , mIsSuspended(mTaskQueue, true, "MediaDecoderReader::mIsSuspended (Canonical)") { MOZ_COUNT_CTOR(MediaDecoderReader); MOZ_ASSERT(NS_IsMainThread()); if (mDecoder && mDecoder->DataArrivedEvent()) { mDataArrivedListener = mDecoder->DataArrivedEvent()->Connect( mTaskQueue, this, &MediaDecoderReader::NotifyDataArrived); } ReaderQueue::Instance().Add(this); // Dispatch initialization that needs to happen on that task queue. mTaskQueue->Dispatch(NewRunnableMethod(this, &MediaDecoderReader::InitializationTask)); }
MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder, TaskQueue* aBorrowedTaskQueue) : mAudioCompactor(mAudioQueue) , mDecoder(aDecoder) , mTaskQueue(aBorrowedTaskQueue ? aBorrowedTaskQueue : new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK), /* aSupportsTailDispatch = */ true)) , mWatchManager(this, mTaskQueue) , mTimer(new MediaTimer()) , mBuffered(mTaskQueue, TimeIntervals(), "MediaDecoderReader::mBuffered (Canonical)") , mDuration(mTaskQueue, NullableTimeUnit(), "MediaDecoderReader::mDuration (Mirror)") , mThrottleDuration(TimeDuration::FromMilliseconds(500)) , mLastThrottledNotify(TimeStamp::Now() - mThrottleDuration) , mIgnoreAudioOutputFormat(false) , mHitAudioDecodeError(false) , mShutdown(false) , mTaskQueueIsBorrowed(!!aBorrowedTaskQueue) , mAudioDiscontinuity(false) , mVideoDiscontinuity(false) { MOZ_COUNT_CTOR(MediaDecoderReader); MOZ_ASSERT(NS_IsMainThread()); // Dispatch initialization that needs to happen on that task queue. nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethod(this, &MediaDecoderReader::InitializationTask); mTaskQueue->Dispatch(r.forget()); }
media::TimeIntervals MediaDecoderReader::GetBuffered() { NS_ENSURE_TRUE(mStartTime >= 0, media::TimeIntervals()); AutoPinned<MediaResource> stream(mDecoder->GetResource()); if (!mDuration.ReadOnWrongThread().isSome()) { return TimeIntervals(); } return GetEstimatedBufferedTimeRanges(stream, mDuration.ReadOnWrongThread().ref().ToMicroseconds()); }
media::TimeIntervals MediaDecoderReader::GetBuffered() { MOZ_ASSERT(OnTaskQueue()); AutoPinned<MediaResource> stream(mDecoder->GetResource()); if (!mDuration.Ref().isSome()) { return TimeIntervals(); } return GetEstimatedBufferedTimeRanges(stream, mDuration.Ref().ref().ToMicroseconds()); }
MediaDecoderReader::MediaDecoderReader(AbstractMediaDecoder* aDecoder) : mAudioCompactor(mAudioQueue) , mDecoder(aDecoder) , mTaskQueue(new TaskQueue( GetMediaThreadPool(MediaThreadType::PLAYBACK), "MediaDecoderReader::mTaskQueue", /* aSupportsTailDispatch = */ true)) , mWatchManager(this, mTaskQueue) , mBuffered(mTaskQueue, TimeIntervals(), "MediaDecoderReader::mBuffered (Canonical)") , mDuration(mTaskQueue, NullableTimeUnit(), "MediaDecoderReader::mDuration (Mirror)") , mIgnoreAudioOutputFormat(false) , mHitAudioDecodeError(false) , mShutdown(false) { MOZ_COUNT_CTOR(MediaDecoderReader); MOZ_ASSERT(NS_IsMainThread()); }
media::TimeIntervals MediaSourceDecoder::GetBuffered() { MOZ_ASSERT(NS_IsMainThread()); if (!mMediaSource) { NS_WARNING("MediaSource element isn't attached"); return media::TimeIntervals::Invalid(); } dom::SourceBufferList* sourceBuffers = mMediaSource->ActiveSourceBuffers(); if (!sourceBuffers) { // Media source object is shutting down. return TimeIntervals(); } media::TimeUnit highestEndTime; nsTArray<media::TimeIntervals> activeRanges; media::TimeIntervals buffered; for (uint32_t i = 0; i < sourceBuffers->Length(); i++) { bool found; dom::SourceBuffer* sb = sourceBuffers->IndexedGetter(i, found); MOZ_ASSERT(found); activeRanges.AppendElement(sb->GetTimeIntervals()); highestEndTime = std::max(highestEndTime, activeRanges.LastElement().GetEnd()); } buffered += media::TimeInterval(media::TimeUnit::FromMicroseconds(0), highestEndTime); for (auto& range : activeRanges) { if (mEnded && range.Length()) { // Set the end time on the last range to highestEndTime by adding a // new range spanning the current end time to highestEndTime, which // Normalize() will then merge with the old last range. range += media::TimeInterval(range.GetEnd(), highestEndTime); } buffered.Intersection(range); } MSE_DEBUG("ranges=%s", DumpTimeRanges(buffered).get()); return buffered; }