我一直在搜索谷歌和StackOverflow,并且找不到这个。也许我错过了一些明显的东西。谢谢!
(这是因为预览回调的Java实现[即使使用缓冲区]效率太低。)
答案 0 :(得分:25)
我对话题进行了一些调查。 presentation(来自p.277,中文)有很多帮助。
正如其他人提到的,您可以使用Camera.setPreviewCallback
方法获取缓冲区
以下是它的发生方式(详细版本):
Camera.startPreview()
这是一个原生函数。android_hardware_Camera_startPreview
调用C ++ startPreview
类的Camera
方法。Camera
调用startPreview
接口ICamera
方法
ICamera
对远程客户端进行IPC
调用。setCameraMode
类的CameraService
方法。CameraService
设置一个窗口以显示预览,并调用startPreview
类的CameraHardwareInterface
方法。start_preview
设备上调用camera_device_t
方法。 dataCallback
的{{1}}。CameraService
方法。handlePreviewData
。ICameraClient
通过ICameraClient
将其发送至IPC
。Camera
调用已注册的侦听器并将缓冲区传递给Camera
。JNI
的缓冲区,则它首先复制到缓冲区。Camera.addCallbackBuffer
处理邮件并调用Camera
的{{1}}方法。正如您所看到的那样,调用了2 onPreviewFrame
个调用,并且在步骤10,11中至少复制了两次缓冲区。Camera.PreviewCallback
返回的原始缓冲区的第一个实例托管在另一个进程中由于IPC
中的安全检查,无法访问它。
但是,当您使用camera_device_t
或CameraService
设置预览曲面时,它会直接传递到相机设备并实时刷新,而无需参与上述所有链。正如它的文件说:
处理由屏幕合成器管理的原始缓冲区。
Java类Camera.setPreviewTexture
有一个方法来检索它的内容:
Camera.setPreviewDisplay
但是这个API是隐藏的。有关使用它的方法,请参见this question。
答案 1 :(得分:5)
没有公共API可以做你想要的事情;唯一的官方(即保证工作)方法是通过调用Camera.setPreviewCallback()设置的Java级预览回调。在Android> 3.0,您还可以使用Camera.setPreviewTexture()将预览数据路由到GPU,并使用GLES处理它(或将其读回CPU)。 GPU路径是ICS AOSP相机应用程序用于视频效果的路径。
据推测,OpenCV和其他人已经浏览了Android框架本机代码,并绕过了Java Camera API,直接与下面的服务交谈。
这是相当危险的,因为绝对不能保证这些界面不会在Android版本之间发生变化,因为它们不是公共API的一部分。使用它们现在可能没问题,然后当用户升级他们的设备时,您的应用程序将停止工作。
答案 2 :(得分:1)
你看过OpenCV for Android了吗?他们的advanced tutorials显示了如何使用JNI,并且他们的相机包中有一个NativeProcessor对象。