fix: adaptation set IDs were referenced by lowest representation ID (#1394)

After change to add forced command line ordering adaptation set IDs in
places were referenced by their sort index (the minimum representation
index they contained).

Instead always refer to adaptation sets by their own ID, and use the
index only as an optional sort key.

Fixes #1393
This commit is contained in:
Cosmin Stejerean 2024-05-10 17:24:04 -07:00 committed by GitHub
parent 52647b900c
commit 94db9c9db3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 47 additions and 28 deletions

View File

@ -1704,7 +1704,9 @@ class PackagerFunctionalTest(PackagerAppTest):
def testAllowCodecSwitching(self): def testAllowCodecSwitching(self):
streams = [ streams = [
self._GetStream('video', test_file='bear-1280x720-hevc.mp4'),
self._GetStream('video', test_file='bear-640x360-hevc.mp4'), self._GetStream('video', test_file='bear-640x360-hevc.mp4'),
self._GetStream('video', test_file='bear-640x360-vp9.mp4'),
self._GetStream('video', test_file='bear-640x360.mp4'), self._GetStream('video', test_file='bear-640x360.mp4'),
self._GetStream('video', test_file='bear-1280x720.mp4'), self._GetStream('video', test_file='bear-1280x720.mp4'),
self._GetStream('audio', test_file='bear-640x360.mp4'), self._GetStream('audio', test_file='bear-640x360.mp4'),

View File

@ -12,7 +12,7 @@
</Representation> </Representation>
</AdaptationSet> </AdaptationSet>
<AdaptationSet id="1" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9"> <AdaptationSet id="1" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="2"/> <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="0"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/> <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation id="1" bandwidth="277411" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1"> <Representation id="1" bandwidth="277411" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-hevc-video.mp4</BaseURL> <BaseURL>bear-640x360-hevc-video.mp4</BaseURL>

View File

@ -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>
<SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="1"/> <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="0"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/> <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation id="0" bandwidth="281671" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1"> <Representation id="0" bandwidth="281671" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-hevc-video.mp4</BaseURL> <BaseURL>bear-640x360-hevc-video.mp4</BaseURL>
@ -21,7 +21,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>
<SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="0"/> <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="2"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/> <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation id="1" bandwidth="977743" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360"> <Representation id="1" bandwidth="977743" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360">
<BaseURL>bear-640x360-video.mp4</BaseURL> <BaseURL>bear-640x360-video.mp4</BaseURL>
@ -41,7 +41,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>
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="1"/> <EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
<Representation id="3" bandwidth="470530" codecs="avc1.64001f" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false"> <Representation id="3" bandwidth="470530" codecs="avc1.64001f" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false">
<BaseURL>bear-1280x720-video-trick_play_factor_1.mp4</BaseURL> <BaseURL>bear-1280x720-video-trick_play_factor_1.mp4</BaseURL>
<SegmentBase indexRange="1136-1203" timescale="30000"> <SegmentBase indexRange="1136-1203" timescale="30000">

View File

@ -2,34 +2,50 @@
<!--Generated with https://github.com/shaka-project/shaka-packager version <tag>-<hash>-<test>--> <!--Generated with https://github.com/shaka-project/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.8028S"> <MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.8028S">
<Period id="0"> <Period id="0">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9"> <AdaptationSet id="0" contentType="video" maxWidth="1280" maxHeight="720" frameRate="30000/1001" par="16:9">
<SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="1"/> <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="1,2"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/> <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation id="0" bandwidth="277411" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1"> <Representation id="0" bandwidth="564516" codecs="hev1.1.6.L93.90" mimeType="video/mp4" sar="1:1" width="1280" height="720">
<BaseURL>bear-1280x720-hevc-video.mp4</BaseURL>
<SegmentBase indexRange="3283-3350" timescale="30000">
<Initialization range="0-3282"/>
</SegmentBase>
</Representation>
<Representation id="1" bandwidth="277411" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1" width="640" height="360">
<BaseURL>bear-640x360-hevc-video.mp4</BaseURL> <BaseURL>bear-640x360-hevc-video.mp4</BaseURL>
<SegmentBase indexRange="1910-1977" timescale="30000"> <SegmentBase indexRange="1910-1977" timescale="30000">
<Initialization range="0-1909"/> <Initialization range="0-1909"/>
</SegmentBase> </SegmentBase>
</Representation> </Representation>
</AdaptationSet> </AdaptationSet>
<AdaptationSet id="1" contentType="video" maxWidth="1280" maxHeight="720" frameRate="30000/1001" subsegmentAlignment="true" par="16:9"> <AdaptationSet id="1" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="0"/> <SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="0,1"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/> <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation id="1" bandwidth="973483" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360"> <Representation id="2" bandwidth="631481" codecs="vp09.00.21.08.00.02.02.02.00" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-vp9-video.mp4</BaseURL>
<SegmentBase indexRange="804-871" timescale="30000">
<Initialization range="0-803"/>
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet id="2" contentType="video" maxWidth="1280" maxHeight="720" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="0,2"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<Representation id="3" bandwidth="973483" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360">
<BaseURL>bear-640x360-video.mp4</BaseURL> <BaseURL>bear-640x360-video.mp4</BaseURL>
<SegmentBase indexRange="870-937" timescale="30000"> <SegmentBase indexRange="870-937" timescale="30000">
<Initialization range="0-869"/> <Initialization range="0-869"/>
</SegmentBase> </SegmentBase>
</Representation> </Representation>
<Representation id="2" bandwidth="2627285" codecs="avc1.64001f" mimeType="video/mp4" sar="1:1" width="1280" height="720"> <Representation id="4" bandwidth="2627285" codecs="avc1.64001f" mimeType="video/mp4" sar="1:1" width="1280" height="720">
<BaseURL>bear-1280x720-video.mp4</BaseURL> <BaseURL>bear-1280x720-video.mp4</BaseURL>
<SegmentBase indexRange="869-936" timescale="30000"> <SegmentBase indexRange="869-936" timescale="30000">
<Initialization range="0-868"/> <Initialization range="0-868"/>
</SegmentBase> </SegmentBase>
</Representation> </Representation>
</AdaptationSet> </AdaptationSet>
<AdaptationSet id="2" contentType="audio" subsegmentStartsWithSAP="1" subsegmentAlignment="true"> <AdaptationSet id="3" contentType="audio" subsegmentStartsWithSAP="1" subsegmentAlignment="true">
<Representation id="3" bandwidth="133334" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100"> <Representation id="5" bandwidth="133334" 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"/>
<BaseURL>bear-640x360-audio.mp4</BaseURL> <BaseURL>bear-640x360-audio.mp4</BaseURL>
<SegmentBase indexRange="804-871" timescale="44100"> <SegmentBase indexRange="804-871" timescale="44100">

View File

@ -20,7 +20,7 @@
</Representation> </Representation>
</AdaptationSet> </AdaptationSet>
<AdaptationSet id="2" contentType="video" width="640" height="360" frameRate="30000/30030" subsegmentAlignment="true" par="16:9"> <AdaptationSet id="2" contentType="video" width="640" height="360" frameRate="30000/30030" subsegmentAlignment="true" par="16:9">
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="1"/> <EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
<Representation id="2" bandwidth="211545" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false"> <Representation id="2" bandwidth="211545" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false">
<BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL> <BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL>
<SegmentBase indexRange="870-937" timescale="30000"> <SegmentBase indexRange="870-937" timescale="30000">

View File

@ -32,7 +32,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>
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="1"/> <EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
<Representation id="2" bandwidth="212297" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false"> <Representation id="2" bandwidth="212297" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" maxPlayoutRate="30" codingDependency="false">
<BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL> <BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL>
<SegmentBase indexRange="1138-1205" timescale="30000"> <SegmentBase indexRange="1138-1205" timescale="30000">

View File

@ -32,7 +32,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>
<EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="1"/> <EssentialProperty schemeIdUri="http://dashif.org/guidelines/trickmode" value="0"/>
<Representation id="2" bandwidth="212297" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/30030" maxPlayoutRate="30" codingDependency="false"> <Representation id="2" bandwidth="212297" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" frameRate="30000/30030" maxPlayoutRate="30" codingDependency="false">
<BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL> <BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL>
<SegmentBase indexRange="1138-1205" timescale="30000"> <SegmentBase indexRange="1138-1205" timescale="30000">

Binary file not shown.

Binary file not shown.

View File

@ -328,8 +328,6 @@ std::optional<xml::XmlNode> AdaptationSet::GetXml() {
bool suppress_representation_height = false; bool suppress_representation_height = false;
bool suppress_representation_frame_rate = false; bool suppress_representation_frame_rate = false;
if (index_.has_value())
id_ = index_.value();
if (id_ && !adaptation_set.SetId(id_.value())) if (id_ && !adaptation_set.SetId(id_.value()))
return std::nullopt; return std::nullopt;
if (!adaptation_set.SetStringAttribute("contentType", content_type_)) if (!adaptation_set.SetStringAttribute("contentType", content_type_))
@ -425,10 +423,7 @@ std::optional<xml::XmlNode> AdaptationSet::GetXml() {
if (!trick_play_reference_ids.empty()) if (!trick_play_reference_ids.empty())
trick_play_reference_ids += ' '; trick_play_reference_ids += ' ';
CHECK(tp_adaptation_set->has_id()); CHECK(tp_adaptation_set->has_id());
trick_play_reference_ids += trick_play_reference_ids += std::to_string(tp_adaptation_set->id());
std::to_string(tp_adaptation_set->index_.has_value()
? tp_adaptation_set->index_.value()
: tp_adaptation_set->id());
} }
if (!trick_play_reference_ids.empty() && if (!trick_play_reference_ids.empty() &&
!adaptation_set.AddEssentialProperty( !adaptation_set.AddEssentialProperty(
@ -442,9 +437,7 @@ std::optional<xml::XmlNode> AdaptationSet::GetXml() {
if (!switching_ids.empty()) if (!switching_ids.empty())
switching_ids += ','; switching_ids += ',';
CHECK(s_adaptation_set->has_id()); CHECK(s_adaptation_set->has_id());
switching_ids += std::to_string(s_adaptation_set->index_.has_value() switching_ids += std::to_string(s_adaptation_set->id());
? s_adaptation_set->index_.value()
: s_adaptation_set->id());
} }
if (!switching_ids.empty() && if (!switching_ids.empty() &&
!adaptation_set.AddSupplementalProperty( !adaptation_set.AddSupplementalProperty(

View File

@ -143,6 +143,11 @@ class AdaptationSet {
/// @return true if id is set, false otherwise. /// @return true if id is set, false otherwise.
bool has_id() const { return static_cast<bool>(id_); } bool has_id() const { return static_cast<bool>(id_); }
/// @return true if id is set, false otherwise.
std::optional<uint32_t> SortIndex() const {
return index_.has_value() ? index_ : id_;
}
// Must be unique in the Period. // Must be unique in the Period.
uint32_t id() const { return id_.value(); } uint32_t id() const { return id_.value(); }

View File

@ -107,11 +107,14 @@ std::optional<xml::XmlNode> Period::GetXml(bool output_period_duration) {
adaptation_sets_.sort( adaptation_sets_.sort(
[](const std::unique_ptr<AdaptationSet>& adaptation_set_a, [](const std::unique_ptr<AdaptationSet>& adaptation_set_a,
const std::unique_ptr<AdaptationSet>& adaptation_set_b) { const std::unique_ptr<AdaptationSet>& adaptation_set_b) {
if (!adaptation_set_a->has_id()) auto index_a = adaptation_set_a->SortIndex();
auto index_b = adaptation_set_b->SortIndex();
if (!index_a)
return false; return false;
if (!adaptation_set_b->has_id()) if (!index_b)
return true; return true;
return adaptation_set_a->id() < adaptation_set_b->id(); return index_a < index_b;
}); });
xml::XmlNode period("Period"); xml::XmlNode period("Period");