gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 20:22:48 25 4
gpt4 key购买 nike

我一直在彻底搜索 Google 和 StackOverflow,但找不到这个。也许我错过了一些明显的东西。谢谢!

(这是因为预览回调的Java实现[即使有缓冲区]效率太低。)

最佳答案

我对主题进行了一些调查。这个presentation (从第277页开始,中文)帮助很大。

相机预览调用链

正如其他人提到的,您可以使用 Camera.setPreviewCallback 方法获取缓冲区。
以下是它的发生方式(详细版本):

  1. 用户调用 Camera.startPreview() 这是一个原生函数。
  2. android_hardware_Camera_startPreview 调用C++ Camera 类的startPreview 方法。
  3. Camera调用ICamera接口(interface)的startPreview方法
  4. ICamera 对远程客户端进行 IPC 调用。
  5. 调用CameraService类的setCameraMode方法。
  6. CameraService 设置一个窗口显示预览并调用CameraHardwareInterface 类的startPreview 方法。
  7. 后者尝试在特定 camera_device_t 设备上调用 start_preview 方法。
    我没有进一步查找,但它应该会调用驱动程序。
  8. 当图片到达时,调用CameraServicedataCallback
  9. 将数据传递给客户端的handlePreviewData方法。
  10. 客户端要么复制缓冲区,要么直接将其发送到 ICameraClient
  11. ICameraClient 通过IPC 将其发送到Camera
  12. Camera 调用已注册的监听器并将缓冲区传递给 JNI
  13. 它调用 Java 类中的回调。如果用户使用 Camera.addCallbackBuffer 提供了一个缓冲区,则它首先复制到缓冲区。
  14. 最后,Java 类 Camera 处理消息并调用 Camera.PreviewCallbackonPreviewFrame 方法。

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

预览表面

但是,当您使用 Camera.setPreviewTextureCamera.setPreviewDisplay 设置预览表面时,它会直接传递给相机设备并实时刷新,而无需上面的所有链条。正如它的文档所说:

Handle onto a raw buffer that is being managed by the screen compositor.

Java 类 Surface 有一个方法来检索它的内容:

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

但是这个 API 是隐藏的。见即this question一种使用它的方法。

关于java - 如何使用 JNI 在 C 中获取原始 Android 相机缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10670953/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com