Make IndexSeekMap
dynamic, allowing seek points to be added later
PiperOrigin-RevId: 660324829
This commit is contained in:
parent
5dac58995a
commit
a087f82fa8
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package androidx.media3.common.util;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/** An append-only, auto-growing {@code long[]}. */
|
||||
@ -49,6 +51,20 @@ public final class LongArray {
|
||||
values[size++] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends all elements of the specified array.
|
||||
*
|
||||
* @param values The array whose elements are to be added.
|
||||
*/
|
||||
public void addAll(long[] values) {
|
||||
int newSize = size + values.length;
|
||||
if (newSize > this.values.length) {
|
||||
this.values = Arrays.copyOf(this.values, max(this.values.length * 2, newSize));
|
||||
}
|
||||
System.arraycopy(values, 0, this.values, size, values.length);
|
||||
size = newSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at a specified index.
|
||||
*
|
||||
|
@ -19,6 +19,7 @@ package androidx.media3.extractor;
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.util.LongArray;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.common.util.Util;
|
||||
|
||||
@ -29,10 +30,9 @@ import androidx.media3.common.util.Util;
|
||||
@UnstableApi
|
||||
public final class IndexSeekMap implements SeekMap {
|
||||
|
||||
private final long[] positions;
|
||||
private final long[] timesUs;
|
||||
private final LongArray positions;
|
||||
private final LongArray timesUs;
|
||||
private final long durationUs;
|
||||
private final boolean isSeekable;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
@ -44,23 +44,24 @@ public final class IndexSeekMap implements SeekMap {
|
||||
public IndexSeekMap(long[] positions, long[] timesUs, long durationUs) {
|
||||
checkArgument(positions.length == timesUs.length);
|
||||
int length = timesUs.length;
|
||||
isSeekable = length > 0;
|
||||
if (isSeekable && timesUs[0] > 0) {
|
||||
if (length > 0 && timesUs[0] > 0) {
|
||||
// Add (position = 0, timeUs = 0) as first entry.
|
||||
this.positions = new long[length + 1];
|
||||
this.timesUs = new long[length + 1];
|
||||
System.arraycopy(positions, 0, this.positions, 1, length);
|
||||
System.arraycopy(timesUs, 0, this.timesUs, 1, length);
|
||||
this.positions = new LongArray(length + 1);
|
||||
this.timesUs = new LongArray(length + 1);
|
||||
this.positions.add(0L);
|
||||
this.timesUs.add(0L);
|
||||
} else {
|
||||
this.positions = positions;
|
||||
this.timesUs = timesUs;
|
||||
this.positions = new LongArray(length);
|
||||
this.timesUs = new LongArray(length);
|
||||
}
|
||||
this.positions.addAll(positions);
|
||||
this.timesUs.addAll(timesUs);
|
||||
this.durationUs = durationUs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSeekable() {
|
||||
return isSeekable;
|
||||
return timesUs.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,18 +71,36 @@ public final class IndexSeekMap implements SeekMap {
|
||||
|
||||
@Override
|
||||
public SeekMap.SeekPoints getSeekPoints(long timeUs) {
|
||||
if (!isSeekable) {
|
||||
if (timesUs.size() == 0) {
|
||||
return new SeekMap.SeekPoints(SeekPoint.START);
|
||||
}
|
||||
int targetIndex =
|
||||
Util.binarySearchFloor(timesUs, timeUs, /* inclusive= */ true, /* stayInBounds= */ true);
|
||||
SeekPoint leftSeekPoint = new SeekPoint(timesUs[targetIndex], positions[targetIndex]);
|
||||
if (leftSeekPoint.timeUs == timeUs || targetIndex == timesUs.length - 1) {
|
||||
SeekPoint leftSeekPoint = new SeekPoint(timesUs.get(targetIndex), positions.get(targetIndex));
|
||||
if (leftSeekPoint.timeUs == timeUs || targetIndex == timesUs.size() - 1) {
|
||||
return new SeekMap.SeekPoints(leftSeekPoint);
|
||||
} else {
|
||||
SeekPoint rightSeekPoint =
|
||||
new SeekPoint(timesUs[targetIndex + 1], positions[targetIndex + 1]);
|
||||
new SeekPoint(timesUs.get(targetIndex + 1), positions.get(targetIndex + 1));
|
||||
return new SeekMap.SeekPoints(leftSeekPoint, rightSeekPoint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a seek point to the index.
|
||||
*
|
||||
* <p>Seek points must be added in order.
|
||||
*
|
||||
* @param timeUs The time of the seek point in microseconds.
|
||||
* @param position The position in the stream corresponding to the seek point, in bytes.
|
||||
*/
|
||||
public void addSeekPoint(long timeUs, long position) {
|
||||
if (timesUs.size() == 0 && timeUs > 0) {
|
||||
// Add (position = 0, timeUs = 0) as first entry.
|
||||
this.positions.add(0L);
|
||||
this.timesUs.add(0L);
|
||||
}
|
||||
positions.add(position);
|
||||
timesUs.add(timeUs);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user