Browse Source

Release Android inflight state at decoder EOS before audio tail

master
evgeny 5 days ago
parent
commit
9ef18b6324
  1. 2
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamDecodePump.kt
  2. 4
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamPlayerEngine.kt
  3. 11
      tools/chatgui-android/app/src/test/java/com/utun/chat/data/StreamDecodePumpTest.kt

2
tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamDecodePump.kt

@ -81,7 +81,7 @@ internal class StreamDecodePump<F : StreamDecodePump.Frame>(
val render = !next.empty && next.pts >= position - 100000
release(next, render); output = null
if (!next.empty) { if (render) shown++ else discarded++ }
if (next.eos) ended = true
if (next.eos) { ended = true; submitted.clear() }
}
}

4
tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamPlayerEngine.kt

@ -263,7 +263,8 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
}
}
if (playbackStarted && playback != 0L && ready >= 0) {
val lateVideo = video.firstOutputPts == null || (video.oldestSubmittedPts >= 0 && video.oldestSubmittedPts < position - 10000)
val lateVideo = !video.ended && (video.firstOutputPts == null
|| (video.oldestSubmittedPts >= 0 && video.oldestSubmittedPts < position - 10000))
if (lateVideo && track != null && !pausedAudio) { track!!.pause(); pausedAudio = true }
if (pausedAudio && !lateVideo) { track!!.play(); pausedAudio = false }
val head = playedFrames(System.nanoTime())
@ -282,6 +283,7 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
MediaCodec.BUFFER_FLAG_END_OF_STREAM); eosQueued = true }
}
video.step(position, System.nanoTime() / 1000); video.checkProgress(System.nanoTime() / 1000, ended)
check(!video.ended || video.firstOutputPts != null || video.inputCount == 0L) { "Decoder ended without producing an image" }
}
if (ended && video.input == null && (decoder == null || video.ended) && NativeLib.streamPlaybackEmpty(playback)
&& playedFrames(System.nanoTime()) >= written) {

11
tools/chatgui-android/app/src/test/java/com/utun/chat/data/StreamDecodePumpTest.kt

@ -95,4 +95,15 @@ class StreamDecodePumpTest {
codec.pump.step(120000, 200000)
assertEquals(4L, codec.pump.outputCount); assertEquals(120000L, codec.pump.decoderLeadUs)
}
@Test fun emptyEosReleasesTheBufferAndClearsInputsWithoutDisplayPictures() {
var finishing = false; var eof = false; var released = 0
val pump = StreamDecodePump<Frame>(submit = { true }, receive = {
if (finishing && !eof) { eof = true; StreamDecodePump.Output(0, 80000, eos = true, empty = true) } else null
}, release = { _, render -> assertFalse(render); released++ })
repeat(3) { i -> pump.offer(Frame(i * 40000L), i * 40000L); pump.step(0, i * 40000L) }
assertEquals(3, pump.inflight); finishing = true; pump.step(0, 120000)
assertTrue(pump.ended); assertEquals(0, pump.inflight); assertEquals(-1L, pump.oldestSubmittedPts)
assertEquals(1, released); pump.checkProgress(30_000_000, true)
}
}

Loading…
Cancel
Save