-
Notifications
You must be signed in to change notification settings - Fork 575
Description
Version
Media3 1.3.1
More version details
commit sha1 d833d59
Devices that reproduce the issue
Android Studio Koala Feature Drop 2024.1.2 Patch 1 Medium Phone API 35 emulator
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Yes
Reproduction steps
Given the following WebVTT content
WEBVTT
X-TIMESTAMP-MAP=LOCAL:479819:32:36.732,MPEGTS:895859864
479819:32:36.732 --> 479819:32:36.920
LANE. JADEN IVEY HANDS IT OFF
INSIDE TO JAYLENOTHER END. ISH G
479819:32:36.920 --> 479819:32:36.954
LANE. JADEN IVEY HANDS IT OFF
INSIDE TO JAYLENOTHER END. ISH G
479819:32:36.954 --> 479819:32:36.987
LANE. JADEN IVEY HANDS IT OFF
INSIDE TO JAYLENOTHER END. ISH G
479819:32:36.987 --> 479819:32:37.120
LANE. JADEN IVEY HANDS IT OFF
INSIDE TO JAYLENOTHER END. ISH G
Loading this WebVTT fragment will result in a calls to androidx.media3.exoplayer.hls.WebVttExtractor::processSample(). Debugging the following to evaluate sampleTimeUs will reveal an int64 overflow on the timestamp passed to usToWrappedPts()
long sampleTimeUs =
timestampAdjuster.adjustTsTimestamp(
TimestampAdjuster.usToWrappedPts(firstCueTimeUs + tsTimestampUs - vttTimestampUs));
When reading fMP4 media, TimestampAdjuster's lastUnadjustedTimestampUs member has a value of 1727354212517266 at the time of the first call to processSample(). This value is in excess of 51-bits, meaning that the call to usToUnwrappedPts() will overflow due to a multiplication with 90000
public synchronized long adjustTsTimestamp(long pts90Khz) {
if (pts90Khz == C.TIME_UNSET) {
return C.TIME_UNSET;
}
if (lastUnadjustedTimestampUs != C.TIME_UNSET) {
// The wrap count for the current PTS may be closestWrapCount or (closestWrapCount - 1),
// and we need to snap to the one closest to lastSampleTimestampUs.
long lastPts = usToNonWrappedPts(lastUnadjustedTimestampUs);
long closestWrapCount = (lastPts + (MAX_PTS_PLUS_ONE / 2)) / MAX_PTS_PLUS_ONE;
Note that when the same code executes with HLS TS segments, the value of TimestampAdjuster's lastUnadjustedTimestampUs is a lot smaller: 14405760488 because the first PES header timestamp stayed within 33-bits. It will take many PCR wraparounds before reaching the magnitude seen for fMP4 TFDT 64-bit EPOCH time values above
It is possible to prevent this overflow by multiplying refactored scaling factors 9/100 and 100/9 instead of 90000/1000000 and 1000000/90000
The live HLS playout URL is not available on a permanent basis so an example segment is attached (video + webVtt) that should be enough to initialize exoplayer's TimestampAdjuster and reproduce the issue in debug mode.
A similar issue was opened in April 2023 that relates strongly to this bug report:
The original issue highlighted a problem with adjustTsTimestamp() but did not dwell on it any further. The workaround cited in the cited issue worked by no longer calling the functions that overflow.
In our case, using scaling factors 9/100 for usToUnwrappedPts and 100/9 for ptsToUs fixes the issue
Expected result
WebVTT content displays when playing fMP4 HLS live feed (as in shakaPlayer and akamai hls.js)
Actual result
Nothing is displayed.
Media
`
Bug Report
- You will email the zip file produced by
adb bugreport
to android-media-github@google.com after filing this issue.