Coder Social home page Coder Social logo

SpoutDX11 about spout2 HOT 13 CLOSED

leadedge avatar leadedge commented on June 1, 2024
SpoutDX11

from spout2.

Comments (13)

leadedge avatar leadedge commented on June 1, 2024

The problem seems to be that in "CreateReceiver" the sender's texture share handle returned by "FindSender" is NULL for some reason.

The check is there because for memoryshare mode there is no texture and so the share handle can be null, but if there is a texture there has to be a share handle or the subsequent sharing functions will not work.

Without knowing what is returned by "FindSender" an tracing it further, I do not know why excluding DXGI_FORMAT_B8G8R8A8_UNORM format works because that is the default format.

I would suggest to find out exactly what is returned by "FindSender". What is the texture format? Is the sharehandle NULL?

from spout2.

ThomasMSondrup avatar ThomasMSondrup commented on June 1, 2024

Hi :-)

For a DX11 texture share, then interop.senders.FindSender(Sendername, width, height, sharehandle, dwFormat)
Returns:
sharehandle = 0
dwFormat = DXGI_FORMAT_B8G8R8A8_UNORM

As bMemory is false, and the sharehandle is 0, then the check in line 1054 returns false - if I'm not adding the format check.

I can see that, I also had to do a change to the line 1059
where:
if(bDxInitOK)
needs to be changed to:
if(bDxInitOK|| (dwFormat == DXGI_FORMAT_B8G8R8A8_UNORM))

As bDxInitOK is false. And, then we get the hWnd from WindowFromDC(wglGetCurrentDC()) - and the receiver works.

from spout2.

leadedge avatar leadedge commented on June 1, 2024

The problem is "sharehandle = 0". This should not happen unless it is memoryshare mode.

What is the sender?

from spout2.

ThomasMSondrup avatar ThomasMSondrup commented on June 1, 2024

I'm using SpoutDirectX for the transmitter, as I got some raw pixels, that I needs to transmit. Here I'm using SpoutDX.CreateDevice and SpoutDX.CreateSharedDX11Texture, and then I'm creating the sender, with an reference for the DX11 texture.
If I'm using the Demo sender - then I do see the same issue - whit the sharehandle = 0 and bMemory=false.

I've just checked the settings within the registry:
Buffering: 0
CPU: 1
DX9: 0
Memoryshare: 0

from spout2.

leadedge avatar leadedge commented on June 1, 2024

I tested this with the demo sender and see a sharehandle value returned by FindSender. Can you test within your sender code that a handle value is passed to both "CreateSender" and "UpdateSender".

CPU: 1 means that Spout is using CPU texture sharing. Confirm this with "SpoutDXmode.exe" and check "Texture" share mode on. Then try your sender again, but not the receiver where you have changed the flags.

Close the sender and open "SpoutDXmode" once more. If CPU mode is now checked, a hardware compatibility test could be switching to CPU mode. Look at the diagnostics in the demo sender to find details of the adapter being used.

from spout2.

ThomasMSondrup avatar ThomasMSondrup commented on June 1, 2024

Sorry about my late reply - had some pretty urgent work to be done :-)
But, I've now been looking a bit more into this issue :-)

I was calling Spout::OpenReceiver() with an non existing Spout sender name. This result in the line 1030:
interop.senders.FindSender(Sendername, width, height, sharehandle, dwFormat) returns false, and then the CheckSpoutPanel() is getting checked. Then, if the CheckSpoutPanel() returns true - then the share handle never get's updated - and hence I did face the issue, where the sharehandle = 0.

The best way around this might be to update the global g_ShareHandle in CheckSpoutPanel(), and then set the sharehandle = g_ShareHandle

How is your view into this - do you have a better recommendation ? :-)

from spout2.

leadedge avatar leadedge commented on June 1, 2024

I can't work out what is happening here so will need some time to trace it through.

The key is whether at any time you retrieve a valid share handle for the sender. If you do, and the earlier functions used in CreateReceiver do not, there could be a problem. Are you getting a valid share handle after calling CheckSpoutPanel() but not before?

FindSender should find whatever sender is currently running and return it's name and details including the share handle. It should only return false if no sender is running. The question is why it is returning a null share handle if the sender texture width and height are returned OK. Other functions depend on FindSender, so it really needs to be resolved.

Ideally I would like to reproduce the problem, but I have not been able to do so. For any testing, if you are not already, use the Spout demo sender and make sure that texture sharing is being used with "spoutDXmode".

from spout2.

leadedge avatar leadedge commented on June 1, 2024

I have traced this though and believe that the global share handle could safely be set within CheckSpoutPanel. However, a null sharehandle returned by FindSender indicates a memoryshare sender and CheckSpoutPanel should also be finding a null handle.

It could be a 64bit/32bit variable problem in FindSender (in SpoutSenderNames.cpp) :

Remove :

#ifdef _M_X64
		hSharehandle = (HANDLE)(LongToHandle((long)info.shareHandle));
#else
		hSharehandle = (HANDLE)info.shareHandle;
#endif

and restore the original cast :

	hSharehandle	= (HANDLE)info.shareHandle;

from spout2.

ThomasMSondrup avatar ThomasMSondrup commented on June 1, 2024

Please note - when I'm calling the
bool SpoutReceiver::CreateReceiver(char* name, unsigned int &width, unsigned int &height, bool bUseActive)

Then I've entered an non existing Spout sender name, and bUseActive is set to false. In this case, then the interop.senders.FindSender (in SpoutSDK.cpp L 1031) returns false - as the sender is not found.

Then in the reset of the section, and including CheckSpoutPanel() - then the sharehandle never get's updated.

My quick fix for this is:

Then in CheckSpoutPanel() SpoutSDK.cpp L 1472 - interop.senders.getSharedInfo() is called - but here the g_ShareHandle aint updated as well.
To get the sharehandle updated here - then I've replaced the section in the lines 1472-1482 with:
if (interop.senders.GetSenderInfo(newname, g_Width, g_Height, g_ShareHandle, g_Format))
{
strcpy_s(g_SharedMemoryName, 256, newname);
bRet = true;
}

This should also be done - replacing the code in the lines 1487-1493

Now we also got the sharehandle from CheckSpoutPanel() - then in the section L 1034 - 1040 we then just need to add: sharehandle = g_ShareHandle;

I've only been testing this in Memory and CPU mode (x64 compile) - and it does seems to do the trick :-)

from spout2.

leadedge avatar leadedge commented on June 1, 2024

Many thanks for this.

The logic of the present code is confusing and will be replaced in the next release. This version has both memoryshare and CPU texture sharing to get some feedback on errors. In the next version, memoryshare will be removed and CPU texture sharing will be the backup in case the NVIDIA GL/DX interop functions fail to work. Hopefully this will simplify the code signficantly throughout.

Meanwhile I will try to reproduce your situation now that I realise that you are passing a sender name. I will make changes if I can reproduce the error.

I am still not clear on why this is happening though. In memoryshare mode there will always be a null texture share handle because no texture exists, so updating the share handle should not be necessary. Do you find the problem in memoryshare mode?

CheckSpoutPanel should only return true if you have activated SpoutPanel and selected a sender. Are you selecting a sender?

In CPU texture share mode, a share handle must exist. But maybe there is a problem that occurs with the circumstances you are using.

If you are compiling 64bit, does the code change indicated above have any effect in CPU share mode?

from spout2.

leadedge avatar leadedge commented on June 1, 2024

I believe that I have reproduced the situation you have described.

If CreateReceiver is called with the name of a sender that is not running, the function will only succeed if that sender is started. That is the purpose of the option to provide a sender name.

If the user then selects another sender, the function will still fail because it is waiting for the nominated sender to start. This is also the intended behaviour, but the code should be more clear and not depend on the null sharehandle causing the failure.

However, I can see that it might be expected that the selected sender will be received and over-ride the initial sender name and I think that behaviour could be more useful. When the selected sender is closed, the receiver will resume waiting for the nominated sender.

The quick fix for this is as you described earlier.

In CheckSpoutPanel (two places) :

g_ShareHandle = (HANDLE)TextureInfo.shareHandle;

In CreateReceiver after CheckSpoutPanel :

sharehandle = g_ShareHandle;

I realise that other changes could be made but this appears to be the minimum. I will make more tests before I commit the changes. Hopefully this will allow other people to make comment before the code is revised for the next release.

from spout2.

ThomasMSondrup avatar ThomasMSondrup commented on June 1, 2024

I've just added your update to my code - and this does the fix :-)
To be honnest, then I haven't seen the issue in Memoryshare mode in the past. I've always had the experience that the Memoryshare mode was always working. But, currently, then the CPU mode always works as well.

from spout2.

leadedge avatar leadedge commented on June 1, 2024

OK I will commit the change when I get a moment. The functions will be simplified considerably when memoryshare mode is removed so it isn't worth doing any more. If you are happy that everything works as expected we can close this one. Contact me by email if you would like further discussion.

from spout2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.