Commit ee0c6224 by ibaker Committed by Ian Baker

Respect 33-bit wraparound when calculating WebVTT timestamps in HLS

Issue: #7462
PiperOrigin-RevId: 314919210
parent 8dedbbbf
...@@ -157,6 +157,8 @@ ...@@ -157,6 +157,8 @@
* HLS: * HLS:
* Add support for upstream discard including cancelation of ongoing load * Add support for upstream discard including cancelation of ongoing load
([#6322](https://github.com/google/ExoPlayer/issues/6322)). ([#6322](https://github.com/google/ExoPlayer/issues/6322)).
* Respect 33-bit PTS wrapping when applying `X-TIMESTAMP-MAP` to WebVTT
timestamps ([#7464](https://github.com/google/ExoPlayer/issues/7464)).
* Ogg: Allow non-contiguous pages * Ogg: Allow non-contiguous pages
([#7230](https://github.com/google/ExoPlayer/issues/7230)). ([#7230](https://github.com/google/ExoPlayer/issues/7230)).
* Extractors: * Extractors:
......
...@@ -113,7 +113,7 @@ public final class TimestampAdjuster { ...@@ -113,7 +113,7 @@ public final class TimestampAdjuster {
if (lastSampleTimestampUs != C.TIME_UNSET) { if (lastSampleTimestampUs != C.TIME_UNSET) {
// The wrap count for the current PTS may be closestWrapCount or (closestWrapCount - 1), // The wrap count for the current PTS may be closestWrapCount or (closestWrapCount - 1),
// and we need to snap to the one closest to lastSampleTimestampUs. // and we need to snap to the one closest to lastSampleTimestampUs.
long lastPts = usToPts(lastSampleTimestampUs); long lastPts = usToNonWrappedPts(lastSampleTimestampUs);
long closestWrapCount = (lastPts + (MAX_PTS_PLUS_ONE / 2)) / MAX_PTS_PLUS_ONE; long closestWrapCount = (lastPts + (MAX_PTS_PLUS_ONE / 2)) / MAX_PTS_PLUS_ONE;
long ptsWrapBelow = pts90Khz + (MAX_PTS_PLUS_ONE * (closestWrapCount - 1)); long ptsWrapBelow = pts90Khz + (MAX_PTS_PLUS_ONE * (closestWrapCount - 1));
long ptsWrapAbove = pts90Khz + (MAX_PTS_PLUS_ONE * closestWrapCount); long ptsWrapAbove = pts90Khz + (MAX_PTS_PLUS_ONE * closestWrapCount);
...@@ -174,13 +174,26 @@ public final class TimestampAdjuster { ...@@ -174,13 +174,26 @@ public final class TimestampAdjuster {
} }
/** /**
* Converts a timestamp in microseconds to a 90 kHz clock timestamp, performing wraparound to keep
* the result within 33-bits.
*
* @param us A value in microseconds.
* @return The corresponding value as a 90 kHz clock timestamp, wrapped to 33 bits.
*/
public static long usToWrappedPts(long us) {
return usToNonWrappedPts(us) % MAX_PTS_PLUS_ONE;
}
/**
* Converts a timestamp in microseconds to a 90 kHz clock timestamp. * Converts a timestamp in microseconds to a 90 kHz clock timestamp.
* *
* <p>Does not perform any wraparound. To get a 90 kHz timestamp suitable for use with MPEG-TS,
* use {@link #usToWrappedPts(long)}.
*
* @param us A value in microseconds. * @param us A value in microseconds.
* @return The corresponding value as a 90 kHz clock timestamp. * @return The corresponding value as a 90 kHz clock timestamp.
*/ */
public static long usToPts(long us) { public static long usToNonWrappedPts(long us) {
return (us * 90000) / C.MICROS_PER_SECOND; return (us * 90000) / C.MICROS_PER_SECOND;
} }
} }
...@@ -200,7 +200,8 @@ public final class SpliceInfoDecoderTest { ...@@ -200,7 +200,8 @@ public final class SpliceInfoDecoderTest {
} }
private static long removePtsConversionPrecisionError(long timeUs, long offsetUs) { private static long removePtsConversionPrecisionError(long timeUs, long offsetUs) {
return TimestampAdjuster.ptsToUs(TimestampAdjuster.usToPts(timeUs - offsetUs)) + offsetUs; return TimestampAdjuster.ptsToUs(TimestampAdjuster.usToNonWrappedPts(timeUs - offsetUs))
+ offsetUs;
} }
} }
...@@ -176,8 +176,9 @@ public final class WebvttExtractor implements Extractor { ...@@ -176,8 +176,9 @@ public final class WebvttExtractor implements Extractor {
long firstCueTimeUs = long firstCueTimeUs =
WebvttParserUtil.parseTimestampUs(Assertions.checkNotNull(cueHeaderMatcher.group(1))); WebvttParserUtil.parseTimestampUs(Assertions.checkNotNull(cueHeaderMatcher.group(1)));
long sampleTimeUs = timestampAdjuster.adjustTsTimestamp( long sampleTimeUs =
TimestampAdjuster.usToPts(firstCueTimeUs + tsTimestampUs - vttTimestampUs)); timestampAdjuster.adjustTsTimestamp(
TimestampAdjuster.usToWrappedPts(firstCueTimeUs + tsTimestampUs - vttTimestampUs));
long subsampleOffsetUs = sampleTimeUs - firstCueTimeUs; long subsampleOffsetUs = sampleTimeUs - firstCueTimeUs;
// Output the track. // Output the track.
TrackOutput trackOutput = buildTrackOutput(subsampleOffsetUs); TrackOutput trackOutput = buildTrackOutput(subsampleOffsetUs);
......
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