From cc44cdc8aac8c71296ae51f1041b11978d8c26d1 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 28 Feb 2022 14:32:54 +0530 Subject: [PATCH 1/3] create sort buckets for improving thumbnail performance --- .../thumbnails/DefaultThumbnailsEngine.kt | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt b/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt index 123748ac..4936a56e 100644 --- a/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt +++ b/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt @@ -77,6 +77,8 @@ class DefaultThumbnailsEngine( } private val stubs = ArrayDeque() + private val bucketListMap = LinkedHashMap>() + private val finalList = ArrayList() private inner class IgnoringEosDataSource( private val source: DataSource, @@ -253,10 +255,36 @@ class DefaultThumbnailsEngine( positions.mapNotNull { (positionUs, request) -> val localizedUs = timer.localize(TrackType.VIDEO, index, positionUs) localizedUs?.let { Stub(request, positionUs, localizedUs) } - }.toMutableList().sortedBy { it.positionUs } +// }.toMutableList().sortedBy { it.positionUs } + }.toMutableList().reorder(dataSources[TrackType.VIDEO][0].keyFrameTimestampsUs) ) } + private fun List.reorder(keyFrameTimestampsUs: ArrayList): Collection { + if(keyFrameTimestampsUs.isEmpty()) + return this + bucketListMap.clear() + finalList.clear() + + forEach { + val keyFrame = findPrevKeyFrame(it.positionUs, keyFrameTimestampsUs) + val list = bucketListMap.getOrPut(keyFrame) { ArrayList() } + list.add(it) + } + bucketListMap.forEach { + finalList.addAll(it.value.sortedBy { it.positionUs }) + } + return finalList + } + + private fun findPrevKeyFrame(positionUs: Long, keyFrameTimestampsUs: ArrayList): Long { + for(i in 0 until keyFrameTimestampsUs.size) { + if(positionUs < keyFrameTimestampsUs[i]) + return keyFrameTimestampsUs[i-1] + } + return -1 + } + private val fetchPosition: () -> VideoSnapshots.Request? = { if (stubs.isEmpty()) null else VideoSnapshots.Request(stubs.first().localizedUs, stubs.first().request.threshold()) From ff2384cbb53f0a1d7b099e93e887f492bf1890ee Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 28 Feb 2022 15:04:02 +0530 Subject: [PATCH 2/3] PR requested changes --- .../thumbnails/DefaultThumbnailsEngine.kt | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt b/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt index 4936a56e..9ea333e2 100644 --- a/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt +++ b/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt @@ -77,8 +77,6 @@ class DefaultThumbnailsEngine( } private val stubs = ArrayDeque() - private val bucketListMap = LinkedHashMap>() - private val finalList = ArrayList() private inner class IgnoringEosDataSource( private val source: DataSource, @@ -256,19 +254,22 @@ class DefaultThumbnailsEngine( val localizedUs = timer.localize(TrackType.VIDEO, index, positionUs) localizedUs?.let { Stub(request, positionUs, localizedUs) } // }.toMutableList().sortedBy { it.positionUs } - }.toMutableList().reorder(dataSources[TrackType.VIDEO][0].keyFrameTimestampsUs) + }.toMutableList().reorder(dataSources[TrackType.VIDEO][0]) ) } - private fun List.reorder(keyFrameTimestampsUs: ArrayList): Collection { - if(keyFrameTimestampsUs.isEmpty()) - return this - bucketListMap.clear() - finalList.clear() + private fun List.reorder(source: DataSource): Collection { + val bucketListMap = LinkedHashMap>() + val finalList = ArrayList() forEach { - val keyFrame = findPrevKeyFrame(it.positionUs, keyFrameTimestampsUs) - val list = bucketListMap.getOrPut(keyFrame) { ArrayList() } + val nextKeyFrameIndex = source.search(it.positionUs) + val previousKeyFrameUs = + source.keyFrameTimestampsUsList[ + if (nextKeyFrameIndex > 0) + nextKeyFrameIndex - 1 else (source.keyFrameTimestampsUsList.size - 1) + ] + val list = bucketListMap.getOrPut(previousKeyFrameUs) { ArrayList() } list.add(it) } bucketListMap.forEach { @@ -277,14 +278,6 @@ class DefaultThumbnailsEngine( return finalList } - private fun findPrevKeyFrame(positionUs: Long, keyFrameTimestampsUs: ArrayList): Long { - for(i in 0 until keyFrameTimestampsUs.size) { - if(positionUs < keyFrameTimestampsUs[i]) - return keyFrameTimestampsUs[i-1] - } - return -1 - } - private val fetchPosition: () -> VideoSnapshots.Request? = { if (stubs.isEmpty()) null else VideoSnapshots.Request(stubs.first().localizedUs, stubs.first().request.threshold()) From d24387fe4a7e36797028f56f5a781955ee5f5ea6 Mon Sep 17 00:00:00 2001 From: Sahil Bajaj Date: Mon, 28 Feb 2022 22:42:44 +0530 Subject: [PATCH 3/3] Replace usage of keyFrameList with keyFrameAt --- .../internal/thumbnails/DefaultThumbnailsEngine.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt b/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt index 9ea333e2..e2b63eb4 100644 --- a/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt +++ b/lib/src/main/java/com/otaliastudios/transcoder/internal/thumbnails/DefaultThumbnailsEngine.kt @@ -264,11 +264,8 @@ class DefaultThumbnailsEngine( forEach { val nextKeyFrameIndex = source.search(it.positionUs) - val previousKeyFrameUs = - source.keyFrameTimestampsUsList[ - if (nextKeyFrameIndex > 0) - nextKeyFrameIndex - 1 else (source.keyFrameTimestampsUsList.size - 1) - ] + val previousKeyFrameUs = source.keyFrameAt(nextKeyFrameIndex - 1) { source.lastKeyFrame() } + val list = bucketListMap.getOrPut(previousKeyFrameUs) { ArrayList() } list.add(it) }