fix: 修复自编码模式黑屏及并发问题

- 修复 MediaCodec 回调需在 configure 前设置导致的异常
- 修复解码器线程安全问题及包乱序/重复处理
- 增加关键帧前重发 SPS/PPS 以防首帧丢失导致黑屏
- 支持分辨率切换时重置解码器
- 修复 Flutter 控制端连接类型选项 UI 显示拥挤问题
This commit is contained in:
2026-07-24 09:31:58 +08:00
parent f8048e1331
commit 778c37b8db
9 changed files with 374 additions and 107 deletions

View File

@@ -141,8 +141,9 @@ class SelfCodecDecoderPlugin :
val st = entry.surfaceTexture()
surfaceTexture = st
st.setDefaultBufferSize(PLACEHOLDER_W, PLACEHOLDER_H)
// MediaCodec 把解码帧渲染到该 SurfaceTexture。必须消费updateTexImage
// 新帧,否则 SurfaceTexture 一直停留在初始(黑)帧,导致切换自编码后无画面。
st.setOnFrameAvailableListener { texture: SurfaceTexture ->
// 解码器将帧渲染到 Surface 后触发,这里更新纹理内容供 Flutter 显示。
try {
texture.updateTexImage()
} catch (e: Exception) {
@@ -251,8 +252,11 @@ class SelfCodecDecoderPlugin :
}
override fun onOutputFormatChanged(codec: MediaCodec, format: MediaFormat) {
val w = format.getInteger(MediaFormat.KEY_WIDTH, 0)
val h = format.getInteger(MediaFormat.KEY_HEIGHT, 0)
// getInteger(key, default) 需要 API 29+,用 containsKey 兼容低版本
val w = if (format.containsKey(MediaFormat.KEY_WIDTH))
format.getInteger(MediaFormat.KEY_WIDTH) else 0
val h = if (format.containsKey(MediaFormat.KEY_HEIGHT))
format.getInteger(MediaFormat.KEY_HEIGHT) else 0
if (w > 0 && h > 0) {
surfaceTexture?.setDefaultBufferSize(w, h)
mainHandler.post {