-
Notifications
You must be signed in to change notification settings - Fork 18
Spout Send & Receive #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spout Send & Receive #213
Conversation
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
… API, framerates. Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
9b027ac to
8d652ee
Compare
src/scope/spout/sender.py
Outdated
| try: | ||
| # Convert torch tensor to numpy if needed | ||
| if isinstance(frame, torch.Tensor): | ||
| frame = frame.detach().cpu().numpy() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My best guess on what is causing the perf hit/slowdown is that it is this movement of each frame to host CPU mem. SpoutGL might ultimately convert the numpy array into a texture in GPU mem that is shared to the receiver (I haven't looked into what it does under the hood yet), but if we are doing a CPU mem transfer here I suspect that would cause non-negligible overhead as that is typically slow especially in the scenario where we have many frames per second.
Ideally, we'd be able to keep the tensor (frame) in GPU mem (CUDA) the entire time. With SpoutGL, perhaps what we need is to convert that frame into a OpenGL texture while keeping it in GPU mem the entire time. I searched around and while it doesn't seem trivial it seems doable. A couple links I encountered that seem relevant:
https://gist.github.com/victor-shepardson/5b3d3087dc2b4817b9bffdb8e87a57c4
https://dev-discuss.pytorch.org/t/opengl-interoperability/2696
https://documen.tician.de/pycuda/gl.html
But...
Should first confirm that this is actually the cause by profiling how much time is getting eaten up by the steps taken her eg transfer to CPU mem + the send call that takes the numpy array.
After a second thought, it does seem a bit weird that the memory transfer on its own cause such a noticeable perf hit (as shown in the video attached in my other comment) because the WebRTC flow also involves a GPU -> CPU mem transfer in order for the frames to be encoded into a video stream. And the WebRTC video is much smoother than the Spout output in TD right now. So, the memory transfer might still be slowing things down, but there might be a bigger issue somewhere else that is the primary cause of the Spout output in TD being more choppy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great find - slipped over this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah so there mem transfer is still incurring overhead, but I believe the real cause of the perf hit is described in this comment.
2025-12-03.20-48-35.mp4Noting that there is def a perf hit right now when sending via Spout and receiving in TD - see the above video. And see my other comment on my guess as to where the hit may be happening. |
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
eba7c47 to
09ce39a
Compare
yondonfu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good!
I mentioned this in a comment, but generally WDYT about using the Spout Sender/Receiver naming convention everywhere instead of Spout Input/Output since the former seems to be the convention in other apps too so we could follow that in the UI as well as in var naming in the code to match?
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
…d default output name, added Windows detection in UI. Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
Signed-off-by: BuffMcBigHuge <marco@bymar.co>
yondonfu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still some visual changes that didn't make it in, but LGTM for now and going to fixup on main.
Spout Send & Receive
This PR adds bidirectional Spout support to Scope, enabling real-time video texture sharing with Spout-compatible applications like TouchDesigner, OBS, and other Windows-based media tools.
Overview
Spout is a Windows-only protocol for sharing OpenGL textures between applications with minimal latency. This implementation adds both Spout input (receiving frames from external apps) and Spout output (sending processed frames to external apps).
Features
Spout Input (Receiver)
Spout Output (Sender)
Technical Details
SpoutGLandpyopengl(optional, gracefully handled if missing)[0, 255]or float[0, 1]Usage
Receiving from Spout (Input)
Sending to Spout (Output)
Screen.Recording.2025-12-02.200831_10mb.mp4