From 91478e259355cbcd1baf2eada542464625028c41 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 20 Oct 2026 01:22:52 +0200 Subject: [PATCH] Warm Android video codecs in the background and accelerate probe tails --- .../main/java/com/utun/chat/ChatApplication.kt | 16 ++++++++++++++-- .../java/com/utun/chat/data/CallVideoCodec.kt | 5 ++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/ChatApplication.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/ChatApplication.kt index 3f54c532..f9bdaf95 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/ChatApplication.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/ChatApplication.kt @@ -13,6 +13,7 @@ import com.utun.chat.data.IncomingCallManager import com.utun.chat.data.TelecomCallManager import com.utun.chat.data.ChatEventCallback import com.utun.chat.data.CallController +import com.utun.chat.data.CallVideoCodec import com.utun.chat.data.AvatarRepository import com.utun.chat.data.MemberFilesRepository import kotlinx.coroutines.flow.MutableSharedFlow @@ -92,8 +93,19 @@ class ChatApplication : Application() { TelecomCallManager.init() CallController.init() com.utun.chat.data.PhoneStateMonitor.init() - - + // Только тестовые codec кадры: разрешения камеры, Activity, Surface и сеть не нужны. + Thread({ + val started = System.nanoTime() + LogManager.addLog("INFO", "call", "video codec background preparation begin; camera and network unused") + try { + val decoders = CallVideoCodec.probeDecoders() + val encoders = CallVideoCodec.probe() + LogManager.addLog("INFO", "call", "video codec background preparation complete " + + "elapsedMs=${(System.nanoTime() - started) / 1_000_000} decodeCodecs=${decoders.size} encodeCodecs=${encoders.size}") + } catch (e: Exception) { + LogManager.addLog("ERROR", "call", "video codec background preparation failed: ${e.message}") + } + }, "call-video-probe").start() } companion object { diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt index 25ab7b53..393fba4e 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoCodec.kt @@ -392,7 +392,8 @@ internal class CallVideoCodec(requested: CallVideoFormat, bitrate: Int, val name var sent = 0; var decoded = 0; var pipeline = 0 val info = MediaCodec.BufferInfo(); val started = System.nanoTime(); val deadline = started + 2_000_000_000 while (decoded < packets.size && System.nanoTime() < deadline && keepRunning()) { - if (sent < packets.size && (!paced || System.nanoTime() - started >= sent * 1_000_000_000L / f.fps)) { + // Измеряем pipeline с исходной частотой до первого выхода, затем проверяем весь хвост без пауз. + if (sent < packets.size && (!paced || decoded > 0 || System.nanoTime() - started >= sent * 1_000_000_000L / f.fps)) { val i = decoder.dequeueInputBuffer(0) if (i >= 0) { val p = packets[sent++]; val data = if (p.key) type.unpackKey(p.bytes).second else p.bytes @@ -410,6 +411,8 @@ internal class CallVideoCodec(requested: CallVideoFormat, bitrate: Int, val name } check(keepRunning()) { "Decoder probe cancelled" } check(decoded == packets.size) { "Decoder did not return all probe frames $decoded/${packets.size}" } + if (paced) LogManager.addLog("DEBUG", "call", "video decoder probe name=$name inputs=$sent outputs=$decoded " + + "pipeline=$pipeline elapsedMs=${(System.nanoTime() - started) / 1_000_000}") decoder.stop(); return pipeline } finally { decoder.release() } }