Skip to content

Commit 5ff7c3c

Browse files
committed
Use Kernel Streaming instead of Direct Show source
1 parent b6e9044 commit 5ff7c3c

File tree

2 files changed

+54
-41
lines changed

2 files changed

+54
-41
lines changed

webcam-capture-drivers/driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDevice.java

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ public class GStreamerDevice implements WebcamDevice, RGBDataSink.Listener, Webc
5454
/**
5555
* Device name, immutable. Used only on Windows platform.
5656
*/
57-
private final String name;
57+
private final int deviceIndex;
5858
/**
5959
* Device name, immutable. Used only on Linux platform.
6060
*/
61-
private final File vfile;
61+
private final File videoFile;
6262

6363
private final GStreamerDriver driver;
6464

@@ -67,7 +67,7 @@ public class GStreamerDevice implements WebcamDevice, RGBDataSink.Listener, Webc
6767
private Pipeline pipe = null;
6868
private Element source = null;
6969
private Element filter = null;
70-
private Element jpegpar = null;
70+
private Element jpegparse = null;
7171
private Element jpegdec = null;
7272
private Element[] elements = null;
7373
private RGBDataSink sink = null;
@@ -95,16 +95,16 @@ public class GStreamerDevice implements WebcamDevice, RGBDataSink.Listener, Webc
9595
*
9696
* @param name the name of webcam device
9797
*/
98-
protected GStreamerDevice(GStreamerDriver driver, String name) {
98+
protected GStreamerDevice(GStreamerDriver driver, int deviceIndex) {
9999
this.driver = driver;
100-
this.name = name;
101-
this.vfile = null;
100+
this.deviceIndex = deviceIndex;
101+
this.videoFile = null;
102102
}
103103

104-
protected GStreamerDevice(GStreamerDriver driver, File vfile) {
104+
protected GStreamerDevice(GStreamerDriver driver, File videoFile) {
105105
this.driver = driver;
106-
this.name = null;
107-
this.vfile = vfile;
106+
this.deviceIndex = -1;
107+
this.videoFile = videoFile;
108108
}
109109

110110
/**
@@ -118,35 +118,30 @@ private synchronized void init() {
118118

119119
LOG.debug("GStreamer webcam device initialization");
120120

121-
pipe = new Pipeline(name);
121+
pipe = new Pipeline(getName());
122+
source = ElementFactory.make(GStreamerDriver.getSourceBySystem(), "source");
122123

123124
if (Platform.isWindows()) {
124-
source = ElementFactory.make("dshowvideosrc", "dshowvideosrc");
125-
source.set("device-name", name);
125+
source.set("device-index", deviceIndex);
126126
} else if (Platform.isLinux()) {
127-
source = ElementFactory.make("v4l2src", "v4l2src");
128-
source.set("device", vfile.getAbsolutePath());
127+
source.set("device", videoFile.getAbsolutePath());
128+
} else if (Platform.isMacOSX()) {
129+
throw new IllegalStateException("not yet implemented");
129130
}
130131

131-
sink = new RGBDataSink(name, this);
132+
sink = new RGBDataSink(getName(), this);
132133
sink.setPassDirectBuffer(true);
133134
sink.getSinkElement().setMaximumLateness(LATENESS, TimeUnit.MILLISECONDS);
134135
sink.getSinkElement().setQOSEnabled(true);
135136

136137
filter = ElementFactory.make("capsfilter", "capsfilter");
137138

138-
jpegpar = ElementFactory.make("jpegparse", "jpegparse");
139+
jpegparse = ElementFactory.make("jpegparse", "jpegparse");
139140
jpegdec = ElementFactory.make("jpegdec", "jpegdec");
140141

141-
// if (Platform.isLinux()) {
142142
pipelineReady();
143-
// }
144-
145143
resolutions = parseResolutions(source.getPads().get(0));
146-
147-
// if (Platform.isLinux()) {
148144
pipelineStop();
149-
// }
150145
}
151146

152147
/**
@@ -233,9 +228,9 @@ private static Dimension capStructToResolution(Structure structure) {
233228
@Override
234229
public String getName() {
235230
if (Platform.isWindows()) {
236-
return name;
231+
return Integer.toString(deviceIndex);
237232
} else if (Platform.isLinux()) {
238-
return vfile.getAbsolutePath();
233+
return videoFile.getAbsolutePath();
239234
} else {
240235
throw new RuntimeException("Platform not supported by GStreamer capture driver");
241236
}
@@ -311,7 +306,7 @@ private void pipelineElementsReset() {
311306
private Element[] pipelineElementsPrepare() {
312307
if (elements == null) {
313308
if (FORMAT_MJPEG.equals(format)) {
314-
elements = new Element[] { source, filter, jpegpar, jpegdec, sink };
309+
elements = new Element[] { source, filter, jpegparse, jpegdec, sink };
315310
} else {
316311
elements = new Element[] { source, filter, sink };
317312
}
@@ -376,7 +371,7 @@ public void dispose() {
376371

377372
source.dispose();
378373
filter.dispose();
379-
jpegpar.dispose();
374+
jpegparse.dispose();
380375
jpegdec.dispose();
381376
caps.dispose();
382377
sink.dispose();

webcam-capture-drivers/driver-gstreamer/src/main/java/com/github/sarxos/webcam/ds/gstreamer/GStreamerDriver.java

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
import org.gstreamer.Element;
1010
import org.gstreamer.ElementFactory;
1111
import org.gstreamer.Gst;
12-
import org.gstreamer.interfaces.PropertyProbe;
12+
import org.gstreamer.State;
13+
import org.gstreamer.StateChangeReturn;
1314
import org.slf4j.Logger;
1415
import org.slf4j.LoggerFactory;
1516

@@ -104,6 +105,10 @@ private static final void init() {
104105
public static final String FORMAT_YUV = "video/x-raw-yuv";
105106
public static final String FORMAT_MJPEG = "image/jpeg";
106107

108+
protected static final String SRC_WINDOWS_KERNEL_STREAMING = "ksvideosrc";
109+
protected static final String SRC_VIDEO_FOR_LINUX_2 = "v4l2src";
110+
protected static final String SRC_QUICKTIME_KIT = "qtkitvideosrc";
111+
107112
private List<String> preferredFormats = new ArrayList<>(Arrays.asList(FORMAT_RGB, FORMAT_YUV, FORMAT_MJPEG));
108113

109114
/**
@@ -121,28 +126,41 @@ public List<String> getPreferredFormats() {
121126
return preferredFormats;
122127
}
123128

124-
@Override
125-
public List<WebcamDevice> getDevices() {
126-
127-
List<WebcamDevice> devices = new ArrayList<WebcamDevice>();
128-
129-
String srcname = null;
129+
protected static String getSourceBySystem() {
130130
if (Platform.isWindows()) {
131-
srcname = "dshowvideosrc";
131+
return SRC_WINDOWS_KERNEL_STREAMING;
132132
} else if (Platform.isLinux()) {
133-
srcname = "v4l2src";
133+
return SRC_VIDEO_FOR_LINUX_2;
134134
} else if (Platform.isMac()) {
135-
srcname = "qtkitvideosrc";
135+
return SRC_QUICKTIME_KIT;
136136
}
137+
throw new IllegalStateException("Unsupported operating system");
138+
}
139+
140+
@Override
141+
public List<WebcamDevice> getDevices() {
142+
143+
List<WebcamDevice> devices = new ArrayList<WebcamDevice>();
137144

138-
final Element src = ElementFactory.make(srcname, "source");
145+
final String srcName = getSourceBySystem();
146+
final Element src = ElementFactory.make(srcName, srcName);
139147

140148
try {
141149
if (Platform.isWindows()) {
142-
PropertyProbe probe = PropertyProbe.wrap(src);
143-
for (Object name : probe.getValues("device-name")) {
144-
devices.add(new GStreamerDevice(this, name.toString()));
145-
}
150+
151+
src.setState(State.NULL);
152+
153+
int m = 50;
154+
int i = 0;
155+
do {
156+
src.set("device-index", i);
157+
if (src.setState(State.READY) == StateChangeReturn.SUCCESS) {
158+
devices.add(new GStreamerDevice(this, i));
159+
} else {
160+
break;
161+
}
162+
} while (i < m);
163+
146164
} else if (Platform.isLinux()) {
147165
for (File vfile : NixVideoDevUtils.getVideoFiles()) {
148166
devices.add(new GStreamerDevice(this, vfile));

0 commit comments

Comments
 (0)