I am trying to write some video stitching software that emulates the functionality of a car dashboard that has an all around camera system. The program uses HD video capture cards to stream from 5 GoPro cameras and detects movement using PIR sensors with the movement detection data sent down a serial connection.
I am getting a problem with memory leaks, specifically it is using large amounts of "modified" ram, which first fills up the hardware ram then the virtual ram then the program crashes.
I am very new to video processing and openGL and have little experience with memory management and unmanned code.
I have included the entirety of my code at the bottom as I may be looking in the wrong place but I believe the issues are arising around these tow key sections:
The event that takes the image from the aForge webcam driver:
  videoSource1.NewFrame += (Object sender, NewFrameEventArgs eventArgs) =>
        {
            System.Threading.Thread.Sleep(10);
            if (videoFrame1 != null)
                lock (videoFrame1)
                {
                    videoFrame1 = new Bitmap(eventArgs.Frame);
                }
            else
            {
                videoFrame1 = new Bitmap(eventArgs.Frame);
            }
        };
And the section that passes the bitmap to the openGl stuff and displays it:
  if (videoFrame1 != null)
                lock (videoFrame1)
                {
                    glControl1.MakeCurrent();
                    if (videoTexture1 != -1)
                        GL.DeleteTextures(1, ref videoTexture1);
                    videoTexture1 = TexUtil.CreateTextureFromBitmap(videoFrame1);
                    GL.BindTexture(TextureTarget.Texture2D, videoTexture1);
                    //  videoFrame1 = null;
                    fullscreenQuad.Draw(1);
                    if (selectedCam == 1) 
                    {
                        drawSide(videoFrame1);
                    glControl1.MakeCurrent();
                }
                    videoFrame1.Dispose();
                    GC.Collect();
                }
I was under the impression if I dispose of the bitmap and then call GC.collect this should free up the space?
Should I be calling something else to make it get rid of the allocated RAM in a different fashion?
Is there a way to force c# to free up the ram as "zeroed" opposed to marking it as "modified"
If I use the sysinternals RAMMap utility I can shift the modified ram to "standby" and can then wipe the standby freeing up the space. Is there a way to do this programmatically in c#?
Sorry if this is a bit jumbled, as I said I'm very new to this
Many thanks,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using TexLib;
namespace GLembedded
{
public partial class Form1 : Form
{
    bool loaded = false;
    Bitmap videoFrame1 = null;
    Bitmap videoFrame2 = null;
    Bitmap videoFrame3 = null;
    Bitmap videoFrame4 = null;
    VideoCaptureDevice videoSource1;
    VideoCaptureDevice videoSource2;
    VideoCaptureDevice videoSource3;
    VideoCaptureDevice videoSource4;
    FilterInfoCollection videoDevices;
    int videoTexture1 = -1;
    int videoTexture2 = -1;
    int videoTexture3 = -1;
    int videoTexture4 = -1;
    int videoTexture5 = -1;
    int videoTexture6 = -1;
    int selectedCam = 1;
    int countdown = 0;
    int bytein = 0;
    Quad fullscreenQuad = new Quad();
    public Form1()
    {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        timer1.Start();
        this.DoubleBuffered = true;
        serialPort1.Open();
    }
    private void SetupViewport()
    {
        int w = glControl1.Width;
        int h = glControl1.Height;
      //  GL.MatrixMode(MatrixMode.Projection);
      //  GL.Ortho(0, w, 0, h, -1, 1); // Bottom-left corner pixel has coordinate (0, 0)
    //    GL.Viewport(0, 0, w, h); // Use all of the glControl painting area
    }
    private void glControl1_Load(object sender, EventArgs e)
    {
        glControl1.MakeCurrent();
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadIdentity();
        GL.Enable(EnableCap.DepthTest);
        TexUtil.InitTexturing();
        videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
        GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
        GL.DepthFunc(DepthFunction.Lequal);
        GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse);
        GL.Enable(EnableCap.ColorMaterial);
        GL.Clear(ClearBufferMask.None);
        GL.Enable(EnableCap.Blend);
        GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // render per default onto screen, not some FBO
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); // use the visible framebuffer
        GL.ClearColor(Color.Black);
        GL.Viewport(glControl1.Location.X - 317, glControl1.Location.Y - 67, glControl1.Width, glControl1.Height);
        Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, -1 * Vector3.UnitZ, Vector3.UnitY);
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadMatrix(ref modelview);
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadIdentity();
        GL.Ortho(-1, 1, -1, 1, -1, 1.1);
        OpenVideoStream();
        loaded = true;
    }
    private void glControl1_Resize(object sender, EventArgs e)
    {
        if (!loaded)
            return;
    }
    private void glControl1_Paint(object sender, PaintEventArgs e)
    {
        glControl1.MakeCurrent();
        if (!loaded) // Play nice
            return;
        //if(videoFrame1!=null & videoFrame2!=null & videoFrame3!=null & videoFrame4!=null )
        {
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.Enable(EnableCap.Texture2D);
            if (videoFrame1 != null)
                lock (videoFrame1)
                {
                    glControl1.MakeCurrent();
                    if (videoTexture1 != -1)
                        GL.DeleteTextures(1, ref videoTexture1);
                    videoTexture1 = TexUtil.CreateTextureFromBitmap(videoFrame1);
                    GL.BindTexture(TextureTarget.Texture2D, videoTexture1);
                    //  videoFrame1 = null;
                    fullscreenQuad.Draw(1);
                    if (selectedCam == 1) 
                    {
                        drawSide(videoFrame1);
                    glControl1.MakeCurrent();
                }
                    videoFrame1.Dispose();
                    GC.Collect();
                }
            if (videoFrame2 != null)
                lock (videoFrame2)
                {
                    glControl1.MakeCurrent();
                    if (videoTexture2 != -1)
                        GL.DeleteTextures(1, ref videoTexture2);
                    videoTexture2 = TexUtil.CreateTextureFromBitmap(videoFrame2);
                    GL.BindTexture(TextureTarget.Texture2D, videoTexture2);
                    if (selectedCam == 2)
                    {
                        drawSide(videoFrame2);
                        glControl1.MakeCurrent();
                    }
                      videoFrame2.Dispose();
                    // videoFrame2 = null;
                    GC.Collect();
                    fullscreenQuad.Draw(2);
                }
            if (videoFrame3 != null)
                lock (videoFrame3)
                {
                    glControl1.MakeCurrent();
                    if (videoTexture3 != -1)
                        GL.DeleteTextures(1, ref videoTexture3);
                    videoTexture3 = TexUtil.CreateTextureFromBitmap(videoFrame3);
                    GL.BindTexture(TextureTarget.Texture2D, videoTexture3);
                    if (selectedCam == 3)
                    {
                        drawSide(videoFrame3);
                        glControl1.MakeCurrent();
                    }
                    videoFrame3.Dispose();
                      //  videoFrame3 = null;
                    GC.Collect();
                  fullscreenQuad.Draw(3);
                }
            if (videoFrame4 != null)
                lock (videoFrame4)
                {
                    if (videoTexture4 != -1)
                        GL.DeleteTextures(1, ref videoTexture4);
                    videoTexture4 = TexUtil.CreateTextureFromBitmap(videoFrame4);
                    GL.BindTexture(TextureTarget.Texture2D, videoTexture4);
                    if (selectedCam == 4)
                    {
                        drawSide(videoFrame4);
                        glControl1.MakeCurrent();
                    }
                       videoFrame4.Dispose();
                  //   videoFrame4 = null;
                    GC.Collect();
                  fullscreenQuad.Draw(4);
                }
        }
        glControl2.SwapBuffers();
       // GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
        GL.Disable(EnableCap.Texture2D);
        GL.Begin(BeginMode.Quads);
        GL.Color4(0f, 0f, 0f,1f);
         GL.Vertex2(1, .98);
         GL.Vertex2(.98, 1);
         GL.Vertex2(0, 0.02);
         GL.Vertex2(0, -0.02);
         GL.Vertex2(-.98, 1);
         GL.Vertex2(-1, .98);
         GL.Vertex2(0, -0.02);
         GL.Vertex2(0, 0.02);
         GL.Vertex2(-1, -.98);
         GL.Vertex2(-.98, -1);
         GL.Vertex2(0, -0.02);
         GL.Vertex2(0, 0.02);
         GL.Vertex2(1, -.98);
         GL.Vertex2(.98, -1);
         GL.Vertex2(0, -0.02);
         GL.Vertex2(0, 0.02);
         GL.Vertex2(-1, 1);
         GL.Vertex2(-0.98, 1);
         GL.Vertex2(-0.98, 0.98);
         GL.Vertex2(-1, 0.98);
         GL.Vertex2(1, 1);
         GL.Vertex2(0.98, 1);
         GL.Vertex2(0.98, 0.98);
         GL.Vertex2(1, 0.98);
         GL.Vertex2(-1, -1);
         GL.Vertex2(-0.98, -1);
         GL.Vertex2(-0.98, -0.98);
         GL.Vertex2(-1, -0.98);
         GL.Vertex2(1, -1);
         GL.Vertex2(0.98, -1);
         GL.Vertex2(0.98, -0.98);
         GL.Vertex2(1, -0.98);
        GL.End();
        GL.Color4(1f, 1f, 1f, 1f);
        glControl1.SwapBuffers();
    }
    private void OpenVideoStream()
    {
        //     Console.WriteLine("Connecting to {0}", url);
        videoSource1 = new VideoCaptureDevice(videoDevices[0].MonikerString);
        videoSource2 = new VideoCaptureDevice(videoDevices[1].MonikerString);
        videoSource3 = new VideoCaptureDevice(videoDevices[2].MonikerString);
        videoSource4 = new VideoCaptureDevice(videoDevices[3].MonikerString);
        videoSource1.NewFrame += (Object sender, NewFrameEventArgs eventArgs) =>
        {
            System.Threading.Thread.Sleep(10);
            if (videoFrame1 != null)
                lock (videoFrame1)
                {
                    videoFrame1 = new Bitmap(eventArgs.Frame);
                }
            else
            {
                videoFrame1 = new Bitmap(eventArgs.Frame);
            }
        };
        videoSource2.NewFrame += (Object sender, NewFrameEventArgs eventArgs) =>
        {
            System.Threading.Thread.Sleep(10);
            if (videoFrame2 != null)
                lock (videoFrame2)
                {
                    videoFrame2 =  new Bitmap(eventArgs.Frame);
                }
            else
            {
                videoFrame2 = new Bitmap(eventArgs.Frame);
            }
        };
        videoSource3.NewFrame += (Object sender, NewFrameEventArgs eventArgs) =>
        {
            System.Threading.Thread.Sleep(10);
            if (videoFrame3 != null)
                lock (videoFrame3)
                {
                    videoFrame3 =  new Bitmap(eventArgs.Frame);
                }
            else
            {
                videoFrame3 = new Bitmap(eventArgs.Frame);
            }
        };
        videoSource4.NewFrame += (Object sender, NewFrameEventArgs eventArgs) =>
        {
            System.Threading.Thread.Sleep(10);
            if (videoFrame4 != null)
                lock (videoFrame4)
                {
                    videoFrame4 = new Bitmap(eventArgs.Frame);
                }
            else
            {
                videoFrame4 = new Bitmap(eventArgs.Frame);
            }
        };
        videoSource1.Start();
        videoSource2.Start();
        videoSource3.Start();
        videoSource4.Start();
    }
    private void timer1_Tick(object sender, EventArgs e)
    {
        glControl1.Refresh();
        pictureBox2.Visible = (selectedCam == 1) ? true : false;
        pictureBox3.Visible = (selectedCam == 2) ? true : false;
        pictureBox4.Visible = (selectedCam == 3) ? true : false;
        pictureBox5.Visible = (selectedCam == 4) ? true : false;
    }
    private void glControl2_Paint(object sender, PaintEventArgs e)
    {
    //   glControl2.SwapBuffers();
    }
    private void glControl2_Load(object sender, EventArgs e)
    {
        glControl2.MakeCurrent();
        int w = glControl2.Width;
        int h = glControl2.Height;
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadIdentity();
        GL.Ortho(-1, 1, -1, 1, -1, 1.1);
        GL.Viewport(0,0, glControl2.Width, glControl2.Height);
        GL.MatrixMode(MatrixMode.Modelview);
        TexUtil.InitTexturing();
        GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
        GL.ColorMaterial(MaterialFace.FrontAndBack, ColorMaterialParameter.AmbientAndDiffuse);
        GL.Enable(EnableCap.ColorMaterial);
        GL.Clear(ClearBufferMask.None);
       GL.Enable(EnableCap.Blend);
        GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // render per default onto screen, not some FBO
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); // use the visible framebuffer
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadIdentity();
        GL.Ortho(-1, 1, -1, 1, -1, 1.1);
    }
    private void drawSide(Bitmap cam)
    {
            glControl2.MakeCurrent();
            GL.MatrixMode(MatrixMode.Modelview);
            GL.Color3(1f, 1f, 1f);
            GL.PushMatrix();
            GL.Enable(EnableCap.Texture2D);
            videoTexture5 = TexUtil.CreateTextureFromBitmap(cam);
            GL.BindTexture(TextureTarget.Texture2D, videoTexture5);
            GL.Begin(BeginMode.Quads);
            GL.TexCoord2(0, 0);
            GL.Vertex2(-1, 1);
            GL.TexCoord2(1f, 0);
            GL.Vertex2(1f, 1f);
            GL.TexCoord2(1f, 1f);
            GL.Vertex2(1f, -1f);
            GL.TexCoord2(0, 1f);
            GL.Vertex2(-1f, -1f);
            GL.End();
            GL.Disable(EnableCap.Texture2D);
            GL.Begin(BeginMode.Quads);
            GL.Color4(1f, 0f, 0.0f, 1f);
        //red
            GL.Vertex2(-0.8f, -0.6f);
            GL.Vertex2(-0.7f, -0.4f);
            GL.Vertex2(-0.68f, -0.4f);
            GL.Vertex2(-0.78f,- 0.6f);
            GL.Vertex2(-0.75f, -0.49f);
            GL.Vertex2(-0.65f, -0.49f);
            GL.Vertex2(-0.65f, -0.51f);
            GL.Vertex2(-0.75f, -0.51f);
            GL.Vertex2(0.8f, -0.6f);
            GL.Vertex2(0.7f, -0.4f);
            GL.Vertex2(0.68f, -0.4f);
            GL.Vertex2(0.78f, -0.6f);
            GL.Vertex2(0.75f, -0.49f);
            GL.Vertex2(0.65f, -0.49f);
            GL.Vertex2(0.65f, -0.51f);
            GL.Vertex2(0.75f, -0.51f);
            GL.Vertex2(-0.69f, -0.38f);
            GL.Vertex2(-0.64f, -0.28f);
            GL.Vertex2(-0.62f, -0.28f);
            GL.Vertex2(-0.67f, -0.38f);
            GL.Vertex2(0.69f, -0.38f);
            GL.Vertex2(0.64f, -0.28f);
            GL.Vertex2(0.62f, -0.28f);
            GL.Vertex2(0.67f, -0.38f);
        //end red
        //yellow
            GL.Color4(1f, 1f, 0.0f, 1f);
            GL.Vertex2(-0.63f, -0.25f);
            GL.Vertex2(-0.53f, -0.05f);
            GL.Vertex2(-0.51f, -0.05f);
            GL.Vertex2(-0.61f, -0.25f);
            GL.Vertex2(-0.58f, -0.14f);
            GL.Vertex2(-0.48f, -0.14f);
            GL.Vertex2(-0.48f, -0.16f);
            GL.Vertex2(-0.58f, -0.16f);
            GL.Vertex2(0.63f, -0.25f);
            GL.Vertex2(0.53f, -0.05f);
            GL.Vertex2(0.51f, -0.05f);
            GL.Vertex2(0.61f, -0.25f);
            GL.Vertex2(0.58f, -0.14f);
            GL.Vertex2(0.48f, -0.14f);
            GL.Vertex2(0.48f, -0.16f);
            GL.Vertex2(0.58f, -0.16f);
            GL.End();
            GL.PopMatrix();
            glControl2.Refresh();
    }
    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        bytein = serialPort1.ReadByte();
        if(countdown==0){
            if ((bytein & 1) == 1)
            {
                selectedCam = 1;
            }
            else if ((bytein & 2) == 2)
            {
                selectedCam = 2;
            }
            else if ((bytein & 8) == 8)
            {
                selectedCam = 4;
            }
            else if ((bytein & 4) == 4)
            {
                selectedCam = 3;
            }
            countdown = 20;
        }
        countdown--;
    }
    private void Form1_FormClosing_1(object sender, FormClosingEventArgs e)
    {
        videoSource1.Stop();
        videoSource2.Stop();
        videoSource3.Stop();
        videoSource4.Stop();
    }
    }
}