mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add a test for 33-bit HLS WebVTT wraparound
This also gives some general test coverage for HLS' WebvttExtractor Issue: #7462 PiperOrigin-RevId: 315257252
This commit is contained in:
parent
bc7310240d
commit
b7486f4883
4 changed files with 56 additions and 0 deletions
|
|
@ -33,6 +33,8 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceSets.test.assets.srcDir '../../testdata/src/test/assets/'
|
||||||
|
|
||||||
testOptions.unitTests.includeAndroidResources = true
|
testOptions.unitTests.includeAndroidResources = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,6 +46,7 @@ dependencies {
|
||||||
compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion
|
compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion
|
||||||
implementation project(modulePrefix + 'library-core')
|
implementation project(modulePrefix + 'library-core')
|
||||||
testImplementation project(modulePrefix + 'testutils')
|
testImplementation project(modulePrefix + 'testutils')
|
||||||
|
testImplementation project(modulePrefix + 'testdata')
|
||||||
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
|
testImplementation 'org.robolectric:robolectric:' + robolectricVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,12 @@ package com.google.android.exoplayer2.source.hls;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||||
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
|
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
|
||||||
|
import com.google.android.exoplayer2.testutil.FakeExtractorOutput;
|
||||||
|
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||||
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
import com.google.android.exoplayer2.util.TimestampAdjuster;
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -63,6 +66,27 @@ public class WebvttExtractorTest {
|
||||||
assertThat(sniffData(data)).isFalse();
|
assertThat(sniffData(data)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void read_handlesLargeCueTimestamps() throws Exception {
|
||||||
|
TimestampAdjuster timestampAdjuster = new TimestampAdjuster(/* firstSampleTimestampUs= */ 0);
|
||||||
|
// Prime the TimestampAdjuster with a close-ish timestamp (5s before the first cue).
|
||||||
|
timestampAdjuster.adjustTsTimestamp(384615190);
|
||||||
|
WebvttExtractor extractor = new WebvttExtractor(/* language= */ null, timestampAdjuster);
|
||||||
|
// We can't use ExtractorAsserts because WebvttExtractor doesn't fulfill the whole Extractor
|
||||||
|
// interface (e.g. throws an exception from seek()).
|
||||||
|
FakeExtractorOutput output =
|
||||||
|
TestUtil.extractAllSamplesFromFile(
|
||||||
|
extractor,
|
||||||
|
ApplicationProvider.getApplicationContext(),
|
||||||
|
"webvtt/with_x-timestamp-map_header");
|
||||||
|
|
||||||
|
// The output has a ~5s sampleTime and a large, negative subsampleOffset because the cue
|
||||||
|
// timestamps are ~10 days ahead of the PTS (due to wrapping) so the offset is used to ensure
|
||||||
|
// they're rendered at the right time.
|
||||||
|
output.assertOutput(
|
||||||
|
ApplicationProvider.getApplicationContext(), "webvtt/with_x-timestamp-map_header.dump");
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean sniffData(byte[] data) throws IOException {
|
private static boolean sniffData(byte[] data) throws IOException {
|
||||||
ExtractorInput input = new FakeExtractorInput.Builder().setData(data).build();
|
ExtractorInput input = new FakeExtractorInput.Builder().setData(data).build();
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
13
testdata/src/test/assets/webvtt/with_x-timestamp-map_header
vendored
Normal file
13
testdata/src/test/assets/webvtt/with_x-timestamp-map_header
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
WEBVTT
|
||||||
|
X-TIMESTAMP-MAP=LOCAL:1:11:16.443,MPEGTS:384879885
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
X-TIMESTAMP-MAP is defined in RFC 8216 section 3.5 (HLS spec).
|
||||||
|
The cue times below are deliberately greater than 2^33 in 90kHz PTS clock,
|
||||||
|
to test wraparound logic.
|
||||||
|
|
||||||
|
266:18:35.679 --> 266:18:37.305
|
||||||
|
Cue text one
|
||||||
|
|
||||||
|
266:18:37.433 --> 266:18:38.276
|
||||||
|
Cue text two
|
||||||
16
testdata/src/test/assets/webvtt/with_x-timestamp-map_header.dump
vendored
Normal file
16
testdata/src/test/assets/webvtt/with_x-timestamp-map_header.dump
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
seekMap:
|
||||||
|
isSeekable = false
|
||||||
|
duration = UNSET TIME
|
||||||
|
getPosition(0) = [[timeUs=0, position=0]]
|
||||||
|
numberOfTracks = 1
|
||||||
|
track 0:
|
||||||
|
total output bytes = 324
|
||||||
|
sample count = 1
|
||||||
|
format 0:
|
||||||
|
sampleMimeType = text/vtt
|
||||||
|
subsampleOffsetUs = -958710678845
|
||||||
|
sample 0:
|
||||||
|
time = 5000155
|
||||||
|
flags = 1
|
||||||
|
data = length 324, hash C0D159A2
|
||||||
|
tracksEnded = true
|
||||||
Loading…
Reference in a new issue