Jump back to I1 Streams Library


I1 Streams Example App

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


Jump back to I1 Streams Library
Return to Software Index
Return to Cheops Homepage
wad@media.mit.edu
This is a "fix it yourself" page, located at ${CHEOPS_BASE}/WWW/software/i1streams.html