From d687ad1ed00da260c4f4e5169b042ef4291052a0 Mon Sep 17 00:00:00 2001 From: Caitlin O'Callaghan <38890251+CaitlinOCallaghan@users.noreply.github.com> Date: Wed, 5 Jul 2023 23:33:51 +0200 Subject: [PATCH] fix: Low Latency DASH: include the "availabilityTimeComplete=false" attribute (#1198) # Low Latency DASH - `availabilityTimeComplete=false` Low Latency DASH manifests generated by Packager were missing the attribute `availabilityTimeComplete`. As per the [DASH specs](https://dashif.org/docs/CR-Low-Latency-Live-r8.pdf): **_the AdaptationSet@availabilityTimeCompleteshould be present and be set to 'FALSE'_** ## The Issue The missing attribute caused ULL streams from Shaka Packager to no longer be compatible with DASH.js. Previous versions of DASH.js allowed users to specify ULL mode when initializing the player. However, the most recent releases of DASH.js automatically detect ULL by scanning the manifest for ULL specific attributes. Although there are many attributes only associated with ULL, [DASH.js only greps for `availabilityTimeComplete` in its detection logic](https://github.com/Dash-Industry-Forum/dash.js/blob/development/src/streaming/controllers/PlaybackController.js#L792-L805). Because of the missing attribute in Packager and the limited ULL verification criteria by DASH.js, Packager streams were not being treated as low latency streams by DASH.js. ## Testing ### Unit Testing `./mpd_unittest --gtest_filter="SegmentTemplateTest.OneSegmentLowLatency"` ` ./mpd_unittest --gtest_filter="LowLatencySegmentTest.LowLatencySegmentTemplate"` ### Manual Testing - Created a low latency stream with Shaka Packager - Observed the expected `availabilityTimeComplete=false` attribute in the generated DASH manifest. --- packager/mpd/base/representation_unittest.cc | 4 ++-- packager/mpd/base/xml/xml_node.cc | 5 +++++ packager/mpd/base/xml/xml_node_unittest.cc | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packager/mpd/base/representation_unittest.cc b/packager/mpd/base/representation_unittest.cc index 03f4e4db57e..42a65872a66 100644 --- a/packager/mpd/base/representation_unittest.cc +++ b/packager/mpd/base/representation_unittest.cc @@ -559,8 +559,8 @@ TEST_F(SegmentTemplateTest, OneSegmentLowLatency) { " width=\"720\" height=\"480\" frameRate=\"10/5\">\n" " \n" + " availabilityTimeComplete=\"false\" initialization=\"init.mp4\" " + " media=\"$Time$.mp4\" startNumber=\"1\"/>\n" "\n"; EXPECT_THAT(representation_->GetXml(), XmlNodeEqual(kOutputTemplate)); } diff --git a/packager/mpd/base/xml/xml_node.cc b/packager/mpd/base/xml/xml_node.cc index a5630fca081..1a1ef64f94c 100644 --- a/packager/mpd/base/xml/xml_node.cc +++ b/packager/mpd/base/xml/xml_node.cc @@ -483,6 +483,11 @@ bool RepresentationXmlNode::AddLiveOnlyInfo( "availabilityTimeOffset", media_info.availability_time_offset())); } + if (low_latency_dash_mode) { + RCHECK(segment_template.SetStringAttribute("availabilityTimeComplete", + "false")); + } + if (media_info.has_init_segment_url()) { RCHECK(segment_template.SetStringAttribute("initialization", media_info.init_segment_url())); diff --git a/packager/mpd/base/xml/xml_node_unittest.cc b/packager/mpd/base/xml/xml_node_unittest.cc index da0216e2493..fd0efe394d8 100644 --- a/packager/mpd/base/xml/xml_node_unittest.cc +++ b/packager/mpd/base/xml/xml_node_unittest.cc @@ -752,6 +752,7 @@ TEST_F(LowLatencySegmentTest, LowLatencySegmentTemplate) { XmlNodeEqual("" " "