【问题标题】:Handling available input buffers in async MediaCodec for decoding when no new data is available在没有新数据可用时处理异步 MediaCodec 中可用的输入缓冲区以进行解码
【发布时间】:2021-03-16 23:52:32
【问题描述】:

我正在使用异步 Android MediaCodec 解码通过 websocket 接收的 H.264 视频数据。

我的问题是当没有新的编码数据要解码时如何处理输入缓冲区?

目前,当没有来自 websocket 的新编码数据时,我将没有任何数据的输入缓冲区排队:

override fun onInputBufferAvailable(codec: MediaCodec, index: Int) {
    if (videoFrames.isNotEmpty()) {
        val inputBuffer = codec.getInputBuffer(index)
        inputBuffer?.put(videoFrames.removeFirst())
        codec.queueInputBuffer(index, 0, currentFrame.size, 0, 0)
    } else {
        codec.queueInputBuffer(index, 0, 0, 0, 0)
    }
}

其中videoFrames 是带有编码视频数据的帧列表。

我这样做是因为如果我删除 else 子句并且不对空输入缓冲区进行排队,则输入缓冲区将永远不会再次可用。

是否有不同的处理方式?对空输入缓冲区进行排队对我来说感觉不对。

【问题讨论】:

    标签: android android-mediacodec


    【解决方案1】:

    另一种似乎可以稍微提高解码器性能的解决方案是将可用的输入缓冲区存储在一个队列中,并在接收到新的编码视频数据时获取它们。类似于以下内容:

    val videoFrames = ConcurrentList<ByteArray>()
    val availableBuffers = mutableListOf<Int>()
    var decoder: MediaCodec? = null
    
    fun onInputBufferAvailable(codec: MediaCodec, index: Int) {
        availableBuffers.add(index)
    }
    
    fun processFrame(frame: ByteArray) {
        var frameToProcess = frame
    
        if (videoFrames.isNotEmpty()) {
            videoFrames.add(frame)
            frameToProcess = videoFrames.removeFirst()
        }
    
        if (availableBuffers.isNotEmpty() && decoder != null) {
            val bufferIndex = availableBuffers.removeFirst()
            val inputBuffer = decoder!!.getInputBuffer(bufferIndex)
    
            inputBuffer?.put(frameToProcess)
            decoder!!.queueInputBuffer(bufferIndex, 0, frameToProcess.size, 0, 0)
        }
    }
    

    【讨论】:

    • 这确实使我的 CPU 使用率降低了大约 3-5%!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-05-01
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多