From 6abb2db1c6d166550036e09959b915c298bbc1c3 Mon Sep 17 00:00:00 2001 From: tonihei Date: Fri, 17 May 2024 11:53:17 -0700 Subject: [PATCH] Refactor pending clock sync logic in DashMediaSource This should be no-op overall and helps to disentangle the clock sync update from the state of the manifest. We currently check oldPeriodCount==0 to trigger the clock sync load, which only works because the manifest happens to be null whenever we need a new clock sync. We can decouple these concepts by directly checking whether we have an existing elapsedRealtimeOffsetMs. This also requires to set this value explicitly at the point where we consider it set to the local device clock fallback when the timing element load fails. PiperOrigin-RevId: 634844921 --- .../exoplayer/dash/DashMediaSource.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java b/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java index 28b898b066..f79a96f3a4 100644 --- a/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java +++ b/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java @@ -664,8 +664,7 @@ public final class DashMediaSource extends BaseMediaSource { // After discarding old periods, we should never have more periods than listed in the new // manifest. That would mean that a previously announced period is no longer advertised. If // this condition occurs, assume that we are hitting a manifest server that is out of sync - // and - // behind. + // and behind. Log.w(TAG, "Loaded out of sync manifest"); isManifestStale = true; } else if (expiredManifestPublishTimeUs != C.TIME_UNSET @@ -698,6 +697,7 @@ public final class DashMediaSource extends BaseMediaSource { manifestLoadPending &= manifest.dynamic; manifestLoadStartTimestampMs = elapsedRealtimeMs - loadDurationMs; manifestLoadEndTimestampMs = elapsedRealtimeMs; + firstPeriodId += removedPeriodCount; synchronized (manifestUriLock) { // Checks whether replaceManifestUri(Uri) was called to manually replace the URI between the @@ -713,18 +713,14 @@ public final class DashMediaSource extends BaseMediaSource { } } - if (oldPeriodCount == 0) { - if (manifest.dynamic) { - if (manifest.utcTiming != null) { - resolveUtcTimingElement(manifest.utcTiming); - } else { - loadNtpTimeOffset(); - } + if (manifest.dynamic && elapsedRealtimeOffsetMs == C.TIME_UNSET) { + // Determine elapsedRealtimeOffsetMs before processing the manifest further. + if (manifest.utcTiming != null) { + resolveUtcTimingElement(manifest.utcTiming); } else { - processManifest(true); + loadNtpTimeOffset(); } } else { - firstPeriodId += removedPeriodCount; processManifest(true); } } @@ -877,6 +873,7 @@ public final class DashMediaSource extends BaseMediaSource { private void onUtcTimestampResolutionError(IOException error) { Log.e(TAG, "Failed to resolve time offset.", error); // Be optimistic and continue in the hope that the device clock is correct. + this.elapsedRealtimeOffsetMs = System.currentTimeMillis() - SystemClock.elapsedRealtime(); processManifest(true); }