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

Memory issues #27

Open lwoldt opened 1 year ago

lwoldt commented 1 year ago

Hello, when using an external video capture card, you may notice that the memory usage continues to increase, ultimately causing the program to crash. Is there a button for real-time release

secile commented 1 year ago

Hello.
I think my library do not have problem of leaking memory.

  1. library include 2 sample project, 'UsbCameraForms' and 'UsbCameraWpf'. Use these sample projects and let me know crash happens or not.
  2. if possible, show me your code.
  3. tell me product name of external video capture card.
SankarGaneshKumar commented 10 months ago

Im aslo facing the same issue. GC is not collecting. Memory keeps on increasing when it reaches 3.9 GB it ends in Out of memory exception. My camera is See3CAM_CU55 by eCam and its details are 5 MP (2592 x 1944) 24 fps and 12 fps Uncompressed UYVY and Compressed MJPEG 60 fps . Screenshot (33) Screenshot (32)

yangjieshao commented 10 months ago

Im aslo facing the same issue. GC is not collecting. Memory keeps on increasing when it reaches 3.9 GB it ends in Out of memory exception. My camera is See3CAM_CU55 by eCam and its details are 5 MP (2592 x 1944) 24 fps and 12 fps Uncompressed UYVY and Compressed MJPEG 60 fps . Screenshot (33) Screenshot (32)

change

var timer = new System.Timers.Timer(1000 / 30) { SynchronizingObject = this };
timer.Elapsed += (s, ev) => pictureBox1.Image = camera.GetBitmap();
timer.start();

to

var timer = new System.Timers.Timer(1000 / 30) { SynchronizingObject = this };
timer.Elapsed += (s, ev) =>
{
    var oldImage = pictureBox1.Image;
    pictureBox1.Image = camera.GetBitmap();
    if(oldImage!=null)
    {
        oldImage.Dispose();
    }
};
timer.start();
lwoldt commented 10 months ago

改用其他库,该库存在明显的内存回收问题,起因是外接的usb设备无法管理

---Original--- From: @.> Date: Thu, Oct 12, 2023 19:30 PM To: @.>; Cc: @.**@.>; Subject: Re: [secile/UsbCamera] Memory issues (Issue #27)

Im aslo facing the same issue. GC is not collecting. Memory keeps on increasing when it reaches 3.9 GB it ends in Out of memory exception. My camera is See3CAM_CU55 by eCam and its details are 5 MP (2592 x 1944) 24 fps and 12 fps Uncompressed UYVY and Compressed MJPEG 60 fps .

change var timer = new System.Timers.Timer(1000 / 30) { SynchronizingObject = this }; timer.Elapsed += (s, ev) => pictureBox1.Image = camera.GetBitmap(); timer.start();
to var timer = new System.Timers.Timer(1000 / 30) { SynchronizingObject = this }; timer.Elapsed += (s, ev) => { var oldImage = pictureBox1.Image; pictureBox1.Image = camera.GetBitmap(); if(oldImage!=null) { oldImage.Dispose(); } }; timer.start();
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

yangjieshao commented 10 months ago

改用其他库,该库存在明显的内存回收问题,起因是外接的usb设备无法管理

并没有问题哦 我有项目跑了2年了 前台登记的客户端 一点内存都没漏 只是例子里 没释放pictureBox1.Image旧图片

你用啥库 只要是把图片clone一份到pictureBox1.Image 都得自己释放

lwoldt commented 10 months ago

您的库在系统自带的摄像头下无任何问题,一旦有其他的外接采集卡存在,内存即使自己回收,也还是会有问题

---Original--- From: @.> Date: Thu, Oct 12, 2023 19:47 PM To: @.>; Cc: @.**@.>; Subject: Re: [secile/UsbCamera] Memory issues (Issue #27)

改用其他库,该库存在明显的内存回收问题,起因是外接的usb设备无法管理

并没有问题哦 我有项目跑了2年了 前台登记的客户端 一点内存都没漏 只是例子里 没释放pictureBox1.Image旧图片

你用啥库 只要是把图片clone一份到pictureBox1.Image 都得自己释放

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

yangjieshao commented 10 months ago

您的库在系统自带的摄像头下无任何问题,一旦有其他的外接采集卡存在,内存即使自己回收,也还是会有问题 ---Original--- From: @.> Date: Thu, Oct 12, 2023 19:47 PM To: @.>; Cc: @.**@.>; Subject: Re: [secile/UsbCamera] Memory issues (Issue #27) 改用其他库,该库存在明显的内存回收问题,起因是外接的usb设备无法管理 并没有问题哦 我有项目跑了2年了 前台登记的客户端 一点内存都没漏 只是例子里 没释放pictureBox1.Image旧图片 你用啥库 只要是把图片clone一份到pictureBox1.Image 都得自己释放 — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

你得翻译成英文啊 作者看不懂中文 然后 USB摄像头我跑了很久没问题 采集卡的话 我没有 不知道什么情况

现在的项目都要考虑信创 不用这个库了

SankarGaneshKumar commented 10 months ago

Tried your change still it leads to out of memory error. Only one time GC is calling atr 3.5 GB. then it leads to out of memory exception. When I changed this function

public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen) { if (Buffer == null || Buffer.Length != BufferLen) { Buffer = new byte[BufferLen]; } // replace lock statement to Monitor.TryEnter. (issue #14) 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);
                Buffer = null;
            }
             // notify buffered to worker thread. (issue #16)
             if (Buffered != null) BufferedEvent.Set();
            return 0;
        }

        To this

         public int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen)
        {

            byte[] tempBuffer = new byte[BufferLen];

            var locked = false;
            try
            {
                System.Threading.Monitor.TryEnter(BufferLock, 0, ref locked);
                if (locked)
                {

                    Marshal.Copy(pBuffer, tempBuffer, 0, BufferLen);
                    //Console.WriteLine("BufferLen " + BufferLen);
                    Buffer = tempBuffer;
                    tempBuffer = null;
                }
            }
            finally
            {
                if (locked) System.Threading.Monitor.Exit(BufferLock);
            }
            // notify buffered to worker thread. (issue #16)
            if (Buffered != null) BufferedEvent.Set();
            return 0;
        }

        GC is calling very frequently. But it is not leading to Out of memory exception. Any idea what is happening ?

Screenshot (2)

yangjieshao commented 10 months ago

@SankarGaneshKumar maybe you can try FlashCap

It can run on Linux and Windows if you want run on mac you can try https://github.com/kekyo/FlashCap/pull/65

secile commented 10 months ago

hello, SankarGaneshKumar.

sorry, I do not have time, so in short.

I have ever experienced this problem once. At that time, when I changed target framework .NET Framework version, the problem is disapeared. Could you try?

lwoldt commented 10 months ago

我已经重写该部分 感谢你的帮助

---Original--- From: @.> Date: Thu, Oct 12, 2023 22:52 PM To: @.>; Cc: @.**@.>; Subject: Re: [secile/UsbCamera] Memory issues (Issue #27)

hello, SankarGaneshKumar.

sorry, I do not have time, so in short.

I have ever experienced this problem once. At that time, when I changed target framework .NET Framework version, the problem is disapeared. Could you try?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

secile commented 10 months ago

If it doesn't work, there's one more thing you can try. Recently, I added 'USBCAMERA_BYTEARRAY' symbol. if 'USBCAMERA_BYTEARRAY' symbol defined, GetBitmap() returns image data as byte array.

Define 'USBCAMERA_BYTEARRAY' symbol and try the code below.

// 2. use Timer and GetBitmap().
var timer = new System.Timers.Timer(1000 / 30) { SynchronizingObject = this };
timer.Elapsed += (s, ev) =>
{
    var buf = (byte[])camera.GetBitmap();
    pictureBox1.Image = BufferToBitmap(buf, camera.Size.Width, camera.Size.Height);
};
timer.Start();

private static Bitmap BufferToBitmap(byte[] buffer, int width, int height)
{
    var result = new Bitmap(width, height);
    var bmpData = result.LockBits(new Rectangle(Point.Empty, result.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    System.Runtime.InteropServices.Marshal.Copy(buffer, 0, bmpData.Scan0, buffer.Length);
    result.UnlockBits(bmpData);
    return result;
}
secile commented 6 months ago

I would like to summarize what we currently know about this issue.

Basically, bitmap object is disposed automatically by GC, so it is not occur out of memory error in normal situation. But for various reasons, for example, selecting large image size, bitmap is not disposed collectly and error occur. If you are in the situation, you have to dispose bitmap expressly. Please see also issue34.

I'll remain this issue open for a while. If the same problem is not reported after a while, I will close this issue.