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: sustained bad network shouldn't pause #966

Closed
wants to merge 5 commits into from
Closed

Conversation

gkatsev
Copy link
Member

@gkatsev gkatsev commented Oct 1, 2020

When playing back bipbop with experimentalBufferBasedABR turned on and
we switch to Slow 3G in chrome, we may time out.
This is because

  • earlyabort is turned off
  • our last attempt at downswitching occurs when our forward buffer is
    too full

To mitigate this, when we get an early abort set up a timer for 10
seconds to see if earlyabort conditions are met again. If a progress
event happens in the meantime, the earlyabort timer will be cancelled.

TODO:

  • Make sure that the setTimeout is cancelled properly if the player is disposed (not sure if we have a player.setTimeout() like method
  • figure out if there's a better way of doing this

@@ -556,6 +556,10 @@ export class MasterPlaylistController extends videojs.EventTarget {
});

this.mainSegmentLoader_.on('progress', () => {
if (this.mainSegmentLoader_.earlyabortTimer) {
window.clearTimeout(this.mainSegmentLoader_.earlyabortTimer);
Copy link
Contributor

Choose a reason for hiding this comment

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

We have to clear this on dispose as well

@@ -615,6 +619,9 @@ export class MasterPlaylistController extends videojs.EventTarget {
// if we shouldn't switch to the next playlist, do nothing
if (!this.shouldSwitchToMedia_(nextPlaylist)) {
this.logger_(`earlyabort triggered, but we will not be switching from ${currentPlaylist.id} -> ${nextPlaylist.id}.`);
this.mainSegmentLoader_.earlyabortTimer = window.setTimeout(() => {
this.mainSegmentLoader_.trigger('earlyabort');
}, 10 * 1000);
Copy link
Contributor

Choose a reason for hiding this comment

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

10s might be too long, what do you think about 5s?

Copy link
Member Author

Choose a reason for hiding this comment

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

Probably should be target duration dependent or something, maybe even forward buffer? Made it 10s just for starters.

@@ -615,6 +619,9 @@ export class MasterPlaylistController extends videojs.EventTarget {
// if we shouldn't switch to the next playlist, do nothing
if (!this.shouldSwitchToMedia_(nextPlaylist)) {
this.logger_(`earlyabort triggered, but we will not be switching from ${currentPlaylist.id} -> ${nextPlaylist.id}.`);
this.mainSegmentLoader_.earlyabortTimer = window.setTimeout(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should clear this timer every time we come into this function right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I have that as part of the TODOs. I wasn't sure whether we had a player.setTimeout method available here or whether I needed to make sure that the timer is handled fully as appropriate.
The variable should be renamed to include a _ as well.

When playing back bipbop with experimentalBufferBasedABR turned on and
we switch to Slow 3G in chrome, we may time out.
This is because
- earlyabort is turned off
- our last attempt at downswitching occurs when our forward buffer is
too full

To mitigate this, when we get an early abort set up a timer for 10
seconds to see if earlyabort conditions are met again. If a progress
event happens in the meantime, the earlyabort timer will be cancelled.
This is because progress gets triggered after the check for earlyabort
and so our timer will always get triggered *immediately*.
@gkatsev
Copy link
Member Author

gkatsev commented Oct 15, 2020

I keep finding various edge cases here. I think we need to implement the proper timer based solution for rendition switches.

@gkatsev gkatsev closed this Oct 15, 2020
gkatsev added a commit that referenced this pull request Oct 30, 2020
… on an interval (#978)

This is a followup to #886. There, I noticed that if we get sustained bad network we will time out because we will an opportunity for earlyabort. At first, I tried working around by delaying earlyabort in that case (#966) but as I was getting that ready I kept finding edge cases that we needed to account for. Specifically, the issue is that we only run our ABR algorithm on progress and bandwidthchange events from the segment loader. This means that if the download stalls, we stop run our algorithm and will eventually stall playback. Instead, we should remove earlyabort altogether (f897dde) and set up an interval (currently 250ms) to re-run our ABR algorithm. This means that if the network becomes bad for a sustained period, we will drop down once the buffer allows us but if the network recovers, we will switch up appropriately as well.

Also, the interval is stopped while we're paused.

Fixes #964.
@gkatsev gkatsev deleted the fix-slow-3g branch May 17, 2021 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants