diff --git a/pom.xml b/pom.xml
index 53b43c30..06050ad4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -313,6 +313,19 @@
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ [1.0,)
+
+ copy-dependencies
+
+
+
+
+
+
diff --git a/webcam-capture-examples/webcam-capture-executable/.classpath b/webcam-capture-examples/webcam-capture-executable/.classpath
new file mode 100644
index 00000000..c7345074
--- /dev/null
+++ b/webcam-capture-examples/webcam-capture-executable/.classpath
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/webcam-capture-examples/webcam-capture-executable/.project b/webcam-capture-examples/webcam-capture-executable/.project
new file mode 100644
index 00000000..1fb499ae
--- /dev/null
+++ b/webcam-capture-examples/webcam-capture-executable/.project
@@ -0,0 +1,23 @@
+
+
+ webcam-capture-example-executable
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/webcam-capture-examples/webcam-capture-executable/pom.xml b/webcam-capture-examples/webcam-capture-executable/pom.xml
new file mode 100644
index 00000000..d3362541
--- /dev/null
+++ b/webcam-capture-examples/webcam-capture-executable/pom.xml
@@ -0,0 +1,131 @@
+
+
+ 4.0.0
+
+
+ com.github.sarxos
+ webcam-capture-examples
+ 0.3.5
+
+
+ webcam-capture-example-executable
+ jar
+
+
+
+ com.github.sarxos
+ webcam-capture
+ ${project.version}
+
+
+ org.jclarion
+ image4j
+ 0.7
+
+
+
+
+
+
+ maven-compiler-plugin
+ 2.3.2
+
+
+ 1.6
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.5.1
+
+
+ copy-libs
+ prepare-package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/libs
+
+
+
+
+
+ com.akathist.maven.plugins.launch4j
+ launch4j-maven-plugin
+ 1.5.1
+
+
+ l4j-gui
+ package
+
+ launch4j
+
+
+ gui
+ ${project.build.directory}/capture.exe
+ ${project.build.directory}/${project.artifactId}-${project.version}.jar
+ Error
+ src/main/resources/Security-Camera.ico
+
+ com.github.sarxos.webcam.WebcamExecutableExample
+ true
+ libs
+
+
+ 1.5.0
+ 1.6.0
+
+
+ WebcamCapture
+ ${project.name}
+
+
+ 1.2.3.4
+ v1.2.3.4
+ ${project.name}
+ Bartosz Firyn
+ 1.2.3.4
+ v1.2.3.4
+ ${project.name}
+ ${project.name}
+ capture.exe
+
+
+
+
+
+
+
+
+
+ org.eclipse.m2e
+ lifecycle-mapping
+ 1.0.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ [2.5.1,)
+
+
+ copy-dependencies
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webcam-capture-examples/webcam-capture-executable/src/main/java/com/github/sarxos/webcam/WebcamExecutableExample.java b/webcam-capture-examples/webcam-capture-executable/src/main/java/com/github/sarxos/webcam/WebcamExecutableExample.java
new file mode 100644
index 00000000..4d143d43
--- /dev/null
+++ b/webcam-capture-examples/webcam-capture-executable/src/main/java/com/github/sarxos/webcam/WebcamExecutableExample.java
@@ -0,0 +1,85 @@
+package com.github.sarxos.webcam;
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+
+import net.sf.image4j.codec.ico.ICODecoder;
+
+
+public class WebcamExecutableExample extends JFrame implements ActionListener {
+
+ private static final long serialVersionUID = -1368783325310232511L;
+
+ private Executor executor = Executors.newSingleThreadExecutor();
+ private AtomicBoolean initialized = new AtomicBoolean(false);
+ private Webcam webcam = null;
+ private WebcamPanel panel = null;
+ private JButton button = null;
+
+ public WebcamExecutableExample() {
+ super();
+
+ setTitle("Webcam Executable Example");
+ setLayout(new FlowLayout(FlowLayout.CENTER));
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ webcam = Webcam.getDefault();
+ webcam.setViewSize(webcam.getViewSizes()[0]);
+
+ panel = new WebcamPanel(webcam, false);
+ panel.setPreferredSize(webcam.getViewSize());
+ panel.setOpaque(true);
+ panel.setBackground(Color.BLACK);
+
+ ImageIcon icon = null;
+ try {
+ List icons = ICODecoder.read(getClass().getResourceAsStream("/Security-Camera.ico"));
+ icon = new ImageIcon(icons.get(1));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ button = new JButton(icon);
+ button.addActionListener(this);
+ button.setFocusable(false);
+ button.setPreferredSize(webcam.getViewSize());
+
+ add(panel);
+ add(button);
+
+ pack();
+ setVisible(true);
+ }
+
+ boolean running = false;
+
+ public static void main(String[] args) throws IOException {
+ new WebcamExecutableExample();
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (initialized.compareAndSet(false, true)) {
+ executor.execute(new Runnable() {
+
+ @Override
+ public void run() {
+ panel.start();
+ }
+ });
+ }
+ }
+
+}
diff --git a/webcam-capture-examples/webcam-capture-executable/src/main/resources/Security-Camera.ico b/webcam-capture-examples/webcam-capture-executable/src/main/resources/Security-Camera.ico
new file mode 100644
index 00000000..97693ad1
Binary files /dev/null and b/webcam-capture-examples/webcam-capture-executable/src/main/resources/Security-Camera.ico differ
diff --git a/webcam-capture-examples/webcam-capture-executable/src/main/resources/Security-Camera.txt b/webcam-capture-examples/webcam-capture-executable/src/main/resources/Security-Camera.txt
new file mode 100644
index 00000000..06ede238
--- /dev/null
+++ b/webcam-capture-examples/webcam-capture-executable/src/main/resources/Security-Camera.txt
@@ -0,0 +1,6 @@
+Icon from http://www.iconarchive.com/show/vista-hardware-devices-icons-by-icons-land/Security-Camera-icon.html
+
+Artist: Icons-Land (Available for custom work)
+Iconset: Vista Hardware Devices Icons (28 icons)
+License: Free for non-commercial use.
+Commercial usage: Not allowed
diff --git a/webcam-capture-examples/webcam-capture-executable/test.png b/webcam-capture-examples/webcam-capture-executable/test.png
new file mode 100644
index 00000000..fcee4b8d
Binary files /dev/null and b/webcam-capture-examples/webcam-capture-executable/test.png differ
diff --git a/webcam-capture-pages/.classpath b/webcam-capture-pages/.classpath
index 71185966..1ae2b029 100644
--- a/webcam-capture-pages/.classpath
+++ b/webcam-capture-pages/.classpath
@@ -1,6 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/webcam-capture/src/example/resources/logback.xml b/webcam-capture/src/example/resources/logback.xml
index 0c2cb717..3811db88 100644
--- a/webcam-capture/src/example/resources/logback.xml
+++ b/webcam-capture/src/example/resources/logback.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java
index 35d2e4ad..3e955d31 100644
--- a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamPanel.java
@@ -34,6 +34,10 @@ public Repainter() {
public void run() {
super.run();
+ if (!webcam.isOpen()) {
+ webcam.open();
+ }
+
while (webcam.isOpen()) {
image = webcam.getImage();
@@ -68,8 +72,10 @@ public WebcamPanel(Webcam webcam, boolean start) {
this.webcam = webcam;
this.webcam.addWebcamListener(this);
- if (!webcam.isOpen()) {
- webcam.open();
+ if (start) {
+ if (!webcam.isOpen()) {
+ webcam.open();
+ }
}
setPreferredSize(webcam.getViewSize());
@@ -91,6 +97,9 @@ protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null) {
+ g.setColor(getForeground());
+ g.drawLine(0, 0, getWidth(), getHeight());
+ g.drawLine(0, getHeight(), getWidth(), 0);
return;
}
@@ -126,6 +135,7 @@ public void webcamClosed(WebcamEvent we) {
public void start() {
if (started.compareAndSet(false, true)) {
+ webcam.open();
repainter.start();
}
}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamStreamer.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamStreamer.java
index b1be3e1f..a4a5406b 100644
--- a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamStreamer.java
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamStreamer.java
@@ -1,8 +1,9 @@
package com.github.sarxos.webcam;
import java.awt.image.BufferedImage;
+import java.io.BufferedOutputStream;
import java.io.BufferedReader;
-import java.io.DataOutputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
@@ -22,7 +23,7 @@ public class WebcamStreamer implements ThreadFactory, WebcamListener {
private static final Logger LOG = LoggerFactory.getLogger(WebcamStreamer.class);
- private static final String BOUNDARY = "mjpeg-frame";
+ private static final String BOUNDARY = "mjpegframe";
private class Acceptor implements Runnable {
@@ -64,6 +65,8 @@ public void run() {
private class Connection implements Runnable {
+ private static final String CRLF = "\r\n";
+
private Socket socket = null;
public Connection(Socket socket) {
@@ -74,18 +77,29 @@ public Connection(Socket socket) {
public void run() {
BufferedReader br = null;
- DataOutputStream dos = null;
+ BufferedOutputStream bos = null;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- dos = new DataOutputStream(socket.getOutputStream());
+ bos = new BufferedOutputStream(socket.getOutputStream());
try {
- while (true) {
+
+ while (webcam.isOpen()) {
+
+ if (socket.isInputShutdown()) {
+ break;
+ }
+ if (socket.isClosed()) {
+ break;
+ }
String line = br.readLine();
- if (line.isEmpty()) {
+ if (line == null || line.isEmpty()) {
+ bos.write(("--" + BOUNDARY + "--" + CRLF).getBytes());
+ LOG.info("Breaking");
break;
}
@@ -94,37 +108,54 @@ public void run() {
socket.setSoTimeout(0);
socket.setKeepAlive(true);
+ getImage();
+
StringBuilder sb = new StringBuilder();
- sb.append("HTTP/1.0 200 OK\n");
- sb.append("Connection: keep-alive\n");
- sb.append("Cache-Control: no-cache\n");
- sb.append("Cache-Control: private\n");
- sb.append("Pragma: no-cache\n");
- sb.append("Content-type: multipart/x-mixed-replace; boundary=").append(BOUNDARY).append("\n\n");
+ sb.append("HTTP/1.0 200 OK").append(CRLF);
+ sb.append("Connection: keep-alive").append(CRLF);
+ sb.append("Cache-Control: no-cache").append(CRLF);
+ sb.append("Cache-Control: private").append(CRLF);
+ sb.append("Pragma: no-cache").append(CRLF);
+ sb.append("Content-type: multipart/x-mixed-replace; boundary=--").append(BOUNDARY).append(CRLF);
+ sb.append(CRLF);
- dos.writeBytes(sb.toString());
- dos.flush();
+ bos.write(sb.toString().getBytes());
do {
- sb.delete(0, sb.length());
-
- sb.append("--").append(BOUNDARY).append("\n");
- sb.append("Content-type: image/jpeg\n\n");
+ baos.reset();
- dos.writeBytes(sb.toString());
+ ImageIO.write(getImage(), "JPG", baos);
- ImageIO.write(getImage(), "JPG", dos);
+ sb.delete(0, sb.length());
+ sb.append("--").append(BOUNDARY).append(CRLF);
+ sb.append("Content-type: image/jpeg").append(CRLF);
+ sb.append("Content-Length: ").append(baos.size()).append(CRLF);
+ sb.append(CRLF);
- dos.flush();
+ bos.write(sb.toString().getBytes());
+ bos.write(baos.toByteArray());
+ bos.write(CRLF.getBytes());
+ bos.flush();
Thread.sleep(getDelay());
- } while (true);
+ } while (webcam.isOpen());
}
}
} catch (Exception e) {
- dos.writeBytes("HTTP/1.0 501 Internal Server Error\n\n\n");
+
+ String message = e.getMessage();
+ if (message != null) {
+ if (message.startsWith("Software caused connection abort")) {
+ LOG.info("User closed stream");
+ return;
+ }
+ }
+
+ LOG.error("Error", e);
+
+ bos.write("HTTP/1.0 501 Internal Server Error\r\n\r\n\r\n".getBytes());
}
} catch (IOException e) {
@@ -137,9 +168,9 @@ public void run() {
LOG.error("Cannot close buffered reader", e);
}
}
- if (dos != null) {
+ if (bos != null) {
try {
- dos.close();
+ bos.close();
} catch (IOException e) {
LOG.error("Cannot close data output stream", e);
}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDevice.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDevice.java
index acf405ae..29137735 100644
--- a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDevice.java
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDevice.java
@@ -12,20 +12,29 @@
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
-import org.bridj.Pointer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.sarxos.webcam.WebcamDevice;
import com.github.sarxos.webcam.WebcamException;
+import com.github.sarxos.webcam.ds.buildin.cgt.CloseSessionTask;
+import com.github.sarxos.webcam.ds.buildin.cgt.GetImageTask;
+import com.github.sarxos.webcam.ds.buildin.cgt.GetSizeTask;
+import com.github.sarxos.webcam.ds.buildin.cgt.NextFrameTask;
+import com.github.sarxos.webcam.ds.buildin.cgt.StartSessionTask;
import com.github.sarxos.webcam.ds.buildin.natives.Device;
-import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
public class WebcamDefaultDevice implements WebcamDevice {
private static final Logger LOG = LoggerFactory.getLogger(WebcamDefaultDevice.class);
+ private static final NextFrameTask FRAME_TASK = new NextFrameTask();
+ private static final GetImageTask IMAGE_TASK = new GetImageTask();
+ private static final StartSessionTask SESSION_TASK = new StartSessionTask();
+ private static final GetSizeTask SIZE_TASK = new GetSizeTask();
+ private static final CloseSessionTask CLOSE_TASK = new CloseSessionTask();
+
/**
* Artificial view sizes. I'm really not sure if will fit into other webcams
* but hope that OpenIMAJ can handle this.
@@ -47,7 +56,6 @@ public class WebcamDefaultDevice implements WebcamDevice {
private static final ColorSpace COLOR_SPACE = ColorSpace.getInstance(ColorSpace.CS_sRGB);
- private OpenIMAJGrabber grabber = null;
private Device device = null;
private Dimension size = null;
private ComponentSampleModel sampleModel = null;
@@ -60,7 +68,7 @@ protected WebcamDefaultDevice(Device device) {
@Override
public String getName() {
- return device.getNameStr() + " " + device.getIdentifierStr();
+ return String.format("%s %s", device.getNameStr(), device.getIdentifierStr());
}
@Override
@@ -85,14 +93,9 @@ public BufferedImage getImage() {
throw new WebcamException("Cannot get image when webcam device is not open");
}
- grabber.nextFrame();
-
- Pointer image = grabber.getImage();
- if (image == null) {
- return null;
- }
+ FRAME_TASK.nextFrame();
- byte[] bytes = image.getBytes(size.width * size.height * 3);
+ byte[] bytes = IMAGE_TASK.getImage(size);
byte[][] data = new byte[][] { bytes };
DataBufferByte buffer = new DataBufferByte(data, bytes.length, OFFSET);
@@ -105,7 +108,7 @@ public BufferedImage getImage() {
}
@Override
- public synchronized void open() {
+ public void open() {
if (open) {
return;
@@ -115,17 +118,17 @@ public synchronized void open() {
size = getSizes()[0];
}
- grabber = new OpenIMAJGrabber();
-
- boolean started = grabber.startSession(size.width, size.height, 0, Pointer.pointerTo(device));
+ boolean started = SESSION_TASK.startSession(size, device);
if (!started) {
throw new WebcamException("Cannot start video data grabber!");
}
+ Dimension size2 = SIZE_TASK.getSize();
+
int w1 = size.width;
- int w2 = grabber.getWidth();
+ int w2 = size2.width;
int h1 = size.height;
- int h2 = grabber.getHeight();
+ int h2 = size2.height;
if (w1 != w2 || h1 != h2) {
LOG.warn("Different size obtained vs requested - [" + w1 + "x" + h1 + "] vs [" + w2 + "x" + h2 + "]. Setting correct one. New size is [" + w2 + "x" + h2 + "]");
@@ -137,8 +140,8 @@ public synchronized void open() {
int i = 0;
do {
- grabber.nextFrame();
- grabber.getImage();
+ FRAME_TASK.nextFrame();
+ IMAGE_TASK.getImage(size);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
@@ -156,7 +159,7 @@ public void close() {
return;
}
- grabber.stopSession();
+ CLOSE_TASK.closeSession();
open = false;
}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDriver.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDriver.java
index acf84c1d..2dbad4ce 100644
--- a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDriver.java
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamDefaultDriver.java
@@ -8,9 +8,8 @@
import com.github.sarxos.webcam.WebcamDevice;
import com.github.sarxos.webcam.WebcamDriver;
+import com.github.sarxos.webcam.ds.buildin.cgt.GetDevicesTask;
import com.github.sarxos.webcam.ds.buildin.natives.Device;
-import com.github.sarxos.webcam.ds.buildin.natives.DeviceList;
-import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
/**
@@ -24,25 +23,20 @@ public class WebcamDefaultDriver implements WebcamDriver {
private static final Logger LOG = LoggerFactory.getLogger(WebcamDefaultDriver.class);
- private static OpenIMAJGrabber grabber = null;
+ private static final GetDevicesTask DEVICES_TASK = new GetDevicesTask();
+
private static List devices = null;
@Override
public List getDevices() {
- if (grabber == null) {
- LOG.debug("Creating grabber for driver");
- grabber = new OpenIMAJGrabber();
- }
-
if (devices == null) {
LOG.debug("Searching devices");
devices = new ArrayList();
- DeviceList list = grabber.getVideoDevices().get();
- for (Device device : list.asArrayList()) {
+ for (Device device : DEVICES_TASK.getDevices()) {
devices.add(new WebcamDefaultDevice(device));
}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamGrabberProcessor.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamGrabberProcessor.java
new file mode 100644
index 00000000..d64bcef8
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamGrabberProcessor.java
@@ -0,0 +1,71 @@
+package com.github.sarxos.webcam.ds.buildin;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import com.github.sarxos.webcam.WebcamException;
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public class WebcamGrabberProcessor implements Runnable, ThreadFactory {
+
+ private static WebcamGrabberProcessor instance = null;
+
+ private final SynchronousQueue tasks = new SynchronousQueue(true);
+ private final Executor runner = Executors.newSingleThreadExecutor(this);
+
+ private OpenIMAJGrabber grabber = null;
+
+ private WebcamGrabberProcessor() {
+ runner.execute(this);
+ }
+
+ public static WebcamGrabberProcessor getInstance() {
+ if (instance == null) {
+ instance = new WebcamGrabberProcessor();
+ }
+ return instance;
+ }
+
+ protected void process(WebcamGrabberTask task) {
+ try {
+ synchronized (task) {
+ tasks.offer(task, 30, TimeUnit.MINUTES);
+ task.wait();
+ }
+ } catch (InterruptedException e) {
+ throw new WebcamException("Offer interrupted", e);
+ }
+ }
+
+ @Override
+ public void run() {
+ initialize();
+ while (true) {
+ WebcamGrabberTask task = null;
+ try {
+ (task = tasks.take()).handle(grabber);
+ } catch (InterruptedException e) {
+ throw new WebcamException("Take interrupted", e);
+ } finally {
+ synchronized (task) {
+ task.notifyAll();
+ }
+ }
+ }
+ }
+
+ private void initialize() {
+ grabber = new OpenIMAJGrabber();
+ }
+
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, getClass().getSimpleName());
+ t.setDaemon(true);
+ return t;
+ }
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamGrabberTask.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamGrabberTask.java
new file mode 100644
index 00000000..452e511f
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/WebcamGrabberTask.java
@@ -0,0 +1,13 @@
+package com.github.sarxos.webcam.ds.buildin;
+
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public abstract class WebcamGrabberTask {
+
+ protected void process() {
+ WebcamGrabberProcessor.getInstance().process(this);
+ }
+
+ protected abstract void handle(OpenIMAJGrabber grabber);
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/CloseSessionTask.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/CloseSessionTask.java
new file mode 100644
index 00000000..881cf24f
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/CloseSessionTask.java
@@ -0,0 +1,17 @@
+package com.github.sarxos.webcam.ds.buildin.cgt;
+
+import com.github.sarxos.webcam.ds.buildin.WebcamGrabberTask;
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public class CloseSessionTask extends WebcamGrabberTask {
+
+ public void closeSession() {
+ process();
+ }
+
+ @Override
+ protected void handle(OpenIMAJGrabber grabber) {
+ grabber.stopSession();
+ }
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetDevicesTask.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetDevicesTask.java
new file mode 100644
index 00000000..342398dc
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetDevicesTask.java
@@ -0,0 +1,24 @@
+package com.github.sarxos.webcam.ds.buildin.cgt;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.github.sarxos.webcam.ds.buildin.WebcamGrabberTask;
+import com.github.sarxos.webcam.ds.buildin.natives.Device;
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public class GetDevicesTask extends WebcamGrabberTask {
+
+ private AtomicReference> devices = new AtomicReference>();
+
+ public List getDevices() {
+ process();
+ return devices.get();
+ }
+
+ @Override
+ protected void handle(OpenIMAJGrabber grabber) {
+ this.devices.set(grabber.getVideoDevices().get().asArrayList());
+ }
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetImageTask.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetImageTask.java
new file mode 100644
index 00000000..92fc6538
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetImageTask.java
@@ -0,0 +1,29 @@
+package com.github.sarxos.webcam.ds.buildin.cgt;
+
+import java.awt.Dimension;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.bridj.Pointer;
+
+import com.github.sarxos.webcam.ds.buildin.WebcamGrabberTask;
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public class GetImageTask extends WebcamGrabberTask {
+
+ private AtomicReference dimension = new AtomicReference();
+ private AtomicReference bytes = new AtomicReference();
+
+ public byte[] getImage(Dimension size) {
+ dimension.set(size);
+ process();
+ return bytes.get();
+ }
+
+ @Override
+ protected void handle(OpenIMAJGrabber grabber) {
+ Pointer image = grabber.getImage();
+ Dimension size = dimension.get();
+ bytes.set(image == null ? null : image.getBytes(size.width * size.height * 3));
+ }
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetSizeTask.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetSizeTask.java
new file mode 100644
index 00000000..899b1d16
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/GetSizeTask.java
@@ -0,0 +1,23 @@
+package com.github.sarxos.webcam.ds.buildin.cgt;
+
+import java.awt.Dimension;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.github.sarxos.webcam.ds.buildin.WebcamGrabberTask;
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public class GetSizeTask extends WebcamGrabberTask {
+
+ private AtomicReference dimension = new AtomicReference();
+
+ public Dimension getSize() {
+ process();
+ return dimension.get();
+ }
+
+ @Override
+ protected void handle(OpenIMAJGrabber grabber) {
+ dimension.set(new Dimension(grabber.getWidth(), grabber.getHeight()));
+ }
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/NextFrameTask.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/NextFrameTask.java
new file mode 100644
index 00000000..56f70a40
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/NextFrameTask.java
@@ -0,0 +1,17 @@
+package com.github.sarxos.webcam.ds.buildin.cgt;
+
+import com.github.sarxos.webcam.ds.buildin.WebcamGrabberTask;
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public class NextFrameTask extends WebcamGrabberTask {
+
+ public void nextFrame() {
+ process();
+ }
+
+ @Override
+ protected void handle(OpenIMAJGrabber grabber) {
+ grabber.nextFrame();
+ }
+}
diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/StartSessionTask.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/StartSessionTask.java
new file mode 100644
index 00000000..38e61614
--- /dev/null
+++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/ds/buildin/cgt/StartSessionTask.java
@@ -0,0 +1,29 @@
+package com.github.sarxos.webcam.ds.buildin.cgt;
+
+import java.awt.Dimension;
+
+import org.bridj.Pointer;
+
+import com.github.sarxos.webcam.ds.buildin.WebcamGrabberTask;
+import com.github.sarxos.webcam.ds.buildin.natives.Device;
+import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;
+
+
+public class StartSessionTask extends WebcamGrabberTask {
+
+ private Dimension size = null;
+ private Device device = null;
+ private volatile boolean started = false;
+
+ public boolean startSession(Dimension size, Device device) {
+ this.size = size;
+ this.device = device;
+ process();
+ return started;
+ }
+
+ @Override
+ protected void handle(OpenIMAJGrabber grabber) {
+ started = grabber.startSession(size.width, size.height, 50, Pointer.pointerTo(device));
+ }
+}