Browse Source

Extend Android playback counters across long running streams

master
evgeny 7 days ago
parent
commit
bb256dccdc
  1. 23
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamPlayerEngine.kt

23
tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamPlayerEngine.kt

@ -59,6 +59,8 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
var lastHead = -1L
var headChangedNs = 0L
var endDrainUntil = 0L
var headEpoch = 0L
var previousRawHead = 0L
fun resetVideo() {
try { decoder?.stop() }
@ -75,15 +77,28 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
catch (e: Exception) { LogManager.addLog("WARN", "stream", "audio release id=$id: ${e.message}") }
track = null
if (opus != 0L) NativeLib.streamOpusClose(opus)
opus = 0; audioBase = -1; written = 0; lastHead = -1; audios.clear()
opus = 0; audioBase = -1; written = 0; lastHead = -1; headEpoch = 0; previousRawHead = 0; audios.clear()
}
// PlaybackHeadPosition — unsigned 32 bit: при 48kHz оборачивается примерно через 25 часов.
fun playedFrames(t: AudioTrack): Long {
val raw = t.playbackHeadPosition.toLong() and 0xffffffffL
if (raw < previousRawHead) headEpoch += 0x100000000L
previousRawHead = raw
return headEpoch + raw
}
fun currentPts(now: Long): Long {
val t = track
if (t != null && audioBase >= 0) {
val head = playedFrames(t)
val played = if (t.getTimestamp(audioTimestamp)) {
(audioTimestamp.framePosition + (now - audioTimestamp.nanoTime).coerceAtLeast(0) * 48000 / 1_000_000_000)
var position = audioTimestamp.framePosition
if (position <= 0xffffffffL) {
position += headEpoch
if (position - head > 0x80000000L) position -= 0x100000000L
if (head - position > 0x80000000L) position += 0x100000000L
}
position + (now - audioTimestamp.nanoTime).coerceAtLeast(0) * 48000 / 1_000_000_000
} else {
val head = t.playbackHeadPosition.toLong() and 0xffffffffL
if (head != lastHead) { lastHead = head; headChangedNs = now }
head + if (head >= written) (now - headChangedNs) * 48000 / 1_000_000_000 else 0
}
@ -168,7 +183,7 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
}
val t = track
if (t != null && audios.isNotEmpty()) {
val head = t.playbackHeadPosition.toLong() and 0xffffffffL
val head = playedFrames(t)
if (written - head < 3840) {
val f = audios.removeFirst()
val missing = ((f.pts - audioBase - written * 1_000_000 / 48000).toDouble() / 20000).roundToInt()

Loading…
Cancel
Save