package com.github.sarxos.webcam.ds.gst1.impl;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.freedesktop.gstreamer.Caps;
import org.freedesktop.gstreamer.Element;
import org.freedesktop.gstreamer.ElementFactory;
import org.freedesktop.gstreamer.State;
import org.freedesktop.gstreamer.StateChangeReturn;
import org.freedesktop.gstreamer.Structure;
import com.github.sarxos.webcam.WebcamException;
public class GsUtils {
public static Element getCompatibleSource(String name) {
final Element source = ElementFactory.make(getCompatibleSourceFactory(), name + "-source");
source.set(getCompatibleSourceFactory(), name);
return source;
}
public static String getCompatibleSourceFactory() {
switch (GsPlatform.getOs()) {
case LINUX:
return "v4l2src";
case WINDOWS:
return "ksvideosrc";
case MACOS:
return "qtkitvideosrc";
default:
throw new WebcamException("This operating system is not supported");
}
}
public static String getCompatibleSourceProperty() {
switch (GsPlatform.getOs()) {
case LINUX:
return "device";
case WINDOWS:
case MACOS:
return "device-index";
default:
throw new WebcamException("This operating system is not supported");
}
}
public static Dimension capsStructureToResolution(Structure structure) {
int w = -1;
int h = -1;
if (GsPlatform.isWindows()) {
w = structure.getRange("width").getMinInt();
h = structure.getRange("height").getMinInt();
} else if (GsPlatform.isLinux()) {
w = structure.getInteger("width");
h = structure.getInteger("height");
}
if (w > 0 && h > 0) {
return new Dimension(w, h);
} else {
return null;
}
}
public static Dimension[] getResolutionsFromCaps(Caps caps, String format) {
final Map<String, Dimension> map = new LinkedHashMap<>();
for (int i = 0; i < caps.size(); i++) {
final Structure structure = caps.getStructure(i);
final String f = structure.getString("format");
if (!Objects.equals(f, format)) {
continue;
}
final Dimension resolution = capsStructureToResolution(structure);
if (resolution != null) {
map.put(resolution.width + "x" + resolution.height, resolution);
}
}
return new ArrayList<Dimension>(map.values()).toArray(new Dimension[0]);
}
public static void dispose(Element element) {
if (element != null) {
element.dispose();
}
}
private String getCompatibleSourceIdentifier(int id) {
switch (GsPlatform.getOs()) {
case LINUX:
return "/dev/video" + id;
case WINDOWS:
case MACOS:
return Integer.toString(id);
default:
throw new WebcamException("This operating system is not supported");
}
}
public List<String> getVideoIdentifiers() {
final List<String> ids = new ArrayList<>();
for (int i = 0; i < 50; i++) {
final String id = getCompatibleSourceIdentifier(i);
final String property = getCompatibleSourceProperty();
final Element source = getCompatibleSource(id);
source.set(property, id);
source.setState(State.NULL);
try {
if (source.setState(State.READY) != StateChangeReturn.FAILURE) {
ids.add(id);
}
} finally {
source.setState(State.NULL);
source.dispose();
}
}
return ids;
}
}