SmartDashboard CameraServer output Flickering

The goal of my code is to be able to switch between vision processing from one camera to another camera.

I have created 2 vision threads, either one or the other is started at one time.
On the SmartDashboard, the camera shows for about a second at 1 fps and 6mbps, then turns off, and repeats. I cannot figure out the issue. Here is the code


		/*
		 * Sync vision variables from thread to thread.
		 */
		imgLockGoal = new Object();
		imgLockGear = new Object();

		/*
		 * Image used to be processed by a CvSink and outputted through a
		 * CvSource.
		 */
		image = new Mat();

		/*
		 * Camera used to track vision targets on the boiler.
		 */
		cam0 = new UsbCamera("cam0", 0);
		cam0.setResolution(camWidth, camHeight);
		cam0.setFPS(16);

		/*
		 * Camera used to track vision targets on the airship.
		 */
		cam1 = new UsbCamera("cam1", 1);
		cam1.setResolution(camWidth, camHeight);
		cam1.setFPS(16);

		/*
		 * CvSink used to grab and process the image used to output to the
		 * CvSource
		 */
		selectedVid = CameraServer.getInstance().getVideo(cam0);

		/*
		 * CvSource used to output the processed image onto the SmartDashboard
		 * (CameraServer Stream Viewer).
		 */
		outputStream = CameraServer.getInstance().putVideo("Tracking", camWidth, camHeight);

		/*
		 * Vision Thread uses the high goal contour filtering to find the best
		 * targets and help lead the robot to the target destination.
		 */
		visionThreadHighGoal = new VisionThread(cam0, new VisionClass(), pipeline -> {
			selectedVid.grabFrame(image);
			if (pipeline.filterContoursOutput().size() >= 2) {
				//isTargetFound = true;
				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),
						new Scalar(0, 0, 255), 2);
				Imgproc.rectangle(image, new Point(r1.x, r1.y), new Point(r1.x + r1.width, r1.y + r1.height),
						new Scalar(0, 0, 255), 2);
				outputStream.putFrame(image);
				synchronized (imgLockGoal) {
					centerX = (r.x + (r1.x + r1.width)) / 2;
					width = (r.x + r1.x) / 2;
				}
			} else {
				synchronized (imgLockGoal) {
					//isTargetFound = false;
				}
				outputStream.putFrame(image);
			}
		}); visionThreadHighGoal.start();

		// TODO: change filters to specify for gears
		/*
		 * Vision Thread uses the gear contour filtering to find the best
		 * targets and help lead the robot to the target destination.
		 */
		
		visionThreadGear = new VisionThread(cam1, new VisionClass(), pipeline -> {
			selectedVid.grabFrame(image);
			if (pipeline.filterContoursOutput().size() >= 2) {
				isTargetFound = true;
				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),
						new Scalar(0, 0, 255), 2);
				Imgproc.rectangle(image, new Point(r1.x, r1.y), new Point(r1.x + r1.width, r1.y + r1.height),
						new Scalar(0, 0, 255), 2);
				synchronized (imgLockGear) {
					// TODO:
				}
			} else {
				synchronized (imgLockGear) {
					isTargetFound = false;
				}
			}
		});

Thanks!