Commit 4c348d8a by ojw28

Merge pull request #83 from google/dev

Pull dev -> dev-l
parents fcd9ec6c 1f0d4118
......@@ -294,6 +294,9 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
case 6:
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
break;
case 8:
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1;
break;
default:
throw new IllegalArgumentException("Unsupported channel count: " + channelCount);
}
......
......@@ -21,7 +21,7 @@ import java.util.List;
/**
* Represents a set of interchangeable encoded versions of a media content component.
*/
public final class AdaptationSet {
public class AdaptationSet {
public static final int TYPE_UNKNOWN = -1;
public static final int TYPE_VIDEO = 0;
......
......@@ -15,36 +15,21 @@
*/
package com.google.android.exoplayer.dash.mpd;
import java.util.Collections;
import java.util.Map;
/**
* Represents a ContentProtection tag in an AdaptationSet. Holds arbitrary data for various DRM
* schemes.
* Represents a ContentProtection tag in an AdaptationSet.
*/
public final class ContentProtection {
public class ContentProtection {
/**
* Identifies the content protection scheme.
*/
public final String schemeUriId;
/**
* Protection scheme specific data.
*/
public final Map<String, String> keyedData;
/**
* @param schemeUriId Identifies the content protection scheme.
* @param keyedData Data specific to the scheme.
*/
public ContentProtection(String schemeUriId, Map<String, String> keyedData) {
public ContentProtection(String schemeUriId) {
this.schemeUriId = schemeUriId;
if (keyedData != null) {
this.keyedData = Collections.unmodifiableMap(keyedData);
} else {
this.keyedData = Collections.emptyMap();
}
}
}
......@@ -21,7 +21,7 @@ import java.util.List;
/**
* Represents a DASH media presentation description (mpd).
*/
public final class MediaPresentationDescription {
public class MediaPresentationDescription {
public final long availabilityStartTime;
......
......@@ -77,7 +77,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
}
}
private MediaPresentationDescription parseMediaPresentationDescription(XmlPullParser xpp,
protected MediaPresentationDescription parseMediaPresentationDescription(XmlPullParser xpp,
String contentId, Uri baseUrl) throws XmlPullParserException, IOException, ParseException {
long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", -1);
long durationMs = parseDuration(xpp, "mediaPresentationDuration", -1);
......@@ -101,17 +101,29 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
}
} while (!isEndTag(xpp, "MPD"));
return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs,
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, periods);
}
protected MediaPresentationDescription buildMediaPresentationDescription(
long availabilityStartTime, long durationMs, long minBufferTimeMs, boolean dynamic,
long minUpdateTimeMs, long timeShiftBufferDepthMs, UtcTimingElement utcTiming,
List<Period> periods) {
return new MediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs,
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, periods);
}
private UtcTimingElement parseUtcTiming(XmlPullParser xpp) {
protected UtcTimingElement parseUtcTiming(XmlPullParser xpp) {
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
String value = xpp.getAttributeValue(null, "value");
return buildUtcTimingElement(schemeIdUri, value);
}
protected UtcTimingElement buildUtcTimingElement(String schemeIdUri, String value) {
return new UtcTimingElement(schemeIdUri, value);
}
private Period parsePeriod(XmlPullParser xpp, String contentId, Uri baseUrl, long mpdDurationMs)
protected Period parsePeriod(XmlPullParser xpp, String contentId, Uri baseUrl, long mpdDurationMs)
throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id");
long startMs = parseDuration(xpp, "start", 0);
......@@ -134,12 +146,17 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
}
} while (!isEndTag(xpp, "Period"));
return buildPeriod(id, startMs, durationMs, adaptationSets);
}
protected Period buildPeriod(
String id, long startMs, long durationMs, List<AdaptationSet> adaptationSets) {
return new Period(id, startMs, durationMs, adaptationSets);
}
// AdaptationSet parsing.
private AdaptationSet parseAdaptationSet(XmlPullParser xpp, String contentId, Uri baseUrl,
protected AdaptationSet parseAdaptationSet(XmlPullParser xpp, String contentId, Uri baseUrl,
long periodStartMs, long periodDurationMs, SegmentBase segmentBase)
throws XmlPullParserException, IOException {
......@@ -176,13 +193,20 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
} else if (isStartTag(xpp, "SegmentTemplate")) {
segmentBase = parseSegmentTemplate(xpp, baseUrl, (SegmentTemplate) segmentBase,
periodDurationMs);
} else if (isStartTag(xpp)) {
parseAdaptationSetChild(xpp);
}
} while (!isEndTag(xpp, "AdaptationSet"));
return buildAdaptationSet(id, contentType, representations, contentProtections);
}
protected AdaptationSet buildAdaptationSet(int id, int contentType,
List<Representation> representations, List<ContentProtection> contentProtections) {
return new AdaptationSet(id, contentType, representations, contentProtections);
}
private int parseAdaptationSetType(String contentType) {
protected int parseAdaptationSetType(String contentType) {
return TextUtils.isEmpty(contentType) ? AdaptationSet.TYPE_UNKNOWN
: MimeTypes.BASE_TYPE_AUDIO.equals(contentType) ? AdaptationSet.TYPE_AUDIO
: MimeTypes.BASE_TYPE_VIDEO.equals(contentType) ? AdaptationSet.TYPE_VIDEO
......@@ -190,7 +214,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
: AdaptationSet.TYPE_UNKNOWN;
}
private int parseAdaptationSetTypeFromMimeType(String mimeType) {
protected int parseAdaptationSetTypeFromMimeType(String mimeType) {
return TextUtils.isEmpty(mimeType) ? AdaptationSet.TYPE_UNKNOWN
: MimeTypes.isAudio(mimeType) ? AdaptationSet.TYPE_AUDIO
: MimeTypes.isVideo(mimeType) ? AdaptationSet.TYPE_VIDEO
......@@ -228,13 +252,29 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
**/
protected ContentProtection parseContentProtection(XmlPullParser xpp)
throws XmlPullParserException, IOException {
String schemeUriId = xpp.getAttributeValue(null, "schemeUriId");
return new ContentProtection(schemeUriId, null);
String schemeIdUri = xpp.getAttributeValue(null, "schemeIdUri");
return buildContentProtection(schemeIdUri);
}
protected ContentProtection buildContentProtection(String schemeIdUri) {
return new ContentProtection(schemeIdUri);
}
/**
* Parses children of AdaptationSet elements not specifically parsed elsewhere.
*
* @param xpp The XmpPullParser from which the AdaptationSet child should be parsed.
* @throws XmlPullParserException If an error occurs parsing the element.
* @throws IOException If an error occurs reading the element.
**/
protected void parseAdaptationSetChild(XmlPullParser xpp)
throws XmlPullParserException, IOException {
// pass
}
// Representation parsing.
private Representation parseRepresentation(XmlPullParser xpp, String contentId, Uri baseUrl,
protected Representation parseRepresentation(XmlPullParser xpp, String contentId, Uri baseUrl,
long periodStartMs, long periodDurationMs, String mimeType, String language,
SegmentBase segmentBase) throws XmlPullParserException, IOException {
String id = xpp.getAttributeValue(null, "id");
......@@ -261,15 +301,27 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
}
} while (!isEndTag(xpp, "Representation"));
Format format = new Format(id, mimeType, width, height, numChannels, audioSamplingRate,
Format format = buildFormat(id, mimeType, width, height, numChannels, audioSamplingRate,
bandwidth, language);
return Representation.newInstance(periodStartMs, periodDurationMs, contentId, -1, format,
return buildRepresentation(periodStartMs, periodDurationMs, contentId, -1, format,
segmentBase);
}
protected Format buildFormat(String id, String mimeType, int width, int height, int numChannels,
int audioSamplingRate, int bandwidth, String language) {
return new Format(id, mimeType, width, height, numChannels, audioSamplingRate,
bandwidth, language);
}
protected Representation buildRepresentation(long periodStartMs, long periodDurationMs,
String contentId, int revisionId, Format format, SegmentBase segmentBase) {
return Representation.newInstance(periodStartMs, periodDurationMs, contentId, revisionId,
format, segmentBase);
}
// SegmentBase, SegmentList and SegmentTemplate parsing.
private SingleSegmentBase parseSegmentBase(XmlPullParser xpp, Uri baseUrl,
protected SingleSegmentBase parseSegmentBase(XmlPullParser xpp, Uri baseUrl,
SingleSegmentBase parent) throws XmlPullParserException, IOException {
long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1);
......@@ -293,11 +345,17 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
}
} while (!isEndTag(xpp, "SegmentBase"));
return buildSingleSegmentBase(initialization, timescale, presentationTimeOffset, baseUrl,
indexStart, indexLength);
}
protected SingleSegmentBase buildSingleSegmentBase(RangedUri initialization, long timescale,
long presentationTimeOffset, Uri baseUrl, long indexStart, long indexLength) {
return new SingleSegmentBase(initialization, timescale, presentationTimeOffset, baseUrl,
indexStart, indexLength);
}
private SegmentList parseSegmentList(XmlPullParser xpp, Uri baseUrl, SegmentList parent,
protected SegmentList parseSegmentList(XmlPullParser xpp, Uri baseUrl, SegmentList parent,
long periodDuration) throws XmlPullParserException, IOException {
long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1);
......@@ -330,11 +388,18 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
segments = segments != null ? segments : parent.mediaSegments;
}
return buildSegmentList(initialization, timescale, presentationTimeOffset, periodDuration,
startNumber, duration, timeline, segments);
}
protected SegmentList buildSegmentList(RangedUri initialization, long timescale,
long presentationTimeOffset, long periodDuration, int startNumber, long duration,
List<SegmentTimelineElement> timeline, List<RangedUri> segments) {
return new SegmentList(initialization, timescale, presentationTimeOffset, periodDuration,
startNumber, duration, timeline, segments);
}
private SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, Uri baseUrl,
protected SegmentTemplate parseSegmentTemplate(XmlPullParser xpp, Uri baseUrl,
SegmentTemplate parent, long periodDuration) throws XmlPullParserException, IOException {
long timescale = parseLong(xpp, "timescale", parent != null ? parent.timescale : 1);
......@@ -364,11 +429,19 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
timeline = timeline != null ? timeline : parent.segmentTimeline;
}
return buildSegmentTemplate(initialization, timescale, presentationTimeOffset, periodDuration,
startNumber, duration, timeline, initializationTemplate, mediaTemplate, baseUrl);
}
protected SegmentTemplate buildSegmentTemplate(RangedUri initialization, long timescale,
long presentationTimeOffset, long periodDuration, int startNumber, long duration,
List<SegmentTimelineElement> timeline, UrlTemplate initializationTemplate,
UrlTemplate mediaTemplate, Uri baseUrl) {
return new SegmentTemplate(initialization, timescale, presentationTimeOffset, periodDuration,
startNumber, duration, timeline, initializationTemplate, mediaTemplate, baseUrl);
}
private List<SegmentTimelineElement> parseSegmentTimeline(XmlPullParser xpp)
protected List<SegmentTimelineElement> parseSegmentTimeline(XmlPullParser xpp)
throws XmlPullParserException, IOException {
List<SegmentTimelineElement> segmentTimeline = new ArrayList<SegmentTimelineElement>();
long elapsedTime = 0;
......@@ -379,7 +452,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
long duration = parseLong(xpp, "d");
int count = 1 + parseInt(xpp, "r", 0);
for (int i = 0; i < count; i++) {
segmentTimeline.add(new SegmentTimelineElement(elapsedTime, duration));
segmentTimeline.add(buildSegmentTimelineElement(elapsedTime, duration));
elapsedTime += duration;
}
}
......@@ -387,7 +460,11 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
return segmentTimeline;
}
private UrlTemplate parseUrlTemplate(XmlPullParser xpp, String name,
protected SegmentTimelineElement buildSegmentTimelineElement(long elapsedTime, long duration) {
return new SegmentTimelineElement(elapsedTime, duration);
}
protected UrlTemplate parseUrlTemplate(XmlPullParser xpp, String name,
UrlTemplate defaultValue) {
String valueString = xpp.getAttributeValue(null, name);
if (valueString != null) {
......@@ -396,15 +473,15 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
return defaultValue;
}
private RangedUri parseInitialization(XmlPullParser xpp, Uri baseUrl) {
protected RangedUri parseInitialization(XmlPullParser xpp, Uri baseUrl) {
return parseRangedUrl(xpp, baseUrl, "sourceURL", "range");
}
private RangedUri parseSegmentUrl(XmlPullParser xpp, Uri baseUrl) {
protected RangedUri parseSegmentUrl(XmlPullParser xpp, Uri baseUrl) {
return parseRangedUrl(xpp, baseUrl, "media", "mediaRange");
}
private RangedUri parseRangedUrl(XmlPullParser xpp, Uri baseUrl, String urlAttribute,
protected RangedUri parseRangedUrl(XmlPullParser xpp, Uri baseUrl, String urlAttribute,
String rangeAttribute) {
String urlText = xpp.getAttributeValue(null, urlAttribute);
long rangeStart = 0;
......@@ -415,6 +492,11 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
rangeStart = Long.parseLong(rangeTextArray[0]);
rangeLength = Long.parseLong(rangeTextArray[1]) - rangeStart + 1;
}
return buildRangedUri(baseUrl, urlText, rangeStart, rangeLength);
}
protected RangedUri buildRangedUri(Uri baseUrl, String urlText, long rangeStart,
long rangeLength) {
return new RangedUri(baseUrl, urlText, rangeStart, rangeLength);
}
......@@ -429,7 +511,11 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
return xpp.getEventType() == XmlPullParser.START_TAG && name.equals(xpp.getName());
}
private static long parseDuration(XmlPullParser xpp, String name, long defaultValue) {
protected static boolean isStartTag(XmlPullParser xpp) throws XmlPullParserException {
return xpp.getEventType() == XmlPullParser.START_TAG;
}
protected static long parseDuration(XmlPullParser xpp, String name, long defaultValue) {
String value = xpp.getAttributeValue(null, name);
if (value == null) {
return defaultValue;
......@@ -438,7 +524,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
}
}
private static long parseDateTime(XmlPullParser xpp, String name, long defaultValue)
protected static long parseDateTime(XmlPullParser xpp, String name, long defaultValue)
throws ParseException {
String value = xpp.getAttributeValue(null, name);
if (value == null) {
......
......@@ -21,7 +21,7 @@ import java.util.List;
/**
* Encapsulates media content components over a contiguous period of time.
*/
public final class Period {
public class Period {
/**
* The period identifier, if one exists.
......
......@@ -167,6 +167,7 @@ public final class Util {
return Uri.parse(stringUri);
}
if (stringUri.startsWith("/")) {
stringUri = stringUri.substring(1);
return new Uri.Builder()
.scheme(baseUri.getScheme())
.authority(baseUri.getAuthority())
......
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