Commit 021291b3 by tonihei Committed by Oliver Woodman

Add server-client time offset to Window.

This offset allows to improve the calculated live offset because it
can take known client-server time offsets into account.

PiperOrigin-RevId: 285970738
parent a035c2e2
...@@ -130,6 +130,7 @@ import java.util.Arrays; ...@@ -130,6 +130,7 @@ import java.util.Arrays;
/* manifest= */ null, /* manifest= */ null,
/* presentationStartTimeMs= */ C.TIME_UNSET, /* presentationStartTimeMs= */ C.TIME_UNSET,
/* windowStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET,
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
/* isSeekable= */ !isDynamic, /* isSeekable= */ !isDynamic,
isDynamic, isDynamic,
isLive[windowIndex], isLive[windowIndex],
......
...@@ -153,7 +153,7 @@ public abstract class BasePlayer implements Player { ...@@ -153,7 +153,7 @@ public abstract class BasePlayer implements Player {
if (windowStartTimeMs == C.TIME_UNSET) { if (windowStartTimeMs == C.TIME_UNSET) {
return C.TIME_UNSET; return C.TIME_UNSET;
} }
return System.currentTimeMillis() - window.windowStartTimeMs - getContentPosition(); return window.getCurrentUnixTimeMs() - window.windowStartTimeMs - getContentPosition();
} }
@Override @Override
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2; package com.google.android.exoplayer2;
import android.os.SystemClock;
import android.util.Pair; import android.util.Pair;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.source.ads.AdPlaybackState; import com.google.android.exoplayer2.source.ads.AdPlaybackState;
...@@ -136,19 +137,28 @@ public abstract class Timeline { ...@@ -136,19 +137,28 @@ public abstract class Timeline {
/** /**
* The start time of the presentation to which this window belongs in milliseconds since the * The start time of the presentation to which this window belongs in milliseconds since the
* epoch, or {@link C#TIME_UNSET} if unknown or not applicable. For informational purposes only. * Unix epoch, or {@link C#TIME_UNSET} if unknown or not applicable. For informational purposes
* only.
*/ */
public long presentationStartTimeMs; public long presentationStartTimeMs;
/** /**
* The window's start time in milliseconds since the epoch, or {@link C#TIME_UNSET} if unknown * The window's start time in milliseconds since the Unix epoch, or {@link C#TIME_UNSET} if
* or not applicable. For informational purposes only. * unknown or not applicable. For informational purposes only.
*/ */
public long windowStartTimeMs; public long windowStartTimeMs;
/** /**
* Whether it's possible to seek within this window. * The offset between {@link SystemClock#elapsedRealtime()} and the time since the Unix epoch
* according to the clock of the media origin server, or {@link C#TIME_UNSET} if unknown or not
* applicable.
*
* <p>Note that the current Unix time can be retrieved using {@link #getCurrentUnixTimeMs()} and
* is calculated as {@code SystemClock.elapsedRealtime() + elapsedRealtimeEpochOffsetMs}.
*/ */
public long elapsedRealtimeEpochOffsetMs;
/** Whether it's possible to seek within this window. */
public boolean isSeekable; public boolean isSeekable;
// TODO: Split this to better describe which parts of the window might change. For example it // TODO: Split this to better describe which parts of the window might change. For example it
...@@ -205,6 +215,7 @@ public abstract class Timeline { ...@@ -205,6 +215,7 @@ public abstract class Timeline {
@Nullable Object manifest, @Nullable Object manifest,
long presentationStartTimeMs, long presentationStartTimeMs,
long windowStartTimeMs, long windowStartTimeMs,
long elapsedRealtimeEpochOffsetMs,
boolean isSeekable, boolean isSeekable,
boolean isDynamic, boolean isDynamic,
boolean isLive, boolean isLive,
...@@ -218,6 +229,7 @@ public abstract class Timeline { ...@@ -218,6 +229,7 @@ public abstract class Timeline {
this.manifest = manifest; this.manifest = manifest;
this.presentationStartTimeMs = presentationStartTimeMs; this.presentationStartTimeMs = presentationStartTimeMs;
this.windowStartTimeMs = windowStartTimeMs; this.windowStartTimeMs = windowStartTimeMs;
this.elapsedRealtimeEpochOffsetMs = elapsedRealtimeEpochOffsetMs;
this.isSeekable = isSeekable; this.isSeekable = isSeekable;
this.isDynamic = isDynamic; this.isDynamic = isDynamic;
this.isLive = isLive; this.isLive = isLive;
...@@ -279,6 +291,16 @@ public abstract class Timeline { ...@@ -279,6 +291,16 @@ public abstract class Timeline {
return positionInFirstPeriodUs; return positionInFirstPeriodUs;
} }
/**
* Returns the current time in milliseconds since the Unix epoch.
*
* <p>This method applies {@link #elapsedRealtimeEpochOffsetMs known corrections} made available
* by the media such that this time corresponds to the clock of the media origin server.
*/
public long getCurrentUnixTimeMs() {
return Util.getNowUnixTimeMs(elapsedRealtimeEpochOffsetMs);
}
@Override @Override
public boolean equals(@Nullable Object obj) { public boolean equals(@Nullable Object obj) {
if (this == obj) { if (this == obj) {
...@@ -293,6 +315,7 @@ public abstract class Timeline { ...@@ -293,6 +315,7 @@ public abstract class Timeline {
&& Util.areEqual(manifest, that.manifest) && Util.areEqual(manifest, that.manifest)
&& presentationStartTimeMs == that.presentationStartTimeMs && presentationStartTimeMs == that.presentationStartTimeMs
&& windowStartTimeMs == that.windowStartTimeMs && windowStartTimeMs == that.windowStartTimeMs
&& elapsedRealtimeEpochOffsetMs == that.elapsedRealtimeEpochOffsetMs
&& isSeekable == that.isSeekable && isSeekable == that.isSeekable
&& isDynamic == that.isDynamic && isDynamic == that.isDynamic
&& isLive == that.isLive && isLive == that.isLive
...@@ -311,6 +334,9 @@ public abstract class Timeline { ...@@ -311,6 +334,9 @@ public abstract class Timeline {
result = 31 * result + (manifest == null ? 0 : manifest.hashCode()); result = 31 * result + (manifest == null ? 0 : manifest.hashCode());
result = 31 * result + (int) (presentationStartTimeMs ^ (presentationStartTimeMs >>> 32)); result = 31 * result + (int) (presentationStartTimeMs ^ (presentationStartTimeMs >>> 32));
result = 31 * result + (int) (windowStartTimeMs ^ (windowStartTimeMs >>> 32)); result = 31 * result + (int) (windowStartTimeMs ^ (windowStartTimeMs >>> 32));
result =
31 * result
+ (int) (elapsedRealtimeEpochOffsetMs ^ (elapsedRealtimeEpochOffsetMs >>> 32));
result = 31 * result + (isSeekable ? 1 : 0); result = 31 * result + (isSeekable ? 1 : 0);
result = 31 * result + (isDynamic ? 1 : 0); result = 31 * result + (isDynamic ? 1 : 0);
result = 31 * result + (isLive ? 1 : 0); result = 31 * result + (isLive ? 1 : 0);
......
...@@ -337,6 +337,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> { ...@@ -337,6 +337,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
/* manifest= */ null, /* manifest= */ null,
/* presentationStartTimeMs= */ C.TIME_UNSET, /* presentationStartTimeMs= */ C.TIME_UNSET,
/* windowStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET,
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
/* isSeekable= */ false, /* isSeekable= */ false,
// Dynamic window to indicate pending timeline updates. // Dynamic window to indicate pending timeline updates.
/* isDynamic= */ true, /* isDynamic= */ true,
......
...@@ -29,6 +29,7 @@ public final class SinglePeriodTimeline extends Timeline { ...@@ -29,6 +29,7 @@ public final class SinglePeriodTimeline extends Timeline {
private final long presentationStartTimeMs; private final long presentationStartTimeMs;
private final long windowStartTimeMs; private final long windowStartTimeMs;
private final long elapsedRealtimeEpochOffsetMs;
private final long periodDurationUs; private final long periodDurationUs;
private final long windowDurationUs; private final long windowDurationUs;
private final long windowPositionInPeriodUs; private final long windowPositionInPeriodUs;
...@@ -110,6 +111,7 @@ public final class SinglePeriodTimeline extends Timeline { ...@@ -110,6 +111,7 @@ public final class SinglePeriodTimeline extends Timeline {
this( this(
/* presentationStartTimeMs= */ C.TIME_UNSET, /* presentationStartTimeMs= */ C.TIME_UNSET,
/* windowStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET,
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
periodDurationUs, periodDurationUs,
windowDurationUs, windowDurationUs,
windowPositionInPeriodUs, windowPositionInPeriodUs,
...@@ -126,8 +128,12 @@ public final class SinglePeriodTimeline extends Timeline { ...@@ -126,8 +128,12 @@ public final class SinglePeriodTimeline extends Timeline {
* position in the period. * position in the period.
* *
* @param presentationStartTimeMs The start time of the presentation in milliseconds since the * @param presentationStartTimeMs The start time of the presentation in milliseconds since the
* epoch. * epoch, or {@link C#TIME_UNSET} if unknown or not applicable.
* @param windowStartTimeMs The window's start time in milliseconds since the epoch. * @param windowStartTimeMs The window's start time in milliseconds since the epoch, or {@link
* C#TIME_UNSET} if unknown or not applicable.
* @param elapsedRealtimeEpochOffsetMs The offset between {@link
* android.os.SystemClock#elapsedRealtime()} and the time since the Unix epoch according to
* the clock of the media origin server, or {@link C#TIME_UNSET} if unknown or not applicable.
* @param periodDurationUs The duration of the period in microseconds. * @param periodDurationUs The duration of the period in microseconds.
* @param windowDurationUs The duration of the window in microseconds. * @param windowDurationUs The duration of the window in microseconds.
* @param windowPositionInPeriodUs The position of the start of the window in the period, in * @param windowPositionInPeriodUs The position of the start of the window in the period, in
...@@ -143,6 +149,7 @@ public final class SinglePeriodTimeline extends Timeline { ...@@ -143,6 +149,7 @@ public final class SinglePeriodTimeline extends Timeline {
public SinglePeriodTimeline( public SinglePeriodTimeline(
long presentationStartTimeMs, long presentationStartTimeMs,
long windowStartTimeMs, long windowStartTimeMs,
long elapsedRealtimeEpochOffsetMs,
long periodDurationUs, long periodDurationUs,
long windowDurationUs, long windowDurationUs,
long windowPositionInPeriodUs, long windowPositionInPeriodUs,
...@@ -154,6 +161,7 @@ public final class SinglePeriodTimeline extends Timeline { ...@@ -154,6 +161,7 @@ public final class SinglePeriodTimeline extends Timeline {
@Nullable Object tag) { @Nullable Object tag) {
this.presentationStartTimeMs = presentationStartTimeMs; this.presentationStartTimeMs = presentationStartTimeMs;
this.windowStartTimeMs = windowStartTimeMs; this.windowStartTimeMs = windowStartTimeMs;
this.elapsedRealtimeEpochOffsetMs = elapsedRealtimeEpochOffsetMs;
this.periodDurationUs = periodDurationUs; this.periodDurationUs = periodDurationUs;
this.windowDurationUs = windowDurationUs; this.windowDurationUs = windowDurationUs;
this.windowPositionInPeriodUs = windowPositionInPeriodUs; this.windowPositionInPeriodUs = windowPositionInPeriodUs;
...@@ -192,13 +200,14 @@ public final class SinglePeriodTimeline extends Timeline { ...@@ -192,13 +200,14 @@ public final class SinglePeriodTimeline extends Timeline {
manifest, manifest,
presentationStartTimeMs, presentationStartTimeMs,
windowStartTimeMs, windowStartTimeMs,
elapsedRealtimeEpochOffsetMs,
isSeekable, isSeekable,
isDynamic, isDynamic,
isLive, isLive,
windowDefaultStartPositionUs, windowDefaultStartPositionUs,
windowDurationUs, windowDurationUs,
0, /* firstPeriodIndex= */ 0,
0, /* lastPeriodIndex= */ 0,
windowPositionInPeriodUs); windowPositionInPeriodUs);
} }
......
...@@ -39,6 +39,7 @@ import android.os.Build; ...@@ -39,6 +39,7 @@ import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Parcel; import android.os.Parcel;
import android.os.SystemClock;
import android.security.NetworkSecurityPolicy; import android.security.NetworkSecurityPolicy;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
...@@ -2045,6 +2046,19 @@ public final class Util { ...@@ -2045,6 +2046,19 @@ public final class Util {
} }
} }
/**
* Returns the current time in milliseconds since the epoch.
*
* @param elapsedRealtimeEpochOffsetMs The offset between {@link SystemClock#elapsedRealtime()}
* and the time since the Unix epoch, or {@link C#TIME_UNSET} if unknown.
* @return The Unix time in milliseconds since the epoch.
*/
public static long getNowUnixTimeMs(long elapsedRealtimeEpochOffsetMs) {
return elapsedRealtimeEpochOffsetMs == C.TIME_UNSET
? System.currentTimeMillis()
: SystemClock.elapsedRealtime() + elapsedRealtimeEpochOffsetMs;
}
@Nullable @Nullable
private static String getSystemProperty(String name) { private static String getSystemProperty(String name) {
try { try {
......
...@@ -134,6 +134,7 @@ public class TimelineTest { ...@@ -134,6 +134,7 @@ public class TimelineTest {
window.manifest, window.manifest,
window.presentationStartTimeMs, window.presentationStartTimeMs,
window.windowStartTimeMs, window.windowStartTimeMs,
window.elapsedRealtimeEpochOffsetMs,
window.isSeekable, window.isSeekable,
window.isDynamic, window.isDynamic,
window.isLive, window.isLive,
......
...@@ -42,7 +42,8 @@ public interface DashChunkSource extends ChunkSource { ...@@ -42,7 +42,8 @@ public interface DashChunkSource extends ChunkSource {
* @param trackSelection The track selection. * @param trackSelection The track selection.
* @param elapsedRealtimeOffsetMs If known, an estimate of the instantaneous difference between * @param elapsedRealtimeOffsetMs If known, an estimate of the instantaneous difference between
* server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, * server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds,
* specified as the server's unix time minus the local elapsed time. If unknown, set to 0. * specified as the server's unix time minus the local elapsed time. Or {@link
* com.google.android.exoplayer2.C#TIME_UNSET} if unknown.
* @param enableEventMessageTrack Whether to output an event message track. * @param enableEventMessageTrack Whether to output an event message track.
* @param closedCaptionFormats The {@link Format Formats} of closed caption tracks to be output. * @param closedCaptionFormats The {@link Format Formats} of closed caption tracks to be output.
* @param transferListener The transfer listener which should be informed of any data transfers. * @param transferListener The transfer listener which should be informed of any data transfers.
......
...@@ -621,6 +621,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -621,6 +621,7 @@ public final class DashMediaSource extends BaseMediaSource {
periodsById = new SparseArray<>(); periodsById = new SparseArray<>();
playerEmsgCallback = new DefaultPlayerEmsgCallback(); playerEmsgCallback = new DefaultPlayerEmsgCallback();
expiredManifestPublishTimeUs = C.TIME_UNSET; expiredManifestPublishTimeUs = C.TIME_UNSET;
elapsedRealtimeOffsetMs = C.TIME_UNSET;
if (sideloadedManifest) { if (sideloadedManifest) {
Assertions.checkState(!manifest.dynamic); Assertions.checkState(!manifest.dynamic);
manifestCallback = null; manifestCallback = null;
...@@ -723,7 +724,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -723,7 +724,7 @@ public final class DashMediaSource extends BaseMediaSource {
handler.removeCallbacksAndMessages(null); handler.removeCallbacksAndMessages(null);
handler = null; handler = null;
} }
elapsedRealtimeOffsetMs = 0; elapsedRealtimeOffsetMs = C.TIME_UNSET;
staleManifestReloadAttempt = 0; staleManifestReloadAttempt = 0;
expiredManifestPublishTimeUs = C.TIME_UNSET; expiredManifestPublishTimeUs = C.TIME_UNSET;
firstPeriodId = 0; firstPeriodId = 0;
...@@ -969,7 +970,8 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -969,7 +970,8 @@ public final class DashMediaSource extends BaseMediaSource {
if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) { if (manifest.dynamic && !lastPeriodSeekInfo.isIndexExplicit) {
// The manifest describes an incomplete live stream. Update the start/end times to reflect the // The manifest describes an incomplete live stream. Update the start/end times to reflect the
// live stream duration and the manifest's time shift buffer depth. // live stream duration and the manifest's time shift buffer depth.
long liveStreamDurationUs = getNowUnixTimeUs() - C.msToUs(manifest.availabilityStartTimeMs); long nowUnixTimeUs = C.msToUs(Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs));
long liveStreamDurationUs = nowUnixTimeUs - C.msToUs(manifest.availabilityStartTimeMs);
long liveStreamEndPositionInLastPeriodUs = liveStreamDurationUs long liveStreamEndPositionInLastPeriodUs = liveStreamDurationUs
- C.msToUs(manifest.getPeriod(lastPeriodIndex).startMs); - C.msToUs(manifest.getPeriod(lastPeriodIndex).startMs);
currentEndTimeUs = Math.min(liveStreamEndPositionInLastPeriodUs, currentEndTimeUs); currentEndTimeUs = Math.min(liveStreamEndPositionInLastPeriodUs, currentEndTimeUs);
...@@ -1022,6 +1024,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -1022,6 +1024,7 @@ public final class DashMediaSource extends BaseMediaSource {
new DashTimeline( new DashTimeline(
manifest.availabilityStartTimeMs, manifest.availabilityStartTimeMs,
windowStartTimeMs, windowStartTimeMs,
elapsedRealtimeOffsetMs,
firstPeriodId, firstPeriodId,
currentStartTimeUs, currentStartTimeUs,
windowDurationUs, windowDurationUs,
...@@ -1093,14 +1096,6 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -1093,14 +1096,6 @@ public final class DashMediaSource extends BaseMediaSource {
manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs); manifestEventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
} }
private long getNowUnixTimeUs() {
if (elapsedRealtimeOffsetMs != 0) {
return C.msToUs(SystemClock.elapsedRealtime() + elapsedRealtimeOffsetMs);
} else {
return C.msToUs(System.currentTimeMillis());
}
}
private static final class PeriodSeekInfo { private static final class PeriodSeekInfo {
public static PeriodSeekInfo createPeriodSeekInfo( public static PeriodSeekInfo createPeriodSeekInfo(
...@@ -1170,6 +1165,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -1170,6 +1165,7 @@ public final class DashMediaSource extends BaseMediaSource {
private final long presentationStartTimeMs; private final long presentationStartTimeMs;
private final long windowStartTimeMs; private final long windowStartTimeMs;
private final long elapsedRealtimeEpochOffsetMs;
private final int firstPeriodId; private final int firstPeriodId;
private final long offsetInFirstPeriodUs; private final long offsetInFirstPeriodUs;
...@@ -1181,6 +1177,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -1181,6 +1177,7 @@ public final class DashMediaSource extends BaseMediaSource {
public DashTimeline( public DashTimeline(
long presentationStartTimeMs, long presentationStartTimeMs,
long windowStartTimeMs, long windowStartTimeMs,
long elapsedRealtimeEpochOffsetMs,
int firstPeriodId, int firstPeriodId,
long offsetInFirstPeriodUs, long offsetInFirstPeriodUs,
long windowDurationUs, long windowDurationUs,
...@@ -1189,6 +1186,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -1189,6 +1186,7 @@ public final class DashMediaSource extends BaseMediaSource {
@Nullable Object windowTag) { @Nullable Object windowTag) {
this.presentationStartTimeMs = presentationStartTimeMs; this.presentationStartTimeMs = presentationStartTimeMs;
this.windowStartTimeMs = windowStartTimeMs; this.windowStartTimeMs = windowStartTimeMs;
this.elapsedRealtimeEpochOffsetMs = elapsedRealtimeEpochOffsetMs;
this.firstPeriodId = firstPeriodId; this.firstPeriodId = firstPeriodId;
this.offsetInFirstPeriodUs = offsetInFirstPeriodUs; this.offsetInFirstPeriodUs = offsetInFirstPeriodUs;
this.windowDurationUs = windowDurationUs; this.windowDurationUs = windowDurationUs;
...@@ -1228,6 +1226,7 @@ public final class DashMediaSource extends BaseMediaSource { ...@@ -1228,6 +1226,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifest, manifest,
presentationStartTimeMs, presentationStartTimeMs,
windowStartTimeMs, windowStartTimeMs,
elapsedRealtimeEpochOffsetMs,
/* isSeekable= */ true, /* isSeekable= */ true,
/* isDynamic= */ isMovingLiveWindow(manifest), /* isDynamic= */ isMovingLiveWindow(manifest),
/* isLive= */ manifest.dynamic, /* isLive= */ manifest.dynamic,
......
...@@ -136,7 +136,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -136,7 +136,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
* @param dataSource A {@link DataSource} suitable for loading the media data. * @param dataSource A {@link DataSource} suitable for loading the media data.
* @param elapsedRealtimeOffsetMs If known, an estimate of the instantaneous difference between * @param elapsedRealtimeOffsetMs If known, an estimate of the instantaneous difference between
* server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, specified * server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, specified
* as the server's unix time minus the local elapsed time. If unknown, set to 0. * as the server's unix time minus the local elapsed time. Or {@link C#TIME_UNSET} if unknown.
* @param maxSegmentsPerLoad The maximum number of segments to combine into a single request. Note * @param maxSegmentsPerLoad The maximum number of segments to combine into a single request. Note
* that segments will only be combined if their {@link Uri}s are the same and if their data * that segments will only be combined if their {@link Uri}s are the same and if their data
* ranges are adjacent. * ranges are adjacent.
...@@ -267,7 +267,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -267,7 +267,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
return; return;
} }
long nowUnixTimeUs = getNowUnixTimeUs(); long nowUnixTimeUs = C.msToUs(Util.getNowUnixTimeMs(elapsedRealtimeOffsetMs));
MediaChunk previous = queue.isEmpty() ? null : queue.get(queue.size() - 1); MediaChunk previous = queue.isEmpty() ? null : queue.get(queue.size() - 1);
MediaChunkIterator[] chunkIterators = new MediaChunkIterator[trackSelection.length()]; MediaChunkIterator[] chunkIterators = new MediaChunkIterator[trackSelection.length()];
for (int i = 0; i < chunkIterators.length; i++) { for (int i = 0; i < chunkIterators.length; i++) {
...@@ -474,14 +474,6 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -474,14 +474,6 @@ public class DefaultDashChunkSource implements DashChunkSource {
? representationHolder.getSegmentEndTimeUs(lastAvailableSegmentNum) : C.TIME_UNSET; ? representationHolder.getSegmentEndTimeUs(lastAvailableSegmentNum) : C.TIME_UNSET;
} }
private long getNowUnixTimeUs() {
if (elapsedRealtimeOffsetMs != 0) {
return (SystemClock.elapsedRealtime() + elapsedRealtimeOffsetMs) * 1000;
} else {
return System.currentTimeMillis() * 1000;
}
}
private long resolveTimeToLiveEdgeUs(long playbackPositionUs) { private long resolveTimeToLiveEdgeUs(long playbackPositionUs) {
boolean resolveTimeToLiveEdgePossible = manifest.dynamic && liveEdgeTimeUs != C.TIME_UNSET; boolean resolveTimeToLiveEdgePossible = manifest.dynamic && liveEdgeTimeUs != C.TIME_UNSET;
return resolveTimeToLiveEdgePossible ? liveEdgeTimeUs - playbackPositionUs : C.TIME_UNSET; return resolveTimeToLiveEdgePossible ? liveEdgeTimeUs - playbackPositionUs : C.TIME_UNSET;
......
...@@ -468,6 +468,7 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -468,6 +468,7 @@ public final class HlsMediaSource extends BaseMediaSource
new SinglePeriodTimeline( new SinglePeriodTimeline(
presentationStartTimeMs, presentationStartTimeMs,
windowStartTimeMs, windowStartTimeMs,
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
periodDurationUs, periodDurationUs,
/* windowDurationUs= */ playlist.durationUs, /* windowDurationUs= */ playlist.durationUs,
/* windowPositionInPeriodUs= */ offsetFromInitialStartTimeUs, /* windowPositionInPeriodUs= */ offsetFromInitialStartTimeUs,
...@@ -485,6 +486,7 @@ public final class HlsMediaSource extends BaseMediaSource ...@@ -485,6 +486,7 @@ public final class HlsMediaSource extends BaseMediaSource
new SinglePeriodTimeline( new SinglePeriodTimeline(
presentationStartTimeMs, presentationStartTimeMs,
windowStartTimeMs, windowStartTimeMs,
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
/* periodDurationUs= */ playlist.durationUs, /* periodDurationUs= */ playlist.durationUs,
/* windowDurationUs= */ playlist.durationUs, /* windowDurationUs= */ playlist.durationUs,
/* windowPositionInPeriodUs= */ 0, /* windowPositionInPeriodUs= */ 0,
......
...@@ -219,6 +219,7 @@ public final class FakeTimeline extends Timeline { ...@@ -219,6 +219,7 @@ public final class FakeTimeline extends Timeline {
manifests[windowIndex], manifests[windowIndex],
/* presentationStartTimeMs= */ C.TIME_UNSET, /* presentationStartTimeMs= */ C.TIME_UNSET,
/* windowStartTimeMs= */ C.TIME_UNSET, /* windowStartTimeMs= */ C.TIME_UNSET,
/* elapsedRealtimeEpochOffsetMs= */ C.TIME_UNSET,
windowDefinition.isSeekable, windowDefinition.isSeekable,
windowDefinition.isDynamic, windowDefinition.isDynamic,
windowDefinition.isLive, windowDefinition.isLive,
......
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