Note that there are some explanatory texts on larger screens.

plurals
  1. POJMF: Setting FPS for webcam
    primarykey
    data
    text
    <p>I have a webcam (actually 3) and java program to capture the frames. However, I have yet to find a way to set the FPS. For example, when I'm setting the FPS using a new <code>VideoFormat</code> and I can see that it is correctly applied by <code>camFormat.intersects(newFormat)</code>. However, when I get frames from the camera (either by the <code>BufferTransferHandler</code> or by manually fetching), I get more frames than the selected FPS.</p> <p>Is there perhaps a way to poll if a new frame is ready?</p> <p><strong>I found a little more information, so I'm editing this. It seems the source of the problems is the Microsoft WDM Image Capture driver. In VirtualDub capture mode, I can select each separate webcam and I can select WDM. When I select WDM, I get the same options as in the <em>Custom Format</em> dialog in JFM, and it doesn't capture at full FPS either. However,</strong> <code>CaptureDeviceManager.getDeviceList</code> <strong>seems to only return the WDM driver and not the individual webcams (and two microphones inside webcams but not the sound card microphone). Why is this?</strong></p> <p>It strikes me odd that I can specify the framerate, but I can't find a way to actually enforce it, even after days of searching the internet and trying different example code. Every example I find will just either request frames at its own pace or not care about fps at all.</p> <p>My test class:</p> <p>Run, use the top button to (re)open the Format Control window (internal to JMF), and try to change the fps. It's also odd that besides the non-functional fps field, other fields like the resolution field are also non-functional (as it is overridden by the resolution field in the "Custom Format..." window.</p> <pre><code>import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.image.BufferedImage; import java.util.Vector; import javax.media.Buffer; import javax.media.CaptureDeviceInfo; import javax.media.CaptureDeviceManager; import javax.media.ControllerAdapter; import javax.media.ControllerClosedEvent; import javax.media.ControllerErrorEvent; import javax.media.Manager; import javax.media.MediaLocator; import javax.media.Player; import javax.media.RealizeCompleteEvent; import javax.media.StartEvent; import javax.media.StopEvent; import javax.media.control.FormatControl; import javax.media.control.FrameGrabbingControl; import javax.media.format.FormatChangeEvent; import javax.media.format.VideoFormat; import javax.media.format.YUVFormat; import javax.media.util.BufferToImage; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JOptionPane; public class CaptureTest extends JComponent implements ActionListener, WindowListener, Runnable { public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { new CaptureTest(); } }; EventQueue.invokeLater(r); } Player player; FrameGrabbingControl grabber; FormatControl formatControl; final JFrame frame; public Image image; public CaptureTest() { setLayout(new BorderLayout()); Vector&lt;?&gt; deviceVector = CaptureDeviceManager.getDeviceList(new YUVFormat()); final CaptureDeviceInfo[] deviceList = new CaptureDeviceInfo[deviceVector.size()]; for (int i = 0; i &lt; deviceList.length; i++) { deviceList[i] = (CaptureDeviceInfo)deviceVector.get(i); System.out.println("Capture Device found: " + deviceList[i].getName()); } frame = new JFrame("Capture test"); frame.addWindowListener(this); { JButton b = new JButton("Format Control"); b.setEnabled(true); b.addActionListener(this); frame.add(b, BorderLayout.NORTH); } { setPreferredSize(new Dimension(640, 480)); frame.add(this, BorderLayout.CENTER); } ControllerAdapter cl = new ControllerAdapter() { @Override public void realizeComplete(RealizeCompleteEvent rce) { formatControl = (FormatControl)player.getControl("javax.media.control.FormatControl"); grabber = (FrameGrabbingControl)player.getControl("javax.media.control.FrameGrabbingControl"); Component co = formatControl.getControlComponent(); if (co != null) { player.stop(); JDialog d = new JDialog(frame, "Format Control", true); d.add(co); d.pack(); d.setLocationRelativeTo(frame); d.setVisible(true); d.dispose(); player.start(); } System.out.println("realizeComplete: " + formatControl.getFormat()); } @Override public void formatChange(FormatChangeEvent fce) {} @Override public void start(StartEvent se) {} @Override public void stop(StopEvent se) {} @Override public void controllerError(ControllerErrorEvent cee) { System.err.println(cee.getMessage()); System.err.println("Caused by: " + cee.getSource()); System.exit(0); } @Override public void controllerClosed(ControllerClosedEvent cce) {} }; MediaLocator ml = deviceList[0].getLocator(); try { Manager.setHint(Manager.PLUGIN_PLAYER, Boolean.TRUE); player = Manager.createPlayer(ml); player.addControllerListener(cl); player.start(); } catch (Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(frame, "Could Not Create Player", "ERROR", JOptionPane.ERROR_MESSAGE); } frame.pack(); frame.setVisible(true); new Thread(this).start(); } public void grab() { if (grabber == null) return; Buffer buf = grabber.grabFrame(); // System.out.println(fps.getFPS() + "\t" + buf.getFormat()); BufferToImage b2i = new BufferToImage((VideoFormat)buf.getFormat()); BufferedImage bi = (BufferedImage)b2i.createImage(buf); if (bi != null) { setImage(bi); repaint(); } } public void setImage(Image im) { image = im; Dimension size = new Dimension(im.getWidth(null), im.getHeight(null)); setPreferredSize(size); setSize(size); } @Override public void paintComponent(Graphics g) { if (image != null) g.drawImage(image, 0, 0, this); } @Override public void run() { while (true) { grab(); Thread.yield(); } } @Override public void actionPerformed(ActionEvent e) { Component co = formatControl.getControlComponent(); if (co != null) { player.stop(); JDialog d = new JDialog(frame, "Format Control", true); d.add(co); d.pack(); d.setLocationRelativeTo(frame); d.setVisible(true); d.dispose(); player.start(); } } @Override public void windowOpened(WindowEvent e) {} @Override public void windowClosing(WindowEvent we) { if (player != null) { player.stop(); player.close(); } System.exit(0); } @Override public void windowClosed(WindowEvent e) {} @Override public void windowIconified(WindowEvent e) {} @Override public void windowDeiconified(WindowEvent e) {} @Override public void windowActivated(WindowEvent e) {} @Override public void windowDeactivated(WindowEvent e) {} } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload