Nous ferons une rapide explication des enjeux et mécanismes de l'Adaptive Bitrate Streaming, puis allons regarder les implémentations pratiques dans les media engines de référence dash.js et hls.js.
Compare Performance-power of Arm Cortex vs RISC-V for AI applications_oct_2021Deepak Shankar
Similar a Paris Video Tech - 1st Edition: Streamroot, Adaptive Bitrate Algorithms: comment ca marche, et comment les optimiser dans votre player HTML5 (20)
2. Streamroot: Who are we?
PARTNERS
INFINITE POSSIBILITIES, LIMITLESS DELIVERY
Streamroot combines the best of a controlled, centralized network
with the resilience and scalability of a widely distributed delivery
architecture.
3. Presentation Outline
I. Design goals
II. Components: Constraints & Parameters
Examples: hls.js & dash.js
Basic Algorithms + improvements: smoothing, quantizing, scheduling
III. Going further
Another Approach: buffer levels
The key to improving: testing and iterating
4. I. Design goals: optimize viewer experience
1. Maximize efficiency – stream at the highest bitrate possible
2. Minimize rebuffering – avoid underrun and playback stalls
3. Encourage stability – switch only when necessary
(4. Promote fairness across network bottlenecks)
5. I. Design goals: why this matters
Views 24 min longer when buffer ratio is < 0.2% for live content
View time drops 40% when > 0.4% buffer ratio mark
Buffer ratio vs. play time
Source: NPAW aggregated
data for a set of European
live broadcasters
6. II. Components: Constraints and Parameters
CONSTRAINTS PARAMETERS
Screen size / Player size Buffer size
CPU & Dropped frame threshold Bandwidth & possible bitrate
Startup time / Rebuffering recovery (Bonus: P2P Bandwidth)
7. II. Components: constraints
1. Screen & Player Size
Resolution should never be larger than the actual size of the video player
2. CPU & Dropped frames
Downgrade when too many dropped frames per second
3. Startup time
Always fetch the lowest quality first whenever the buffer is empty
8. Screen & player size: HLS.js
https://github.com/dailymotion/hls.js/blob/master/src/controller/cap-level-controller.js#L68
Checks the max CapLevel
corresponding to current
player size
Frequency: every 1000 ms
11. II. Components: parameters
1. Bandwidth Estimation (goal: maximize bitrate)
Estimate available bandwidth based on prior segment(s)
Available bandwidth = size of chunk / time taken to download
2. Buffer size (goal: minimize rebuffering ratio)
Rebuffering ratio = buffering time / (buffering time + playback time)
Also: Abandon strategy
14. Bandwidth estimation: DASH.JS smoothing
Bandwidth smoothing,
taking the last X segment
estimations into account
https://github.com/Dash-Industry-Forum/dash.js/blob/development/src/streaming/rules/abr/ThroughputRule.js
15. Bandwidth fragment abort rule: HLS.js and DASH.JS
https://github.com/dailymotion/hls.js/blob/master/src/controller/abr-controller.js#L51
https://github.com/Dash-Industry-Forum/dash.js/blob/master/src/streaming/rules/abr/AbandonRequestsRule.js
HLS.js DASH.js
16. (Bonus) DASH.JS complementary buffer-based rules
Prevents from switching
down when buffer is large
enough (mostly for VOD)
https://github.com/Dash-Industry-Forum/dash.js/blob/development/src/streaming/rules/abr/BufferOccupancyRule.js
17. Buffer size based ONLY no more bandwidth estimations
Uses utility theory to make decisions: configurable tradeoff between rebuffering potential
& bitrate maximization:
Maximize Vn + y Sn
Where:
Vn is the bitrate utility
Sn is the playback Smoothness
y is the tradeoff weight parameter
IV. Going further: DASH.js BOLA, another approach
18. IV. Going further: test and iterate!
You’ve got the power!
- Know what is important to you (buffering, max bitrate, bandwidth savings…)
- Compare and cross with QoS analytics to understand your audiences
- Test and iterate: AB testing allows you to compare changes in real-time
19. 1. Tweak the parameters
https://github.com/dailymotion/hls.js/blob/master/API
.md#fine-tuning
2. Write your own rules!
AbrController: AbrController
capLevelController: CapLevelController,
fpsController: fpsController
IV. Going further: how to improve in practice
HLS.js DASH.js
1. Tweak the Parameters
http://cdn.dashjs.org/latest/jsdoc/index.html
2. Write your own rules
https://github.com/Dash-Industry-
Forum/dash.js/wiki/Migration-2.0#extending-dashjs
https://github.com/Dash-Industry-
Forum/dash.js/blob/development/src/streaming/rules/
abr/ABRRulesCollection.js
22. Further Reading / Contact Us
Probe and Adapt: Rate Adaptation for HTTP Video Streaming At Scale. Zhi Li, Xiaoqing Zhu, Josh Gahm, Rong Pan, Hao
Hu, Ali C. Begen, Dave Oran, Cisco Systems, 7 Jul 2013.
Improving Fairness, Efficiency, and Stability in HTTP-based Adaptive Video Streaming with FESTIVE, Junchen Jiang,
Carnegie Mellon University, Vyas Sekar, Stony Brook University, Hui Zhang, Carnegie Mellon, University/Conviva Inc.
2012.
ELASTIC: a Client-side Controller for Dynamic Adaptive Streaming over HTTP (DASH). Luca De Cicco, Member, IEEE,
Vito Caldaralo, Vittorio Palmisano, and Saverio Mascolo, Senior Member, IEEE.
BOLA: Near-Optimal Bitrate Adaptation for Online Videos. Kevin Spiteri, Rahul Urgaonkar , Ramesh K. Sitaraman,
University of Massachusetts Amherst, Amazon Inc., Akamai Technologies Inc.
Drop us a line:
Nikolay Rodionov, Co-Founder and CPO, nikolay@streamroot.io
Erica Beavers, Head of Partnerships, erica@streamroot.io
Notas del editor
Checks the max CapLevel corresponding to current player size
Every 1000ms.
You can also add up manual level caps on initialization.
If the cap level is bigger that the last one (which means the player size has grown, like in Fullscreen for exemple), then you flush the current buffer and ask for a new quality right away (force the buffer)
Calculates the dropped frames per second ratio.
If it is > 0.2, bans the level for ever => goes into restricated levels
Not activated in production!
fpsDroppedMonitoringThreshold
fpsDroppedMonitoringPeriod
First segment always from the lowest quality, then it continues with normal rule (very simple simple rule in practice!)
Another optimization is just to load this level (and playlist), and don’t wait for the other levels to have been loaded
Simple algorithm,
Here talk about Streamroot, and the fact having the sources from different buffers is even more difficult!
Code from us?x
Basically a onProgress & bandwidth estimation too (coming from CDN & P2P network!)
Request.onProgress
Request.onLoad => classic estimation
With P2P estimation! Don’t wanna infinite speed, and thus includes a P2P bandwidth metric.
Not the same for different peers, so averaged and smoothed
Code from us?x
Basically a onProgress & bandwidth estimation too (coming from CDN & P2P network!)
Shema => a P2P cache and a CDN buffer => and time = 0
DASH.Js has 4 different Rules
ThroughputRule calculates bandwidth with some smoothing!
No real quantizing (have a real estimate and no other values)
AbandonRequestsRule cancels if takes more than 1.5x of donwload
BufferOccupancyRule to now go down if buffer large enough (RICH BUFFER TRESHOLD)
InsufficientBufferRule au tas
One of the most important ones here
What happens if you started a request and then BW drops ? Especially important when you ahve long fragments, this can very easily lead to a buffer underrun!
After Half of the needed time, compare the estimate time of arrival to time of buffer underrun. And then see if there is another level that could solve the issue?
DASH.Js has 4 different Rules
ThroughputRule calculates bandwidth with some smoothing!
No real quantizing (have a real estimate and no other values)
AbandonRequestsRule cancels if takes more than 1.5x of donwload
BufferOccupancyRule to now go down if buffer large enough (RICH BUFFER TRESHOLD)
InsufficientBufferRule au tas
BOLA stuff ? The approach is quite difficult to explain… based on utility theory, and supposed to be a lot more efficient because there are no need to estimate the bandiwdth.
BUT
Not fully implemented in dash.js, and there are some optimisation constants that depend a lot on the use-case (target buffer, live, vod…)
Today not working great for small segment sizes AND small buffer size ( but good for 1+ min apparently?)
Still work in progress, but an interesting approach!
We can give a lot of tips, but most of the use-cases are spcific (segment size, playlist size, latency… and also which parameter is most important to you (buffer rate? Best bitrate ? Best bitrate no so useful if you KNOW that most of your user have a better bandwidth anyway? Number of switches)
So what’s important is to have a way to iterate and improve ?
The best is to have AB testing on 50/50 of population, to be able to quickly see results and compare them! What happens if you just tweak one parameter ?
The results can be quite stunning!
The different static constants more for you use-case?
You can play with them
You can also easily build your own rule!
Here is an example on Github?
First explain how to do that?
We can give a lot of tips, but most of the use-cases are spcific (segment size, playlist size, latency… and also which parameter is most important to you (buffer rate? Best bitrate ? Best bitrate no so useful if you KNOW that most of your user have a better bandwidth anyway? Number of switches)
So what’s important is to have a way to iterate and improve ?
The best is to have AB testing on 50/50 of population, to be able to quickly see results and compare them! What happens if you just tweak one parameter ?
The results can be quite stunning!