Recover streams after five seconds and start from complete keys
Preserve queued media under backpressure, advertise retained keyframe ranges in stream wire v6, and reopen stalled subflows without resetting playback. Cover large fragmented keys, sustained slow delivery, missing subflows, buffer eviction and stale bootstrap snapshots in integration regressions.
This commit is contained in:
1 parent
4a785c2598
commit
c3cf86b9e0
15 files changed
+461
-160
No files matched your search
@@ -90,7 +90,6 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
||||
var video: StreamVideoPlayback? = null
|
||||
var waitingKey = true
|
||||
var audioEnabled = false
|
||||
var opened = false
|
||||
var ended = false
|
||||
var videoInputEnded = false
|
||||
var audioInputEnded = false
|
||||
@@ -113,7 +112,6 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
||||
var underrunBase = 0L
|
||||
var silenceBase = 0L
|
||||
var workMaxUs = 0L
|
||||
var deadline = System.nanoTime() + 10_000_000_000
|
||||
var clockState: LongArray? = null
|
||||
|
||||
fun observeStatus(meta: LongArray?) {
|
||||
@@ -139,7 +137,7 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
||||
playback = null; position = -1; generation = 0; needsAudio = true; clockState = null; playbackStarted = false
|
||||
underrunBase = 0; silenceBase = 0
|
||||
records.clear(); ended = false; videoInputEnded = false; audioInputEnded = false; endUntil = 0
|
||||
resetVideo(); deadline = System.nanoTime() + 10_000_000_000
|
||||
resetVideo()
|
||||
if (request) check(NativeLib.streamResync(id)) { "Media resync refused" }
|
||||
}
|
||||
try {
|
||||
@@ -180,7 +178,6 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
||||
1 -> {
|
||||
if (revision != videoRevision) {
|
||||
check(revision > videoRevision); resetVideo(); videoRevision = revision
|
||||
deadline = System.nanoTime() + 10_000_000_000
|
||||
}
|
||||
val key = flags and 1 != 0
|
||||
if (!waitingKey || key) {
|
||||
@@ -203,7 +200,7 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
||||
if (result == -2) resetTimeline(true) else check(result >= 0) { "Opus feed failed=$result" }
|
||||
}
|
||||
3 -> { LogManager.addLog("INFO", "stream", "playback GAP id=$id"); resetTimeline(false) }
|
||||
4 -> opened = true
|
||||
4 -> Unit
|
||||
5, 7, 8 -> {
|
||||
if (kind != 8 && !videoInputEnded) { videoInputEnded = true; video.finish() }
|
||||
if (kind != 7 && !audioInputEnded) { audioInputEnded = true; playback?.finish() }
|
||||
@@ -224,7 +221,7 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
||||
}
|
||||
}
|
||||
if (!running) break
|
||||
if (!ended && (!opened || waitingKey) && System.nanoTime() > deadline) error("Viewer open timeout")
|
||||
// Ядро перезапрашивает DATA после 5с без прогресса; большой KEY может собираться дольше.
|
||||
val decoded = video.state
|
||||
if (!playbackStarted && decoded.firstOutputPts != null) playbackStarted = true
|
||||
if (playbackStarted && playback != null && ready >= 0) {
|
||||
|
||||
Reference in new issue
Block a user