-
Notifications
You must be signed in to change notification settings - Fork 795
Keep track of approximate total bytes in SourceBuffer / Prevent quota exceeded with 4K streams #1242
Keep track of approximate total bytes in SourceBuffer / Prevent quota exceeded with 4K streams #1242
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @tchakabam , sorry this has gone a while without any review. We definitely need to handle this case, and thank you for submitting the PR!
The main thing I wanted to hear your thoughts on is making use of the segment metadata track (and adding byte info to that) to calculate buffer occupancy on demand instead of maintaining more state in the source updater.
Thanks again!
// we can reach a QuotaExceeded error easily within just 60 seconds | ||
// of buffer. Therefore we need to actively check the exact number | ||
// of bytes occupied in the buffer. | ||
// If we reach the limit, we are triming pre-emptively, enqueuing this action |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are triming pre-emptively, enqueueing
=> we trim preemptively, and enqueue
// and drive the loading / triming actively | ||
// to make sure we do not reach this limit. | ||
if (bufferedBytes >= Config.MAX_SOURCE_BUFFER_OCCUPATION_BYTES) { | ||
// If we reached the limit let's trim the buffer already |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we...jamming situation
I think we can remove, since the comment above states the intention well
// of jamming situation. | ||
// We keep some back-buffer but reduce the allowed size significantly | ||
// compared to the initial configuration. | ||
this.logger_('SourceBuffer occupation exceeds limit, triming back-buffer and deferring further loading'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trimming
// We keep some back-buffer but reduce the allowed size significantly | ||
// compared to the initial configuration. | ||
this.logger_('SourceBuffer occupation exceeds limit, triming back-buffer and deferring further loading'); | ||
this.trimBackBuffer_(Config.BACK_BUFFER_LENGTH / 3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any specific reason for the / 3
? Maybe we can calculate how much buffer we need to trim judging by segment starts/ends and their respective sizes?
// on the source buffer during subsequent appends | ||
// | ||
// We also monitor the bytes in buffer (see checkBuffer_()) | ||
// and drive the loading / triming actively |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trimming
@@ -859,7 +885,18 @@ export default class SegmentLoader extends videojs.EventTarget { | |||
loadSegment_(segmentInfo) { | |||
this.state = 'WAITING'; | |||
this.pendingSegment_ = segmentInfo; | |||
this.trimBackBuffer_(segmentInfo); | |||
|
|||
// Chrome has a hard limit of 150MB of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not too big of a deal, but I think this comment still makes sense to be in the trimBackBuffer
function, since that is where the logic of how much to clear happens. loadSegment
just needs to know to call trimBackBuffer
if (typeof segment.start === 'number' && typeof segment.end === 'number') { | ||
this.mediaSecondsLoaded += segment.end - segment.start; | ||
this.mediaSecondsLoaded += segmentDuration = segment.end - segment.start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, but is a bit hard to read. Maybe the conditionals just set the value of segmentDuration
(or a ternary is used), then this.mediaSecondsLoaded += segmentDuration
exists after?
if (mediaSource.readyState === 'closed') { | ||
mediaSource.addEventListener('sourceopen', createSourceBuffer); | ||
} else { | ||
createSourceBuffer(); | ||
} | ||
} | ||
|
||
appendToBufferInfoQueue_(timestampOffset, duration, byteLength) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of putting all of the buffer info in SourceUpdater
and keeping track of it, maybe it makes sense for us to add byte info to the segment metadata track https://github.com/videojs/videojs-contrib-hls#segment-metadata and we can make use of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, the PR to include the required information in the segment metadata is #1210.
Hey, thanks for the review! And yes @squarebracket is right, if we combine both contributions, no need anymore for the rough estimation with the I hope I can progress on both of these this week! Thanks for the patience ;) |
Hey @tchakabam! We've been talking in the slack channel about how to handle That solution would require some additional functionality to what you've got here, and a new PR to contrib-media-sources, since there's a Would that be something you're up for? I can walk you through the details if you're interested. No pressure if not; I can code up the PRs and credit you with the basis for the solution :) Thanks again for taking the time to contribute and moving us forwards on a fix. |
@squarebracket Hey, thanks for the update on this. These days I've got quite some new things on my plate, and unfortunately wont get to work on this one here anytime soon. So please go on with that proposed solution :) Sounds very good to me 👍 Adapting the buffer limit dynamically is definitely favorable, and even more favoreable to leverage the contrib-media-sources layer to handle this stuff, as it will be a common concern for any user of the API :) Feel free to continue or close this here as you see fit! |
Sounds good :) thanks again for the initial PR. I'll close this one once I've got a new one open. |
Hi :) |
I know it's been a while, but any progress on this? Running into the exact same issue! I tried implementing the fix but I'm still running into an issue. Running this on some SmartTvs. The error is thrown on some, but not all. Question, if I wanted to reduce the size even more, which values should I change in the code? Thank you! |
Yes, actually! My apologies, I forgot to comment in this ticket. These features are now being tracked in #1416. It would certainly be a big help to me if everyone interested in these features could go build the project with those changes and test it out with their sources / devices. Closing this PR in favour of #1416. |
Description
Specific Changes proposed
totalBytesInBuffer
toSourceBuffer
SourceBuffer
interface to passduration
SegmentLoader
when limit is exceededConfig
moduletrimBackBuffer_
improvementsRequirements Checklist