Memory leak in webcam code

Ok, I've been trying to do something specific with video feed from a webcam. I have a Lumenera Infinity 2 microscope that I am trying to pull feed from, and want to be able to modify the feed as it comes in. Since I couldn't find a way to do that using Video Source Player, I decided to instead pull each frame (max of 15fps for the camera) as a bitmap so I can do my modifications there.

The problem is: I have a HUGE memory leak. When I run the video just using the videoSourcePlayer, it hovers at using around 30 megs. When I run pulling the frames as bitmaps, it breaks 1 gig of memory in a matter of seconds.

What am I missing, here? I figured auto-garbage collection would scoop up the old frames as they became inaccessible. Should I try to force garbage collection on bitmap? Or is it something else entirely and I am noobishly missing it.

FilterInfoCollection captureDevices;
VideoCaptureDevice cam;
Bitmap bitmap;

public Form1()
{
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
  try
  {
    captureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

    if (captureDevices.Count == 0)
      throw new ApplicationException();

    CameraSelectComboBox.Items.Clear();

    foreach (FilterInfo device in captureDevices)
    {
      CameraSelectComboBox.Items.Add(device.Name);
    }

    CameraSelectComboBox.SelectedIndex = 0;
    CameraSelectComboBox.Enabled = true;
  }
  catch (ApplicationException)
  {
    CameraSelectComboBox.Enabled = false;
  }
}

private void connectButton_Click(object sender, EventArgs e)
{
  cam = new VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString);
  cam.NewFrame -= Handle_New_Frame; //Just to avoid the possibility of a second event handler being put on
  cam.NewFrame += new AForge.Video.NewFrameEventHandler(Handle_New_Frame);
  videoSourcePlayer1.Visible = false;
  cam.Start();

  //videoPictureBox1.Visible = false;
  //videoSourcePlayer1.VideoSource = new VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString);
  //videoSourcePlayer1.Start();
}

private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs)
{
  bitmap = (Bitmap)eventArgs.Frame.Clone();

  videoPictureBox1.Image = bitmap;
}

Answers


Try this:

private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs)
{
    if(bitmap != null)
        bitmap.Dispose();
    bitmap = new Bitmap(eventArgs.Frame);

    if(videoPictureBox1.Image != null)
        this.Invoke(new MethodInvoker(delegate() {videoPictureBox1.Image.Dispose();}));
    videoPictureBox1.Image = bitmap;
}

It solved some of the memory leaks I experienced with Aforge and PictureBoxes, but the VideoSourcePlayer is much better where memory consumption is concerned.


I think this is one area that can use improvement:

cam = new 
  VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString);

cam.NewFrame -= Handle_New_Frame; // you're pointing to the new instance of VCD, so this will have no effect.

cam.NewFrame += new AForge.Video.NewFrameEventHandler(Handle_New_Frame);
videoSourcePlayer1.Visible = false;
cam.Start();

That code block is bleeding memory every time you press the connect button.

You pretty much need to have a reference to the VCD at the main level. So define a member variable at Form1 class level:

private VideoCaptureDevice _cameraContext;

And in the connect event handler, do this:

if (_camerContext != null)
{
  _cameraContext.NewFrame -= Handle_New_Frame;
}
_cameraContext = new VideoCaptureDevice(blah blah blah);
_cameraContext.NewFrame += Handle_New_Frame;
videoSourcePlayer1.Visible = false;
_cameraContext.Start();

BTW, I'm assuming you're .NET 3.5 or later, hence the new delegate assignment syntax.


Need Your Help

iOS 7 App Loading View Flash before appear

ios objective-c iphone launch

I am building an App and Deployment Target back to iOS 7 (so Launch Screen File in xCode6 not work for me)

How to have checkbox function access table data in Angularjs

javascript angularjs angularjs-ng-repeat

I have a table in Angularjs that has a checkbox in each row. When the checkbox is clicked, I would like an alert function to be launched to display the content of the row being clicked. The problem I

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.