Skip to content

bug in parseCaps #224

Open
Open

Description

@clankill3r

I need to get the resolution of the webcam. In the source we have the following:

  // This is a temporary addition until it's decided how to bring back resolution/framerate caps to the official API.
  // The old way of doing things is still listed in the video tutorial:
  // https://processing.org/tutorials/video
  static public String[] getCapabilities(String device) {
    for (int i=0; i < devices.size(); i++) {
      String deviceName = assignDisplayName(devices.get(i), i);
      if (devices.get(i).getDisplayName().equals(device) || devices.get(i).getName().equals(device) || deviceName.equals(device)) {
        return parseCaps(devices.get(i));
      }
    }
    return new String[]{};
  }

The above calls parseCaps which has the following part (this is a piece of it):

      if (0 < indexWidth && 0 < indexHeight && 0 < indexFramerate) {
        stringWidth = cap.substring(indexWidth, cap.indexOf(',', indexWidth));
        stringHeight = cap.substring(indexHeight, cap.indexOf(", format", indexHeight));
        stringFramerate = cap.substring(indexFramerate, cap.indexOf(']', indexFramerate));
      }

An example of the String cap is " video/x-raw, format=(string)YUY2, width=(int)1280, height=(int)720, framerate=(fraction)10/1, pixel-aspect-ratio=(fraction)1/1".

The problem with the above code is that stringHeight = cap.substring(indexHeight, cap.indexOf(", format", indexHeight)); assumes a certain order of the elements being listed. The assumption being made is wrong resulting in the following error:

java.lang.StringIndexOutOfBoundsException: begin 52, end -1, length 127
        at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4606)
        at java.base/java.lang.String.substring(String.java:2709)
        at processing.video.Capture.parseCaps(Capture.java:791)
        at processing.video.Capture.getCapabilities(Capture.java:768)
        at room_activity.Room_Activity.setup(Room_Activity.java:95)
        at processing.core.PApplet.handleDraw(PApplet.java:2051)
        at processing.opengl.PSurfaceJOGL$DrawListener.display(PSurfaceJOGL.java:840)
        at jogamp.opengl.GLDrawableHelper.displayImpl(GLDrawableHelper.java:692)
        at jogamp.opengl.GLDrawableHelper.display(GLDrawableHelper.java:674)
        at jogamp.opengl.GLAutoDrawableBase$2.run(GLAutoDrawableBase.java:443)
        at jogamp.opengl.GLDrawableHelper.invokeGLImpl(GLDrawableHelper.java:1293)
        at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:1147)
        at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:797)
        at com.jogamp.opengl.util.AWTAnimatorImpl.display(AWTAnimatorImpl.java:81)
        at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:471)
        at com.jogamp.opengl.util.FPSAnimator$MainTask.run(FPSAnimator.java:245)
        at java.base/java.util.TimerThread.mainLoop(Timer.java:566)
        at java.base/java.util.TimerThread.run(Timer.java:516)

Activity

  1. glvjr commented on May 4, 2026

    @glvjr

    Hello,

    This was used to read the camera capability data from Processing Video’s internal device list:

    import processing.video.*;
    
    import java.lang.reflect.*;
    import java.util.*;
    
    void setup() 
      {
      try 
        {
        String[] cameras = Capture.list();
        printArray(cameras);
        println();
        
        // This failed:
        // println(Capture.getCapabilities(cameras[0]));
        // Related issue:
        // https://github.com/processing/processing-video/issues/224
    
        Field f = Capture.class.getDeclaredField("devices");
        f.setAccessible(true);
        
        List devices = (List) f.get(null);
    
        Object dev = devices.get(0);
        Method m = dev.getClass().getMethod("getCaps");
    
        println("Camera 0: " + cameras[0]);
        println();
    
        String modes = String.valueOf(m.invoke(dev));
       
        String formattedModes = modes.replace(";", ";\n");
        println(formattedModes);
        }
      catch (Exception e) 
        {
        e.printStackTrace();
        }
      }
    
    /*
    Capture.getCapabilities(cameras[0]) failed with:
    
    java.lang.StringIndexOutOfBoundsException: begin 49, end -1, length 133
      at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4606)
      at java.base/java.lang.String.substring(String.java:2709)
      at processing.video.Capture.parseCaps(Unknown Source)
      at processing.video.Capture.getCapabilities(Unknown Source)
      at sketch_260503a.setup(sketch_260503a.java:38)
      at processing.core.PApplet.handleDraw(PApplet.java:2055)
      at processing.awt.PSurfaceAWT$9.callDraw(PSurfaceAWT.java:1388)
      at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:356)
    */

    It was a long list so test was for one camera only.

    My research started here:
    https://discourse.processing.org/t/capture-list-showing-duplicate-cameras/47153

    Developed through research, testing, and input from various AI tools.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions