CameraServer - is anyone watching?

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()
cs.enableLogging()
csSource = cs.putVideo("Jetson", STREAM_WIDTH, STREAM_HEIGHT)

while True:
  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, 
format=img.format)
  jetson.utils.cudaResize(img, smallImg)
  bgrSmallImg = jetson.utils.cudaAllocMapped(width=STREAM_WIDTH, height=STREAM_HEIGHT, format="bgr8")
  jetson.utils.cudaConvertColor(smallImg, bgrSmallImg)
  jetson.utils.cudaDeviceSynchronize()
  numpyImg = jetson.utils.cudaToNumpy(bgrSmallImg, STREAM_WIDTH, STREAM_HEIGHT, 4)

  csSource.putFrame(numpyImg)

There’s no way currently to do this, but why not do it all the time?

I think he was wanting to save processing and improve inference rates by not doing those steps if no one was watching.

1 Like

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.

1 Like

@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.

3 Likes

This doesn’t appear to be available in robotpy. :frowning:

Looking at the robotpy-cscore sources, you’re correct. Time to file an issue or PR there…

1 Like

Fixed in robotpy-cscore 2022.0.3

2 Likes

Thanks @virtuald , that was fast! How do I get the latest release for my Jetson (without building it myself?) In the Ubuntu 18.04 ports repo the latest I’m seeing is 2121.0.2-1.

1 Like

I would talk to whomever maintains the ports repo, I don’t maintain it. Maybe @auscompgeek ?

If @gdefender is referring to my openSUSE Build Service repo, that’d be me. I can’t guarantee I can get out a working package for Ubuntu 18.04 though. I’ll see what I can do after work in a few hours.

Seems like they found a solution:

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!

Ah yeah, that reminds me, I’ve been meaning to add https://github.com/conda-forge/robotpy-cscore-feedstock to that page too. I’m not entirely sure that would’ve been easier for you anyway though.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.