我一直在通过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中找到更长的机制解释.