mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Allow applications to specify the live edge offset.
Also allow use of suggestedPresentationDelay taken from the manifest, and enable this by default. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130409924
This commit is contained in:
parent
76f7fffb8d
commit
e0773f705f
4 changed files with 41 additions and 16 deletions
|
|
@ -57,23 +57,31 @@ public final class DashMediaSource implements MediaSource {
|
||||||
* The default minimum number of times to retry loading data prior to failing.
|
* The default minimum number of times to retry loading data prior to failing.
|
||||||
*/
|
*/
|
||||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
||||||
|
/**
|
||||||
|
* A constant indicating that the live edge offset (the offset subtracted from the live edge
|
||||||
|
* when calculating the default position returned by {@link #getDefaultStartPosition(int)}) should
|
||||||
|
* be set to {@link DashManifest#suggestedPresentationDelay} if specified by the manifest, or
|
||||||
|
* {@link #DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS} otherwise.
|
||||||
|
*/
|
||||||
|
public static final long DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS = -1;
|
||||||
|
/**
|
||||||
|
* A fixed default live edge offset (the offset subtracted from the live edge when calculating the
|
||||||
|
* default position returned by {@link #getDefaultStartPosition(int)}).
|
||||||
|
*/
|
||||||
|
public static final long DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS = 30000;
|
||||||
/**
|
/**
|
||||||
* The interval in milliseconds between invocations of
|
* The interval in milliseconds between invocations of
|
||||||
* {@link MediaSource.Listener#onSourceInfoRefreshed(Timeline, Object)} when the source's
|
* {@link MediaSource.Listener#onSourceInfoRefreshed(Timeline, Object)} when the source's
|
||||||
* {@link Window} is changing dynamically (for example, for incomplete live streams).
|
* {@link Window} is changing dynamically (for example, for incomplete live streams).
|
||||||
*/
|
*/
|
||||||
private static final int NOTIFY_MANIFEST_INTERVAL_MS = 5000;
|
private static final int NOTIFY_MANIFEST_INTERVAL_MS = 5000;
|
||||||
/**
|
|
||||||
* The offset in milliseconds subtracted from the live edge position when calculating the default
|
|
||||||
* position returned by {@link #getDefaultStartPosition(int)}.
|
|
||||||
*/
|
|
||||||
private static final long LIVE_EDGE_OFFSET_MS = 30000;
|
|
||||||
|
|
||||||
private static final String TAG = "DashMediaSource";
|
private static final String TAG = "DashMediaSource";
|
||||||
|
|
||||||
private final DataSource.Factory manifestDataSourceFactory;
|
private final DataSource.Factory manifestDataSourceFactory;
|
||||||
private final DashChunkSource.Factory chunkSourceFactory;
|
private final DashChunkSource.Factory chunkSourceFactory;
|
||||||
private final int minLoadableRetryCount;
|
private final int minLoadableRetryCount;
|
||||||
|
private final long liveEdgeOffsetMs;
|
||||||
private final EventDispatcher eventDispatcher;
|
private final EventDispatcher eventDispatcher;
|
||||||
private final DashManifestParser manifestParser;
|
private final DashManifestParser manifestParser;
|
||||||
private final ManifestCallback manifestCallback;
|
private final ManifestCallback manifestCallback;
|
||||||
|
|
@ -99,16 +107,18 @@ public final class DashMediaSource implements MediaSource {
|
||||||
DashChunkSource.Factory chunkSourceFactory, Handler eventHandler,
|
DashChunkSource.Factory chunkSourceFactory, Handler eventHandler,
|
||||||
AdaptiveMediaSourceEventListener eventListener) {
|
AdaptiveMediaSourceEventListener eventListener) {
|
||||||
this(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
|
this(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
|
||||||
DEFAULT_MIN_LOADABLE_RETRY_COUNT, eventHandler, eventListener);
|
DEFAULT_MIN_LOADABLE_RETRY_COUNT, DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS, eventHandler,
|
||||||
|
eventListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DashMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory,
|
public DashMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory,
|
||||||
DashChunkSource.Factory chunkSourceFactory, int minLoadableRetryCount,
|
DashChunkSource.Factory chunkSourceFactory, int minLoadableRetryCount, long liveEdgeOffsetMs,
|
||||||
Handler eventHandler, AdaptiveMediaSourceEventListener eventListener) {
|
Handler eventHandler, AdaptiveMediaSourceEventListener eventListener) {
|
||||||
this.manifestUri = manifestUri;
|
this.manifestUri = manifestUri;
|
||||||
this.manifestDataSourceFactory = manifestDataSourceFactory;
|
this.manifestDataSourceFactory = manifestDataSourceFactory;
|
||||||
this.chunkSourceFactory = chunkSourceFactory;
|
this.chunkSourceFactory = chunkSourceFactory;
|
||||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||||
|
this.liveEdgeOffsetMs = liveEdgeOffsetMs;
|
||||||
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
||||||
manifestParser = new DashManifestParser(generateContentId());
|
manifestParser = new DashManifestParser(generateContentId());
|
||||||
manifestCallback = new ManifestCallback();
|
manifestCallback = new ManifestCallback();
|
||||||
|
|
@ -159,7 +169,12 @@ public final class DashMediaSource implements MediaSource {
|
||||||
if (index == 0 && manifest.dynamic) {
|
if (index == 0 && manifest.dynamic) {
|
||||||
// The stream is live, so return a position a position offset from the live edge.
|
// The stream is live, so return a position a position offset from the live edge.
|
||||||
int periodIndex = window.endPeriodIndex;
|
int periodIndex = window.endPeriodIndex;
|
||||||
long positionMs = window.endTimeMs - LIVE_EDGE_OFFSET_MS;
|
long liveEdgeOffsetForManifest = liveEdgeOffsetMs;
|
||||||
|
if (liveEdgeOffsetForManifest == DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS) {
|
||||||
|
liveEdgeOffsetForManifest = manifest.suggestedPresentationDelay != -1
|
||||||
|
? manifest.suggestedPresentationDelay : DEFAULT_LIVE_EDGE_OFFSET_FIXED_MS;
|
||||||
|
}
|
||||||
|
long positionMs = window.endTimeMs - liveEdgeOffsetForManifest;
|
||||||
while (positionMs < 0 && periodIndex > window.startPeriodIndex) {
|
while (positionMs < 0 && periodIndex > window.startPeriodIndex) {
|
||||||
periodIndex--;
|
periodIndex--;
|
||||||
positionMs += manifest.getPeriodDurationMs(periodIndex);
|
positionMs += manifest.getPeriodDurationMs(periodIndex);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ public class DashManifest {
|
||||||
|
|
||||||
public final long timeShiftBufferDepth;
|
public final long timeShiftBufferDepth;
|
||||||
|
|
||||||
|
public final long suggestedPresentationDelay;
|
||||||
|
|
||||||
public final UtcTimingElement utcTiming;
|
public final UtcTimingElement utcTiming;
|
||||||
|
|
||||||
public final Uri location;
|
public final Uri location;
|
||||||
|
|
@ -44,14 +46,16 @@ public class DashManifest {
|
||||||
private final List<Period> periods;
|
private final List<Period> periods;
|
||||||
|
|
||||||
public DashManifest(long availabilityStartTime, long duration, long minBufferTime,
|
public DashManifest(long availabilityStartTime, long duration, long minBufferTime,
|
||||||
boolean dynamic, long minUpdatePeriod, long timeShiftBufferDepth, UtcTimingElement utcTiming,
|
boolean dynamic, long minUpdatePeriod, long timeShiftBufferDepth,
|
||||||
Uri location, List<Period> periods) {
|
long suggestedPresentationDelay, UtcTimingElement utcTiming, Uri location,
|
||||||
|
List<Period> periods) {
|
||||||
this.availabilityStartTime = availabilityStartTime;
|
this.availabilityStartTime = availabilityStartTime;
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.minBufferTime = minBufferTime;
|
this.minBufferTime = minBufferTime;
|
||||||
this.dynamic = dynamic;
|
this.dynamic = dynamic;
|
||||||
this.minUpdatePeriod = minUpdatePeriod;
|
this.minUpdatePeriod = minUpdatePeriod;
|
||||||
this.timeShiftBufferDepth = timeShiftBufferDepth;
|
this.timeShiftBufferDepth = timeShiftBufferDepth;
|
||||||
|
this.suggestedPresentationDelay = suggestedPresentationDelay;
|
||||||
this.utcTiming = utcTiming;
|
this.utcTiming = utcTiming;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.periods = periods == null ? Collections.<Period>emptyList() : periods;
|
this.periods = periods == null ? Collections.<Period>emptyList() : periods;
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,10 @@ public class DashManifestParser extends DefaultHandler
|
||||||
long minBufferTimeMs = parseDuration(xpp, "minBufferTime", -1);
|
long minBufferTimeMs = parseDuration(xpp, "minBufferTime", -1);
|
||||||
String typeString = xpp.getAttributeValue(null, "type");
|
String typeString = xpp.getAttributeValue(null, "type");
|
||||||
boolean dynamic = typeString != null && typeString.equals("dynamic");
|
boolean dynamic = typeString != null && typeString.equals("dynamic");
|
||||||
long minUpdateTimeMs = (dynamic) ? parseDuration(xpp, "minimumUpdatePeriod", -1) : -1;
|
long minUpdateTimeMs = dynamic ? parseDuration(xpp, "minimumUpdatePeriod", -1) : -1;
|
||||||
long timeShiftBufferDepthMs = (dynamic) ? parseDuration(xpp, "timeShiftBufferDepth", -1) : -1;
|
long timeShiftBufferDepthMs = dynamic ? parseDuration(xpp, "timeShiftBufferDepth", -1) : -1;
|
||||||
|
long suggestedPresentationDelayMs = dynamic
|
||||||
|
? parseDuration(xpp, "suggestedPresentationDelay", -1) : -1;
|
||||||
UtcTimingElement utcTiming = null;
|
UtcTimingElement utcTiming = null;
|
||||||
Uri location = null;
|
Uri location = null;
|
||||||
|
|
||||||
|
|
@ -159,14 +161,17 @@ public class DashManifestParser extends DefaultHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs,
|
return buildMediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs,
|
||||||
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods);
|
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, utcTiming,
|
||||||
|
location, periods);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DashManifest buildMediaPresentationDescription(long availabilityStartTime,
|
protected DashManifest buildMediaPresentationDescription(long availabilityStartTime,
|
||||||
long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdateTimeMs,
|
long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdateTimeMs,
|
||||||
long timeShiftBufferDepthMs, UtcTimingElement utcTiming, Uri location, List<Period> periods) {
|
long timeShiftBufferDepthMs, long suggestedPresentationDelayMs, UtcTimingElement utcTiming,
|
||||||
|
Uri location, List<Period> periods) {
|
||||||
return new DashManifest(availabilityStartTime, durationMs, minBufferTimeMs,
|
return new DashManifest(availabilityStartTime, durationMs, minBufferTimeMs,
|
||||||
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods);
|
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, suggestedPresentationDelayMs, utcTiming,
|
||||||
|
location, periods);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UtcTimingElement parseUtcTiming(XmlPullParser xpp) {
|
protected UtcTimingElement parseUtcTiming(XmlPullParser xpp) {
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,8 @@ public final class DashTest extends ActivityInstrumentationTestCase2<HostActivit
|
||||||
DefaultDashChunkSource.Factory chunkSourceFactory = new DefaultDashChunkSource.Factory(
|
DefaultDashChunkSource.Factory chunkSourceFactory = new DefaultDashChunkSource.Factory(
|
||||||
mediaDataSourceFactory);
|
mediaDataSourceFactory);
|
||||||
return new DashMediaSource(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
|
return new DashMediaSource(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
|
||||||
MIN_LOADABLE_RETRY_COUNT, null, null);
|
MIN_LOADABLE_RETRY_COUNT, DashMediaSource.DEFAULT_LIVE_EDGE_OFFSET_PREFER_MANIFEST_MS,
|
||||||
|
null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue