Example #1
0
nsresult GStreamerReader::GetBuffered(dom::TimeRanges* aBuffered,
                                      int64_t aStartTime)
{
    if (!mInfo.HasValidMedia()) {
        return NS_OK;
    }

#if GST_VERSION_MAJOR == 0
    GstFormat format = GST_FORMAT_TIME;
#endif
    MediaResource* resource = mDecoder->GetResource();
    nsTArray<MediaByteRange> ranges;
    resource->GetCachedRanges(ranges);

    if (resource->IsDataCachedToEndOfResource(0)) {
        /* fast path for local or completely cached files */
        gint64 duration = 0;

        {
            ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
            duration = mDecoder->GetMediaDuration();
        }

        double end = (double) duration / GST_MSECOND;
        LOG(PR_LOG_DEBUG, "complete range [0, %f] for [0, %li]",
            end, resource->GetLength());
        aBuffered->Add(0, end);
        return NS_OK;
    }

    for(uint32_t index = 0; index < ranges.Length(); index++) {
        int64_t startOffset = ranges[index].mStart;
        int64_t endOffset = ranges[index].mEnd;
        gint64 startTime, endTime;

#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;
#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;
#endif

        double start = (double) GST_TIME_AS_USECONDS (startTime) / GST_MSECOND;
        double end = (double) GST_TIME_AS_USECONDS (endTime) / GST_MSECOND;
        LOG(PR_LOG_DEBUG, "adding range [%f, %f] for [%li %li] size %li",
            start, end, startOffset, endOffset, resource->GetLength());
        aBuffered->Add(start, end);
    }

    return NS_OK;
}
nsresult GStreamerReader::GetBuffered(TimeRanges* aBuffered,
                                      int64_t aStartTime)
{
  if (!mInfo.mHasVideo && !mInfo.mHasAudio) {
    return NS_OK;
  }

  GstFormat format = GST_FORMAT_TIME;
  MediaResource* resource = mDecoder->GetResource();
  nsTArray<MediaByteRange> ranges;
  resource->GetCachedRanges(ranges);

  if (mDecoder->OnStateMachineThread())
    /* Report the position from here while buffering as we can't report it from
     * the gstreamer threads that are actually reading from the resource
     */
    NotifyBytesConsumed();

  if (resource->IsDataCachedToEndOfResource(0)) {
    /* fast path for local or completely cached files */
    gint64 duration = 0;

    duration = QueryDuration();
    double end = (double) duration / GST_MSECOND;
    LOG(PR_LOG_DEBUG, ("complete range [0, %f] for [0, %li]",
          end, resource->GetLength()));
    aBuffered->Add(0, end);
    return NS_OK;
  }

  for(uint32_t index = 0; index < ranges.Length(); index++) {
    int64_t startOffset = ranges[index].mStart;
    int64_t endOffset = ranges[index].mEnd;
    gint64 startTime, endTime;

    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;

    double start = (double) GST_TIME_AS_USECONDS (startTime) / GST_MSECOND;
    double end = (double) GST_TIME_AS_USECONDS (endTime) / GST_MSECOND;
    LOG(PR_LOG_DEBUG, ("adding range [%f, %f] for [%li %li] size %li",
          start, end, startOffset, endOffset, resource->GetLength()));
    aBuffered->Add(start, end);
  }

  return NS_OK;
}
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;
}