001package com.github.sarxos.webcam.ds.buildin; 002 003import java.util.ArrayList; 004import java.util.Collections; 005import java.util.List; 006import java.util.concurrent.atomic.AtomicReference; 007 008import org.bridj.Pointer; 009import org.slf4j.Logger; 010import org.slf4j.LoggerFactory; 011 012import com.github.sarxos.webcam.WebcamDevice; 013import com.github.sarxos.webcam.WebcamDiscoverySupport; 014import com.github.sarxos.webcam.WebcamDriver; 015import com.github.sarxos.webcam.WebcamTask; 016import com.github.sarxos.webcam.ds.buildin.natives.Device; 017import com.github.sarxos.webcam.ds.buildin.natives.DeviceList; 018import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber; 019 020 021/** 022 * Default build-in webcam driver based on natives from OpenIMAJ framework. It 023 * can be widely used on various systems - Mac OS, Linux (x86, x64, ARM), 024 * Windows (win32, win64). 025 * 026 * @author Bartosz Firyn (SarXos) 027 */ 028public class WebcamDefaultDriver implements WebcamDriver, WebcamDiscoverySupport { 029 030 static { 031 if (!"true".equals(System.getProperty("webcam.debug"))) { 032 System.setProperty("bridj.quiet", "true"); 033 } 034 } 035 036 private static class WebcamNewGrabberTask extends WebcamTask { 037 038 private AtomicReference<OpenIMAJGrabber> grabber = new AtomicReference<OpenIMAJGrabber>(); 039 040 public WebcamNewGrabberTask(WebcamDriver driver) { 041 super(driver, null); 042 } 043 044 public OpenIMAJGrabber newGrabber() { 045 try { 046 process(); 047 } catch (InterruptedException e) { 048 LOG.error("Processor has been interrupted"); 049 return null; 050 } 051 return grabber.get(); 052 } 053 054 @Override 055 protected void handle() { 056 grabber.set(new OpenIMAJGrabber()); 057 } 058 } 059 060 private static class GetDevicesTask extends WebcamTask { 061 062 private volatile List<WebcamDevice> devices = null; 063 private volatile OpenIMAJGrabber grabber = null; 064 065 public GetDevicesTask(WebcamDriver driver) { 066 super(driver, null); 067 } 068 069 /** 070 * Return camera devices. 071 * 072 * @param grabber the native grabber to use for search 073 * @return Camera devices. 074 */ 075 public List<WebcamDevice> getDevices(OpenIMAJGrabber grabber) { 076 077 this.grabber = grabber; 078 079 try { 080 process(); 081 } catch (InterruptedException e) { 082 LOG.error("Processor has been interrupted"); 083 return Collections.emptyList(); 084 } 085 086 return devices; 087 } 088 089 @Override 090 protected void handle() { 091 092 devices = new ArrayList<WebcamDevice>(); 093 094 Pointer<DeviceList> pointer = grabber.getVideoDevices(); 095 DeviceList list = pointer.get(); 096 097 for (Device device : list.asArrayList()) { 098 devices.add(new WebcamDefaultDevice(device)); 099 } 100 } 101 } 102 103 /** 104 * Logger. 105 */ 106 private static final Logger LOG = LoggerFactory.getLogger(WebcamDefaultDriver.class); 107 108 private static OpenIMAJGrabber grabber = null; 109 110 @Override 111 public List<WebcamDevice> getDevices() { 112 113 LOG.debug("Searching devices"); 114 115 if (grabber == null) { 116 117 WebcamNewGrabberTask task = new WebcamNewGrabberTask(this); 118 grabber = task.newGrabber(); 119 120 if (grabber == null) { 121 return Collections.emptyList(); 122 } 123 } 124 125 List<WebcamDevice> devices = new GetDevicesTask(this).getDevices(grabber); 126 127 if (LOG.isDebugEnabled()) { 128 for (WebcamDevice device : devices) { 129 LOG.debug("Found device {}", device.getName()); 130 } 131 } 132 133 return devices; 134 } 135 136 @Override 137 public long getScanInterval() { 138 return 3000; 139 } 140 141 @Override 142 public boolean isScanPossible() { 143 return true; 144 } 145 146 @Override 147 public boolean isThreadSafe() { 148 return false; 149 } 150}