1

背景

我正在使用 video4linux 2 规范捕获视频。它是使用 C 程序实时捕获的。我还有一个可以在本地和远程运行的 Java 前端。远程端很简单,我只需将图像压缩为 JPEG,然后通过 mini-http 服务器将它们发送到客户端,客户端将它们解压缩并显示在屏幕上。

当我们在本地运行时,我希望通过某种方式 IPC 直接连接到该内存并从 Java 访问图像。然后,使用尽可能少的 CPU 资源将它们粘贴到屏幕上。这是一个“监视”类型的系统,所以我可以同时运行 8-16 个摄像机源。

问题

将图像数据(YUV420P)从 v4l2 mmap 缓冲区移动到我的 Java 应用程序以在屏幕上显示的最有效方法是什么?如果有可用的,请显示代码或指向一些 api/specs。

回答

考虑到时间,我决定只使用普通的套接字并以 RGB 格式发送数据。当 Java 客户端在同一台机器上运行时,我能够显着提高性能。如果客户端远程运行,我仍然会通过网络发送 JPEG。接下来,我需要找到一个优化的 JPEG 解码器。

顺便说一句,这不是 2 个客户端,只是我的 CameraStream 小部件读取并解析这两种类型。

4

4 回答 4

2

Unless you use a Socket, you're going to have to use JNI to hook into a more primitive IPC mechanism.

Given that you've got a memory buffer containing the video data, you may be able to use the "shared memory" APIs to get access to that memory from within your JVM. Have a look at the man page for shmat.

You'll also need some sort of signal to tell the Java client that new video data is available.

于 2008-11-10T16:54:05.213 回答
1

您可能想考虑让“远程”界面在这两种情况下都可以接受。

维护双前端(在这种情况下,还有一些后端)只会意味着两倍的维护和两倍的(潜在)错误。

于 2008-11-10T18:34:38.943 回答
1

您可以尝试JNA(Java Native Access),而不是使用 JNI 。通过使用它,您可以直接从 Java 调用 C API,而无需编写 JNI 代码。请考虑准备小 DLL,它定义了所有必需的方法,例如打开、关闭网络摄像头设备并将图像获取为字节数组。然后使用JNAreator从这个 DLL 中准备 Java 类。它工作得很好。几年后,当我发现这个项目时,我再次开始使用本机代码。

您还可以考虑使用BridJ,它是本机代码的其他 Java API。它也和 JNA 一样透明,但速度更快,而且您也不需要使用 JNI。

于 2012-12-05T00:48:32.087 回答
0

您可以考虑使用 JNI 来公开本机内存。请参阅有关直接字节缓冲区的 JNI API。

一旦您在 Java 中像这样公开您的本机内存,将字节从 DirectByteBuffer 复制到 Java byte[] 数组中,它应该比您的套接字方法快得多。

于 2009-12-11T23:10:33.343 回答