WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
135614
[MSE] Implement a maximum buffer size for SourceBuffer
https://bugs.webkit.org/show_bug.cgi?id=135614
Summary
[MSE] Implement a maximum buffer size for SourceBuffer
Jer Noble
Reported
2014-08-05 10:57:13 PDT
[MSE] Implement a maximum buffer size for SourceBuffer
Attachments
WIP
(7.59 KB, patch)
2014-08-05 10:59 PDT
,
Jer Noble
no flags
Details
Formatted Diff
Diff
Updated WIP
(26.74 KB, patch)
2014-08-08 12:19 PDT
,
Eric Carlson
jer.noble
: review+
Details
Formatted Diff
Diff
Updated patch.
(36.87 KB, patch)
2014-08-14 17:22 PDT
,
Eric Carlson
no flags
Details
Formatted Diff
Diff
Patch for landing.
(39.75 KB, patch)
2014-08-15 14:31 PDT
,
Eric Carlson
no flags
Details
Formatted Diff
Diff
Rebased patch for landing.
(38.88 KB, patch)
2014-08-15 14:50 PDT
,
Eric Carlson
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Jer Noble
Comment 1
2014-08-05 10:59:00 PDT
Created
attachment 236035
[details]
WIP
Eric Carlson
Comment 2
2014-08-08 12:19:59 PDT
Created
attachment 236295
[details]
Updated WIP
WebKit Commit Bot
Comment 3
2014-08-12 12:32:48 PDT
Attachment 236295
[details]
did not pass style-queue: ERROR: Source/WebCore/html/HTMLMediaSession.cpp:305: One space before end of line comments [whitespace/comments] [5] ERROR: Source/WebCore/html/HTMLMediaSession.cpp:306: One space before end of line comments [whitespace/comments] [5] Total errors found: 2 in 10 files If any of these errors are false positives, please file a bug against check-webkit-style.
Eric Carlson
Comment 4
2014-08-12 12:35:33 PDT
Comment on
attachment 236295
[details]
Updated WIP This doesn't have any tests yet, but we need to make significant changes to the mock MSE implementation and JS library so I have filed
https://bugs.webkit.org/show_bug.cgi?id=135847
for adding tests.
Eric Carlson
Comment 5
2014-08-12 12:36:37 PDT
<
rdar://problem/17896828
>
Jer Noble
Comment 6
2014-08-13 09:57:51 PDT
Comment on
attachment 236295
[details]
Updated WIP View in context:
https://bugs.webkit.org/attachment.cgi?id=236295&action=review
r=me, with a couple nits:
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:663 > + m_bufferFull = extraMemoryCost() + newDataSize > maximumBufferSize;
This is technically against the spec. The buffer full flag should be modified in step 6.4 of the segment parser loop algorithm, which would best fit in sourceBufferPrivateAppendComplete().
> Source/WebCore/html/HTMLMediaSession.cpp:333 > +size_t HTMLMediaSession::maximumMediaSourceBufferSize(const HTMLMediaElement& element) const > +{ > + // A good quality 1080p video uses 8,000 kbps and stereo audio uses 384 kbps, so assume 95% for video and 5% for audio. > + const float bufferBudgetPercentageForVideo = .95; > + const float bufferBudgetPercentageForAudio = .05; > + > + size_t maximum; > + Settings* settings = element.document().settings(); > + if (settings) > + maximum = settings->maximumSourceBufferSize(); > + else > + maximum = fiveMinutesOf1080PVideo + fiveMinutesStereoAudio; > + > + // Allow an element to buffer as though it as audio-only even if it doesn't have any active tracks. > + size_t bufferSize = static_cast<size_t>(maximum * bufferBudgetPercentageForAudio); > + if (element.hasVideo()) > + bufferSize += static_cast<size_t>(maximum * bufferBudgetPercentageForVideo); > + > + // FIXME: we might want to modify this algorithm to: > + // - decrease the maximum size for background tabs > + // - decrease the maximum size allowed for inactive elements when a process has more than one > + // element, eg. so a page with many elements which are played one at a time doesn't keep all > + // everything buffered after an element has been played. > + > + return bufferSize; > +}
So this code will give the same buffer to a SourceBuffer with a single audio track and a SourceBuffer with a single video track, if both those buffers are attached to the same HTMLMediaElement. I think we should add to the list of FIXMEs that the budget should be based on what tracks each SourceBuffer contains, rather than the HTMLMediaElement as a whole.
Eric Carlson
Comment 7
2014-08-14 17:20:53 PDT
(In reply to
comment #6
)
> (From update of
attachment 236295
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=236295&action=review
> > r=me, with a couple nits: > > > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:663 > > + m_bufferFull = extraMemoryCost() + newDataSize > maximumBufferSize; > > This is technically against the spec. The buffer full flag should be modified in step 6.4 of the segment parser loop algorithm, which would best fit in sourceBufferPrivateAppendComplete(). >
Fixed, we only ever set m_bufferFull to true in sourceBufferPrivateAppendComplete.
> > Source/WebCore/html/HTMLMediaSession.cpp:333 > > +size_t HTMLMediaSession::maximumMediaSourceBufferSize(const HTMLMediaElement& element) const > > +{ > > + // A good quality 1080p video uses 8,000 kbps and stereo audio uses 384 kbps, so assume 95% for video and 5% for audio. > > + const float bufferBudgetPercentageForVideo = .95; > > + const float bufferBudgetPercentageForAudio = .05; > > + > > + size_t maximum; > > + Settings* settings = element.document().settings(); > > + if (settings) > > + maximum = settings->maximumSourceBufferSize(); > > + else > > + maximum = fiveMinutesOf1080PVideo + fiveMinutesStereoAudio; > > + > > + // Allow an element to buffer as though it as audio-only even if it doesn't have any active tracks. > > + size_t bufferSize = static_cast<size_t>(maximum * bufferBudgetPercentageForAudio); > > + if (element.hasVideo()) > > + bufferSize += static_cast<size_t>(maximum * bufferBudgetPercentageForVideo); > > + > > + // FIXME: we might want to modify this algorithm to: > > + // - decrease the maximum size for background tabs > > + // - decrease the maximum size allowed for inactive elements when a process has more than one > > + // element, eg. so a page with many elements which are played one at a time doesn't keep all > > + // everything buffered after an element has been played. > > + > > + return bufferSize; > > +} > > So this code will give the same buffer to a SourceBuffer with a single audio track and a SourceBuffer with a single video track, if both those buffers are attached to the same HTMLMediaElement. I think we should add to the list of FIXMEs that the budget should be based on what tracks each SourceBuffer contains, rather than the HTMLMediaElement as a whole.
Good point! I fixed this by having this method take a SourceBuffer and adding hasAudio and hasVideo to SourceBuffer.
Eric Carlson
Comment 8
2014-08-14 17:22:22 PDT
Created
attachment 236639
[details]
Updated patch.
Jer Noble
Comment 9
2014-08-15 11:39:10 PDT
Comment on
attachment 236639
[details]
Updated patch. View in context:
https://bugs.webkit.org/attachment.cgi?id=236639&action=review
r=me, with nits:
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:92 > +#if !LOG_DISABLED > +static void logRanges(const String& prefix, const TimeRanges* ranges) > +{ > + > + if (!ranges->length()) > + return; > + > + StringBuilder log; > + > + log.append(prefix); > + for (size_t i = 0; i < ranges->length(); ++i) > + log.append(String::format("[%lf .. %lf] ", ranges->start(i, ASSERT_NO_EXCEPTION), ranges->end(i, ASSERT_NO_EXCEPTION))); > + > + LOG(MediaSource, "%s", log.toString().utf8().data()); > +} > + > +#define LOG_RANGES(prefix, ranges) logRanges(prefix, ranges) > +#else > +#define LOG_RANGES(prefix, ranges) ((void)0) > +#endif
It would be better here to add a "void dump(PrintStream& out) const" member variable to PlatformTimeRanges which does this. We have an existing one for MediaTime which you could use as an example.
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:756 > +#if !LOG_DISABLED > + LOG(MediaSource, "SourceBuffer::evictCodedFrames(%p) - evicted %zu bytes", this, initialBufferedSize - extraMemoryCost()); > +#endif
This doesn't need a #if guard.
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:763 > + size_t currentTimeRange = m_buffered->find(m_source->currentTime());
TimeRanges methods take doubles, but PlatformTimeRanges methods take MediaTimes. You could re-use the existing "currentMediaTime" by doing a "m_buffered->ranges().find(currentMediaTime)" here, or by caching the result of m_buffered->ranges() in a local to use later.
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:767 > +#if !LOG_DISABLED > + LOG(MediaSource, "SourceBuffer::evictCodedFrames(%p) - evicted %zu bytes but FAILED to free enough", this, initialBufferedSize - extraMemoryCost()); > +#endif
No #if guard necessary.
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:778 > + size_t startTimeRange = m_buffered->find(rangeStart.toDouble());
Ditto here about PlatformTimeRanges. This becomes "m_buffered->ranges().find(rangeStart)", or "bufferedRanges.find(rangeStart)" if you use a local variable.
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:780 > + size_t endTimeRange = m_buffered->find(rangeEnd.toDouble());
Ditto.
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:784 > + rangeEnd = MediaTime::createWithDouble(m_buffered->start(endTimeRange, ASSERT_NO_EXCEPTION));
ditto.
> Source/WebCore/Modules/mediasource/SourceBuffer.cpp:801 > +#if !LOG_DISABLED > + LOG(MediaSource, "SourceBuffer::evictCodedFrames(%p) - evicted %zu bytes%s", this, initialBufferedSize - extraMemoryCost(), m_bufferFull ? "" : " but FAILED to free enough"); > +#endif
Ditto.
Eric Carlson
Comment 10
2014-08-15 14:31:37 PDT
Created
attachment 236676
[details]
Patch for landing.
Eric Carlson
Comment 11
2014-08-15 14:33:21 PDT
(In reply to
comment #9
)
> (From update of
attachment 236639
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=236639&action=review
> > It would be better here to add a "void dump(PrintStream& out) const" member variable to PlatformTimeRanges which does this. We have an existing one for MediaTime which you could use as an example. >
Fixed.
> > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:756 > > +#if !LOG_DISABLED > > + LOG(MediaSource, "SourceBuffer::evictCodedFrames(%p) - evicted %zu bytes", this, initialBufferedSize - extraMemoryCost()); > > +#endif > > This doesn't need a #if guard. >
Ditto.
> > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:763 > > + size_t currentTimeRange = m_buffered->find(m_source->currentTime()); > > TimeRanges methods take doubles, but PlatformTimeRanges methods take MediaTimes. You could re-use the existing "currentMediaTime" by doing a "m_buffered->ranges().find(currentMediaTime)" here, or by caching the result of m_buffered->ranges() in a local to use later. >
Ditto.
> > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:767 > > +#if !LOG_DISABLED > > + LOG(MediaSource, "SourceBuffer::evictCodedFrames(%p) - evicted %zu bytes but FAILED to free enough", this, initialBufferedSize - extraMemoryCost()); > > +#endif > > No #if guard necessary. >
Ditto.
> > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:778 > > + size_t startTimeRange = m_buffered->find(rangeStart.toDouble()); > > Ditto here about PlatformTimeRanges. This becomes "m_buffered->ranges().find(rangeStart)", or "bufferedRanges.find(rangeStart)" if you use a local variable. >
Ditto.
> > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:780 > > + size_t endTimeRange = m_buffered->find(rangeEnd.toDouble()); > > Ditto. >
Ditto.
> > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:784 > > + rangeEnd = MediaTime::createWithDouble(m_buffered->start(endTimeRange, ASSERT_NO_EXCEPTION)); > > ditto. >
Ditto.
> > Source/WebCore/Modules/mediasource/SourceBuffer.cpp:801 > > +#if !LOG_DISABLED > > + LOG(MediaSource, "SourceBuffer::evictCodedFrames(%p) - evicted %zu bytes%s", this, initialBufferedSize - extraMemoryCost(), m_bufferFull ? "" : " but FAILED to free enough"); > > +#endif > > Ditto.
Ditto.
Eric Carlson
Comment 12
2014-08-15 14:50:19 PDT
Created
attachment 236677
[details]
Rebased patch for landing.
WebKit Commit Bot
Comment 13
2014-08-15 14:52:55 PDT
Attachment 236677
[details]
did not pass style-queue: ERROR: Source/WebCore/platform/graphics/PlatformTimeRanges.h:36: Code inside a namespace should not be indented. [whitespace/indent] [4] ERROR: Source/WebCore/platform/graphics/PlatformTimeRanges.cpp:29: Alphabetical sorting problem. [build/include_order] [4] ERROR: Source/WebCore/Modules/mediasource/SourceBuffer.cpp:610: One line control clauses should not use braces. [whitespace/braces] [4] Total errors found: 3 in 16 files If any of these errors are false positives, please file a bug against check-webkit-style.
Eric Carlson
Comment 14
2014-08-15 16:10:59 PDT
Committed
r172657
:
https://trac.webkit.org/r172657
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug