Commit 1055c520 by olly Committed by Oliver Woodman

Remove side effects from SeekMap.getPosition implementations

Issue: #2167

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=141451444
parent f4575187
...@@ -45,7 +45,6 @@ import java.io.IOException; ...@@ -45,7 +45,6 @@ import java.io.IOException;
private int state; private int state;
private long totalGranules; private long totalGranules;
private volatile long queriedGranule;
private long positionBeforeSeekToEnd; private long positionBeforeSeekToEnd;
private long targetGranule; private long targetGranule;
...@@ -114,9 +113,9 @@ import java.io.IOException; ...@@ -114,9 +113,9 @@ import java.io.IOException;
} }
@Override @Override
public long startSeek() { public long startSeek(long timeUs) {
Assertions.checkArgument(state == STATE_IDLE || state == STATE_SEEK); Assertions.checkArgument(state == STATE_IDLE || state == STATE_SEEK);
targetGranule = queriedGranule; targetGranule = timeUs == 0 ? 0 : streamReader.convertTimeToGranule(timeUs);
state = STATE_SEEK; state = STATE_SEEK;
resetSeeking(); resetSeeking();
return targetGranule; return targetGranule;
...@@ -222,11 +221,10 @@ import java.io.IOException; ...@@ -222,11 +221,10 @@ import java.io.IOException;
@Override @Override
public long getPosition(long timeUs) { public long getPosition(long timeUs) {
if (timeUs == 0) { if (timeUs == 0) {
queriedGranule = 0;
return startPosition; return startPosition;
} }
queriedGranule = streamReader.convertTimeToGranule(timeUs); long granule = streamReader.convertTimeToGranule(timeUs);
return getEstimatedPosition(startPosition, queriedGranule, DEFAULT_OFFSET); return getEstimatedPosition(startPosition, granule, DEFAULT_OFFSET);
} }
@Override @Override
......
...@@ -127,12 +127,15 @@ import java.util.List; ...@@ -127,12 +127,15 @@ import java.util.List;
private static final int METADATA_LENGTH_OFFSET = 1; private static final int METADATA_LENGTH_OFFSET = 1;
private static final int SEEK_POINT_SIZE = 18; private static final int SEEK_POINT_SIZE = 18;
private long[] sampleNumbers; private long[] seekPointGranules;
private long[] offsets; private long[] seekPointOffsets;
private long firstFrameOffset = -1; private long firstFrameOffset;
private volatile long queriedGranule; private long pendingSeekGranule;
private volatile long seekedGranule;
private long currentGranule = -1; public FlacOggSeeker() {
firstFrameOffset = -1;
pendingSeekGranule = -1;
}
public void setFirstFrameOffset(long firstFrameOffset) { public void setFirstFrameOffset(long firstFrameOffset) {
this.firstFrameOffset = firstFrameOffset; this.firstFrameOffset = firstFrameOffset;
...@@ -141,40 +144,40 @@ import java.util.List; ...@@ -141,40 +144,40 @@ import java.util.List;
/** /**
* Parses a FLAC file seek table metadata structure and initializes internal fields. * Parses a FLAC file seek table metadata structure and initializes internal fields.
* *
* @param data * @param data A {@link ParsableByteArray} including whole seek table metadata block. Its
* A ParsableByteArray including whole seek table metadata block. Its position should be set * position should be set to the beginning of the block.
* to the beginning of the block.
* @see <a href="https://xiph.org/flac/format.html#metadata_block_seektable">FLAC format * @see <a href="https://xiph.org/flac/format.html#metadata_block_seektable">FLAC format
* METADATA_BLOCK_SEEKTABLE</a> * METADATA_BLOCK_SEEKTABLE</a>
*/ */
public void parseSeekTable(ParsableByteArray data) { public void parseSeekTable(ParsableByteArray data) {
data.skipBytes(METADATA_LENGTH_OFFSET); data.skipBytes(METADATA_LENGTH_OFFSET);
int length = data.readUnsignedInt24(); int length = data.readUnsignedInt24();
int numberOfSeekPoints = length / SEEK_POINT_SIZE; int numberOfSeekPoints = length / SEEK_POINT_SIZE;
seekPointGranules = new long[numberOfSeekPoints];
sampleNumbers = new long[numberOfSeekPoints]; seekPointOffsets = new long[numberOfSeekPoints];
offsets = new long[numberOfSeekPoints];
for (int i = 0; i < numberOfSeekPoints; i++) { for (int i = 0; i < numberOfSeekPoints; i++) {
sampleNumbers[i] = data.readLong(); seekPointGranules[i] = data.readLong();
offsets[i] = data.readLong(); seekPointOffsets[i] = data.readLong();
data.skipBytes(2); // Skip "Number of samples in the target frame." data.skipBytes(2); // Skip "Number of samples in the target frame."
} }
} }
@Override @Override
public long read(ExtractorInput input) throws IOException, InterruptedException { public long read(ExtractorInput input) throws IOException, InterruptedException {
if (currentGranule >= 0) { if (pendingSeekGranule >= 0) {
currentGranule = -currentGranule - 2; long result = -(pendingSeekGranule + 2);
return currentGranule; pendingSeekGranule = -1;
return result;
} }
return -1; return -1;
} }
@Override @Override
public synchronized long startSeek() { public long startSeek(long timeUs) {
currentGranule = seekedGranule; long granule = convertTimeToGranule(timeUs);
return queriedGranule; int index = Util.binarySearchFloor(seekPointGranules, granule, true, true);
pendingSeekGranule = seekPointGranules[index];
return granule;
} }
@Override @Override
...@@ -188,11 +191,10 @@ import java.util.List; ...@@ -188,11 +191,10 @@ import java.util.List;
} }
@Override @Override
public synchronized long getPosition(long timeUs) { public long getPosition(long timeUs) {
queriedGranule = convertTimeToGranule(timeUs); long granule = convertTimeToGranule(timeUs);
int index = Util.binarySearchFloor(sampleNumbers, queriedGranule, true, true); int index = Util.binarySearchFloor(seekPointGranules, granule, true, true);
seekedGranule = sampleNumbers[index]; return firstFrameOffset + seekPointOffsets[index];
return firstFrameOffset + offsets[index];
} }
@Override @Override
......
...@@ -83,7 +83,7 @@ public class OggExtractor implements Extractor { ...@@ -83,7 +83,7 @@ public class OggExtractor implements Extractor {
@Override @Override
public void seek(long position, long timeUs) { public void seek(long position, long timeUs) {
streamReader.seek(position); streamReader.seek(position, timeUs);
} }
@Override @Override
......
...@@ -35,9 +35,10 @@ import java.io.IOException; ...@@ -35,9 +35,10 @@ import java.io.IOException;
/** /**
* Initializes a seek operation. * Initializes a seek operation.
* *
* @param timeUs The seek position in microseconds.
* @return The granule position targeted by the seek. * @return The granule position targeted by the seek.
*/ */
long startSeek(); long startSeek(long timeUs);
/** /**
* Reads data from the {@link ExtractorInput} to build the {@link SeekMap} or to continue a * Reads data from the {@link ExtractorInput} to build the {@link SeekMap} or to continue a
......
...@@ -81,15 +81,15 @@ import java.io.IOException; ...@@ -81,15 +81,15 @@ import java.io.IOException;
} }
/** /**
* @see Extractor#seek(long) * @see Extractor#seek(long, long)
*/ */
final void seek(long position) { final void seek(long position, long timeUs) {
oggPacket.reset(); oggPacket.reset();
if (position == 0) { if (position == 0) {
reset(!seekMapSet); reset(!seekMapSet);
} else { } else {
if (state != STATE_READ_HEADERS) { if (state != STATE_READ_HEADERS) {
targetGranule = oggSeeker.startSeek(); targetGranule = oggSeeker.startSeek(timeUs);
state = STATE_READ_PAYLOAD; state = STATE_READ_PAYLOAD;
} }
} }
...@@ -162,7 +162,7 @@ import java.io.IOException; ...@@ -162,7 +162,7 @@ import java.io.IOException;
seekPosition.position = position; seekPosition.position = position;
return Extractor.RESULT_SEEK; return Extractor.RESULT_SEEK;
} else if (position < -1) { } else if (position < -1) {
onSeekEnd(-position - 2); onSeekEnd(-(position + 2));
} }
if (!seekMapSet) { if (!seekMapSet) {
SeekMap seekMap = oggSeeker.createSeekMap(); SeekMap seekMap = oggSeeker.createSeekMap();
...@@ -232,7 +232,7 @@ import java.io.IOException; ...@@ -232,7 +232,7 @@ import java.io.IOException;
/** /**
* Called on end of seeking. * Called on end of seeking.
* *
* @param currentGranule Current granule at the current position of input. * @param currentGranule The granule at the current input position.
*/ */
protected void onSeekEnd(long currentGranule) { protected void onSeekEnd(long currentGranule) {
this.currentGranule = currentGranule; this.currentGranule = currentGranule;
...@@ -246,7 +246,7 @@ import java.io.IOException; ...@@ -246,7 +246,7 @@ import java.io.IOException;
} }
@Override @Override
public long startSeek() { public long startSeek(long timeUs) {
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment