Bug 1108917 - Part 1: Attempt to evict data from decoders in start-time order. r=ajones
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -197,39 +197,72 @@ TrackBuffer::AppendDataToCurrentResource
mCurrentDecoder->NotifyDataArrived(reinterpret_cast<const char*>(aData),
aLength, appendOffset);
mParentDecoder->NotifyBytesDownloaded();
mParentDecoder->NotifyTimeRangesChanged();
return true;
}
+class DecoderSorter
+{
+public:
+ bool LessThan(SourceBufferDecoder* aFirst, SourceBufferDecoder* aSecond) const
+ {
+ nsRefPtr<dom::TimeRanges> first = new dom::TimeRanges();
+ aFirst->GetBuffered(first);
+
+ nsRefPtr<dom::TimeRanges> second = new dom::TimeRanges();
+ aSecond->GetBuffered(second);
+
+ return first->GetStartTime() < second->GetStartTime();
+ }
+
+ bool Equals(SourceBufferDecoder* aFirst, SourceBufferDecoder* aSecond) const
+ {
+ nsRefPtr<dom::TimeRanges> first = new dom::TimeRanges();
+ aFirst->GetBuffered(first);
+
+ nsRefPtr<dom::TimeRanges> second = new dom::TimeRanges();
+ aSecond->GetBuffered(second);
+
+ return first->GetStartTime() == second->GetStartTime();
+ }
+};
+
bool
TrackBuffer::EvictData(uint32_t aThreshold)
{
MOZ_ASSERT(NS_IsMainThread());
ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor());
int64_t totalSize = 0;
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
totalSize += mDecoders[i]->GetResource()->GetSize();
}
int64_t toEvict = totalSize - aThreshold;
if (toEvict <= 0) {
return false;
}
- for (uint32_t i = 0; i < mInitializedDecoders.Length(); ++i) {
+ nsTArray<SourceBufferDecoder*> decoders;
+ decoders.AppendElements(mInitializedDecoders);
+ decoders.Sort(DecoderSorter());
+
+ for (uint32_t i = 0; i < decoders.Length(); ++i) {
MSE_DEBUG("TrackBuffer(%p)::EvictData decoder=%u threshold=%u toEvict=%lld",
this, i, aThreshold, toEvict);
- toEvict -= mInitializedDecoders[i]->GetResource()->EvictData(toEvict);
- if (!mInitializedDecoders[i]->GetResource()->GetSize() &&
- mInitializedDecoders[i] != mCurrentDecoder) {
- RemoveDecoder(mInitializedDecoders[i]);
+ toEvict -= decoders[i]->GetResource()->EvictData(toEvict);
+ if (!decoders[i]->GetResource()->GetSize() &&
+ decoders[i] != mCurrentDecoder) {
+ RemoveDecoder(decoders[i]);
+ }
+ if (toEvict <= 0 || decoders[i] == mCurrentDecoder) {
+ break;
}
}
return toEvict < (totalSize - aThreshold);
}
void
TrackBuffer::EvictBefore(double aTime)
{