Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ class DefaultThumbnailsEngine(
override fun requestKeyFrameTimestamps(): Long {
return source.requestKeyFrameTimestamps()
}
override fun getKeyFrameTimestampsUs(): ArrayList<Long> {
return source.keyFrameTimestampsUs
override fun getKeyFrameTimestamps(): ArrayList<Long> {
return source.keyFrameTimestamps
}

override fun isDrained(): Boolean {
Expand Down Expand Up @@ -118,13 +118,8 @@ class DefaultThumbnailsEngine(
val threshold = stubs.firstOrNull()?.request?.threshold() ?: 0L
val nextKeyFrameIndex = source.search(requested)

val nextKeyFrameUs =
if (nextKeyFrameIndex == -1) Long.MAX_VALUE else source.keyFrameTimestampsUs[nextKeyFrameIndex]
val previousKeyFrameUs =
source.keyFrameTimestampsUs[
if (nextKeyFrameIndex > 0)
nextKeyFrameIndex - 1 else (source.keyFrameTimestampsUs.size - 1)
]
val nextKeyFrameUs = source.keyFrameAt(nextKeyFrameIndex) { Long.MAX_VALUE }
val previousKeyFrameUs = source.keyFrameAt(nextKeyFrameIndex - 1) { source.lastKeyFrame() }

log.i(
"seek: current ${source.positionUs}," +
Expand Down Expand Up @@ -170,26 +165,34 @@ class DefaultThumbnailsEngine(

private lateinit var progress: (Thumbnail) -> Unit

private fun DataSource.lastKeyFrame(): Long {
return keyFrameAt(keyFrameTimestamps.size - 1)
}

private inline fun DataSource.keyFrameAt(index: Int, defaultValue: ((Int)-> Long) = {_ -> -1}): Long {
return keyFrameTimestamps.getOrElse(index, defaultValue)
}

private fun DataSource.search(timestampUs: Long): Int {
if (keyFrameTimestampsUs.isEmpty())
if (keyFrameTimestamps.isEmpty())
requestKeyFrameTimestamps()

val searchIndex = keyFrameTimestampsUs.binarySearch(timestampUs)
val searchIndex = keyFrameTimestamps.binarySearch(timestampUs)

val nextKeyFrameIndex = when {
searchIndex >= 0 -> searchIndex
searchIndex < 0 -> {
val index = -searchIndex - 1
when {
index >= keyFrameTimestampsUs.size -> {
index >= keyFrameTimestamps.size -> {
val ts = requestKeyFrameTimestamps()
if (ts == -1L) {
-1
} else {
search(timestampUs)
}
}
index < keyFrameTimestampsUs.size -> index
index < keyFrameTimestamps.size -> index
else -> {
-1 // will never reach here. kotlin is stupid
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,10 @@ public interface DataSource {

default long requestKeyFrameTimestamps() { return -1;}

default ArrayList<Long> getKeyFrameTimestampsUs() {
default ArrayList<Long> getKeyFrameTimestamps() {
return new ArrayList<>();
}

/**
* Rewinds this source, moving it to its default state.
* To be used again, tracks will be selected again.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public abstract class DefaultDataSource implements DataSource {
private long mDontRenderRangeStart = -1L;
private long mDontRenderRangeEnd = -1L;

private final ArrayList<Long> keyFrameTsUs = new ArrayList<>();
private final ArrayList<Long> keyFrameTimestamps = new ArrayList<>();
@Override
public void initialize() {
LOG.i("initialize(): initializing...");
Expand Down Expand Up @@ -92,24 +92,24 @@ public void initialize() {
}

@Override
public ArrayList<Long> getKeyFrameTimestampsUs() {
return keyFrameTsUs;
public ArrayList<Long> getKeyFrameTimestamps() {
return keyFrameTimestamps;
}

private Boolean lastKeyFrame = false;
@Override
public long requestKeyFrameTimestamps() {

if(lastKeyFrame) return -1L;
if(keyFrameTsUs.size() > 0) {
mExtractor.seekTo(keyFrameTsUs.get(keyFrameTsUs.size() - 1) + 10001L, MediaExtractor.SEEK_TO_NEXT_SYNC);
if(keyFrameTimestamps.size() > 0) {
mExtractor.seekTo(keyFrameTimestamps.get(keyFrameTimestamps.size() - 1) + 10001L, MediaExtractor.SEEK_TO_NEXT_SYNC);
}

long sampleTime = mExtractor.getSampleTime();

if (sampleTime == -1 || (keyFrameTsUs.size() > 0 && sampleTime == keyFrameTsUs.get(keyFrameTsUs.size() - 1))) {
if (sampleTime == -1 || (keyFrameTimestamps.size() > 0 && sampleTime == keyFrameTimestamps.get(keyFrameTimestamps.size() - 1))) {
lastKeyFrame = true;
mExtractor.seekTo(keyFrameTsUs.get(keyFrameTsUs.size() - 1) + 10001L, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
mExtractor.seekTo(keyFrameTimestamps.get(keyFrameTimestamps.size() - 1) + 10001L, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
return -1;
}
LOG.i("keyFrameStartTime:" + sampleTime);
Expand All @@ -119,17 +119,17 @@ public long requestKeyFrameTimestamps() {
int prefetchCount = 100;
while (sampleTime >= 0L && sampleTime != lastSampleTime && count < prefetchCount) {
if ((mExtractor.getSampleFlags() & MediaExtractor.SAMPLE_FLAG_SYNC) > 0) {
if (!keyFrameTsUs.isEmpty() && sampleTime <= keyFrameTsUs.get(keyFrameTsUs.size() - 1)) {
Collections.sort(keyFrameTsUs);
if (!keyFrameTimestamps.isEmpty() && sampleTime <= keyFrameTimestamps.get(keyFrameTimestamps.size() - 1)) {
Collections.sort(keyFrameTimestamps);
}
keyFrameTsUs.add(sampleTime);
keyFrameTimestamps.add(sampleTime);
}
mExtractor.seekTo(sampleTime + 10001L, MediaExtractor.SEEK_TO_NEXT_SYNC);
lastSampleTime = sampleTime;
sampleTime = mExtractor.getSampleTime();
count++;
}
LOG.i("keyFrameStopCount:" + keyFrameTsUs);
LOG.i("keyFrameStopCount:" + keyFrameTimestamps);
return sampleTime;
}

Expand Down