diff --git a/webcam-capture-drivers/webcam-capture-driver-gstreamer/pom.xml b/webcam-capture-drivers/webcam-capture-driver-gstreamer/pom.xml
index 2ea4e7c5..0457471a 100644
--- a/webcam-capture-drivers/webcam-capture-driver-gstreamer/pom.xml
+++ b/webcam-capture-drivers/webcam-capture-driver-gstreamer/pom.xml
@@ -33,13 +33,6 @@
org.apache.maven.plugins
maven-assembly-plugin
-
- org.apache.maven.plugins
- maven-deploy-plugin
-
- true
-
-
diff --git a/webcam-capture-drivers/webcam-capture-driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDevice.java b/webcam-capture-drivers/webcam-capture-driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDevice.java
new file mode 100644
index 00000000..ae600daf
--- /dev/null
+++ b/webcam-capture-drivers/webcam-capture-driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDevice.java
@@ -0,0 +1,193 @@
+package com.github.sarxos.webcam.ds.gstreamer;
+
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.gstreamer.Caps;
+import org.gstreamer.Element;
+import org.gstreamer.ElementFactory;
+import org.gstreamer.Pad;
+import org.gstreamer.Pipeline;
+import org.gstreamer.State;
+import org.gstreamer.Structure;
+import org.gstreamer.elements.RGBDataSink;
+
+import com.github.sarxos.webcam.WebcamDevice;
+import com.github.sarxos.webcam.WebcamResolution;
+
+
+public class GStreamerDevice implements WebcamDevice, RGBDataSink.Listener {
+
+ /**
+ * Limit the lateness of frames to no more than 20ms (half a frame at 25fps)
+ */
+ private static final long LATENESS = 20; // ms
+
+ private static final String FORMAT = "video/x-raw-yuv";
+
+ private final String name;
+ private final Dimension[] resolutions;
+
+ private Pipeline pipe = null;
+ private Element source = null;
+ private Element filter = null;
+ private RGBDataSink sink = null;
+ private BufferedImage image = null;
+ private Caps caps = null;
+
+ private AtomicBoolean open = new AtomicBoolean(false);
+ private AtomicBoolean disposed = new AtomicBoolean(false);
+ private Dimension resolution = WebcamResolution.VGA.getSize();
+
+ protected GStreamerDevice(String name) {
+
+ this.name = name;
+
+ pipe = new Pipeline(name);
+
+ sink = new RGBDataSink(name, this);
+ sink.setPassDirectBuffer(true);
+ sink.getSinkElement().setMaximumLateness(LATENESS, TimeUnit.MILLISECONDS);
+ sink.getSinkElement().setQOSEnabled(true);
+
+ source = ElementFactory.make("dshowvideosrc", "source");
+ source.set("device-name", name);
+
+ filter = ElementFactory.make("capsfilter", "filter");
+
+ resolutions = parseResolutions(source.getPads().get(0));
+ }
+
+ private static final Dimension[] parseResolutions(Pad pad) {
+
+ List dimensions = new ArrayList();
+
+ Caps caps = pad.getCaps();
+
+ Structure structure = null;
+ String format = null;
+
+ int n = caps.size();
+ int i = 0;
+
+ int w = -1;
+ int h = -1;
+
+ do {
+
+ structure = caps.getStructure(i++);
+ format = structure.getName();
+
+ if (format.equals(FORMAT)) {
+ w = structure.getRange("width").getMinInt();
+ h = structure.getRange("height").getMinInt();
+ dimensions.add(new Dimension(w, h));
+ }
+
+ } while (i < n);
+
+ return dimensions.toArray(new Dimension[dimensions.size()]);
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Dimension[] getResolutions() {
+ return resolutions;
+ }
+
+ @Override
+ public Dimension getResolution() {
+ return resolution;
+ }
+
+ @Override
+ public void setResolution(Dimension size) {
+ this.resolution = size;
+ }
+
+ @Override
+ public BufferedImage getImage() {
+ return image;
+ }
+
+ @Override
+ public void open() {
+
+ if (!open.compareAndSet(false, true)) {
+ return;
+ }
+
+ Dimension size = getResolution();
+
+ image = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
+ image.setAccelerationPriority(0);
+ image.flush();
+
+ if (caps != null) {
+ caps.dispose();
+ } else {
+ caps = Caps.fromString(String.format("%s,width=%d,height=%d", FORMAT, size.width, size.height));
+ }
+
+ filter.setCaps(caps);
+
+ pipe.addMany(source, filter, sink);
+ Element.linkMany(source, filter, sink);
+ pipe.setState(State.PLAYING);
+ }
+
+ @Override
+ public void close() {
+
+ if (!open.compareAndSet(true, false)) {
+ return;
+ }
+
+ pipe.setState(State.NULL);
+ Element.unlinkMany(source, filter, sink);
+ pipe.removeMany(source, filter, sink);
+ }
+
+ @Override
+ public void dispose() {
+
+ if (!disposed.compareAndSet(false, true)) {
+ return;
+ }
+
+ close();
+
+ filter.dispose();
+ source.dispose();
+ sink.dispose();
+ pipe.dispose();
+ caps.dispose();
+ }
+
+ @Override
+ public boolean isOpen() {
+ return open.get();
+ }
+
+ @Override
+ public void rgbFrame(boolean preroll, int width, int height, IntBuffer rgb) {
+
+ BufferedImage tmp = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ tmp.setAccelerationPriority(0);
+ tmp.flush();
+
+ rgb.get(((DataBufferInt) tmp.getRaster().getDataBuffer()).getData(), 0, width * height);
+
+ image = tmp;
+ }
+}
diff --git a/webcam-capture-drivers/webcam-capture-driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDriver.java b/webcam-capture-drivers/webcam-capture-driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDriver.java
index e9f72753..4b3f4cf7 100644
--- a/webcam-capture-drivers/webcam-capture-driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDriver.java
+++ b/webcam-capture-drivers/webcam-capture-driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDriver.java
@@ -1,18 +1,21 @@
package com.github.sarxos.webcam.ds.gstreamer;
+import java.util.ArrayList;
import java.util.List;
+import javax.swing.JFrame;
+
import org.gstreamer.Element;
import org.gstreamer.ElementFactory;
import org.gstreamer.Gst;
-import org.gstreamer.Pipeline;
-import org.gstreamer.State;
import org.gstreamer.interfaces.PropertyProbe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamDevice;
import com.github.sarxos.webcam.WebcamDriver;
+import com.github.sarxos.webcam.WebcamPanel;
import com.sun.jna.NativeLibrary;
@@ -20,6 +23,10 @@ public class GStreamerDriver implements WebcamDriver {
private static final Logger LOG = LoggerFactory.getLogger(GStreamerDriver.class);
+ static {
+ init();
+ }
+
private static final class GStreamerShutdownHook extends Thread {
public GStreamerShutdownHook() {
@@ -28,40 +35,33 @@ public GStreamerShutdownHook() {
@Override
public void run() {
+ LOG.debug("GStreamer deinitialization");
Gst.deinit();
}
}
- static {
+ private static final void init() {
+ LOG.debug("GStreamer initialization");
NativeLibrary.addSearchPath("gstreamer-0.10", "C:\\Program Files\\OSSBuild\\GStreamer\\v0.10.6\\bin");
Gst.init(GStreamerDriver.class.getSimpleName(), new String[0]);
Runtime.getRuntime().addShutdownHook(new GStreamerShutdownHook());
}
- private static final Pipeline pipe = new Pipeline(GStreamerDriver.class.getSimpleName());
-
@Override
public List getDevices() {
- Element dshowsrc = ElementFactory.make("dshowvideosrc", "source");
- dshowsrc.setState(State.READY);
+ List devices = new ArrayList();
+ Element dshowsrc = ElementFactory.make("dshowvideosrc", "source");
PropertyProbe probe = PropertyProbe.wrap(dshowsrc);
- for (Object device : probe.getValues("device-name")) {
- System.out.println(device);
- }
- dshowsrc.setState(State.NULL);
+ for (Object name : probe.getValues("device-name")) {
+ devices.add(new GStreamerDevice(name.toString()));
+ }
- // final Element videosrc = ElementFactory.make("videotestsrc",
- // "source");
- // final Element videofilter = ElementFactory.make("capsfilter",
- // "filter");
- // videofilter.setCaps(Caps.fromString("video/x-raw-yuv, width=720, height=576"
- // + ", bpp=32, depth=32, framerate=25/1"));
+ dshowsrc.dispose();
- // TODO Auto-generated method stub
- return null;
+ return devices;
}
@Override
@@ -70,6 +70,19 @@ public boolean isThreadSafe() {
}
public static void main(String[] args) {
- new GStreamerDriver().getDevices();
+ // WebcamDriver driver = new GStreamerDriver();
+ // for (WebcamDevice device : driver.getDevices()) {
+ // System.out.println(device.getName());
+ // for (Dimension d : device.getResolutions()) {
+ // System.out.println(d);
+ // }
+ // }
+
+ Webcam.setDriver(new GStreamerDriver());
+ JFrame frame = new JFrame();
+ frame.add(new WebcamPanel(Webcam.getWebcams().get(1)));
+ frame.pack();
+ frame.setVisible(true);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
diff --git a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/MjpegLignanoBeachExample.java b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/MjpegLignanoBeachExample.java
index 3246a4e2..477c5757 100644
--- a/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/MjpegLignanoBeachExample.java
+++ b/webcam-capture-drivers/webcam-capture-driver-ipcam/src/examples/java/MjpegLignanoBeachExample.java
@@ -4,7 +4,6 @@
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamPanel;
-import com.github.sarxos.webcam.ds.ipcam.IpCamDevice;
import com.github.sarxos.webcam.ds.ipcam.IpCamDeviceRegistry;
import com.github.sarxos.webcam.ds.ipcam.IpCamDriver;
import com.github.sarxos.webcam.ds.ipcam.IpCamMode;