diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoEngine.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoEngine.kt index aa25ccbb..4aba413d 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoEngine.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoEngine.kt @@ -232,26 +232,27 @@ class CallVideoEngine(private val context: Context, private val id: Long) { val pts = (image.timestamp + offset) / 1000 // Camera2 уже ограничена 30 fps. Порог 33333 мкс отбрасывал каждый второй кадр при дрожании часов. if (pts <= lastPts) return@setOnImageAvailableListener - val key = needKey || lastKey < 0 || pts - lastKey >= 1_000_000 + val key = needKey || confirmingRequest != 0L || lastKey < 0 || pts - lastKey >= 1_000_000 if (key && pendingRequest != 0L) { val requestId = pendingRequest; pendingRequest = 0 val old = checkNotNull(encoder); val oldRate = old.bitrate; val name = old.name confirmingPts = pts if (old.setBitrate(pendingRate)) { - confirmingRequest = requestId; needKey = true + // References сохранены: уже закодированные P-кадры остаются пригодны до нового KEY. + confirmingRequest = requestId } else { - old.close(); encoder = null - try { - encoder = CallVideoCodec(f, pendingRate, name) - encoder!!.prepare(); check(encoder!!.format == f) { "Bitrate change altered encoder format" } - confirmingRequest = requestId; needKey = true - report("Applying ${pendingRate / 1000} kbit/s on IDR") - } catch (e: Exception) { - LogManager.addLog("WARN", "call", "video bitrate replacement failed: ${e.message}; restoring $oldRate") - encoder?.close(); encoder = CallVideoCodec(f, oldRate, name) - encoder!!.prepare(); check(encoder!!.format == f) - confirmingRequest = requestId; needKey = true - } + old.close(); encoder = null + try { + encoder = CallVideoCodec(f, pendingRate, name) + encoder!!.prepare(); check(encoder!!.format == f) { "Bitrate change altered encoder format" } + confirmingRequest = requestId; needKey = true + report("Applying ${pendingRate / 1000} kbit/s on IDR") + } catch (e: Exception) { + LogManager.addLog("WARN", "call", "video bitrate replacement failed: ${e.message}; restoring $oldRate") + encoder?.close(); encoder = CallVideoCodec(f, oldRate, name) + encoder!!.prepare(); check(encoder!!.format == f) + confirmingRequest = requestId; needKey = true + } } } if (encoder?.submit(image, pts, key) == true) lastPts = pts