secile / UsbCamera

C# source code for using usb camera and web camera in WinForms/WPF. With only single CSharp source code. No external library required.
MIT License
179 stars 55 forks source link

It is better do not enter critical section in callback function. #14

Closed secile closed 2 years ago

secile commented 2 years ago

take over from issue #13

I found that it is necessary to return quickly in callback function. if callback does not return quickly, it can interfere with playback. https://docs.microsoft.com/en-us/windows/win32/directshow/isamplegrabber-setcallback

This is previous version document, it is prohibited to enter critical section. https://docs.microsoft.com/en-us/previous-versions/ms786692(v=vs.85)

It is better do not enter critical section and do not wait another thread.

public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
{
    if (Buffer == null || Buffer.Length != BufferLen)
    {
        Buffer = new byte[BufferLen];
    }

    var locked = false;
    try
    {
        System.Threading.Monitor.TryEnter(BufferLock, 0, ref locked);
        if (locked)
        {
            Marshal.Copy(pBuffer, Buffer, 0, BufferLen);
        }
    }
    finally
    {
        if (locked) System.Threading.Monitor.Exit(BufferLock);
    }
    return 0;
}
secile commented 2 years ago

I measured time to execute BufferCB function under frequently executed GetBitmap().

var timer = new System.Timers.Timer(100) { SynchronizingObject = this };
timer.Elapsed += (s, ev) => pbxScreen.Image = camera.GetBitmap();
timer.Start();

not change (use lock statement)

after change (use Monitor.TryEnter)

My conclution: It is better to use Monitor.TryEnter.