Skip to content
This repository has been archived by the owner on Jan 12, 2019. It is now read-only.

Fixed mediaIndex tracking so that it is consistent when the playlist updates during a live stream #977

Merged
merged 4 commits into from
Jan 25, 2017

Conversation

imbcmdth
Copy link
Member

@imbcmdth imbcmdth commented Jan 24, 2017

What

During low-bandwidth conditions, segment requests can take long enough that the playlist reloads while we are fetching segments. This confused our handling of mediaIndex forcing the player to load the same segment that it loaded previously.

If network conditions are bad enough (and we are on the lowest rendition) then we can get into a situation where we refresh the playlist during each segment's request. The end result is that we will fetch the same segment over and over again without making progress. In extreme cases (when two playlist loads happened while fetching a segment) we can actually go backwards!!

Why

There was code in SegmentLoader#handleUpdateEnd_ that would adjust segmentInfo.mediaIndex before setting this.mediaIndex. The change was based on the difference between the saved playlist object and the current playlist's mediaSequence.

This action by handleUpdateEnd_ was ONLY required when this.mediaIndex was null but we didn't have a check. When this.mediaIndex was not null, SegmentLoader#playlist was responsible for adjusting mediaIndex.

For this PR, I decided to remove the code in handleUpdateEnd_ and move all the responsibility of tracking mediaIndex to one place - SegmentLoader#playlist.

Changes

  1. Removed any code in SegmentLoader#handleUpdateEnd_ that modified the mediaIndex
  2. Reordered SegmentLoader#playlist to make it easier to follow and less deeply nested
  3. All changes to both mediaIndex-es (SegmentLoader's and segmentInfo's) now happen solely in SegmentLoader#playlist

…updates during a live stream

* Removed any code in SegmentLoader#handleUpdateEnd_ that changed the mediaIndex
* Reordered SegmentLoader#playlist to make it easier to follow
* All changes to both mediaIndexes (SegmentLoader's and segmentInfo's) now happen in SegmentLoader#playlist
// this is important because we can abort a request and this value must be
// equal to the last appended mediaIndex
if (this.mediaIndex !== null) {
this.mediaIndex -= mediaSequenceDiff;
Copy link
Contributor

Choose a reason for hiding this comment

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

In the case where this results in a mediaIndex < -1 (we fell two slots behind the end of the playlist), do we want to handle the case in any way (since we knowingly fell off the back), or let playback watcher catch that we fell off the back in its own time (or another resolution, e.g., we keep the index at -1 and hope it'll create a 1 segment gap that will be skipped over by the gap skipper)?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it is ok to let playback watcher handle this scenario instead of introducing complexity here. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, it's probably fine to do that. The behavior at least will be the same as current.

But it may be an interesting idea for the future. Since we're in a place where we knowingly will fall back to playback-watcher, and the user will experience a pause in playback, maybe we should at least add a comment or TODO to consider taking action.

}
} else if (!this.hasPlayed_()) {
// when we haven't started playing yet, the start of the playlist is always
// our zero-time so force a sync update each time we get a new playlist
Copy link
Contributor

Choose a reason for hiding this comment

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

"each time we get a new playlist" may be a bit confusing in this context

@mjneil
Copy link
Contributor

mjneil commented Jan 25, 2017

It would be nice to have a unit test that emulates the scenario that caused the issue.

});

QUnit.test('segmentInfo.mediaIndex is adjusted when live playlist is updated', function(assert) {
currentTime = 31;
Copy link
Contributor

Choose a reason for hiding this comment

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

A short comment here explaining that you're setting currentTime to 31 so the loader selects segment 3.ts would be helpful. It took me a while to figure out why segmentInfo.mediaIndex starts at 3 down below when loader.mediaIndex = null was being set

@mjneil
Copy link
Contributor

mjneil commented Jan 25, 2017

LGTM

@mjneil mjneil merged commit 5113058 into master Jan 25, 2017
@mjneil mjneil deleted the improve-media-index-tracking branch January 25, 2017 23:57
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants