public int DelayChanged(int percentage) { // Set the new delay, and give back the value in seconds. // The value given back is just an integer, not a double, because we don't have that much precision. // The frame rate is roughly estimated from frame received by seconds, // and there is a latency inherent to the camcorder that we can't know. m_iFrameIndex = (int)(((double)m_FrameBuffer.Capacity / 100.0) * percentage); double interval = (m_FrameGrabber.FramesInterval > 0)?(double)m_FrameGrabber.FramesInterval:40.0; int delay = (int)(((double)m_iFrameIndex * interval) / 1000); // Re-adjust frame for the special case of no delay at all. // (it's not always easy to drag all the way left to the real 0 spot). if (delay < 1) { m_iFrameIndex = 0; } // Explicitely call the refresh if we are not currently grabbing. if (!m_FrameGrabber.IsGrabbing) { m_ImageToDisplay = m_FrameBuffer.ReadAt(m_iFrameIndex); if (!m_bPainting) { m_bPainting = true; m_Container.DoInvalidate(); } } return(delay); }
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(); } } } }