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):
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-vp9.mp4'),
self._GetStream('video', test_file='bear-640x360.mp4'),
self._GetStream('video', test_file='bear-1280x720.mp4'),
self._GetStream('audio', test_file='bear-640x360.mp4'),

View File

@ -12,7 +12,7 @@
</Representation>
</AdaptationSet>
<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"/>
<Representation id="1" bandwidth="277411" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-hevc-video.mp4</BaseURL>

View File

@ -7,7 +7,7 @@
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</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"/>
<Representation id="0" bandwidth="281671" codecs="hev1.1.6.L63.90" mimeType="video/mp4" sar="1:1">
<BaseURL>bear-640x360-hevc-video.mp4</BaseURL>
@ -21,7 +21,7 @@
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</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"/>
<Representation id="1" bandwidth="977743" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1" width="640" height="360">
<BaseURL>bear-640x360-video.mp4</BaseURL>
@ -41,7 +41,7 @@
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</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">
<BaseURL>bear-1280x720-video-trick_play_factor_1.mp4</BaseURL>
<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>-->
<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">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
<SupplementalProperty schemeIdUri="urn:mpeg:dash:adaptation-set-switching:2016" value="1"/>
<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,2"/>
<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>
<SegmentBase indexRange="1910-1977" timescale="30000">
<Initialization range="0-1909"/>
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" 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"/>
<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,1"/>
<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>
<SegmentBase indexRange="870-937" timescale="30000">
<Initialization range="0-869"/>
</SegmentBase>
</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>
<SegmentBase indexRange="869-936" timescale="30000">
<Initialization range="0-868"/>
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet id="2" contentType="audio" subsegmentStartsWithSAP="1" subsegmentAlignment="true">
<Representation id="3" bandwidth="133334" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AdaptationSet id="3" contentType="audio" subsegmentStartsWithSAP="1" subsegmentAlignment="true">
<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"/>
<BaseURL>bear-640x360-audio.mp4</BaseURL>
<SegmentBase indexRange="804-871" timescale="44100">

View File

@ -20,7 +20,7 @@
</Representation>
</AdaptationSet>
<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">
<BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL>
<SegmentBase indexRange="870-937" timescale="30000">

View File

@ -32,7 +32,7 @@
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</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">
<BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL>
<SegmentBase indexRange="1138-1205" timescale="30000">

View File

@ -32,7 +32,7 @@
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
</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">
<BaseURL>bear-640x360-video-trick_play_factor_1.mp4</BaseURL>
<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_frame_rate = false;
if (index_.has_value())
id_ = index_.value();
if (id_ && !adaptation_set.SetId(id_.value()))
return std::nullopt;
if (!adaptation_set.SetStringAttribute("contentType", content_type_))
@ -425,10 +423,7 @@ std::optional<xml::XmlNode> AdaptationSet::GetXml() {
if (!trick_play_reference_ids.empty())
trick_play_reference_ids += ' ';
CHECK(tp_adaptation_set->has_id());
trick_play_reference_ids +=
std::to_string(tp_adaptation_set->index_.has_value()
? tp_adaptation_set->index_.value()
: tp_adaptation_set->id());
trick_play_reference_ids += std::to_string(tp_adaptation_set->id());
}
if (!trick_play_reference_ids.empty() &&
!adaptation_set.AddEssentialProperty(
@ -442,9 +437,7 @@ std::optional<xml::XmlNode> AdaptationSet::GetXml() {
if (!switching_ids.empty())
switching_ids += ',';
CHECK(s_adaptation_set->has_id());
switching_ids += std::to_string(s_adaptation_set->index_.has_value()
? s_adaptation_set->index_.value()
: s_adaptation_set->id());
switching_ids += std::to_string(s_adaptation_set->id());
}
if (!switching_ids.empty() &&
!adaptation_set.AddSupplementalProperty(

View File

@ -143,6 +143,11 @@ class AdaptationSet {
/// @return true if id is set, false otherwise.
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.
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(
[](const std::unique_ptr<AdaptationSet>& adaptation_set_a,
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;
if (!adaptation_set_b->has_id())
if (!index_b)
return true;
return adaptation_set_a->id() < adaptation_set_b->id();
return index_a < index_b;
});
xml::XmlNode period("Period");