diff --git a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfig.kt b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfig.kt index 152678261c..40611741c9 100644 --- a/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfig.kt +++ b/libraries/mediaupload/impl/src/main/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfig.kt @@ -34,11 +34,14 @@ internal object VideoCompressorConfigFactory { val newFrameRate = min(originalFrameRate, DEFAULT_FRAME_RATE) // If we need to resize the video, we also want to recalculate the bitrate - val newBitrate = resizer.calculateOptimalBitrate(Size(width, height), newFrameRate) + val optimalBitrate = resizer.calculateOptimalBitrate(Size(width, height), newFrameRate).toInt() + + val sourceBitrate = metadata?.bitrate?.takeIf { it > 0 } + val newBitrate = sourceBitrate?.let { min(optimalBitrate.toLong(), it).toInt() } ?: optimalBitrate return VideoCompressorConfig( videoCompressorHelper = resizer, - newBitRate = newBitrate.toInt(), + newBitRate = newBitrate, newFrameRate = newFrameRate, ) } diff --git a/libraries/mediaupload/impl/src/test/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfigFactoryTest.kt b/libraries/mediaupload/impl/src/test/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfigFactoryTest.kt index 6af0956541..4309d59209 100644 --- a/libraries/mediaupload/impl/src/test/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfigFactoryTest.kt +++ b/libraries/mediaupload/impl/src/test/kotlin/io/element/android/libraries/mediaupload/impl/VideoCompressorConfigFactoryTest.kt @@ -33,6 +33,46 @@ class VideoCompressorConfigFactoryTest : RobolectricTest() { assertThat(videoCompressorConfig.newBitRate).isNotEqualTo(VideoEncoderSettings.NO_VALUE) } + @Test + fun `the bitrate is clamped to the source bitrate when the source is already low`() { + val metadata = VideoFileMetadata(width = 720, height = 720, bitrate = 615_000, frameRate = 25, rotation = 0) + + val videoCompressorConfig = VideoCompressorConfigFactory.create( + metadata = metadata, + preset = VideoCompressionPreset.STANDARD, + ) + + assertThat(videoCompressorConfig.newBitRate).isEqualTo(615_000) + } + + @Test + fun `the bitrate is not raised for a high bitrate source`() { + val metadata = VideoFileMetadata(width = 1920, height = 1080, bitrate = 20_000_000, frameRate = 30, rotation = 0) + + val videoCompressorConfig = VideoCompressorConfigFactory.create( + metadata = metadata, + preset = VideoCompressionPreset.STANDARD, + ) + + assertThat(videoCompressorConfig.newBitRate).isLessThan(20_000_000) + assertThat(videoCompressorConfig.newBitRate).isGreaterThan(0) + } + + @Test + fun `an unknown bitrate falls back to the calculated optimal`() { + val unknown = VideoCompressorConfigFactory.create( + metadata = VideoFileMetadata(width = 1280, height = 720, bitrate = -1, frameRate = 30, rotation = 0), + preset = VideoCompressionPreset.STANDARD, + ) + val zero = VideoCompressorConfigFactory.create( + metadata = VideoFileMetadata(width = 1280, height = 720, bitrate = 0, frameRate = 30, rotation = 0), + preset = VideoCompressionPreset.STANDARD, + ) + + assertThat(unknown.newBitRate).isGreaterThan(0) + assertThat(zero.newBitRate).isEqualTo(unknown.newBitRate) + } + @Test fun `if the video should be compressed and is larger than 720p it will be resized`() { // Given