diff --git a/packager/mpd/base/xml/xml_node.cc b/packager/mpd/base/xml/xml_node.cc index 5143518366..379155d9fd 100644 --- a/packager/mpd/base/xml/xml_node.cc +++ b/packager/mpd/base/xml/xml_node.cc @@ -24,6 +24,12 @@ DEFINE_bool(segment_template_constant_duration, "Generates SegmentTemplate@duration if all segments except the " "last one has the same duration if this flag is set to true."); +DEFINE_bool(dash_add_last_segment_number_when_needed, + false, + "Adds a Supplemental Descriptor with @schemeIdUri " + "set to http://dashif.org/guidelines/last-segment-number with " + "the @value set to the last segment number."); + namespace shaka { using xml::XmlNode; @@ -429,6 +435,15 @@ bool RepresentationXmlNode::AddLiveOnlyInfo( if (IsTimelineConstantDuration(segment_infos, start_number)) { segment_template.SetIntegerAttribute("duration", segment_infos.front().duration); + if (FLAGS_dash_add_last_segment_number_when_needed) { + uint32_t last_segment_number = start_number - 1; + for (const auto& segment_info_element : segment_infos) + last_segment_number += segment_info_element.repeat + 1; + + AddSupplementalProperty( + "http://dashif.org/guidelines/last-segment-number", + std::to_string(last_segment_number)); + } } else { XmlNode segment_timeline("SegmentTimeline"); if (!PopulateSegmentTimeline(segment_infos, &segment_timeline) || diff --git a/packager/mpd/base/xml/xml_node_unittest.cc b/packager/mpd/base/xml/xml_node_unittest.cc index 558284503c..ec2abf83f1 100644 --- a/packager/mpd/base/xml/xml_node_unittest.cc +++ b/packager/mpd/base/xml/xml_node_unittest.cc @@ -18,6 +18,7 @@ #include "packager/mpd/test/xml_compare.h" DECLARE_bool(segment_template_constant_duration); +DECLARE_bool(dash_add_last_segment_number_when_needed); using ::testing::ElementsAre; @@ -397,5 +398,31 @@ TEST_F(LiveSegmentTimelineTest, TwoSegmentInfoWithGap) { "")); } +TEST_F(LiveSegmentTimelineTest, LastSegmentNumberSupplementalProperty) { + const uint32_t kStartNumber = 1; + const uint64_t kStartTime = 0; + const uint64_t kDuration = 100; + const uint64_t kRepeat = 9; + + std::list segment_infos = { + {kStartTime, kDuration, kRepeat}, + }; + RepresentationXmlNode representation; + FLAGS_dash_add_last_segment_number_when_needed = true; + + ASSERT_TRUE( + representation.AddLiveOnlyInfo(media_info_, segment_infos, kStartNumber)); + + EXPECT_THAT( + representation.GetRawPtr(), + XmlNodeEqual("" + "" + " " + "")); + FLAGS_dash_add_last_segment_number_when_needed = false; +} + } // namespace xml } // namespace shaka