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() */