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 5fb43b99..ffe3a3cc 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 @@ -114,7 +114,9 @@ class StreamCaptureEngine( } } catch (e: Exception) { failed("encoded frame: ${e.message}") } finally { if (!stopped) codec.releaseOutputBuffer(index, false) } - if (info.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0) finishStop() + if (info.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0) { + if (stopping) finishStop() else failed("unexpected encoder EOS") + } } }, handler) codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamController.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamController.kt index a7154a5a..7ee4c9f9 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamController.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamController.kt @@ -57,12 +57,13 @@ object StreamController { } fun failed(id: Long, detail: String) { - main.post { - val st = mutable.value ?: return@post - if (st.id != id || !st.ongoing) return@post + val update = Runnable { + val st = mutable.value + if (st == null || st.id != id || !st.ongoing) return@Runnable LogManager.addLog("ERROR", "stream", "publisher failed id=$id $detail") mutable.value = st.copy(error = R.string.stream_failed); stop() } + if (Looper.myLooper() == Looper.getMainLooper()) update.run() else main.post(update) } fun stop() { diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamService.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamService.kt index d4e5a149..e63c5213 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamService.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamService.kt @@ -8,6 +8,8 @@ import android.content.Intent import android.content.pm.ServiceInfo import android.os.Build import android.os.IBinder +import android.os.Handler +import android.os.Looper import android.os.PowerManager import androidx.core.app.NotificationCompat import androidx.core.app.ServiceCompat @@ -95,6 +97,7 @@ class StreamService : Service() { } private fun finish() { + if (capture != null) { shutdown(abort = true); return } poll?.cancel(); poll = null lock?.let { if (it.isHeld) it.release() }; lock = null StreamController.ended(id, this) @@ -103,9 +106,16 @@ class StreamService : Service() { override fun onDestroy() { poll?.cancel() - capture?.stop { NativeLib.streamStop(id) }; capture = null - lock?.let { if (it.isHeld) it.release() }; lock = null - StreamController.ended(id, this); scope.cancel() + val engine = capture; capture = null + val ownedLock = lock; lock = null + val release = { + NativeLib.streamStop(id) + ownedLock?.let { if (it.isHeld) it.release() } + Handler(Looper.getMainLooper()).post { StreamController.ended(id, this) } + Unit + } + if (engine != null) engine.stop(release) else release() + scope.cancel() LogManager.addLog("INFO", "stream", "foreground destroyed id=$id") super.onDestroy() }