I have a python script where I am doing object detection on an nvidia Jetson. I have an RGB image on the GPU with objects labeled and I am to streaming it to the driver station for debug purposes with CameraServer. I have this working by resizing and converting the image to BGR and then calling csSource.putFrame().
I am wondering if there is any way to know if anyone is connected to the MjpegServer. If nobody is watching, there is no need to do the scaling and color conversion.
Here is a partial snippet of code to demonstrate what I’m doing (this code is incomplete.)
# Set up CameraServer
cs = CameraServer.getInstance()
csSource = cs.putVideo("Jetson", STREAM_WIDTH, STREAM_HEIGHT)
img = camera.Capture()
detections = detectNet.Detect(img, overlay='conf')
# ***** Can I check if anyone is watching the MjpegServer before doing this work?
smallImg = jetson.utils.cudaAllocMapped(width=STREAM_WIDTH, height=STREAM_HEIGHT,
bgrSmallImg = jetson.utils.cudaAllocMapped(width=STREAM_WIDTH, height=STREAM_HEIGHT, format="bgr8")
numpyImg = jetson.utils.cudaToNumpy(bgrSmallImg, STREAM_WIDTH, STREAM_HEIGHT, 4)
Sure, but if you can’t keep up when someone’s watching, why bother doing it at all?
In general, I would recommend turning this behavior on and off via a dashboard control over networktables.
That said, there’s not a real reason why the API couldn’t be extended to give you the number of clients, the information exists somewhere. File a bug at https://github.com/wpilibsuite/allwpilib if you think there’s a good reason to provide that information.
@Bmongar That’s exactly right, I want to avoid the processing when I don’t need it.
@virtuald It is able to keep up when someone is watching. The image processing is very fast, only a few milliseconds, so it has minimal impact on fps. But, I don’t expect anyone will be watching during a match, and that is when fps matters most.
We certainly can find alternate solutions, like sending a NetworkTable value to turn streaming on and off. Knowing if anyone is watching would have been a quick and direct solution.
Yes, there is a way. You can use VideoSource.isEnabled() (VideoSource is a base class of CvSource). This returns true only if there is someone watching, assuming that the video source ConnectionStrategy is kAutoManage (which is is by default).
So in your code, you should be able to just call csSource.isEnabled() to get the info you’re looking for.
A bit of info on how this works under the hood: cscore has the concept of sources and sinks and connectivity between them within cscore. CvSource is a source, MjpegServer is a sink. CameraServer.putVideo() is a convenience function that creates both a CvSource and a MjpegServer and sets the CvSource as the source for the MjpegServer. Each source keeps track of how many sinks connected to it are actively consuming frames, and in the MjpegServer case, it is only active if there is at least one client connected.
Yes, that was the repo I was referring to. The robotpy docs say that’s how to install on Linux. As Peter noted, I found a solution to get it building/installing with pip so I’m good to go now. Thanks guys for a quick solution!