Create a thread instead of using VisionThread?

I’ve been doing a lot of research about roboRio performance when handling vision processing, 2 cameras, and the rest of a robot program. I’ve been suggested to use a coprocessor if I want fast speeds, but I still think the roboRio will be able to handle the tasks.

Switching from camera to camera and using vision processing on both one at a time has made this tricky. The most obvious solution that came to mind was to create 2 VisionThreads, and switch between them one at a time using a boolean. This works, but It seems sloppy and would most likely lead to performance issues.

What I’m currently working on is using a Thread and one pipeline to process images from the 2 cameras, again, using a boolean. The problem I’m facing is using the pipeline.process method. I’m able to switch the cameras very quickly without error with this code, but once : if (pipeline.filterContoursOutput().size() >= 2) is true, then I get “too many simultaneous client streams”. I found that this happens when the outputStream does not receive any new frames (I don’t know if thats the actual cause but it seems to be based off of testing). Is there a different way I should approach the way this thread is structured? Here is the code


	new Thread(() -> {
			/*
			 * The colors that the rectangles will be set to 
			 * Default: red
			 */
			double] red = { 0, 0, 255 };
			double] green = { 0, 255, 0 };
			Scalar color = new Scalar(red);

			while (!Thread.interrupted()) {
				if (whichCam) {
					vid1.grabFrame(image);
					//
				} else {
					vid2.grabFrame(image);
				}
				SmartDashboard.putString("Contours?", "false");
				if (pipeline.filterContoursOutput().size() >= 2) {
					SmartDashboard.putString("Contours?", "true");
					if (!isTargetFound) {
						color.set(red);
					} else {
						color.set(green);
					}
					Rect r = Imgproc.boundingRect(pipeline.filterContoursOutput().get(0));
					Rect r1 = Imgproc.boundingRect(pipeline.filterContoursOutput().get(1));
					Imgproc.rectangle(image, new Point(r.x, r.y), new Point(r.x + r.width, r.y + r.height), color, 2);
					Imgproc.rectangle(image, new Point(r1.x, r1.y), new Point(r1.x + r1.width, r1.y + r1.height), color,
							2);
					outputStream.putFrame(image);
					synchronized (imgLock) {
						if (!isTurning) {
							centerX = r.x + (r.x + r.width) / 2;
						}
						width = r.width;
					}
				} else {
					synchronized (imgLock) {
						centerX = 0.0;
						width = 0.0;
						isTargetFound = false;
					}
					outputStream.putFrame(image);
				}
				try {
					Thread.sleep(10);
				} catch (Exception e) {

					e.printStackTrace();
				}
			}

		}).start();

And here is what I’m doing to switch cameras (if it matters)


	// Switch camera streams.
	public void switchCams() {
		if (whichCam) {
			whichCam = false;
			Timer.delay(0.25);
		} else {
			whichCam = true;
			Timer.delay(0.25);
		}
	}

Thanks!