author | Jean-Yves Avenard <jyavenard@mozilla.com> |
Fri, 20 Feb 2015 14:19:13 +1300 | |
changeset 229948 | 661dcf41cef9a2acbb6b4b2dc4af627c750a4b56 |
parent 229947 | 25e29e6871e6ee7ed8180d779b5557abc3c972f5 |
child 229949 | af39fc4994cc2c06cce3f11d582b17cd3195cfbb |
push id | 55849 |
push user | jyavenard@mozilla.com |
push date | Fri, 20 Feb 2015 01:20:02 +0000 |
treeherder | mozilla-inbound@fb6b682a464e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | cajbir |
bugs | 1133625 |
milestone | 38.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/media/mediasource/SourceBuffer.cpp +++ b/dom/media/mediasource/SourceBuffer.cpp @@ -554,16 +554,25 @@ SourceBuffer::PrepareAppend(const uint8_ 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); } + // 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 ((mTrackBuffer->GetSize() > mEvictionThreshold - aLength) && + !mTrackBuffer->HasOnlyIncompleteMedia()) { + aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR); + return nullptr; + } + nsRefPtr<LargeDataBuffer> data = new LargeDataBuffer(); if (!data->AppendElements(aData, aLength)) { aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR); return nullptr; } // TODO: Test buffer full flag. return data.forget(); }
--- a/dom/media/mediasource/TrackBuffer.cpp +++ b/dom/media/mediasource/TrackBuffer.cpp @@ -301,20 +301,17 @@ TrackBuffer::EvictData(double aPlaybackT { MOZ_ASSERT(NS_IsMainThread()); ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); if (!mCurrentDecoder) { return false; } - int64_t totalSize = 0; - for (uint32_t i = 0; i < mDecoders.Length(); ++i) { - totalSize += mDecoders[i]->GetResource()->GetSize(); - } + int64_t totalSize = GetSize(); int64_t toEvict = totalSize - aThreshold; if (toEvict <= 0 || mInitializedDecoders.IsEmpty()) { return false; } // Get a list of initialized decoders. nsTArray<SourceBufferDecoder*> decoders; @@ -444,16 +441,37 @@ TrackBuffer::RemoveEmptyDecoders(nsTArra buffered->GetStartTime() < 0.0 || buffered->GetEndTime() < 0.0) { MSE_DEBUG("remove empty decoders=%d", i); RemoveDecoder(aDecoders[i]); } } } +int64_t +TrackBuffer::GetSize() +{ + int64_t totalSize = 0; + for (uint32_t i = 0; i < mInitializedDecoders.Length(); ++i) { + totalSize += mInitializedDecoders[i]->GetResource()->GetSize(); + } + return totalSize; +} + +bool +TrackBuffer::HasOnlyIncompleteMedia() +{ + if (!mCurrentDecoder) { + return false; + } + nsRefPtr<dom::TimeRanges> buffered = new dom::TimeRanges(); + mCurrentDecoder->GetBuffered(buffered); + return mCurrentDecoder->GetResource()->GetSize() && !buffered->Length(); +} + void TrackBuffer::EvictBefore(double aTime) { MOZ_ASSERT(NS_IsMainThread()); ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); for (uint32_t i = 0; i < mInitializedDecoders.Length(); ++i) { int64_t endOffset = mInitializedDecoders[i]->ConvertToByteOffset(aTime); if (endOffset > 0) {
--- a/dom/media/mediasource/TrackBuffer.h +++ b/dom/media/mediasource/TrackBuffer.h @@ -99,16 +99,23 @@ public: // Implementation is only partial, we can only trim a buffer. // Returns true if data was evicted. // Times are in microseconds. bool RangeRemoval(int64_t aStart, int64_t aEnd); // Abort any pending appendBuffer by rejecting any pending promises. void AbortAppendData(); + // Return the size used by all decoders managed by this TrackBuffer. + int64_t GetSize(); + + // Return true if we have a partial media segment being appended that is + // currently not playable. + bool HasOnlyIncompleteMedia(); + #ifdef MOZ_EME nsresult SetCDMProxy(CDMProxy* aProxy); #endif #if defined(DEBUG) void Dump(const char* aPath); #endif