sarxos / webcam-capture

The goal of this project is to allow integrated or USB-connected webcams to be accessed directly from Java. Using provided libraries users are able to read camera images and detect motion. Main project consist of several sub projects - the root one, which contains required classes, build-in webcam driver compatible with Windows, Linux and Mac OS, which can stream images as fast as your camera can serve them (up to 50 FPS). Main project can be used standalone, but user is able to replace build-in driver with different one - such as OpenIMAJ, GStreamer, V4L4j, JMF, LTI-CIVIL, FMJ, etc.
http://webcam-capture.sarxos.pl
MIT License
2.27k stars 1.11k forks source link

Program hang on quit on Mac OS X #318

Open oleklam opened 9 years ago

oleklam commented 9 years ago

The program run and capture images properly but hang on exit and force quit is need on Mac (with Retina display) installed with OS X Yosemite (running inside eclipse).

17:46:30.145 [main] INFO com.github.sarxos.webcam.Webcam - WebcamDefaultDriver capture driver will be used
17:46:30.151 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices
17:46:30.476 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Found device FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:30.478 [main] DEBUG com.github.sarxos.webcam.Webcam - Setting new resolution 320x240
17:46:30.478 [main] WARN com.github.sarxos.webcam.Webcam - Automated deallocation on TERM signal is now enabled! Make sure to not use it in production!
17:46:30.478 [main] DEBUG com.github.sarxos.webcam.WebcamLock - Lock Webcam FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:30.488 [atomic-processor-1] INFO c.g.s.webcam.ds.cgt.WebcamOpenTask - Opening webcam FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:30.488 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Opening webcam device FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:30.488 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Webcam device 0x1470000005ac8511 starting session, size java.awt.Dimension[width=320,height=240]
17:46:30.532 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Webcam device session started
17:46:30.532 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Initialize buffer
17:46:33.481 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices
17:46:34.175 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Webcam device com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice@be4535e is now open
17:46:34.175 [main] DEBUG com.github.sarxos.webcam.Webcam - Webcam is now open FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:34.176 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Found device FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:34.219 [main] DEBUG c.github.sarxos.webcam.WebcamUpdater - Webcam updater has been started
17:46:34.225 [main] DEBUG com.github.sarxos.webcam.WebcamPanel - Starting panel rendering and trying to open attached webcam
17:46:37.181 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices
17:46:37.213 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Found device FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:40.217 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices
17:46:40.246 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Found device FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:43.247 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices
17:46:43.253 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Found device FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:45.653 [shutdown-hook-1] INFO c.g.sarxos.webcam.WebcamShutdownHook - Automatic FaceTime HD Camera (Built-in) 0x1470000005ac8511 deallocation
17:46:45.653 [shutdown-hook-1] INFO com.github.sarxos.webcam.Webcam - Disposing webcam FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:45.664 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Disposing webcam device FaceTime HD Camera (Built-in) 0x1470000005ac8511
17:46:45.664 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Closing webcam device
17:46:46.256 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices

The above is the message shown on eclipse console and hang after "Searching devices".

sarxos commented 9 years ago

Hi @oleklam,

Thank you for the report.

Can you please do the following things:

oleklam commented 9 years ago

Hi @sarxos, here is the information.

Program tested is from one of your example, as shown below:

public static void main(String[] args) throws InterruptedException {
    Webcam webcam = Webcam.getDefault();
    webcam.setViewSize(WebcamResolution.VGA.getSize());

    WebcamPanel panel = new WebcamPanel(webcam);
    panel.setFPSDisplayed(true);
    panel.setDisplayDebugInfo(true);
    panel.setImageSizeDisplayed(true);
    panel.setMirrored(true);
    JFrame window = new JFrame("Test webcam panel");
    window.add(panel);
    window.setResizable(true);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.pack();
    window.setVisible(true);
}

Log output (from Eclipse):

09:12:54.374 [main] INFO  com.github.sarxos.webcam.Webcam - WebcamDefaultDriver capture driver will be used
09:12:54.379 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices
09:12:54.714 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Found device FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:54.716 [main] DEBUG com.github.sarxos.webcam.Webcam - Setting new resolution 640x480
09:12:54.897 [main] DEBUG com.github.sarxos.webcam.WebcamPanel - Starting panel rendering and trying to open attached webcam
09:12:54.898 [main] TRACE com.github.sarxos.webcam.WebcamLock - Lock timestamp 1425597108385 now 1425597174898 for Webcam FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:54.898 [main] DEBUG com.github.sarxos.webcam.WebcamLock - Lock Webcam FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:54.908 [atomic-processor-1] INFO  c.g.s.webcam.ds.cgt.WebcamOpenTask - Opening webcam FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:54.908 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Opening webcam device FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:54.908 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Webcam device 0x1470000005ac8511 starting session, size java.awt.Dimension[width=640,height=480]
09:12:54.953 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Webcam device session started
09:12:54.955 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Initialize buffer
09:12:57.718 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices
09:12:58.615 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Webcam device com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice@6b08d7cf is now open
09:12:58.615 [main] DEBUG com.github.sarxos.webcam.Webcam - Webcam is now open FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:58.615 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.615 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Found device FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:58.616 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.621 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.664 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.692 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.749 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.753 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.753 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:58.753 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.809 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.809 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.809 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:58.840 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.841 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:58.840 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.857 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.857 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.857 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:58.896 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.896 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.896 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:58.950 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.950 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.950 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:58.959 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.959 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.959 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:58.998 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:58.998 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:58.998 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.026 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.026 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.026 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.057 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.057 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.057 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.100 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.100 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.100 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.134 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.134 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.134 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.154 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.154 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.154 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.203 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.203 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.203 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.230 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.230 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.230 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.266 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.267 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.267 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.297 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.297 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.297 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.332 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.332 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.332 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.363 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.363 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.363 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.396 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.396 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.396 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.429 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.429 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.429 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.465 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.465 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.465 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.496 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.496 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.496 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.528 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.528 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.528 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.560 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.560 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.560 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.591 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.591 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.591 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.624 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.624 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.624 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.656 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.656 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.656 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.688 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.688 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.688 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.719 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.719 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.719 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.753 [shutdown-hook-1] INFO  c.g.sarxos.webcam.WebcamShutdownHook - Automatic FaceTime HD Camera (Built-in) 0x1470000005ac8511 deallocation
09:12:59.753 [shutdown-hook-1] INFO  com.github.sarxos.webcam.Webcam - Disposing webcam FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:59.765 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam grabber get image pointer
09:12:59.765 [frames-refresher-[0x1470000005ac8511]] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Next frame
09:12:59.765 [atomic-processor-1] TRACE c.g.s.w.d.b.WebcamDefaultDevice - Webcam device get buffer, read 921600 bytes
09:12:59.765 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Disposing webcam device FaceTime HD Camera (Built-in) 0x1470000005ac8511
09:12:59.765 [atomic-processor-1] DEBUG c.g.s.w.d.b.WebcamDefaultDevice - Closing webcam device
09:13:01.616 [webcam-discovery-service] DEBUG c.g.s.w.d.b.WebcamDefaultDriver - Searching devices

Output from jstack

2015-03-06 09:46:10
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.71-b01 mixed mode):
"process reaper" daemon prio=5 tid=0x00007fcbdcaa8800 nid=0x16403 waiting on condition [0x0000000119f56000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007ab80c970> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"shutdown-hook-1" prio=5 tid=0x00007fcbdc9d2800 nid=0x16307 waiting on condition [0x0000000123de3000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000700193e58> (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:70)
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46)
    at com.github.sarxos.webcam.ds.cgt.WebcamDisposeTask.dispose(WebcamDisposeTask.java:20)
    at com.github.sarxos.webcam.Webcam.dispose(Webcam.java:426)
    at com.github.sarxos.webcam.WebcamShutdownHook.run(WebcamShutdownHook.java:44)
"Attach Listener" daemon prio=5 tid=0x00007fcbdd192800 nid=0x857f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"notificator-[FaceTime HD Camera (Built-in) 0x1470000005ac8511]" daemon prio=5 tid=0x00007fcbdc9bc000 nid=0x15113 waiting on condition [0x00000001224bb000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007000331b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"DestroyJavaVM" prio=5 tid=0x00007fcbdddc1000 nid=0x1303 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"webcam-panel-scheduled-executor-1" daemon prio=5 tid=0x00007fcbdcab5800 nid=0x13f0f waiting on condition [0x000000012080f000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000700193ce0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"frames-refresher-[0x1470000005ac8511]" daemon prio=5 tid=0x00007fcbdc139000 nid=0x13e83 waiting on condition [0x000000012070c000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000700297438> (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.put(SynchronousQueue.java:878)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:68)
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice$NextFrameTask.nextFrame(WebcamDefaultDevice.java:60)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.updateFrameBuffer(WebcamDefaultDevice.java:451)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.run(WebcamDefaultDevice.java:480)
    at java.lang.Thread.run(Thread.java:745)
"webcam-lock-[FaceTime HD Camera (Built-in) 0x1470000005ac8511]" daemon prio=5 tid=0x00007fcbdd3cc000 nid=0x12403 waiting on condition [0x000000011f9fd000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at com.github.sarxos.webcam.WebcamLock$LockUpdater.run(WebcamLock.java:60)
"AWT-EventQueue-0" prio=5 tid=0x00007fcbdc32b000 nid=0x12203 waiting on condition [0x000000011f8fa000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007001950e0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at java.awt.EventQueue.getNextEvent(EventQueue.java:543)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
"Java2D Disposer" daemon prio=5 tid=0x00007fcbdc9c1800 nid=0x11e07 in Object.wait() [0x000000011f6f4000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007001a8050> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
    - locked <0x00000007001a8050> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
    at sun.java2d.Disposer.run(Disposer.java:145)
    at java.lang.Thread.run(Thread.java:745)
"Java2D Queue Flusher" daemon prio=5 tid=0x00007fcbdc334000 nid=0x11907 in Object.wait() [0x000000011f1aa000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x000000070001e288> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
    at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:206)
    - locked <0x000000070001e288> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
"webcam-discovery-service" daemon prio=5 tid=0x00007fcbdd226800 nid=0xca0f waiting on condition [0x000000011efa4000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000700297438> (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.put(SynchronousQueue.java:878)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:68)
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver$GetDevicesTask.getDevices(WebcamDefaultDriver.java:80)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver.getDevices(WebcamDefaultDriver.java:125)
    at com.github.sarxos.webcam.WebcamDiscoveryService.scan(WebcamDiscoveryService.java:156)
    at com.github.sarxos.webcam.WebcamDiscoveryService.run(WebcamDiscoveryService.java:265)
    at java.lang.Thread.run(Thread.java:745)
"atomic-processor-1" daemon prio=5 tid=0x00007fcbdc2ff800 nid=0xcc03 runnable [0x000000011f0a7000]
   java.lang.Thread.State: RUNNABLE
    at com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber.stopSession(Native Method)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.close(WebcamDefaultDevice.java:391)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.dispose(WebcamDefaultDevice.java:403)
    at com.github.sarxos.webcam.ds.cgt.WebcamDisposeTask.handle(WebcamDisposeTask.java:25)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:81)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"AWT-Shutdown" prio=5 tid=0x00007fcbdc09a800 nid=0x6f07 in Object.wait() [0x000000011b7d2000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000700255768> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:503)
    at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:296)
    - locked <0x0000000700255768> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)
"AppKit Thread" daemon prio=5 tid=0x00007fcbdd82b000 nid=0x713 in Object.wait() [0x00007fff572b0000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000700349650> (a com.github.sarxos.webcam.WebcamShutdownHook)
    at java.lang.Thread.join(Thread.java:1281)
    - locked <0x0000000700349650> (a com.github.sarxos.webcam.WebcamShutdownHook)
    at java.lang.Thread.join(Thread.java:1355)
    at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106)
    at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46)
    at java.lang.Shutdown.runHooks(Shutdown.java:123)
    at java.lang.Shutdown.sequence(Shutdown.java:167)
    at java.lang.Shutdown.exit(Shutdown.java:212)
    - locked <0x0000000700496f38> (a java.lang.Class for java.lang.Shutdown)
    at java.lang.Runtime.exit(Runtime.java:109)
    at java.lang.System.exit(System.java:962)
    at com.apple.eawt._AppEventHandler.performQuit(_AppEventHandler.java:145)
    - locked <0x00000007002b3cd0> (a com.apple.eawt._AppEventHandler)
    at com.apple.eawt.QuitResponse.performQuit(QuitResponse.java:51)
    at com.apple.eawt._AppEventHandler$_QuitDispatcher.performDefaultAction(_AppEventHandler.java:390)
    at com.apple.eawt._AppEventHandler$_AppEventDispatcher.dispatch(_AppEventHandler.java:512)
    at com.apple.eawt._AppEventHandler.handleNativeNotification(_AppEventHandler.java:202)
"Service Thread" daemon prio=5 tid=0x00007fcbdd82f800 nid=0x4503 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007fcbdd82f000 nid=0x4303 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007fcbdc819800 nid=0x4103 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007fcbdc027000 nid=0x3113 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007fcbdd01d000 nid=0x2d03 in Object.wait() [0x000000011814e000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x0000000700012b80> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
    - locked <0x0000000700012b80> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" daemon prio=5 tid=0x00007fcbdc810800 nid=0x2b03 in Object.wait() [0x000000011804b000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007000125e0> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:503)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
    - locked <0x00000007000125e0> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=5 tid=0x00007fcbdc80e000 nid=0x2903 runnable 
"GC task thread#0 (ParallelGC)" prio=5 tid=0x00007fcbdd01c800 nid=0x2103 runnable 
"GC task thread#1 (ParallelGC)" prio=5 tid=0x00007fcbdc00b000 nid=0x2303 runnable 
"GC task thread#2 (ParallelGC)" prio=5 tid=0x00007fcbdc009000 nid=0x2503 runnable 
"GC task thread#3 (ParallelGC)" prio=5 tid=0x00007fcbdc00c000 nid=0x2703 runnable 
"VM Periodic Task Thread" prio=5 tid=0x00007fcbdd838800 nid=0x4703 waiting on condition 
JNI global references: 639
sarxos commented 9 years ago

Hi @oleklam,

Thank you for the above. This really helps and I'm pretty sure what is happening.

Several threads are waiting for the AtomicProcessor to be free, these are:

"shutdown-hook-1" prio=5 tid=0x00007fcbdc9d2800 nid=0x16307 waiting on condition [0x0000000123de3000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for   (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:70)

"frames-refresher-[0x1470000005ac8511]" daemon prio=5 tid=0x00007fcbdc139000 nid=0x13e83 waiting on condition [0x000000012070c000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for   (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.put(SynchronousQueue.java:878)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:68)

"webcam-discovery-service" daemon prio=5 tid=0x00007fcbdd226800 nid=0xca0f waiting on condition [0x000000011efa4000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for   (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.put(SynchronousQueue.java:878)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:68)

But AtomicProcessor is running forever doing OpenIMAJGrabber.stopSession(..):

"atomic-processor-1" daemon prio=5 tid=0x00007fcbdc2ff800 nid=0xcc03 runnable [0x000000011f0a7000]
   java.lang.Thread.State: RUNNABLE
    at com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber.stopSession(Native Method)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.close(WebcamDefaultDevice.java:391)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.dispose(WebcamDefaultDevice.java:403)
    at com.github.sarxos.webcam.ds.cgt.WebcamDisposeTask.handle(WebcamDisposeTask.java:25)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:81)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

Therefore, when JVM shut down, it runs all ShutdownHooks and wait for all to complete, but since one of the ShutdownHooks uses AtomicProcessor which is busy, the application hangs. The root cause seems to be the fact that OpenIMAJGrabber.stopSession(..) runs forever.

I take a look into the OpenIMAJ code (which can be found here) but I'm pretty lame in ObjectiveC, so I have to ask someone for help.

In the meantime I will prepare small code sample which should help us diagnose this problem a little bit.

sarxos commented 9 years ago

@oleklam,

Can you please check these two classes and verify if you can observe hangs?

First one, test B, discovery disabled, high abstraction.

import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.github.sarxos.webcam.Webcam;

public class Test318b {

    public static void main(String[] args) throws IOException {
        Webcam.getDiscoveryService().setEnabled(false);
        Webcam.getDiscoveryService().stop();
        Webcam webcam = Webcam.getDefault();
        webcam.open();
        ImageIO.write(webcam.getImage(), "JPG", new File("test.jpg"));
        webcam.close();
    }
}

Second one, test A, low level, no abstraction:

import java.nio.ByteBuffer;
import java.util.List;

import org.bridj.Pointer;

import com.github.sarxos.webcam.WebcamException;
import com.github.sarxos.webcam.ds.buildin.natives.Device;
import com.github.sarxos.webcam.ds.buildin.natives.DeviceList;
import com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber;

public class Test318a {

    private static List<Device> list() {
        System.out.println(">> list new grabber");
        OpenIMAJGrabber search = new OpenIMAJGrabber();
        System.out.println(">> list get video devices");
        Pointer<DeviceList> pointer = search.getVideoDevices();
        System.out.println(">> list get pointer");
        DeviceList list = pointer.get();
        System.out.println(">> list as array");
        return list.asArrayList();
    }

    private static void capture(Device device) {
        System.out.println(">> capture new grabber");
        OpenIMAJGrabber grabber = new OpenIMAJGrabber();

        System.out.println(">> capture start session");
        boolean started = grabber.startSession(640, 480, 50, Pointer.pointerTo(device));
        if (!started) {
            throw new WebcamException("Cannot start native grabber!");
        }

        System.out.println(">> capture set timeout");
        grabber.setTimeout(5000);
        System.out.println(">> capture clean memory");
        for (int i = 0; i < 5; i++) { // clean memory buffers
            System.out.println(">> capture clean memory next frame " + i);
            grabber.nextFrame();
        }

        for (int i = 0; i < 5; i++) {

            System.out.println(">> capture get image " + i);
            Pointer<Byte> image = grabber.getImage();
            if (image == null) {
                System.out.println(">> capture image is null");
                return;
            }

            int size = 640 * 480 * 3;
            System.out.println(">> capture valid bytes");
            image = image.validBytes(size);
            System.out.println(">> capture get bytes buffer");
            ByteBuffer buffer = image.getByteBuffer(size);
            System.out.println(">> capture copy memory");
            buffer.get(new byte[size]);
            System.out.println(">> capture copy memory done");
            grabber.nextFrame();
            System.out.println(">> capture next frame done");
        }

        System.out.println(">> loop frames");
        for (int i = 0; i < 20; i++) {
            grabber.nextFrame();
        }

        System.out.println(">> stop session");
        grabber.stopSession();
        System.out.println(">> stop session done");
    }

    public static void main(String[] args) {

        for (int i = 0; i < 5; i++) {

            System.out.println(">> search " + i + " started");
            List<Device> devices = list();
            System.out.println(">> search " + i + " done");

            for (Device device : devices) {
                System.out.println(""
                    + ">> search " + i + " found device "
                    + device.getIdentifierStr() + " name "
                    + device.getNameStr());
            }
        }

        System.out.println(">> check device 0");

        List<Device> devices = list();
        Device device = devices.get(0);
        capture(device);

    }
}
oleklam commented 9 years ago

Hi @sarxos,

No hangs appear for both of the tests.

and Test B, as expected, an image captured was saved onto the current folder.

fyi, below is the output of test A:

>> search 0 started
>> list new grabber
>> list get video devices
>> list get pointer
>> list as array
>> search 0 done
>> search 0 found device 0x1470000005ac8511 name FaceTime HD Camera (Built-in)
>> search 1 started
>> list new grabber
>> list get video devices
>> list get pointer
>> list as array
>> search 1 done
>> search 1 found device 0x1470000005ac8511 name FaceTime HD Camera (Built-in)
>> search 2 started
>> list new grabber
>> list get video devices
>> list get pointer
>> list as array
>> search 2 done
>> search 2 found device 0x1470000005ac8511 name FaceTime HD Camera (Built-in)
>> search 3 started
>> list new grabber
>> list get video devices
>> list get pointer
>> list as array
>> search 3 done
>> search 3 found device 0x1470000005ac8511 name FaceTime HD Camera (Built-in)
>> search 4 started
>> list new grabber
>> list get video devices
>> list get pointer
>> list as array
>> search 4 done
>> search 4 found device 0x1470000005ac8511 name FaceTime HD Camera (Built-in)
>> check device 0
>> list new grabber
>> list get video devices
>> list get pointer
>> list as array
>> capture new grabber
>> capture start session
>> capture set timeout
>> capture clean memory
>> capture clean memory next frame 0
>> capture clean memory next frame 1
>> capture clean memory next frame 2
>> capture clean memory next frame 3
>> capture clean memory next frame 4
>> capture get image 0
>> capture valid bytes
>> capture get bytes buffer
>> capture copy memory
>> capture copy memory done
>> capture next frame done
>> capture get image 1
>> capture valid bytes
>> capture get bytes buffer
>> capture copy memory
>> capture copy memory done
>> capture next frame done
>> capture get image 2
>> capture valid bytes
>> capture get bytes buffer
>> capture copy memory
>> capture copy memory done
>> capture next frame done
>> capture get image 3
>> capture valid bytes
>> capture get bytes buffer
>> capture copy memory
>> capture copy memory done
>> capture next frame done
>> capture get image 4
>> capture valid bytes
>> capture get bytes buffer
>> capture copy memory
>> capture copy memory done
>> capture next frame done
>> loop frames
>> stop session
>> stop session done
sarxos commented 9 years ago

Hi @oleklam,

Thank you for this information. It seems like there is some weird thing I'm not aware when it comes to work with native objects of BridJ on Mac OS and ShutdownHook JVM functionality. These two examples working well clearly proves that hooks functionality does not work well in Webcam Capture API on Mac OS. I will have to investigate this carefully.

For the time before this is fixed you should be able to w/a this issue by closing webcams in WindowListener before the shutdown hook is executed:

import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;

import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamPanel;
import com.github.sarxos.webcam.WebcamResolution;

public class WebcamPanelExample {

    public static void main(String[] args) throws InterruptedException {

        final Webcam webcam = Webcam.getDefault();
        webcam.setViewSize(WebcamResolution.VGA.getSize());

        final WebcamPanel panel = new WebcamPanel(webcam);
        panel.setFPSDisplayed(true);
        panel.setDisplayDebugInfo(true);
        panel.setImageSizeDisplayed(true);
        panel.setMirrored(true);

        JFrame window = new JFrame("Test webcam panel");
        window.addWindowListener(new WindowListener() {

            @Override
            public void windowClosed(WindowEvent e) {
                panel.stop();
                webcam.close();
            }

            @Override
            public void windowOpened(WindowEvent e) {}
            @Override
            public void windowIconified(WindowEvent e) {}
            @Override
            public void windowDeiconified(WindowEvent e) {}
            @Override
            public void windowDeactivated(WindowEvent e) {}
            @Override
            public void windowClosing(WindowEvent e) {}
            @Override
            public void windowActivated(WindowEvent e) {}
        });
        window.add(panel);
        window.setResizable(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.pack();
        window.setVisible(true);
    }
}

Can you please verify it, @oleklam?

oleklam commented 9 years ago

Hi @sarxos, the code above hang on exit! Below is the output from jstack:

2015-03-09 09:46:58
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.71-b01 mixed mode):
"Attach Listener" daemon prio=5 tid=0x00007f910ee86800 nid=0x2f07 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"process reaper" daemon prio=5 tid=0x00007f910b1f3800 nid=0x14803 waiting on condition [0x000000012144d000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007acad9c68> (a java.util.concurrent.SynchronousQueue$TransferStack)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
    at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
    at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
    at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"shutdown-hook-1" prio=5 tid=0x00007f910c087000 nid=0x14707 waiting on condition [0x0000000121422000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007af801a58> (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:70)
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46)
    at com.github.sarxos.webcam.ds.cgt.WebcamDisposeTask.dispose(WebcamDisposeTask.java:20)
    at com.github.sarxos.webcam.Webcam.dispose(Webcam.java:426)
    at com.github.sarxos.webcam.WebcamShutdownHook.run(WebcamShutdownHook.java:44)
"notificator-[FaceTime HD Camera (Built-in) 0x1470000005ac8511]" daemon prio=5 tid=0x00007f910b50c000 nid=0x10d2b waiting on condition [0x000000011fdbb000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007af590078> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"DestroyJavaVM" prio=5 tid=0x00007f910c309000 nid=0x1303 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"webcam-panel-scheduled-executor-1" daemon prio=5 tid=0x00007f910c161000 nid=0x13c0b waiting on condition [0x000000011e266000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007af590248> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1090)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"AWT-EventQueue-0" prio=5 tid=0x00007f910ee81000 nid=0xbc07 waiting on condition [0x000000011ded4000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007af591e58> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
    at java.awt.EventQueue.getNextEvent(EventQueue.java:543)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
"AWT-Shutdown" prio=5 tid=0x00007f910b9e5000 nid=0xbbbb in Object.wait() [0x000000011d438000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007af5b5398> (a java.lang.Object)
    at java.lang.Object.wait(Object.java:503)
    at sun.awt.AWTAutoShutdown.run(AWTAutoShutdown.java:296)
    - locked <0x00000007af5b5398> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:745)
"frames-refresher-[0x1470000005ac8511]" daemon prio=5 tid=0x00007f910fae2000 nid=0x12903 waiting on condition [0x0000000119e7e000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007af80df68> (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.put(SynchronousQueue.java:878)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:68)
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice$NextFrameTask.nextFrame(WebcamDefaultDevice.java:60)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.updateFrameBuffer(WebcamDefaultDevice.java:451)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.run(WebcamDefaultDevice.java:480)
    at java.lang.Thread.run(Thread.java:745)
"webcam-lock-[FaceTime HD Camera (Built-in) 0x1470000005ac8511]" daemon prio=5 tid=0x00007f910b937800 nid=0x11003 waiting on condition [0x000000011d53b000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at com.github.sarxos.webcam.WebcamLock$LockUpdater.run(WebcamLock.java:60)
"Java2D Disposer" daemon prio=5 tid=0x00007f910ccad000 nid=0x10a0b in Object.wait() [0x000000011d232000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007af592c68> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
    - locked <0x00000007af592c68> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
    at sun.java2d.Disposer.run(Disposer.java:145)
    at java.lang.Thread.run(Thread.java:745)
"Java2D Queue Flusher" daemon prio=5 tid=0x00007f910c0f5000 nid=0xe61b in Object.wait() [0x000000011ccd8000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007af58da68> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
    at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:206)
    - locked <0x00000007af58da68> (a sun.java2d.opengl.OGLRenderQueue$QueueFlusher)
"webcam-discovery-service" daemon prio=5 tid=0x00007f910c0f0000 nid=0x4807 waiting on condition [0x0000000118153000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007af80df68> (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.put(SynchronousQueue.java:878)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:68)
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver$GetDevicesTask.getDevices(WebcamDefaultDriver.java:80)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver.getDevices(WebcamDefaultDriver.java:125)
    at com.github.sarxos.webcam.WebcamDiscoveryService.scan(WebcamDiscoveryService.java:156)
    at com.github.sarxos.webcam.WebcamDiscoveryService.run(WebcamDiscoveryService.java:265)
    at java.lang.Thread.run(Thread.java:745)
"AppKit Thread" daemon prio=5 tid=0x00007f910c110000 nid=0x713 in Object.wait() [0x00007fff59736000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007af7fffd8> (a com.github.sarxos.webcam.WebcamShutdownHook)
    at java.lang.Thread.join(Thread.java:1281)
    - locked <0x00000007af7fffd8> (a com.github.sarxos.webcam.WebcamShutdownHook)
    at java.lang.Thread.join(Thread.java:1355)
    at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106)
    at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46)
    at java.lang.Shutdown.runHooks(Shutdown.java:123)
    at java.lang.Shutdown.sequence(Shutdown.java:167)
    at java.lang.Shutdown.exit(Shutdown.java:212)
    - locked <0x00000007afaa3690> (a java.lang.Class for java.lang.Shutdown)
    at java.lang.Runtime.exit(Runtime.java:109)
    at java.lang.System.exit(System.java:962)
    at com.apple.eawt._AppEventHandler.performQuit(_AppEventHandler.java:145)
    - locked <0x00000007afab4438> (a com.apple.eawt._AppEventHandler)
    at com.apple.eawt.QuitResponse.performQuit(QuitResponse.java:51)
    at com.apple.eawt._AppEventHandler$_QuitDispatcher.performDefaultAction(_AppEventHandler.java:390)
    at com.apple.eawt._AppEventHandler$_AppEventDispatcher.dispatch(_AppEventHandler.java:512)
    at com.apple.eawt._AppEventHandler.handleNativeNotification(_AppEventHandler.java:202)
"atomic-processor-1" daemon prio=5 tid=0x00007f910b419000 nid=0x4a03 runnable [0x0000000118256000]
   java.lang.Thread.State: RUNNABLE
    at com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber.stopSession(Native Method)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.close(WebcamDefaultDevice.java:391)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.dispose(WebcamDefaultDevice.java:403)
    at com.github.sarxos.webcam.ds.cgt.WebcamDisposeTask.handle(WebcamDisposeTask.java:25)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:81)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
"Service Thread" daemon prio=5 tid=0x00007f910c800000 nid=0x4403 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=5 tid=0x00007f910b80b800 nid=0x4203 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=5 tid=0x00007f910c012000 nid=0x4003 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=5 tid=0x00007f910c011000 nid=0x300f runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=5 tid=0x00007f910c001000 nid=0x2d03 in Object.wait() [0x0000000115cd1000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007af5c0570> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
    - locked <0x00000007af5c0570> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
"Reference Handler" daemon prio=5 tid=0x00007f910c000000 nid=0x2b03 in Object.wait() [0x0000000115bce000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000007af5bffd0> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:503)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
    - locked <0x00000007af5bffd0> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=5 tid=0x00007f910b046000 nid=0x2903 runnable 
"GC task thread#0 (ParallelGC)" prio=5 tid=0x00007f910b80f800 nid=0x2103 runnable 
"GC task thread#1 (ParallelGC)" prio=5 tid=0x00007f910b810800 nid=0x2303 runnable 
"GC task thread#2 (ParallelGC)" prio=5 tid=0x00007f910b811000 nid=0x2503 runnable 
"GC task thread#3 (ParallelGC)" prio=5 tid=0x00007f910b811800 nid=0x2703 runnable 
"VM Periodic Task Thread" prio=5 tid=0x00007f910c809000 nid=0x4603 waiting on condition 
JNI global references: 539
sarxos commented 9 years ago

Hi @oleklam,

Ooops, this is not what I expected... Can you please disable discovery service and try again? Add this at the very beginning of main() method:

Webcam.getDiscoveryService().setEnabled(false);
Webcam.getDiscoveryService().stop();

Situation is the same as before, but to be honest I have no idea why stopSession() is blocking... Currently it looks like this - the AppKit thread is doing System.exit(), which indirectly calls WebcamShutdownHook:

"AppKit Thread" daemon prio=5 tid=0x00007f910c110000 nid=0x713 in Object.wait() [0x00007fff59736000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on  (a com.github.sarxos.webcam.WebcamShutdownHook) <<=== it's waiting for this one
    at java.lang.Thread.join(Thread.java:1281)
    - locked  (a com.github.sarxos.webcam.WebcamShutdownHook)
    at java.lang.Thread.join(Thread.java:1355)
    at java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106)
    at java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46)
    at java.lang.Shutdown.runHooks(Shutdown.java:123)
    at java.lang.Shutdown.sequence(Shutdown.java:167)
    at java.lang.Shutdown.exit(Shutdown.java:212)
    - locked  (a java.lang.Class for java.lang.Shutdown)
    at java.lang.Runtime.exit(Runtime.java:109)
    at java.lang.System.exit(System.java:962)

And WebcamShutdownHook is waiting for AtomicProcessor to complete process():

"shutdown-hook-1" prio=5 tid=0x00007f910c087000 nid=0x14707 waiting on condition [0x0000000121422000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for   (a java.util.concurrent.SynchronousQueue$TransferQueue)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.SynchronousQueue$TransferQueue.awaitFulfill(SynchronousQueue.java:763)
    at java.util.concurrent.SynchronousQueue$TransferQueue.transfer(SynchronousQueue.java:694)
    at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:925)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:70) <<=== waiting to complete
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46)
    at com.github.sarxos.webcam.ds.cgt.WebcamDisposeTask.dispose(WebcamDisposeTask.java:20)
    at com.github.sarxos.webcam.Webcam.dispose(Webcam.java:426)
    at com.github.sarxos.webcam.WebcamShutdownHook.run(WebcamShutdownHook.java:44)

But AtomicProcessor is running native stopSession(..) forever:

"atomic-processor-1" daemon prio=5 tid=0x00007f910b419000 nid=0x4a03 runnable [0x0000000118256000]
   java.lang.Thread.State: RUNNABLE
    at com.github.sarxos.webcam.ds.buildin.natives.OpenIMAJGrabber.stopSession(Native Method)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.close(WebcamDefaultDevice.java:391)
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.dispose(WebcamDefaultDevice.java:403)
    at com.github.sarxos.webcam.ds.cgt.WebcamDisposeTask.handle(WebcamDisposeTask.java:25)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:81)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

Thus blocking whole shutdown process...

oleklam commented 9 years ago

Hi @sarxos,

Sorry for the late reply.

The WebcamPanelExample application still halt on exit even the two lines of code is added at the beginning of the main().

I have done a manual trace on the example and the following is the call sequence when exiting the program:

Webcam.dispose
WebcamDisposeTask.dispose 
WebcamTask.process -> processor.process(this)
WebcamProcessor.process -> runner.isShutdown = false 
WebcamProcessor$AtomicProcessor.process -> outbound.take().getThrowable() <-- halt here

The program cannot exit properly due to the synchronization problem of the outbound.take() call inside AtomicProcess.process.

Not sure if this is useful to you.

sarxos commented 9 years ago

Hi @oleklam,

Well, this is not a sync problem but the normal behaviour. The outbound.take() will block until the outbound.put(t) is invoked in AtomicProcessor.run() (line 91 in WebcamProcessor, the inbound and outbound works as exchangers). The problem lies in the fact that t.handle() from line 81 never ends so put(t) is not invoked...

The easiest way would be to remove outbound/inbound queues, however, by doing this the code will stop working properly on Windows (much to talk about, but to cut the story short - Windows native binaries suffer from synchronization issues and some methods does not work properly form two separate threads, even in case when they are synchronized properly) :(

I will need to investigate this deeper, simulate hang and try to escape it with interrupt(), but this needs to wait when I have some more free time to donate into the project, because now I have way too many things on my head.

msj121 commented 9 years ago

Just for the record, simply writing the static void main as follows:

public static void main(String[] args) {    
        Webcam.getDiscoveryService().setEnabled(true);
        Webcam.getDiscoveryService().stop();
        webcam = Webcam.getDefault();
        launch(args);
        while(running){
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        webcam.close();
}

Now you can use the webcam in JavaFx. My assumption is natively the main thread needs to exist, or something.... I hope this is a useable workaround for some.

Of course you need to set running = false, when your JavaFX application is done with the Webcam.

sarxos commented 9 years ago

Note to myself, this is related to https://github.com/sarxos/webcam-capture/issues/170

reinaldoluckman commented 8 years ago

Hello.

I'm with the exact same problem here. Tried everything on this thread, but still hangs on cmd+q.

Thanks.

reinaldoluckman commented 8 years ago

The only way that I could solve this was by putting a shutdown hook with a halt:

if (System.getProperty("os.name").equals("Mac OS X")) {            

    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            camMMOPanel.stop();
            camMMO.close();
            Runtime.getRuntime().halt(0);
        }
    });            
}

If someone has a better solution, please share.

Thanks.