Jump back to I1 Streams Library
These are relevant code fragments from an example application. This application requires two temporal taps from the same input stream, separated by MY_TAP frames. It processes either video from a live source or a sequence stored in M1 memory. Multiple instances of this program may be run simultaneously using the same input device. If processing a finite stream from a file, the stream is looped.
The amount of parallelism provided (the number of frames that may be processed simultaneously) is determined by MY_PARALLELISM.
This application uses relative stream_time throughout.
#include < cheops_rman.h>
#include < cheops_i1.h>
...
#define MY_TAP 6 /* distance between taps */
#define MY_INPUT_FIFO_LENGTH (MY_TAP + 3) /* stream buf size */
#define MY_PARALLELISM 2 /* amount of parallelism */
#define MY_RMAN_HEAP_SIZE 30000 /* adjust as needed */
...
/* A call back mechanism is used to determine when buffers may
be reused. The transfer_done array are semaphores between
the callback routine and the main thread. */
volatile int transfer_done[ MY_PARALLELISM ];
...
main( int argc, char **argv )
{
/* Declare the queue element pointers and other variables */
QueueElem *input_tap0, *input_tap1;
InputSource input_src = { 0, 0 };
input_stream_hdr *input_stream;
int my_pid;
int use_file = 0;
int buf_set = 0;
input_stream_dest tap0_dst[ MY_PARALLELISM ];
input_stream_dest tap1_dst[ MY_PARALLELISM ];
input_stream_size stream_size[ MAX_SOURCE_CHANNELS ];
char input_name[ MAX_STREAM_NAME_CHARS ];
...
/* Initialize the Rman library */
RmanInit( MY_RMAN_HEAP_SIZE );
if( (my_pid = RmanPipeIdAllocate()) < 0 )
{ /* signal pipe id not available and exit... */ }
...
/* The command line arguments should be parsed to set
use_file, and define either or both of the input_src
and input_name variables.
Now either open or connect to the stream.
*/
if( use_file ) {
input_stream = RmanInputConnectStream( input_name );
if( input_stream == NULL )
{ /* signal file not found and exit... */ }
} else { /* use live video */
input_stream = RmanInputOpenStream( input_src, TIME_IMMEDIATE,
TIME_INFINITE, &input_no_decimation,
MY_INPUT_FIFO_LENGTH, input_name );
if( input_stream == NULL )
{ /* signal source unavailable and exit... */ }
}
/* Obtain channel size for local buffer allocation */
if( RmanInputStreamSize( input_stream, NULL, NULL,
stream_size, NULL ) != RMAN_NO_ERROR )
{ /* signal error and exit... */ }
...
/* Here allocate memory, and build the array of tap_dst
structs. Note that we need a separate set of temporary
buffers for each frame that we allow to be processed in
parallel. (MY_PARALLELISM) */
...
/* Now generate the Rman Queue elements for the two taps. */
input_tap0 = RmanInputReadStream( input_stream,
TIME_REL_TAIL(MY_TAP), tap0_dst[0] );
input_tap1 = RmanInputReadStream( input_stream,
TIME_STREAM_TAIL, tap1_dst[0] );
if( (input_tap0 == NULL) || (input_tap1 == NULL) )
{ /* signal error and exit */ }
...
/* Here build remainder of Rman queue describing algorithm */
...
/* Enable the digitizing, if not inputting from a file. */
if( !use_file )
if( RmanInputEnableStream( input_stream, TIME_IMMEDIATE )
!= RMAN_NO_ERROR ) { /* signal error and exit */ }
/* Main loop of application. */
while( !quit_application() ) { /* quit_app checks user I/O */
/* Present the rman queue to Norman */
if( RmanExecute( my_pid, input_tap0 ) != RMAN_NO_ERROR )
{ /* signal error and exit */ }
transfer_done[ buf_set ] = 0; /* clear semaphore */
/* Spin until buffers for next frame are available */
if( ++buf_set => MY_PARALLELISM ) buf_set = 0;
while( !transfer_done[ buf_set ] ) proc_sleep();
/* Modify the stream taps to advance to the next frame. */
if( (RmanInputIndexStream( input_tap0, TIME_NEXT_FRAME )
== TIME_INVALID ) ||
(RmanInputIndexStream( input_tap1, TIME_NEXT_FRAME )
== TIME_INVALID ) ) {
/* An error occured. If a fixed sequence is being
processed, it is probably just us running out of
frames to process. Just process it starting at
the beginning again. Loop indefinitely ! */
if( use_file ) { /* try to start at beginning */
if( (RmanInputIndexStream( input_tap0,
TIME_REL_TAIL(MY_TAP) ) == TIME_INVALID ) ||
(RmanInputIndexStream( input_tap1,
TIME_STREAM_TAIL ) == TIME_INVALID ) )
{ /* signal error and exit */ }
} else { /* not using file. signal an error ! */ }
}
...
} /* end of while( !quit_app() ) loop */
RmanInputCloseStream( input_stream );
...
} /* end of main() */