home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectShow / Editing / SampGrabCB / SampGrabCB.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-08  |  7.0 KB  |  258 lines

  1. //------------------------------------------------------------------------------
  2. // File: SampGrabCB.cpp
  3. //
  4. // Desc: DirectShow sample code - C++ console application demonstrating
  5. //       use of the IMediaDet interface to create a graph that contains a
  6. //       sample grabber filter.  It shows how to use the sample grabber 
  7. //       and a COM object callback to display information about media
  8. //       samples in a running video file.  
  9. //
  10. // Copyright (c) 1998-2001 Microsoft Corporation.  All rights reserved.
  11. //------------------------------------------------------------------------------
  12.  
  13.  
  14. #include "stdafx.h"
  15.  
  16. // Function prototypes
  17. //
  18. int GrabSamples( char * pFilename ); 
  19.  
  20. #ifdef UNICODE
  21. #error This sample will not compile UNICODE.
  22. #endif
  23.  
  24. // This semi-COM object is a callback COM object for the sample grabber
  25. //
  26. class CFakeCallback : public ISampleGrabberCB 
  27. {
  28. public:
  29.     STDMETHODIMP_(ULONG) AddRef() { return 2; }
  30.     STDMETHODIMP_(ULONG) Release() { return 1; }
  31.  
  32.     STDMETHODIMP QueryInterface(REFIID riid, void ** ppv)
  33.     {
  34.         if (riid == IID_ISampleGrabberCB || riid == IID_IUnknown) 
  35.         {
  36.             *ppv = (void *) static_cast<ISampleGrabberCB *>(this);
  37.             return NOERROR;
  38.         }    
  39.         return E_NOINTERFACE;
  40.     }
  41.  
  42.     STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
  43.     {
  44.         static long counter = 0;
  45.         printf( "Sample received = %05ld  Clock = %ld\r\n", 
  46.                  counter++, timeGetTime( ) );
  47.         return 0;
  48.     }
  49.  
  50.     STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferLen )
  51.     {
  52.         return 0;
  53.     }
  54.  
  55. };
  56.  
  57.  
  58. int main(int argc, char* argv[])
  59. {
  60.     if( argc != 2 )
  61.     {
  62.         printf( "Usage: SampGrabCB <filename>\r\n\r\n" );
  63.         printf( "This application reads a media file and receives callbacks for every\r\n"
  64.                 "media sample processed.  You must provide a valid filename.\r\n");
  65.         return -1;
  66.     }
  67.  
  68.     // Initialize COM
  69.     CoInitialize( NULL );
  70.  
  71.     // Run the test on the filename specified on the command line
  72.     GrabSamples( argv[1] );
  73.  
  74.     // COM cleanup
  75.     CoUninitialize( );
  76.  
  77.     return 0;
  78. }
  79.  
  80.  
  81. int GrabSamples( char * pFilename )
  82. {
  83.     USES_CONVERSION;
  84.  
  85.     CFakeCallback pCallback;
  86.     HRESULT hr;
  87.  
  88.     printf("Grabbing samples from %s.\r\n", pFilename);
  89.  
  90.     // create a media detector
  91.     //
  92.     CComPtr< IMediaDet > pDet;
  93.     hr = CoCreateInstance( CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, 
  94.                            IID_IMediaDet, (void**) &pDet );
  95.     if( FAILED( hr ) ) 
  96.     {
  97.         printf( "Failed in CoCreateInstance!  hr=0x%x\r\n", hr );
  98.         return hr;
  99.     }
  100.  
  101.     // set filename
  102.     //
  103.     hr = pDet->put_Filename( T2W( pFilename ) );
  104.     if( FAILED( hr ) ) 
  105.     {
  106.         printf( "couldn't load the file!  hr=0x%x\r\n", hr );
  107.         return hr;
  108.     }
  109.  
  110.     // look for a video stream
  111.     //
  112.     long Streams = 0;
  113.     hr = pDet->get_OutputStreams( &Streams );
  114.     if( FAILED( hr ) ) 
  115.     {
  116.         printf( "couldn't get the output streams!  hr=0x%x\r\n", hr );
  117.         return hr;
  118.     }
  119.  
  120.     BOOL bFoundVideo = FALSE;
  121.  
  122.     for( int i = 0 ; i < Streams ; i++ )
  123.     {
  124.         BOOL bIsVideo = FALSE;
  125.  
  126.         AM_MEDIA_TYPE Type;
  127.         memset( &Type, 0, sizeof( Type ) );
  128.  
  129.         // Select a media stream
  130.         hr = pDet->put_CurrentStream( i );
  131.         if( FAILED( hr ) ) 
  132.         {
  133.             printf( "couldn't put stream %d  hr=0x%x\r\n", i, hr );
  134.             return hr;
  135.         }
  136.  
  137.         // Read the media type of the selected stream
  138.         hr = pDet->get_StreamMediaType( &Type );
  139.         if( FAILED( hr ) ) 
  140.         {
  141.             printf( "couldn't get stream media type for stream %d  hr=0x%x\r\n",
  142.                     i, hr );
  143.             return hr;
  144.         }
  145.  
  146.         // Does this stream contain video?
  147.         if( Type.majortype == MEDIATYPE_Video )
  148.             bIsVideo = TRUE;
  149.  
  150.         FreeMediaType( Type );
  151.  
  152.         if( !bIsVideo ) 
  153.             continue;
  154.  
  155.         // Found a video stream
  156.         bFoundVideo = TRUE;
  157.         break;
  158.     }
  159.  
  160.     if( !bFoundVideo )
  161.     {
  162.         printf( "Couldn't find a video stream\r\n" );
  163.         return 0;
  164.     }
  165.  
  166.     // this method will change the MediaDet to go into 
  167.     // "sample grabbing mode" at time 0.
  168.     //
  169.     hr = pDet->EnterBitmapGrabMode( 0.0 );
  170.     if( FAILED( hr ) ) 
  171.     {
  172.         printf( "Failed in EnterBitmapGrabMode!  hr=0x%x\r\n", hr );
  173.         return hr;
  174.     }
  175.  
  176.     // ask for the sample grabber filter that we know lives inside the
  177.     // graph made by the MediaDet
  178.     //
  179.     CComPtr< ISampleGrabber > pGrabber;
  180.     hr = pDet->GetSampleGrabber( &pGrabber );
  181.     if( FAILED(hr) || !pGrabber)
  182.     {
  183.         printf( "couldn't find the sample grabber filter!  hr=0x%x\r\n", hr );
  184.         return hr;
  185.     }
  186.  
  187.     // set the callback (our COM object callback)
  188.     //
  189.     CComQIPtr< ISampleGrabberCB, &IID_ISampleGrabberCB > pCB( &pCallback );
  190.     CComQIPtr< IBaseFilter, &IID_IBaseFilter > pFilter( pGrabber );
  191.     hr = pGrabber->SetCallback( pCB, 0 );
  192.     hr = pGrabber->SetOneShot( FALSE );       // don't do one-shot mode
  193.     hr = pGrabber->SetBufferSamples( FALSE ); // don't buffer samples
  194.  
  195.     // find the filter graph interface from the sample grabber filter
  196.     //
  197.     FILTER_INFO fi;
  198.     memset( &fi, 0, sizeof( fi ) );
  199.     hr = pFilter->QueryFilterInfo( &fi );
  200.     if( FAILED( hr ) ) 
  201.     {
  202.         printf( "Failed in QueryFilterInfo!  hr=0x%x\r\n", hr );
  203.         return hr;
  204.     }
  205.  
  206.     // Release the filter's graph reference
  207.     if( fi.pGraph ) 
  208.         fi.pGraph->Release( );
  209.     IFilterGraph * pGraph = fi.pGraph;
  210.  
  211.     // The graph will have been paused by entering bitmap grab mode.
  212.     // We'll need to seek back to 0 to get it to deliver correctly.
  213.     //
  214.     CComQIPtr< IMediaSeeking, &IID_IMediaSeeking > pSeeking( pGraph );
  215.     REFERENCE_TIME Start = 0;
  216.     REFERENCE_TIME Duration = 0;
  217.  
  218.     hr = pSeeking->GetDuration( &Duration );
  219.     if( FAILED( hr ) ) 
  220.     {
  221.         printf( "Failed in GetDuration!  hr=0x%x\r\n", hr );
  222.         return hr;
  223.     }
  224.  
  225.     hr = pSeeking->SetPositions( &Start,    AM_SEEKING_AbsolutePositioning, 
  226.                                  &Duration, AM_SEEKING_AbsolutePositioning );
  227.     if( FAILED( hr ) ) 
  228.     {
  229.         printf( "Failed in SetPositions!  hr=0x%x\r\n", hr );
  230.         return hr;
  231.     }
  232.  
  233.     // run the graph
  234.     //
  235.     CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
  236.     CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
  237.     hr = pControl->Run( );
  238.     if( FAILED( hr ) ) 
  239.     {
  240.         printf( "Failed to run the graph!  hr=0x%x\r\n", hr );
  241.         return hr;
  242.     }
  243.  
  244.     // wait 
  245.     //
  246.     long EventCode = 0;
  247.     hr = pEvent->WaitForCompletion( INFINITE, &EventCode );
  248.     if( FAILED( hr ) ) 
  249.     {
  250.         printf( "Failed in WaitForCompletion!  hr=0x%x\r\n", hr );
  251.         return hr;
  252.     }
  253.  
  254.     printf("Sample grabbing complete.\r\n");
  255.     return 0;
  256. }
  257.  
  258.