From 83ea839d0c297cdee3ba3d1af64b08e707e86d75 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 29 Oct 2026 00:35:28 +0100 Subject: [PATCH] Recognize shared preview sources and model texture cleanup failures --- .../java/com/utun/chat/data/StreamCaptureEngine.kt | 4 +++- .../main/kotlin/android/graphics/SurfaceTexture.kt | 14 ++++++++++++++ .../src/main/kotlin/android/view/Surface.kt | 3 ++- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 tools/chatgui-android/video-tests/src/main/kotlin/android/graphics/SurfaceTexture.kt diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamCaptureEngine.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamCaptureEngine.kt index bf6d816d..e9441e08 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamCaptureEngine.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamCaptureEngine.kt @@ -107,8 +107,10 @@ class StreamCaptureEngine( fun start() { preview.bind { target -> if (!handler.post { + if (target?.released == true) { LogManager.addLog("WARN", "video", "cancelled preview command id=$id"); return@post } if (stopping || stopped || terminalFailure) { target?.release(); return@post } - if (target === previewTarget) { target?.release(); return@post } + if (target == null && previewTarget == null) return@post + if (target?.sameSource(previewTarget) == true) { target.release(); return@post } val previous = previewTarget; previewTarget = target; previous?.release() val config = activeConfig; val device = camera LogManager.videoTrace("preview output change id=$id target=${target?.let(System::identityHashCode)} " + diff --git a/tools/chatgui-android/video-tests/src/main/kotlin/android/graphics/SurfaceTexture.kt b/tools/chatgui-android/video-tests/src/main/kotlin/android/graphics/SurfaceTexture.kt new file mode 100644 index 00000000..23aca170 --- /dev/null +++ b/tools/chatgui-android/video-tests/src/main/kotlin/android/graphics/SurfaceTexture.kt @@ -0,0 +1,14 @@ +package android.graphics + +/** Только JVM: физический texture descriptor и отказ до/после release. */ +class SurfaceTexture(val id: Int) { + var released = false + private set + var releaseCalls = 0 + private set + var failures = emptySet() + fun release() { + releaseCalls++; check("release" !in failures) { "texture release failed" } + released = true; check("release after" !in failures) { "texture release failed after effect" } + } +} diff --git a/tools/chatgui-android/video-tests/src/main/kotlin/android/view/Surface.kt b/tools/chatgui-android/video-tests/src/main/kotlin/android/view/Surface.kt index d7cf3427..8aec27d5 100644 --- a/tools/chatgui-android/video-tests/src/main/kotlin/android/view/Surface.kt +++ b/tools/chatgui-android/video-tests/src/main/kotlin/android/view/Surface.kt @@ -1,7 +1,8 @@ package android.view /** Только дескриптор вывода; реальных EGL/TextureView/драйверов нет. */ -class Surface { +class Surface() { + constructor(texture: android.graphics.SurfaceTexture) : this() @Volatile var isValid = true var releaseCalls = 0 private set