Pelco Developer Network (PDN)

Viewing Live Video with the SDK Object Model

The SDK Object Model makes it easy to start and view a video stream using a small number of classes and method calls. The SDK has a set of defaults that work for most situations, freeing the developer to focus on other aspects of the application. The classes in the Object Model streamline this task compared to the Pelco API Viewer component, which will eventually be deprecated.
 
This article discusses the steps necessary to start and manipulate a video stream within an application using the classes in the SDK Object Model. It also shows how to save a snapshot of the current stream image. A brief discussion of the Pelco API Viewer component is included for those who need to migrate from that component to the SDK Object Model.
 
The sample discussed in this article is written in C++ and uses a console window to display a video stream. A C# sample (named ViewVideo) is included with the SDK.
 
This is the sequence for viewing live video:
  1. Create a System object.
  2. [Add a camera to the system. This is only required for an Edge Device system. Endura systems should already have cameras attached.]
  3. Select a Camera.
  4. Create a Stream object from the camera.
  5. Create a Display object.
  6. Start the stream.
The C++ sample is shown here in its entirety. Code snippets will be highlighted in the following sections to illustrate specific functionality. The program is contained in one C++ file. It uses console input to perform video stream actions, such as saving a snapshot of the current image. The stream images are displayed in the console window.
 
// Startup the PelcoSDK
PelcoSDK::Startup();
       
// Call Pelco SDK or COM functions here
try
{
    PelcoSDK::System system( PelcoSDK::PString( 
      "admin:admin@pelcoedgedevices://?alias=SampleSystemEdge" ) );

    system.GetDeviceCollection().Add( 
      "admin:admin@pelcoedgedevices://192.168.5.172" );

    PelcoSDK::Camera camera = system.GetDeviceCollection().GetItem( 0 );

    PelcoSDK::Stream stream( camera );

    // Set stream configuration options
    PelcoSDK::StreamConfiguration config = stream.GetConfiguration();

    config.VideoFormat = PelcoSDK::kSTREAM_FORMAT_MJPEG;

    stream.SetConfiguration( config );
               
    HWND hwnd = GetConsoleWindow();

    PelcoSDK::Display display = PelcoSDK::Display( hwnd );

    display.Show( stream );

    stream.Play( PelcoSDK::kFWD_1X );

    stream.GotoLive();

    int fileIndexCounter = 0;

    bool done = false;

    while ( done == false )
    {
        int c = getchar();

        if ( c == 'q' )
        {
            done = true;
        }
        else if ( c == 's' )
        {
            char fileIndexString[ 4 ];

            sprintf_s( fileIndexString, "%d", fileIndexCounter );

            std::string filename = "c:\\snapshot";

            filename.append( fileIndexString );
            filename.append( ".jpg" );

            PelcoSDK::PString imageFilename(filename);

            stream.Snapshot( imageFilename );

            fileIndexCounter++;
        }
    }                       

    printf( "Press any key to exit.\n" );

    getchar();
}
catch ( PelcoSDK::Exception ex )
{
    printf( "An error occurred: %s (%d)\n", ex.Message().c_str(), ex.Error() );
    printf( "Press any key to exit.\n" );

    getchar();
}               

// Shutdown the PelcoSDK
PelcoSDK::Shutdown();
 
 

Create the System

This sample creates an edge device system and adds one camera. An edge device system is an arbitrary set of cameras or other devices residing in a virtual container (the “system”). Cameras are added manually (in code) to the edge device system. The system gets added to the local device cache. The scheme string specified in the System constructor includes credentials, the System provider type, and an alias that can be used to refer to the system. More information is available in the PDN article “Managing Systems and the Device Cache”, and in the SDK Programming Guide.
 
PelcoSDK::System system( PelcoSDK::PString( 
  "admin:admin@pelcoedgedevices://?alias=SampleSystemEdge" ) );

system.GetDeviceCollection().Add( 
  "admin:admin@pelcoedgedevices://192.168.5.172" );
 
 
Although error checking is omitted here for brevity, the full sample includes a try-catch block that handles SDK-related exceptions.
 

Stream and Display

Create a Stream from the Camera object in the System’s Device Collection. The default stream protocol is RTP, but other options include RTSP or HTTP. The VideoFormat property can affect the protocol. Refer to the SDK Programming Guide for details.
 
PelcoSDK::Camera camera = system.GetDeviceCollection().GetItem( 0 );

PelcoSDK::Stream stream( camera );

// Set stream configuration options
PelcoSDK::StreamConfiguration config = stream.GetConfiguration();

config.VideoFormat = PelcoSDK::kSTREAM_FORMAT_MJPEG;

stream.SetConfiguration( config );
 
 
 In this sample there is only one Camera which makes the choice easy. However, more complex systems may contain cameras that also include alarm and relay arrays, as well as other types of non-camera devices. Each of these devices has a unique type but is not capable of streaming. In that situation it is important to check that the device type is PelcoSDK::CAMERA.
 
The Display object requires only an HWND reference for its initialization, so a stream image can be shown in almost any Windows window, including the console. After creating the Display object, associate the display with the stream by calling Display::Show(), then start playing the stream.
 
HWND hwnd = GetConsoleWindow();

PelcoSDK::Display display = PelcoSDK::Display( hwnd );

display.Show( stream );

stream.Play( PelcoSDK::kFWD_1X );
 
 
 The sequence is important. Calling Stream::Play() before Display::Show() may result in no image displaying in the window.
 
The image will appear in the window, as shown in Figure 1.
 
Figure 1. Stream display in the console window.
 

Take a Snapshot

The Stream::Snapshot() method saves a still of the current image to a file. The code sample maintains a counter that gets appended to the filename, which allows multiple snapshots to be saved without overwriting previous files. In Figure 2 the snapshots are stored at the root of the C: drive.
 
char fileIndexString[ 4 ];

sprintf_s( fileIndexString, "%d", fileIndexCounter );

std::string filename = "c:\\snapshot";

filename.append( fileIndexString );
filename.append( ".jpg" );

PelcoSDK::PString imageFilename(filename);

stream.Snapshot( imageFilename );

fileIndexCounter++;
 
 
Figure 2. Snapshots saved on the local drive.
 
 
Figure 3 shows one of the snapshot file images. Not surprisingly, it looks the same as what was displayed in the console window in Figure 1.
 
Figure 3. Snapshot image.
 

Migrating from the Pelco API Viewer

The Pelco API Viewer component (“the viewer”) in the SDK provides a lot of flexibility but at the expense of more complicated method calls. The viewer requires more setup than the classes in the SDK Object Model before streaming can commence. Compare the following code listing, which starts a live RTP stream in the viewer, to the relatively simple sequence discussed earlier for the Object Model.
// Camera Information
#define CAMERA_UUID   "uuid:e882c6c5-0a1d-d970-850b-ee00a528c704"
#define CAMERA_IP     "192.168.5.28"
#define CAMERA_PORT   "80"
#define CAMERA_NUM    "1"
#define CAMERA_USER   "admin"
#define CAMERA_PASSWORD "admin"

// NSN/NVR Information
#define NVR_NUM       "1”

// Live Stream 
#define LIVE_START    "NOW"
#define LIVE_END      "INFINITE"

// Setup Information
#define PLUGIN_DIR 
  "C:\\Users\\Public\\Documents\\apidevelopment\\PelcoAPIViewer\\trunk\\bin\\pelco\\lib\\"

#define RTP_URL        "rtp://192.168.5.20:7170"

// Initialize viewer
PelcoAPI::PelcoAPIViewer _pViewer;

PelcoAPI::AuthenticationCredentials authentication( 
  CAMERA_USER,CAMERA_PASSWORD,PelcoAPI::AuthenticationCredentials::BASIC );

if ( _pViewer.IsAuthenticationEnabled( CAMERA_IP ,CAMERA_PORT,"1" ) )
{
    _pViewer.SetAuthenticationCredentials( &authentication );
}

// Initialize streamInfo
PelcoAPI::StreamInfo streamInfo;

// Initialize timestamp delegate
MyAppNamespace::TimeStamp _pDelegate;

try
{
    //Set the plugin directory
    _pViewer.SetPluginDir( PLUGIN_DIR );

    //Create a win32 window and set the handle
    _DbgCreateParentWindow();

    // Set window handle for rendering
    _pViewer.SetWindowHandle( ( void * )_hWndParent );

    // Get information about the available stream. Not required
    result = _pViewer.VideoQuery( LIVE_START, LIVE_END, CAMERA_IP, CAMERA_PORT, 
      NVR_NUM, CAMERA_NUM, CAMERA_UUID, false, streamInfo ); 

    // Start stream
    const char *pszSesId = _pViewer.StartStream( LIVE_START, LIVE_END, CAMERA_IP, 
      CAMERA_PORT, CAMERA_NUM, RTP_URL, CAMERA_UUID, NVR_NUM, &_pDelegate, false, 
      false, &streamInfo ); 

    // Check if we have a valid session Id.
    // If valid start stream
    if ( pszSesId != NULL ) 
    {
        TRACE_INFO( "%s\n", pszSesId );

        //Now play the stream.
        if ( _pViewer.PlayForward( pszSesId, 1.0 ) != 0 )
        {
            TRACE_ERROR( "Playing forward the stream failed\n" );
            throw false;
        }
    }
    else
    {
        TRACE_ERROR( "Starting Stream failed\n" );
        throw false;
    }

    getchar();
}
catch(...)
{
    TRACE_ERROR( "Playing the stream failed\n" );
    result = -1;
}

TRACE_INFO( "Press Enter to exit ...." );

getchar();
 
 
This listing only shows how to start a live stream. The full APIViewer sample contains other features such as RTSP streaming and PTZ control.
 
Changing code to use the Object Model instead of the viewer is straightforward. For live streaming there is no longer a need to specify:
  • Camera credentials
  • Plug-in directory
  • Camera UUID or IP and port, unless adding it manually to an edge device system
  • NVR associated with the camera
  • Time range
This list only addresses live streaming. More information is required for RTSP streaming and playback, but is still simpler to implement using the Object Model. Refer to the SDK Programming Guide for more information.
 
 Pelco strongly encourages users of the Pelco API Viewer to migrate to the SDK Object Model as soon as possible. The viewer will be deprecated in the future. New integration projects should use the Object Model.
 

For More Information…

The links below provide additional information regarding the SDK Object Model and manipulating video streams using the Pelco SDK.
 
* Camera, Stream, and Display objects: