Bug 1216460 - [2.2] Refactor SourceBuffer frame eviction and threshold defaults. r=jya

* Move eviction handling out of SourceBuffer into TrackBuffersManager
* Separate audio and video eviction thresholds
* Reduce default audio eviction threshold to 15MB
This commit is contained in:
Eugen Sawin 2016-03-18 22:26:56 +01:00
parent 39faf25691
commit c94e9927bc
6 changed files with 31 additions and 18 deletions

View File

@ -295,8 +295,6 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aMediaSource);
mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold",
100 * (1 << 20));
bool generateTimestamps = false;
if (aType.LowerCaseEqualsLiteral("audio/mpeg") ||
aType.LowerCaseEqualsLiteral("audio/aac")) {
@ -524,11 +522,9 @@ SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult&
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);
aLength, &newBufferStartTime);
if (evicted == Result::DATA_EVICTED) {
MSE_DEBUG("AppendData Evict; current buffered start=%f",
GetBufferedStart());
@ -541,7 +537,8 @@ SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult&
// 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) {
if (aLength > mContentManager->EvictionThreshold() ||
evicted == Result::BUFFER_FULL) {
aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
return nullptr;
}

View File

@ -253,8 +253,6 @@ private:
RefPtr<MediaSource> mMediaSource;
uint32_t mEvictionThreshold;
RefPtr<SourceBufferContentManager> mContentManager;
RefPtr<SourceBufferAttributes> mAttributes;

View File

@ -107,6 +107,7 @@ public:
virtual void SetGroupStartTimestamp(const media::TimeUnit& aGroupStartTimestamp) {}
virtual void RestartGroupStartTimestamp() {}
virtual media::TimeUnit GroupEndTimestamp() = 0;
virtual int64_t EvictionThreshold() const = 0;
protected:
virtual ~SourceBufferContentManager() { }

View File

@ -111,9 +111,9 @@ public:
ReentrantMonitorAutoEnter mon(mMonitor);
return mEnded;
}
// Remove data from resource if it holds more than the threshold
// number of bytes. Returns amount evicted.
uint32_t EvictData(uint64_t aPlaybackOffset, int64_t aThreshold,
// Remove data from resource if it holds more than the threshold reduced by
// the given number of bytes. Returns amount evicted.
uint32_t EvictData(uint64_t aPlaybackOffset, int64_t aThresholdReduct,
ErrorResult& aRv);
// Remove data from resource before the given offset.

View File

@ -99,8 +99,10 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBufferAttributes* aAttribute
, mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue())
, mSourceBufferAttributes(aAttributes)
, mParentDecoder(new nsMainThreadPtrHolder<MediaSourceDecoder>(aParentDecoder, false /* strict */))
, mEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold",
100 * (1 << 20)))
, mVideoEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold.video",
100 * 1024 * 1024))
, mAudioEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold.audio",
15 * 1024 * 1024))
, mEvictionOccurred(false)
, mMonitor("TrackBuffersManager")
, mAppendRunning(false)
@ -202,9 +204,13 @@ TrackBuffersManager::EvictData(TimeUnit aPlaybackTime,
TimeUnit* aBufferStartTime)
{
MOZ_ASSERT(NS_IsMainThread());
MSE_DEBUG("");
int64_t toEvict = GetSize() - aThreshold;
const int64_t toEvict = GetSize() -
std::max(EvictionThreshold() - aThresholdReduct, aThresholdReduct);
MSE_DEBUG("buffered=%lldkb, eviction threshold=%ukb, evict=%lldkb",
GetSize() / 1024, EvictionThreshold() / 1024, toEvict / 1024);
if (toEvict <= 0) {
return EvictDataResult::NO_DATA_EVICTED;
}
@ -351,6 +357,15 @@ TrackBuffersManager::CompleteResetParserState()
mAppendPromise.RejectIfExists(NS_ERROR_ABORT, __func__);
}
int64_t
TrackBuffersManager::EvictionThreshold() const
{
if (HasVideo()) {
return mVideoEvictionThreshold;
}
return mAudioEvictionThreshold;
}
void
TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
int64_t aSizeToEvict)
@ -501,7 +516,7 @@ TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval)
mSizeSourceBuffer = mVideoTracks.mSizeBuffer + mAudioTracks.mSizeBuffer;
// 4. If buffer full flag equals true and this object is ready to accept more bytes, then set the buffer full flag to false.
if (mBufferFull && mSizeSourceBuffer < mEvictionThreshold) {
if (mBufferFull && mSizeSourceBuffer < EvictionThreshold()) {
mBufferFull = false;
}
mEvictionOccurred = true;
@ -1237,7 +1252,7 @@ TrackBuffersManager::CompleteCodedFrameProcessing()
// Return to step 6.4 of Segment Parser Loop algorithm
// 4. If this SourceBuffer is full and cannot accept more media data, then set the buffer full flag to true.
if (mSizeSourceBuffer >= mEvictionThreshold) {
if (mSizeSourceBuffer >= EvictionThreshold()) {
mBufferFull = true;
mEvictionOccurred = false;
}

View File

@ -77,6 +77,7 @@ public:
void SetGroupStartTimestamp(const media::TimeUnit& aGroupStartTimestamp) override;
void RestartGroupStartTimestamp() override;
media::TimeUnit GroupEndTimestamp() override;
int64_t EvictionThreshold() const override;
// Interface for MediaSourceDemuxer
MediaInfo GetMetadata();
@ -344,7 +345,8 @@ private:
// Global size of this source buffer content.
Atomic<int64_t> mSizeSourceBuffer;
uint32_t mEvictionThreshold;
int64_t mVideoEvictionThreshold;
int64_t mAudioEvictionThreshold;
Atomic<bool> mEvictionOccurred;
// Monitor to protect following objects accessed across multipple threads.