public void Run()
        {
            const int VIDEODEVICE = 0; // zero based index of video capture device to use
            const int FRAMERATE = 15;  // Depends on video device caps.  Generally 4-30.
            const int VIDEOWIDTH = 640; // Depends on video device caps
            const int VIDEOHEIGHT = 480; // Depends on video device caps
            const long JPEGQUALITY = 30; // 1-100 or 0 for default

            const int TCPLISTENPORT = 399;

            Capture cam = null;
            TcpServer serv = null;
            ImageCodecInfo myImageCodecInfo;
            EncoderParameters myEncoderParameters;

            // Set up logging
            StreamWriter sw = File.AppendText(@"c:\WebCam.log");

            try
            {
                // Set up member vars
                ConnectionReady = new ManualResetEvent(false);
                bShutDown = false;

                // Set up tcp server
                iConnectionCount = 0;
                serv = new TcpServer(TCPLISTENPORT, TcpServer.GetAddresses()[0]);
                serv.Connected += new TcpConnected(Connected);
                serv.Disconnected += new TcpConnected(Disconnected);
                serv.DataReceived += new TcpReceive(Receive);
                serv.Send += new TcpSend(Send);

                myEncoderParameters = null;
                myImageCodecInfo = GetEncoderInfo("image/jpeg");

                if (JPEGQUALITY != 0)
                {
                    // If not using the default jpeg quality setting
                    EncoderParameter myEncoderParameter;
                    myEncoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, JPEGQUALITY);
                    myEncoderParameters = new EncoderParameters(1);
                    myEncoderParameters.Param[0] = myEncoderParameter;
                }

                cam = new Capture(VIDEODEVICE, FRAMERATE, VIDEOWIDTH, VIDEOHEIGHT);

                // Initialization succeeded.  Now, start serving up frames
                DoIt(cam, serv, sw, myImageCodecInfo, myEncoderParameters);
            }
            catch(Exception ex)
            {
                try
                {
                    sw.WriteLine(String.Format("{0}: Failed on startup {1}", DateTime.Now.ToString(), ex));
                }
                catch {}
            }
            finally
            {
                // Cleanup
                if (serv != null)
                {
                    serv.Dispose();
                }

                if (cam != null)
                {
                    cam.Dispose();
                }
                sw.Close();
            }
        }
        private void CMB_videosources_Click(object sender, EventArgs e)
        {
            if (MainV2.MONO)
                return;
            // the reason why i dont populate this list is because on linux/mac this call will fail.
            var capt = new Capture();

            var devices = WebCamService.Capture.getDevices();

            CMB_videosources.DataSource = devices;

            capt.Dispose();
        }
        // Start serving up frames
        private void DoIt(Capture cam, TcpServer serv, StreamWriter sw, ImageCodecInfo myImageCodecInfo, EncoderParameters myEncoderParameters)
        {
            MemoryStream m = new MemoryStream(20000);
            Bitmap image = null;
            IntPtr ip = IntPtr.Zero;
            do
            {
                // Wait til a client connects before we start the graph
                ConnectionReady.WaitOne();
                cam.Start();

                // While not shutting down, and still at least one client
                while ((!bShutDown) && (serv.Connections > 0))
                {
                    try
                    {

                        // capture image
                        ip = cam.GetBitMap();
                        image = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, ip);
                        image.RotateFlip(RotateFlipType.RotateNoneFlipY);

                        // save it to jpeg using quality options
                        m.Position = 10;
                        image.Save(m, myImageCodecInfo, myEncoderParameters);

                        // Send the length as a fixed length string
                        m.Position = 0;
                        m.Write(Encoding.ASCII.GetBytes( (m.Length - 10).ToString("d8") + "\r\n"), 0, 10);

                        // send the jpeg image
                        serv.SendToAll(m);

                        // Empty the stream
                        m.SetLength(0);

                        // remove the image from memory
                        image.Dispose();
                        image = null;
                    }
                    catch(Exception ex)
                    {
                        try
                        {
                            sw.WriteLine(DateTime.Now.ToString());
                            sw.WriteLine(ex);
                        }
                        catch {}
                    }
                    finally
                    {
                        if (ip != IntPtr.Zero)
                        {
                            Marshal.FreeCoTaskMem(ip);
                            ip = IntPtr.Zero;
                        }
                    }
                }

                // Clients have all disconnected.  Pause, then sleep and wait for more
                cam.Pause();
                sw.WriteLine("Dropped frames: " + cam.m_Dropped.ToString());

            } while ( !bShutDown );
        }