diff --git a/webcam-capture-drivers/webcam-capture-driver-v4l4j/pom.xml b/webcam-capture-drivers/webcam-capture-driver-v4l4j/pom.xml index 09781d95..08b3a75b 100644 --- a/webcam-capture-drivers/webcam-capture-driver-v4l4j/pom.xml +++ b/webcam-capture-drivers/webcam-capture-driver-v4l4j/pom.xml @@ -41,13 +41,6 @@ org.apache.maven.plugins maven-assembly-plugin - - org.apache.maven.plugins - maven-deploy-plugin - - true - - diff --git a/webcam-capture-examples/webcam-capture-applet/.classpath b/webcam-capture-examples/webcam-capture-applet/.classpath index 94df3fc3..b4dc627b 100644 --- a/webcam-capture-examples/webcam-capture-applet/.classpath +++ b/webcam-capture-examples/webcam-capture-applet/.classpath @@ -14,6 +14,7 @@ + diff --git a/webcam-capture-examples/webcam-capture-applet/pom.xml b/webcam-capture-examples/webcam-capture-applet/pom.xml index 6a887bf8..c5a2847f 100644 --- a/webcam-capture-examples/webcam-capture-applet/pom.xml +++ b/webcam-capture-examples/webcam-capture-applet/pom.xml @@ -23,6 +23,7 @@ + applet maven-compiler-plugin diff --git a/webcam-capture-examples/webcam-capture-applet/src/main/html/index.html b/webcam-capture-examples/webcam-capture-applet/src/main/html/index.html index d6e7f038..5d94e60b 100644 --- a/webcam-capture-examples/webcam-capture-applet/src/main/html/index.html +++ b/webcam-capture-examples/webcam-capture-applet/src/main/html/index.html @@ -4,10 +4,8 @@

This is my page, below you see an Webcam Capture applet

- + + diff --git a/webcam-capture-examples/webcam-capture-applet/src/main/java/WebcamAppletExample.java b/webcam-capture-examples/webcam-capture-applet/src/main/java/WebcamAppletExample.java index 07b1f2a6..8fda7078 100644 --- a/webcam-capture-examples/webcam-capture-applet/src/main/java/WebcamAppletExample.java +++ b/webcam-capture-examples/webcam-capture-applet/src/main/java/WebcamAppletExample.java @@ -5,14 +5,13 @@ import com.github.sarxos.webcam.Webcam; import com.github.sarxos.webcam.WebcamPanel; import com.github.sarxos.webcam.WebcamResolution; -import com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver; public class WebcamAppletExample extends JApplet { private static final long serialVersionUID = 3517366452510566924L; - private Dimension size = WebcamResolution.QQVGA.getSize(); + private Dimension size = WebcamResolution.QVGA.getSize(); private Webcam webcam = null; private WebcamPanel panel = null; @@ -28,12 +27,6 @@ public void start() { super.start(); - try { - Webcam.setDriver(new WebcamDefaultDriver()); - } catch (Exception e) { - e.printStackTrace(); - } - webcam = Webcam.getDefault(); webcam.setViewSize(size); @@ -67,23 +60,20 @@ public void start() { @Override public void destroy() { System.out.println("Destroy"); - super.destroy(); - webcam.close(); webcam.close(); + Webcam.shutdown(); + System.out.println("Destroyed"); } @Override public void stop() { System.out.println("Stop"); - super.stop(); webcam.close(); - webcam.getLock().unlock(); - panel.stop(); + System.out.println("Stopped"); } @Override public void init() { System.out.println("Init"); - super.init(); } } diff --git a/webcam-capture-examples/webcam-capture-applet/src/main/resources/logback.xml b/webcam-capture-examples/webcam-capture-applet/src/main/resources/logback.xml new file mode 100644 index 00000000..efcb9867 --- /dev/null +++ b/webcam-capture-examples/webcam-capture-applet/src/main/resources/logback.xml @@ -0,0 +1,10 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java index 280bf030..ded74344 100644 --- a/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java +++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/Webcam.java @@ -241,6 +241,8 @@ public boolean close() { if (open.compareAndSet(true, false)) { + LOG.debug("Closing webcam {}", getName()); + assert updater != null; assert lock != null; @@ -258,20 +260,15 @@ public boolean close() { throw e; } - // unlock webcam so other Java processes can start using it - - lock.unlock(); - // stop updater - - if (asynchronous) { - updater.stop(); - } + updater.stop(); // remove shutdown hook (it's not more necessary) - removeShutdownHook(); + // unlock webcam so other Java processes can start using it + lock.unlock(); + // notify listeners WebcamEvent we = new WebcamEvent(WebcamEventType.CLOSED, this); @@ -287,8 +284,10 @@ public boolean close() { } } + LOG.debug("Webcam {} has been closed", getName()); + } else { - LOG.debug("Webcam is already closed {}", getName()); + LOG.debug("Webcam {} is already closed", getName()); } return true; @@ -1086,4 +1085,17 @@ public void setImageTransformer(WebcamImageTransformer transformer) { public WebcamLock getLock() { return lock; } + + public static void shutdown() { + + // stop discovery service + WebcamDiscoveryService discovery = getDiscoveryServiceRef(); + if (discovery != null) { + discovery.stop(); + } + + // stop processor + WebcamProcessor.getInstance().shutdown(); + + } } diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamDiscoveryService.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamDiscoveryService.java index 6cd4b51a..52760cf6 100644 --- a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamDiscoveryService.java +++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamDiscoveryService.java @@ -252,9 +252,6 @@ public void run() { try { monitor.wait(support.getScanInterval()); } catch (InterruptedException e) { - if (LOG.isTraceEnabled()) { - LOG.error("Interrupted", e); - } break; } catch (Exception e) { throw new RuntimeException("Problem waiting on monitor", e); diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamProcessor.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamProcessor.java index 5af62b63..ffd69ce1 100644 --- a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamProcessor.java +++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamProcessor.java @@ -5,12 +5,18 @@ import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class WebcamProcessor { + private static final Logger LOG = LoggerFactory.getLogger(WebcamProcessor.class); + /** * Thread factory for processor. * @@ -49,7 +55,6 @@ private static final class AtomicProcessor implements Runnable { * @throws InterruptedException when thread has been interrupted */ public void process(WebcamTask task) throws InterruptedException { - inbound.put(task); Throwable t = outbound.take().getThrowable(); @@ -93,7 +98,7 @@ public void run() { /** * Execution service. */ - private static final ExecutorService runner = Executors.newSingleThreadExecutor(new ProcessorThreadFactory()); + private static ExecutorService runner = null; /** * Static processor. @@ -115,9 +120,12 @@ private WebcamProcessor() { * @throws InterruptedException when thread has been interrupted */ public void process(WebcamTask task) throws InterruptedException { + if (started.compareAndSet(false, true)) { + runner = Executors.newSingleThreadExecutor(new ProcessorThreadFactory()); runner.execute(processor); } + if (!runner.isShutdown()) { processor.process(task); } else { @@ -125,6 +133,31 @@ public void process(WebcamTask task) throws InterruptedException { } } + public void shutdown() { + if (started.compareAndSet(true, false)) { + + LOG.debug("Shutting down webcam processor"); + + runner.shutdown(); + + LOG.debug("Awaiting tasks termination"); + + while (runner.isTerminated()) { + + try { + runner.awaitTermination(100, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + return; + } + + runner.shutdownNow(); + } + + LOG.debug("All tasks has been terminated"); + } + + } + public static synchronized WebcamProcessor getInstance() { return INSTANCE; } diff --git a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java index 638726f5..f363b11e 100644 --- a/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java +++ b/webcam-capture/src/main/java/com/github/sarxos/webcam/WebcamUpdater.java @@ -6,6 +6,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -102,7 +103,7 @@ public void run() { /** * Executor service. */ - private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(THREAD_FACTORY); + private ScheduledExecutorService executor = null; /** * Executor service for image notifications. @@ -127,7 +128,7 @@ public void run() { /** * Is updater running. */ - private volatile boolean running = false; + private AtomicBoolean running = new AtomicBoolean(false); private volatile boolean imageNew = false; @@ -144,25 +145,46 @@ protected WebcamUpdater(Webcam webcam) { * Start updater. */ public void start() { - running = true; - image.set(new WebcamReadImageTask(Webcam.getDriver(), webcam.getDevice()).getImage()); - executor.execute(this); + if (running.compareAndSet(false, true)) { - LOG.debug("Webcam updater has been started"); + image.set(new WebcamReadImageTask(Webcam.getDriver(), webcam.getDevice()).getImage()); + + executor = Executors.newSingleThreadScheduledExecutor(THREAD_FACTORY); + executor.execute(this); + + LOG.debug("Webcam updater has been started"); + } else { + LOG.debug("Webcam updater is already started"); + } } /** * Stop updater. */ public void stop() { - running = false; - LOG.debug("Webcam updater has been stopped"); + if (running.compareAndSet(true, false)) { + + executor.shutdown(); + + while (!executor.isTerminated()) { + try { + executor.awaitTermination(100, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + LOG.trace(e.getMessage(), e); + return; + } + } + + LOG.debug("Webcam updater has been stopped"); + } else { + LOG.debug("Webcam updater is already stopped"); + } } @Override public void run() { - if (!running) { + if (!running.get()) { return; }