예제 #1
0
 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());
}
예제 #3
0
  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__);
    }
  }
예제 #4
0
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;
}