From 5dd21179ec7a2baa5e456816a2d4a229f86ec0b0 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Fri, 22 Jun 2018 16:19:30 -0700 Subject: [PATCH] Do not use harmonic mean in bandwidth calculation Instead, caclulating average bandwidth by dividing the sum of the sizes of every segment by the sum of the durations of every segment. This aligns with the requirement in HLS spec: https://tools.ietf.org/html/draft-pantos-http-live-streaming-23 4.1. BandwidthEstimator is also simplified to handle all blocks only. Fixes #361 Change-Id: I89e7d415a841f4d4048f199de8dae7ffa250467b --- .../testdata/avc-aac-ts-language/output.m3u8 | 4 +- .../app/test/testdata/avc-aac-ts/output.m3u8 | 4 +- .../testdata/avc-ac3-ts-to-mp4/output.m3u8 | 4 +- .../avc-ac3-ts-with-encryption/output.m3u8 | 4 +- .../app/test/testdata/avc-ac3-ts/output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../avc-ts-event-playlist/output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../testdata/avc-ts-live-playlist/output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../avc-ts-with-encryption/output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../ec3-packed-audio-encrypted/output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../output.m3u8 | 2 +- .../testdata/hls-segmented-webvtt/output.m3u8 | 2 +- .../output.m3u8 | 4 +- .../output.m3u8 | 4 +- .../hls-with-bandwidth-override/output.m3u8 | 2 +- .../live-profile-with-webm/output.m3u8 | 2 +- .../vtt-text-to-mp4-with-ad-cues/output.m3u8 | 4 +- packager/hls/base/media_playlist.cc | 3 +- packager/hls/base/media_playlist_unittest.cc | 3 +- packager/mpd/base/bandwidth_estimator.cc | 66 +++-------- packager/mpd/base/bandwidth_estimator.h | 58 ++-------- .../mpd/base/bandwidth_estimator_unittest.cc | 105 ++---------------- packager/mpd/base/representation.cc | 1 - packager/mpd/base/representation_unittest.cc | 4 - 31 files changed, 83 insertions(+), 245 deletions(-) diff --git a/packager/app/test/testdata/avc-aac-ts-language/output.m3u8 b/packager/app/test/testdata/avc-aac-ts-language/output.m3u8 index ec43e9cfdf..8e9e9c86b7 100644 --- a/packager/app/test/testdata/avc-aac-ts-language/output.m3u8 +++ b/packager/app/test/testdata/avc-aac-ts-language/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",LANGUAGE="pt",NAME="stream_0",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1109509,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1117320,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-aac-ts/output.m3u8 b/packager/app/test/testdata/avc-aac-ts/output.m3u8 index 985fd91755..d6e778dce2 100644 --- a/packager/app/test/testdata/avc-aac-ts/output.m3u8 +++ b/packager/app/test/testdata/avc-aac-ts/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1109509,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1117320,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ac3-ts-to-mp4/output.m3u8 b/packager/app/test/testdata/avc-ac3-ts-to-mp4/output.m3u8 index 5d447f0703..058e06c241 100644 --- a/packager/app/test/testdata/avc-ac3-ts-to-mp4/output.m3u8 +++ b/packager/app/test/testdata/avc-ac3-ts-to-mp4/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-ac3-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1168321,AVERAGE-BANDWIDTH=1046257,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1168321,AVERAGE-BANDWIDTH=1053216,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-ac3-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=214292,AVERAGE-BANDWIDTH=153342,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=214292,AVERAGE-BANDWIDTH=156327,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ac3-ts-with-encryption/output.m3u8 b/packager/app/test/testdata/avc-ac3-ts-with-encryption/output.m3u8 index b6378c7e2a..db9f321732 100644 --- a/packager/app/test/testdata/avc-ac3-ts-with-encryption/output.m3u8 +++ b/packager/app/test/testdata/avc-ac3-ts-with-encryption/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-ac3-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1242863,AVERAGE-BANDWIDTH=1142132,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1242863,AVERAGE-BANDWIDTH=1148679,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-ac3-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ac3-ts/output.m3u8 b/packager/app/test/testdata/avc-ac3-ts/output.m3u8 index b6378c7e2a..db9f321732 100644 --- a/packager/app/test/testdata/avc-ac3-ts/output.m3u8 +++ b/packager/app/test/testdata/avc-ac3-ts/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-ac3-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1242863,AVERAGE-BANDWIDTH=1142132,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1242863,AVERAGE-BANDWIDTH=1148679,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-ac3-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/output.m3u8 b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/output.m3u8 index 50c768e24f..18aac65af5 100644 --- a/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-aac-packed-audio-with-encryption/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1154999,AVERAGE-BANDWIDTH=1046205,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1154999,AVERAGE-BANDWIDTH=1054750,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/output.m3u8 b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/output.m3u8 index c0c100f97e..0ca6fd46d5 100644 --- a/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-ac3-packed-audio-with-encryption/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-ac3-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1216578,AVERAGE-BANDWIDTH=1115973,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1216578,AVERAGE-BANDWIDTH=1122532,CODECS="avc1.64001e,ac-3",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-ac3-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ac3-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-event-playlist/output.m3u8 b/packager/app/test/testdata/avc-ts-event-playlist/output.m3u8 index 985fd91755..d6e778dce2 100644 --- a/packager/app/test/testdata/avc-ts-event-playlist/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-event-playlist/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1109509,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1117320,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/output.m3u8 b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/output.m3u8 index 985fd91755..d6e778dce2 100644 --- a/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-live-playlist-with-key-rotation/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1109509,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1117320,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-live-playlist/output.m3u8 b/packager/app/test/testdata/avc-ts-live-playlist/output.m3u8 index 985fd91755..d6e778dce2 100644 --- a/packager/app/test/testdata/avc-ts-live-playlist/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-live-playlist/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1109509,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1117320,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/output.m3u8 b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/output.m3u8 index 985fd91755..d6e778dce2 100644 --- a/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-with-encryption-and-fairplay/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1109509,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1117320,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/output.m3u8 b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/output.m3u8 index 82fd728a2d..7718f93b18 100644 --- a/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-with-encryption-exercise-emulation-prevention/output.m3u8 @@ -1,7 +1,7 @@ #EXTM3U ## Generated with https://github.com/google/shaka-packager version -- -#EXT-X-STREAM-INF:BANDWIDTH=1183949,AVERAGE-BANDWIDTH=80147,CODECS="avc1.64001f",RESOLUTION=1024x436 +#EXT-X-STREAM-INF:BANDWIDTH=1183949,AVERAGE-BANDWIDTH=390289,CODECS="avc1.64001f",RESOLUTION=1024x436 sintel-1024x436-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=447591,AVERAGE-BANDWIDTH=6232,CODECS="avc1.64001f",RESOLUTION=1024x436,URI="sintel-1024x436-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=447591,AVERAGE-BANDWIDTH=40358,CODECS="avc1.64001f",RESOLUTION=1024x436,URI="sintel-1024x436-video-iframe.m3u8" diff --git a/packager/app/test/testdata/avc-ts-with-encryption/output.m3u8 b/packager/app/test/testdata/avc-ts-with-encryption/output.m3u8 index 985fd91755..d6e778dce2 100644 --- a/packager/app/test/testdata/avc-ts-with-encryption/output.m3u8 +++ b/packager/app/test/testdata/avc-ts-with-encryption/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1109509,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1217520,AVERAGE-BANDWIDTH=1117320,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/ec3-and-hls-single-segment-mp4-encrypted/output.m3u8 b/packager/app/test/testdata/ec3-and-hls-single-segment-mp4-encrypted/output.m3u8 index 2393b3d8b0..8780295fcf 100644 --- a/packager/app/test/testdata/ec3-and-hls-single-segment-mp4-encrypted/output.m3u8 +++ b/packager/app/test/testdata/ec3-and-hls-single-segment-mp4-encrypted/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-ec3-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1174214,AVERAGE-BANDWIDTH=1030678,CODECS="avc1.64001e,ec-3",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1174214,AVERAGE-BANDWIDTH=1040768,CODECS="avc1.64001e,ec-3",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-ec3-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=155992,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ec3-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=159315,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ec3-video-iframe.m3u8" diff --git a/packager/app/test/testdata/ec3-packed-audio-encrypted/output.m3u8 b/packager/app/test/testdata/ec3-packed-audio-encrypted/output.m3u8 index 96b1d4b867..4233dd42a3 100644 --- a/packager/app/test/testdata/ec3-packed-audio-encrypted/output.m3u8 +++ b/packager/app/test/testdata/ec3-packed-audio-encrypted/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-ec3-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1216655,AVERAGE-BANDWIDTH=1095969,CODECS="avc1.64001e,ec-3",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1216655,AVERAGE-BANDWIDTH=1104925,CODECS="avc1.64001e,ec-3",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-ec3-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=153967,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ec3-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=217180,AVERAGE-BANDWIDTH=157213,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-ec3-video-iframe.m3u8" diff --git a/packager/app/test/testdata/encryption-and-ad-cues-split-content/output.m3u8 b/packager/app/test/testdata/encryption-and-ad-cues-split-content/output.m3u8 index 831f317e62..5e64e17586 100644 --- a/packager/app/test/testdata/encryption-and-ad-cues-split-content/output.m3u8 +++ b/packager/app/test/testdata/encryption-and-ad-cues-split-content/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1152421,AVERAGE-BANDWIDTH=986776,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1152421,AVERAGE-BANDWIDTH=987816,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=155643,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=159070,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/hls-audio-video-text-with-ad-cues/output.m3u8 b/packager/app/test/testdata/hls-audio-video-text-with-ad-cues/output.m3u8 index 50f26c312f..51885b603a 100644 --- a/packager/app/test/testdata/hls-audio-video-text-with-ad-cues/output.m3u8 +++ b/packager/app/test/testdata/hls-audio-video-text-with-ad-cues/output.m3u8 @@ -5,7 +5,7 @@ #EXT-X-MEDIA:TYPE=SUBTITLES,URI="bear-subtitle-english-text.m3u8",GROUP-ID="default-text-group",NAME="stream_0",AUTOSELECT=YES -#EXT-X-STREAM-INF:BANDWIDTH=1150006,AVERAGE-BANDWIDTH=983710,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" +#EXT-X-STREAM-INF:BANDWIDTH=1150006,AVERAGE-BANDWIDTH=984507,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=214292,AVERAGE-BANDWIDTH=153342,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=214292,AVERAGE-BANDWIDTH=156327,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/hls-multi-segment-mp4-with-custom-path/output.m3u8 b/packager/app/test/testdata/hls-multi-segment-mp4-with-custom-path/output.m3u8 index 32242ca1b9..055c4fb285 100644 --- a/packager/app/test/testdata/hls-multi-segment-mp4-with-custom-path/output.m3u8 +++ b/packager/app/test/testdata/hls-multi-segment-mp4-with-custom-path/output.m3u8 @@ -3,5 +3,5 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="audio/audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1105131,AVERAGE-BANDWIDTH=974563,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1105131,AVERAGE-BANDWIDTH=983986,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" video/video.m3u8 diff --git a/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 b/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 index 3ad045904b..4f212a179a 100644 --- a/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 +++ b/packager/app/test/testdata/hls-segmented-webvtt/output.m3u8 @@ -5,5 +5,5 @@ #EXT-X-MEDIA:TYPE=SUBTITLES,URI="stream_0.m3u8",GROUP-ID="default-text-group",NAME="stream_0",AUTOSELECT=YES -#EXT-X-STREAM-INF:BANDWIDTH=1105131,AVERAGE-BANDWIDTH=974563,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" +#EXT-X-STREAM-INF:BANDWIDTH=1105131,AVERAGE-BANDWIDTH=983986,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" stream_2.m3u8 diff --git a/packager/app/test/testdata/hls-single-segment-mp4-encrypted-and-ad-cues/output.m3u8 b/packager/app/test/testdata/hls-single-segment-mp4-encrypted-and-ad-cues/output.m3u8 index 831f317e62..5e64e17586 100644 --- a/packager/app/test/testdata/hls-single-segment-mp4-encrypted-and-ad-cues/output.m3u8 +++ b/packager/app/test/testdata/hls-single-segment-mp4-encrypted-and-ad-cues/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1152421,AVERAGE-BANDWIDTH=986776,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1152421,AVERAGE-BANDWIDTH=987816,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=155643,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=159070,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/hls-single-segment-mp4-encrypted/output.m3u8 b/packager/app/test/testdata/hls-single-segment-mp4-encrypted/output.m3u8 index 33e03086fd..bee37fae7a 100644 --- a/packager/app/test/testdata/hls-single-segment-mp4-encrypted/output.m3u8 +++ b/packager/app/test/testdata/hls-single-segment-mp4-encrypted/output.m3u8 @@ -3,7 +3,7 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="bear-640x360-audio.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=1111149,AVERAGE-BANDWIDTH=977986,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=1111149,AVERAGE-BANDWIDTH=987362,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=155643,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=218705,AVERAGE-BANDWIDTH=159070,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/app/test/testdata/hls-with-bandwidth-override/output.m3u8 b/packager/app/test/testdata/hls-with-bandwidth-override/output.m3u8 index e701b3517a..68edc4cb1b 100644 --- a/packager/app/test/testdata/hls-with-bandwidth-override/output.m3u8 +++ b/packager/app/test/testdata/hls-with-bandwidth-override/output.m3u8 @@ -3,5 +3,5 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="stream_0.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=55555,AVERAGE-BANDWIDTH=974563,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=55555,AVERAGE-BANDWIDTH=983986,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group" stream_1.m3u8 diff --git a/packager/app/test/testdata/live-profile-with-webm/output.m3u8 b/packager/app/test/testdata/live-profile-with-webm/output.m3u8 index 9c96fbd47c..670f5e9744 100644 --- a/packager/app/test/testdata/live-profile-with-webm/output.m3u8 +++ b/packager/app/test/testdata/live-profile-with-webm/output.m3u8 @@ -3,5 +3,5 @@ #EXT-X-MEDIA:TYPE=AUDIO,URI="stream_0.m3u8",GROUP-ID="default-audio-group",NAME="stream_0",AUTOSELECT=YES,CHANNELS="2" -#EXT-X-STREAM-INF:BANDWIDTH=556353,AVERAGE-BANDWIDTH=378244,CODECS="vp08.00.10.08.01.02.02.02.00,vorbis",RESOLUTION=640x360,AUDIO="default-audio-group" +#EXT-X-STREAM-INF:BANDWIDTH=556353,AVERAGE-BANDWIDTH=412719,CODECS="vp08.00.10.08.01.02.02.02.00,vorbis",RESOLUTION=640x360,AUDIO="default-audio-group" stream_1.m3u8 diff --git a/packager/app/test/testdata/vtt-text-to-mp4-with-ad-cues/output.m3u8 b/packager/app/test/testdata/vtt-text-to-mp4-with-ad-cues/output.m3u8 index 50f26c312f..51885b603a 100644 --- a/packager/app/test/testdata/vtt-text-to-mp4-with-ad-cues/output.m3u8 +++ b/packager/app/test/testdata/vtt-text-to-mp4-with-ad-cues/output.m3u8 @@ -5,7 +5,7 @@ #EXT-X-MEDIA:TYPE=SUBTITLES,URI="bear-subtitle-english-text.m3u8",GROUP-ID="default-text-group",NAME="stream_0",AUTOSELECT=YES -#EXT-X-STREAM-INF:BANDWIDTH=1150006,AVERAGE-BANDWIDTH=983710,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" +#EXT-X-STREAM-INF:BANDWIDTH=1150006,AVERAGE-BANDWIDTH=984507,CODECS="avc1.64001e,mp4a.40.2",RESOLUTION=640x360,AUDIO="default-audio-group",SUBTITLES="default-text-group" bear-640x360-video.m3u8 -#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=214292,AVERAGE-BANDWIDTH=153342,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" +#EXT-X-I-FRAME-STREAM-INF:BANDWIDTH=214292,AVERAGE-BANDWIDTH=156327,CODECS="avc1.64001e",RESOLUTION=640x360,URI="bear-640x360-video-iframe.m3u8" diff --git a/packager/hls/base/media_playlist.cc b/packager/hls/base/media_playlist.cc index 3e3b9bdbc0..bcd6a29d84 100644 --- a/packager/hls/base/media_playlist.cc +++ b/packager/hls/base/media_playlist.cc @@ -330,8 +330,7 @@ MediaPlaylist::MediaPlaylist(const HlsParams& hls_params, : hls_params_(hls_params), file_name_(file_name), name_(name), - group_id_(group_id), - bandwidth_estimator_(BandwidthEstimator::kUseAllBlocks) {} + group_id_(group_id) {} MediaPlaylist::~MediaPlaylist() {} diff --git a/packager/hls/base/media_playlist_unittest.cc b/packager/hls/base/media_playlist_unittest.cc index 3f0a90fe55..64eb546753 100644 --- a/packager/hls/base/media_playlist_unittest.cc +++ b/packager/hls/base/media_playlist_unittest.cc @@ -262,9 +262,8 @@ TEST_F(MediaPlaylistMultiSegmentTest, GetBitrateFromSegments) { media_playlist_->AddSegment("file2.ts", 10 * kTimeScale, 20 * kTimeScale, kZeroByteOffset, 5 * kMBytes); - // Max bitrate is 2000Kb/s. EXPECT_EQ(2000000u, media_playlist_->MaxBitrate()); - EXPECT_EQ(1142858u, media_playlist_->AvgBitrate()); + EXPECT_EQ(1600000u, media_playlist_->AvgBitrate()); } TEST_F(MediaPlaylistMultiSegmentTest, GetLongestSegmentDuration) { diff --git a/packager/mpd/base/bandwidth_estimator.cc b/packager/mpd/base/bandwidth_estimator.cc index 90d7220ea6..82cdcef5a1 100644 --- a/packager/mpd/base/bandwidth_estimator.cc +++ b/packager/mpd/base/bandwidth_estimator.cc @@ -6,71 +6,41 @@ #include "packager/mpd/base/bandwidth_estimator.h" +#include #include #include "packager/base/logging.h" namespace shaka { -BandwidthEstimator::BandwidthEstimator(size_t num_blocks) - : sliding_queue_(num_blocks) {} -BandwidthEstimator::~BandwidthEstimator() {} +BandwidthEstimator::BandwidthEstimator() = default; +BandwidthEstimator::~BandwidthEstimator() = default; -void BandwidthEstimator::AddBlock(uint64_t size, double duration) { - if (size == 0 || duration == 0) { - LOG(WARNING) << "Ignore block with size=" << size +void BandwidthEstimator::AddBlock(uint64_t size_in_bytes, double duration) { + if (size_in_bytes == 0 || duration == 0) { + LOG(WARNING) << "Ignore block with size=" << size_in_bytes << ", duration=" << duration; return; } + const int kBitsInByte = 8; - const double bits_per_second_reciprocal = duration / (kBitsInByte * size); - sliding_queue_.Add(bits_per_second_reciprocal); + const uint64_t size_in_bits = size_in_bytes * kBitsInByte; + total_size_in_bits_ += size_in_bits; + + total_duration_ += duration; + + const uint64_t bitrate = static_cast(ceil(size_in_bits / duration)); + max_bitrate_ = std::max(bitrate, max_bitrate_); } uint64_t BandwidthEstimator::Estimate() const { - return sliding_queue_.size() == 0 - ? 0 - : static_cast( - ceil(sliding_queue_.size() / sliding_queue_.sum())); + if (total_duration_ == 0) + return 0; + return static_cast(ceil(total_size_in_bits_ / total_duration_)); } uint64_t BandwidthEstimator::Max() const { - // The first element has minimum "bits per second reciprocal", thus the - // reverse is maximum "bits per second". - return sliding_queue_.size() == 0 - ? 0 - : static_cast(ceil(1 / sliding_queue_.min())); -} - -BandwidthEstimator::SlidingQueue::SlidingQueue(size_t window_size) - : window_size_(window_size) {} - -void BandwidthEstimator::SlidingQueue::Add(double value) { - // Remove elements if needed to form a monotonic non-decreasing sequence. - while (!min_.empty() && min_.back() > value) - min_.pop_back(); - min_.push_back(value); - - if (window_size_ == kUseAllBlocks) { - size_++; - sum_ += value; - min_.resize(1); // Keep only the minimum one. - return; - } - - window_.push_back(value); - sum_ += value; - - if (window_.size() <= window_size_) { - size_++; - return; - } - - if (min_.front() == window_.front()) - min_.pop_front(); - - sum_ -= window_.front(); - window_.pop_front(); + return max_bitrate_; } } // namespace shaka diff --git a/packager/mpd/base/bandwidth_estimator.h b/packager/mpd/base/bandwidth_estimator.h index e7f59e2c55..5544de129b 100644 --- a/packager/mpd/base/bandwidth_estimator.h +++ b/packager/mpd/base/bandwidth_estimator.h @@ -7,27 +7,23 @@ #ifndef MPD_BASE_BANDWIDTH_ESTIMATOR_H_ #define MPD_BASE_BANDWIDTH_ESTIMATOR_H_ -#include #include -#include - namespace shaka { class BandwidthEstimator { public: - /// @param num_blocks is the number of latest blocks to use. 0 uses all. - static constexpr size_t kUseAllBlocks = 0; - explicit BandwidthEstimator(size_t num_blocks); + BandwidthEstimator(); ~BandwidthEstimator(); /// @param size is the size of the block in bytes. Should be positive. /// @param duration is the length in seconds. Should be positive. - void AddBlock(uint64_t size, double duration); + void AddBlock(uint64_t size_in_bytes, double duration); - /// @return The estimate bandwidth, in bits per second, from the harmonic mean - /// of the number of blocks specified in the constructor. The value is - /// rounded up to the nearest integer. + /// @return The estimate bandwidth, in bits per second, calculated from the + /// sum of the sizes of every block, divided by the sum of durations + /// of every block, of the number of blocks specified in the + /// constructor. The value is rounded up to the nearest integer. uint64_t Estimate() const; /// @return The max bandwidth, in bits per second, of the number of blocks @@ -39,45 +35,9 @@ class BandwidthEstimator { BandwidthEstimator(const BandwidthEstimator&) = delete; BandwidthEstimator& operator=(const BandwidthEstimator&) = delete; - // A sliding queue that provide convenient functions to get the minimum value - // and the sum when window slides. - class SlidingQueue { - public: - // |window_size| defines the size of the sliding window. 0 uses all. - explicit SlidingQueue(size_t window_size); - - // Add a new value. Old values may be moved out. - void Add(double value); - - // Return the sum of the values in the sliding window. - double sum() const { return sum_; } - // Return the number of values in the sliding window. - double size() const { return size_; } - // Return the minimum value of the values in the sliding window. - double min() const { return min_.front(); } - - private: - SlidingQueue(const SlidingQueue&) = delete; - SlidingQueue& operator=(const SlidingQueue&) = delete; - - const size_t window_size_; - size_t size_ = 0; - double sum_ = 0; - // Keeps track of the values in the sliding window. Not needed if - // |window_size| is kUseAllBlocks. - std::deque window_; - // Keeps track of a monotonic non-decreasing sequence of values, i.e. - // local minimum values in the sliding window. The front() is always the - // global minimum, i.e. the minimum value in the sliding window. - // This is achieved through: - // (1) New value is added to the back with the original values before it - // that are larger removed as they are no longer useful. - // (2) When a value is removed from |window_|, if it is the minimum value, - // it is also removed from |min_|; if it is not, it means the value is not - // present in |min_|. - std::deque min_; - }; - SlidingQueue sliding_queue_; + uint64_t total_size_in_bits_ = 0; + double total_duration_ = 0; + uint64_t max_bitrate_ = 0; }; } // namespace shaka diff --git a/packager/mpd/base/bandwidth_estimator_unittest.cc b/packager/mpd/base/bandwidth_estimator_unittest.cc index ad24cc85e2..e3632f25ac 100644 --- a/packager/mpd/base/bandwidth_estimator_unittest.cc +++ b/packager/mpd/base/bandwidth_estimator_unittest.cc @@ -4,116 +4,31 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -#include - -#include - -#include "packager/base/macros.h" #include "packager/mpd/base/bandwidth_estimator.h" +#include + namespace shaka { namespace { -const size_t kNumBlocksForEstimate = 5; const uint64_t kBitsInByte = 8; -const int kEstimateRoundError = 1; - -struct Bandwidth { - uint64_t average; - uint64_t max; -}; - } // namespace -// Make sure that averaging of 5 blocks works, and also when there aren't all 5 -// blocks. -TEST(BandwidthEstimatorTest, FiveBlocksFiveBlocksAdded) { - BandwidthEstimator be(kNumBlocksForEstimate); - const double kDuration = 1.0; - const Bandwidth kExpectedResults[] = { - // Harmonic mean of [1 * 8], [1 * 8, 2 * 8], ... - // 8 is the number of bits in a byte and 1, 2, ... is from the loop - // counter below. - // Note that these are rounded up. - {8, 8}, {11, 2 * 8}, {14, 3 * 8}, {16, 4 * 8}, {18, 5 * 8}, - }; - - static_assert(kNumBlocksForEstimate == arraysize(kExpectedResults), - "incorrect_number_of_expectations"); - for (uint64_t i = 1; i <= arraysize(kExpectedResults); ++i) { - be.AddBlock(i, kDuration); - EXPECT_EQ(kExpectedResults[i - 1].average, be.Estimate()); - EXPECT_EQ(kExpectedResults[i - 1].max, be.Max()); - } -} - -// More practical situation where a lot of blocks get added but only the last 5 -// are considered for the estimate. -TEST(BandwidthEstimatorTest, FiveBlocksNormal) { - BandwidthEstimator be(kNumBlocksForEstimate); - const double kDuration = 10.0; - const uint64_t kNumBlocksToAdd = 200; - const uint64_t kExptectedEstimate = 800; - - // Doesn't matter what gets passed to the estimator except for the last 5 - // blocks which we add kExptectedEstimate / 8 bytes per second so that the - // estimate becomes kExptectedEstimate. - for (uint64_t i = 1; i <= kNumBlocksToAdd; ++i) { - if (i > kNumBlocksToAdd - kNumBlocksForEstimate) { - be.AddBlock(kExptectedEstimate * kDuration / kBitsInByte, kDuration); - } else { - be.AddBlock(i, kDuration); - } - } - - EXPECT_NEAR(kExptectedEstimate, be.Estimate(), kEstimateRoundError); - // All blocks are of the same bitrate, so Max is the same as average. - EXPECT_NEAR(kExptectedEstimate, be.Max(), kEstimateRoundError); -} - TEST(BandwidthEstimatorTest, AllBlocks) { - BandwidthEstimator be(BandwidthEstimator::kUseAllBlocks); + BandwidthEstimator be; const uint64_t kNumBlocksToAdd = 100; const double kDuration = 1.0; - for (uint64_t i = 1; i <= kNumBlocksToAdd; ++i) + uint64_t total_bytes = 0; + for (uint64_t i = 1; i <= kNumBlocksToAdd; ++i) { be.AddBlock(i, kDuration); + total_bytes += i; + } - // The harmonic mean of 8, 16, ... , 800; rounded up. - const uint64_t kExptectedEstimate = 155; + const uint64_t kExptectedEstimate = + total_bytes * kBitsInByte / kNumBlocksToAdd; EXPECT_EQ(kExptectedEstimate, be.Estimate()); - const uint64_t kMax = 100 * 8; + const uint64_t kMax = kNumBlocksToAdd * kBitsInByte; EXPECT_EQ(kMax, be.Max()); } -TEST(BandwidthEstimatorTest, MaxWithSlidingWindow) { - BandwidthEstimator be(kNumBlocksForEstimate); - const double kDuration = 1.0 * kBitsInByte; - - // clang-format off - const uint64_t kSizes[] = { - // Sequence 1: Monotonic decreasing. - 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, - // Sequence 2: Monotonic increasing. - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - // Sequence 3: Random sequence. - 10, 1, 9, 6, 9, 5, 4, 9, 7, 8, - }; - const uint64_t kExpectedMaxes[] = { - // Sequence 1. - 10, 10, 10, 10, 10, 9, 8, 7, 6, 5, - // Sequence 2. - 4, 3, 3, 4, 5, 6, 7, 8, 9, 10, - // Sequence 3. - 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, - }; - // clang-format on - - static_assert(arraysize(kSizes) == arraysize(kExpectedMaxes), - "incorrect_number_of_expectations"); - for (size_t i = 0; i < arraysize(kSizes); ++i) { - be.AddBlock(kSizes[i], kDuration); - EXPECT_EQ(kExpectedMaxes[i], be.Max()); - } -} - } // namespace shaka diff --git a/packager/mpd/base/representation.cc b/packager/mpd/base/representation.cc index 1340c2e502..35fb9a6b14 100644 --- a/packager/mpd/base/representation.cc +++ b/packager/mpd/base/representation.cc @@ -115,7 +115,6 @@ Representation::Representation( std::unique_ptr state_change_listener) : media_info_(media_info), id_(id), - bandwidth_estimator_(BandwidthEstimator::kUseAllBlocks), mpd_options_(mpd_options), state_change_listener_(std::move(state_change_listener)), allow_approximate_segment_timeline_( diff --git a/packager/mpd/base/representation_unittest.cc b/packager/mpd/base/representation_unittest.cc index 8857db51ae..829f1e7016 100644 --- a/packager/mpd/base/representation_unittest.cc +++ b/packager/mpd/base/representation_unittest.cc @@ -441,10 +441,6 @@ std::string GetDefaultMediaInfo() { class SegmentTemplateTest : public RepresentationTest { public: - SegmentTemplateTest() - : bandwidth_estimator_(BandwidthEstimator::kUseAllBlocks) {} - ~SegmentTemplateTest() override {} - void SetUp() override { mpd_options_.mpd_type = MpdType::kDynamic; representation_ =