
This example demonstrates how to create a memory buffer collection, which uses user allocated buffers.
The program can be found in the %TOPLEVEL%\Samples\VC71\MemBufferCollection directory. A VC6 version can be found in the directory %TOPLEVEL%\Samples\VC6. In order to run the program, open the solution file MemBufferCollection.sln in this directory and select Build -> Build MemBufferCollection in the menu. You can then start the program by selecting Debug -> Start.
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, that is loaded when the function is called again.
Grabber grabber; if( !setupDeviceFromFile( grabber ) ) { return -1; }
To find out the required size for the user-allocated buffers, we set a FrameHandlerSink with the desired color format (in this case eY800 ) and call Grabber::prepareLive. After this call, we can retrieve the sink format by calling FrameHandlerSink::getOutputFrameType.
// Set the image buffer format to eY800. eY800 means monochrome, 8 bits (1 byte) per pixel. // Let the sink create a matching MemBufferCollection with 1 buffer. tFrameHandlerSinkPtr pSink = FrameHandlerSink::create( eY800, 1 ); // We use snap mode. pSink->setSnapMode( true ); // Set the sink. grabber.setSinkType( pSink ); // Prepare the live mode, to get the output size if the sink. if( !grabber.prepareLive( false ) ) { std::cerr << "Could not render the VideoFormat into a eY800 sink."; return -1; } // Retrieve the output type and dimension of the handler sink. // The dimension of the sink could be different from the VideoFormat, when // you use filters. FrameTypeInfo info; pSink->getOutputFrameType( info );
Now that we found the sink format, we can create buffers with the appropriate size. FrameTypeInfo::buffersize contains the number of bytes for one image. The MemBufferCollection is created by calling MemBufferCollection::create with the frame type, the number of buffers and the buffer array as parameters:
BYTE* pBuf[5]; // Allocate 5 image buffers of the above calculate buffer size. for( int i = 0; i < 5; ++i ) { pBuf[i] = new BYTE[info.buffersize]; } // Create a new MemBuffer collection that uses our own image buffers. tMemBufferCollectionPtr pCollection = MemBufferCollection::create( info, 5, pBuf ); if( pCollection == 0 || !pSink->setMemBufferCollection( pCollection ) ) { std::cerr << "Could not set the new MemBufferCollection, because types do not match."; return -1; }
After the MemBufferCollection has been set up, the program snaps five images into the buffers and saves them to disk:
// Start live mode for fast snapping. The live video will not be displayed, // because false is passed to startLive(). grabber.startLive( false ); // Snap 5 images. The images are copied to the MemBufferCollection the // application created above. pSink->snapImages( 5 ); // Stop the live video. grabber.stopLive(); // Close the device. grabber.closeDev(); // Save the five captured images in the MemBuffer collection to separate files. pCollection->save( "file*.bmp" );