Skip to content

Commit cb34246

Browse files
committed
Always sort AdaptationSets by mimeType
1 parent 5dae5b9 commit cb34246

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/manifest/DashManifestParser.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ protected Period buildPeriod(
393393
List<AdaptationSet> adaptationSets,
394394
List<EventStream> eventStreams,
395395
@Nullable Descriptor assetIdentifier) {
396+
java.util.Collections.sort(adaptationSets, (a, b) -> Integer.compare(a.type, b.type));
396397
return new Period(id, startMs, adaptationSets, eventStreams, assetIdentifier);
397398
}
398399

libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/manifest/DashManifestParserTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public class DashManifestParserTest {
5555
private static final String SAMPLE_MPD_UNKNOWN_MIME_TYPE =
5656
"media/mpd/sample_mpd_unknown_mime_type";
5757
private static final String SAMPLE_MPD_SEGMENT_TEMPLATE = "media/mpd/sample_mpd_segment_template";
58+
private static final String SAMPLE_MPD_SEGMENT_TEMPLATE_ORDER =
59+
"media/mpd/sample_mpd_segment_template_order";
5860
private static final String SAMPLE_MPD_EVENT_STREAM = "media/mpd/sample_mpd_event_stream";
5961
private static final String SAMPLE_MPD_IMAGES = "media/mpd/sample_mpd_images";
6062
private static final String SAMPLE_MPD_LABELS = "media/mpd/sample_mpd_labels";
@@ -116,6 +118,11 @@ public void parseMediaPresentationDescription_segmentTemplate() throws IOExcepti
116118
Period period = manifest.getPeriod(0);
117119
assertThat(period).isNotNull();
118120
assertThat(period.adaptationSets).hasSize(2);
121+
// AdaptationSets should be always sorted from DashManifestParser::buildPeriod by type
122+
assertThat(period.adaptationSets.get(0).type).isEqualTo(C.TRACK_TYPE_AUDIO);
123+
assertThat(period.adaptationSets.get(0).representations).hasSize(1);
124+
assertThat(period.adaptationSets.get(1).type).isEqualTo(C.TRACK_TYPE_VIDEO);
125+
assertThat(period.adaptationSets.get(1).representations).hasSize(5);
119126

120127
for (AdaptationSet adaptationSet : period.adaptationSets) {
121128
assertThat(adaptationSet).isNotNull();
@@ -132,6 +139,27 @@ public void parseMediaPresentationDescription_segmentTemplate() throws IOExcepti
132139
}
133140
}
134141

142+
@Test
143+
public void parseMediaPresentationDescription_buildPeriod() throws IOException {
144+
DashManifestParser parser = new DashManifestParser();
145+
DashManifest manifest =
146+
parser.parse(
147+
Uri.parse("https://example.com/test.mpd"),
148+
TestUtil.getInputStream(
149+
ApplicationProvider.getApplicationContext(), SAMPLE_MPD_SEGMENT_TEMPLATE_ORDER));
150+
151+
assertThat(manifest.getPeriodCount()).isEqualTo(1);
152+
153+
Period period = manifest.getPeriod(0);
154+
assertThat(period).isNotNull();
155+
assertThat(period.adaptationSets).hasSize(2);
156+
// AdaptationSets should be always sorted from DashManifestParser::buildPeriod by type
157+
assertThat(period.adaptationSets.get(0).type).isEqualTo(C.TRACK_TYPE_AUDIO);
158+
assertThat(period.adaptationSets.get(0).representations).hasSize(1);
159+
assertThat(period.adaptationSets.get(1).type).isEqualTo(C.TRACK_TYPE_VIDEO);
160+
assertThat(period.adaptationSets.get(1).representations).hasSize(5);
161+
}
162+
135163
@Test
136164
public void parseMediaPresentationDescription_eventStream() throws IOException {
137165
DashManifestParser parser = new DashManifestParser();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:yt="http://youtube.com/yt/2012/10/10" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" minBufferTime="PT1.500S" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="dynamic" availabilityStartTime="2016-10-14T17:00:17" timeShiftBufferDepth="PT7200.000S" minimumUpdatePeriod="PT2.000S" yt:earliestMediaSequence="0" yt:mpdRequestTime="2016-10-14T18:29:17.082" yt:mpdResponseTime="2016-10-14T18:29:17.194">
3+
<Period start="PT0.000S" yt:segmentIngestTime="2016-10-14T17:00:14.257">
4+
<SegmentTemplate startNumber="0" timescale="1000" media="sq/$Number$">
5+
<SegmentTimeline>
6+
<S d="2002" t="6009" r="2"/>
7+
<S d="1985"/>
8+
<S d="2000"/>
9+
</SegmentTimeline>
10+
</SegmentTemplate>
11+
<AdaptationSet id="1" mimeType="video/mp4" subsegmentAlignment="true">
12+
<Role schemeIdUri="urn:mpeg:DASH:role:2011" value="main"/>
13+
<Representation id="133" codecs="avc1.4d4015" width="426" height="240" startWithSAP="1" maxPlayoutRate="1" bandwidth="258000" frameRate="30">
14+
<BaseURL>http://redirector.googlevideo.com/videoplayback/id/BktsoMO3OMs.0/itag/133/source/yt_live_broadcast/ratebypass/yes/cmbypass/yes/mime/video%2Fmp4/live/1/gir/yes/noclen/1/signature/90154AE9C5C9D9D519CBF2E43AB0A1778375992D.40E2E855ADFB38FA7E95E168FEEEA6796B080BD7/key/dg_test0/mpd_version/5/ip/0.0.0.0/ipbits/0/expire/1476490914/sparams/ip,ipbits,expire,id,itag,source,ratebypass,cmbypass,mime,live,gir,noclen/</BaseURL>
15+
</Representation>
16+
<Representation id="134" codecs="avc1.4d401e" width="640" height="360" startWithSAP="1" maxPlayoutRate="1" bandwidth="646000" frameRate="30">
17+
<BaseURL>http://redirector.googlevideo.com/videoplayback/id/BktsoMO3OMs.0/itag/134/source/yt_live_broadcast/ratebypass/yes/cmbypass/yes/mime/video%2Fmp4/live/1/gir/yes/noclen/1/signature/5C094AEFDCEB1A4D2F3C05F8BD095C336EF0E1C3.7AE6B9951B0237AAE6F031927AACAC4974BAFFAA/key/dg_test0/mpd_version/5/ip/0.0.0.0/ipbits/0/expire/1476490914/sparams/ip,ipbits,expire,id,itag,source,ratebypass,cmbypass,mime,live,gir,noclen/</BaseURL>
18+
</Representation>
19+
<Representation id="135" codecs="avc1.4d401f" width="854" height="480" startWithSAP="1" maxPlayoutRate="1" bandwidth="1171000" frameRate="30">
20+
<BaseURL>http://redirector.googlevideo.com/videoplayback/id/BktsoMO3OMs.0/itag/135/source/yt_live_broadcast/ratebypass/yes/cmbypass/yes/mime/video%2Fmp4/live/1/gir/yes/noclen/1/signature/1F7660CA4E5B4AE4D60E18795680E34CDD2EF3C9.800B0A1D5F490DE142CCF4C88C64FD21D42129/key/dg_test0/mpd_version/5/ip/0.0.0.0/ipbits/0/expire/1476490914/sparams/ip,ipbits,expire,id,itag,source,ratebypass,cmbypass,mime,live,gir,noclen/</BaseURL>
21+
</Representation>
22+
<Representation id="160" codecs="avc1.42c00b" width="256" height="144" startWithSAP="1" maxPlayoutRate="1" bandwidth="124000" frameRate="30">
23+
<BaseURL>http://redirector.googlevideo.com/videoplayback/id/BktsoMO3OMs.0/itag/160/source/yt_live_broadcast/ratebypass/yes/cmbypass/yes/mime/video%2Fmp4/live/1/gir/yes/noclen/1/signature/94EB61673784DF0C4237A1A866F2E171C8A64ADB.AEC00AA06C2278FEA8702FB62693B70D8977F46C/key/dg_test0/mpd_version/5/ip/0.0.0.0/ipbits/0/expire/1476490914/sparams/ip,ipbits,expire,id,itag,source,ratebypass,cmbypass,mime,live,gir,noclen/</BaseURL>
24+
</Representation>
25+
<Representation id="136" codecs="avc1.4d401f" width="1280" height="720" startWithSAP="1" maxPlayoutRate="1" bandwidth="2326000" frameRate="30">
26+
<BaseURL>http://redirector.googlevideo.com/videoplayback/id/BktsoMO3OMs.0/itag/136/source/yt_live_broadcast/ratebypass/yes/cmbypass/yes/mime/video%2Fmp4/live/1/gir/yes/noclen/1/signature/6D8C34FC30A1F1A4F700B61180D1C4CCF6274844.29EBCB4A837DE626C52C66CF650519E61C2FF0BF/key/dg_test0/mpd_version/5/ip/0.0.0.0/ipbits/0/expire/1476490914/sparams/ip,ipbits,expire,id,itag,source,ratebypass,cmbypass,mime,live,gir,noclen/</BaseURL>
27+
</Representation>
28+
</AdaptationSet>
29+
<AdaptationSet id="0" mimeType="audio/mp4" subsegmentAlignment="true">
30+
<Role schemeIdUri="urn:mpeg:DASH:role:2011" value="main"/>
31+
<Representation id="140" codecs="mp4a.40.2" audioSamplingRate="48000" startWithSAP="1" bandwidth="144000">
32+
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
33+
<BaseURL>http://redirector.googlevideo.com/videoplayback/id/BktsoMO3OMs.0/itag/140/source/yt_live_broadcast/ratebypass/yes/cmbypass/yes/mime/audio%2Fmp4/live/1/gir/yes/noclen/1/signature/B5137EA0CC278C07DD056D204E863CC81EDEB39E.1AD5D242EBC94922EDA7165353A89A5E08A4103A/key/dg_test0/mpd_version/5/ip/0.0.0.0/ipbits/0/expire/1476490914/sparams/ip,ipbits,expire,id,itag,source,ratebypass,cmbypass,mime,live,gir,noclen/</BaseURL>
34+
</Representation>
35+
</AdaptationSet>
36+
</Period>
37+
</MPD>

0 commit comments

Comments
 (0)