Skip to content

Commit

Permalink
Add some initial plumbing for DASH EMSG support
Browse files Browse the repository at this point in the history
Issue: #2176

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=143554094
  • Loading branch information
ojw28 committed Jan 4, 2017
1 parent 2176262 commit 44d6b1a
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,48 @@
*/
public class AdaptationSet {

public static final int UNSET_ID = -1;
/**
* Value of {@link #id} indicating no value is set.=
*/
public static final int ID_UNSET = -1;

/**
* 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.
*/
public final int id;

/**
* The type of the adaptation set. One of the {@link com.google.android.exoplayer2.C}
* {@code TRACK_TYPE_*} constants.
*/
public final int type;

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

public AdaptationSet(int id, int type, List<Representation> representations) {
/**
* The {@link InbandEventStream}s contained by all {@link Representation}s in the adaptation set.
*/
public final List<InbandEventStream> inbandEventStreams;

/**
* @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 inbandEventStreams The {@link InbandEventStream}s contained by all
* {@link Representation}s in the adaptation set.
*/
public AdaptationSet(int id, int type, List<Representation> representations,
List<InbandEventStream> inbandEventStreams) {
this.id = id;
this.type = type;
this.representations = Collections.unmodifiableList(representations);
this.inbandEventStreams = Collections.unmodifiableList(inbandEventStreams);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ protected Period buildPeriod(String id, long startMs, List<AdaptationSet> adapta

protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
SegmentBase segmentBase) throws XmlPullParserException, IOException {
int id = parseInt(xpp, "id", AdaptationSet.UNSET_ID);
int id = parseInt(xpp, "id", AdaptationSet.ID_UNSET);
int contentType = parseContentType(xpp);

String mimeType = xpp.getAttributeValue(null, "mimeType");
Expand All @@ -241,6 +241,8 @@ protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
int accessibilityChannel = Format.NO_VALUE;
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
List<RepresentationInfo> representationInfos = new ArrayList<>();
List<InbandEventStream> adaptationSetInbandEventStreams = new ArrayList<>();
List<InbandEventStream> commonRepresentationInbandEventStreams = null;

boolean seenFirstBaseUrl = false;
do {
Expand All @@ -265,6 +267,22 @@ protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
contentType = checkContentTypeConsistency(contentType,
getContentType(representationInfo.format));
representationInfos.add(representationInfo);
// Initialize or update InbandEventStream elements defined in all child Representations.
List<InbandEventStream> inbandEventStreams = representationInfo.inbandEventStreams;
if (commonRepresentationInbandEventStreams == null) {
// Initialize with the elements defined in this representation.
commonRepresentationInbandEventStreams = new ArrayList<>(inbandEventStreams);
} else {
// Remove elements that are not also defined in this representation.
for (int i = commonRepresentationInbandEventStreams.size() - 1; i >= 0; i--) {
InbandEventStream inbandEventStream = commonRepresentationInbandEventStreams.get(i);
if (!inbandEventStreams.contains(inbandEventStream)) {
Log.w(TAG, "Ignoring InbandEventStream element not defined on all Representations: "
+ inbandEventStream);
commonRepresentationInbandEventStreams.remove(i);
}
}
}
} else if (XmlPullParserUtil.isStartTag(xpp, "AudioChannelConfiguration")) {
audioChannels = parseAudioChannelConfiguration(xpp);
} else if (XmlPullParserUtil.isStartTag(xpp, "Accessibility")) {
Expand All @@ -275,23 +293,34 @@ protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String baseUrl,
segmentBase = parseSegmentList(xpp, (SegmentList) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "SegmentTemplate")) {
segmentBase = parseSegmentTemplate(xpp, (SegmentTemplate) segmentBase);
} else if (XmlPullParserUtil.isStartTag(xpp, "InbandEventStream")) {
adaptationSetInbandEventStreams.add(parseInbandEventStream(xpp));
} else if (XmlPullParserUtil.isStartTag(xpp)) {
parseAdaptationSetChild(xpp);
}
} while (!XmlPullParserUtil.isEndTag(xpp, "AdaptationSet"));

// Pull up InbandEventStream elements defined in all child Representations.
for (int i = 0; i < commonRepresentationInbandEventStreams.size(); i++) {
InbandEventStream inbandEventStream = commonRepresentationInbandEventStreams.get(i);
if (!adaptationSetInbandEventStreams.contains(inbandEventStream)) {
adaptationSetInbandEventStreams.add(inbandEventStream);
}
}

// Build the representations.
List<Representation> representations = new ArrayList<>(representationInfos.size());
for (int i = 0; i < representationInfos.size(); i++) {
representations.add(buildRepresentation(representationInfos.get(i), contentId,
drmSchemeDatas));
}

return buildAdaptationSet(id, contentType, representations);
return buildAdaptationSet(id, contentType, representations, adaptationSetInbandEventStreams);
}

protected AdaptationSet buildAdaptationSet(int id, int contentType,
List<Representation> representations) {
return new AdaptationSet(id, contentType, representations);
List<Representation> representations, List<InbandEventStream> inbandEventStreams) {
return new AdaptationSet(id, contentType, representations, inbandEventStreams);
}

protected int parseContentType(XmlPullParser xpp) {
Expand Down Expand Up @@ -355,6 +384,24 @@ protected SchemeData parseContentProtection(XmlPullParser xpp) throws XmlPullPar
}
}

/**
* 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 {@link InbandEventStream} parsed from the element.
*/
protected InbandEventStream parseInbandEventStream(XmlPullParser xpp)
throws XmlPullParserException, IOException {
String schemeIdUri = parseString(xpp, "schemeIdUri", null);
String value = parseString(xpp, "value", null);
do {
xpp.next();
} while (!XmlPullParserUtil.isEndTag(xpp, "InbandEventStream"));
return new InbandEventStream(schemeIdUri, value);
}

/**
* Parses children of AdaptationSet elements not specifically parsed elsewhere.
*
Expand Down Expand Up @@ -386,6 +433,7 @@ protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseU
int audioChannels = adaptationSetAudioChannels;
int audioSamplingRate = parseInt(xpp, "audioSamplingRate", adaptationSetAudioSamplingRate);
ArrayList<SchemeData> drmSchemeDatas = new ArrayList<>();
ArrayList<InbandEventStream> inbandEventStreams = new ArrayList<>();

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

Expand All @@ -416,7 +466,7 @@ protected RepresentationInfo parseRepresentation(XmlPullParser xpp, String baseU
codecs);
segmentBase = segmentBase != null ? segmentBase : new SingleSegmentBase();

return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeDatas);
return new RepresentationInfo(format, baseUrl, segmentBase, drmSchemeDatas, inbandEventStreams);
}

protected Format buildFormat(String id, String containerMimeType, int width, int height,
Expand Down Expand Up @@ -850,13 +900,15 @@ private static final class RepresentationInfo {
public final String baseUrl;
public final SegmentBase segmentBase;
public final ArrayList<SchemeData> drmSchemeDatas;
public final ArrayList<InbandEventStream> inbandEventStreams;

public RepresentationInfo(Format format, String baseUrl, SegmentBase segmentBase,
ArrayList<SchemeData> drmSchemeDatas) {
ArrayList<SchemeData> drmSchemeDatas, ArrayList<InbandEventStream> inbandEventStreams) {
this.format = format;
this.baseUrl = baseUrl;
this.segmentBase = segmentBase;
this.drmSchemeDatas = drmSchemeDatas;
this.inbandEventStreams = inbandEventStreams;
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.dash.manifest;

import com.google.android.exoplayer2.util.Util;

/**
* Represents a DASH in-band event stream.
*/
public class InbandEventStream {

public final String schemeIdUri;
public final String value;

public InbandEventStream(String schemeIdUri, String value) {
this.schemeIdUri = schemeIdUri;
this.value = value;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
InbandEventStream other = (InbandEventStream) obj;
return Util.areEqual(schemeIdUri, other.schemeIdUri) && Util.areEqual(value, other.value);
}

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

}

0 comments on commit 44d6b1a

Please sign in to comment.