/// <summary>
        /// grabs frames from two cameras
        /// </summary>
        protected static void CaptureFrames(
            int start_camera_index,
            WebcamVisionDirectShowCapture[] cam,
            int initial_frames,
            string output_filename,
            string output_format,
            IntPtr[] m_ip,
            bool save_images,
            int exposure,
            bool use_pause,
            ref string left_image_filename,
            ref string right_image_filename,
            ref Bitmap left_image_bitmap,
            ref Bitmap right_image_bitmap,
            ref DateTime left_image_capture,
            ref DateTime right_image_capture)
        {
            const int step_size = 5; // when checking if frames are blank

            if (left_image_bitmap != null)
            {
                left_image_bitmap.Dispose();
            }
            if (right_image_bitmap != null)
            {
                right_image_bitmap.Dispose();
            }

            if ((cam[start_camera_index] != null) && (cam[start_camera_index + 1] != null))
            {
                /*
                 * if (m_ip[start_camera_index] != IntPtr.Zero)
                 * {
                 *  Marshal.FreeCoTaskMem(m_ip[start_camera_index]);
                 *  m_ip[start_camera_index] = IntPtr.Zero;
                 * }
                 *
                 * if (m_ip[start_camera_index+1] != IntPtr.Zero)
                 * {
                 *  Marshal.FreeCoTaskMem(m_ip[start_camera_index+1]);
                 *  m_ip[start_camera_index+1] = IntPtr.Zero;
                 * }
                 */

                for (int i = 0; i < 2; i++)
                {
                    WebcamVisionDirectShowCapture c = cam[start_camera_index];
                    if (i > 0)
                    {
                        c = cam[start_camera_index + 1];
                    }

                    // start rolling the cameras
                    if (c.lastFrame != null)
                    {
                        c.lastFrame.Dispose();
                    }

                    c.Resume();
                }

                // grab frames
                Bitmap   grabbed_image0  = null;
                Bitmap   grabbed_image1  = null;
                bool     is_blank0       = true;
                bool     is_blank1       = true;
                DateTime left_image_cap  = DateTime.Now;
                DateTime right_image_cap = DateTime.Now;

                //for (int j = 0; j < 2; j++)
                Parallel.For(0, 2, delegate(int j)
                {
                    for (int i = 0; i < initial_frames + 1; i++)
                    {
                        if (j == 0)
                        {
                            left_image_cap = DateTime.Now;
                            cam[start_camera_index].SetExposure(exposure);
                            grabbed_image0 = cam[start_camera_index].Grab(ref m_ip[start_camera_index], true);
                            is_blank0      = IsBlankFrame(grabbed_image0, step_size);
                            if ((!is_blank0) && (i > 1))
                            {
                                break;
                            }
                        }
                        else
                        {
                            right_image_cap = DateTime.Now;
                            cam[start_camera_index + 1].SetExposure(exposure);
                            grabbed_image1 = cam[start_camera_index + 1].Grab(ref m_ip[start_camera_index + 1], true);
                            is_blank1      = IsBlankFrame(grabbed_image1, step_size);
                            if ((!is_blank0) && (i > 1))
                            {
                                break;
                            }
                        }
                    }
                });

                left_image_capture  = left_image_cap;
                right_image_capture = right_image_cap;

                if ((grabbed_image0 != null) &&
                    (grabbed_image1 != null))
                {
                    System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
                    output_format = output_format.ToLower();
                    if (output_format == "bmp")
                    {
                        format = System.Drawing.Imaging.ImageFormat.Bmp;
                    }
                    if (output_format == "png")
                    {
                        format = System.Drawing.Imaging.ImageFormat.Png;
                    }
                    if (output_format == "gif")
                    {
                        format = System.Drawing.Imaging.ImageFormat.Gif;
                    }
                    left_image_bitmap    = grabbed_image0;
                    right_image_bitmap   = grabbed_image1;
                    left_image_filename  = output_filename + "0." + output_format;
                    right_image_filename = output_filename + "1." + output_format;
                    try
                    {
                        if (save_images)
                        {
                            grabbed_image0.Save(left_image_filename, format);
                            grabbed_image1.Save(right_image_filename, format);
                        }
                    }
                    catch
                    {
                        left_image_filename  = "";
                        right_image_filename = "";
                    }
                }

                for (int i = 0; i < 2; i++)
                {
                    WebcamVisionDirectShowCapture c = cam[start_camera_index];
                    if (i > 0)
                    {
                        c = cam[start_camera_index + 1];
                    }

                    // stop the camera
                    if (use_pause)
                    {
                        c.Pause();
                    }
                    else
                    {
                        c.Stop();
                    }
                }
            }
        }
        /// <summary>
        /// grabs a frame from the camera
        /// </summary>
        protected static void CaptureFrame(
            WebcamVisionDirectShowCapture cam,
            int initial_frames,
            string output_filename,
            string output_format,
            ref IntPtr m_ip,
            int exposure,
            bool use_pause)
        {
            if (cam != null)
            {
                // start rolling the cameras
                if (cam.lastFrame != null)
                {
                    cam.lastFrame.Dispose();
                }

                if (m_ip != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(m_ip);
                    m_ip = IntPtr.Zero;
                }

                cam.Resume();

                // grab frames
                for (int i = 0; i < initial_frames; i++)
                {
                    cam.Grab(ref m_ip, false);

                    if (m_ip != IntPtr.Zero)
                    {
                        Marshal.FreeCoTaskMem(m_ip);
                        m_ip = IntPtr.Zero;
                    }
                }
                cam.SetExposure(exposure);
                Bitmap grabbed_image = cam.Grab(ref m_ip, true);
                if (grabbed_image != null)
                {
                    System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
                    output_format = output_format.ToLower();
                    if (output_format == "bmp")
                    {
                        format = System.Drawing.Imaging.ImageFormat.Bmp;
                    }
                    if (output_format == "png")
                    {
                        format = System.Drawing.Imaging.ImageFormat.Png;
                    }
                    if (output_format == "gif")
                    {
                        format = System.Drawing.Imaging.ImageFormat.Gif;
                    }
                    grabbed_image.Save(output_filename + "." + output_format, format);
                }

                // stop the camera
                if (use_pause)
                {
                    cam.Pause();
                }
                else
                {
                    cam.Stop();
                }
            }
        }
        /// <summary>
        /// grabs a frame from the camera
        /// </summary>
        protected static void CaptureFrame(
            WebcamVisionDirectShowCapture cam,
            int initial_frames,
            string output_filename,
            string output_format,
            ref IntPtr m_ip,
            int exposure,
            bool use_pause)
        {
            if (cam != null)
            {
                // start rolling the cameras
                if (cam.lastFrame != null)
                    cam.lastFrame.Dispose();

                if (m_ip != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(m_ip);
                    m_ip = IntPtr.Zero;
                }

                cam.Resume();

                // grab frames                
                for (int i = 0; i < initial_frames; i++)
                {
                    cam.Grab(ref m_ip, false);

                    if (m_ip != IntPtr.Zero)
                    {
                        Marshal.FreeCoTaskMem(m_ip);
                        m_ip = IntPtr.Zero;
                    }
                }
                cam.SetExposure(exposure);
                Bitmap grabbed_image = cam.Grab(ref m_ip, true);
                if (grabbed_image != null)
                {
                    System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
                    output_format = output_format.ToLower();
                    if (output_format == "bmp") format = System.Drawing.Imaging.ImageFormat.Bmp;
                    if (output_format == "png") format = System.Drawing.Imaging.ImageFormat.Png;
                    if (output_format == "gif") format = System.Drawing.Imaging.ImageFormat.Gif;
                    grabbed_image.Save(output_filename + "." + output_format, format);
                }

                // stop the camera
                if (use_pause)
                    cam.Pause();
                else
                    cam.Stop();
            }
        }