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