Accord.Video.WindowCaptureStream.WorkerThread C# (CSharp) Method

WorkerThread() private method

private WorkerThread ( ) : void
return void
        private void WorkerThread()
        {
            int width = region.Width;
            int height = region.Height;
            int x = region.Location.X;
            int y = region.Location.Y;
            Size size = region.Size;

            // Create 10 frames (which we will keep overwriting and reusing)
            Context[] buffer = new Context[10];
            for (int i = 0; i < buffer.Length; i++)
            {
                // Note: It's important to use 32-bpp ARGB to avoid problems with FFmpeg later
                //var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
                var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                buffer[i] = new Context
                {
                    original = bmp,
                    hwndGraphics = Graphics.FromHwnd(windowHandle),
                    imgGraphics = Graphics.FromImage(bmp),
                    args = new NewFrameEventArgs(bmp)
                };
            }

            // download start time and duration
            DateTime start;
            TimeSpan span;
            int counter = 0;
            int bufferPos = 0;

            Context captureContext = buffer[bufferPos];
            Context displayContext = null;

            while (!stopEvent.WaitOne(0, false))
            {
                // set download start time
                start = DateTime.Now;

                try
                {
                    // Start capturing a new frame at the same
                    // time we send the previous one to listeners
#if !NET35
                    Task.WaitAll(
#if NET40
                        Task.Factory.StartNew(() =>
#else
                        Task.Run(() =>
#endif
                        {
#endif
                            // wait for a while ?
                            if (frameInterval > 0)
                            {
                                // get download duration
                                span = DateTime.Now.Subtract(start);

                                // miliseconds to sleep
                                int msec = frameInterval - (int)span.TotalMilliseconds;

                                // if we should sleep, then sleep as long as needed
                                if ((msec > 0) && (stopEvent.WaitOne(msec, false)))
                                    return;
                            }



                            // capture the screen
                            var wndHdc = captureContext.hwndGraphics.GetHdc();
                            var imgHdc = captureContext.imgGraphics.GetHdc();

                            captureContext.args.CaptureStarted = DateTime.Now;
                            BitBlt(imgHdc, 0, 0, width, height, wndHdc, x, y, (int)CopyPixelOperation.SourceCopy);
                            captureContext.args.FrameSize = size;
                            captureContext.args.CaptureFinished = DateTime.Now;

                            captureContext.hwndGraphics.ReleaseHdc(wndHdc);
                            captureContext.imgGraphics.ReleaseHdc(imgHdc);

                            // increment frames counter
                            captureContext.args.FrameIndex = counter++;
                            framesReceived++;
#if !NET35
                        }
                    ),
#if NET40
                        Task.Factory.StartNew(() =>
#else
                        Task.Run(() =>
#endif
                        {
#endif
                            // provide new image to clients
                            if (displayContext != null)
                            {
                                // reset whatever listeners had done with the frame
                                displayContext.args.Frame = displayContext.original;

                                if (NewFrame != null)
                                    NewFrame(this, displayContext.args);
                            }
#if !NET35
                        }));
#endif

                    // Update buffer position
                    displayContext = buffer[bufferPos];
                    bufferPos = (bufferPos + 1) % buffer.Length;
                    captureContext = buffer[bufferPos];
                    Debug.Assert(displayContext != captureContext);
                }
                catch (ThreadAbortException)
                {
                    break;
                }
                catch (Exception exception)
                {
#if !NET35
                    AggregateException ae = exception as AggregateException;

                    if (ae != null && ae.InnerExceptions.Count == 1)
                        exception = ae.InnerExceptions[0];
#endif
                    // provide information to clients
                    if (VideoSourceError == null)
                        throw;

                    VideoSourceError(this, new VideoSourceErrorEventArgs(exception));

                    // wait for a while before the next try
                    Thread.Sleep(250);
                }

                // need to stop ?
                if (stopEvent.WaitOne(0, false))
                    break;
            }

            // release resources
            foreach (var c in buffer)
            {
                c.imgGraphics.Dispose();
                c.args.Frame.Dispose();
            }

            if (PlayingFinished != null)
                PlayingFinished(this, ReasonToFinishPlaying.StoppedByUser);
        }