From 701f343ee5fb65111afb7a87211ae9b03482cb9c Mon Sep 17 00:00:00 2001 From: Steve Mayhew Date: Mon, 18 Oct 2021 17:04:29 -0700 Subject: [PATCH] Fixes issues with EXTINF duration conversion to microseconds The HLS Parser converts from a string decimal duration in seconds into long microseconds. Because the conversion passes through a java double type it can result in representation errors. For example: `#EXTINF:4.004` -> `Segment.durationUs` of 4003999 This matters because the first sample (which is the IDR) for a segment will be discarded following a seek because of the logic in the `SampleQueue`: ````java buffer.timeUs = timesUs[relativeReadIndex]; if (buffer.timeUs < startTimeUs) { buffer.addFlag(C.BUFFER_FLAG_DECODE_ONLY); } ```` --- .../source/hls/playlist/HlsPlaylistParser.java | 10 ++++++++-- .../hls/playlist/HlsMediaPlaylistParserTest.java | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java index ac8bf1e5a8..022b9f1b2b 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java @@ -48,6 +48,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.math.BigDecimal; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; @@ -759,8 +760,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser segments = mediaPlaylist.segments; assertThat(segments).isNotNull(); - assertThat(segments).hasSize(5); + assertThat(segments).hasSize(6); Segment segment = segments.get(0); assertThat(mediaPlaylist.discontinuitySequence + segment.relativeDiscontinuitySequence) @@ -152,6 +155,9 @@ public class HlsMediaPlaylistParserTest { assertThat(segment.byteRangeLength).isEqualTo(C.LENGTH_UNSET); assertThat(segment.byteRangeOffset).isEqualTo(0); assertThat(segment.url).isEqualTo("https://priv.example.com/fileSequence2683.ts"); + + segment = segments.get(5); + assertThat(segment.durationUs).isEqualTo(2002000); } @Test