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

Cannot execute task, cannot start native grabber #94

Closed sarxos closed 3 years ago

sarxos commented 11 years ago

Extracted from #81


There is a new problem. It still does not show an image and shows the following exception (Note: It detects correctly, how many webcams there are connected, that is if I plug in the USB cam, the

Webcam.getWebcams(Long.MAX_VALUE, TimeUnit.MILLISECONDS) 

command returns a list with 1 item, if I unplug it no device is found.). Here is the stacktrace when trying to open the webcam using open(true)

Exception in thread "Thread-26" com.github.sarxos.webcam.WebcamException: Cannot execute task
        at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:57)
        at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:120)
        at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:35)
        at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.open(WebcamOpenTask.java:20)
        at com.github.sarxos.webcam.Webcam.open(Webcam.java:177)
        at android.hardware.d.run(Unknown Source)
Caused by: com.github.sarxos.webcam.WebcamException: Cannot start native grabber!
        at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.open(WebcamDefaultDevice.java:223)
        at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.handle(WebcamOpenTask.java:38)
        at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:66)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
sarxos commented 11 years ago

FYI @hodka

sarxos commented 11 years ago

Can you please share the example source code you are running where this exception is reproducible?

Few things worth to know about this error and possible root causes:

Dirty Application Shutdown

Dirty shutdown means:

Clean shutdown means:

The root cause here is the fact that DirectShow graph has not been properly destroyed and there are still some important pointers allocated which causes new graph to be unusable. Webcam Capture API is taking care of this and perform clean webcam dispose operation while clean shutdown.

For the dirty shutdown, there is a special development setting, which shall not be used in production due to unknown side effects, which can be used to force webcams dispose when KILL signal is detected:

static {
    Webcam.setHandleTermSignal(true);
}

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

    Webcam webcam = Webcam.getDefault();
    webcam.open(true);

    for (int i = 0; i < 100; i++) {
        webcam.getImage();
        Thread.sleep(100);
    }
}

Webcam Does Not Support RGB Format

Some cameras does not support RGB format so default capture driver which is based on OpenIMAJ, which uses Theo's VideoLibrary, which does not support YUV, is not able to to stream pictures from such devices.

To eliminate this problem other capture driver can be used, e.g. GStreamer Webcam Capture Driver. I created it in lately so it does not have distribution ZIP yet, but I can release it if someone would like to try it. This driver requires GStreamer libraries to be installed on the PC (~60MB).

Webcam.setDriver(new GStreamerDriver());

The other option is to use LTI-CIVIL Webcam Capture Driver which also use some unique streaming method, but there is no guarantee it will be working. LTI-CIVIL is not being maintained any more, but it can be usable sometimes.

Webcam.setDriver(new LtiCivilDriver());

Unknown Reason

If none of the above methods helps, it's time to debug.

hodka commented 11 years ago

Thanks for sharing your ideas about the root of the problem. I will work through them and come back as soon as I have some new results on the problem.

sarxos commented 11 years ago

Here you can find some usable information of how to enable debug logs. You could need them for deeper problem analysis.

hodka commented 11 years ago

The root of the problem is the ViewSize set for the webcam. In order to get a simple test case, I modified your TakePictureExample. The following code produces the above mentioned error on my Windows XP machine (but not Windows 7 machine with same usb webcam):

public class TakePictureExample {
    public static void main(String[] args) throws IOException {

        Webcam webcam = Webcam.getDefault();

        webcam.setViewSize(new Dimension(1024,768));

        webcam.open(false);

        // get image
        BufferedImage image = webcam.getImage();

        // save image to PNG file
        ImageIO.write(image, "PNG", new File("test.png"));  
    }
}

When I uncomment the webcam.setViewSize(new Dimension(1024,768)); line, it works just fine. If I run the same code block on my Windows 7 computer (with the same usb webcam) it works just fine also with the view size set. However, it produces a 800 x 600 Pixel picture (possibly the highest resolution the webcam supports)

I just run another test scenario on my Windows XP machine (that produces the error) with View Size set to all the possible values. This is the result: 1024x768: Above error 640x480: Above error 480x400: picture with resolution 640x480 352x288: picture with resolution 352x288 320x240: picture with resolution 320x240 176x144: picture with resolution 176x144

The error is thrown in the WebcamDefaultDevice.java at the following line:

boolean started = grabber.startSession(size.width, size.height, 50, Pointer.pointerTo(device));
if (!started) {
    throw new WebcamException("Cannot start native grabber!");
}

A possible workaround might be that it tries to startSession and if it fails and the size != getResolutions()[0], then it retries once with the lowest resolution. Certainly, an even better solution would be if grabber.startSession would try to determine a resolution that is close to the settings set by the user and chose that one (as it does on my Windows 7 machine where it uses 800x600 instead of the set 1024x768)

Is there a possibility to modify the getResolutions() function such that it will only return resolutions that are supported by the current system?

sarxos commented 11 years ago

Hi,

Let me clarify how it is working.

The default capture driver (i.e. refined OpenIMAJ) is not able to determine the list of formats supported by webcam. That's because it is using Theo's VideoInput library which does not expose such functionality. Therefore, default capture driver has static artificial set of supported resolutions, which includes:

These marked as *standard are supported by almost all of the modern webcams, and the remaining ones could be supported, but don't have to.

When I uncomment the webcam.setViewSize(new Dimension(1024,768)); line, it works just fine. If I run the same code block on my Windows 7 computer (with the same usb webcam) it works just fine also with the view size set. However, it produces a 800 x 600 Pixel picture (possibly the highest resolution the webcam supports)

The 800x600 is the closest resolution to 1024x768 - it's being set in VideoInput library (check here), so I cannot do much in Java code.

In terms of the issue you found, to avoid such situations, I think I should remove all non-standard resolutions from the supported set, thus I would leave only QQVGA, QVGA and VGA. Those are the ones almost camera is supporting.

Can you please check 640x480 one more time? It's very strange since VideoInput is selecting it for 480x400. That means it is supported.

Certainly, an even better solution would be if grabber.startSession would try to determine a resolution that is close to the settings set by the user and chose that one (as it does on my Windows 7 machine where it uses 800x600 instead of the set 1024x768)

I have a plan to create some code to detect supported format, but I'm not very familiar with C++, so I'm not even sure how I should start it...

Regarding the difference in webcam functionality between Windows 7 and Windows XP, I suppose there is something in the drivers which are used to handle low-level webcam HW calls.

Depending on the needs you could use other, non-default capture driver. If you need your app to be portable and running on many operating systems, then you should still use default one, but if you do not need it to be portable, and running on only one PC, then you could choose GStreamer capture driver. The GStreamer driver automatically detects all formats supported by the camera and getResolution() method returns only these resolutions which can be "really" set.

hodka commented 11 years ago

Hi,

just tried the 640x480 after a reboot of my Windows XP machine. There is still the same problem with this resolution. I think further investigation is needed in order to detemine the exact source of the problem. I will engage in some debugging and work through the sources.... Hope to find a solution. I will come back as soon as there are some news. As I am very short on time, it might take some time. I will also look whether I can work out a way to determine the supported camera resolutions.

Thanks so far.

sarxos commented 11 years ago

Native logs can be helpful here. To enable them please set OPENIMAJ_GRABBER_VERBOSE environment variable to any value.

If you are using IDE you would have to probably restart it so it re-read all existing variables.

hodka commented 11 years ago

Hi sarxos,

I did a lot of testing, also rebooting my Windows XP machine quite often to ensure a clean setting and the bug does not reproduce reliably. The native logs were very helpful in determining that the native VideoInput library does a good job in changing the requested resolutions to ones that are actually supported. Instead, the problems is deeper and caused by the following error "ERROR: Could not connect pins - RenderStream()" ... However, this also occurs after a reboot sometimes such that in can not be the result of a dirty application shutdown... Well, I guess that I will catch the Exception for now and present an error message to users whenever this occurs. If it occurs more often, I will add another step of switching to lti-civil first, retry to connect and if there is still a problem then show the error message.

Here is the log for the same application start, both after a reboot, once doing well and once failing:

OK

***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****

VIDEOINPUT SPY MODE!

SETUP: Looking For Capture Devices
SETUP: 0) Trust Webcam 14839 
SETUP: 1 Device(s) found

***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****

VIDEOINPUT SPY MODE!

SETUP: Looking For Capture Devices
SETUP: 0) Trust Webcam 14839 
SETUP: 1 Device(s) found

VIDEOINPUT SPY MODE!

SETUP: Looking For Capture Devices
SETUP: 0) Trust Webcam 14839 
SETUP: 1 Device(s) found

SETUP: Setting up device 0
SETUP: Trust Webcam 14839
SETUP: Couldn't find preview pin using SmartTee
SETUP: Default Format is set to 640 by 480 
SETUP: trying format RGB24 @ 1024 by 768
SETUP: trying format RGB32 @ 1024 by 768
SETUP: trying format RGB555 @ 1024 by 768
SETUP: trying format RGB565 @ 1024 by 768
SETUP: trying format YUY2 @ 1024 by 768
SETUP: trying format YVYU @ 1024 by 768
SETUP: trying format YUYV @ 1024 by 768
SETUP: trying format IYUV @ 1024 by 768
SETUP: trying format UYVY @ 1024 by 768
SETUP: trying format YV12 @ 1024 by 768
SETUP: trying format YVU9 @ 1024 by 768
SETUP: trying format Y411 @ 1024 by 768
SETUP: trying format Y41P @ 1024 by 768
SETUP: trying format Y211 @ 1024 by 768
SETUP: trying format AYUV @ 1024 by 768
SETUP: trying format Y800 @ 1024 by 768
SETUP: trying format Y8 @ 1024 by 768
SETUP: trying format GREY @ 1024 by 768
SETUP: couldn't find requested size - searching for closest matching size
SETUP: closest supported size is RGB24 @ 800 600
SETUP: Capture callback set
SETUP: Device is setup and ready to capture.

ERROR: SampleCB() - buffer sizes do not match

SETUP: Disconnecting device 0
SETUP: freeing Grabber Callback
SETUP: freeing Grabber  
SETUP: freeing Control   
SETUP: freeing Media Type  
SETUP: removing filter NullRenderer...
SETUP: filter removed NullRenderer  
SETUP: removing filter Sample Grabber...
SETUP: filter removed Sample Grabber  
SETUP: removing filter Smart Tee...
SETUP: filter removed Smart Tee  
SETUP: removing filter Trust Webcam 14839...
SETUP: filter removed Trust Webcam 14839  
SETUP: freeing Capture Graph 
SETUP: freeing Main Graph 
SETUP: Device 0 disconnected and freed

ERROR

Exception in thread "main" com.github.sarxos.webcam.WebcamException: Cannot execute task
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:57)
    at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:120)
    at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:35)
    at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.open(WebcamOpenTask.java:20)
    at com.github.sarxos.webcam.Webcam.open(Webcam.java:177)
    at TakePictureExample.main(TakePictureExample.java:31)
Caused by: com.github.sarxos.webcam.WebcamException: Cannot start native grabber!
    at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.open(WebcamDefaultDevice.java:223)
    at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.handle(WebcamOpenTask.java:38)
    at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:66)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****

VIDEOINPUT SPY MODE!

SETUP: Looking For Capture Devices
SETUP: 0) Trust Webcam 14839 
SETUP: 1 Device(s) found

***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****

VIDEOINPUT SPY MODE!

SETUP: Looking For Capture Devices
SETUP: 0) Trust Webcam 14839 
SETUP: 1 Device(s) found

VIDEOINPUT SPY MODE!

SETUP: Looking For Capture Devices
SETUP: 0) Trust Webcam 14839 
SETUP: 1 Device(s) found

SETUP: Setting up device 0
SETUP: Trust Webcam 14839
SETUP: Couldn't find preview pin using SmartTee
SETUP: Default Format is set to 640 by 480 
SETUP: trying format RGB24 @ 1024 by 768
SETUP: trying format RGB32 @ 1024 by 768
SETUP: trying format RGB555 @ 1024 by 768
SETUP: trying format RGB565 @ 1024 by 768
SETUP: trying format YUY2 @ 1024 by 768
SETUP: trying format YVYU @ 1024 by 768
SETUP: trying format YUYV @ 1024 by 768
SETUP: trying format IYUV @ 1024 by 768
SETUP: trying format UYVY @ 1024 by 768
SETUP: trying format YV12 @ 1024 by 768
SETUP: trying format YVU9 @ 1024 by 768
SETUP: trying format Y411 @ 1024 by 768
SETUP: trying format Y41P @ 1024 by 768
SETUP: trying format Y211 @ 1024 by 768
SETUP: trying format AYUV @ 1024 by 768
SETUP: trying format Y800 @ 1024 by 768
SETUP: trying format Y8 @ 1024 by 768
SETUP: trying format GREY @ 1024 by 768
SETUP: couldn't find requested size - searching for closest matching size
SETUP: closest supported size is RGB24 @ 800 600
SETUP: Capture callback set
ERROR: Could not connect pins - RenderStream()

SETUP: Disconnecting device 0
SETUP: freeing Grabber Callback
SETUP: freeing Renderer 
SETUP: freeing Capture Source 
SETUP: freeing Grabber Filter  
SETUP: freeing Grabber  
SETUP: freeing Control   
SETUP: freeing Media Type  
SETUP: removing filter NullRenderer...
SETUP: filter removed NullRenderer  
SETUP: removing filter Sample Grabber...
SETUP: filter removed Sample Grabber  
SETUP: removing filter Trust Webcam 14839...
SETUP: filter removed Trust Webcam 14839  
SETUP: freeing Capture Graph 
SETUP: freeing Main Graph 
SETUP: Device 0 disconnected and freed
sarxos commented 11 years ago

@hodka, I'm glad we have at least such info available. Dealing with problem in native layer sometimes is like the pain in the arse.

I'm currently trying to make GStreamer driver portable. Today I was able to make it running on Linux as well as on MS Windows. It is running on Linux very smoothly since GStreamer is installed by default (I suppose that, but not sure, since I didn't have to install it by myself, but it could be installed as 3rd party dependency), but on Windows you will still have to use GStreamer installer.

In the upcoming days I will be trying to extract required DLLs from Windows installation and try to load them dynamically, but it failed in my last experiment and I need to clarify what is wrong...

I hope to complete above steps, so Webcam Capture users will have one more, reliable driver to use, which is comparable in functionality to the default one, but gives additional feature to get list of supported resolutions.

hodka commented 11 years ago

@sarxos, I am looking forward to see your progress. In the meanwhile I will use this library in its current form. This is a great project, especially as I am currently developing a application that is running on both, Windows and Mac OS X. Keep it up and all the best for the future development!

pknauber commented 11 years ago

Hi, my program starts as follows:

Webcam.setAutoOpenMode(true);
Webcam webcam = Webcam.getDefault();
BufferedImage image = webcam.getImage();

I am seeing the exact same error message as above on my ASUS tablet (32 bit) / windows8 (not RT) plus the message

ERROR: Registry access denied - administrator privileges are required.

when executing the last line. Unfortunately, running it as admin is not acceptable in my context.

Running the same program on my Lenovo ThinkPad (64 bit, windows8) everything works fine.

Do you have any idea what could be different on those two machines, i.e., what registry settings are accessed here? I guess that java (the vm?) has to have the permission to access the camera, but I did not find any hint on how to change the permissions for a desktop application (only for metro apps). Any help would be very much appreciated!

sarxos commented 11 years ago

Hi,

Thank you for the report.

Can you please provide more details?

sarxos commented 11 years ago

Please create separate thread so this issue will not be affected.

pknauber commented 11 years ago

Moved to #148 with additional information.

wasifmirza commented 9 years ago

Hi, im accessing total 6 cameras,

For 3 cameras it just worked fine,,,but when i am trying to access 6 camera it throws an exception com.github.sarxos.webcam.WebcamException: Cannot execute task

Please assit

sarxos commented 9 years ago

@wasifmirza, your USB controller does not have enough bandwidth to stream data from all the webcams at once. It can be easily calculated. USB 2.0 = 60 MB/s, 640x480 RGB @ 25 FPS = 21 MB/s, so you can stream ~2 or 3 cameras at once.

wasifmirza commented 9 years ago

Can you please provide me a solution for this.... I have extension box of usb slots. USB 2.0. 7 slots. Any kind of suggestion....because i am using it in my project and i need to access 6 camera. Please give me a solution.

Waiting for your response. Regards

sarxos commented 9 years ago

@wasifmirza there is no possibility to extend USB capacity. You can connect any number of extension boxes, but your USB controller on your motherboard is still the same - it has limited capacity (60 MB/s for USB 2.0, which is max for almost all UVC cameras) and cannot be changed up.

You can try using GStreamer v0.10 with gstreamer-driver which should stream more (due to smaller format: 4 bytes for two pixels instead of 6), but this is still too low to stream from 6 cameras at once.

As a workaround you may try to:

But the above will be pretty slow, so if you need speed, this may be insufficient for your application.

wasifmirza commented 9 years ago

Thanks alot @sarxos for the suggestion.

I am also facing 1 more problem. It is the extension box for usb.

Due to port com reorganization i am not able to open 2 camera on that box.

wasifmirza commented 9 years ago

@sarxos should i mail you the basic program i made ?

wasifmirza commented 9 years ago
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import java.awt.*;

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

public class Camera extends JFrame {

     JFrame cam=new JFrame("Check Camera");

      //Webcam.getWebcams().get(0):

      Webcam w1;
      Webcam w2;
      Webcam w3;
      Webcam w4;
      Webcam w5;
      Webcam w6;

      WebcamPanel cam1;
      WebcamPanel cam2;
      WebcamPanel cam3;
      WebcamPanel cam4;
      WebcamPanel cam5;
      WebcamPanel cam6;

      /* Setting of webcam view can be done in following resolutions only :
       * QQVGA (176 , 144)
QVGA (320 x 240)
VGA (640 x 480)
       */

public Camera()
{

     w1=Webcam.getWebcams().get(0);

     w1.setViewSize(new Dimension(176 , 144)); // set size

     w2=Webcam.getWebcams().get(1);
     w2.setViewSize(new Dimension(176 , 144)); // set size

     w3=Webcam.getWebcams().get(2);
     w3.setViewSize(new Dimension(176 , 144)); // set size

     w4=Webcam.getWebcams().get(3);
     w4.setViewSize(new Dimension(176 , 144)); // set size

     w5=Webcam.getWebcams().get(2);
     w5.setViewSize(new Dimension(176 , 144)); // set size

     w6=Webcam.getWebcams().get(5);
     w6.setViewSize(new Dimension(176 , 144)); // set size

     cam1=new WebcamPanel(w1);

     cam2=new WebcamPanel(w2);

     cam3=new WebcamPanel(w3);

     cam4=new WebcamPanel(w4);

     cam5=new WebcamPanel(w5);

     cam6=new WebcamPanel(w6);

     cam.setLayout(new FlowLayout());
     cam.setSize(1224,1000);

     cam.add(cam1);

     cam.add(cam2);

     cam.add(cam3);
     cam.add(cam4);

     cam.add(cam5);

     cam.add(cam6);

     cam.setVisible(true);

     //check image capture
 BufferedImage image = w1.getImage();
     try {
        ImageIO.write(image, "jpg", new File("test.jpg"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
public void camera_close()
{
    w1.close();
    w2.close();

    w3.close();
    w4.close();

    w5.close();

    w6.close();

}
public void camera_open()
{
    w1.open();
    w2.open();
    w3.open();
    w4.open();
    w5.open();
    w6.open();  
}
}
wasifmirza commented 9 years ago

This code can work with 4 cameras smoothly with resolution of each as 640,480 It runs when i connect 4 cameras on my laptop USB slots.

But when i connect my cameras to extension box it cannot add it and gives exceptions.

sarxos commented 9 years ago

@wasifmirza, there is no way to fix this in Webcam Capture API. The USB ports and whole communication is being done by your operating system. If you experience problems with the external USB hub (or extension box) this is because:

You may try to connect 3 hubs to your USB sloths and try to connect 2 cameras to each hub (this will give you 6 cameras). This may work but I never tried this approach, and honestly I cannot guarantee such solution to work.

wasifmirza commented 9 years ago

Once again thanks.

Is there is any function from which we can input webcam by the usb id or any of it's USB controller feature.

wasifmirza commented 9 years ago

I mean we use

Webcam.getWebcams.get( number such as 0 to n );

Cant we use some else for .get(number);

because while detecting from external box there it must detect it....! It is not detecting from it. Only 1 camera is detected. And i got your answer that over bandwidth cant be used but now i want to know another to access the webcam using some class or id of usb.

wasifmirza commented 9 years ago

And i am using windows 8 ... So there is no option of port in my device manager....! If that would have been possible so i would have changed the port number...! but unfortunately i dont have the port option.

sarxos commented 9 years ago

@wasifmirza, the Webcam Capture API does not operate on the USB level. The number you are passing to Webcam.getWebcams().get(..) is a camera identifier, not the port. The API is using operating system features to list and access webcams without dealing too much with the USB. At the very bottom level the camera is accessed (thru Microsoft API) with the URI like:

vfw:Microsoft WDM Image Capture (Win32):0

Where 0 in the above example is the first camera detected (by the operating system). However, it can be connected to USB1, USB2, or even to USB10 on USB hub, so as you can see there is no way to deal with the USB port itself.

The number you are passing to the get(..) method is just a number. It's not ID, not class, not anything special - just a ordinary number which means: 0 = first camera detected, 1 = second camera detected, 2 = third camera detected, etc...

wasifmirza commented 9 years ago

@sarxos Yup i got you and thanks for the response for every single query... Your work on webcam is appreciable and i liked it.

Thanks !

wasifmirza commented 9 years ago

@sarxos what if i use usb 3.0 . I have lappy with usb 3.0 and what if i use extension box with 3.0 It will work?

sarxos commented 9 years ago

@wasifmirza I guess this should be OK, but if and only if your camera is 3.0 compliant. In case it's 2.0 and your USB port is 3.0, the whole communication is still limited to 2.0 speed.

wasifmirza commented 9 years ago

Hellos @sarxos I have 1 issue.

I am coding in Java using eclipse IDE. I have an start and stop button. On start button and starting the loop of capturing of camera but when i am trying to close the window or to code on stop, the process doesnt break or that loop goes on taking pictures.

Can you please suggest me how to break or stop the camera on Frame close or to stop the camera between the process.

Thanks!

sarxos commented 9 years ago

@wasifmirza, can you please prepare small code example to demonstrate your issue? Normally it should be enough to call close() on webcam to stop.

wasifmirza commented 9 years ago

@sarxos I have tried close() function also. But it doesnt work when the camera is capturing the images.

sarxos commented 9 years ago

@wasifmirza, can you verify which threads are blocking?

sarxos commented 9 years ago

@wasifmirza, I was testing the code below and I do not observe more than 1.5s delay between the window close and program termination (which is actually expected because application must properly dispose the webcam in shutdown hooks).

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);

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

            @Override
            public void windowClosed(WindowEvent e) {
                webcam.close();
                window.dispose();
            }

            @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.DISPOSE_ON_CLOSE);
        window.pack();
        window.setVisible(true);
    }
}

I cannot do anything more in regards to this issue. You first need to figure out which thread is blocking your application. The only way to stop camera taking pictures is to close() it.

salmansaifi7 commented 6 years ago

I am also facing same issue.. but in some weird pattern..

Here is my application pattern:

  1. this issue come whenever i am installing for the very first time, application is up, but not able to call webcam.open(); for fixing it we do restart (dirty shutdown) our application.
  2. After step-1, This issue again come-back after OS (RHEL-7) restart, process came up via init.d scripts, it start failing while webcam.open(); now again we hv to restart..

Is there any fix/workaround available for this? should we try changing the default driver?

salmansaifi7 commented 6 years ago

this is the log when it fail:

_2018-09-13 11:41:10.0049 PDT  (webcam-discovery-service) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver - Found device USB 2.0 Camera /dev/video0
2018-09-13 11:41:10.0062 PDT  (ForkJoinPool.commonPool-worker-1) [DEBUG]: com.github.sarxos.webcam.Webcam - Setting new resolution 1280x720
2018-09-13 11:41:10.0066 PDT  (ForkJoinPool.commonPool-worker-1) [DEBUG]: com.github.sarxos.webcam.WebcamLock - Lock Webcam USB 2.0 Camera /dev/video0
2018-09-13 11:41:10.0071 PDT  (atomic-processor-1) [INFO]: com.github.sarxos.webcam.ds.cgt.WebcamOpenTask - Opening webcam USB 2.0 Camera /dev/video0
2018-09-13 11:41:10.0072 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Opening webcam device USB 2.0 Camera /dev/video0
2018-09-13 11:41:10.0073 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Webcam device /dev/video0 starting session, size java.awt.Dimen
sion[width=1280,height=720]
2018-09-13 11:41:10.0764 PDT  (ForkJoinPool.commonPool-worker-1) [DEBUG]: com.github.sarxos.webcam.WebcamLock - Unlock Webcam USB 2.0 Camera /dev/video0
2018-09-13 11:41:10.0766 PDT  (webcam-lock-[USB 2.0 Camera /dev/video0]) [DEBUG]: com.github.sarxos.webcam.WebcamLock - Lock updater has been interrupted
2018-09-13 11:41:10.0766 PDT  (ForkJoinPool.commonPool-worker-1) [DEBUG]: com.github.sarxos.webcam.Webcam - Webcam exception when opening
com.github.sarxos.webcam.WebcamException: Cannot execute task
        at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.process(WebcamProcessor.java:72) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.WebcamProcessor.process(WebcamProcessor.java:140) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.WebcamTask.process(WebcamTask.java:46) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.open(WebcamOpenTask.java:20) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.Webcam.open(Webcam.java:295) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.Webcam.open(Webcam.java:250) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.Webcam.open(Webcam.java:236) ~[Sarxos_webcam-capture-0.x.jar:?]

        at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1626) [?:1.8.0_91]
        at java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1618) [?:1.8.0_91]
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) [?:1.8.0_91]
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) [?:1.8.0_91]
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) [?:1.8.0_91]
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) [?:1.8.0_91]
Caused by: com.github.sarxos.webcam.WebcamException: Cannot start native grabber!
        at com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice.open(WebcamDefaultDevice.java:334) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.ds.cgt.WebcamOpenTask.handle(WebcamOpenTask.java:38) ~[Sarxos_webcam-capture-0.x.jar:?]
        at com.github.sarxos.webcam.WebcamProcessor$AtomicProcessor.run(WebcamProcessor.java:81) ~[Sarxos_webcam-capture-0.x.jar:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_91]

_

and this is the log when it pass:

2018-09-13 11:33:20.0171 PDT  (ForkJoinPool.commonPool-worker-3) [DEBUG]: com.github.sarxos.webcam.WebcamLock - Lock Webcam USB 2.0 Camera /dev/video0
2018-09-13 11:33:20.0175 PDT  (atomic-processor-1) [INFO]: com.github.sarxos.webcam.ds.cgt.WebcamOpenTask - Opening webcam USB 2.0 Camera /dev/video0
2018-09-13 11:33:20.0175 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Opening webcam device USB 2.0 Camera /dev/video0
2018-09-13 11:33:20.0176 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Webcam device /dev/video0 starting session, size java.awt.Dimen
sion[width=1280,height=720]

2018-09-13 11:33:20.0913 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Webcam device session started
2018-09-13 11:33:20.0914 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Clear memory buffer
2018-09-13 11:33:21.0118 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Webcam device com.github.sarxos.webcam.ds.buildin.WebcamDefault
Device@540994ce is now open
2018-09-13 11:33:21.0119 PDT  (ForkJoinPool.commonPool-worker-3) [DEBUG]: com.github.sarxos.webcam.Webcam - Webcam is now open USB 2.0 Camera /dev/video0
2018-09-13 11:33:21.0152 PDT  (ForkJoinPool.commonPool-worker-3) [INFO]: com.hardware.device.camera.ImageCameraDeviceImpl - Image is clicked!
2018-09-13 11:33:21.0152 PDT  (ForkJoinPool.commonPool-worker-3) [DEBUG]: com.github.sarxos.webcam.Webcam - Closing webcam USB 2.0 Camera /dev/video0
2018-09-13 11:33:21.0181 PDT  (atomic-processor-1) [INFO]: com.github.sarxos.webcam.ds.cgt.WebcamCloseTask - Closing USB 2.0 Camera /dev/video0
2018-09-13 11:33:21.0181 PDT  (atomic-processor-1) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDevice - Closing webcam device
2018-09-13 11:33:21.0366 PDT  (ForkJoinPool.commonPool-worker-3) [DEBUG]: com.github.sarxos.webcam.WebcamLock - Unlock Webcam USB 2.0 Camera /dev/video0
2018-09-13 11:33:21.0367 PDT  (webcam-lock-[USB 2.0 Camera /dev/video0]) [DEBUG]: com.github.sarxos.webcam.WebcamLock - Lock updater has been interrupted
2018-09-13 11:33:21.0368 PDT  (ForkJoinPool.commonPool-worker-3) [DEBUG]: com.github.sarxos.webcam.Webcam - Webcam USB 2.0 Camera /dev/video0 has been closed
2018-09-13 11:33:21.0505 PDT  (ForkJoinPool.commonPool-worker-3) [INFO]: com.hardware.device.camera.ImageCameraDeviceImpl - Image is saved to filesystem!
2018-09-13 11:33:21.0525 PDT  (ForkJoinPool.commonPool-worker-3) [INFO]: com.hardware.device.camera.ImageCameraDeviceImpl - Total time taken to click and process image: 1343 
millisec.
2018-09-13 11:33:22.0941 PDT  (webcam-discovery-service) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver - Searching devices
2018-09-13 11:33:22.0945 PDT  (webcam-discovery-service) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver - Found device USB 2.0 Camera /dev/video0
2018-09-13 11:33:25.0945 PDT  (webcam-discovery-service) [DEBUG]: com.github.sarxos.webcam.ds.buildin.WebcamDefaultDriver - Searching devices