android - 如何理解 MediaCodec 的用户界面以提高编解码器性能?
问题描述
mediacodec 的官方文档说:
数据类型编解码器对三种数据进行操作:压缩数据、原始音频数据和原始视频数据。所有这三种数据都可以使用 ByteBuffers 进行处理,但您应该使用 Surface 来处理原始视频数据以提高编解码器性能。Surface 使用本机视频缓冲区,无需映射或复制到 ByteBuffers;因此,它的效率要高得多。使用 Surface 时通常无法访问原始视频数据,但可以使用 ImageReader 类访问不安全的解码(原始)视频帧。这可能仍然比使用 ByteBuffers 更有效,因为一些本机缓冲区可能会映射到直接 ByteBuffers。使用 ByteBuffer 模式时,您可以使用 Image 类和 getInput/OutputImage(int) 访问原始视频帧。
如何理解这一点?您应该使用 Surface 处理原始视频数据以提高编解码器性能,什么是原生视频缓冲区?如何使用 Surface 提高编码或解码性能?
解决方案
您可以使用编解码器的输入表面对视频帧进行编码,您可以使用createInputSurface()获取此表面,然后(如果您不使用 NDK)您可以从表面获取画布并在其上绘制帧,或者您可以使用NDK 并将帧数据复制到表面缓冲区,结果中的这两种方法都会为您提供编码的帧数据。
至于解码,您可以在 UI 中创建一些表面并使用configure()将其传递给解码器,它将允许解码器将解码的帧渲染到表面,因此您无需从解码器的输出缓冲区复制解码数据您应该做的是将true
作为“渲染”参数传递给解码器的releaseOutputBuffer()。
推荐阅读
- flutter - Flutter - Navigator.push 值列表
- css - 当且仅当下一行没有足够空间容纳整个单词时,使用 CSS 强制使用连字符进行分词
- c# - 如何修复 C# 中的停止“无法将 int 类型隐式转换为 bool”错误代码
- c# - 抓取 URL 中的令牌
- pandas - 使用逻辑索引时,熊猫仅适用于返回第一个值
- sql - 将多个列更新为相同的值时如何避免 SQL 中的重复?
- r - 如何使用 shinyjs 来识别选项卡是否在闪亮中处于活动状态?
- python - 循环遍历数据框的每一行并根据条件向数据框添加一个元素
- html - 为什么 Visual Studio 不会格式化我的 HTML 文档?
- java - Kafka StreamsException TimeoutException:即将到期的 N 条记录实现 KTable