Add utility methods for inexact ceil/floor binary searches.
This change also fixes issue #5
This commit is contained in:
parent
f1213a7656
commit
1b957268a6
@ -33,6 +33,7 @@ import com.google.android.exoplayer.parser.mp4.FragmentedMp4Extractor;
|
||||
import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.upstream.DataSpec;
|
||||
import com.google.android.exoplayer.upstream.NonBlockingInputStream;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@ -170,8 +171,8 @@ public class DashMp4ChunkSource implements ChunkSource {
|
||||
|
||||
int nextIndex;
|
||||
if (queue.isEmpty()) {
|
||||
nextIndex = Arrays.binarySearch(extractor.getSegmentIndex().timesUs, seekPositionUs);
|
||||
nextIndex = nextIndex < 0 ? -nextIndex - 2 : nextIndex;
|
||||
nextIndex = Util.binarySearchFloor(extractor.getSegmentIndex().timesUs, seekPositionUs,
|
||||
true, true);
|
||||
} else {
|
||||
nextIndex = queue.get(out.queueSize - 1).nextChunkIndex;
|
||||
}
|
||||
@ -196,7 +197,7 @@ public class DashMp4ChunkSource implements ChunkSource {
|
||||
public void onChunkLoadError(Chunk chunk, Exception e) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
|
||||
private static Chunk newInitializationChunk(Representation representation,
|
||||
FragmentedMp4Extractor extractor, DataSource dataSource, int trigger) {
|
||||
DataSpec dataSpec = new DataSpec(representation.uri, 0, representation.indexEnd + 1,
|
||||
|
@ -33,6 +33,7 @@ import com.google.android.exoplayer.parser.webm.WebmExtractor;
|
||||
import com.google.android.exoplayer.upstream.DataSource;
|
||||
import com.google.android.exoplayer.upstream.DataSpec;
|
||||
import com.google.android.exoplayer.upstream.NonBlockingInputStream;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@ -151,8 +152,7 @@ public class DashWebmChunkSource implements ChunkSource {
|
||||
|
||||
int nextIndex;
|
||||
if (queue.isEmpty()) {
|
||||
nextIndex = Arrays.binarySearch(extractor.getCues().timesUs, seekPositionUs);
|
||||
nextIndex = nextIndex < 0 ? -nextIndex - 2 : nextIndex;
|
||||
nextIndex = Util.binarySearchFloor(extractor.getCues().timesUs, seekPositionUs, true, true);
|
||||
} else {
|
||||
nextIndex = queue.get(out.queueSize - 1).nextChunkIndex;
|
||||
}
|
||||
|
@ -16,8 +16,8 @@
|
||||
package com.google.android.exoplayer.smoothstreaming;
|
||||
|
||||
import com.google.android.exoplayer.util.MimeTypes;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -195,9 +195,7 @@ public class SmoothStreamingManifest {
|
||||
* @return The index of the corresponding chunk.
|
||||
*/
|
||||
public int getChunkIndex(long timeUs) {
|
||||
long time = (timeUs * timeScale) / 1000000L;
|
||||
int chunkIndex = Arrays.binarySearch(chunkStartTimes, time);
|
||||
return chunkIndex < 0 ? -chunkIndex - 2 : chunkIndex;
|
||||
return Util.binarySearchFloor(chunkStartTimes, (timeUs * timeScale) / 1000000L, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,8 +16,7 @@
|
||||
package com.google.android.exoplayer.text.ttml;
|
||||
|
||||
import com.google.android.exoplayer.text.Subtitle;
|
||||
|
||||
import java.util.Arrays;
|
||||
import com.google.android.exoplayer.util.Util;
|
||||
|
||||
/**
|
||||
* A representation of a TTML subtitle.
|
||||
@ -41,8 +40,7 @@ public final class TtmlSubtitle implements Subtitle {
|
||||
|
||||
@Override
|
||||
public int getNextEventTimeIndex(long timeUs) {
|
||||
int index = Arrays.binarySearch(eventTimesUs, timeUs - startTimeUs);
|
||||
index = index >= 0 ? index + 1 : ~index;
|
||||
int index = Util.binarySearchCeil(eventTimesUs, timeUs - startTimeUs, false, false);
|
||||
return index < eventTimesUs.length ? index : -1;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,9 @@ import com.google.android.exoplayer.upstream.DataSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
@ -112,4 +115,88 @@ public final class Util {
|
||||
return text == null ? null : text.toLowerCase(Locale.US);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the largest value in an array that is less than (or optionally equal to)
|
||||
* a specified key.
|
||||
* <p>
|
||||
* The search is performed using a binary search algorithm, and so the array must be sorted.
|
||||
*
|
||||
* @param a The array to search.
|
||||
* @param key The key being searched for.
|
||||
* @param inclusive If the key is present in the array, whether to return the corresponding index.
|
||||
* If false then the returned index corresponds to the largest value in the array that is
|
||||
* strictly less than the key.
|
||||
* @param stayInBounds If true, then 0 will be returned in the case that the key is smaller than
|
||||
* the smallest value in the array. If false then -1 will be returned.
|
||||
*/
|
||||
public static int binarySearchFloor(long[] a, long key, boolean inclusive, boolean stayInBounds) {
|
||||
int index = Arrays.binarySearch(a, key);
|
||||
index = index < 0 ? -(index + 2) : (inclusive ? index : (index - 1));
|
||||
return stayInBounds ? Math.max(0, index) : index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the smallest value in an array that is greater than (or optionally equal
|
||||
* to) a specified key.
|
||||
* <p>
|
||||
* The search is performed using a binary search algorithm, and so the array must be sorted.
|
||||
*
|
||||
* @param a The array to search.
|
||||
* @param key The key being searched for.
|
||||
* @param inclusive If the key is present in the array, whether to return the corresponding index.
|
||||
* If false then the returned index corresponds to the smallest value in the array that is
|
||||
* strictly greater than the key.
|
||||
* @param stayInBounds If true, then {@code (a.length - 1)} will be returned in the case that the
|
||||
* key is greater than the largest value in the array. If false then {@code a.length} will be
|
||||
* returned.
|
||||
*/
|
||||
public static int binarySearchCeil(long[] a, long key, boolean inclusive, boolean stayInBounds) {
|
||||
int index = Arrays.binarySearch(a, key);
|
||||
index = index < 0 ? ~index : (inclusive ? index : (index + 1));
|
||||
return stayInBounds ? Math.min(a.length - 1, index) : index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the largest value in an list that is less than (or optionally equal to)
|
||||
* a specified key.
|
||||
* <p>
|
||||
* The search is performed using a binary search algorithm, and so the list must be sorted.
|
||||
*
|
||||
* @param list The list to search.
|
||||
* @param key The key being searched for.
|
||||
* @param inclusive If the key is present in the list, whether to return the corresponding index.
|
||||
* If false then the returned index corresponds to the largest value in the list that is
|
||||
* strictly less than the key.
|
||||
* @param stayInBounds If true, then 0 will be returned in the case that the key is smaller than
|
||||
* the smallest value in the list. If false then -1 will be returned.
|
||||
*/
|
||||
public static<T> int binarySearchFloor(List<? extends Comparable<? super T>> list, T key,
|
||||
boolean inclusive, boolean stayInBounds) {
|
||||
int index = Collections.binarySearch(list, key);
|
||||
index = index < 0 ? -(index + 2) : (inclusive ? index : (index - 1));
|
||||
return stayInBounds ? Math.max(0, index) : index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the smallest value in an list that is greater than (or optionally equal
|
||||
* to) a specified key.
|
||||
* <p>
|
||||
* The search is performed using a binary search algorithm, and so the list must be sorted.
|
||||
*
|
||||
* @param list The list to search.
|
||||
* @param key The key being searched for.
|
||||
* @param inclusive If the key is present in the list, whether to return the corresponding index.
|
||||
* If false then the returned index corresponds to the smallest value in the list that is
|
||||
* strictly greater than the key.
|
||||
* @param stayInBounds If true, then {@code (list.size() - 1)} will be returned in the case that
|
||||
* the key is greater than the largest value in the list. If false then {@code list.size()}
|
||||
* will be returned.
|
||||
*/
|
||||
public static<T> int binarySearchCeil(List<? extends Comparable<? super T>> list, T key,
|
||||
boolean inclusive, boolean stayInBounds) {
|
||||
int index = Collections.binarySearch(list, key);
|
||||
index = index < 0 ? ~index : (inclusive ? index : (index + 1));
|
||||
return stayInBounds ? Math.min(list.size() - 1, index) : index;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user