mirror of
https://github.com/twinksoftware/Gearslip.git
synced 2026-11-10 16:02:25 +01:00
screen size auto negotiation
This commit is contained in:
1 parent
f21df41506
commit
c52a6c32b7
2 files changed
+33
-7
No files matched your search
@@ -631,15 +631,11 @@ class GearslipRunner(
|
||||
"configuration_indices=$indices",
|
||||
)
|
||||
if (maxUnackedFromConfig != null) maxUnacked = maxOf(1, maxUnackedFromConfig)
|
||||
// Prefer the smallest offered resolution for the first attempt: fewer pixels,
|
||||
// fewer ways for a first encode to go wrong.
|
||||
val offered = indices.map { it.toInt() }
|
||||
val preferred = vehicleProfile?.resolution?.let { want ->
|
||||
offered.firstOrNull { videoConfigs.getOrNull(it)?.resolutionName == want }
|
||||
}
|
||||
selectedConfigIndex = preferred ?: offered.minByOrNull { idx ->
|
||||
videoConfigs.getOrNull(idx)?.pixelCount() ?: Int.MAX_VALUE
|
||||
} ?: offered.firstOrNull()
|
||||
selectedConfigIndex = preferred ?: fitToScreen(offered) ?: offered.firstOrNull()
|
||||
log.i("selected config index $selectedConfigIndex from offered $offered")
|
||||
SessionReport.video(
|
||||
"${videoConfigs.getOrNull(selectedConfigIndex ?: -1)?.resolutionName ?: "?"} " +
|
||||
@@ -685,6 +681,20 @@ class GearslipRunner(
|
||||
// -> Data (8-byte big-endian timestamp, then the H.264 access unit)
|
||||
// <- Ack { session_id, ack } - at most max_unacked frames may be outstanding
|
||||
|
||||
/**
|
||||
* The offered config that best fills the car's screen: the smallest whose visible width
|
||||
* reaches most of the touchscreen's, else the largest there is. Always taking the smallest
|
||||
* put 800x480 on a 1540x720 Audi screen and stretched it. With no touchscreen size to go
|
||||
* by, the smallest is still the safe choice.
|
||||
*/
|
||||
private fun fitToScreen(offered: List<Int>): Int? {
|
||||
val known = offered.filter { videoConfigs.getOrNull(it)?.pixelSize() != null }
|
||||
fun pixels(idx: Int) = videoConfigs[idx].pixelCount()
|
||||
if (touchWidth <= 0) return known.minByOrNull(::pixels)
|
||||
val wide = known.filter { (videoConfigs[it].visibleSize()?.first ?: 0) >= touchWidth * 8 / 10 }
|
||||
return wide.minByOrNull(::pixels) ?: known.maxByOrNull(::pixels)
|
||||
}
|
||||
|
||||
private fun startVideoSource() {
|
||||
lastKeyframeSentAt = System.currentTimeMillis() // frame #1 is always a keyframe
|
||||
val index = selectedConfigIndex ?: 0
|
||||
@@ -702,6 +712,13 @@ class GearslipRunner(
|
||||
Protobuf.varintField(2, index.toLong())
|
||||
send(MSG_MEDIA_START, start, encrypted = true, channel = videoChannelId)
|
||||
log.i("-> Start(session_id=$SESSION_ID, configuration_index=$index -> $config)")
|
||||
// The car crops its margins off the frame, so keep the UI out of them unless a vehicle
|
||||
// profile has its own tuned insets.
|
||||
if (vehicleProfile?.insets.let { it == null || it == Insets.NONE }) {
|
||||
val insets = config.marginInsets()
|
||||
CarEnvironment.setInsets(insets)
|
||||
if (insets != Insets.NONE) log.i("keeping the UI clear of the car's margins: $insets")
|
||||
}
|
||||
|
||||
val useProjection = projection != null
|
||||
videoSource = VideoSource(
|
||||
|
||||
@@ -20,8 +20,8 @@ object ServiceDiscovery {
|
||||
|
||||
/**
|
||||
* [widthMargin]/[heightMargin] are the head unit's own numbers (VideoConfiguration fields 3
|
||||
* and 4): pixels of the frame it does not treat as usable UI. Logged, and available to a
|
||||
* vehicle profile, but not applied automatically - what they mean varies by unit.
|
||||
* and 4): pixels of the frame it crops away, split evenly between the two edges, to fit the
|
||||
* frame to a screen of a different shape. A matched vehicle profile's insets override them.
|
||||
*/
|
||||
class VideoConfig(
|
||||
val resolution: Int,
|
||||
@@ -38,6 +38,15 @@ object ServiceDiscovery {
|
||||
|
||||
fun pixelCount(): Int = pixelSize()?.let { it.first * it.second } ?: Int.MAX_VALUE
|
||||
|
||||
/** What's left on the car's screen once the margins are cropped off. */
|
||||
fun visibleSize(): Pair<Int, Int>? = pixelSize()?.let { (w, h) -> (w - widthMargin) to (h - heightMargin) }
|
||||
|
||||
/** The margins as the strips of the frame the car UI keeps clear. */
|
||||
fun marginInsets(): Insets = Insets(
|
||||
top = heightMargin / 2, bottom = heightMargin - heightMargin / 2,
|
||||
left = widthMargin / 2, right = widthMargin - widthMargin / 2,
|
||||
)
|
||||
|
||||
override fun toString() =
|
||||
"$resolutionName @ $frameRateName, density=$density, margin=${widthMargin}x$heightMargin"
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user