예제 #1
0
        private void bgWorkerDualSave_DoWork(object sender, DoWorkEventArgs e)
        {
            // This is executed in Worker Thread space. (Do not call any UI methods)
            log.Debug("Saving side by side video.");

            int threadResult = 0;

            // Get first frame outside the loop to set up the saving context.
            long   currentTime = 0;
            Bitmap composite   = GetCompositeImage(currentTime);

            log.DebugFormat("Composite size: {0}.", composite.Size);

            VideoInfo info = new VideoInfo
            {
                ReferenceSize = composite.Size
            };

            string formatString = FilenameHelper.GetFormatString(dualSaveFileName);

            SaveResult result = videoFileWriter.OpenSavingContext(dualSaveFileName, info, formatString, fileFrameInterval);

            if (result != SaveResult.Success)
            {
                e.Result = 2;
                return;
            }

            videoFileWriter.SaveFrame(composite);
            composite.Dispose();

            while (currentTime < commonTimeline.LastTime && !dualSaveCancelled)
            {
                currentTime += commonTimeline.FrameTime;

                if (bgWorkerDualSave.CancellationPending)
                {
                    threadResult      = 1;
                    dualSaveCancelled = true;
                    break;
                }

                composite = GetCompositeImage(currentTime);
                videoFileWriter.SaveFrame(composite);
                composite.Dispose();

                int percent = (int)((double)currentTime * 100 / commonTimeline.LastTime);
                bgWorkerDualSave.ReportProgress(percent);
            }

            if (!dualSaveCancelled)
            {
                threadResult = 0;
            }

            e.Result = threadResult;
        }
예제 #2
0
        private void Work()
        {
            Thread.CurrentThread.Name = "Record";

            while (!m_bCancelling)
            {
                Bitmap bmp = null;
                lock (m_Locker)
                {
                    if (m_FrameQueue.Count > 0)
                    {
                        bmp = m_FrameQueue.Dequeue();
                        if (bmp == null)
                        {
                            log.Debug("Recording thread finished.");
                            return;
                        }
                    }
                }

                if (bmp != null)
                {
                    SaveResult res = m_VideoFileWriter.SaveFrame(bmp);

                    if (res != SaveResult.Success)
                    {
                        // Start cancellation procedure
                        // The producer should test for .Cancelling and stop queuing items at this point.
                        // We don't try to save the outstanding frames, but the video file should be valid.
                        log.Error("Error while saving frame to file.");
                        m_bCancelling  = true;
                        m_CancelReason = res;

                        bmp.Dispose();

                        lock (m_Locker)
                        {
                            while (m_FrameQueue.Count > 0)
                            {
                                Bitmap outstanding = m_FrameQueue.Dequeue();
                                if (outstanding != null)
                                {
                                    outstanding.Dispose();
                                }
                            }

                            if (m_bInitialized)
                            {
                                try
                                {
                                    m_VideoFileWriter.CloseSavingContext(true);
                                }
                                catch (Exception exp)
                                {
                                    log.Error(exp.Message);
                                    log.Error(exp.StackTrace);
                                }
                            }
                        }

                        m_WaitHandle.Close();
                        return;
                    }
                    else
                    {
                        if (!m_bCaptureThumbSet)
                        {
                            m_CaptureThumb     = bmp;
                            m_bCaptureThumbSet = true;
                        }
                        else
                        {
                            bmp.Dispose();
                        }
                    }
                }
                else
                {
                    m_WaitHandle.WaitOne();
                }
            }
        }
예제 #3
0
        public void FrameGrabbed()
        {
            //----------------------------------------------
            // NOTE : This method is in the GRABBING thread,
            // NO UI calls can be made directly from here.
            // must use BeginInvoke at some point.
            //----------------------------------------------

            // The frame grabber has just pushed a new frame to the buffer.

            // Consolidate this real-time frame locally.
            Bitmap temp = m_FrameBuffer.ReadFrameAt(0);

            // Copy the frame over if size change is needed.
            if (!temp.Size.Equals(m_ImageSize))
            {
                m_MostRecentImage = new Bitmap(m_ImageSize.Width, m_ImageSize.Height);
                Graphics g = Graphics.FromImage(m_MostRecentImage);

                Rectangle  rDst = new Rectangle(0, 0, m_MostRecentImage.Width, m_MostRecentImage.Height);
                RectangleF rSrc = new Rectangle(0, 0, temp.Width, temp.Height);
                g.DrawImage(temp, rDst, rSrc, GraphicsUnit.Pixel);
            }
            else
            {
                m_MostRecentImage = temp;
            }

            // Ask a refresh. This could also be done with a timer,
            // but using the frame grabber event is convenient.
            if (!m_bPainting)
            {
                m_bPainting = true;
                m_Container.DoInvalidate();
            }

            // We also use this event to commit frame to disk during saving.
            // However, it is what is drawn on screen that will be pushed to the file,
            // not the frame the device just grabbed.
            if (m_bIsRecording)
            {
                // Is it necessary to make another copy of the frame ?
                Bitmap     bmp = GetFlushedImage();
                SaveResult res = m_VideoFileWriter.SaveFrame(bmp);

                if (res != SaveResult.Success)
                {
                    log.Error("Error while saving frame to file.");
                    DisplayError(res);
                    bmp.Dispose();
                    m_bIsRecording = false;
                    m_VideoFileWriter.CloseSavingContext(true);

                    // TODO: remove broken file.
                }
                else
                {
                    if (!m_bCaptureThumbSet)
                    {
                        m_CurrentCaptureBitmap = bmp;
                        m_bCaptureThumbSet     = true;
                    }
                    else
                    {
                        bmp.Dispose();
                    }
                }
            }
        }