Skip to content

Commit

Permalink
Fix playback of OGG with only a single payload page
Browse files Browse the repository at this point in the history
Issue: #1976

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=137044583
  • Loading branch information
ojw28 committed Oct 24, 2016
1 parent 5c83c28 commit 99503e6
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
*/
public final class DefaultOggSeekerTest extends TestCase {

public void testSetupUnboundAudioLength() {
public void testSetupWithUnsetEndPositionFails() {
try {
new DefaultOggSeeker(0, C.LENGTH_UNSET, new TestStreamReader());
new DefaultOggSeeker(0, C.LENGTH_UNSET, new TestStreamReader(), 1, 1);
fail();
} catch (IllegalArgumentException e) {
// ignored
Expand All @@ -43,11 +43,12 @@ public void testSeeking() throws IOException, InterruptedException {
}
}

public void testSeeking(Random random) throws IOException, InterruptedException {
private void testSeeking(Random random) throws IOException, InterruptedException {
OggTestFile testFile = OggTestFile.generate(random, 1000);
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(testFile.data).build();
TestStreamReader streamReader = new TestStreamReader();
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, testFile.data.length, streamReader);
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, testFile.data.length, streamReader,
testFile.firstPayloadPageSize, testFile.firstPayloadPageGranulePosition);
OggPageHeader pageHeader = new OggPageHeader();

while (true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
public class DefaultOggSeekerUtilMethodsTest extends TestCase {

private Random random = new Random(0);

public void testSkipToNextPage() throws Exception {
FakeExtractorInput extractorInput = TestData.createInput(
TestUtil.joinByteArrays(
Expand Down Expand Up @@ -75,7 +75,7 @@ public void testSkipToNextPageNoMatch() throws Exception {
private static void skipToNextPage(ExtractorInput extractorInput)
throws IOException, InterruptedException {
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, extractorInput.getLength(),
new FlacReader());
new FlacReader(), 1, 2);
while (true) {
try {
oggSeeker.skipToNextPage(extractorInput);
Expand Down Expand Up @@ -143,7 +143,7 @@ public void testSkipToPageOfGranuleAfterTargetPage() throws IOException, Interru

private void skipToPageOfGranule(ExtractorInput input, long granule,
long elapsedSamplesExpected) throws IOException, InterruptedException {
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader());
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader(), 1, 2);
while (true) {
try {
assertEquals(elapsedSamplesExpected, oggSeeker.skipToPageOfGranule(input, granule, -1));
Expand Down Expand Up @@ -193,7 +193,7 @@ public void testReadGranuleOfLastPageWithUnboundedLength()

private void assertReadGranuleOfLastPage(FakeExtractorInput input, int expected)
throws IOException, InterruptedException {
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader());
DefaultOggSeeker oggSeeker = new DefaultOggSeeker(0, input.getLength(), new FlacReader(), 1, 2);
while (true) {
try {
assertEquals(expected, oggSeeker.readGranuleOfLastPage(input));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@
long lastGranule;
int packetCount;
int pageCount;
int firstPayloadPageSize;
long firstPayloadPageGranulePosition;

private OggTestFile(byte[] data, long lastGranule, int packetCount, int pageCount) {
private OggTestFile(byte[] data, long lastGranule, int packetCount, int pageCount,
int firstPayloadPageSize, long firstPayloadPageGranulePosition) {
this.data = data;
this.lastGranule = lastGranule;
this.packetCount = packetCount;
this.pageCount = pageCount;
this.firstPayloadPageSize = firstPayloadPageSize;
this.firstPayloadPageGranulePosition = firstPayloadPageGranulePosition;
}

public static OggTestFile generate(Random random, int pageCount) {
Expand All @@ -47,6 +52,8 @@ public static OggTestFile generate(Random random, int pageCount) {
long granule = 0;
int packetLength = -1;
int packetCount = 0;
int firstPayloadPageSize = 0;
long firstPayloadPageGranulePosition = 0;

for (int i = 0; i < pageCount; i++) {
int headerType = 0x00;
Expand Down Expand Up @@ -89,6 +96,10 @@ public static OggTestFile generate(Random random, int pageCount) {
byte[] payload = TestUtil.buildTestData(bodySize, random);
fileData.add(payload);
fileSize += payload.length;
if (i == 0) {
firstPayloadPageSize = header.length + bodySize;
firstPayloadPageGranulePosition = granule;
}
}

byte[] file = new byte[fileSize];
Expand All @@ -97,7 +108,8 @@ public static OggTestFile generate(Random random, int pageCount) {
System.arraycopy(data, 0, file, position, data.length);
position += data.length;
}
return new OggTestFile(file, granule, packetCount, pageCount);
return new OggTestFile(file, granule, packetCount, pageCount, firstPayloadPageSize,
firstPayloadPageGranulePosition);
}

public int findPreviousPageStart(long position) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,21 @@
* @param startPosition Start position of the payload (inclusive).
* @param endPosition End position of the payload (exclusive).
* @param streamReader StreamReader instance which owns this OggSeeker
* @param firstPayloadPageSize The total size of the first payload page, in bytes.
* @param firstPayloadPageGranulePosition The granule position of the first payload page.
*/
public DefaultOggSeeker(long startPosition, long endPosition, StreamReader streamReader) {
public DefaultOggSeeker(long startPosition, long endPosition, StreamReader streamReader,
int firstPayloadPageSize, long firstPayloadPageGranulePosition) {
Assertions.checkArgument(startPosition >= 0 && endPosition > startPosition);
this.streamReader = streamReader;
this.startPosition = startPosition;
this.endPosition = endPosition;
this.state = STATE_SEEK_TO_END;
if (firstPayloadPageSize == endPosition - startPosition) {
totalGranules = firstPayloadPageGranulePosition;
state = STATE_IDLE;
} else {
state = STATE_SEEK_TO_END;
}
}

@Override
Expand All @@ -77,9 +85,9 @@ public long read(ExtractorInput input) throws IOException, InterruptedException
positionBeforeSeekToEnd = input.getPosition();
state = STATE_READ_LAST_PAGE;
// Seek to the end just before the last page of stream to get the duration.
long lastPagePosition = endPosition - OggPageHeader.MAX_PAGE_SIZE;
if (lastPagePosition > positionBeforeSeekToEnd) {
return lastPagePosition;
long lastPageSearchPosition = endPosition - OggPageHeader.MAX_PAGE_SIZE;
if (lastPageSearchPosition > positionBeforeSeekToEnd) {
return lastPageSearchPosition;
}
// Fall through.
case STATE_READ_LAST_PAGE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ private int readHeaders(ExtractorInput input) throws IOException, InterruptedExc
} else if (input.getLength() == C.LENGTH_UNSET) {
oggSeeker = new UnseekableOggSeeker();
} else {
oggSeeker = new DefaultOggSeeker(payloadStartPosition, input.getLength(), this);
OggPageHeader firstPayloadPageHeader = oggPacket.getPageHeader();
oggSeeker = new DefaultOggSeeker(payloadStartPosition, input.getLength(), this,
firstPayloadPageHeader.headerSize + firstPayloadPageHeader.bodySize,
firstPayloadPageHeader.granulePosition);
}

setupData = null;
Expand Down

0 comments on commit 99503e6

Please sign in to comment.