Commit 0249058c by olly Committed by Oliver Woodman

Parse Label elements for adaptation sets

Issue: #6297
PiperOrigin-RevId: 273297284
parent 904e3f8d
......@@ -5,7 +5,9 @@
* Add `Player.onPlaybackSuppressionReasonChanged` to allow listeners to
detect playbacks suppressions (e.g. audio focus loss) directly
([#6203](https://github.com/google/ExoPlayer/issues/6203)).
* Expose the raw ICY metadata through `IcyInfo`
* DASH: Support `Label` elements
([#6297](https://github.com/google/ExoPlayer/issues/6297)).
* Metadata: Expose the raw ICY metadata through `IcyInfo`
([#6476](https://github.com/google/ExoPlayer/issues/6476)).
* UI
* Setting `app:played_color` on `PlayerView` and `PlayerControlView` no longer
......
......@@ -1066,6 +1066,38 @@ public final class Format implements Parcelable {
accessibilityChannel);
}
public Format copyWithLabel(@Nullable String label) {
return new Format(
id,
label,
selectionFlags,
roleFlags,
bitrate,
codecs,
metadata,
containerMimeType,
sampleMimeType,
maxInputSize,
initializationData,
drmInitData,
subsampleOffsetUs,
width,
height,
frameRate,
rotationDegrees,
pixelWidthHeightRatio,
projectionData,
stereoMode,
colorInfo,
channelCount,
sampleRate,
pcmEncoding,
encoderDelay,
encoderPadding,
language,
accessibilityChannel);
}
public Format copyWithContainerInfo(
@Nullable String id,
@Nullable String label,
......
......@@ -313,7 +313,6 @@ public class DashManifestParser extends DefaultHandler
parseRepresentation(
xpp,
baseUrl,
label,
mimeType,
codecs,
width,
......@@ -338,6 +337,8 @@ public class DashManifestParser extends DefaultHandler
parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase, supplementalProperties);
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
} else if (XmlPullParserUtil.isStartTag(xpp, "Label")) {
label = parseLabel(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp)) {
parseAdaptationSetChild(xpp);
}
......@@ -348,7 +349,11 @@ public class DashManifestParser extends DefaultHandler
for (int i = 0; i < representationInfos.size(); i++) {
representations.add(
buildRepresentation(
representationInfos.get(i), drmSchemeType, drmSchemeDatas, inbandEventStreams));
representationInfos.get(i),
label,
drmSchemeType,
drmSchemeDatas,
inbandEventStreams));
}
return buildAdaptationSet(id, contentType, representations, accessibilityDescriptors,
......@@ -484,7 +489,6 @@ public class DashManifestParser extends DefaultHandler
protected RepresentationInfo parseRepresentation(
XmlPullParser xpp,
String baseUrl,
String label,
String adaptationSetMimeType,
String adaptationSetCodecs,
int adaptationSetWidth,
......@@ -551,7 +555,6 @@ public class DashManifestParser extends DefaultHandler
Format format =
buildFormat(
id,
label,
mimeType,
width,
height,
......@@ -572,7 +575,6 @@ public class DashManifestParser extends DefaultHandler
protected Format buildFormat(
String id,
String label,
String containerMimeType,
int width,
int height,
......@@ -596,7 +598,7 @@ public class DashManifestParser extends DefaultHandler
if (MimeTypes.isVideo(sampleMimeType)) {
return Format.createVideoContainerFormat(
id,
label,
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
......@@ -611,7 +613,7 @@ public class DashManifestParser extends DefaultHandler
} else if (MimeTypes.isAudio(sampleMimeType)) {
return Format.createAudioContainerFormat(
id,
label,
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
......@@ -634,7 +636,7 @@ public class DashManifestParser extends DefaultHandler
}
return Format.createTextContainerFormat(
id,
label,
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
......@@ -647,7 +649,7 @@ public class DashManifestParser extends DefaultHandler
}
return Format.createContainerFormat(
id,
label,
/* label= */ null,
containerMimeType,
sampleMimeType,
codecs,
......@@ -659,10 +661,14 @@ public class DashManifestParser extends DefaultHandler
protected Representation buildRepresentation(
RepresentationInfo representationInfo,
String label,
String extraDrmSchemeType,
ArrayList<SchemeData> extraDrmSchemeDatas,
ArrayList<Descriptor> extraInbandEventStreams) {
Format format = representationInfo.format;
if (label != null) {
format = format.copyWithLabel(label);
}
String drmSchemeType = representationInfo.drmSchemeType != null
? representationInfo.drmSchemeType : extraDrmSchemeType;
ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
......@@ -1076,6 +1082,32 @@ public class DashManifestParser extends DefaultHandler
return new ProgramInformation(title, source, copyright, moreInformationURL, lang);
}
/**
* Parses a Label element.
*
* @param xpp The parser from which to read.
* @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element.
* @return The parsed label.
*/
protected String parseLabel(XmlPullParser xpp) throws XmlPullParserException, IOException {
return parseText(xpp, "Label");
}
/**
* Parses a BaseURL element.
*
* @param xpp The parser from which to read.
* @param parentBaseUrl A base URL for resolving the parsed URL.
* @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element.
* @return The parsed and resolved URL.
*/
protected String parseBaseUrl(XmlPullParser xpp, String parentBaseUrl)
throws XmlPullParserException, IOException {
return UriUtil.resolve(parentBaseUrl, parseText(xpp, "BaseURL"));
}
// AudioChannelConfiguration parsing.
protected int parseAudioChannelConfiguration(XmlPullParser xpp)
......@@ -1427,10 +1459,18 @@ public class DashManifestParser extends DefaultHandler
}
}
protected static String parseBaseUrl(XmlPullParser xpp, String parentBaseUrl)
protected static String parseText(XmlPullParser xpp, String label)
throws XmlPullParserException, IOException {
xpp.next();
return UriUtil.resolve(parentBaseUrl, xpp.getText());
String text = "";
do {
xpp.next();
if (xpp.getEventType() == XmlPullParser.TEXT) {
text = xpp.getText();
} else {
maybeSkipTag(xpp);
}
} while (!XmlPullParserUtil.isEndTag(xpp, label));
return text;
}
protected static int parseInt(XmlPullParser xpp, String name, int defaultValue) {
......
<?xml version="1.0" encoding="UTF-8"?>
<MPD type="static" duration="1s" mediaPresentationDuration="PT1S">
<Period>
<SegmentTemplate startNumber="0" timescale="1000" media="sq/$Number$">
<SegmentTimeline>
<S d="1000"/>
</SegmentTimeline>
</SegmentTemplate>
<AdaptationSet id="0" mimeType="audio/mp4" subsegmentAlignment="true" label="audio label">
<Representation id="0" codecs="mp4a.40.2" audioSamplingRate="48000" bandwidth="144000">
<BaseURL>https://test.com/0</BaseURL>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" mimeType="video/mp4" subsegmentAlignment="true" label="ignored label">
<Representation id="1" codecs="avc1.4d4015" width="426" height="240" bandwidth="258000">
<BaseURL>https://test.com/1</BaseURL>
</Representation>
<Label>video label</Label>
</AdaptationSet>
</Period>
</MPD>
......@@ -40,6 +40,7 @@ public class DashManifestParserTest {
private static final String SAMPLE_MPD_UNKNOWN_MIME_TYPE = "sample_mpd_unknown_mime_type";
private static final String SAMPLE_MPD_SEGMENT_TEMPLATE = "sample_mpd_segment_template";
private static final String SAMPLE_MPD_EVENT_STREAM = "sample_mpd_event_stream";
private static final String SAMPLE_MPD_LABELS = "sample_mpd_labels";
private static final String NEXT_TAG_NAME = "Next";
private static final String NEXT_TAG = "<" + NEXT_TAG_NAME + "/>";
......@@ -173,6 +174,21 @@ public class DashManifestParserTest {
}
@Test
public void parseMediaPresentationDescription_labels() throws IOException {
DashManifestParser parser = new DashManifestParser();
DashManifest manifest =
parser.parse(
Uri.parse("https://example.com/test.mpd"),
TestUtil.getInputStream(
ApplicationProvider.getApplicationContext(), SAMPLE_MPD_LABELS));
List<AdaptationSet> adaptationSets = manifest.getPeriod(0).adaptationSets;
assertThat(adaptationSets.get(0).representations.get(0).format.label).isEqualTo("audio label");
assertThat(adaptationSets.get(1).representations.get(0).format.label).isEqualTo("video label");
}
@Test
public void parseSegmentTimeline_repeatCount() throws Exception {
DashManifestParser parser = new DashManifestParser();
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
......@@ -248,6 +264,30 @@ public class DashManifestParserTest {
}
@Test
public void parseLabel() throws Exception {
DashManifestParser parser = new DashManifestParser();
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
xpp.setInput(new StringReader("<Label>test label</Label>" + NEXT_TAG));
xpp.next();
String label = parser.parseLabel(xpp);
assertThat(label).isEqualTo("test label");
assertNextTag(xpp);
}
@Test
public void parseLabel_noText() throws Exception {
DashManifestParser parser = new DashManifestParser();
XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
xpp.setInput(new StringReader("<Label/>" + NEXT_TAG));
xpp.next();
String label = parser.parseLabel(xpp);
assertThat(label).isEqualTo("");
assertNextTag(xpp);
}
@Test
public void parseCea608AccessibilityChannel() {
assertThat(
DashManifestParser.parseCea608AccessibilityChannel(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment