Skip to content

Instantly share code, notes, and snippets.

@gesinger
Last active September 10, 2022 19:01
Show Gist options
  • Save gesinger/8aa3608278b3c398fe8dc5facf57eb3e to your computer and use it in GitHub Desktop.
Save gesinger/8aa3608278b3c398fe8dc5facf57eb3e to your computer and use it in GitHub Desktop.
VHS ABR (as of September 2022)

Goals (priority order)

1. Least disturbance

current: rebuffering
future: rebuffering + dropped frames

2. Highest quality

current: bitrate + resolution
future: bitrate + resolution + framerate + quality score + codec

3. Least wasted bandwidth

avoid exceeding width and height of player

ABR algorithms

Algorithm systemBandwidth Value Low Water Line High Water Line When is it run?
default most recent 0-30s (dynamic) N/A bandwidthupdate events2
experimentalBufferBasedABR moving average1 0-16s (dynamic) 30s timer (250ms)3

1 decay of 0.55: average = 0.55 * systemBandwidth + (1 - 0.55) * average

2 bandwidthupdate events occur on the following

  • XHR progress events (~250ms)
  • XHR timeout
  • source buffer updateend events

3 decay does not run on the timer

Further comparing the algorithms

Similarities

  • Dynamic GOAL_BUFFER_LENGTH of 30-60s: buffer occupancy at which to stop buffering
  • Use of simpleSelector
  • Use of Config.BUFFER_LOW_WATER_LINE: buffer occupancy before allowing upswitches
  • Use of shouldSwitchToMedia
    • if live: don't consider low water line
    • if LL-HLS: don't switch before playback starts
  • MIN_SEGMENT_DURATION_TO_SAVE_STATS = 1 / 60

Differences

  • Config.BUFFER_LOW_WATER_LINE values
  • experimentalBufferBasedABR uses Config.BUFFER_HIGH_WATER_LINE: buffer occupancy before disallowing downswitches
  • experimentalBufferBasedABR uses a moving average instead of most recent value
  • default uses earlyAbortWhenNeeded on XHR progress events

How is systemBandwidth calculated?

bandwidth

  • uses NetworkInformation.downlink (max 10 Mbps) if available
  • otherwise (or if over 10 Mbps) uses XHR bits / time taken
  • timeout means bandwidth goes to 1

throughput

  • decryption + transmuxing + appending
  • cumulative moving average: new = old + (sample - old) / (sample count + 1)

systemBandwidth = 1 / (1 / bandwidth + 1 / throughput)

Playlist selectors

In the future

  • dropped frames
  • segment size
  • quality score (e.g., VMAF)
  • codec comparison
  • framerates
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment