예제 #1
0
TimeUnit
MP3TrackDemuxer::FastSeek(TimeUnit aTime) {
  MP3DEMUXER_LOG("FastSeek(%" PRId64 ") avgFrameLen=%f mNumParsedFrames=%" PRIu64
                 " mFrameIndex=%" PRId64 " mOffset=%" PRIu64,
                 aTime, AverageFrameLength(), mNumParsedFrames, mFrameIndex,
                 mOffset);

  if (!aTime.ToMicroseconds()) {
    // Quick seek to the beginning of the stream.
    mOffset = mFirstFrameOffset;
    mFrameIndex = 0;
    mParser.EndFrameSession();
    return TimeUnit();
  }

  if (!mSamplesPerFrame || !mNumParsedFrames) {
    return TimeUnit::FromMicroseconds(-1);
  }

  const int64_t numFrames = aTime.ToSeconds() *
                            mSamplesPerSecond / mSamplesPerFrame;
  mOffset = mFirstFrameOffset + numFrames * AverageFrameLength();
  mFrameIndex = numFrames;

  MP3DEMUXER_LOG("FastSeek mSamplesPerSecond=%d mSamplesPerFrame=%d "
                 "numFrames=%" PRId64,
                 mSamplesPerSecond, mSamplesPerFrame, numFrames);

  mParser.EndFrameSession();

  return Duration(mFrameIndex);
}
예제 #2
0
already_AddRefed<MediaByteBuffer>
SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
    typedef SourceBufferContentManager::EvictDataResult Result;

    if (!IsAttached() || mUpdating) {
        aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
        return nullptr;
    }
    if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
        mMediaSource->SetReadyState(MediaSourceReadyState::Open);
    }

    // Eviction uses a byte threshold. If the buffer is greater than the
    // number of bytes then data is evicted. The time range for this
    // eviction is reported back to the media source. It will then
    // evict data before that range across all SourceBuffers it knows
    // about.
    // TODO: Make the eviction threshold smaller for audio-only streams.
    // TODO: Drive evictions off memory pressure notifications.
    // TODO: Consider a global eviction threshold  rather than per TrackBuffer.
    TimeUnit newBufferStartTime;
    // Attempt to evict the amount of data we are about to add by lowering the
    // threshold.
    uint32_t toEvict =
        (mEvictionThreshold > aLength) ? mEvictionThreshold - aLength : aLength;
    Result evicted =
        mContentManager->EvictData(TimeUnit::FromSeconds(mMediaSource->GetDecoder()->GetCurrentTime()),
                                   toEvict, &newBufferStartTime);
    if (evicted == Result::DATA_EVICTED) {
        MSE_DEBUG("AppendData Evict; current buffered start=%f",
                  GetBufferedStart());

        // We notify that we've evicted from the time range 0 through to
        // the current start point.
        mMediaSource->NotifyEvicted(0.0, newBufferStartTime.ToSeconds());
    }

    // See if we have enough free space to append our new data.
    // As we can only evict once we have playable data, we must give a chance
    // to the DASH player to provide a complete media segment.
    if (aLength > mEvictionThreshold || evicted == Result::BUFFER_FULL ||
            ((!mIsUsingFormatReader &&
              mContentManager->GetSize() > mEvictionThreshold - aLength) &&
             evicted != Result::CANT_EVICT)) {
        aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
        return nullptr;
    }

    nsRefPtr<MediaByteBuffer> data = new MediaByteBuffer();
    if (!data->AppendElements(aData, aLength, fallible)) {
        aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
        return nullptr;
    }
    return data.forget();
}
예제 #3
0
void MediaDecoder::DurationChanged(TimeUnit aNewDuration)
{
  MOZ_ASSERT(NS_IsMainThread());
  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
  int64_t oldDuration = mDuration;
  mDuration = aNewDuration.ToMicroseconds();
  // Duration has changed so we should recompute playback rate
  UpdatePlaybackRate();

  SetInfinite(mDuration == -1);

  if (mOwner && oldDuration != mDuration && !IsInfinite()) {
    DECODER_LOG("Duration changed to %lld", mDuration);
    mOwner->DispatchAsyncEvent(NS_LITERAL_STRING("durationchange"));
  }

  if (CurrentPosition() > aNewDuration.ToMicroseconds()) {
    Seek(aNewDuration.ToSeconds(), SeekTarget::Accurate);
  }
}
예제 #4
0
TimeUnit
MP3TrackDemuxer::FastSeek(TimeUnit aTime) {
  if (!aTime.ToMicroseconds()) {
    // Quick seek to the beginning of the stream.
    mOffset = mFirstFrameOffset;
    mFrameIndex = 0;
    mParser.EndFrameSession();
    return TimeUnit();
  }

  if (!mSamplesPerFrame || !mNumParsedFrames) {
    return TimeUnit::FromMicroseconds(-1);
  }

  const int64_t numFrames = aTime.ToSeconds() *
                            mSamplesPerSecond / mSamplesPerFrame;
  mOffset = mFirstFrameOffset + numFrames * AverageFrameLength();
  mFrameIndex = numFrames;

  mParser.EndFrameSession();

  return Duration(mFrameIndex);
}