IC Imaging Control C++

Writing an Image Stream to a video file

Writing an Image Stream to a video file

This example demonstrates how to write a sequence of images to a video file.

The program can be found in the %TOPLEVEL%\Samples\VC71\CreateVideoFile directory. Similarly, you can find a VC6 version in the directory %TOPLEVEL%\Samples\VC6. In order to run the program, open the solution file CreateVideoFile.sln in this directory and select Build -> Build CreateVideoFile in the menu. You can execute the program by selecting Debug -> Start.

The program generates a list of all available media stream containers and prompts the end user to select one. In a second step, the end user may choose between 3 possible ways of storing the video data in the file:

  • Codec: If this option is selected, a list of all available video compressors is generated and the end user is asked to select one from the list.
  • Uncompressed: The end user may select an uncompressed format from a list.
  • Unspecified: If this option is selected, the current device, the frame filters and the overlays in the device path and the sink path determine the uncompressed video format.

In the next step, the program asks for a filename. Once the end user has entered a file name, the program waits until another key is pressed. Then, it starts capturing. It proceeds to capture, writing data into the video file, until enter is pressed.

Opening a Device

The example program uses the setupDeviceFromFile function from %TOPLEVEL%\Samples\VC71\Common\CmdHelper.h. This function displays the device selection dialog and saves the selected device in a configuration file. When the function is called again, this configuration file is reloaded.

Grabber grabber;
if( !setupDeviceFromFile( grabber ) )
{
    return 1;
}

Selecting the video data format

the end user may choose between 3 possible ways to store the video data in the file:

  • Codec: The static method Codec::getAvailableCodecs returns a list with the available video compressors. With the help of presentUserChoice and toStringArrayPtrListPtr from %TOPLEVEL%\Samples\VC71\Common\CmdHelper.h, this list is displayed on the console and the end user has to select one of the available codecs.
  • Uncompressed: With the help of presentUserChoice and toStringArrayPtrListPtr from %TOPLEVEL%\Samples\VC71\Common\CmdHelper.h, a list of uncompressed video formats s_UncompressedFormatList is displayed on the console, allowing the end user to select one of the available formats.
  • Unspecified: If this option is selected, the current device, frame filters and overlays in the device path and the sink path determine the uncompressed video format.

In order to save image data to a video file, a MediaStreamSink is created and initialized.

// Check whether codecs are supported by the container.
if( pCont->isCustomCodecSupported() )
{
    static const char* pCodecOrCompressorChoice[] =
    {
        "Codec",
        "Uncompressed Video",
        "Unspecified Type (uses the video format specified by either the device, frame filters or OverlayBitmap)"
    };
 
    int idx = presentUserChoice( pCodecOrCompressorChoice, pCodecOrCompressorChoice + 3 );
    if( idx == -1 )
    {
        std::cerr << "No choice was made between Codec or Uncompressed Video." << std::endl;
        return 1;
    }
 
    if( idx == 0 )
    {
        // Get a list of all available video compressors (codecs)
        tCodecListPtr pCodecList = Codec::getAvailableCodecs();
        if( pCodecList == 0 )
        {
            std::cerr << "No codecs found." << std::endl;
            return 1;
        }
 
        int Compressor_idx = presentUserChoice( toStringArrayPtrListPtr( pCodecList ) );
        if( Compressor_idx == -1 )
        {
            std::cerr << "No compressor chosen." << std::endl;
            return 1;
        }
        tCodecPtr pCodec = pCodecList->at( Compressor_idx );
 
        // If the codec provides a dialog, display it.
        if( pCodec->hasDialog() )
        {
            std::cout << "Setup the codec: " << std::endl;
            pCodec->callDialog();
        }
        // Create the sink with the specified codec.
        pSink = MediaStreamSink::create( pCont, pCodec );
    }
    else if( idx == 1 )
    {
        // Let the user select an uncompressed format.
        int UFL_idx = presentUserChoice( s_UncompressedFormatList, s_UncompressedFormatList + s_UncompressedFormatListCount );
        if( UFL_idx == -1 )
        {
            std::cerr << "No uncompressed video format chosen" << std::endl;
            return 1;
        }
        // Create the sink with the specified uncompressed format.
        GUID fmt_id = s_UncompressedFormatList[UFL_idx].id;
 
        pSink = MediaStreamSink::create( pCont, fmt_id );
    }
    else
    {
        // Create the sink with the format that is determined by the device, frame filters or overlay.
        pSink = MediaStreamSink::create( pCont );
    }
}
else
{
    // Create the sink with the format that is determined by the device, frame filters or overlay.
    pSink = MediaStreamSink::create( pCont );
}
 
/* The combinations of codec and container might not be created, so we have to check
 * this here.
 */
if( pSink == 0 )
{
    std::cerr << "The selected sink could not be built." << std::endl;
    return 1;
}

Controlling Video Recording

In order to save image data to a video file, a MediaStreamSink is created and initialized to record an AVI files. The selected codec and filename are set. The sink is initially paused by calling GrabberSinkType::setSinkMode with the parameter ePAUSE.

// The sink is initially paused, so that no video data is written to the file.
pSink->setSinkMode( GrabberSinkType::ePAUSE );
 
// apply the sink
grabber.setSinkType( pSink );
 
// Start the live mode. The live video will be displayed but no images will be written
// to the AVI file because pSink is in pause mode.
if( !grabber.startLive( true ) )
{
    std::cerr << grabber.getLastError().toString() << std::endl;
    return -1;
}
 
fflush(stdin);
 
std::cout << "Press [enter] to start capturing!";
std::cin.get();
 
// Start the sink. The image stream is written to the AVI file.
pSink->setSinkMode(GrabberSinkType::eRUN );
 
std::cout << "Video recording started." << std::endl;
std::cout << "Press [enter] to stop capturing!";
std::cin.get();
 
// Stop the live mode. This stops writing the avi file to disk.
grabber.stopLive();

After live mode has been started using Grabber::startLive, the program waits for end user input. To actually start AVI recording, the sink is put in run mode.

See also

Properties of a Codec

<< Programmer's Guide

Get in touch with us


About The Imaging Source

Established in 1990, The Imaging Source is one of the leading manufacturers of industrial cameras, frame grabbers and video converters for production automation, quality assurance, logistics, medicine, science and security.

Our comprehensive range of cameras with USB 3.1, USB 3.0, USB 2.0, GigE interfaces and other innovative machine vision products are renowned for their high quality and ability to meet the performance requirements of demanding applications.

Automated Imaging Association ISO 9001:2015 certified

Contact us