Bug 1407549 - Avoid array operations that can cause alloc/dalloc in MediaSegment. r?padenot
MozReview-Commit-ID: Fhg9NIltFti
--- a/dom/media/MediaSegment.h
+++ b/dom/media/MediaSegment.h
@@ -449,36 +449,50 @@ public:
protected:
explicit MediaSegmentBase(Type aType)
: MediaSegment(aType)
, mChunks(DEFAULT_SEGMENT_CAPACITY)
{}
MediaSegmentBase(MediaSegmentBase&& aSegment)
: MediaSegment(Move(aSegment))
- , mChunks(Move(aSegment.mChunks))
+ , mChunks(aSegment.mChunks.Capacity())
#ifdef MOZILLA_INTERNAL_API
, mTimeStamp(Move(aSegment.mTimeStamp))
#endif
- {}
+ {
+ mChunks.SwapElements(aSegment.mChunks);
+ MOZ_ASSERT(mChunks.Capacity() >= DEFAULT_SEGMENT_CAPACITY,
+ "Capacity must be retained in self after swap");
+ MOZ_ASSERT(aSegment.mChunks.Capacity() >= DEFAULT_SEGMENT_CAPACITY,
+ "Capacity must be retained in other after swap");
+ }
/**
* Appends the contents of aSource to this segment, clearing aSource.
*/
void AppendFromInternal(MediaSegmentBase<C, Chunk>* aSource)
{
MOZ_ASSERT(aSource->mDuration >= 0);
mDuration += aSource->mDuration;
aSource->mDuration = 0;
+ size_t offset = 0;
if (!mChunks.IsEmpty() && !aSource->mChunks.IsEmpty() &&
mChunks[mChunks.Length() - 1].CanCombineWithFollowing(aSource->mChunks[0])) {
mChunks[mChunks.Length() - 1].mDuration += aSource->mChunks[0].mDuration;
- aSource->mChunks.RemoveElementAt(0);
+ offset = 1;
}
- mChunks.AppendElements(Move(aSource->mChunks));
+
+ for (; offset < aSource->mChunks.Length(); ++offset) {
+ mChunks.AppendElement(Move(aSource->mChunks[offset]));
+ }
+
+ aSource->mChunks.ClearAndRetainStorage();
+ MOZ_ASSERT(aSource->mChunks.Capacity() >= DEFAULT_SEGMENT_CAPACITY,
+ "Capacity must be retained after appending from aSource");
}
void AppendSliceInternal(const MediaSegmentBase<C, Chunk>& aSource,
StreamTime aStart, StreamTime aEnd)
{
MOZ_ASSERT(aStart <= aEnd, "Endpoints inverted");
NS_ASSERTION(aStart >= 0 && aEnd <= aSource.mDuration, "Slice out of range");
mDuration += aEnd - aStart;
@@ -521,18 +535,25 @@ protected:
if (c->GetDuration() > t) {
c->SliceTo(t, c->GetDuration());
t = 0;
break;
}
t -= c->GetDuration();
chunksToRemove = i + 1 - aStartIndex;
}
- mChunks.RemoveElementsAt(aStartIndex, chunksToRemove);
+ if (aStartIndex == 0 && chunksToRemove == mChunks.Length()) {
+ mChunks.ClearAndRetainStorage();
+ } else {
+ mChunks.RemoveElementsAt(aStartIndex, chunksToRemove);
+ }
mDuration -= aDuration - t;
+
+ MOZ_ASSERT(mChunks.Capacity() >= DEFAULT_SEGMENT_CAPACITY,
+ "Capacity must be retained after removing chunks");
}
void RemoveTrailing(StreamTime aKeep, uint32_t aStartIndex)
{
NS_ASSERTION(aKeep >= 0, "Can't keep negative duration");
StreamTime t = aKeep;
uint32_t i;
for (i = aStartIndex; i < mChunks.Length(); ++i) {
@@ -544,16 +565,18 @@ protected:
t -= c->GetDuration();
if (t == 0) {
break;
}
}
if (i+1 < mChunks.Length()) {
mChunks.RemoveElementsAt(i+1, mChunks.Length() - (i+1));
}
+ MOZ_ASSERT(mChunks.Capacity() >= DEFAULT_SEGMENT_CAPACITY,
+ "Capacity must be retained after removing chunks");
// Caller must adjust mDuration
}
nsTArray<Chunk> mChunks;
#ifdef MOZILLA_INTERNAL_API
mozilla::TimeStamp mTimeStamp;
#endif
};