stream.dash: respect the manifest's minBufferTime

Don't allow the manifest's `suggestedPresentationDelay` to be lower than
the `minBufferTime` value.
This commit is contained in:
bastimeyer 2023-10-13 13:27:11 +02:00 committed by Sebastian Meyer
parent ebcf335934
commit a23bb617ad
3 changed files with 44 additions and 2 deletions

View File

@ -292,6 +292,8 @@ class MPD(MPDNode):
parent: None # type: ignore[assignment]
timelines: Dict[TTimelineIdent, int]
DEFAULT_MINBUFFERTIME = 3.0
def __init__(self, *args, url: Optional[str] = None, **kwargs) -> None:
# top level has no parent
kwargs["root"] = self
@ -350,9 +352,12 @@ class MPD(MPDNode):
self.suggestedPresentationDelay = self.attr(
"suggestedPresentationDelay",
parser=MPDParsers.duration(self.publishTime),
# if there is no delay, use a delay of 3 seconds
# if there is no delay, use a delay of 3 seconds, but respect the manifest's minBufferTime
# TODO: add a customizable parameter for this
default=timedelta(seconds=3),
default=timedelta(seconds=max(
self.DEFAULT_MINBUFFERTIME,
self.minBufferTime.total_seconds(),
)),
)
# parse children

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<MPD
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:mpeg:dash:schema:mpd:2011"
xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
profiles="urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash-if-simple"
type="dynamic"
availabilityStartTime="1970-01-01T00:00:00Z"
publishTime="2000-01-01T00:00:00Z"
maxSegmentDuration="PT5S"
minBufferTime="PT5S"
>
<Period id="p0" start="PT0S">
<AdaptationSet mimeType="video/mp4" segmentAlignment="true" startWithSAP="1">
<SegmentTemplate initialization="$RepresentationID$_init.mp4" media="$RepresentationID$_t$Time$.m4s" timescale="90000">
<SegmentTimeline>
<S t="152740179303376" d="360000" r="899"/>
</SegmentTimeline>
</SegmentTemplate>
<Representation id="V0" bandwidth="1255000" codecs="avc1.640028" frameRate="25" width="1920" height="1080" sar="1:1"/>
<Representation id="V1" bandwidth="535000" codecs="avc1.64001f" frameRate="25" width="1280" height="720" sar="1:1"/>
<Representation id="V2" bandwidth="353000" codecs="avc1.4d401f" frameRate="25" width="960" height="540" sar="1:1"/>
<Representation id="V3" bandwidth="213000" codecs="avc1.4d401e" frameRate="25" width="768" height="432" sar="1:1"/>
<Representation id="V4" bandwidth="157000" codecs="avc1.4d401e" frameRate="25" width="640" height="360" sar="1:1"/>
</AdaptationSet>
</Period>
</MPD>

View File

@ -112,6 +112,16 @@ class TestMPDParsers:
class TestMPDParser:
@pytest.mark.parametrize(("min_buffer_time", "expected"), [
pytest.param("PT1S", 3.0, id="minBufferTime lower than suggestedPresentationDelay"),
pytest.param("PT5S", 5.0, id="minBufferTime greater than suggestedPresentationDelay"),
])
def test_suggested_presentation_delay(self, min_buffer_time: str, expected: float):
with xml("dash/test_suggested_presentation_delay.mpd") as mpd_xml:
mpd_xml.attrib["minBufferTime"] = min_buffer_time
mpd = MPD(mpd_xml, base_url="http://test/", url="http://test/manifest.mpd")
assert mpd.suggestedPresentationDelay.total_seconds() == expected
def test_no_segment_list_or_template(self):
with xml("dash/test_no_segment_list_or_template.mpd") as mpd_xml:
mpd = MPD(mpd_xml, base_url="http://test/", url="http://test/manifest.mpd")