Skip to content

Getting Started

mailmindlin edited this page Jul 31, 2017 · 6 revisions

Requirements

When you start this tutorial, it is assumed that you have already completed Installation.

Initializing the Video Device

All interaction with the webcam or other video source is done through the VideoDevice object. To connect to a camera, type

VideoDevice device = new VideoDevice("/dev/video0");

If your device is not at /dev/video0, replace it with the path to the camera.

From the VideoDevice, you can:

  • detect the supported resolutions and framerates with a DeviceInfo object
  • access its controls with a ControlList
  • capture video with a FrameGrabber
  • control whatever tuners the device may have with a TunerList

Closing the Camera

After opening a VideoDevice, you must call device.release() on it, before terminating your program

Gathering Resolution & Framerate Information

Now that you have your VideoDevice, it's time to figure out what resolutions are supported, and at what framerates. To do this, you must first get a DeviceInfo object:

DeviceInfo info = device.getDeviceInfo();

From the DeviceInfo object, you can get many different attributes about the device, but first, we should to find out what formats are supported by the device:

ImageFormatList formats = info.getFormatList();

A VideoDevice has two types of formats:

  • Native formats
    • No guarantees as to whether your preferred format is available on any given VideoDevice
    • Faster to read, as no conversion takes place
    • Usually YUYV or MJPEG
  • Converted formats
    • These are a bit slower, because conversion has to happen (but not by much)
    • Doesn't depend on hardware capabilities (although can be accelerated in some cases)
    • More format options
      • Including MJPEG, RGB, YUV, BGR, and YVU

To print out all the native formats:

for (ImageFormat format : formats.getNativeFormats()) {
	System.out.println("Native format: " + format);
	
	ResolutionInfo resolutions = format.getResolutionInfo();
	for (DiscreteResolution resolution : resolutions.getDiscreteResolutions()) {
		System.out.println("Resolution available: " + resolution.getWidth() + "x" + resolution.getHeight());
		
		FrameInterval intervals = resolution.getInterval();
		for (DiscreteInterval interval : intervals.getDiscreteIntervals()) {
			float fps = ((float) interval.getDenom()) / ((float) interval.getNum());
			System.out.println("-> " + fps + " FPS");
		}
	}
}

Because that was a lot, let's go through it:

First, we loop through the available native formats, and print them. Note that these aren't the only formats that you can use (far from it!), but they are the ones that the video device supports without internal conversion.

for (ImageFormat format : formats.getNativeFormats())
	System.out.println("Native format: " + format);

Now, we loop through all the available resolutions (for the format), and print them as WIDTHxHEIGHT.

ResolutionInfo resolutions = format.getResolutionInfo();
for (DiscreteResolution resolution : resolutions.getDiscreteResolutions()) {
	System.out.println("Resolution available: " + resolution.getWidth() + "x" + resolution.getHeight());

We end with going through the frame intervals for each resolution. Each discrete interval is represented as a fraction of a second, so an interval for 1 frame per 40ms would be 1/25. To calculate the FPS, you do the inverse of the interval, so 25/1 = 25 FPS.

		FrameInterval intervals = resolution.getInterval();
		for (DiscreteInterval interval : intervals.getDiscreteIntervals()) {
			float fps = ((float) interval.getNumerator()) / ((float) interval.getDenominator());
			System.out.println("-> " + fps + " FPS");

Converted formats

Because there are many formats available for conversion, looping through all of them might not be ideal in your program. To detect if a format is available, VideoDevice has a nice method, supportXXXConversion(). For example:

if (!device.supportJPEGConversion())
	throw new Exception("No JPEG conversion available!");

Grabbing Frames

Now that we know what formats, resolutions, and intervals are available, we can start streaming pictures in from the camera. We do that with a FrameGrabber; to open it, we need at least 4 arguments:

  • width: the width, in pixels to capture frames in. Setting this to V4L4JConstants.MAX_WIDTH will request the largest available resolution.
  • height: The height of the frames captured.
  • channel: the input channel, that depends on the hardware: webcams only have one (channel 0), while capture cards might have many. If you don't know what this means, you probably want to set it to 0.
  • std: the video standard. Can be one of:
    • FrameGrabber.STANDARD_WEBCAM normal webcams (probably what you want)
    • FrameGrabber.STANDARD_PAL PAL color encoding
    • FrameGrabber.STANDARD_SECAM SECAM color encoding
    • FrameGrabber.STANDARD_NTSC NTSC color encoding

Wrapping it all together, we get:

if (device.supportRGBConversion()) { //or device.support___Conversion()
	FrameGrabber grabber;
	try {
		frameGrabber = device.getRGBFrameGrabber(width, height, channel, std);
		//do stuff
	} finally {
		device.releaseFrameGrabber();
	}
}
device.release();

Note: After finishing with the FrameGrabber, you MUST call releaseFrameGrabber(), especially before calling release() on the VideoDevice, or your program will hang.

Setting capture options

Now that you have your FrameGrabber, we should tell v4l4j how to capture frames. The main thing that we want to set is the FPS to capture at. Here we're restricted to the FPS ranges that are offered by the device.

Note: The FPS that you pass to your FrameGrabber is more of an upper bound, and YMMV based on USB speed, background processing, etc.

frameGrabber.setFrameInterval(interval.getNumerator(), interval.getDenominator());

Tuners

[TODO: finish section]

Next: Using frames

Examples


After installing, you should be able to use any of the examples provided with V4L4J. To do this, run ant [example name]. Elevated privileges may be required for some of the examples.

test-fps
Test the FPS of a video device
test-gui
Open a window, and display the video stream from a camera
test-server
Open a HTTP server on port `8080`. You can connect to this in your web browser (Chrome works pretty well), and see the video and control the camera.
test-dual
Open two windows and show the video streams from two cameras at the same time
test-getsnapshot
Get snapshots from a camera
deviceinfo
Display information about a video source