From 52120afdbd085c77f1f7cb0c4836c66d85e87ad8 Mon Sep 17 00:00:00 2001 From: Nicholas Tinsley Date: Tue, 16 Jan 2024 17:19:42 -0500 Subject: [PATCH] Remove dependency on Guava limited stream. --- .../Mp4FaststartPostProcessor.kt | 75 ++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/video/lib/src/main/java/org/thoughtcrime/securesms/video/postprocessing/Mp4FaststartPostProcessor.kt b/video/lib/src/main/java/org/thoughtcrime/securesms/video/postprocessing/Mp4FaststartPostProcessor.kt index 19bed91d92..bb8a0facf2 100644 --- a/video/lib/src/main/java/org/thoughtcrime/securesms/video/postprocessing/Mp4FaststartPostProcessor.kt +++ b/video/lib/src/main/java/org/thoughtcrime/securesms/video/postprocessing/Mp4FaststartPostProcessor.kt @@ -5,11 +5,12 @@ package org.thoughtcrime.securesms.video.postprocessing -import com.google.common.io.ByteStreams import org.signal.libsignal.media.Mp4Sanitizer import org.signal.libsignal.media.SanitizedMetadata import org.thoughtcrime.securesms.video.exceptions.VideoPostProcessingException import java.io.ByteArrayInputStream +import java.io.FilterInputStream +import java.io.IOException import java.io.InputStream import java.io.OutputStream import java.io.SequenceInputStream @@ -36,7 +37,8 @@ class Mp4FaststartPostProcessor(private val inputStreamFactory: () -> InputStrea val inputStream = inputStreamFactory() inputStream.skip(metadata.dataOffset) - return SequenceInputStream(ByteArrayInputStream(metadata.sanitizedMetadata), ByteStreams.limit(inputStream, metadata.dataLength)) + + return SequenceInputStream(ByteArrayInputStream(metadata.sanitizedMetadata), LimitedInputStream(inputStream, metadata.dataLength)) } fun processAndWriteTo(outputStream: OutputStream): Long { @@ -48,4 +50,73 @@ class Mp4FaststartPostProcessor(private val inputStreamFactory: () -> InputStrea companion object { const val TAG = "Mp4Faststart" } + + private class LimitedInputStream(innerStream: InputStream, limit: Long) : FilterInputStream(innerStream) { + private var left: Long = limit + private var mark: Long = -1 + + init { + if (limit < 0) { + throw IllegalArgumentException("Limit must be non-negative!") + } + } + + @Throws(IOException::class) + override fun available(): Int { + return `in`.available().toLong().coerceAtMost(left).toInt() + } + + @Synchronized + override fun mark(readLimit: Int) { + `in`.mark(readLimit) + mark = left + } + + @Throws(IOException::class) + override fun read(): Int { + if (left == 0L) { + return -1 + } + val result = `in`.read() + if (result != -1) { + --left + } + return result + } + + @Throws(IOException::class) + override fun read(b: ByteArray, off: Int, len: Int): Int { + if (left == 0L) { + return -1 + } + val toRead = len.toLong().coerceAtMost(left).toInt() + val result = `in`.read(b, off, toRead) + if (result != -1) { + left -= result.toLong() + } + return result + } + + @Synchronized + @Throws(IOException::class) + override fun reset() { + if (!`in`.markSupported()) { + throw IOException("Mark not supported") + } + if (mark == -1L) { + throw IOException("Mark not set") + } + `in`.reset() + left = mark + } + + @Throws(IOException::class) + override fun skip(n: Long): Long { + val toSkip = n.coerceAtMost(left) + val skipped = `in`.skip(toSkip) + left -= skipped + return skipped + } + + } }