Skip to content

Commit

Permalink
Noop cleanup of binary seeking / duration reading.
Browse files Browse the repository at this point in the history
This is a precursor for fixing the ref'd issue. These classes are
well tested, so the tests passing should give you reasonable
confidence I didn't break anything :).

Issue: #5097

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=221435824
  • Loading branch information
ojw28 committed Nov 14, 2018
1 parent c20b157 commit 866b088
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,16 @@ public abstract class BinarySearchSeeker {
protected interface TimestampSeeker {

/**
* Searches for a given timestamp from the input.
* Searches a limited window of the provided input for a target timestamp. The size of the
* window is implementation specific, but should be small enough such that it's reasonable for
* multiple such reads to occur during a seek operation.
*
* <p>Given a target timestamp and an input stream, this seeker will try to read up to a range
* of {@code searchRangeBytes} bytes from that input, look for all available timestamps from all
* frames in that range, compare those with the target timestamp, and return one of the {@link
* TimestampSearchResult}.
*
* @param input The {@link ExtractorInput} from which data should be read.
* @param targetTimestamp The target timestamp that we are looking for.
* @param outputFrameHolder If {@link TimestampSearchResult#RESULT_TARGET_TIMESTAMP_FOUND} is
* @param input The {@link ExtractorInput} from which data should be peeked.
* @param targetTimestamp The target timestamp.
* @param outputFrameHolder If {@link TimestampSearchResult#TYPE_TARGET_TIMESTAMP_FOUND} is
* returned, this holder may be updated to hold the extracted frame that contains the target
* frame/sample associated with the target timestamp.
* @return A {@link TimestampSearchResult}, that includes a {@link TimestampSearchResult#result}
* value, and other necessary info:
* <ul>
* <li>{@link TimestampSearchResult#RESULT_NO_TIMESTAMP} is returned if there is no
* timestamp in the reading range.
* <li>{@link TimestampSearchResult#RESULT_POSITION_UNDERESTIMATED} is returned if all
* timestamps in the range are smaller than the target timestamp.
* <li>{@link TimestampSearchResult#RESULT_POSITION_OVERESTIMATED} is returned if all
* timestamps in the range are larger than the target timestamp.
* <li>{@link TimestampSearchResult#RESULT_TARGET_TIMESTAMP_FOUND} is returned if this
* seeker can find a timestamp that it deems close enough to the given target.
* </ul>
*
* @return A {@link TimestampSearchResult} that describes the result of the search.
* @throws IOException If an error occurred reading from the input.
* @throws InterruptedException If the thread was interrupted.
*/
Expand Down Expand Up @@ -232,22 +217,22 @@ public int handlePendingSeek(
timestampSeeker.searchForTimestamp(
input, seekOperationParams.getTargetTimePosition(), outputFrameHolder);

switch (timestampSearchResult.result) {
case TimestampSearchResult.RESULT_POSITION_OVERESTIMATED:
switch (timestampSearchResult.type) {
case TimestampSearchResult.TYPE_POSITION_OVERESTIMATED:
seekOperationParams.updateSeekCeiling(
timestampSearchResult.timestampToUpdate, timestampSearchResult.bytePositionToUpdate);
break;
case TimestampSearchResult.RESULT_POSITION_UNDERESTIMATED:
case TimestampSearchResult.TYPE_POSITION_UNDERESTIMATED:
seekOperationParams.updateSeekFloor(
timestampSearchResult.timestampToUpdate, timestampSearchResult.bytePositionToUpdate);
break;
case TimestampSearchResult.RESULT_TARGET_TIMESTAMP_FOUND:
case TimestampSearchResult.TYPE_TARGET_TIMESTAMP_FOUND:
markSeekOperationFinished(
/* foundTargetFrame= */ true, timestampSearchResult.bytePositionToUpdate);
skipInputUntilPosition(input, timestampSearchResult.bytePositionToUpdate);
return seekToPosition(
input, timestampSearchResult.bytePositionToUpdate, seekPositionHolder);
case TimestampSearchResult.RESULT_NO_TIMESTAMP:
case TimestampSearchResult.TYPE_NO_TIMESTAMP:
// We can't find any timestamp in the search range from the search position.
// Give up, and just continue reading from the last search position in this case.
markSeekOperationFinished(/* foundTargetFrame= */ false, searchPosition);
Expand Down Expand Up @@ -434,45 +419,49 @@ private void updateNextSearchBytePosition() {
*/
public static final class TimestampSearchResult {

public static final int RESULT_TARGET_TIMESTAMP_FOUND = 0;
public static final int RESULT_POSITION_OVERESTIMATED = -1;
public static final int RESULT_POSITION_UNDERESTIMATED = -2;
public static final int RESULT_NO_TIMESTAMP = -3;
/** The search found a timestamp that it deems close enough to the given target. */
public static final int TYPE_TARGET_TIMESTAMP_FOUND = 0;
/** The search found only timestamps larger than the target timestamp. */
public static final int TYPE_POSITION_OVERESTIMATED = -1;
/** The search found only timestamps smaller than the target timestamp. */
public static final int TYPE_POSITION_UNDERESTIMATED = -2;
/** The search didn't find any timestamps. */
public static final int TYPE_NO_TIMESTAMP = -3;

@Documented
@Retention(RetentionPolicy.SOURCE)
@IntDef({
RESULT_TARGET_TIMESTAMP_FOUND,
RESULT_POSITION_OVERESTIMATED,
RESULT_POSITION_UNDERESTIMATED,
RESULT_NO_TIMESTAMP
TYPE_TARGET_TIMESTAMP_FOUND,
TYPE_POSITION_OVERESTIMATED,
TYPE_POSITION_UNDERESTIMATED,
TYPE_NO_TIMESTAMP
})
@interface SearchResult {}
@interface Type {}

public static final TimestampSearchResult NO_TIMESTAMP_IN_RANGE_RESULT =
new TimestampSearchResult(RESULT_NO_TIMESTAMP, C.TIME_UNSET, C.POSITION_UNSET);
new TimestampSearchResult(TYPE_NO_TIMESTAMP, C.TIME_UNSET, C.POSITION_UNSET);

/** @see TimestampSeeker */
private final @SearchResult int result;
/** The type of the result. */
@Type private final int type;

/**
* When {@code result} is {@link #RESULT_POSITION_OVERESTIMATED}, the {@link
* SeekOperationParams#ceilingTimePosition} should be updated with this value. When {@code
* result} is {@link #RESULT_POSITION_UNDERESTIMATED}, the {@link
* When {@link #type} is {@link #TYPE_POSITION_OVERESTIMATED}, the {@link
* SeekOperationParams#ceilingTimePosition} should be updated with this value. When {@link
* #type} is {@link #TYPE_POSITION_UNDERESTIMATED}, the {@link
* SeekOperationParams#floorTimePosition} should be updated with this value.
*/
private final long timestampToUpdate;
/**
* When {@code result} is {@link #RESULT_POSITION_OVERESTIMATED}, the {@link
* SeekOperationParams#ceilingBytePosition} should be updated with this value. When {@code
* result} is {@link #RESULT_POSITION_UNDERESTIMATED}, the {@link
* When {@link #type} is {@link #TYPE_POSITION_OVERESTIMATED}, the {@link
* SeekOperationParams#ceilingBytePosition} should be updated with this value. When {@link
* #type} is {@link #TYPE_POSITION_UNDERESTIMATED}, the {@link
* SeekOperationParams#floorBytePosition} should be updated with this value.
*/
private final long bytePositionToUpdate;

private TimestampSearchResult(
@SearchResult int result, long timestampToUpdate, long bytePositionToUpdate) {
this.result = result;
@Type int type, long timestampToUpdate, long bytePositionToUpdate) {
this.type = type;
this.timestampToUpdate = timestampToUpdate;
this.bytePositionToUpdate = bytePositionToUpdate;
}
Expand All @@ -485,7 +474,7 @@ private TimestampSearchResult(
public static TimestampSearchResult overestimatedResult(
long newCeilingTimestamp, long newCeilingBytePosition) {
return new TimestampSearchResult(
RESULT_POSITION_OVERESTIMATED, newCeilingTimestamp, newCeilingBytePosition);
TYPE_POSITION_OVERESTIMATED, newCeilingTimestamp, newCeilingBytePosition);
}

/**
Expand All @@ -496,11 +485,11 @@ public static TimestampSearchResult overestimatedResult(
public static TimestampSearchResult underestimatedResult(
long newFloorTimestamp, long newCeilingBytePosition) {
return new TimestampSearchResult(
RESULT_POSITION_UNDERESTIMATED, newFloorTimestamp, newCeilingBytePosition);
TYPE_POSITION_UNDERESTIMATED, newFloorTimestamp, newCeilingBytePosition);
}

/**
* Returns a result to signal that the target timestamp has been found at the {@code
* Returns a result to signal that the target timestamp has been found at {@code
* resultBytePosition}, and the seek operation can stop.
*
* <p>Note that when this value is returned from {@link
Expand All @@ -509,7 +498,7 @@ public static TimestampSearchResult underestimatedResult(
*/
public static TimestampSearchResult targetFoundResult(long resultBytePosition) {
return new TimestampSearchResult(
RESULT_TARGET_TIMESTAMP_FOUND, C.TIME_UNSET, resultBytePosition);
TYPE_TARGET_TIMESTAMP_FOUND, C.TIME_UNSET, resultBytePosition);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ public PsBinarySearchSeeker(
/**
* A seeker that looks for a given SCR timestamp at a given position in a PS stream.
*
* <p>Given a SCR timestamp, and a position within a PS stream, this seeker will try to read a
* range of up to {@link #TIMESTAMP_SEARCH_BYTES} bytes from that stream position, look for all
* packs in that range, and then compare the SCR timestamps (if available) of these packets vs the
* target timestamp.
* <p>Given a SCR timestamp, and a position within a PS stream, this seeker will peek up to {@link
* #TIMESTAMP_SEARCH_BYTES} bytes from that stream position, look for all packs in that range, and
* then compare the SCR timestamps (if available) of these packets to the target timestamp.
*/
private static final class PsScrSeeker implements TimestampSeeker {

Expand All @@ -73,10 +72,10 @@ public TimestampSearchResult searchForTimestamp(
ExtractorInput input, long targetTimestamp, OutputFrameHolder outputFrameHolder)
throws IOException, InterruptedException {
long inputPosition = input.getPosition();
int bytesToRead =
(int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - input.getPosition());
packetBuffer.reset(bytesToRead);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToRead);
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);

input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

return searchForScrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
*/
/* package */ final class PsDurationReader {

private static final int DURATION_READ_BYTES = 20000;
private static final int TIMESTAMP_SEARCH_BYTES = 20000;

private final TimestampAdjuster scrTimestampAdjuster;
private final ParsableByteArray packetBuffer;
Expand All @@ -56,7 +56,7 @@
firstScrValue = C.TIME_UNSET;
lastScrValue = C.TIME_UNSET;
durationUs = C.TIME_UNSET;
packetBuffer = new ParsableByteArray(DURATION_READ_BYTES);
packetBuffer = new ParsableByteArray(TIMESTAMP_SEARCH_BYTES);
}

/** Returns true if a PS duration has been read. */
Expand Down Expand Up @@ -136,16 +136,16 @@ private int finishReadDuration(ExtractorInput input) {

private int readFirstScrValue(ExtractorInput input, PositionHolder seekPositionHolder)
throws IOException, InterruptedException {
if (input.getPosition() != 0) {
seekPositionHolder.position = 0;
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength());
int searchStartPosition = 0;
if (input.getPosition() != searchStartPosition) {
seekPositionHolder.position = searchStartPosition;
return Extractor.RESULT_SEEK;
}

int bytesToRead = (int) Math.min(DURATION_READ_BYTES, input.getLength());
input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToRead);
packetBuffer.setPosition(0);
packetBuffer.setLimit(bytesToRead);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

firstScrValue = readFirstScrValueFromBuffer(packetBuffer);
isFirstScrValueRead = true;
Expand All @@ -172,17 +172,17 @@ private long readFirstScrValueFromBuffer(ParsableByteArray packetBuffer) {

private int readLastScrValue(ExtractorInput input, PositionHolder seekPositionHolder)
throws IOException, InterruptedException {
int bytesToRead = (int) Math.min(DURATION_READ_BYTES, input.getLength());
long bufferStartStreamPosition = input.getLength() - bytesToRead;
if (input.getPosition() != bufferStartStreamPosition) {
seekPositionHolder.position = bufferStartStreamPosition;
long inputLength = input.getLength();
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, inputLength);
long searchStartPosition = inputLength - bytesToSearch;
if (input.getPosition() != searchStartPosition) {
seekPositionHolder.position = searchStartPosition;
return Extractor.RESULT_SEEK;
}

input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToRead);
packetBuffer.setPosition(0);
packetBuffer.setLimit(bytesToRead);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

lastScrValue = readLastScrValueFromBuffer(packetBuffer);
isLastScrValueRead = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@
/* package */ final class TsBinarySearchSeeker extends BinarySearchSeeker {

private static final long SEEK_TOLERANCE_US = 100_000;
private static final int MINIMUM_SEARCH_RANGE_BYTES = TsExtractor.TS_PACKET_SIZE * 5;
private static final int TIMESTAMP_SEARCH_PACKETS = 200;
private static final int TIMESTAMP_SEARCH_BYTES =
TsExtractor.TS_PACKET_SIZE * TIMESTAMP_SEARCH_PACKETS;
private static final int MINIMUM_SEARCH_RANGE_BYTES = 5 * TsExtractor.TS_PACKET_SIZE;
private static final int TIMESTAMP_SEARCH_BYTES = 200 * TsExtractor.TS_PACKET_SIZE;

public TsBinarySearchSeeker(
TimestampAdjuster pcrTimestampAdjuster, long streamDurationUs, long inputLength, int pcrPid) {
Expand All @@ -56,10 +54,10 @@ public TsBinarySearchSeeker(
* A {@link TimestampSeeker} implementation that looks for a given PCR timestamp at a given
* position in a TS stream.
*
* <p>Given a PCR timestamp, and a position within a TS stream, this seeker will try to read up to
* {@link #TIMESTAMP_SEARCH_PACKETS} TS packets from that stream position, look for all packet
* with PID equals to PCR_PID, and then compare the PCR timestamps (if available) of these packets
* vs the target timestamp.
* <p>Given a PCR timestamp, and a position within a TS stream, this seeker will peek up to {@link
* #TIMESTAMP_SEARCH_BYTES} from that stream position, look for all packets with PID equal to
* PCR_PID, and then compare the PCR timestamps (if available) of these packets to the target
* timestamp.
*/
private static final class TsPcrSeeker implements TimestampSeeker {

Expand All @@ -78,10 +76,10 @@ public TimestampSearchResult searchForTimestamp(
ExtractorInput input, long targetTimestamp, OutputFrameHolder outputFrameHolder)
throws IOException, InterruptedException {
long inputPosition = input.getPosition();
int bytesToRead =
(int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - input.getPosition());
packetBuffer.reset(bytesToRead);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToRead);
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength() - inputPosition);

input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

return searchForPcrValueInBuffer(packetBuffer, targetTimestamp, inputPosition);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@
*/
/* package */ final class TsDurationReader {

private static final int DURATION_READ_PACKETS = 200;
private static final int DURATION_READ_BYTES = TsExtractor.TS_PACKET_SIZE * DURATION_READ_PACKETS;
private static final int TIMESTAMP_SEARCH_BYTES = 200 * TsExtractor.TS_PACKET_SIZE;

private final TimestampAdjuster pcrTimestampAdjuster;
private final ParsableByteArray packetBuffer;
Expand All @@ -54,7 +53,7 @@
firstPcrValue = C.TIME_UNSET;
lastPcrValue = C.TIME_UNSET;
durationUs = C.TIME_UNSET;
packetBuffer = new ParsableByteArray(DURATION_READ_BYTES);
packetBuffer = new ParsableByteArray(TIMESTAMP_SEARCH_BYTES);
}

/** Returns true if a TS duration has been read. */
Expand Down Expand Up @@ -124,16 +123,16 @@ private int finishReadDuration(ExtractorInput input) {

private int readFirstPcrValue(ExtractorInput input, PositionHolder seekPositionHolder, int pcrPid)
throws IOException, InterruptedException {
if (input.getPosition() != 0) {
seekPositionHolder.position = 0;
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, input.getLength());
int searchStartPosition = 0;
if (input.getPosition() != searchStartPosition) {
seekPositionHolder.position = searchStartPosition;
return Extractor.RESULT_SEEK;
}

int bytesToRead = (int) Math.min(DURATION_READ_BYTES, input.getLength());
input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToRead);
packetBuffer.setPosition(0);
packetBuffer.setLimit(bytesToRead);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

firstPcrValue = readFirstPcrValueFromBuffer(packetBuffer, pcrPid);
isFirstPcrValueRead = true;
Expand All @@ -159,17 +158,17 @@ private long readFirstPcrValueFromBuffer(ParsableByteArray packetBuffer, int pcr

private int readLastPcrValue(ExtractorInput input, PositionHolder seekPositionHolder, int pcrPid)
throws IOException, InterruptedException {
int bytesToRead = (int) Math.min(DURATION_READ_BYTES, input.getLength());
long bufferStartStreamPosition = input.getLength() - bytesToRead;
if (input.getPosition() != bufferStartStreamPosition) {
seekPositionHolder.position = bufferStartStreamPosition;
long inputLength = input.getLength();
int bytesToSearch = (int) Math.min(TIMESTAMP_SEARCH_BYTES, inputLength);
long searchStartPosition = inputLength - bytesToSearch;
if (input.getPosition() != searchStartPosition) {
seekPositionHolder.position = searchStartPosition;
return Extractor.RESULT_SEEK;
}

input.resetPeekPosition();
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToRead);
packetBuffer.setPosition(0);
packetBuffer.setLimit(bytesToRead);
input.peekFully(packetBuffer.data, /* offset= */ 0, bytesToSearch);
packetBuffer.reset(bytesToSearch);

lastPcrValue = readLastPcrValueFromBuffer(packetBuffer, pcrPid);
isLastPcrValueRead = true;
Expand Down

0 comments on commit 866b088

Please sign in to comment.