Use max bitrate in Representation@bandwidth instead of average bitrate
According to DASH spec (23009-1:2014): Consider a hypothetical constant bitrate channel of bandwidth with the value of this attribute in bits per second (bps). Then, if the Representation is continuously delivered at this bitrate, starting at any SAP that is indicated either by @startwithsap or by any Segment Index box, a client can be assured of having enough data for continuous playout providing playout begins after @minbuffertime * @bandwidth bits have been received (i.e. at time @minbuffertime after the first bit is received). For dependent Representations this value specifies the bandwidth according to the above definition for the aggregation of this Representation and all complementary Representations. This suggests that max bitrate should be used instead of average bitrate. Also cleaned up BandwidthEstimator code. Fixes #376. Change-Id: Ibf5896394c5c6bb820849771a2129c59202d2273
This commit is contained in:
parent
9403f2f927
commit
b31fc75eb6
|
@ -7,7 +7,7 @@
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
||||||
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
||||||
</ContentProtection>
|
</ContentProtection>
|
||||||
<Representation id="0" bandwidth="854753" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="978382" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
<S t="0" d="32032"/>
|
<S t="0" d="32032"/>
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
||||||
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
||||||
</ContentProtection>
|
</ContentProtection>
|
||||||
<Representation id="1" bandwidth="124634" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="134015" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="854753" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="978382" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
||||||
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
</Representation>
|
</Representation>
|
||||||
</AdaptationSet>
|
</AdaptationSet>
|
||||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
<Representation id="1" bandwidth="124634" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="134015" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
<Representation id="0" bandwidth="855607" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="979373" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
<S t="0" d="32032"/>
|
<S t="0" d="32032"/>
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
<Representation id="1" bandwidth="125598" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="135009" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
<Representation id="0" bandwidth="855149" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="978958" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
<S t="0" d="32032"/>
|
<S t="0" d="32032"/>
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
<Representation id="1" bandwidth="125122" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="134592" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="855607" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="979373" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
</Representation>
|
</Representation>
|
||||||
</AdaptationSet>
|
</AdaptationSet>
|
||||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
<Representation id="1" bandwidth="125598" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="135009" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
<ContentProtection value="cenc" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_publish_time" availabilityStartTime="some_availability_start_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
<Period id="0" start="PT0S">
|
<Period id="0" start="PT0S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="852255" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="974122" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
<S t="0" d="32032"/>
|
<S t="0" d="32032"/>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
</Representation>
|
</Representation>
|
||||||
</AdaptationSet>
|
</AdaptationSet>
|
||||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
<Representation id="1" bandwidth="122308" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="131009" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.802799940109253S">
|
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.802799940109253S">
|
||||||
<Period id="0" duration="PT2.0687333333333333S">
|
<Period id="0" duration="PT2.0687333333333333S">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="844102" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="974122" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
<S t="0" d="32032"/>
|
<S t="0" d="32032"/>
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
</Representation>
|
</Representation>
|
||||||
</AdaptationSet>
|
</AdaptationSet>
|
||||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
<Representation id="1" bandwidth="143117" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="175884" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.802799940109253S">
|
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.802799940109253S">
|
||||||
<Period id="0">
|
<Period id="0">
|
||||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
<Representation id="0" bandwidth="852255" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
<Representation id="0" bandwidth="974122" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="30000" initialization="output_video-init.mp4" media="output_video-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
<S t="0" d="32032"/>
|
<S t="0" d="32032"/>
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
</Representation>
|
</Representation>
|
||||||
</AdaptationSet>
|
</AdaptationSet>
|
||||||
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
<Representation id="1" bandwidth="122308" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
<Representation id="1" bandwidth="131009" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
<SegmentTemplate timescale="44100" initialization="output_audio-init.mp4" media="output_audio-$Number$.m4s" startNumber="1">
|
||||||
<SegmentTimeline>
|
<SegmentTimeline>
|
||||||
|
|
|
@ -7,57 +7,68 @@
|
||||||
#include "packager/mpd/base/bandwidth_estimator.h"
|
#include "packager/mpd/base/bandwidth_estimator.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include "packager/base/logging.h"
|
#include "packager/base/logging.h"
|
||||||
|
|
||||||
const int BandwidthEstimator::kUseAllBlocks = 0;
|
namespace shaka {
|
||||||
|
|
||||||
BandwidthEstimator::BandwidthEstimator(int num_blocks)
|
BandwidthEstimator::BandwidthEstimator(size_t num_blocks)
|
||||||
: num_blocks_for_estimation_(num_blocks),
|
: sliding_queue_(num_blocks) {}
|
||||||
harmonic_mean_denominator_(0.0),
|
|
||||||
num_blocks_added_(0) {}
|
|
||||||
BandwidthEstimator::~BandwidthEstimator() {}
|
BandwidthEstimator::~BandwidthEstimator() {}
|
||||||
|
|
||||||
void BandwidthEstimator::AddBlock(uint64_t size, double duration) {
|
void BandwidthEstimator::AddBlock(uint64_t size, double duration) {
|
||||||
DCHECK_GT(duration, 0.0);
|
DCHECK_GT(duration, 0.0);
|
||||||
DCHECK_GT(size, 0u);
|
DCHECK_GT(size, 0u);
|
||||||
|
|
||||||
if (num_blocks_for_estimation_ < 0 &&
|
|
||||||
static_cast<int>(history_.size()) >= -1 * num_blocks_for_estimation_) {
|
|
||||||
// Short circuiting the case where |num_blocks_for_estimation_| number of
|
|
||||||
// blocks have been added already.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int kBitsInByte = 8;
|
const int kBitsInByte = 8;
|
||||||
const double bits_per_second_reciprocal = duration / (kBitsInByte * size);
|
const double bits_per_second_reciprocal = duration / (kBitsInByte * size);
|
||||||
harmonic_mean_denominator_ += bits_per_second_reciprocal;
|
sliding_queue_.Add(bits_per_second_reciprocal);
|
||||||
if (num_blocks_for_estimation_ == kUseAllBlocks) {
|
|
||||||
DCHECK_EQ(history_.size(), 0u);
|
|
||||||
++num_blocks_added_;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
history_.push_back(bits_per_second_reciprocal);
|
|
||||||
if (num_blocks_for_estimation_ > 0 &&
|
|
||||||
static_cast<int>(history_.size()) > num_blocks_for_estimation_) {
|
|
||||||
harmonic_mean_denominator_ -= history_.front();
|
|
||||||
history_.pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
DCHECK_NE(num_blocks_for_estimation_, kUseAllBlocks);
|
|
||||||
DCHECK_LE(static_cast<int>(history_.size()), abs(num_blocks_for_estimation_));
|
|
||||||
DCHECK_EQ(num_blocks_added_, 0u);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t BandwidthEstimator::Estimate() const {
|
uint64_t BandwidthEstimator::Estimate() const {
|
||||||
if (harmonic_mean_denominator_ == 0.0)
|
return sliding_queue_.size() == 0
|
||||||
return 0;
|
? 0
|
||||||
|
: static_cast<uint64_t>(
|
||||||
const uint64_t num_blocks = num_blocks_for_estimation_ == kUseAllBlocks
|
ceil(sliding_queue_.size() / sliding_queue_.sum()));
|
||||||
? num_blocks_added_
|
|
||||||
: history_.size();
|
|
||||||
return static_cast<uint64_t>(ceil(num_blocks / harmonic_mean_denominator_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<uint64_t>(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace shaka
|
||||||
|
|
|
@ -10,34 +10,76 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <list>
|
#include <deque>
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
|
||||||
class BandwidthEstimator {
|
class BandwidthEstimator {
|
||||||
public:
|
public:
|
||||||
/// @param num_blocks is the number of latest blocks to use. Negative values
|
/// @param num_blocks is the number of latest blocks to use. 0 uses all.
|
||||||
/// use first N blocks. 0 uses all.
|
static constexpr size_t kUseAllBlocks = 0;
|
||||||
explicit BandwidthEstimator(int num_blocks);
|
explicit BandwidthEstimator(size_t num_blocks);
|
||||||
~BandwidthEstimator();
|
~BandwidthEstimator();
|
||||||
|
|
||||||
// @param size is the size of the block in bytes. Should be positive.
|
/// @param size is the size of the block in bytes. Should be positive.
|
||||||
// @param duration is the length in seconds. 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, double duration);
|
||||||
|
|
||||||
// @return The estimate bandwidth, in bits per second, from the harmonic mean
|
/// @return The estimate bandwidth, in bits per second, from the harmonic mean
|
||||||
// of the number of blocks specified in the constructor. The value is
|
/// of the number of blocks specified in the constructor. The value is
|
||||||
// rounded up to the nearest integer.
|
/// rounded up to the nearest integer.
|
||||||
uint64_t Estimate() const;
|
uint64_t Estimate() const;
|
||||||
|
|
||||||
static const int kUseAllBlocks;
|
/// @return The max bandwidth, in bits per second, of the number of blocks
|
||||||
|
/// specified in the constructor. The value is rounded up to the
|
||||||
|
/// nearest integer.
|
||||||
|
uint64_t Max() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int num_blocks_for_estimation_;
|
BandwidthEstimator(const BandwidthEstimator&) = delete;
|
||||||
double harmonic_mean_denominator_;
|
BandwidthEstimator& operator=(const BandwidthEstimator&) = delete;
|
||||||
|
|
||||||
// This is not used when num_blocks_for_estimation_ != 0. Therefore it should
|
// A sliding queue that provide convenient functions to get the minimum value
|
||||||
// always be 0 if num_blocks_for_estimation_ != 0.
|
// and the sum when window slides.
|
||||||
size_t num_blocks_added_;
|
class SlidingQueue {
|
||||||
std::list<double> history_;
|
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<double> 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<double> min_;
|
||||||
|
};
|
||||||
|
SlidingQueue sliding_queue_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace shaka
|
||||||
|
|
||||||
#endif // MPD_BASE_BANDWIDTH_ESTIMATOR_H_
|
#endif // MPD_BASE_BANDWIDTH_ESTIMATOR_H_
|
||||||
|
|
|
@ -14,10 +14,15 @@
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const int kNumBlocksForEstimate = 5;
|
const size_t kNumBlocksForEstimate = 5;
|
||||||
const int kFirstOneBlockForEstimate = -1;
|
|
||||||
const uint64_t kBitsInByte = 8;
|
const uint64_t kBitsInByte = 8;
|
||||||
const int kEstimateRoundError = 1;
|
const int kEstimateRoundError = 1;
|
||||||
|
|
||||||
|
struct Bandwidth {
|
||||||
|
uint64_t average;
|
||||||
|
uint64_t max;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Make sure that averaging of 5 blocks works, and also when there aren't all 5
|
// Make sure that averaging of 5 blocks works, and also when there aren't all 5
|
||||||
|
@ -25,23 +30,20 @@ const int kEstimateRoundError = 1;
|
||||||
TEST(BandwidthEstimatorTest, FiveBlocksFiveBlocksAdded) {
|
TEST(BandwidthEstimatorTest, FiveBlocksFiveBlocksAdded) {
|
||||||
BandwidthEstimator be(kNumBlocksForEstimate);
|
BandwidthEstimator be(kNumBlocksForEstimate);
|
||||||
const double kDuration = 1.0;
|
const double kDuration = 1.0;
|
||||||
const uint64_t kExpectedResults[] = {
|
const Bandwidth kExpectedResults[] = {
|
||||||
// Harmonic mean of [1 * 8], [1 * 8, 2 * 8], ...
|
// 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
|
// 8 is the number of bits in a byte and 1, 2, ... is from the loop
|
||||||
// counter below.
|
// counter below.
|
||||||
// Note that these are rounded up.
|
// Note that these are rounded up.
|
||||||
8,
|
{8, 8}, {11, 2 * 8}, {14, 3 * 8}, {16, 4 * 8}, {18, 5 * 8},
|
||||||
11,
|
|
||||||
14,
|
|
||||||
16,
|
|
||||||
18
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(kNumBlocksForEstimate == arraysize(kExpectedResults),
|
static_assert(kNumBlocksForEstimate == arraysize(kExpectedResults),
|
||||||
"incorrect_number_of_expectations");
|
"incorrect_number_of_expectations");
|
||||||
for (uint64_t i = 1; i <= arraysize(kExpectedResults); ++i) {
|
for (uint64_t i = 1; i <= arraysize(kExpectedResults); ++i) {
|
||||||
be.AddBlock(i, kDuration);
|
be.AddBlock(i, kDuration);
|
||||||
EXPECT_EQ(kExpectedResults[i - 1], be.Estimate());
|
EXPECT_EQ(kExpectedResults[i - 1].average, be.Estimate());
|
||||||
|
EXPECT_EQ(kExpectedResults[i - 1].max, be.Max());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,9 +67,10 @@ TEST(BandwidthEstimatorTest, FiveBlocksNormal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_NEAR(kExptectedEstimate, be.Estimate(), kEstimateRoundError);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Average all the blocks!
|
|
||||||
TEST(BandwidthEstimatorTest, AllBlocks) {
|
TEST(BandwidthEstimatorTest, AllBlocks) {
|
||||||
BandwidthEstimator be(BandwidthEstimator::kUseAllBlocks);
|
BandwidthEstimator be(BandwidthEstimator::kUseAllBlocks);
|
||||||
const uint64_t kNumBlocksToAdd = 100;
|
const uint64_t kNumBlocksToAdd = 100;
|
||||||
|
@ -78,19 +81,39 @@ TEST(BandwidthEstimatorTest, AllBlocks) {
|
||||||
// The harmonic mean of 8, 16, ... , 800; rounded up.
|
// The harmonic mean of 8, 16, ... , 800; rounded up.
|
||||||
const uint64_t kExptectedEstimate = 155;
|
const uint64_t kExptectedEstimate = 155;
|
||||||
EXPECT_EQ(kExptectedEstimate, be.Estimate());
|
EXPECT_EQ(kExptectedEstimate, be.Estimate());
|
||||||
|
const uint64_t kMax = 100 * 8;
|
||||||
|
EXPECT_EQ(kMax, be.Max());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use only the first one.
|
TEST(BandwidthEstimatorTest, MaxWithSlidingWindow) {
|
||||||
TEST(BandwidthEstimatorTest, FirstOneBlock) {
|
BandwidthEstimator be(kNumBlocksForEstimate);
|
||||||
BandwidthEstimator be(kFirstOneBlockForEstimate);
|
const double kDuration = 1.0 * kBitsInByte;
|
||||||
const double kDuration = 11.0;
|
|
||||||
const uint64_t kExptectedEstimate = 123456;
|
|
||||||
be.AddBlock(kExptectedEstimate * kDuration / kBitsInByte, kDuration);
|
|
||||||
|
|
||||||
// Anything. Should be ignored.
|
// clang-format off
|
||||||
for (int i = 0; i < 1000; ++i)
|
const uint64_t kSizes[] = {
|
||||||
be.AddBlock(100000, 10);
|
// Sequence 1: Monotonic decreasing.
|
||||||
EXPECT_EQ(kExptectedEstimate, be.Estimate());
|
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
|
} // namespace shaka
|
||||||
|
|
|
@ -240,7 +240,7 @@ xml::scoped_xml_ptr<xmlNode> Representation::GetXml() {
|
||||||
|
|
||||||
const uint64_t bandwidth = media_info_.has_bandwidth()
|
const uint64_t bandwidth = media_info_.has_bandwidth()
|
||||||
? media_info_.bandwidth()
|
? media_info_.bandwidth()
|
||||||
: bandwidth_estimator_.Estimate();
|
: bandwidth_estimator_.Max();
|
||||||
|
|
||||||
DCHECK(!(HasVODOnlyFields(media_info_) && HasLiveOnlyFields(media_info_)));
|
DCHECK(!(HasVODOnlyFields(media_info_) && HasLiveOnlyFields(media_info_)));
|
||||||
|
|
||||||
|
|
|
@ -461,7 +461,7 @@ class SegmentTemplateTest : public RepresentationTest {
|
||||||
" </SegmentTimeline>\n"
|
" </SegmentTimeline>\n"
|
||||||
" </SegmentTemplate>\n"
|
" </SegmentTemplate>\n"
|
||||||
"</Representation>\n";
|
"</Representation>\n";
|
||||||
return base::StringPrintf(kOutputTemplate, bandwidth_estimator_.Estimate(),
|
return base::StringPrintf(kOutputTemplate, bandwidth_estimator_.Max(),
|
||||||
expected_s_elements_.c_str());
|
expected_s_elements_.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,7 +721,7 @@ class TimeShiftBufferDepthTest : public SegmentTemplateTest {
|
||||||
" </SegmentTemplate>\n"
|
" </SegmentTemplate>\n"
|
||||||
"</Representation>\n";
|
"</Representation>\n";
|
||||||
|
|
||||||
return base::StringPrintf(kOutputTemplate, bandwidth_estimator_.Estimate(),
|
return base::StringPrintf(kOutputTemplate, bandwidth_estimator_.Max(),
|
||||||
expected_start_number,
|
expected_start_number,
|
||||||
expected_s_element.c_str());
|
expected_s_element.c_str());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue