使用MediaCodec和Surface进行Android编码

我一直在通过MediaCodec将视频直接渲染到我的UI中从SurfaceView获取的Surface.这非常有效.

我现在正在尝试使用MediaCodec作为编码器.作为测试,我想渲染到Surface(如上所述)并通过配置为编码器的MediaCodec的不同实例进行环回.

我看到编码器的createInputSurface()方法.我想我希望编码器创建这个表面然后让解码器MediaCodec使用它作为要绘制的表面.首先,这可能吗?

其次,我不确定如何从编码器创建的Surface创建SurfaceView.我只从SurfaceView中提取了一个Surface,而我从文档中看不到如何反向执行此操作.

解决方法:

表面是生产者 – 消费者安排的“生产者”方面.一般来说,API以消费者为中心,创建两端,然后将生产者界面(Surface)交给您.

因此,对于SurfaceView或MediaCodec编码器,您可以创建对象,并获取其Surface.然后使用Canvas,OpenGL ES或MediaCodec解码器向其发送图形数据缓冲区.

无法获取编码器的输入Surface并将其用作SurfaceView的显示Surface – 它们是两个不同的管道. SurfaceView的使用者位于系统合成器(SurfaceFlinger)中,这就是为什么你必须等待“表面创建”回调才能触发的原因. MediaCodec编码器的消费者处于mediaserver过程中,尽管隐藏了异步性.

将MediaCodec解码器输出发送到SurfaceView非常简单,将输出发送到MediaCodec编码器也是如此.如您所推测的那样,只需将编码器的输入Surface传递给解码器即可.生活变得有趣的地方就是你想要同时做这两件事.

Surface下面的代码(称为BufferQueue)应该能够(从Lollipop开始)进行多路复用,但我不知道Lollipop中的API会向应用程序公开该功能.这意味着你很难坚持做事.

困难的方法是创建一个SurfaceTexture(a / k / a GLConsumer),它是管道的消费者端.从那里你可以使用sole constructor创建一个Surface.你可以将它交给MediaCodec解码器.现在,每个出来的帧都将被SurfaceTexture转换为GLES纹理.您可以将它们渲染到SurfaceView和编码器的输入Surface.

您可以在Grafika中找到各种示例,并在graphics architecture doc中找到更长的机制解释.

上一篇:用深度学习构造聊天机器人简介


下一篇:使用装饰器编码自定义对象 – Python