package com.github.sarxos.webcam.ds.buildin; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicReference; import org.bridj.Pointer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.sarxos.webcam.WebcamDevice; import com.github.sarxos.webcam.WebcamDiscoverySupport; import com.github.sarxos.webcam.WebcamDriver; import com.github.sarxos.webcam.WebcamTask; 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; /** * Default build-in webcam driver based on natives from OpenIMAJ framework. It can be widely used on * various systems - Mac OS, Linux (x86, x64, ARM), Windows (win32, win64). * * @author Bartosz Firyn (SarXos) */ public class WebcamDefaultDriver implements WebcamDriver, WebcamDiscoverySupport { static { if (!"true".equals(System.getProperty("webcam.debug"))) { System.setProperty("bridj.quiet", "true"); } } private static class WebcamNewGrabberTask extends WebcamTask { private AtomicReference<OpenIMAJGrabber> grabber = new AtomicReference<OpenIMAJGrabber>(); public WebcamNewGrabberTask(WebcamDriver driver) { super(driver, null); } public OpenIMAJGrabber newGrabber() { try { process(); } catch (InterruptedException e) { LOG.error("Processor has been interrupted"); return null; } return grabber.get(); } @Override protected void handle() { grabber.set(new OpenIMAJGrabber()); } } private static class GetDevicesTask extends WebcamTask { private volatile List<WebcamDevice> devices = null; private volatile OpenIMAJGrabber grabber = null; public GetDevicesTask(WebcamDriver driver) { super(driver, null); } /** * Return camera devices. * * @param grabber the native grabber to use for search * @return Camera devices. */ public List<WebcamDevice> getDevices(OpenIMAJGrabber grabber) { this.grabber = grabber; try { process(); } catch (InterruptedException e) { LOG.error("Processor has been interrupted"); return Collections.emptyList(); } return devices; } @Override protected void handle() { devices = new ArrayList<WebcamDevice>(); Pointer<DeviceList> pointer = grabber.getVideoDevices(); DeviceList list = pointer.get(); for (Device device : list.asArrayList()) { devices.add(new WebcamDefaultDevice(device)); } } } /** * Logger. */ private static final Logger LOG = LoggerFactory.getLogger(WebcamDefaultDriver.class); private static OpenIMAJGrabber grabber = null; @Override public List<WebcamDevice> getDevices() { LOG.debug("Searching devices"); if (grabber == null) { WebcamNewGrabberTask task = new WebcamNewGrabberTask(this); grabber = task.newGrabber(); if (grabber == null) { return Collections.emptyList(); } } List<WebcamDevice> devices = new GetDevicesTask(this).getDevices(grabber); if (LOG.isDebugEnabled()) { for (WebcamDevice device : devices) { LOG.debug("Found device {}", device.getName()); } } return devices; } @Override public long getScanInterval() { return DEFAULT_SCAN_INTERVAL; } @Override public boolean isScanPossible() { return true; } @Override public boolean isThreadSafe() { return false; } }