001    package com.github.sarxos.webcam.ds.buildin;
002    
003    import java.util.ArrayList;
004    import java.util.Collections;
005    import java.util.List;
006    import java.util.concurrent.atomic.AtomicReference;
007    
008    import org.bridj.Pointer;
009    import org.slf4j.Logger;
010    import org.slf4j.LoggerFactory;
011    
012    import com.github.sarxos.webcam.WebcamDevice;
013    import com.github.sarxos.webcam.WebcamDiscoverySupport;
014    import com.github.sarxos.webcam.WebcamDriver;
015    import com.github.sarxos.webcam.WebcamTask;
016    import com.github.sarxos.webcam.ds.buildin.natives.Device;
017    import com.github.sarxos.webcam.ds.buildin.natives.DeviceList;
018    import 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     */
028    public 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    }