February 23, 2018 at 7:46 pm #3835
I am trying to use spout in a multi-threaded scenario. In my specific setup I have thread for each receiver and I am trying to read from the spouts concurrently. I tried it as shown in the code below (along with a few other configurations) and found that I got many different run-time errors. Sometimes Receivers would fail to create, other times they would fail to receive image after successfully being created. Does spout not support this access pattern? If not is there something I can do to make it work in a similar way?
-MattFebruary 24, 2018 at 6:38 am #3836
This should work. I started a similar project a while back but never finished it, so I don’t have a great deal of experience with threads, but I hope I can help a little.
I notice that an OpenGL window is created for each receiver. It could be that a separate OpenGL context is needed for each new thread or that a shared context needs to be set up but I am not sure. In any case there will possibly be trouble because all the windows will have the same name “SpoutOpenGL”. A single OpenGL context would be simple, but it would be necessary for an OpenGL context that exists when a thread is created to be available within the thread. Also it might be safer to create the spoutreceiver object after the OpenGL context is created.
Presumably you want to connect with each sender called “Test1″, Test2” etc. In that case CreateReceiver will only succeed when that particular sender is running. But I see a new flag “bool flag = true;” which is the one passed to the thread. I would have set it up with both the receiver creation and ReceiveImage in the thread itself. Then you can release the receiver if the sender closed and the read fails. Also if the senders are likely to change size you could handle it here.
Access to each sender texture and name shared memory will already be protected by mutexes so that should be OK with multiple threads.
That’s about all I can think of right now. It would be useful to know the errors you see. If they are OpenGL errors, you can use spoutGLDXinterop::GLerror() to find out what they are.February 26, 2018 at 6:12 pm #3841
Things tend to be working better once I created the Receiver in the thread. However not perfect. There seems to be a memory leak somewhere relating to the continuous setup and release of spout. The code below when run quickly uses up all the system memory.
As an aside is there any resources about how to setup a shared opengl context for all the threads? Or perhaps there is a small code snip-it you could share that sets up two receivers with the same context given that wglGetCurrentContext() when called from a separate thread returns NULL?
Thanks so much for your help and support. This is an awesome project!
Memory Leak code: https://gist.github.com/anonymous/ec7aebdcf5202d40724ae528c86ead3dFebruary 27, 2018 at 12:18 am #3842
It is most likely that the leak is on the OpenGL window creation. This will still create multiple windows with the same name. Possibly they are not destroyed properly. I don’t have time right now to trace through it but will keep this on the debugging list. First try putting the Spout object creation “SpoutReceiver* spout_receiver_ = new SpoutReceiver()” after the OpenGL window creation. It might not make any difference but it is worth trying.
Creating multiple windows like this is probably not the best way to do it. Have you tried creating one OpenGL window outside the thread loop?
The only code of mine that I can refer you to for shared context is here. This only creates one shared context. I assume you can create several of them with wglShareLists but I have never tried.
I think you would need to read up on it and become familiar with shared contexts so that you create and release things properly, but this could be the way to do it if a single context is not available within the threads.
You must be logged in to reply to this topic.