Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some issues that may arise on BUFFER_FULL situations #1546

Merged
merged 1 commit into from
Sep 19, 2024

Conversation

peaBerberian
Copy link
Collaborator

I'm working on heuristics to determine adaptively how much the current device can hold in its audio and video buffers.

To quickly iterate on this, I'm setting a very high (or even Infinity) wantedBufferAhead to quickly fill-up memory until the device has to perform a strategy to free it.

While doing this, I saw a collection of issues:

  1. When calling the MSE SourceBuffer.prototype.remove API to remove buffer (which we already do in some clean-up strategies), putting an end timestamp equal to the start timestamp leads to an Error (as defined by MSE).

    A long-term fix would be to just avoid doing the MSE remove call as close as possible to our MSE abstraction, but for now I also added a check at the initial call (which also makes sense).

    I'm thinking of also adding the long-term fix, but not in this PR as I want it to have the less risks possible.

  2. When a QuotaExceededError is received after a push, we internally trigger a BUFFER_FULL_ERROR error, which is then handled by waiting a little, then reducing the wantedBufferAhead value progressively through a ratio system and retrying.

    If after either the wantedBufferAhead is too low (less than 2 seconds) or the ratio is too low (less or equal to 0.05), we trigger the error through the API and stop the content.

    Turns out that last part was broken. We never triggered the error, leading to possibilities such as infinite rebuffering (in extreme cases hopefully never really encountered).

  3. The logic in (2) never considered that wantedBufferAhead could be set to Infinity, and dividing Infinity is not a very bright idea here. To make it work I decided that when there's a ratio set to less than 1, a wantedBufferAhead set to Infinity would be equal to 5 minutes.

@peaBerberian peaBerberian added bug This is an RxPlayer issue (unexpected result when comparing to the API) Priority: 0 (Very high) This issue or PR has a very high priority. Efforts should be concentrated on it first. labels Sep 17, 2024
@peaBerberian peaBerberian added this to the 4.2.0 milestone Sep 17, 2024
const oldBufferGoalRatio = bufferGoalRatioMap.get(representation.id);
const bufferGoalRatio = oldBufferGoalRatio !== undefined ? oldBufferGoalRatio : 1;
if (oldBufferGoalRatio === undefined) {
bufferGoalRatioMap.set(representation.id, bufferGoalRatio);
}
return bufferGoalRatio;
if (bufferGoalRatio < 1 && wba === Infinity) {
return 5 * 60 * 1000 * bufferGoalRatio;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can add a comment to say that 5 minutes is the default for calculation in case wanted buffer head is infinite

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

I'm working on heuristics to determine adaptively how much the current
device can hold in its audio and video buffers.

To quickly iterate on this, I'm setting a very high (or even `Infinity`)
`wantedBufferAhead` to quickly fill-up memory until the device has to
perform a strategy to free it.

While doing this, I saw a collection of issues:

  1. When calling the MSE `SourceBuffer.prototype.remove` API to remove
     buffer (which we already do in some clean-up strategies), putting
     an end timestamp equal to the start timestamp leads to an Error (as
     defined by MSE).

     A long-term fix would be to just avoid doing the MSE `remove` call
     as close as possible to our MSE abstraction, but for now I also
     added a check at the initial call (which also makes sense).

     I'm thinking of also adding the long-term fix, but not in this PR
     as I want it to have the less risks possible.

  2. When a `QuotaExceededError` is received after a push, we trigger a
     `BUFFER_FULL_ERROR` error, which is then handled by, waiting a
     little, then reducing the `wantedBufferAhead` value progressively
     through a ratio and retrying.

     If after either the `wantedBufferAhead` is too low (less than 2
     seconds) or the ratio is too low (less or equal to 0.05), we
     trigger the error through the API.

     Turns out that last part was broken. We never triggered the error,
     leading to possibilities such as infinite rebuffering (in extreme
     cases hopefully never really encountered).

  3. The logic in (2) never considered that `wantedBufferAhead` could be
     set to `Infinity`, and dividing `Infinity` is not a very bright
     idea here. To make it work I decided that when there's a ratio set
     to less than `1`, a `wantedBufferAhead` set to `Infinity` would be
     equal to 5 minutes.
@peaBerberian peaBerberian force-pushed the fix/check-source-buffer-remove-arguments branch from f3b0994 to fd26e84 Compare September 18, 2024 15:55
@peaBerberian peaBerberian merged commit 10f6b4e into dev Sep 19, 2024
8 checks passed
peaBerberian added a commit that referenced this pull request Oct 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This is an RxPlayer issue (unexpected result when comparing to the API) Priority: 0 (Very high) This issue or PR has a very high priority. Efforts should be concentrated on it first.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants