FrameGrabber.startCapture dying Logitech C920 , Ubuntu 12.04

48 views
Skip to first unread message

sami...@gmail.com

unread,
Jul 14, 2013, 1:44:05 AM7/14/13
to v4...@googlegroups.com

Running build from the trunk version,

I built a small test gui based on the simple viewer code, just added extra start capture
and stop capture on the window iconified , deiconified methods.

I have a frame grabber from the below line
videoDevice.getJPEGFrameGrabber(640, 480, 0, V4L4JConstants.STANDARD_WEBCAM, 80);

on window iconified i stop capture , and on window deiconified i start capture

As long as i dont minimize the window the video stream is good.

on the release build after minimizing the window and then maximising after 20 -30 seconds
i get a V4L4JException, some time this happens on the first maximise, some time on the second
. I was never able to go beyond two maximise.

build the debug version no it always throws V4L4JException on the first maximize, note if i dont
minimize the window then video works fine....

Attached logs from debug runs
frame start error.txt

Gilles Gigan

unread,
Jul 14, 2013, 9:01:45 PM7/14/13
to v4...@googlegroups.com
Can you send the code you are using to start/stop capture on window minimise/maximise.
Thanks



--
You received this message because you are subscribed to the Google Groups "v4l4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v4l4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Gilles Gigan

unread,
Jul 16, 2013, 3:43:20 AM7/16/13
to v4...@googlegroups.com
Hi,
I have committed a potential fix for this issue. Can you update your trunk working copy, rebuild and reinstall v4l4j and try again. Let me know if it is fixed.
Thanks
Gilles

sami...@gmail.com

unread,
Jul 16, 2013, 9:59:37 PM7/16/13
to v4...@googlegroups.com
incomplete post earlier
below is a cut copy code after removing all the other unnecessary stuff (may have some compile issue)
if you notice i create the video device and the frame grabber in the constructor
and when the window is iconified / deiconified , start / stop capture method of
frame grabber is called, the video device and frame grabber is released only on
window closing.

in your example on start or stop button press the video device and the frame grabber is being
released completely, that is the only difference i could observe.

will test the trunk and post back a reply...


public class Viewer implements  WindowListener , CaptureCallback
{
   String deviceName = "/dev/video0";
   private int    width, height, std, channel;
   VideoDevice videoDevice;
   FrameGrabber    frameGrabber;
   JFrame topFrame;
   JLabel imgLabel;

    public Viewer()
    {
        width    = 640;
        height    = 480;
        std        = V4L4JConstants.STANDARD_WEBCAM;
        channel    = 0;
       
        try
        {
            videoDevice = new VideoDevice(deviceName);
            frameGrabber = videoDevice.getJPEGFrameGrabber(width, height, channel, std, 80);   
            frameGrabber.setCaptureCallback(this);
            width = frameGrabber.getWidth();
            height = frameGrabber.getHeight();       


            topFrame = new JFrame();
            imgLabel = new JLabel();
           
            topFrame.getContentPane().setLayout(new BorderLayout(10,10));
            topFrame.getContentPane().add(imgLabel,BorderLayout.CENTER);
            topFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            topFrame.addWindowListener(this);
            topFrame.setVisible(true);
            topFrame.setSize(width, height);
           
            frameGrabber.startCapture();
        }
        catch (V4L4JException e)
        {
            System.out.println("Excepion during creating video device");
            e.printStackTrace();
        }

       
       
    }

    @Override
    public void windowActivated(WindowEvent arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Window activated");
    }

    @Override
    public void windowClosed(WindowEvent arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Window closed");       
    }

    @Override
    public void windowClosing(WindowEvent arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Window closing");
        try
        {
            frameGrabber.stopCapture();
        }
        catch (StateException ex)
        {
            // the frame grabber may be already stopped, so we just ignore
            // any exception and simply continue.
        }
         
        // release the frame grabber and video device
        videoDevice.releaseFrameGrabber();
        videoDevice.release();

    }

    @Override
    public void windowDeactivated(WindowEvent arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Window deactivated");
    }

    @Override
    public void windowDeiconified(WindowEvent arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Re Starting grabber");
       
        if(frameGrabber != null)
        {
            try
            {
                frameGrabber.startCapture();
            }
            catch (V4L4JException e)
            {
                // TODO Auto-generated catch block
                System.out.println("Exceptio during Starting grabber");
                e.printStackTrace();
            }
        }
    }

    @Override
    public void windowIconified(WindowEvent arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Stopping grabber");
       
        if(frameGrabber != null)
        {
                frameGrabber.stopCapture();
        }
    }

    @Override
    public void windowOpened(WindowEvent arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Window opened");
       
    }

    @Override
    public void exceptionReceived(V4L4JException arg0)
    {
        // TODO Auto-generated method stub
        System.out.println("Exception during capture");
    }

    @Override
    public void nextFrame(VideoFrame frame)
    {
        // TODO Auto-generated method stub
        //check if we need to close the grab
        //System.out.println("Received frame");
        imgLabel.getGraphics().drawImage(frame.getBufferedImage(), 0, 0, width, height, null);
        //imp.setImage(frame.getBufferedImage());
        //imp.updateAndDraw();
        frame.recycle();
    }

}

sami...@gmail.com

unread,
Jul 16, 2013, 10:57:35 PM7/16/13
to v4...@googlegroups.com
the behaviour has improved slightly with new trunk build
however after a few window activated/deactivated it dies agin

this time i have observed that it throws a bunch of java state exception
complaining that the grabber object is not instanciated, which is contrary
to what is happening in code.

i am on ubuntu 12.04 and attached is a good java class that should be able
to replicate the problem.

all you need to do is instantiate LiveView (it will start its own thread) and call start()
look at the first two lines in the java file attached
A new window displays video from camera, minimize and maximize this window  alternatively
give a gap of few seconds between each operation.
LiveView.java

Gilles Gigan

unread,
Jul 16, 2013, 11:01:33 PM7/16/13
to v4...@googlegroups.com
thanks, let me look into it.

Gilles


Gilles Gigan

unread,
Jul 17, 2013, 7:40:17 AM7/17/13
to v4...@googlegroups.com
You made a few unnecessary calls in your LiveView class, and end up calling frameGrabber.startCapture()/stopCapture() more than once in a row which is why you received these StateExceptions: the first call effectively starts/stops the capture and the following ones throw the exception !
Only call startGrab() at the end of the constructor and in windowDeiconified() and remove all other invocations. Similarly, only call stopGrab() in windowIconified() and windowClosing().

I have also modified the au.edu.jcu.v4l4j.examples.SimpleViewer class to demonstrate how to do what you mentioned (stop capture when minimised and start capture when maximised), so you can look at this class too as a guide.

Gilles

sami...@gmail.com

unread,
Jul 17, 2013, 10:28:44 AM7/17/13
to v4...@googlegroups.com
Thanks Gilles

I will take a look at your Simpleviewer class,

just a quick question though can a method call be provided in Framegrabber interface allowing query of state

i.e.  FrameGrabber.isCapturing() return true if capture is ON else false....

ofcourse user app could also keep a flag to trace the state, but it is much better if FrameGrabber it self can provide that
information.

Regards

Gilles Gigan

unread,
Jul 17, 2013, 6:44:22 PM7/17/13
to v4...@googlegroups.com
Inherently, a FrameGrabber.getState() method would not be thread-safe:  there is absolutely no guarantee that the state returned by getState() is still valid by the time your application reads it and takes a decision based on it, unless your application ensures access to a frame grabber instance is serialised, ie. the frame grabber's state wont be changed by other threads while calling frameGrabber.getState().
In my opinion, it would be easier to ensure all possible call sequences are valid (one call to startCapture() can only be followed by a call to stopCapture() in your example) than to synchronise access to a frame grabber. Of course, this might not be possible all the time, but in your case I think it is.
If you decide to go the serialisation route, I would just create a single method similar to the toggleCapture() method below, and call it when you need to start or stop the capture.

class LiveView
{
    private bool captureStarted;

    public LiveView(...)
    {
        // constructor
        ....
        captureStarted = false;
        ...
    }
 
   // call with startCapture set to true to start the capture, false to stop it
   void synchronized toggleCapture(bool startCapture)
   {
        // if we want to start the capture, but it is already started OR
       // if we want to stop it and it is already stopped, do nothing
        if ((startCapture == captureStarted) || (frameGrabber == null))
          return;
 
       try {
           if (startCapture)
              frameGrabber.startCapture();
           else
              frameGrabber.stopCatpture();

           captureStarted = startCapture;
       } catch (V4L4JException e) {
            e.printStackTrace();
       }
   }

    public void windowActivated(WindowEvent arg0)
    {
        toggleCapture(true);
    }

    public void windowClosing(WindowEvent arg0)
    {
        toggleCapture(false)

         
        // release the frame grabber and video device
        videoDevice.releaseFrameGrabber();
        videoDevice.release();

    }

    public void windowDeactivated(WindowEvent arg0)
    {
        toggleCapture(false);
    }

    public void windowDeiconified(WindowEvent arg0)
    {
        toggleCapture(true);
    }

   public void windowIconified(WindowEvent arg0)
    {
        toggleCapture(false);
    }

}

Hope this helps
Gilles

sami...@gmail.com

unread,
Jul 18, 2013, 1:03:20 AM7/18/13
to v4...@googlegroups.com
I have implemented a gatekeeper state similar to your toggle method above and everything works well now.

Thanks again for all the help.
Reply all
Reply to author
Forward
0 new messages