|
|
|
|
@ -62,9 +62,10 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
|
|
|
|
var generation = 0L |
|
|
|
|
var decoded = 0L |
|
|
|
|
var discarded = 0L |
|
|
|
|
var decodedThrough = -1L |
|
|
|
|
var lastSubmittedPts = -1L |
|
|
|
|
var pendingOutput = -1 |
|
|
|
|
var pendingPts = 0L |
|
|
|
|
var pendingEos = false |
|
|
|
|
var eosQueued = false |
|
|
|
|
var decoderEnded = false |
|
|
|
|
var endUntil = 0L |
|
|
|
|
@ -87,7 +88,7 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
|
|
|
|
fun resetVideo() { |
|
|
|
|
try { decoder?.stop(); decoder?.release() } |
|
|
|
|
catch (e: Exception) { LogManager.addLog("WARN", "video", "decoder reset id=$id: ${e.message}") } |
|
|
|
|
decoder = null; videos.clear(); submitted.clear(); pendingOutput = -1; decodedThrough = -1 |
|
|
|
|
decoder = null; videos.clear(); submitted.clear(); pendingOutput = -1; lastSubmittedPts = -1; pendingEos = false |
|
|
|
|
waitingKey = true; eosQueued = false; decoderEnded = false |
|
|
|
|
mutableStatus.value = R.string.stream_waiting_key |
|
|
|
|
} |
|
|
|
|
@ -237,14 +238,14 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
|
|
|
|
val input = decoder!!.getInputBuffer(index) ?: error("Missing decoder input") |
|
|
|
|
check(frame.data.size <= input.capacity()); input.clear(); input.put(frame.data) |
|
|
|
|
decoder!!.queueInputBuffer(index, 0, frame.data.size, frame.pts, 0) |
|
|
|
|
submitted.addLast(frame.pts); videos.removeFirst(); decoded++ |
|
|
|
|
submitted.addLast(frame.pts); lastSubmittedPts = frame.pts; videos.removeFirst(); decoded++ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
val codec = decoder |
|
|
|
|
if (codec != null) { |
|
|
|
|
if (ended && videos.isEmpty() && !eosQueued) { |
|
|
|
|
val index = codec.dequeueInputBuffer(0) |
|
|
|
|
if (index >= 0) { codec.queueInputBuffer(index, 0, 0, decodedThrough.coerceAtLeast(0) + 1, |
|
|
|
|
if (index >= 0) { codec.queueInputBuffer(index, 0, 0, lastSubmittedPts.coerceAtLeast(0), |
|
|
|
|
MediaCodec.BUFFER_FLAG_END_OF_STREAM); eosQueued = true } |
|
|
|
|
} |
|
|
|
|
repeat(8) { |
|
|
|
|
@ -254,12 +255,14 @@ class StreamPlayerEngine(private val group: Long, private val source: Long, priv
|
|
|
|
|
if (info.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0 && info.size == 0) { |
|
|
|
|
codec.releaseOutputBuffer(index, false); decoderEnded = true; return@repeat |
|
|
|
|
} |
|
|
|
|
pendingOutput = index; pendingPts = info.presentationTimeUs; decodedThrough = pendingPts |
|
|
|
|
pendingOutput = index; pendingPts = info.presentationTimeUs |
|
|
|
|
pendingEos = info.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0 |
|
|
|
|
while (submitted.isNotEmpty() && submitted.first <= pendingPts) submitted.removeFirst() |
|
|
|
|
} |
|
|
|
|
if (pendingPts > position) return@repeat |
|
|
|
|
val render = pendingPts >= position - 100000 |
|
|
|
|
codec.releaseOutputBuffer(pendingOutput, render); pendingOutput = -1 |
|
|
|
|
if (pendingEos) { decoderEnded = true; pendingEos = false } |
|
|
|
|
if (!render) discarded++ else mutableStatus.value = R.string.stream_live |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|