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).
This commit is contained in:
Steve Mayhew 2020-03-30 14:40:02 -07:00
parent ccf2ba3e1b
commit 48592071a3
3 changed files with 14 additions and 8 deletions

View file

@ -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

View file

@ -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);
}

View file

@ -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;