fix:调整渲染缓冲区
This commit is contained in:
parent
c97f719ccb
commit
6e44ee8b48
@ -80,7 +80,7 @@ class VideoDecoder(
|
||||
|
||||
// 渲染帧率(fps),可由外部控制,默认30
|
||||
@Volatile
|
||||
var renderFps: Int = 25
|
||||
var renderFps: Int = 20
|
||||
|
||||
// 兜底:记录最近一次I帧的frameSeq,P/B帧依赖校验
|
||||
@Volatile
|
||||
@ -111,6 +111,10 @@ class VideoDecoder(
|
||||
private val reorderLock = ReentrantLock() // 线程安全
|
||||
private val MAX_REORDER_BUFFER_SIZE = BUFFER_QUEUE_CAPACITY
|
||||
|
||||
// 低水位启动渲染标志
|
||||
@Volatile
|
||||
private var renderStarted = false
|
||||
|
||||
// 输入帧结构体
|
||||
private data class FrameData(
|
||||
val data: ByteArray,
|
||||
@ -161,6 +165,39 @@ class VideoDecoder(
|
||||
|
||||
// 创建解码器
|
||||
val decoder = MediaCodec.createDecoderByType(mime)
|
||||
|
||||
// ========== 输出所有支持的视频解码器及类型 ==========
|
||||
try {
|
||||
val codecList = if (android.os.Build.VERSION.SDK_INT >= 21) {
|
||||
android.media.MediaCodecList(android.media.MediaCodecList.ALL_CODECS).codecInfos
|
||||
} else {
|
||||
arrayOf<android.media.MediaCodecInfo>()
|
||||
}
|
||||
Log.i(TAG, "[CodecList] 支持的视频解码器如下:")
|
||||
for (info in codecList) {
|
||||
if (!info.isEncoder) {
|
||||
val types = info.supportedTypes.joinToString(", ")
|
||||
val name = info.name
|
||||
val isHardware = if (android.os.Build.VERSION.SDK_INT >= 29) info.isHardwareAccelerated else !name.startsWith("OMX.google.")
|
||||
val isSoftware = if (android.os.Build.VERSION.SDK_INT >= 29) info.isSoftwareOnly else name.startsWith("OMX.google.")
|
||||
Log.i(TAG, "解码器名称: $name, 支持类型: [$types], 硬解码: $isHardware, 软解码: $isSoftware")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "[CodecList] 获取解码器列表失败", e)
|
||||
}
|
||||
|
||||
// ========== 输出当前创建的解码器类型 ==========
|
||||
try {
|
||||
val codecInfo = decoder.codecInfo
|
||||
val name = codecInfo.name
|
||||
val isHardware = if (android.os.Build.VERSION.SDK_INT >= 29) codecInfo.isHardwareAccelerated else !name.startsWith("OMX.google.")
|
||||
val isSoftware = if (android.os.Build.VERSION.SDK_INT >= 29) codecInfo.isSoftwareOnly else name.startsWith("OMX.google.")
|
||||
Log.i(TAG, "[CurrentCodec] 当前解码器: $name, 硬解码: $isHardware, 软解码: $isSoftware")
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "[CurrentCodec] 获取当前解码器信息失败", e)
|
||||
}
|
||||
|
||||
// 设置解码回调
|
||||
decoder.setCallback(object : MediaCodec.Callback() {
|
||||
override fun onInputBufferAvailable(codec: MediaCodec, index: Int) {
|
||||
@ -237,6 +274,17 @@ class VideoDecoder(
|
||||
return@Runnable
|
||||
}
|
||||
|
||||
// 低水位启动渲染逻辑
|
||||
if (!renderStarted) {
|
||||
if (outputFrameQueue.size >= (BUFFER_QUEUE_CAPACITY * 0.15).toInt()) {
|
||||
renderStarted = true
|
||||
Log.i(TAG, "[Render] 渲染启动,outputFrameQueue已达低水位: ${outputFrameQueue.size}")
|
||||
} else {
|
||||
// 未达到低水位前不渲染
|
||||
return@Runnable
|
||||
}
|
||||
}
|
||||
|
||||
val frame = outputFrameQueue.poll()
|
||||
if (frame != null) {
|
||||
frame.codec.releaseOutputBuffer(frame.bufferIndex, true)
|
||||
@ -247,10 +295,10 @@ class VideoDecoder(
|
||||
mainHandler.post { onFrameRendered() }
|
||||
hasNotifiedFlutter = true
|
||||
}
|
||||
// Log.d(TAG, "[Render] 渲染: bufferIdx=${frame.bufferIndex}, pts=${frame.timestampUs}, " +
|
||||
// "当前outputFrameQueue=${outputFrameQueue.size}")
|
||||
Log.d(TAG, "[Render] 渲染: bufferIdx=${frame.bufferIndex}, pts=${frame.timestampUs}, " +
|
||||
"当前outputFrameQueue=${outputFrameQueue.size}")
|
||||
} else {
|
||||
// Log.w(TAG, "[Render] 渲染空转,无帧可渲染,当前outputFrameQueue=${outputFrameQueue.size}")
|
||||
Log.w(TAG, "[Render] 渲染空转,无帧可渲染,当前outputFrameQueue=${outputFrameQueue.size}")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "[RenderTask] Exception", e)
|
||||
@ -275,10 +323,10 @@ class VideoDecoder(
|
||||
refIFrameSeq: Int?
|
||||
): Boolean {
|
||||
if (!running || mediaCodec == null) return false
|
||||
if (!frameSeqSet.add(frameSeq)) {
|
||||
Log.w(TAG, "[decodeFrame] 丢弃重复帧: type=$frameType, seq=$frameSeq, refI=$refIFrameSeq, ts=$timestamp")
|
||||
return false // 防止重复帧
|
||||
}
|
||||
// if (!frameSeqSet.add(frameSeq)) {
|
||||
// Log.w(TAG, "[decodeFrame] 丢弃重复帧: type=$frameType, seq=$frameSeq, refI=$refIFrameSeq, ts=$timestamp")
|
||||
// return false // 防止重复帧
|
||||
// }
|
||||
// 2. 初始化起点
|
||||
if (timestampBaseMs == null) {
|
||||
synchronized(this) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user