From 66498068fec6e41f9062f3418684880737ffc1ec Mon Sep 17 00:00:00 2001 From: Chun-Min Chang Date: Fri, 14 Jan 2022 18:39:04 +0000 Subject: [PATCH] Bug 1749372 - Combine chunks in AppendAndConsumeChunk if possible r=pehrsons Differential Revision: https://phabricator.services.mozilla.com/D135542 --- dom/media/AudioSegment.h | 7 +++ dom/media/gtest/TestAudioSegment.cpp | 69 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/dom/media/AudioSegment.h b/dom/media/AudioSegment.h index 9f83034cffb5..b8f0c2f79bb2 100644 --- a/dom/media/AudioSegment.h +++ b/dom/media/AudioSegment.h @@ -445,6 +445,13 @@ class AudioSegment : public MediaSegmentBase { return; } + if (!mChunks.IsEmpty() && + mChunks.LastElement().CanCombineWithFollowing(aChunk)) { + mChunks.LastElement().mDuration += aChunk.GetDuration(); + mDuration += aChunk.GetDuration(); + return; + } + chunk = AppendChunk(aChunk.mDuration); } void ApplyVolume(float aVolume); diff --git a/dom/media/gtest/TestAudioSegment.cpp b/dom/media/gtest/TestAudioSegment.cpp index 74457886ce76..ad1a99dc2521 100644 --- a/dom/media/gtest/TestAudioSegment.cpp +++ b/dom/media/gtest/TestAudioSegment.cpp @@ -372,4 +372,73 @@ TEST(AudioSegment, AppendAndConsumeNonEmptyZeroDurationChunk) EXPECT_FALSE(c.mBuffer->IsShared()); } +TEST(AudioSegment, CombineChunksInAppendAndConsumeChunk) +{ + AudioChunk source; + fillChunk(&source, 10); + + auto checkChunks = [&](const AudioSegment& aSegement, + const nsTArray& aDurations) { + size_t i = 0; + for (AudioSegment::ConstChunkIterator iter(aSegement); !iter.IsEnded(); + iter.Next()) { + EXPECT_EQ(iter->GetDuration(), aDurations[i++]); + } + EXPECT_EQ(i, aDurations.Length()); + }; + + // The chunks can be merged if their duration are adjacent. + { + AudioChunk c1(source); + c1.SliceTo(2, 5); + + AudioChunk c2(source); + c2.SliceTo(5, 9); + + AudioSegment s; + s.AppendAndConsumeChunk(std::move(c1)); + EXPECT_EQ(s.GetDuration(), 3); + + s.AppendAndConsumeChunk(std::move(c2)); + EXPECT_EQ(s.GetDuration(), 7); + + checkChunks(s, {7}); + } + // Otherwise, they cannot be merged. + { + // If durations of chunks are overlapped, they cannot be merged. + AudioChunk c1(source); + c1.SliceTo(2, 5); + + AudioChunk c2(source); + c2.SliceTo(4, 9); + + AudioSegment s; + s.AppendAndConsumeChunk(std::move(c1)); + EXPECT_EQ(s.GetDuration(), 3); + + s.AppendAndConsumeChunk(std::move(c2)); + EXPECT_EQ(s.GetDuration(), 8); + + checkChunks(s, {3, 5}); + } + { + // If durations of chunks are discontinuous, they cannot be merged. + AudioChunk c1(source); + c1.SliceTo(2, 4); + + AudioChunk c2(source); + c2.SliceTo(5, 9); + + AudioSegment s; + s.AppendAndConsumeChunk(std::move(c1)); + EXPECT_EQ(s.GetDuration(), 2); + + s.AppendAndConsumeChunk(std::move(c2)); + EXPECT_EQ(s.GetDuration(), 6); + + checkChunks(s, {2, 4}); + } +} + } // namespace audio_segment