0

My Goal is, to write image data received by ffmpeg into shared memory and from there access the image data again in a second application wrote with c#.

For now I tried to build this behaviour with two c# scripts in the same project. My Question is, how to best sync the read and write access to the shared memory between two different applications.

So far I do this with a Thread.Sleep command to keep the using open until the Receiver was able to read the Data. Of cause LoadDataToSharedMemory() is beeing processed within a Task and not in the main Loop. See the scripts below:

 private void GrabBytesFromSharedMemory()
{
    try
    {
        //Debug.Log("trying to access mmf ...");
        using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("oneframe"))
        {
            Mutex mutex = Mutex.OpenExisting("oneframemutex");
            mutex.WaitOne();

            using (MemoryMappedViewStream stream = mmf.CreateViewStream())
            {
                BinaryReader reader = new BinaryReader(stream);
                int byteArrayCount = reader.ReadInt32();
                pixelHeigth = reader.ReadUInt32();
                pixelWidth = reader.ReadUInt32();
                dataFromSharedMemory = reader.ReadBytes(byteArrayCount);
            }
            mutex.ReleaseMutex();
        }
        //Debug.Log("File Exists!!");
    }
    catch (Exception e)
    {
        Debug.LogError(e.ToString());
    }
}



private void LoadDataToSharedMemory()
{
    if (sharedBuffer != null && sharedBuffer.Length > 0)
    {
        TaskRunningCurrently = true;

        try
        { 
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("oneframe", sharedBuffer.Length + 12))
            {

                if (!mutexCreated)
                {
                    mutex = new Mutex(true, "oneframemutex", out mutexCreated);
                }
                else
                {
                    mutex.WaitOne();
                }
                using (MemoryMappedViewStream stream = mmf.CreateViewStream())
                {
                    BinaryWriter writer = new BinaryWriter(stream);
                    writer.Write(sharedBuffer.Length);
                    writer.Write(sharedHeight);
                    writer.Write(sharedWidth);
                    writer.Write(sharedBuffer);

                    System.Threading.Thread.Sleep(30);
                }

                mutex.ReleaseMutex();
                //Debug.Log("task ended!!");
            }
        }
        catch(Exception e)
        {
            Debug.LogError(e.ToString()); 
                }
         TaskRunningCurrently = false;
    }
}
SilverLife
  • 21
  • 4

1 Answers1

0

There are various types for inter process synchronization, typically the types that inherit from WaitHandle can be named and used by several processes. You already seem to be using a Mutex, but there are also EventWaitHandle that can be used for signaling.

See also how to implement shared memory in .net

I would however suggest using a messaging framework instead. This will make synchronization much easier, and I would not think the performance impact would be noticeable.

JonasH
  • 28,608
  • 2
  • 10
  • 23