RefPtr<HaveStartTimePromise> AwaitStartTime() { if (HaveStartTime()) { return HaveStartTimePromise::CreateAndResolve(true, __func__); } return mHaveStartTimePromise.Ensure(__func__); }
media::TimeIntervals MediaDecoderReader::GetBuffered() { MOZ_ASSERT(OnTaskQueue()); if (!HaveStartTime()) { return media::TimeIntervals(); } AutoPinned<MediaResource> stream(mDecoder->GetResource()); if (!mDuration.Ref().isSome()) { return TimeIntervals(); } return GetEstimatedBufferedTimeRanges(stream, mDuration.Ref().ref().ToMicroseconds()); }
void MaybeSetChannelStartTime(int64_t aStartTime) { if (ChannelStartTime(SampleType).isSome()) { // If we're initialized with aForceZeroStartTime=true, the channel start // times are already set. return; } LOG("StartTimeRendezvous=%p Setting SampleType(%d) start time to %lld", this, SampleType, aStartTime); ChannelStartTime(SampleType).emplace(aStartTime); if (HaveStartTime()) { mHaveStartTimePromise.ResolveIfExists(true, __func__); } }
media::TimeIntervals GStreamerReader::GetBuffered() { MOZ_ASSERT(OnTaskQueue()); if (!HaveStartTime()) { return media::TimeIntervals(); } media::TimeIntervals buffered; if (!mInfo.HasValidMedia()) { return buffered; } #if GST_VERSION_MAJOR == 0 GstFormat format = GST_FORMAT_TIME; #endif AutoPinned<MediaResource> resource(mDecoder->GetResource()); nsTArray<MediaByteRange> ranges; resource->GetCachedRanges(ranges); if (resource->IsDataCachedToEndOfResource(0)) { /* fast path for local or completely cached files */ gint64 duration = mDuration.ReadOnWrongThread().refOr(media::TimeUnit::FromMicroseconds(0)).ToMicroseconds(); LOG(LogLevel::Debug, "complete range [0, %f] for [0, %li]", (double) duration / GST_MSECOND, GetDataLength()); buffered += media::TimeInterval(media::TimeUnit::FromMicroseconds(0), media::TimeUnit::FromMicroseconds(duration)); return buffered; } for(uint32_t index = 0; index < ranges.Length(); index++) { int64_t startOffset = ranges[index].mStart; int64_t endOffset = ranges[index].mEnd; gint64 startTime, endTime, duration; bool haveDuration = false; #if GST_VERSION_MAJOR >= 1 if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, startOffset, GST_FORMAT_TIME, &startTime)) continue; if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, endOffset, GST_FORMAT_TIME, &endTime)) continue; if (gst_element_query_duration(GST_ELEMENT(mPlayBin), GST_FORMAT_TIME, &duration)) { haveDuration = true; } #else if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, startOffset, &format, &startTime) || format != GST_FORMAT_TIME) continue; if (!gst_element_query_convert(GST_ELEMENT(mPlayBin), GST_FORMAT_BYTES, endOffset, &format, &endTime) || format != GST_FORMAT_TIME) continue; if (gst_element_query_duration(GST_ELEMENT(mPlayBin), &format, &duration) && format == GST_FORMAT_TIME) { haveDuration = true; } #endif // Check that the estimated time doesn't go beyond known duration // as this indicates a buggy gst plugin. if (haveDuration && endTime > duration) { LOG(LogLevel::Debug, "Have duration %" GST_TIME_FORMAT "contradicting endTime %" GST_TIME_FORMAT, GST_TIME_ARGS(duration), GST_TIME_ARGS(endTime)); endTime = std::min(endTime, duration); } LOG(LogLevel::Debug, "adding range [%f, %f] for [%li %li] size %li", (double) GST_TIME_AS_USECONDS (startTime) / GST_MSECOND, (double) GST_TIME_AS_USECONDS (endTime) / GST_MSECOND, startOffset, endOffset, GetDataLength()); buffered += media::TimeInterval(media::TimeUnit::FromMicroseconds(GST_TIME_AS_USECONDS(startTime)), media::TimeUnit::FromMicroseconds(GST_TIME_AS_USECONDS(endTime))); } return buffered; }