Getting Dropped Frames

This snippet illustrates how to retrieve dropped frames using IC Imaging Control's ImageAvailable event.

Language:.NET C#/Visual Basic
Version:3.3
Author:IC Imaging Control Support Department

Requirements:
Software:IC Imaging Control 3.3, Visual Studio™ 2010
Hardware:Camera, converter or grabber with WDM Stream Class drivers.
Download VB8 sampleGetting Dropped Frames - VB8
Download C# sampleGetting Dropped Frames - C#

Frames in the ImageAvailable event handler may be dropped when time-intensive image processing is performed. IC Imaging Congtrol's image ring buffer technology provides access to the captured frames that are not processed in the ImageAvailable event handler. For the purpose of this article, the frames that have been captured, but not processed shall be called "dropped frames".

To estimate the number of dropped frames, the global variable LastHandledFrameIndex is first declared. It is used to save the ring buffer index of the last processed frame.

C#
      
// Save the ring buffer index of the last processed frame.
private int LastHandledFrameIndex;

        

In order to receive the dropped frames, it is necessary to set the .OverlayUpdateEventEnable property to false. The .LiveCaptureContinuous property must set to true, which lets IC Imaging Control capture each frame into memory. The frames are displayed in the ImageAvailable event handler from the image buffers. Thus, the property .LiveDisplay must be set to false. The .ImageRingBufferSize must be large enough to store the dropped frames. In this sample the .ImageRingBufferSize property is set to 60. Thus, 60 frames are stored in memory. The initialization code looks as follows:

C#
      
private void Form1_Load(object sender, EventArgs e)
{

    icImagingControl1.ShowDeviceSettingsDialog();

    if (icImagingControl1.DeviceValid )
    {
        icImagingControl1.LiveDisplayDefault = false;
        icImagingControl1.LiveDisplayHeight = icImagingControl1.Height;
        icImagingControl1.LiveDisplayWidth = icImagingControl1.Width;

        icImagingControl1.LiveCaptureContinuous = true;
        icImagingControl1.LiveDisplay = false;

        // To recieve dropped frames it is necessary to set
        // OverlayUpdateEventEnable to false.
        icImagingControl1.OverlayUpdateEventEnable = false;

        // Set the imagebuffer (must be large enough).
        icImagingControl1.ImageRingBufferSize = 60;

        icImagingControl1.LiveStart();
    }

}

        

The dropped frames are detected in the ImageAvailable event handler. The algorithm has two steps. In the first step, the count of dropped frames is calculated and stored in the variable DroppedFramesCount. If DroppedFramesCount is greater than 1, then frames have been dropped. The second step contains a loop. In the loop, all dropped frames are displayed and DroppedFramesCount is decremented by one until it is less than 2.

C#
      
private void icImagingControl1_ImageAvailable(object sender, TIS.Imaging.ICImagingControl.ImageAvailableEventArgs e)
{
    TIS.Imaging.ImageBuffer buffer  = icImagingControl1.ImageBuffers[e.bufferIndex];

    // Calculate the difference between the last processed buffer index and the current buffer
    // index. This will return the count of dropped frames.
    int DroppedFramesCount = e.bufferIndex - LastHandledFrameIndex;

    // If DroppedFramesCount is less than zero then the ring buffer index has been started
    // again at zero between the LastHandledFrameIndex and then current e.bufferIndex.
    if ( DroppedFramesCount < 0 )
        DroppedFramesCount = icImagingControl1.ImageRingBufferSize + DroppedFramesCount;

    // If frames have been dropped, then display all non processed frames in the following
    // loop.
    while (DroppedFramesCount > 1)
    {
        // Calculate the index of a dropped frame.
        int DroppedFrameIndex = LastHandledFrameIndex - DroppedFramesCount - 1;
        // Handle an overflow of the RingBufferIndex.
        if (DroppedFrameIndex < 0)
        {
            //Keep in mind DroppedFrameIndex is negative!
            DroppedFrameIndex = icImagingControl1.ImageRingBufferSize + DroppedFrameIndex;
        }

        // Get the dropped frame.
        TIS.Imaging.ImageBuffer LostFrame = icImagingControl1.ImageBuffers[DroppedFrameIndex];
        // Display the dropped frame.
        icImagingControl1.DisplayImageBuffer(LostFrame);

        DroppedFramesCount--;
    }

    //Sleep for simulate time expensive image processing.
    System.Threading.Thread.Sleep(300);

    icImagingControl1.DisplayImageBuffer(buffer);

    // Save the ring buffer index of the current frame into LastHandledFrameIndex. This will
    // be used next time ImageAvailable is called again.
    LastHandledFrameIndex = e.bufferIndex;
}