Fix Ogg/Flac sync exception.

Restores input position after flac block size read.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=122978325
This commit is contained in:
eguven 2016-05-23 02:31:15 -07:00 committed by Oliver Woodman
parent 731d4283ab
commit 9981a83c05
3 changed files with 34 additions and 18 deletions

View File

@ -43,10 +43,20 @@ public final class OggExtractorFileTests extends InstrumentationTestCase {
} }
public void testFlac() throws Exception { public void testFlac() throws Exception {
parseFile(FLAC_TEST_FILE, false, false, false, MimeTypes.AUDIO_FLAC, 2741000, 33); testFlac(false, false, false);
parseFile(FLAC_TEST_FILE, false, true, false, MimeTypes.AUDIO_FLAC, 2741000, 33); testFlac(false, true, false);
parseFile(FLAC_TEST_FILE, true, false, true, MimeTypes.AUDIO_FLAC, 2741000, 33); testFlac(true, false, true);
parseFile(FLAC_TEST_FILE, true, true, true, MimeTypes.AUDIO_FLAC, 2741000, 33); testFlac(true, true, true);
}
private void testFlac(boolean simulateIOErrors, boolean simulateUnknownLength,
boolean simulatePartialReads) throws Exception {
FakeTrackOutput trackOutput = parseFile(FLAC_TEST_FILE, simulateIOErrors, simulateUnknownLength,
simulatePartialReads, MimeTypes.AUDIO_FLAC, 2741000, 33);
for (int i = 0; i < 33; i++) {
byte[] sampleData = trackOutput.getSampleData(i);
assertTrue(FlacReader.isAudioPacket(sampleData));
}
} }
public void testFlacNoSeektable() throws Exception { public void testFlacNoSeektable() throws Exception {
@ -56,10 +66,9 @@ public final class OggExtractorFileTests extends InstrumentationTestCase {
parseFile(FLAC_NS_TEST_FILE, true, true, true, MimeTypes.AUDIO_FLAC, C.UNSET_TIME_US, 33); parseFile(FLAC_NS_TEST_FILE, true, true, true, MimeTypes.AUDIO_FLAC, C.UNSET_TIME_US, 33);
} }
private void parseFile(String testFile, boolean simulateIOErrors, boolean simulateUnknownLength, private FakeTrackOutput parseFile(String testFile, boolean simulateIOErrors,
boolean simulatePartialReads, String expectedMimeType, long expectedDuration, boolean simulateUnknownLength, boolean simulatePartialReads, String expectedMimeType,
int expectedSampleCount) long expectedDuration, int expectedSampleCount) throws Exception {
throws Exception {
byte[] fileData = TestUtil.getByteArray(getInstrumentation(), testFile); byte[] fileData = TestUtil.getByteArray(getInstrumentation(), testFile);
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(fileData) FakeExtractorInput input = new FakeExtractorInput.Builder().setData(fileData)
.setSimulateIOErrors(simulateIOErrors) .setSimulateIOErrors(simulateIOErrors)
@ -89,6 +98,7 @@ public final class OggExtractorFileTests extends InstrumentationTestCase {
assertEquals(expectedDuration != C.UNSET_TIME_US, seekMap.isSeekable()); assertEquals(expectedDuration != C.UNSET_TIME_US, seekMap.isSeekable());
trackOutput.assertSampleCount(expectedSampleCount); trackOutput.assertSampleCount(expectedSampleCount);
return trackOutput;
} }
} }

View File

@ -21,7 +21,6 @@ import com.google.android.exoplayer.extractor.TrackOutput;
import com.google.android.exoplayer.util.ParsableByteArray; import com.google.android.exoplayer.util.ParsableByteArray;
import android.test.MoreAsserts; import android.test.MoreAsserts;
import junit.framework.Assert; import junit.framework.Assert;
import java.io.IOException; import java.io.IOException;
@ -86,8 +85,7 @@ public final class FakeTrackOutput implements TrackOutput {
} }
public void assertSample(int index, byte[] data, long timeUs, int flags, byte[] encryptionKey) { public void assertSample(int index, byte[] data, long timeUs, int flags, byte[] encryptionKey) {
byte[] actualData = Arrays.copyOfRange(sampleData, sampleStartOffsets.get(index), byte[] actualData = getSampleData(index);
sampleEndOffsets.get(index));
MoreAsserts.assertEquals(data, actualData); MoreAsserts.assertEquals(data, actualData);
Assert.assertEquals(timeUs, (long) sampleTimesUs.get(index)); Assert.assertEquals(timeUs, (long) sampleTimesUs.get(index));
Assert.assertEquals(flags, (int) sampleFlags.get(index)); Assert.assertEquals(flags, (int) sampleFlags.get(index));
@ -99,6 +97,11 @@ public final class FakeTrackOutput implements TrackOutput {
} }
} }
public byte[] getSampleData(int index) {
return Arrays.copyOfRange(sampleData, sampleStartOffsets.get(index),
sampleEndOffsets.get(index));
}
public void assertEquals(FakeTrackOutput expected) { public void assertEquals(FakeTrackOutput expected) {
Assert.assertEquals(expected.format, format); Assert.assertEquals(expected.format, format);
Assert.assertEquals(expected.sampleTimesUs.size(), sampleTimesUs.size()); Assert.assertEquals(expected.sampleTimesUs.size(), sampleTimesUs.size());

View File

@ -47,9 +47,14 @@ import java.util.List;
data.readUnsignedInt() == 0x464C4143; // ASCII signature "FLAC" data.readUnsignedInt() == 0x464C4143; // ASCII signature "FLAC"
} }
//@VisibleForTesting
public static boolean isAudioPacket(byte[] data) {
return data[0] == AUDIO_PACKET_TYPE;
}
@Override @Override
protected long preparePayload(ParsableByteArray packet) { protected long preparePayload(ParsableByteArray packet) {
if (packet.data[0] != AUDIO_PACKET_TYPE) { if (!isAudioPacket(packet.data)) {
return -1; return -1;
} }
return getFlacFrameBlockSize(packet); return getFlacFrameBlockSize(packet);
@ -71,7 +76,7 @@ import java.util.List;
Assertions.checkArgument(flacOggSeeker == null); Assertions.checkArgument(flacOggSeeker == null);
flacOggSeeker = new FlacOggSeeker(); flacOggSeeker = new FlacOggSeeker();
flacOggSeeker.parseSeekTable(packet); flacOggSeeker.parseSeekTable(packet);
} else if (data[0] == AUDIO_PACKET_TYPE) { } else if (isAudioPacket(data)) {
if (flacOggSeeker != null) { if (flacOggSeeker != null) {
flacOggSeeker.setFirstFrameOffset(position); flacOggSeeker.setFirstFrameOffset(position);
setupData.oggSeeker = flacOggSeeker; setupData.oggSeeker = flacOggSeeker;
@ -96,11 +101,9 @@ import java.util.List;
// skip the sample number // skip the sample number
packet.skipBytes(FRAME_HEADER_SAMPLE_NUMBER_OFFSET); packet.skipBytes(FRAME_HEADER_SAMPLE_NUMBER_OFFSET);
packet.readUtf8EncodedLong(); packet.readUtf8EncodedLong();
if (blockSizeCode == 6) { int value = blockSizeCode == 6 ? packet.readUnsignedByte() : packet.readUnsignedShort();
return packet.readUnsignedByte() + 1; packet.setPosition(0);
} else { return value + 1;
return packet.readUnsignedShort() + 1;
}
case 8: case 8:
case 9: case 9:
case 10: case 10: