如何在Android中使用受限的高速捕获会话获取实时图像处理?

Dan*_*l F 5 real-time surfaceview android-ndk mediarecorder android-camera2

我正在一个需要使用Android智能手机的摄像头(实际上是三星Galaxy S7)进行实时图像处理的项目。

简要地说,主要要求/条件是:

  • 我需要以高帧速率(理想情况下为120fps或240fps,但60fps是一个好的开始)实时捕获和处理图像;
  • 无需预览显示的图像。
  • 我只需要灰度图像(使用nv21格式,这是图像数据的第一部分)。因此,为了提高效率,我宁愿不要将图像从本机格式转换为jpg,然后再解码和计算灰度数据;
  • 我不需要高分辨率图像(640x480会很好),并且帧处理本身相对简单并且可以非常快速地完成(我只需要扫描灰度数据并提取一些基本信息即可);

我曾尝试使用带ImageReader表面的Camera2 Api进行传统拍摄,但即使关闭自动控制模式,为拍摄请求设置更大范围,更改曝光量,我也能获得37fps(只是拍摄,不进行处理)时间,帧时长等

现在,我正在尝试使用CameraConstrainedHighSpeedCaptureSessionCamera2 Api中的类解决问题。但是,Android参考资料表示应将其用于高速VIDEO RECORDING用例。此外,根据该文件,该方法createConstrainedHighSpeedCaptureSession需要一个表面必须是一个视频编码器的表面(即可以从获取MediaRecorder)或预览表面(获自SurfaceViewSurfaceTexture)。我认为这种捕获模式使用一种特殊的表面/缓冲区(可能更快,更有效)。

我认为使用预览图面(SurfaceViewSurfaceTexture),我可能会陷入60fps(显示刷新率)的困境。所以,我正在寻找一种方式来获得进入BufferQueueMediaRecorder的表面,也许使用NDK / JNI。这个想法是MediaRecorder在对帧进行视频编码之前,可以访问从相机设备传递到的原始帧数据。

拜托,这可能吗?如何实现?有没有更好的办法?

作为替代方案,我已经读过一篇文章FileDescriptor,目的是将生成的视频帧重定向MediaRecorder 到内存中的缓冲区,然后尝试在生成这些帧时对其进行访问,但这似乎效率很低,并且延迟可能应用程序不容忍。