缓冲表面输入到MediaCodec

dbr*_*bro 7 android mediacodec

已经演示了如何使用像SurfacePreview这样的Surface输入提供MediaCodec,但是在提交之前是否有实用的方法来缓冲此输入MediaCodec

在我的实验中,Galaxy Nexus在使用CameraToMpegTest.java中的直接同步编码方法生成音频/视频流时遇到了令人无法接受的打嗝

当使用MediaCodecbyte[]ByteBuffer输入,我们可以提交未编码数据的ExecutorService或类似的队列进行处理,以确保帧不丢失,即使在CPU使用该设备的经验尖峰我们的应用程序的控制.但是,由于要求在Android的Camera和MediaCodec之间执行颜色格式转换,这种方法对于高分辨率的直播视频来说是不现实的.

想法:

  1. 有没有办法喂NativePixmapType以创建EGL14.eglCopyBuffers(EGLDisplay d, EGLSurface s, NativePixmapType p)MediaCodec

  2. 任何来自Android的人都可以评论相机和MediaCodec之间是否协调ByteBuffer格式是否在路线图上?

fad*_*den 5

您真的根本不想复制数据。为大量数据分配存储和复制可能需要足够长的时间来降低帧速率。这通常排除了 byte[] 和 ByteBuffer[] 解决方案,即使您不必进行 U/V 平面交换。

在系统中移动数据的最有效方法是使用 Surface。诀窍在于 Surface 不是缓冲区,而是缓冲区队列的接口。缓冲区通过引用传递;当您unlockCanvasAndPost()实际将当前缓冲区放入消费者队列时,这通常位于不同的进程中。

没有公共机制来创建新缓冲区并将其添加到队列使用的集合中,或者从队列中提取缓冲区,因此您无法在侧面实现 DIY 缓冲方案。没有公共接口可以更改池中缓冲区的数量。

了解导致打嗝的原因会很有用。用于分析此类问题的 Android 工具是 systrace,可在 Android 4.1+ 中使用(文档示例bigflake 示例)。如果您可以识别 CPU 负载的来源,或者确定不是 CPU 而是一些代码发生了混乱,您可能会找到一个比向 Surface 添加更多缓冲区要容易得多的解决方案。