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 9607bc37..379860de 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 @@ -1,5 +1,7 @@ package com.github.sarxos.webcam; +import static com.github.sarxos.webcam.WebcamExceptionHandler.handle; + import java.awt.image.BufferedImage; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionException; @@ -17,47 +19,44 @@ /** - * The goal of webcam updater class is to update image in parallel, so all calls - * to fetch image invoked on webcam instance will be non-blocking (will return - * immediately). + * The goal of webcam updater class is to update image in parallel, so all calls to fetch image + * invoked on webcam instance will be non-blocking (will return immediately). * * @author Bartosz Firyn (sarxos) */ public class WebcamUpdater implements Runnable { /** - * Implementation of this interface is responsible for calculating the delay - * between 2 image fetching, when the non-blocking (asynchronous) access to the - * webcam is enabled. + * Implementation of this interface is responsible for calculating the delay between 2 image + * fetching, when the non-blocking (asynchronous) access to the webcam is enabled. */ public static interface DelayCalculator { /** - * Calculates delay before the next image will be fetched from the - * webcam. - * Must return number greater or equal 0. + * Calculates delay before the next image will be fetched from the webcam. Must return + * number greater or equal 0. * * @param snapshotDuration - duration of taking the last image - * @param deviceFps - current FPS obtained from the device, or -1 if the - * driver doesn't support it + * @param deviceFps - current FPS obtained from the device, or -1 if the driver doesn't + * support it * @return interval (in millis) */ long calculateDelay(long snapshotDuration, double deviceFps); } /** - * Default impl of DelayCalculator, based on TARGET_FPS. Returns 0 delay for - * snapshotDuration > 20 millis. + * Default impl of DelayCalculator, based on TARGET_FPS. Returns 0 delay for snapshotDuration + * > 20 millis. */ public static class DefaultDelayCalculator implements DelayCalculator { @Override public long calculateDelay(long snapshotDuration, double deviceFps) { - // Calculate delay required to achieve target FPS. - // In some cases it can be less than 0 + // Calculate delay required to achieve target FPS. + // In some cases it can be less than 0 // because camera is not able to serve images as fast as - // we would like to. In such case just run with no delay, - // so maximum FPS will be the one supported + // we would like to. In such case just run with no delay, + // so maximum FPS will be the one supported // by camera device in the moment. long delay = Math.max((1000 / TARGET_FPS) - snapshotDuration, 0); @@ -127,7 +126,7 @@ public Thread newThread(Runnable r) { * DelayCalculator implementation. */ private final DelayCalculator delayCalculator; - + /** * Construct new webcam updater using DefaultDelayCalculator. * @@ -201,9 +200,8 @@ public void run() { try { tick(); } catch (Throwable t) { - WebcamExceptionHandler.handle(t); + handle(t); } - } private void tick() { @@ -212,9 +210,6 @@ private void tick() { return; } - long t1 = 0; - long t2 = 0; - // Calculate time required to fetch 1 picture. WebcamDriver driver = Webcam.getDriver(); @@ -223,23 +218,25 @@ private void tick() { assert driver != null; assert device != null; - BufferedImage img = null; - - t1 = System.currentTimeMillis(); - img = webcam.transform(new WebcamGetImageTask(driver, device).getImage()); - t2 = System.currentTimeMillis(); - - image.set(img); - imageNew = true; + boolean imageOk = false; + long t1 = System.currentTimeMillis(); + try { + image.set(webcam.transform(new WebcamGetImageTask(driver, device).getImage())); + imageNew = true; + imageOk = true; + } catch (WebcamException e) { + handle(e); + } + long t2 = System.currentTimeMillis(); double deviceFps = -1; if (device instanceof WebcamDevice.FPSSource) { deviceFps = ((WebcamDevice.FPSSource) device).getFPS(); } - long duration = t2 - t1; + long duration = t2 - t1; long delay = delayCalculator.calculateDelay(duration, deviceFps); - + long delta = duration + 1; // +1 to avoid division by zero if (deviceFps >= 0) { fps = deviceFps; @@ -259,16 +256,17 @@ private void tick() { // notify webcam listeners about the new image available - webcam.notifyWebcamImageAcquired(image.get()); + if (imageOk) { + webcam.notifyWebcamImageAcquired(image.get()); + } } /** - * Return currently available image. This method will return immediately - * while it was been called after camera has been open. In case when there - * are parallel threads running and there is a possibility to call this - * method in the opening time, or before camera has been open at all, this - * method will block until webcam return first image. Maximum blocking time - * will be 10 seconds, after this time method will return null. + * Return currently available image. This method will return immediately while it was been + * called after camera has been open. In case when there are parallel threads running and there + * is a possibility to call this method in the opening time, or before camera has been open at + * all, this method will block until webcam return first image. Maximum blocking time will be 10 + * seconds, after this time method will return null. * * @return Image stored in cache */ @@ -305,8 +303,8 @@ protected boolean isImageNew() { } /** - * Return current FPS number. It is calculated in real-time on the base of - * how often camera serve new image. + * Return current FPS number. It is calculated in real-time on the base of how often camera + * serve new image. * * @return FPS number */