Skip to content

Commit

Permalink
Parse SupplementalProperty elements in DASH adaptation sets
Browse files Browse the repository at this point in the history
This will be used to merge adaptation sets that are marked for
seamless switching into single TrackGroups in DashMediaSource.

Issue: #2431

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=157209358
  • Loading branch information
ojw28 committed May 31, 2017
1 parent 5092efe commit 9737046
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private static Period newPeriod(AdaptationSet... adaptationSets) {
}

private static AdaptationSet newAdaptationSets(Representation... representations) {
return new AdaptationSet(0, C.TRACK_TYPE_VIDEO, Arrays.asList(representations), null);
return new AdaptationSet(0, C.TRACK_TYPE_VIDEO, Arrays.asList(representations), null, null);
}

private static Representation newRepresentations(DrmInitData drmInitData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ public void testParseCea708AccessibilityChannel() {
buildCea708AccessibilityDescriptors("Wrong format")));
}

private static List<SchemeValuePair> buildCea608AccessibilityDescriptors(String value) {
return Collections.singletonList(new SchemeValuePair("urn:scte:dash:cc:cea-608:2015", value));
private static List<Descriptor> buildCea608AccessibilityDescriptors(String value) {
return Collections.singletonList(new Descriptor("urn:scte:dash:cc:cea-608:2015", value, null));
}

private static List<SchemeValuePair> buildCea708AccessibilityDescriptors(String value) {
return Collections.singletonList(new SchemeValuePair("urn:scte:dash:cc:cea-708:2015", value));
private static List<Descriptor> buildCea708AccessibilityDescriptors(String value) {
return Collections.singletonList(new Descriptor("urn:scte:dash:cc:cea-708:2015", value, null));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
public class DashManifestTest extends TestCase {

private static final UtcTimingElement DUMMY_UTC_TIMING = new UtcTimingElement("", "");
private static final List<SchemeValuePair> DUMMY_ACCESSIBILITY_DESCRIPTORS =
Collections.emptyList();
private static final SingleSegmentBase DUMMY_SEGMENT_BASE = new SingleSegmentBase();
private static final Format DUMMY_FORMAT = Format.createSampleFormat("", "", 0);

Expand Down Expand Up @@ -190,8 +188,7 @@ private static Period newPeriod(String id, int startMs, AdaptationSet... adaptat
}

private static AdaptationSet newAdaptationSet(int seed, Representation... representations) {
return new AdaptationSet(++seed, ++seed, Arrays.asList(representations),
DUMMY_ACCESSIBILITY_DESCRIPTORS);
return new AdaptationSet(++seed, ++seed, Arrays.asList(representations), null, null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream.EmbeddedSampleStream;
import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.Descriptor;
import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.source.dash.manifest.SchemeValuePair;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
Expand Down Expand Up @@ -319,9 +319,9 @@ private static boolean hasEventMessageTrack(AdaptationSet adaptationSet) {
}

private static boolean hasCea608Track(AdaptationSet adaptationSet) {
List<SchemeValuePair> descriptors = adaptationSet.accessibilityDescriptors;
List<Descriptor> descriptors = adaptationSet.accessibilityDescriptors;
for (int i = 0; i < descriptors.size(); i++) {
SchemeValuePair descriptor = descriptors.get(i);
Descriptor descriptor = descriptors.get(i);
if ("urn:scte:dash:cc:cea-608:2015".equals(descriptor.schemeIdUri)) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,31 +41,40 @@ public class AdaptationSet {
public final int type;

/**
* The {@link Representation}s in the adaptation set.
* {@link Representation}s in the adaptation set.
*/
public final List<Representation> representations;

/**
* The accessibility descriptors in the adaptation set.
* Accessibility descriptors in the adaptation set.
*/
public final List<SchemeValuePair> accessibilityDescriptors;
public final List<Descriptor> accessibilityDescriptors;

/**
* Supplemental properties in the adaptation set.
*/
public final List<Descriptor> supplementalProperties;

/**
* @param id A non-negative identifier for the adaptation set that's unique in the scope of its
* containing period, or {@link #ID_UNSET} if not specified.
* @param type The type of the adaptation set. One of the {@link com.google.android.exoplayer2.C}
* {@code TRACK_TYPE_*} constants.
* @param representations The {@link Representation}s in the adaptation set.
* @param accessibilityDescriptors The accessibility descriptors in the adaptation set.
* @param representations {@link Representation}s in the adaptation set.
* @param accessibilityDescriptors Accessibility descriptors in the adaptation set.
* @param supplementalProperties Supplemental properties in the adaptation set.
*/
public AdaptationSet(int id, int type, List<Representation> representations,
List<SchemeValuePair> accessibilityDescriptors) {
List<Descriptor> accessibilityDescriptors, List<Descriptor> supplementalProperties) {
this.id = id;
this.type = type;
this.representations = Collections.unmodifiableList(representations);
this.accessibilityDescriptors = accessibilityDescriptors == null
? Collections.<SchemeValuePair>emptyList()
? Collections.<Descriptor>emptyList()
: Collections.unmodifiableList(accessibilityDescriptors);
this.supplementalProperties = supplementalProperties == null
? Collections.<Descriptor>emptyList()
: Collections.unmodifiableList(supplementalProperties);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ private static ArrayList<AdaptationSet> copyAdaptationSets(
} while(key.periodIndex == periodIndex && key.adaptationSetIndex == adaptationSetIndex);

copyAdaptationSets.add(new AdaptationSet(adaptationSet.id, adaptationSet.type,
copyRepresentations, adaptationSet.accessibilityDescriptors));
copyRepresentations, adaptationSet.accessibilityDescriptors,
adaptationSet.supplementalProperties));
} while(key.periodIndex == periodIndex);
// Add back the last key which doesn't belong to the period being processed
keys.addFirst(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,9 @@ protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", Format.NO_VALUE);
String language = xpp.getAttributeValue(null, "lang");
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
ArrayList<SchemeValuePair> inbandEventStreams = new ArrayList<>();
ArrayList<SchemeValuePair> accessibilityDescriptors = new ArrayList<>();
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();
ArrayList<Descriptor> accessibilityDescriptors = new ArrayList<>();
ArrayList<Descriptor> supplementalProperties = new ArrayList<>();
List<RepresentationInfo> representationInfos = new ArrayList<>();
@C.SelectionFlags int selectionFlags = 0;

Expand All @@ -265,7 +266,9 @@ protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
} else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) {
audioChannels = parseAudioChannelConfiguration(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Accessibility")) {
accessibilityDescriptors.add(parseAccessibility(xpp));
accessibilityDescriptors.add(parseDescriptor(xpp, "Accessibility"));
} else if (XmlPullParserUtil.isStartTag(xpp, "SupplementalProperty")) {
supplementalProperties.add(parseDescriptor(xpp, "SupplementalProperty"));
} else if (XmlPullParserUtil.isStartTag(xpp, "Representation")) {
RepresentationInfo representationInfo = parseRepresentation(xpp, baseUrl, mimeType, codecs,
width, height, frameRate, audioChannels, audioSamplingRate, language,
Expand All @@ -280,7 +283,7 @@ protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
inbandEventStreams.add(parseInbandEventStream(xpp));
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
} else if (XmlPullParserUtil.isStartTag(xpp)) {
parseAdaptationSetChild(xpp);
}
Expand All @@ -293,12 +296,15 @@ protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
drmSchemeDatas, inbandEventStreams));
}

return buildAdaptationSet(id, contentType, representations, accessibilityDescriptors);
return buildAdaptationSet(id, contentType, representations, accessibilityDescriptors,
supplementalProperties);
}

protected AdaptationSet buildAdaptationSet(int id, int contentType,
List<Representation> representations, List<SchemeValuePair> accessibilityDescriptors) {
return new AdaptationSet(id, contentType, representations, accessibilityDescriptors);
List<Representation> representations, List<Descriptor> accessibilityDescriptors,
List<Descriptor> supplementalProperties) {
return new AdaptationSet(id, contentType, representations, accessibilityDescriptors,
supplementalProperties);
}

protected int parseContentType(XmlPullParser xpp) {
Expand Down Expand Up @@ -366,32 +372,6 @@ protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullPar
: null;
}

/**
* Parses an InbandEventStream 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 A {@link SchemeValuePair} parsed from the element.
*/
protected SchemeValuePair parseInbandEventStream(XmlPullParser xpp)
throws XmlPullParserException, IOException {
return parseSchemeValuePair(xpp, "InbandEventStream");
}

/**
* Parses an Accessibility 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 A {@link SchemeValuePair} parsed from the element.
*/
protected SchemeValuePair parseAccessibility(XmlPullParser xpp)
throws XmlPullParserException, IOException {
return parseSchemeValuePair(xpp, "Accessibility");
}

/**
* Parses a Role element.
*
Expand Down Expand Up @@ -429,7 +409,7 @@ protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseU
int adaptationSetHeight, float adaptationSetFrameRate, int adaptationSetAudioChannels,
int adaptationSetAudioSamplingRate, String adaptationSetLanguage,
@C.SelectionFlags int adaptationSetSelectionFlags,
List<SchemeValuePair> adaptationSetAccessibilityDescriptors, SegmentBase segmentBase)
List<Descriptor> adaptationSetAccessibilityDescriptors, SegmentBase segmentBase)
throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id");
int bandwidth = parseInt(xpp, "bandwidth", Format.NO_VALUE);
Expand All @@ -442,7 +422,7 @@ protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseU
int audioChannels = adaptationSetAudioChannels;
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", adaptationSetAudioSamplingRate);
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
ArrayList<SchemeValuePair> inbandEventStreams = new ArrayList<>();
ArrayList<Descriptor> inbandEventStreams = new ArrayList<>();

boolean seenFirstBaseUrl = false;
do {
Expand All @@ -466,7 +446,7 @@ protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseU
drmSchemeDatas.add(contentProtection);
}
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
inbandEventStreams.add(parseInbandEventStream(xpp));
inbandEventStreams.add(parseDescriptor(xpp, "InbandEventStream"));
}
} while (!XmlPullParserUtil.isEndTag(xpp, "Representation"));

Expand All @@ -480,7 +460,7 @@ protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseU

protected Format buildFormat(String id, String containerMimeType, int width, int height,
float frameRate, int audioChannels, int audioSamplingRate, int bitrate, String language,
@C.SelectionFlags int selectionFlags, List<SchemeValuePair> accessibilityDescriptors,
@C.SelectionFlags int selectionFlags, List<Descriptor> accessibilityDescriptors,
String codecs) {
String sampleMimeType = getSampleMimeType(containerMimeType, codecs);
if (sampleMimeType != null) {
Expand Down Expand Up @@ -509,14 +489,14 @@ protected Format buildFormat(String id, String containerMimeType, int width, int

protected Representation buildRepresentation(RepresentationInfo representationInfo,
String contentId, ArrayList<SchemeData> extraDrmSchemeDatas,
ArrayList<SchemeValuePair> extraInbandEventStreams) {
ArrayList<Descriptor> extraInbandEventStreams) {
Format format = representationInfo.format;
ArrayList<SchemeData> drmSchemeDatas = representationInfo.drmSchemeDatas;
drmSchemeDatas.addAll(extraDrmSchemeDatas);
if (!drmSchemeDatas.isEmpty()) {
format = format.copyWithDrmInitData(new DrmInitData(drmSchemeDatas));
}
ArrayList<SchemeValuePair> inbandEventStremas = representationInfo.inbandEventStreams;
ArrayList<Descriptor> inbandEventStremas = representationInfo.inbandEventStreams;
inbandEventStremas.addAll(extraInbandEventStreams);
return Representation.newInstance(contentId, Representation.REVISION_ID_DEFAULT, format,
representationInfo.baseUrl, representationInfo.segmentBase, inbandEventStremas);
Expand Down Expand Up @@ -809,28 +789,29 @@ private static int checkContentTypeConsistency(int firstType, int secondType) {
}

/**
* Parses a {@link SchemeValuePair} from an element.
* Parses a {@link Descriptor} from an element.
*
* @param xpp The parser from which to read.
* @param tag The tag of the element being parsed.
* @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element.
* @return The parsed {@link SchemeValuePair}.
* @return The parsed {@link Descriptor}.
*/
protected static SchemeValuePair parseSchemeValuePair(XmlPullParser xpp, String tag)
protected static Descriptor parseDescriptor(XmlPullParser xpp, String tag)
throws XmlPullParserException, IOException {
String schemeIdUri = parseString(xpp, "schemeIdUri", null);
String schemeIdUri = parseString(xpp, "schemeIdUri", "");
String value = parseString(xpp, "value", null);
String id = parseString(xpp, "id", null);
do {
xpp.next();
} while (!XmlPullParserUtil.isEndTag(xpp, tag));
return new SchemeValuePair(schemeIdUri, value);
return new Descriptor(schemeIdUri, value, id);
}

protected static int parseCea608AccessibilityChannel(
List<SchemeValuePair> accessibilityDescriptors) {
List<Descriptor> accessibilityDescriptors) {
for (int i = 0; i < accessibilityDescriptors.size(); i++) {
SchemeValuePair descriptor = accessibilityDescriptors.get(i);
Descriptor descriptor = accessibilityDescriptors.get(i);
if ("urn:scte:dash:cc:cea-608:2015".equals(descriptor.schemeIdUri)
&& descriptor.value != null) {
Matcher accessibilityValueMatcher = CEA_608_ACCESSIBILITY_PATTERN.matcher(descriptor.value);
Expand All @@ -845,9 +826,9 @@ protected static int parseCea608AccessibilityChannel(
}

protected static int parseCea708AccessibilityChannel(
List<SchemeValuePair> accessibilityDescriptors) {
List<Descriptor> accessibilityDescriptors) {
for (int i = 0; i < accessibilityDescriptors.size(); i++) {
SchemeValuePair descriptor = accessibilityDescriptors.get(i);
Descriptor descriptor = accessibilityDescriptors.get(i);
if ("urn:scte:dash:cc:cea-708:2015".equals(descriptor.schemeIdUri)
&& descriptor.value != null) {
Matcher accessibilityValueMatcher = CEA_708_ACCESSIBILITY_PATTERN.matcher(descriptor.value);
Expand Down Expand Up @@ -925,10 +906,10 @@ private static final class RepresentationInfo {
public final String baseUrl;
public final SegmentBase segmentBase;
public final ArrayList<SchemeData> drmSchemeDatas;
public final ArrayList<SchemeValuePair> inbandEventStreams;
public final ArrayList<Descriptor> inbandEventStreams;

public RepresentationInfo(Format format, String baseUrl, SegmentBase segmentBase,
ArrayList<SchemeData> drmSchemeDatas, ArrayList<SchemeValuePair> inbandEventStreams) {
ArrayList<SchemeData> drmSchemeDatas, ArrayList<Descriptor> inbandEventStreams) {
this.format = format;
this.baseUrl = baseUrl;
this.segmentBase = segmentBase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,37 @@
*/
package com.google.android.exoplayer2.source.dash.manifest;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.util.Util;

/**
* A pair consisting of a scheme ID and value.
* A descriptor, as defined by ISO 23009-1, 2nd edition, 5.8.2.
*/
public class SchemeValuePair {
public final class Descriptor {

public final String schemeIdUri;
public final String value;
/**
* The scheme URI.
*/
@NonNull public final String schemeIdUri;
/**
* The value, or null.
*/
@Nullable public final String value;
/**
* The identifier, or null.
*/
@Nullable public final String id;

public SchemeValuePair(String schemeIdUri, String value) {
/**
* @param schemeIdUri The scheme URI.
* @param value The value, or null.
* @param id The identifier, or null.
*/
public Descriptor(@NonNull String schemeIdUri, @Nullable String value, @Nullable String id) {
this.schemeIdUri = schemeIdUri;
this.value = value;
this.id = id;
}

@Override
Expand All @@ -38,14 +56,17 @@ public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
SchemeValuePair other = (SchemeValuePair) obj;
return Util.areEqual(schemeIdUri, other.schemeIdUri) && Util.areEqual(value, other.value);
Descriptor other = (Descriptor) obj;
return Util.areEqual(schemeIdUri, other.schemeIdUri) && Util.areEqual(value, other.value)
&& Util.areEqual(id, other.id);
}

@Override
public int hashCode() {
return 31 * (schemeIdUri != null ? schemeIdUri.hashCode() : 0)
+ (value != null ? value.hashCode() : 0);
int result = (schemeIdUri != null ? schemeIdUri.hashCode() : 0);
result = 31 * result + (value != null ? value.hashCode() : 0);
result = 31 * result + (id != null ? id.hashCode() : 0);
return result;
}

}
Loading

0 comments on commit 9737046

Please sign in to comment.