Refactor IndexSeeker to utilize IndexSeekMap, removing redundant code

This is a no-op change.

PiperOrigin-RevId: 660370824
This commit is contained in:
rohks 2024-08-07 06:48:28 -07:00 committed by Copybara-Service
parent 8f8e48731e
commit 9bc199f107
2 changed files with 53 additions and 32 deletions

View File

@ -32,7 +32,8 @@ public final class IndexSeekMap implements SeekMap {
private final LongArray positions; private final LongArray positions;
private final LongArray timesUs; private final LongArray timesUs;
private final long durationUs;
private long durationUs;
/** /**
* Creates an instance. * Creates an instance.
@ -103,4 +104,38 @@ public final class IndexSeekMap implements SeekMap {
positions.add(position); positions.add(position);
timesUs.add(timeUs); timesUs.add(timeUs);
} }
/**
* Maps a position (byte offset) to a corresponding sample timestamp.
*
* @param position A seek position (byte offset) relative to the start of the stream.
* @return The corresponding timestamp of the sample at or before the given position, in
* microseconds, or the timestamp of the last available sample in the seek map if the position
* is past the last seek point added, or {@link C#TIME_UNSET} if no seek points exist.
*/
public long getTimeUs(long position) {
if (timesUs.size() == 0) {
return C.TIME_UNSET;
}
int targetIndex =
Util.binarySearchFloor(
positions, position, /* inclusive= */ true, /* stayInBounds= */ true);
return timesUs.get(targetIndex);
}
/**
* Returns the timestamp of the last seek point added, in microseconds, or {@link C#TIME_UNSET} if
* no seek points exist.
*/
public long getLastSeekPointTimeUs() {
if (timesUs.size() == 0) {
return C.TIME_UNSET;
}
return timesUs.get(timesUs.size() - 1);
}
/** Sets the duration of the input stream, or {@link C#TIME_UNSET} if it is unknown. */
public void setDurationUs(long durationUs) {
this.durationUs = durationUs;
}
} }

View File

@ -15,11 +15,12 @@
*/ */
package androidx.media3.extractor.mp3; package androidx.media3.extractor.mp3;
import static androidx.media3.common.util.Assertions.checkState;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.media3.common.C; import androidx.media3.common.C;
import androidx.media3.common.util.LongArray;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
import androidx.media3.extractor.SeekPoint; import androidx.media3.extractor.IndexSeekMap;
import java.math.RoundingMode; import java.math.RoundingMode;
/** MP3 seeker that builds a time-to-byte mapping as the stream is read. */ /** MP3 seeker that builds a time-to-byte mapping as the stream is read. */
@ -29,19 +30,16 @@ import java.math.RoundingMode;
/* package */ static final long MIN_TIME_BETWEEN_POINTS_US = C.MICROS_PER_SECOND / 10; /* package */ static final long MIN_TIME_BETWEEN_POINTS_US = C.MICROS_PER_SECOND / 10;
private final long dataEndPosition; private final long dataEndPosition;
private final LongArray timesUs;
private final LongArray positions;
private final int averageBitrate; private final int averageBitrate;
private final IndexSeekMap indexSeekMap;
private long durationUs;
public IndexSeeker(long durationUs, long dataStartPosition, long dataEndPosition) { public IndexSeeker(long durationUs, long dataStartPosition, long dataEndPosition) {
this.durationUs = durationUs; this.indexSeekMap =
new IndexSeekMap(
/* positions= */ new long[] {dataStartPosition},
/* timesUs= */ new long[] {0L},
durationUs);
this.dataEndPosition = dataEndPosition; this.dataEndPosition = dataEndPosition;
timesUs = new LongArray();
positions = new LongArray();
timesUs.add(0L);
positions.add(dataStartPosition);
if (durationUs != C.TIME_UNSET) { if (durationUs != C.TIME_UNSET) {
long bitrate = long bitrate =
Util.scaleLargeValue( Util.scaleLargeValue(
@ -55,10 +53,7 @@ import java.math.RoundingMode;
@Override @Override
public long getTimeUs(long position) { public long getTimeUs(long position) {
int targetIndex = return indexSeekMap.getTimeUs(position);
Util.binarySearchFloor(
positions, position, /* inclusive= */ true, /* stayInBounds= */ true);
return timesUs.get(targetIndex);
} }
@Override @Override
@ -68,26 +63,17 @@ import java.math.RoundingMode;
@Override @Override
public boolean isSeekable() { public boolean isSeekable() {
return true; return indexSeekMap.isSeekable();
} }
@Override @Override
public long getDurationUs() { public long getDurationUs() {
return durationUs; return indexSeekMap.getDurationUs();
} }
@Override @Override
public SeekPoints getSeekPoints(long timeUs) { public SeekPoints getSeekPoints(long timeUs) {
int targetIndex = return indexSeekMap.getSeekPoints(timeUs);
Util.binarySearchFloor(timesUs, timeUs, /* inclusive= */ true, /* stayInBounds= */ true);
SeekPoint seekPoint = new SeekPoint(timesUs.get(targetIndex), positions.get(targetIndex));
if (seekPoint.timeUs == timeUs || targetIndex == timesUs.size() - 1) {
return new SeekPoints(seekPoint);
} else {
SeekPoint nextSeekPoint =
new SeekPoint(timesUs.get(targetIndex + 1), positions.get(targetIndex + 1));
return new SeekPoints(seekPoint, nextSeekPoint);
}
} }
@Override @Override
@ -107,8 +93,7 @@ import java.math.RoundingMode;
if (isTimeUsInIndex(timeUs)) { if (isTimeUsInIndex(timeUs)) {
return; return;
} }
timesUs.add(timeUs); indexSeekMap.addSeekPoint(timeUs, position);
positions.add(position);
} }
/** /**
@ -118,11 +103,12 @@ import java.math.RoundingMode;
* sufficiently close to the last point. * sufficiently close to the last point.
*/ */
public boolean isTimeUsInIndex(long timeUs) { public boolean isTimeUsInIndex(long timeUs) {
long lastIndexedTimeUs = timesUs.get(timesUs.size() - 1); long lastIndexedTimeUs = indexSeekMap.getLastSeekPointTimeUs();
checkState(lastIndexedTimeUs != C.TIME_UNSET);
return timeUs - lastIndexedTimeUs < MIN_TIME_BETWEEN_POINTS_US; return timeUs - lastIndexedTimeUs < MIN_TIME_BETWEEN_POINTS_US;
} }
/* package */ void setDurationUs(long durationUs) { /* package */ void setDurationUs(long durationUs) {
this.durationUs = durationUs; indexSeekMap.setDurationUs(durationUs);
} }
} }