Skip to content

Commit

Permalink
undo even scale changes
Browse files Browse the repository at this point in the history
WebRTC m97 handles odd dimensions
  • Loading branch information
davidliu committed Feb 18, 2022
1 parent 1b81a82 commit a62e4dc
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import io.livekit.android.room.DefaultsManager
import io.livekit.android.room.RTCEngine
import io.livekit.android.room.track.*
import io.livekit.android.room.util.EncodingUtils
import io.livekit.android.room.util.EncodingUtils.findEvenScaleDownBy
import io.livekit.android.util.LKLog
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.cancel
Expand Down Expand Up @@ -323,7 +322,6 @@ internal constructor(
val midPreset = presets[1]
val lowPreset = presets[0]


fun addEncoding(videoEncoding: VideoEncoding, scale: Double) {
if (encodings.size >= EncodingUtils.VIDEO_RIDS.size) {
throw IllegalStateException("Attempting to add more encodings than we have rids for!")
Expand All @@ -336,18 +334,19 @@ internal constructor(
// if resolution is high enough, we send both h and q res.
// otherwise only send h
val size = max(width, height)

fun calculateScaleDown(captureParam: VideoCaptureParameter): Double {
val targetSize = max(captureParam.width, captureParam.height)
return size / targetSize.toDouble()
}
if (size >= 960) {
var lowScale = findEvenScaleDownBy(width, height, lowPreset.capture.width, lowPreset.capture.height)
var midScale = findEvenScaleDownBy(width, height, midPreset.capture.width, midPreset.capture.height)
val lowScale = calculateScaleDown(lowPreset.capture)
val midScale = calculateScaleDown(midPreset.capture)

if (midScale == null || lowScale == null) {
lowScale = 4.0
midScale = 2.0
}
addEncoding(lowPreset.encoding, lowScale)
addEncoding(midPreset.encoding, midScale)
} else {
val lowScale = findEvenScaleDownBy(width, height, lowPreset.capture.width, lowPreset.capture.height) ?: 2.0
val lowScale = calculateScaleDown(lowPreset.capture)
addEncoding(lowPreset.encoding, lowScale)
}
addEncoding(encoding, 1.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,6 @@ internal object EncodingUtils {
VideoPreset43.FHD
)


/**
* Encoders will often not be able to handle odd dimensions, so we should try to find a scale that will
* result in even dimensions.
*
* @return a scale that will result in dimensions that are both even, or null if none found.
*/
fun findEvenScaleDownBy(
sourceWidth: Int,
sourceHeight: Int,
targetWidth: Int,
targetHeight: Int,
): Double? {
fun Int.isEven() = this % 2 == 0

val sourceSize = min(sourceWidth, sourceHeight)
val targetSize = min(targetWidth, targetHeight)
for (i in 0..20) {
val scaleDownBy = sourceSize.toDouble() / (targetSize + i)
// Internally, WebRTC casts directly to int without rounding.
// https://github.com/webrtc-sdk/webrtc/blob/8c7139f8e6fa19ddf2c91510c177a19746e1ded3/media/engine/webrtc_video_engine.cc#L3676
val scaledWidth = (sourceWidth / scaleDownBy).toInt()
val scaledHeight = (sourceHeight / scaleDownBy).toInt()

if (scaledHeight.isEven() && scaledWidth.isEven()) {
return scaleDownBy
}
}

return null
}


fun determineAppropriateEncoding(width: Int, height: Int): VideoEncoding {
val presets = presetsForResolution(width, height)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,4 @@
package io.livekit.android.room.util

import org.junit.Assert
import org.junit.Test

class EncodingUtilsTest {
@Test
fun evenScale() {
fun Int.isEven() = this % 2 == 0

val sourceWidth = 800
val sourceHeight = 600
val scaleDownBy = EncodingUtils.findEvenScaleDownBy(sourceWidth, sourceHeight, 240, 180)
?: throw Exception("scale should not be null!")

Assert.assertTrue((sourceWidth / scaleDownBy).toInt().isEven())
Assert.assertTrue((sourceHeight / scaleDownBy).toInt().isEven())
}

@Test
fun evenScaleWeirdSource() {
fun Int.isEven() = this % 2 == 0

val sourceWidth = 800
val sourceHeight = 602
val scaleDownBy = EncodingUtils.findEvenScaleDownBy(sourceWidth, sourceHeight, 240, 180)
?: throw Exception("scale should not be null!")

Assert.assertTrue((sourceWidth / scaleDownBy).toInt().isEven())
Assert.assertTrue((sourceHeight / scaleDownBy).toInt().isEven())
}
}

0 comments on commit a62e4dc

Please sign in to comment.