Android 如何将相机预览传递到MediaCodec.createInputSurface()创建的曲面?
理想情况下,我希望实现两个目标:Android 如何将相机预览传递到MediaCodec.createInputSurface()创建的曲面?,android,camera,surfaceview,encoder,android-mediacodec,Android,Camera,Surfaceview,Encoder,Android Mediacodec,理想情况下,我希望实现两个目标: 通过表面将摄像头预览数据传递到MediaCodec编码器。我可以使用MediaCodec.createInputSurface()创建曲面,但是摄像头.setPreviewDisplay()使用曲面文件夹,而不是曲面 除了将相机预览数据传递给编码器之外,我还希望在屏幕上显示预览(这样用户可以真正看到他们正在编码什么)。如果不涉及编码器,那么我会使用SurfaceView,但在这种情况下似乎不起作用,因为SurfaceView创建了自己的Surface,我想我需要
表面
将摄像头
预览数据传递到MediaCodec
编码器。我可以使用MediaCodec.createInputSurface()
创建曲面
,但是摄像头.setPreviewDisplay()
使用曲面文件夹
,而不是曲面
李>
相机
预览数据传递给编码器之外,我还希望在屏幕上显示预览(这样用户可以真正看到他们正在编码什么)。如果不涉及编码器,那么我会使用SurfaceView
,但在这种情况下似乎不起作用,因为SurfaceView
创建了自己的Surface
,我想我需要使用由MediaCodec
创建的摄像头和MediaCodec更直接地说话,而不涉及EGL或纹理。从Android 4.3(API 18)开始,CameraToPegTest方法是正确的方法
EGL/SurfaceTexture开销目前是不可避免的,特别是对于您在目标2中想要做的事情。这个想法是:
- 将摄像头配置为将输出发送到
SurfaceTexture
。这将使相机输出作为“外部纹理”提供给GLES
- 将
SurfaceTexture
渲染到由MediaCodec\createInputSurface()
返回的曲面。为视频编码器提供信息
- 再次将
SurfaceTexture
渲染到GLSurfaceView
。这样就可以在显示屏上进行实时预览
唯一发生的数据复制是由GLES驱动程序执行的,因此您正在执行硬件加速的BLIT,这将非常快
唯一棘手的是,您希望外部纹理可用于两个不同的EGL上下文(一个用于MediaCodec
,一个用于GLSurfaceView
)。您可以在bigflake上的“Android Breakout game recorder补丁”示例中看到一个创建共享上下文的示例——它将游戏渲染两次,一次渲染到屏幕,一次渲染到MediaCodec
编码器
更新:这在(“Show+capture camera”)中实现
更新:在“显示+捕获摄影机”方法中的多上下文方法是。“连续捕获”活动使用普通的SurfaceView,并且能够使用单个EGL上下文进行屏幕渲染和视频录制。这是推荐的。关于棘手的一点,我发现CameraToMpegTest和breakout游戏录制器之间的主要区别在于,在录制器中,在为录制器部分创建上下文时,实际上定义了一个共享的egl上下文。因此,只要确保上下文是共享的,在绘制“主”图片之后,将次要上下文和曲面设置为当前,然后再次使用相同的绘图代码。或者,使用一个EGL上下文和两个EGL曲面。(自从我写这篇文章以来,Grafika已经扩展了很多;另一个例子见“持续捕获”活动。)