VMWithDirectShow

This tutorial shows how to capture frames from a video file and camera using the VMDirectShow input module and display the images in a window with OpenGL using GLUT.

These variables are globally declared

VideoManControl videoMan; //VideoMan control object
bool fullScreened; //To nkow if the application is in fullscreen mode
bool activated; //To know if the first input is activated or not
std::vector< int > videoInputIDs; //List of indexes of the initialized inputs
char *dirPath = 0; //Path to the video file that is passed as argument to the programa
double videoLength; //Length of the initialized video file

In the InitializeVideoMan function, first we initialize an input coming from a video file

bool InitializeVideoMan()
{
   VideoManInputFormat format;
   inputIdentification device;
   //Initialize one input from a video file
   int inputID;
   if ( dirPath )
   {
      device.fileName = dirPath;
      device.identifier = "DSHOW_VIDEO_FILE"; //using directshow  
      //play in real-time using the framrate of the video
      format.clock = true;
      format.dropFrames = true;
      format.renderAudio = true; //play the audio stream also  
      if ( ( inputID = videoMan.addVideoInput( device, &format ) ) != -1 )
      {
         videoInputIDs.push_back( inputID );
         videoLength = videoMan.getLengthSeconds( inputID );
         videoMan.playVideo( inputID );
      }
   }

In the input identification variable we specify that we want to load the video using the VMDirectshow module using the identifier "DSHOW_VIDEO_FILE". With the format variable we can set some parameters of the input initialization.

Then another input is initialized from a camera

   //Initialize one input from a camera   
   inputIdentification *list;
   int numDevices;
   videoMan.getAvailableDevices( "DSHOW_CAPTURE_DEVICE", &list, numDevices ); //list all the available devices
   if ( numDevices > 0 )
   {
      device = list[0]; //take the first
      format.showDlg = true; //Show dialog to select the format
      if ( ( inputID = videoMan.addVideoInput( device, &format ) ) != -1 )
      {
         videoInputIDs.push_back( inputID );
      }
   }
   videoMan.freeAvailableDevicesList(  &list, numDevices );

We use the function getAvailableDevices to get a list of the devices that VMDirectshow module can handle and are currently connected to the PC. We can get a list of all the available devices without specifying any identifier. But in this case we use the identifier "DSHOW_CAPTURE_DEVICE" from VMDirectshow module, so we will only get the devices from that module. With the field showDlg of the format variable, we tell VideoMan to show the set-up dialog from the camera driver in order to manually choose the resolution, frame rate, etc..

The display function is nothing special:

void glutDisplay(void)
{
   //Clear the opengl window
   glClear( GL_COLOR_BUFFER_BIT );
   //For each initialized inputs
   for ( size_t n=0; n < videoInputIDs.size(); n++ )
   {
      //Get a new frame from input n
      char *image = videoMan.getFrame( videoInputIDs[n] );
      if ( image != NULL )
      {
         //Update the texture of the renderer
         videoMan.updateTexture( videoInputIDs[n] );
            //Release the frame
         videoMan.releaseFrame( videoInputIDs[n] );
      }
      //render the image of input n in the screen
      videoMan.renderFrame( videoInputIDs[n] );
   }
   //Check if the video file (input number 0) has reached the end 
   if ( videoFileInputID != -1 && videoMan.getPositionSeconds( videoFileInputID ) == videoLength )
      videoMan.goToFrame( videoFileInputID, 0 ); //restart from the begining
    glutSwapBuffers();
}

With getPositionSeconds we check if the video file has finished and, if needed, restart it to frame 0 with gotToFrame.