Skip to content

Commit

Permalink
[MSE] Reuse "fudge factor" when samples are removed
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=258869

Reviewed by Xabier Rodriguez-Calvar.

Currently when TrackBuffer::removeSamples is called and erasedRanged is created from the samples,
removing small gaps between samples is not done. It causes that in some cases many separated ranges
are created which has impact on performance of removing samples.

Reusing "eliminate small gap" mechanism from SourceBufferPrivate::processMediaSample solves the problem.

* Source/WebCore/html/TimeRanges.cpp:
(WebCore::TimeRanges::add):
* Source/WebCore/html/TimeRanges.h:
* Source/WebCore/platform/graphics/PlatformTimeRanges.cpp:
(WebCore::PlatformTimeRanges::timeFudgeFactor):
(WebCore::PlatformTimeRanges::add):
* Source/WebCore/platform/graphics/PlatformTimeRanges.h:
* Source/WebCore/platform/graphics/SourceBufferPrivate.cpp:
(WebCore::SourceBufferPrivate::processMediaSample):
* Source/WebCore/platform/graphics/SourceBufferPrivate.h:
(WebCore::SourceBufferPrivate::timeFudgeFactor const):
* Source/WebCore/platform/graphics/TrackBuffer.cpp:
(WebCore::TrackBuffer::addBufferedRange):
(WebCore::TrackBuffer::removeSamples):
* Source/WebCore/platform/graphics/TrackBuffer.h:
* Tools/TestWebKitAPI/Tests/WebCore/TimeRanges.cpp:
(TestWebKitAPI::TEST):

Canonical link: https://commits.webkit.org/266357@main
  • Loading branch information
pgorszkowski-igalia authored and Ahmad Saleem committed Jul 27, 2023
1 parent a799925 commit c3bf8dd
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 22 deletions.
4 changes: 2 additions & 2 deletions Source/WebCore/html/TimeRanges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ unsigned TimeRanges::length() const
return m_ranges.length();
}

void TimeRanges::add(double start, double end)
void TimeRanges::add(double start, double end, AddTimeRangeOption addTimeRangeOption)
{
m_ranges.add(MediaTime::createWithDouble(start), MediaTime::createWithDouble(end));
m_ranges.add(MediaTime::createWithDouble(start), MediaTime::createWithDouble(end), addTimeRangeOption);
}

bool TimeRanges::contain(double time) const
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/html/TimeRanges.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class TimeRanges : public RefCounted<TimeRanges> {

WEBCORE_EXPORT unsigned length() const;

WEBCORE_EXPORT void add(double start, double end);
WEBCORE_EXPORT void add(double start, double end, AddTimeRangeOption = AddTimeRangeOption::None);
bool contain(double time) const;

size_t find(double time) const;
Expand Down
22 changes: 20 additions & 2 deletions Source/WebCore/platform/graphics/PlatformTimeRanges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ const PlatformTimeRanges& PlatformTimeRanges::emptyRanges()
return emptyRanges.get();
}

MediaTime PlatformTimeRanges::timeFudgeFactor()
{
return { 2002, 24000 };
}

void PlatformTimeRanges::invert()
{
PlatformTimeRanges inverted;
Expand Down Expand Up @@ -192,16 +197,29 @@ MediaTime PlatformTimeRanges::minimumBufferedTime() const
return m_ranges[0].start;
}

void PlatformTimeRanges::add(const MediaTime& start, const MediaTime& end)
void PlatformTimeRanges::add(const MediaTime& start, const MediaTime& end, AddTimeRangeOption addTimeRangeOption)
{
#if !PLATFORM(MAC) // https://bugs.webkit.org/show_bug.cgi?id=180253
ASSERT(start.isValid());
ASSERT(end.isValid());
#endif
ASSERT(start <= end);

auto startTime = start;
auto endTime = end;
if (addTimeRangeOption == AddTimeRangeOption::EliminateSmallGaps) {
// Eliminate small gaps between buffered ranges by coalescing
// disjoint ranges separated by less than a "fudge factor".
auto nearestToPresentationStartTime = nearest(startTime);
if (nearestToPresentationStartTime.isValid() && (startTime - nearestToPresentationStartTime).isBetween(MediaTime::zeroTime(), timeFudgeFactor()))
startTime = nearestToPresentationStartTime;

auto nearestToPresentationEndTime = nearest(endTime);
if (nearestToPresentationEndTime.isValid() && (nearestToPresentationEndTime - endTime).isBetween(MediaTime::zeroTime(), timeFudgeFactor()))
endTime = nearestToPresentationEndTime;
}
size_t overlappingArcIndex;
Range addedRange { .start = start, .end = end };
Range addedRange { .start = startTime, .end = endTime };

// For each present range check if we need to:
// - merge with the added range, in case we are overlapping or contiguous
Expand Down
8 changes: 7 additions & 1 deletion Source/WebCore/platform/graphics/PlatformTimeRanges.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ class PrintStream;

namespace WebCore {

enum class AddTimeRangeOption : uint8_t {
None,
EliminateSmallGaps,
};

class WEBCORE_EXPORT PlatformTimeRanges final {
WTF_MAKE_FAST_ALLOCATED;
public:
Expand All @@ -45,6 +50,7 @@ class WEBCORE_EXPORT PlatformTimeRanges final {
PlatformTimeRanges copyWithEpsilon(const MediaTime&) const;

static const PlatformTimeRanges& emptyRanges();
static MediaTime timeFudgeFactor();

MediaTime start(unsigned index) const;
MediaTime start(unsigned index, bool& valid) const;
Expand All @@ -62,7 +68,7 @@ class WEBCORE_EXPORT PlatformTimeRanges final {

unsigned length() const { return m_ranges.size(); }

void add(const MediaTime& start, const MediaTime& end);
void add(const MediaTime& start, const MediaTime& end, AddTimeRangeOption = AddTimeRangeOption::None);
void clear();

bool contain(const MediaTime&) const;
Expand Down
12 changes: 1 addition & 11 deletions Source/WebCore/platform/graphics/SourceBufferPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1218,18 +1218,8 @@ void SourceBufferPrivate::processMediaSample(Ref<MediaSample>&& sample)
resetTimestampOffsetInTrackBuffers();
}

// Eliminate small gaps between buffered ranges by coalescing
// disjoint ranges separated by less than a "fudge factor".
auto presentationEndTime = presentationTimestamp + frameDuration;
auto nearestToPresentationStartTime = trackBuffer.buffered().nearest(presentationTimestamp);
if (nearestToPresentationStartTime.isValid() && (presentationTimestamp - nearestToPresentationStartTime).isBetween(MediaTime::zeroTime(), timeFudgeFactor()))
presentationTimestamp = nearestToPresentationStartTime;

auto nearestToPresentationEndTime = trackBuffer.buffered().nearest(presentationEndTime);
if (nearestToPresentationEndTime.isValid() && (nearestToPresentationEndTime - presentationEndTime).isBetween(MediaTime::zeroTime(), timeFudgeFactor()))
presentationEndTime = nearestToPresentationEndTime;

trackBuffer.addBufferedRange(presentationTimestamp, presentationEndTime);
trackBuffer.addBufferedRange(presentationTimestamp, presentationEndTime, AddTimeRangeOption::EliminateSmallGaps);
m_client->sourceBufferPrivateDidParseSample(frameDuration.toDouble());

break;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/platform/graphics/SourceBufferPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class SourceBufferPrivate

virtual void appendInternal(Ref<SharedBuffer>&&) = 0;
virtual void resetParserStateInternal() = 0;
virtual MediaTime timeFudgeFactor() const { return { 2002, 24000 }; }
virtual MediaTime timeFudgeFactor() const { return PlatformTimeRanges::timeFudgeFactor(); }
virtual bool isActive() const { return false; }
virtual bool isSeeking() const { return false; }
virtual MediaTime currentMediaTime() const { return { }; }
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/platform/graphics/TrackBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ MediaTime TrackBuffer::maximumBufferedTime() const
return m_buffered.maximumBufferedTime();
}

void TrackBuffer::addBufferedRange(const MediaTime& start, const MediaTime& end)
void TrackBuffer::addBufferedRange(const MediaTime& start, const MediaTime& end, AddTimeRangeOption addTimeRangeOption)
{
m_buffered.add(start, end);
m_buffered.add(start, end, addTimeRangeOption);
}

void TrackBuffer::addSample(MediaSample& sample)
Expand Down Expand Up @@ -198,7 +198,7 @@ PlatformTimeRanges TrackBuffer::removeSamples(const DecodeOrderSampleMap::MapTyp

auto startTime = sample->presentationTime();
auto endTime = startTime + sample->duration();
erasedRanges.add(startTime, endTime);
erasedRanges.add(startTime, endTime, AddTimeRangeOption::EliminateSmallGaps);

#if !RELEASE_LOG_DISABLED
bytesRemoved += startBufferSize - m_samples.sizeInBytes();
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/platform/graphics/TrackBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class TrackBuffer final
static UniqueRef<TrackBuffer> create(RefPtr<MediaDescription>&&, const MediaTime&);

MediaTime maximumBufferedTime() const;
void addBufferedRange(const MediaTime& start, const MediaTime& end);
void addBufferedRange(const MediaTime& start, const MediaTime& end, AddTimeRangeOption = AddTimeRangeOption::None);
void addSample(MediaSample&);

bool updateMinimumUpcomingPresentationTime();
Expand Down
29 changes: 29 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebCore/TimeRanges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,5 +287,34 @@ TEST(TimeRanges, IntersectWith_Gaps3)
ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);
}

TEST(TimeRanges, Add_SmallGaps)
{
RefPtr<TimeRanges> ranges = TimeRanges::create();

const MediaTime duration { MediaTime::createWithDouble(1.0) };
const double smallGap { 0.001 };
const unsigned numberOfSamples { 10 };

for (unsigned i = 0; i < numberOfSamples; ++i) {
const double start = duration.toDouble() * i;
const double end = start + duration.toDouble() - smallGap;

ranges->add(start, end, AddTimeRangeOption::None);
}

EXPECT_EQ(numberOfSamples, ranges->length());

ranges = TimeRanges::create();

for (unsigned i = 0; i < numberOfSamples; ++i) {
const double start = duration.toDouble() * i;
const double end = start + duration.toDouble() - smallGap;

ranges->add(start, end, AddTimeRangeOption::EliminateSmallGaps);
}

EXPECT_EQ(1u, ranges->length());
}

}

0 comments on commit c3bf8dd

Please sign in to comment.