Constraint seek targetGranule within bounds + simplify tests

PiperOrigin-RevId: 261328701
This commit is contained in:
olly 2019-08-02 16:49:17 +01:00 committed by Oliver Woodman
parent 173eadc70e
commit f179feb292
3 changed files with 43 additions and 49 deletions

View File

@ -29,8 +29,8 @@ import java.io.IOException;
/** Seeks in an Ogg stream. */
/* package */ final class DefaultOggSeeker implements OggSeeker {
@VisibleForTesting public static final int MATCH_RANGE = 72000;
@VisibleForTesting public static final int MATCH_BYTE_RANGE = 100000;
private static final int MATCH_RANGE = 72000;
private static final int MATCH_BYTE_RANGE = 100000;
private static final int DEFAULT_OFFSET = 30000;
private static final int STATE_SEEK_TO_END = 0;
@ -127,7 +127,7 @@ import java.io.IOException;
@Override
public void startSeek(long targetGranule) {
this.targetGranule = targetGranule;
this.targetGranule = Util.constrainValue(targetGranule, 0, totalGranules - 1);
state = STATE_SEEK;
start = payloadStartPosition;
end = payloadEndPosition;
@ -201,7 +201,7 @@ import java.io.IOException;
private void skipToPageOfTargetGranule(ExtractorInput input)
throws IOException, InterruptedException {
pageHeader.populate(input, /* quiet= */ false);
while (pageHeader.granulePosition < targetGranule) {
while (pageHeader.granulePosition <= targetGranule) {
input.skipFully(pageHeader.headerSize + pageHeader.bodySize);
start = input.getPosition();
startGranule = pageHeader.granulePosition;

View File

@ -160,7 +160,7 @@ public final class DefaultOggSeekerTest {
/* payloadStartPosition= */ 0,
/* payloadEndPosition= */ testFile.data.length,
/* firstPayloadPageSize= */ testFile.firstPayloadPageSize,
/* firstPayloadPageGranulePosition= */ testFile.firstPayloadPageGranulePosition,
/* firstPayloadPageGranulePosition= */ testFile.firstPayloadPageGranuleCount,
/* firstPayloadPageIsLastPage= */ false);
OggPageHeader pageHeader = new OggPageHeader();
@ -183,28 +183,12 @@ public final class DefaultOggSeekerTest {
assertThat(input.getPosition()).isEqualTo(0);
// Test last granule.
granule = seekTo(input, oggSeeker, testFile.lastGranule, 0);
long position = testFile.data.length;
// TODO: Simplify this.
assertThat(
(testFile.lastGranule > granule && position > input.getPosition())
|| (testFile.lastGranule == granule && position == input.getPosition()))
.isTrue();
// Test exact granule.
input.setPosition(testFile.data.length / 2);
oggSeeker.skipToNextPage(input);
assertThat(pageHeader.populate(input, true)).isTrue();
position = input.getPosition() + pageHeader.headerSize + pageHeader.bodySize;
granule = seekTo(input, oggSeeker, pageHeader.granulePosition, 0);
// TODO: Simplify this.
assertThat(
(pageHeader.granulePosition > granule && position > input.getPosition())
|| (pageHeader.granulePosition == granule && position == input.getPosition()))
.isTrue();
granule = seekTo(input, oggSeeker, testFile.granuleCount - 1, 0);
assertThat(granule).isEqualTo(testFile.granuleCount - testFile.lastPayloadPageGranuleCount);
assertThat(input.getPosition()).isEqualTo(testFile.data.length - testFile.lastPayloadPageSize);
for (int i = 0; i < 100; i += 1) {
long targetGranule = (long) (random.nextDouble() * testFile.lastGranule);
long targetGranule = random.nextInt(testFile.granuleCount);
int initialPosition = random.nextInt(testFile.data.length);
granule = seekTo(input, oggSeeker, targetGranule, initialPosition);
long currentPosition = input.getPosition();

View File

@ -30,35 +30,39 @@ import java.util.Random;
private static final int MAX_GRANULES_IN_PAGE = 100000;
public final byte[] data;
public final long lastGranule;
public final int packetCount;
public final int granuleCount;
public final int pageCount;
public final int firstPayloadPageSize;
public final long firstPayloadPageGranulePosition;
public final int firstPayloadPageGranuleCount;
public final int lastPayloadPageSize;
public final int lastPayloadPageGranuleCount;
private OggTestFile(
byte[] data,
long lastGranule,
int packetCount,
int granuleCount,
int pageCount,
int firstPayloadPageSize,
long firstPayloadPageGranulePosition) {
int firstPayloadPageGranuleCount,
int lastPayloadPageSize,
int lastPayloadPageGranuleCount) {
this.data = data;
this.lastGranule = lastGranule;
this.packetCount = packetCount;
this.granuleCount = granuleCount;
this.pageCount = pageCount;
this.firstPayloadPageSize = firstPayloadPageSize;
this.firstPayloadPageGranulePosition = firstPayloadPageGranulePosition;
this.firstPayloadPageGranuleCount = firstPayloadPageGranuleCount;
this.lastPayloadPageSize = lastPayloadPageSize;
this.lastPayloadPageGranuleCount = lastPayloadPageGranuleCount;
}
public static OggTestFile generate(Random random, int pageCount) {
ArrayList<byte[]> fileData = new ArrayList<>();
int fileSize = 0;
long granule = 0;
int packetLength = -1;
int packetCount = 0;
int granuleCount = 0;
int firstPayloadPageSize = 0;
long firstPayloadPageGranulePosition = 0;
int firstPayloadPageGranuleCount = 0;
int lastPageloadPageSize = 0;
int lastPayloadPageGranuleCount = 0;
int packetLength = -1;
for (int i = 0; i < pageCount; i++) {
int headerType = 0x00;
@ -71,17 +75,17 @@ import java.util.Random;
if (i == pageCount - 1) {
headerType |= 4;
}
granule += random.nextInt(MAX_GRANULES_IN_PAGE - 1) + 1;
int pageGranuleCount = random.nextInt(MAX_GRANULES_IN_PAGE - 1) + 1;
int pageSegmentCount = random.nextInt(MAX_SEGMENT_COUNT);
byte[] header = OggTestData.buildOggHeader(headerType, granule, 0, pageSegmentCount);
granuleCount += pageGranuleCount;
byte[] header = OggTestData.buildOggHeader(headerType, granuleCount, 0, pageSegmentCount);
fileData.add(header);
fileSize += header.length;
int pageSize = header.length;
byte[] laces = new byte[pageSegmentCount];
int bodySize = 0;
for (int j = 0; j < pageSegmentCount; j++) {
if (packetLength < 0) {
packetCount++;
if (i < pageCount - 1) {
packetLength = random.nextInt(MAX_PACKET_LENGTH);
} else {
@ -96,14 +100,19 @@ import java.util.Random;
packetLength -= 255;
}
fileData.add(laces);
fileSize += laces.length;
pageSize += laces.length;
byte[] payload = TestUtil.buildTestData(bodySize, random);
fileData.add(payload);
fileSize += payload.length;
pageSize += payload.length;
fileSize += pageSize;
if (i == 0) {
firstPayloadPageSize = header.length + bodySize;
firstPayloadPageGranulePosition = granule;
firstPayloadPageSize = pageSize;
firstPayloadPageGranuleCount = pageGranuleCount;
} else if (i == pageCount - 1) {
lastPageloadPageSize = pageSize;
lastPayloadPageGranuleCount = pageGranuleCount;
}
}
@ -115,11 +124,12 @@ import java.util.Random;
}
return new OggTestFile(
file,
granule,
packetCount,
granuleCount,
pageCount,
firstPayloadPageSize,
firstPayloadPageGranulePosition);
firstPayloadPageGranuleCount,
lastPageloadPageSize,
lastPayloadPageGranuleCount);
}
public int findPreviousPageStart(long position) {