Skip to content
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

System.AccessViolationException #3

Open
Chester-Gould opened this issue Feb 8, 2022 · 12 comments
Open

System.AccessViolationException #3

Chester-Gould opened this issue Feb 8, 2022 · 12 comments

Comments

@Chester-Gould
Copy link

Thank you for creating this .NET implementation of Spout2. I'm not sure if it's my configuration or what, but I believe I've followed the instructions correctly and I am getting the following Error, at "sender.SendImage" when I try run it.

System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

Regularly I've seen that if the architecture was incorrect, but my build config is set to x64 per the ReadMe.

@HolgerFoerterer
Copy link

I get the same issue here. Could you resolve the issue in February?

@kinsi55
Copy link

kinsi55 commented Feb 16, 2023

I get this too but at random. Some times I do, other times I dont. I'll try to figure out if theres a way to workaround it

Edit: Took a look and there is no consistent way to detect that it is broken. some times some values of the Spout instance are 01010101.... when its broken but not always. Some some times SendImage will not fail, but only send a black image anyways.

Something has to be going wrong in the construction phase of something because when it does work once, reusing the same instances will consistently work 100% of the time.

@YaF3li
Copy link

YaF3li commented Jun 3, 2023

I have a similar issue. Although from the testing I have conducted on my machine so far, it seems that I can reliably make it work or crash. If I set Serilog to output to console Spout works, at least I did not yet have it throw the exception in this case. If I set it to output to a file, it will throw, also reliably as of my current observations.
I presume the different logging outputs change something about the timing, but I could not narrow it down any further as of yet.

@YaF3li
Copy link

YaF3li commented Jun 7, 2023

I was unable to find an exact cause, but I have switched from using a managed byte array to using memory obtained by Marshal.AllocHGlobal. This has seemingly resolved my issue.

@kinsi55
Copy link

kinsi55 commented Jun 7, 2023

I already am kind of doing that - My sent pixels are obtained via LockBits

@YaF3li
Copy link

YaF3li commented Jun 7, 2023

Specifically what I am now doing that seems to work is allocate using AllocHGlobal at the start of the program and retaining the memory, then LockBits of the bitmap, and copy that over into the allocated memory using Buffer.MemoryCopy, then UnlockBits and finally passing the pointer of the allocated memory to SendImage.

@kinsi55
Copy link

kinsi55 commented Jun 7, 2023

Seems like we're having different issues then (See my first comment above). This didnt fix my problem FWIW

@nickhudson4
Copy link

For me this happens when I try to convert my bitmap to a JPEG byte array like so

using (var memoryStream = new MemoryStream())
{
    bitmap.Save(memoryStream, ImageFormat.Jpeg);
    _newFrame = memoryStream.ToArray();
}

The solution was to change to Bmp format

using (var memoryStream = new MemoryStream())
{
    bitmap.Save(memoryStream, ImageFormat.Bmp);
    _newFrame = memoryStream.ToArray();
}

@JanMisker
Copy link

Specifically what I am now doing that seems to work is allocate using AllocHGlobal at the start of the program and retaining the memory, then LockBits of the bitmap, and copy that over into the allocated memory using Buffer.MemoryCopy, then UnlockBits and finally passing the pointer of the allocated memory to SendImage.

It's been a while, but I'm facing this issue as well.
@YaF3li could you share the relevant parts of your code please?

@YaF3li
Copy link

YaF3li commented Sep 10, 2024

@JanMisker These should be the relevant extracts:

// Init:
int bufferLength = size.Width * size.Height * 4; // Assume alpha channel
IntPtr bufferPtr = Marshal.AllocHGlobal(bufferLength);

// Send Loop:
// (must declare unsafe)
BitmapData bmpData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
int numbytes = bmpData.Stride * bitmap.Height;
if(numbytes == bufferLength)
	Buffer.MemoryCopy((void*)bmpData.Scan0, (void*)bufferPtr, numbytes, numbytes);
bitmap.UnlockBits(bmpData);
sender.SendImage((byte*)bufferPtr, size.Width, size.Height, GL_RGBA, false, 0);

// Dispose:
Marshal.FreeHGlobal(bufferPtr);

@JanMisker
Copy link

Thanks so much @YaF3li
I was doing some more debugging and in the end I managed to do it without an extra buffer, i.e. it's something like

BitmapData bmpData = bitmap.LockBits(...);
sender.SendImage((byte*)bmpData.Scan0, ... );
bitmap.UnlockBits(bmpData);
bitmap.Dispose();

And this works...

@kinsi55
Copy link

kinsi55 commented Sep 10, 2024

@JanMisker I also eventually came up with that implementation and that does still error out occasionally for me - Tho it worked more consistently from what I remember

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants