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}