From ad87a431012546a94d045d99e4140a13c2afdc8a Mon Sep 17 00:00:00 2001 From: Bryce Seager van Dyk Date: Fri, 18 Feb 2022 02:18:49 +0000 Subject: [PATCH] Bug 1697476 - Shrink MSE's mInputBuffer during append even if it's not empty. r=media-playback-reviewers,kinetik,alwu This prevents us eventually overflowing the buffer when getting certain data appended. Differential Revision: https://phabricator.services.mozilla.com/D138970 --- dom/media/mediasource/TrackBuffersManager.cpp | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index 22a246895b25..d521d80f3c0d 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -216,9 +216,28 @@ void TrackBuffersManager::ProcessTasks() { // Note: we reset mInputBuffer here to ensure it doesn't grow unbounded. mInputBuffer.reset(); mInputBuffer = Some(MediaSpan(task->As()->mBuffer)); - } else if (!mInputBuffer->Append(task->As()->mBuffer)) { - RejectAppend(NS_ERROR_OUT_OF_MEMORY, __func__); - return; + } else { + // mInputBuffer wasn't empty, so we can't just reset it, but we move + // the data into a new buffer to clear out data no longer in the span. + MSE_DEBUG( + "mInputBuffer not empty during append -- data will be copied to " + "new buffer. mInputBuffer->Length()=%zu " + "mInputBuffer->Buffer()->Length()=%zu", + mInputBuffer->Length(), mInputBuffer->Buffer()->Length()); + const RefPtr newBuffer{new MediaByteBuffer()}; + // Set capacity outside of ctor to let us explicitly handle OOM. + const size_t newCapacity = + mInputBuffer->Length() + + task->As()->mBuffer->Length(); + if (!newBuffer->SetCapacity(newCapacity, fallible)) { + RejectAppend(NS_ERROR_OUT_OF_MEMORY, __func__); + return; + } + // Use infallible appends as we've already set capacity above. + newBuffer->AppendElements(mInputBuffer->Elements(), + mInputBuffer->Length()); + newBuffer->AppendElements(*task->As()->mBuffer); + mInputBuffer = Some(MediaSpan(newBuffer)); } mSourceBufferAttributes = MakeUnique( task->As()->mAttributes);