当前位置: 首页 > 面试题库 >

如何使用JNI在C中获取原始的Android相机缓冲区?

山越
2023-03-14
问题内容

我一直在详尽搜索Google,但是找不到。也许我缺少明显的东西。谢谢!

(这是因为预览回调(即使使用缓冲区)的Java实现效率也很低。)


问题答案:

我对这个话题做了一些调查。该演讲(来自第277页,中文)很有帮助。

相机预览通话链

如其他人所述,您可以使用Camera.setPreviewCallback方法获得缓冲区。
这是那里发生的情况(详细版本):

  1. 用户调用Camera.startPreview()这是一个本机函数。
  2. android_hardware_Camera_startPreview调用startPreviewC ++ Camera类的方法。
  3. Camera调用接口startPreview方法ICamera
  4. ICamera使一个IPC远程客户端调用。
  5. 它调用类的setCameraMode方法CameraService
  6. CameraService设置一个窗口以显示预览并调用类的startPreview方法CameraHardwareInterface
  7. 后者尝试start_preview在特定camera_device_t设备上调用方法。
    我没有进一步查找,但是它应该执行呼叫驱动程序。

  8. 当图像到达时,dataCallbackCameraService被调用。

  9. 它将数据传递给handlePreviewData客户端的方法。
  10. 客户端要么复制缓冲区,要么直接将其发送到ICameraClient
  11. ICameraClient将其发送IPCCamera
  12. Camera调用注册的侦听器并将缓冲区传递给JNI
  13. 它调用Java类中的回调。如果用户提供了缓冲区,Camera.addCallbackBuffer则它将首先复制到缓冲区。
  14. 最后,Java类Camera处理消息并调用的onPreviewFrame方法Camera.PreviewCallback

如您所见IPC,在步骤10、11上,调用了2个调用,并且缓冲区被复制了至少两次。所返回的raw缓冲区的第一个实例camera_device_t托管在另一个进程中,由于中的安全检查,您无法访问它CameraService

预览表面

但是,当您使用Camera.setPreviewTexture或设置预览图面时,或将Camera.setPreviewDisplay其直接传递到摄像头设备并实时刷新,而无需上面所有链条的参与。正如文档所述:

处理到由屏幕合成器管理的原始缓冲区。

Java类Surface具有一种检索其内容的方法:

public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer);

但是此API是隐藏的。请参阅此问题以获取使用方法。



 类似资料:
  • CameraToMpegTest的示例。bigflake中的java。com或Grafika中的“Show capture camera”使用该摄像机。预览以获取帧数据。实验表明(Nexus 4,Android 4.4.2)的帧速率为10fps。这没有预期的那么高。 如果我们使用相同的设备(Nexus 4、Android 4.4.2)使用摄像头录制视频,帧速率为30fps。 所以我假设使用came

  • 如何获取相机捕获的原始图像的路径或uri。当我使用下面的代码时,它会返回google文档中提到的原始图像的缩略图。我想要原始图像的路径或uri。 我使用了以下代码,但它返回一个缩略图。

  • 我们正在探索在Android项目中包含一些现有的C库,并被推荐使用JNI。我看到的大多数参考资料都建议这样做:https://medium.com/@ssarel/create-your-first-jni-Application ation-on-android-with-the-ndk-5f149508fb12,您可以在其中生成本机标头和代码以与Java交互。 假设您不能修改本机库,这仍然是最

  • 我有一条基类消息 以及扩展动物的子类 因此,在构建狗消息时,我应该能够设置动物的所有字段。我知道这样做的方法(在狗消息中再次声明所有动物字段),但是否可以简单有效地使用原型缓冲区?我还了解了扩展,我明白它只是用于向已经存在的消息添加一个新字段,因此不应该被误解为实现继承的可能解决方案。 使用protobuffers的扩展是否可以实现上述简单的设计?

  • 下面是我想做的: 我的csv有5列 a b c d e 如何使用java获取csv中每个列的列号,以及使用列号获取该列的列号,我想将数据附加到单元格。我是这个概念的新手,所以请建议我如何继续前进。谢谢。

  • 问题内容: 我想确定使用JNI从C ++代码调用该函数时Java函数引发了什么异常。我有以下捕获Java异常的代码: 我不知道如何在此C ++代码中获取有关Java异常的描述性信息。有人可以帮忙吗? 问题答案: 在每次JNI 调用之后,我都省略了调用,并没有检查任何为简便起见而定位失败的尝试:在实现时应添加这些方法。 首先,存储异常,然后获取获取有关的信息所必需的Java方法: 其次,递归构造错误