|
|
|
|
@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentLinkedQueue
|
|
|
|
|
/** Один RX worker; удерживаем output buffer до фактического audio PTS. Новое поколение ждёт drain старого. */ |
|
|
|
|
internal class CallVideoPlayer(private val id: Long, private val failure: (String) -> Unit) { |
|
|
|
|
@Volatile private var running = true |
|
|
|
|
private data class Output(val surface: Surface?, val release: () -> Unit) |
|
|
|
|
private data class Output(val surface: Surface?, val release: () -> Unit, val detach: Surface? = null) |
|
|
|
|
private val outputs = ConcurrentLinkedQueue<Output>() |
|
|
|
|
private val displayed = MutableStateFlow<CallVideoFormat?>(null) |
|
|
|
|
val display: StateFlow<CallVideoFormat?> = displayed |
|
|
|
|
@ -18,6 +18,9 @@ internal class CallVideoPlayer(private val id: Long, private val failure: (Strin
|
|
|
|
|
@Synchronized fun surface(surface: Surface?, release: () -> Unit = {}) { |
|
|
|
|
if (running) outputs.add(Output(surface, release)) else release() |
|
|
|
|
} |
|
|
|
|
@Synchronized fun detach(surface: Surface) { |
|
|
|
|
if (running) outputs.add(Output(null, {}, surface)) |
|
|
|
|
} |
|
|
|
|
fun decoders(value: Map<Int, CallVideoCodec.Companion.Decoder>) { verified = value } |
|
|
|
|
fun stop() { synchronized(this) { running = false }; worker.join() } |
|
|
|
|
|
|
|
|
|
@ -39,6 +42,7 @@ internal class CallVideoPlayer(private val id: Long, private val failure: (Strin
|
|
|
|
|
val now = System.nanoTime() |
|
|
|
|
while (true) { |
|
|
|
|
val next = outputs.poll() ?: break |
|
|
|
|
if (next.detach != null && output?.surface !== next.detach) continue |
|
|
|
|
close(); output?.release?.invoke(); output = next; surface = next.surface |
|
|
|
|
pending = null; displayed.value = null; CallVideoNative.requestKey(id) |
|
|
|
|
} |
|
|
|
|
|