sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.26k stars 1.11k forks source link

Include MJPEG decoding in the standard distribution and make it choosable #145

Open thhart opened 10 years ago

thhart commented 10 years ago

For a Logitech C910 webcam the MJPEG stream is much faster than any other encoding: http://wiki.oz9aec.net/index.php/Logitech_HD_Pro_Webcam_C910. This is especially noticeable in higher resolutions. Right now it is transparent for the user which image encoding is chosen for the transport which is not optimal.

sarxos commented 10 years ago

Hi,

Thank you for the report. I have a good and bad news. Let's start from the bad ones.

Please note that such feature is impossible to be implemented in some capture drivers (due to the native API limitations). These are:

I'm not sure about this one (will need to investigate):

And now the good news. This feature can be easily implemented in these drivers:

Due to above, such feature will not be generic for all the drivers, and as such will have to be implemented on the WebcamDevice interface level only. The Webcam class API will remain untouched.

AmnonOwed commented 7 years ago

:+1: Just wanted to say +1, would love to see this feature implemented. I'm using a Logitech C922 webcam on Windows 8 (64 bit) and seeing the same performance issues. The hardware is capable of 30/60 fps at high resolutions, but only with MJPEG. Would be great if this was supported by the webcam-capture library.

I'm seeing some recent GStreamer 1.x commits in this repo. Does this mean this feature is coming soon? :smile:

lessthanoptimal commented 6 years ago

I'm running into performance issuing using webcam-capture and I suspect that this is the root cause. As of now for all webcams (various Logitech and built in) on all computers I have (Linux and Windows) any resolution above 640x480 is a slide show. I've experimented with JavaCV which was using a wrapper around V4L2 and it says the format was MJPEG. With JavaCV I was able to get the expected FPS.

sarxos commented 6 years ago

Hi @lessthanoptimal,

I added MPJEG support in GStreamer 1.x driver. It's in a development state, not yet released and it was tested only on Linux, but you can fork the code and play with it as you want. Please also note that API may change over time before I release this driver as stable.

I'm not sure if it will satisfy your needs because what I observed on my laptop (Ubuntu Linux) is that MJPEG with GStreamer driver is 50% slower than RGB (with RGB I'm getting constant 30 FPS, but with MJPEG I'm getting only 15 FPS on HD720p). I cannot verify if this is caused by the fact that I'm either doing something wrong in the code, or by the fact I'm on Linux, or by some GStreamer-specific problem. I personally suspect some problem in the code because 15 FPS is pretty stable and strangely close to the second framerate of MJPEG on my laptop (first is 30/1, second is 15/1). I invite all of you to play with the code. Maybe you can come up with something.

Example (you need to have newest code from master branch and GStreamer 1.x installed for this to work):

import static com.github.sarxos.webcam.ds.gstreamer.GStreamerDriver.FORMAT_MJPEG;
import static com.github.sarxos.webcam.ds.gstreamer.GStreamerDriver.FORMAT_RGB;
import static com.github.sarxos.webcam.ds.gstreamer.GStreamerDriver.FORMAT_YUV;

import java.util.Arrays;

import javax.swing.JFrame;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamPanel;
import com.github.sarxos.webcam.ds.gstreamer.GStreamerDriver;

public class GStreamerDriverMjpegExample {

    static {
        Webcam.setDriver(new GStreamerDriver(Arrays.asList(FORMAT_MJPEG, FORMAT_RGB, FORMAT_YUV)));
    }

    public static void main(String[] args) {

        WebcamPanel panel = new WebcamPanel(Webcam.getWebcams().get(0));
        panel.setFPSDisplayed(true);

        JFrame frame = new JFrame("GStreamer Webcam Capture Driver Demo");
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}