|
|
|
|
@ -625,10 +625,11 @@ class CallAudioEngine {
|
|
|
|
|
playFramesPlayed = played |
|
|
|
|
operationNs = System.nanoTime() |
|
|
|
|
val device = trace.device |
|
|
|
|
val anchor = playbackClock.update(playFramesWritten, played, nowUs, routeGeneration, |
|
|
|
|
device.generation, device.stampFrame, device.stampNs / 1000) |
|
|
|
|
val generation = routeGeneration |
|
|
|
|
val anchor = playbackClock.update(playFramesWritten, played, nowUs, generation, |
|
|
|
|
device.generation, device.stampFrame, device.stampNs / 1000).takeIf { generation == routeGeneration } |
|
|
|
|
outputUs = if (anchor?.measured == true) (anchor.atUs - nowUs).coerceAtLeast(0) else -1 |
|
|
|
|
outputSample = OutputSample(nowUs, routeGeneration, CallOutputLatency( |
|
|
|
|
outputSample = OutputSample(nowUs, generation, CallOutputLatency( |
|
|
|
|
((playFramesWritten - played) * 1000 / SAMPLE_RATE).toInt(), |
|
|
|
|
if (outputUs >= 0) (outputUs / 1000).toInt() else -1)) |
|
|
|
|
if (anchor != null) NativeLib.callAudioProgress(callId, epoch, anchor.position, anchor.atUs, nowUs, anchor.measured) |
|
|
|
|
@ -636,12 +637,13 @@ class CallAudioEngine {
|
|
|
|
|
val mode = if (anchor == null) "unavailable" else if (anchor.measured) "timestamp" else "head-estimate" |
|
|
|
|
if (mode != clockMode) { |
|
|
|
|
LogManager.addLog(if (mode == "unavailable") "WARN" else "INFO", "CallAudio", |
|
|
|
|
"playback clock id=$callId mode=$mode routeGeneration=$routeGeneration outputUs=$outputUs") |
|
|
|
|
"playback clock id=$callId mode=$mode routeGeneration=$generation outputUs=$outputUs") |
|
|
|
|
clockMode = mode |
|
|
|
|
} |
|
|
|
|
} else if (!clockFailed) { |
|
|
|
|
clockFailed = true |
|
|
|
|
playFramesPlayed = -1 |
|
|
|
|
outputUs = -1; outputSample = null |
|
|
|
|
// Отрицательная позиция немедленно инвалидирует снимок в native. |
|
|
|
|
NativeLib.callAudioProgress(callId, epoch, -1, nowUs, nowUs, false) |
|
|
|
|
LogManager.addLog("ERROR", "CallAudio", |
|
|
|
|
@ -711,11 +713,13 @@ class CallAudioEngine {
|
|
|
|
|
} else { |
|
|
|
|
playbackBuffer?.applied(now, change, actual, capacity) |
|
|
|
|
} |
|
|
|
|
val level = if (actual == requested && (change == null || change.underruns == 0)) "INFO" else "WARN" |
|
|
|
|
val performance = track.performanceMode |
|
|
|
|
val level = if (actual == requested && (change == null || change.underruns == 0) && |
|
|
|
|
performance == AudioTrack.PERFORMANCE_MODE_LOW_LATENCY) "INFO" else "WARN" |
|
|
|
|
LogManager.addLog(level, "CallAudio", |
|
|
|
|
"playback buffering id=$callId reason=$reason requestedFrames=$requested actualFrames=$actual " + |
|
|
|
|
"previousFrames=$previous startFrames=$start capacityFrames=$capacity underruns=${change?.underruns ?: 0} " + |
|
|
|
|
"performanceRequested=${AudioTrack.PERFORMANCE_MODE_LOW_LATENCY} performanceActual=${track.performanceMode} pacing=device") |
|
|
|
|
"performanceRequested=${AudioTrack.PERFORMANCE_MODE_LOW_LATENCY} performanceActual=$performance pacing=device") |
|
|
|
|
if (playReady && (previous != actual || reason == "route")) { |
|
|
|
|
// Очередь сначала принимает новый размер; устаревшая задача не затронет следующий звонок. |
|
|
|
|
mainHandler.post { |
|
|
|
|
|