Most efficient way to move image from Java program to Java and display on screen?
Background
I am shooting video using the video4linux 2 specification. It is captured using a C program in real time. I also have a Java interface that can work both locally and remotely. It was easy for the remote side, I just compress the images to JPEG and send them through the mini-http server to the client, which decompresses them and displays them on the screen.
When we run locally, I would like the IPC to be able to directly connect to this memory and access the images from Java. Then, blit those to the screen using as little CPU power as possible. This is a "surveillance" type system, so I can work with 8-16 cameras simultaneously.
Question
What is the most efficient way to move image data (YUV420P) from mm4 v4l2 buffer to my Java application to display it on screen? Please show the code or point me to some api / specs if any.
Answer
For the sake of timing, I decided to just use simple sockets and send the data in RGB. I was able to dramatically improve performance when the Java client is running on the same machine. I am still sending JPEGs over the network if the client is remote. Then I need to find an optimized JPEG decoder.
By the way, these are not 2 clients, only my CameraStream widget reads and parses both types.
source to share
If you don't Socket
, you will need to use JNI to connect to the more primitive IPC mechanism.
Given that you have a memory buffer containing video data, you can use the shared memory API to access that memory from your JVM. Check out the man page shmat
.
You also need some kind of signal to tell the Java client that new video data is available.
source to share
Instead of using JNI, you can try JNA (Java Native Access). Using it, you can call the C API directly from Java without having to write JNI code. Please consider preparing a small DLL that defines all the necessary methods such as opening, closing the webcam and getting the image as a byte array. Then use JNAreator to prepare Java classes from this DLL. It works fantastic. I started playing with my own code again a few years later when I opened this project.
You can also use BridJ , which is another Java API for native code. It's also transparent like JNA, but much faster and you don't need to use JNI either.
source to share