fix:调整渲染缓冲区
This commit is contained in:
parent
c97f719ccb
commit
6e44ee8b48
@ -80,7 +80,7 @@ class VideoDecoder(
|
|||||||
|
|
||||||
// 渲染帧率(fps),可由外部控制,默认30
|
// 渲染帧率(fps),可由外部控制,默认30
|
||||||
@Volatile
|
@Volatile
|
||||||
var renderFps: Int = 25
|
var renderFps: Int = 20
|
||||||
|
|
||||||
// 兜底:记录最近一次I帧的frameSeq,P/B帧依赖校验
|
// 兜底:记录最近一次I帧的frameSeq,P/B帧依赖校验
|
||||||
@Volatile
|
@Volatile
|
||||||
@ -111,6 +111,10 @@ class VideoDecoder(
|
|||||||
private val reorderLock = ReentrantLock() // 线程安全
|
private val reorderLock = ReentrantLock() // 线程安全
|
||||||
private val MAX_REORDER_BUFFER_SIZE = BUFFER_QUEUE_CAPACITY
|
private val MAX_REORDER_BUFFER_SIZE = BUFFER_QUEUE_CAPACITY
|
||||||
|
|
||||||
|
// 低水位启动渲染标志
|
||||||
|
@Volatile
|
||||||
|
private var renderStarted = false
|
||||||
|
|
||||||
// 输入帧结构体
|
// 输入帧结构体
|
||||||
private data class FrameData(
|
private data class FrameData(
|
||||||
val data: ByteArray,
|
val data: ByteArray,
|
||||||
@ -161,6 +165,39 @@ class VideoDecoder(
|
|||||||
|
|
||||||
// 创建解码器
|
// 创建解码器
|
||||||
val decoder = MediaCodec.createDecoderByType(mime)
|
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() {
|
decoder.setCallback(object : MediaCodec.Callback() {
|
||||||
override fun onInputBufferAvailable(codec: MediaCodec, index: Int) {
|
override fun onInputBufferAvailable(codec: MediaCodec, index: Int) {
|
||||||
@ -237,6 +274,17 @@ class VideoDecoder(
|
|||||||
return@Runnable
|
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()
|
val frame = outputFrameQueue.poll()
|
||||||
if (frame != null) {
|
if (frame != null) {
|
||||||
frame.codec.releaseOutputBuffer(frame.bufferIndex, true)
|
frame.codec.releaseOutputBuffer(frame.bufferIndex, true)
|
||||||
@ -247,10 +295,10 @@ class VideoDecoder(
|
|||||||
mainHandler.post { onFrameRendered() }
|
mainHandler.post { onFrameRendered() }
|
||||||
hasNotifiedFlutter = true
|
hasNotifiedFlutter = true
|
||||||
}
|
}
|
||||||
// Log.d(TAG, "[Render] 渲染: bufferIdx=${frame.bufferIndex}, pts=${frame.timestampUs}, " +
|
Log.d(TAG, "[Render] 渲染: bufferIdx=${frame.bufferIndex}, pts=${frame.timestampUs}, " +
|
||||||
// "当前outputFrameQueue=${outputFrameQueue.size}")
|
"当前outputFrameQueue=${outputFrameQueue.size}")
|
||||||
} else {
|
} else {
|
||||||
// Log.w(TAG, "[Render] 渲染空转,无帧可渲染,当前outputFrameQueue=${outputFrameQueue.size}")
|
Log.w(TAG, "[Render] 渲染空转,无帧可渲染,当前outputFrameQueue=${outputFrameQueue.size}")
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "[RenderTask] Exception", e)
|
Log.e(TAG, "[RenderTask] Exception", e)
|
||||||
@ -275,10 +323,10 @@ class VideoDecoder(
|
|||||||
refIFrameSeq: Int?
|
refIFrameSeq: Int?
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (!running || mediaCodec == null) return false
|
if (!running || mediaCodec == null) return false
|
||||||
if (!frameSeqSet.add(frameSeq)) {
|
// if (!frameSeqSet.add(frameSeq)) {
|
||||||
Log.w(TAG, "[decodeFrame] 丢弃重复帧: type=$frameType, seq=$frameSeq, refI=$refIFrameSeq, ts=$timestamp")
|
// Log.w(TAG, "[decodeFrame] 丢弃重复帧: type=$frameType, seq=$frameSeq, refI=$refIFrameSeq, ts=$timestamp")
|
||||||
return false // 防止重复帧
|
// return false // 防止重复帧
|
||||||
}
|
// }
|
||||||
// 2. 初始化起点
|
// 2. 初始化起点
|
||||||
if (timestampBaseMs == null) {
|
if (timestampBaseMs == null) {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user