From 48592071a3bc8f250663fe6362455ade81fff07f Mon Sep 17 00:00:00 2001 From: Steve Mayhew Date: Mon, 30 Mar 2020 14:40:02 -0700 Subject: [PATCH] Move back to `UnexpectedDiscontinuityException` extending a `RuntimeException` This avoids massive changes to method signatures to add throws. Also, took suggestion to make it an `IllegalStateException`. Move the catch outside of the finally that sets `nextLoadPosition` (this allows for possible recovery by reseting the `Extractor` and `TimestampAdjuster`). Lastly, took the suggestion to make a minimum value for the tolerance (especially usefull for very short i-Frame only segments). --- .../source/UnexpectedDiscontinuityException.java | 2 +- .../exoplayer2/source/hls/HlsMediaChunk.java | 6 +++--- .../source/hls/HlsSampleStreamWrapper.java | 14 ++++++++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/UnexpectedDiscontinuityException.java b/library/core/src/main/java/com/google/android/exoplayer2/source/UnexpectedDiscontinuityException.java index 2d1a784c10..6f810eb0b9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/UnexpectedDiscontinuityException.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/UnexpectedDiscontinuityException.java @@ -32,7 +32,7 @@ import com.google.android.exoplayer2.upstream.DataSpec; * {@see https://www.w3.org/2018/12/webmediaguidelines.html#server-side-ad-insertion} * */ -public final class UnexpectedDiscontinuityException extends RuntimeException { +public final class UnexpectedDiscontinuityException extends IllegalStateException { /** the last in-bounds timestamp committed to the {@link SampleQueue}, or * {@link C#TIME_UNSET} if this was for the first committed sample diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java index e700068321..11c176bf34 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaChunk.java @@ -379,12 +379,12 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; while (result == Extractor.RESULT_CONTINUE && !loadCanceled) { result = extractor.read(input, DUMMY_POSITION_HOLDER); } - } catch (UnexpectedDiscontinuityException e) { - Log.d(TAG, "UnexpectedDiscontinuityException - recovering by discarding balance of segment", e); - throw new IOException("load aborted for segment - " + e.dataSpec + " unexpected discontinuity", e); } finally { nextLoadPosition = (int) (input.getPosition() - dataSpec.position); } + } catch (UnexpectedDiscontinuityException e) { + Log.d(TAG, "UnexpectedDiscontinuityException - recovering by discarding balance of segment", e); + throw new IOException("load aborted for segment - " + e.dataSpec + " unexpected discontinuity", e); } finally { Util.closeQuietly(dataSource); } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java index 15b57d708b..e32138d5d1 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsSampleStreamWrapper.java @@ -1360,10 +1360,16 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; private static final String TAG = "HlsSampleQueue"; /** - * largest timestamp deviation from the segment time bounds expressed as a percentage of - * the segment duration. + * Used to compute the "tolerance" value, that is the largest timestamp deviation from + * the segment time bounds. The "tolerance" is set to this percentage of the segment duration. */ - private static double MAX_TIMESTAMP_DEVIATION_PERCENTAGE = 0.50; + private static double MAX_TIMESTAMP_DEVIATION_PERCENTAGE = 0.75; + + /** + * Min time value for "tolerance", for very short segment durations, this overrides + * the percentage + */ + private static double MIN_TOLERANCE_US = 4_000_000; private long lowestTimeUs = C.TIME_UNSET; private long highestTimeUs = C.TIME_UNSET; @@ -1383,7 +1389,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; } void setCurrentLoadingChunk(HlsMediaChunk chunk) { - double tolerance = (chunk.endTimeUs - chunk.startTimeUs) * MAX_TIMESTAMP_DEVIATION_PERCENTAGE; + double tolerance = Math.max(MIN_TOLERANCE_US, (chunk.endTimeUs - chunk.startTimeUs) * MAX_TIMESTAMP_DEVIATION_PERCENTAGE); this.lowestTimeUs = (long) (chunk.startTimeUs - tolerance); this.highestTimeUs = (long) (chunk.endTimeUs + tolerance); this.chunk = chunk;