VideoBB
Upload Premium Sign in

Adaptive bitrate streaming, explained

A player that changes quality mid-stream is making a prediction every few seconds. How the rendition ladder is built, how the player chooses a rung, and what makes the choice hard.

Adaptive bitrate streaming makes several versions of a video at different sizes and bitrates. Each version is cut into segments at the same points. For each segment, the player picks the version that fits its measured speed and buffer. Viewers get the best quality their connection can hold without stalling.

Abstract illustration of a staircase of glowing bars of increasing height with a small marker moving between the steps

A viewer on a train watches the picture soften as the carriage enters a cutting. It sharpens again on the far side, and the video never stops. That small miracle is adaptive bitrate streaming (ABR). It depends on two things done well. The first is a set of renditions made in advance, so there is something to switch to. The second is a player that decides when to switch without stalling or flickering between qualities.

This deep dive covers both halves. It starts with the encoding ladder. Then it moves to what the player measures and how it decides. It ends with what this means for anyone who uploads or embeds video. In short, the automatic quality setting is nearly always right, and a good source helps it most. The video streaming hub puts ABR in context next to HLS, CDNs and transcoding.

The ladder

An ABR ladder is a list of renditions of the same video, each at a lower resolution and bitrate than the last. Every rendition is cut into segments at exactly the same timestamps, with a keyframe at the start of each. So the player can play segment 12 from the 1080p rendition and segment 13 from the 480p one. The decoder will not notice. The HLS guide covers how the playlist describes the ladder; the transcoding guide covers how the aligned renditions are made.

The spacing of the rungs is a design choice. With too few, the player has nowhere to go when bandwidth drops a little. With too many, transcoding and storage costs climb for little visible gain. A common rule of thumb is that neighbouring rungs should differ in bitrate by about 1.5 to 2 times. Then each step down is a real saving and each step up a real gain. Apple publishes a reference H.264 ladder in its authoring specification. It starts at 416×234 and ends at 1920×1080, with bitrates rising from a few hundred kilobits per second to several megabits.

The VideoBB ladder

Resolutions are the renditions VideoBB produces; the bitrate column is a rule-of-thumb range for H.264 at each height rather than a fixed platform figure, since the transcoder adapts to content.

RenditionHeightTypical H.264 bitrateTypical use
144p144Under 200 kbpsVery poor mobile links; keeps audio and picture moving
240p240200-400 kbpsSlow mobile
360p360400-800 kbpsSmall screens, congested networks
480p4800.8-1.5 MbpsPhones on good mobile data
720p7201.5-3 MbpsLaptops and tablets
1080p10803-6 MbpsDesktop and TV on broadband
1440p (Premium)14406-12 MbpsLarge monitors
2160p (Premium)216012-25 Mbps4K televisions

What the player measures

The first input is throughput: how many bits arrived in how many seconds while the last segment downloaded. That is a noisy number. A single segment can arrive fast because it hit a warm cache. It can arrive slowly because a background download started. So players smooth the number, often with a weighted average that favours recent samples, and treat the estimate with suspicion.

The second input is the buffer: how many seconds of video are already downloaded and waiting to play. A full buffer is insurance. If it holds thirty seconds, a bad bandwidth guess costs nothing, because there is time to correct it. If it holds three, the same guess causes a stall. The most robust algorithms weight buffer occupancy heavily, and some, such as BOLA (used in dash.js and available in hls.js), are driven almost entirely by it.

Other inputs matter at the edges. The first is the size of the viewport: there is no point fetching 1080p into a 320-pixel-wide embed. Whether the tab is visible also counts. So do the device's decoding power and the CODECS strings in the playlist. Together they limit which rungs are even candidates.

The decision loop

Every player implements some version of this cycle for each segment.

  1. Estimate bandwidth

    Combine recent segment download rates into a conservative estimate, usually discounting it by a safety factor so that the chosen rendition leaves headroom.

  2. Check the buffer

    If the buffer is below a low-water mark, prefer a lower rung regardless of the estimate; if it is above a high-water mark, a higher rung is affordable even on a shaky estimate.

  3. Filter the candidates

    Remove rungs whose resolution exceeds the viewport by a large margin, whose codec the device cannot decode, or whose BANDWIDTH exceeds the discounted estimate.

  4. Apply hysteresis

    Require a clearer margin to step up than to step down, and limit how often switches happen. Then the picture does not flip between two rungs on a connection that hovers near a boundary.

  5. Fetch and re-measure

    Request the next segment from the chosen rendition, record how long it took, and start again.

Why this is harder than it sounds

Bandwidth is a property of the next few seconds, and the player only has evidence about the last few. Mobile networks change by an order of magnitude when a handset switches cells. Home connections are shared with other devices that start and stop their own traffic. A CDN edge that has the next segment cached delivers it far faster than one that must fetch it from the origin. The CDN guide explains why. The player cannot tell which kind of edge it is talking to.

The failure modes are lopsided. A stall is far more annoying than a few seconds at 480p. So good algorithms are pessimists: they step down quickly and step up slowly. The cost of that pessimism is small. A viewer on an excellent connection may sit at 720p for the first segment or two. Then the player trusts its own measurements enough to move to 1080p.

Three families of algorithm

Throughput-based

Pick the highest rung whose bitrate fits under the smoothed bandwidth estimate. Simple, responsive, and prone to over-reacting to noisy measurements.

Classic
Buffer-based

Map buffer occupancy to a rung: the fuller the buffer, the higher the quality. Ignores bandwidth entirely in steady state and is very stable, but starts slowly.

BOLA and relatives
Hybrid

Use throughput at start-up and when the buffer is thin, then lean on buffer occupancy once playback is established. Most production players do this.

Most common

What you can do at the source

The player's job is easier when the ladder is well made, and the ladder is only as good as the upload.

  • Upload the highest quality source you have. Every rung is transcoded from it, and a compressed source caps every rendition; the blurry after upload guide shows the effect.
  • Keep the frame rate the camera recorded. Mixed or variable frame rates complicate segment alignment; the frame rate guide explains the options.
  • Do not pre-shrink to 720p in the hope of a faster upload. The ladder would then stop at 720p, and viewers on big screens would notice. Use resumable uploads instead and let the platform handle size.
  • Leave the quality setting on automatic in the embedded player. Forcing 1080p defeats the mechanism that prevents stalls.

Frequently asked questions

Why does the quality keep changing on a fast connection?

Usually because the throughput measurement is noisy rather than because the bandwidth is low. Cached segments arrive quickly and uncached ones slowly, other devices share the link, and the player's smoothing may not fully hide that. Well-tuned players apply hysteresis so switches are rare. If they are frequent, a very small buffer target or a busy local network is the likely cause.

Is adaptive streaming lower quality than a fixed 1080p file?

At the top rung, no: the 1080p rendition is a normal 1080p encode. The difference is that an ABR player will drop below it when the connection cannot sustain it, where a fixed file would stall. On a strong connection the viewer sees 1080p almost all the time. If a rendition looks worse than expected, the cause is normally the source upload rather than the switching.

Can I force viewers to always get the highest quality?

The player menu lets a viewer pin a rendition, as the help page on quality levels and Auto shows. But forcing it for everyone is not something to want. A viewer whose connection cannot carry 1080p would buffer constantly, and most would leave. Automatic mode gives every viewer the best quality their link supports at each moment, which is a better outcome than a fixed quality a large share of them cannot play.

How is the initial quality chosen?

Before any segment has downloaded there is no bandwidth measurement, so players use a prior. In HLS the first variant listed in the multivariant playlist is the conventional starting point; some players also remember the last measured bandwidth for that site. The first segment then provides a real measurement and the algorithm takes over, which is why quality often improves within a few seconds.

Sources

adaptive bitrateabrencoding laddervideo quality switchinghls

Related guides