Skip to content

Commit

Permalink
Non-blocking image access
Browse files Browse the repository at this point in the history
  • Loading branch information
sarxos committed Feb 24, 2013
1 parent a314254 commit 1edd3f9
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 34 deletions.
2 changes: 1 addition & 1 deletion webcam-capture-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<module>webcam-capture-painter</module>
<module>webcam-capture-qrcode</module>
<module>webcam-capture-manycams</module>
<module>webcam-capture-record-video</module>
<module>webcam-capture-video-recording</module>
</modules>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
<version>0.3.10-SNAPSHOT</version>
</parent>

<artifactId>webcam-capture-example-record-video</artifactId>
<artifactId>webcam-capture-example-video-recordig</artifactId>
<packaging>jar</packaging>

<name>Webcam Capture - Record Video Example</name>
<description>Example how to record video from your Webcam using Xuggler (video only, no audio)</description>
<name>Webcam Capture - Video Recording Example</name>
<description>Example how to record h264 video from your webcam device (without audio track) using awesome Xuggler library</description>

<repositories>
<repository>
Expand Down
84 changes: 54 additions & 30 deletions webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,6 @@ public class Webcam {

private static final List<WebcamDiscoveryListener> DISCOVERY_LISTENERS = Collections.synchronizedList(new ArrayList<WebcamDiscoveryListener>());

/**
* Shutdown hook to be executed when JVM exits gracefully.
*
* @author Bartosz Firyn (sarxos)
*/
private static final class ShutdownHook extends Thread {

private static int number = 0;

/**
* Webcam instance to be disposed / closed.
*/
private Webcam webcam = null;

public ShutdownHook(Webcam webcam) {
super("shutdown-hook-" + (++number));
this.webcam = webcam;
}

@Override
public void run() {
LOG.info("Automatic {} deallocation", webcam.getName());
webcam.dispose();
}
}

/**
* Webcam driver (LtiCivil, JMF, FMJ, JQT, OpenCV, VLCj, etc).
*/
Expand All @@ -95,6 +69,9 @@ public void run() {
*/
private static boolean deallocOnTermSignal = false;

/**
* Is auto-open feature enabled?
*/
private static boolean autoOpen = false;

/**
Expand All @@ -110,7 +87,7 @@ public void run() {
/**
* Shutdown hook.
*/
private ShutdownHook hook = null;
private WebcamShutdownHook hook = null;

/**
* Underlying webcam device.
Expand All @@ -127,11 +104,16 @@ public void run() {
*/
private AtomicBoolean disposed = new AtomicBoolean(false);

/**
* Is non-blocking (asynchronous) access enabled?
*/
private AtomicBoolean asynchronous = new AtomicBoolean(false);

/**
* Webcam class.
*
* @param device - device to be used as webcam
* @throws IllegalArgumentException when argument is null
* @throws IllegalArgumentException when device argument is null
*/
protected Webcam(WebcamDevice device) {
if (device == null) {
Expand All @@ -141,9 +123,41 @@ protected Webcam(WebcamDevice device) {
}

/**
* Open the webcam.
* Open the webcam in blocking (synchronous) mode.
*
* @see #open(boolean)
*/
public void open() {
open(false);
}

/**
* Open the webcam in either blocking (synchronous) or non-blocking
* (asynchronous) mode.The difference between those two modes lies in the
* image acquisition mechanism.<br>
* <br>
* In blocking mode, when user calls {@link #getImage()} method, device is
* being queried for new image buffer and user have to wait for it to be
* available.<br>
* <br>
* In non-blocking mode, there is a special thread running in the background
* which constantly fetch new images and cache them internally for further
* use. This cached instance is returned every time when user request new
* image. Because of that it can be used when timeing is very important,
* because all users calls for new image do not have to wait on device
* response. By using this mode user should be aware of the fact that in
* some cases, when two consecutive calls to get new image are executed more
* often than webcam device can serve them, the same image instance will be
* returned. User should use {@link #isImageNew()} method to distinguish if
* returned image is not the same as the previous one.
*
* @param asynchronous true for non-blocking mode, false for blocking
*/
public void open(boolean async) {

if (asynchronous.compareAndSet(false, true)) {
// TODO: start async thread
}

if (open.compareAndSet(false, true)) {

Expand All @@ -154,7 +168,7 @@ public void open() {

// install shutdown hook

Runtime.getRuntime().addShutdownHook(hook = new ShutdownHook(this));
Runtime.getRuntime().addShutdownHook(hook = new WebcamShutdownHook(this));

// notify listeners

Expand Down Expand Up @@ -396,6 +410,16 @@ private boolean isReady() {
return true;
}

public boolean isImageNew() {
if (!asynchronous.get()) {
// TODO: for dshow this is not true, need to add special check
return true;
} else {
// TODO: implement
return false;
}
}

/**
* Get list of webcams to use. This method will wait predefined time
* interval for webcam devices to be discovered. By default this time is set
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.github.sarxos.webcam;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
* Shutdown hook to be executed when JVM exits gracefully. This class intention
* is to be used internally only.
*
* @author Bartosz Firyn (sarxos)
*/
public final class WebcamShutdownHook extends Thread {

/**
* Logger.
*/
private static final Logger LOG = LoggerFactory.getLogger(WebcamShutdownHook.class);

/**
* Number of shutdown hook instance.
*/
private static int number = 0;

/**
* Webcam instance to be disposed / closed.
*/
private Webcam webcam = null;

/**
* Create new shutdown hook instance.
*
* @param webcam the webcam for which hook is intended
*/
protected WebcamShutdownHook(Webcam webcam) {
super("shutdown-hook-" + (++number));
this.webcam = webcam;
}

@Override
public void run() {
LOG.info("Automatic {} deallocation", webcam.getName());
webcam.dispose();
}
}

0 comments on commit 1edd3f9

Please sign in to comment.