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); }
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(); }
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); } }
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); }