Noop cleanup of binary seeking / duration reading.
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
This commit is contained in:
parent
0311e153f3
commit
177f3883e9
@ -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.
|
||||
*/
|
||||
@ -231,22 +216,22 @@ public abstract class BinarySearchSeeker {
|
||||
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);
|
||||
@ -433,45 +418,49 @@ public abstract class BinarySearchSeeker {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -484,7 +473,7 @@ public abstract class BinarySearchSeeker {
|
||||
public static TimestampSearchResult overestimatedResult(
|
||||
long newCeilingTimestamp, long newCeilingBytePosition) {
|
||||
return new TimestampSearchResult(
|
||||
RESULT_POSITION_OVERESTIMATED, newCeilingTimestamp, newCeilingBytePosition);
|
||||
TYPE_POSITION_OVERESTIMATED, newCeilingTimestamp, newCeilingBytePosition);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -495,11 +484,11 @@ public abstract class BinarySearchSeeker {
|
||||
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
|
||||
@ -508,7 +497,7 @@ public abstract class BinarySearchSeeker {
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,10 +53,9 @@ import java.io.IOException;
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
@ -73,10 +72,10 @@ import java.io.IOException;
|
||||
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);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ import java.io.IOException;
|
||||
*/
|
||||
/* 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;
|
||||
@ -56,7 +56,7 @@ import java.io.IOException;
|
||||
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. */
|
||||
@ -136,16 +136,16 @@ import java.io.IOException;
|
||||
|
||||
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;
|
||||
@ -172,17 +172,17 @@ import java.io.IOException;
|
||||
|
||||
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;
|
||||
|
@ -33,10 +33,8 @@ import java.io.IOException;
|
||||
/* 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) {
|
||||
@ -56,10 +54,10 @@ import java.io.IOException;
|
||||
* 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 {
|
||||
|
||||
@ -78,10 +76,10 @@ import java.io.IOException;
|
||||
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);
|
||||
}
|
||||
|
@ -35,8 +35,7 @@ import java.io.IOException;
|
||||
*/
|
||||
/* 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;
|
||||
@ -54,7 +53,7 @@ import java.io.IOException;
|
||||
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. */
|
||||
@ -124,16 +123,16 @@ import java.io.IOException;
|
||||
|
||||
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;
|
||||
@ -159,17 +158,17 @@ import java.io.IOException;
|
||||
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user