// Create the file reader pSource.CoCreateInstance(CLSID_AsyncReader); if (!pSource) { _tprintf( TEXT("Could not create source filter\r\n") ); return -1; }
// Create the graph pGraph.CoCreateInstance(CLSID_FilterGraph); if( !pGraph ) { _tprintf( TEXT("Could not not create the graph\r\n") ); return -1; }
// Put them in the graph hr = pGraph->AddFilter( pSource, L"Source" ); hr = pGraph->AddFilter( pGrabberBase, L"Grabber" ); // Load the source CComQIPtr<IFileSourceFilter, &IID_IFileSourceFilter> pLoad(pSource); hr = pLoad->Load( T2W( szFile ), NULL ); if (FAILED(hr)) { _tprintf( TEXT("Could not load the media file\r\n") ); return -1; } CMediaType GrabType; GrabType.SetType(&MEDIATYPE_Audio); GrabType.SetSubtype(&MEDIASUBTYPE_PCM); GrabType.SetFormatType(&FORMAT_WaveFormatEx); hr = pGrabber->SetMediaType(&GrabType); // Get the output pin and the input pin CComPtr< IPin > pSourcePin; CComPtr< IPin > pGrabPin; pSourcePin = GetOutPin( pSource, 0 ); pGrabPin = GetInPin( pGrabberBase, 0 ); // ... and connect them hr = pGraph->Connect( pSourcePin, pGrabPin ); if( FAILED( hr ) ) { _tprintf( TEXT("Could not connect source filter to grabber\r\n") ); return -1; } CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 ); hr = pGraph->Render( pGrabOutPin ); if( FAILED( hr ) ) { _tprintf( TEXT("Could not render grabber output pin\r\n") ); return -1; }
// Don't buffer the samples as they pass through hr = pGrabber->SetBufferSamples( FALSE ); // Only grab one at a time, stop stream after grabbing one sample hr = pGrabber->SetOneShot(FALSE); // Set the callback, so we can grab the one sample CSampleGrabberCB CB; hr = pGrabber->SetCallback(&CB, 1); // Keep a useless clock from being instantiated.... CComQIPtr<IMediaFilter, &IID_IMediaFilter> pFilter(pGraph); hr = pFilter->SetSyncSource(NULL); if (FAILED(hr)) printf("SetNoClock: Failed to set sync source! hr=0x%x\n", hr); CComQIPtr<IVideoWindow, &IID_IVideoWindow> pWindow(pGraph); if (pWindow) hr = pWindow->put_AutoShow(OAFALSE); // activate the threads CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph ); hr = pControl->Run( ); // wait for the graph to settle CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph ); long EvCode = 0; hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
HRESULT SampleCB(
double SampleTime,
IMediaSample *pSample
);
#include <windows.h>
#include <streams.h>
#include <stdio.h>
#include <atlbase.h>
#include <qedit.h>
int GrabBitmaps(TCHAR * szFile);
HRESULT GetPin(IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin);
IPin * GetInPin ( IBaseFilter *pFilter, int Num );
IPin * GetOutPin( IBaseFilter *pFilter, int Num );
class CSampleGrabberCB : public ISampleGrabberCB {
public:
STDMETHODIMP_(ULONG) AddRef() { return 2; }
STDMETHODIMP_(ULONG) Release() { return 1; }
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv) {
CheckPointer(ppv,E_POINTER);
if( riid == IID_ISampleGrabberCB || riid == IID_IUnknown ) {
*ppv = (void *) static_cast<ISampleGrabberCB*> ( this );
return NOERROR;
}
return E_NOINTERFACE;
} STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ) {return 0;}
STDMETHODIMP BufferCB( double SampleTime, BYTE * pBuffer, long BufferSize ) {
_tprintf(TEXT("Found a sample at %f s\t[%ld]\r\n"), SampleTime , BufferSize );
return 0;
}
}
int _tmain(int argc, TCHAR* argv[]) {
if( argc != 2 || !argv || !argv[1] ) {
_tprintf( TEXT("GrabBitmaps: You must specify a media filename!\r\n") );
_tprintf( TEXT("Usage: GrabBitmaps Filename\r\n"));
return 0;
}
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// Read the filename from the command line
TCHAR szFile[MAX_PATH];
_tcsncpy(szFile, argv[1], MAX_PATH-1);
szFile[MAX_PATH-1] = 0; // Null-terminate
int nSuccess = GrabBitmaps(szFile);
CoUninitialize();
return nSuccess;
}
int GrabBitmaps(TCHAR * szFile ) {
USES_CONVERSION;
CComPtr< ISampleGrabber > pGrabber;
CComPtr< IBaseFilter > pSource;
CComPtr< IGraphBuilder > pGraph;
CComPtr< IVideoWindow > pVideoWindow;
HRESULT hr;
if (!szFile) return -1;
_tprintf(TEXT("Grabbing bitmaps from %s.\r\n"), szFile);
// Create the sample grabber
pGrabber.CoCreateInstance( CLSID_SampleGrabber );
if( !pGrabber ) {
_tprintf( TEXT("Could not create CLSID_SampleGrabber\r\n") );
return -1;
}
CComQIPtr<IBaseFilter, &IID_IBaseFilter> pGrabberBase(pGrabber);
// Create the file reader
pSource.CoCreateInstance(CLSID_AsyncReader);
if (!pSource) {
_tprintf( TEXT("Could not create source filter\r\n") );
return -1;
}
// Create the graph
pGraph.CoCreateInstance(CLSID_FilterGraph);
if( !pGraph ) {
_tprintf( TEXT("Could not not create the graph\r\n") );
return -1;
}
// Put them in the graph
hr = pGraph->AddFilter( pSource, L"Source" );
hr = pGraph->AddFilter( pGrabberBase, L"Grabber" );
// Load the source
CComQIPtr<IFileSourceFilter, &IID_IFileSourceFilter> pLoad(pSource);
hr = pLoad->Load( T2W( szFile ), NULL );
if (FAILED(hr)) {
_tprintf( TEXT("Could not load the media file\r\n") );
return -1;
}
CMediaType GrabType;
GrabType.SetType(&MEDIATYPE_Audio);
GrabType.SetSubtype(&MEDIASUBTYPE_PCM);
GrabType.SetFormatType(&FORMAT_WaveFormatEx);
hr = pGrabber->SetMediaType(&GrabType);
// Get the output pin and the input pin
CComPtr< IPin > pSourcePin;
CComPtr< IPin > pGrabPin;
pSourcePin = GetOutPin( pSource, 0 );
pGrabPin = GetInPin( pGrabberBase, 0 );
// ... and connect them
hr = pGraph->Connect( pSourcePin, pGrabPin );
if( FAILED( hr ) ) {
_tprintf( TEXT("Could not connect source filter to grabber\r\n") );
return -1;
}
CComPtr <IPin> pGrabOutPin = GetOutPin( pGrabberBase, 0 );
hr = pGraph->Render( pGrabOutPin );
if( FAILED( hr ) ) {
_tprintf( TEXT("Could not render grabber output pin\r\n") );
return -1;
}
// Don't buffer the samples as they pass through
hr = pGrabber->SetBufferSamples( FALSE );
// Only grab one at a time, stop stream after grabbing one sample
hr = pGrabber->SetOneShot(FALSE);
// Set the callback, so we can grab the one sample
CSampleGrabberCB CB;
hr = pGrabber->SetCallback(&CB, 1);
// Keep a useless clock from being instantiated....
CComQIPtr<IMediaFilter, &IID_IMediaFilter> pFilter(pGraph);
hr = pFilter->SetSyncSource(NULL);
if (FAILED(hr)) printf("SetNoClock: Failed to set sync source! hr=0x%x\n", hr);
CComQIPtr<IVideoWindow, &IID_IVideoWindow> pWindow(pGraph);
if (pWindow) hr = pWindow->put_AutoShow(OAFALSE);
// activate the threads
CComQIPtr< IMediaControl, &IID_IMediaControl > pControl( pGraph );
hr = pControl->Run( );
// wait for the graph to settle
CComQIPtr< IMediaEvent, &IID_IMediaEvent > pEvent( pGraph );
long EvCode = 0;
hr = pEvent->WaitForCompletion( INFINITE, &EvCode );
_tprintf(TEXT("Sample grabbing complete.\r\n"));
return 0;
}HRESULT GetPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, int iNum, IPin **ppPin) {
CComPtr< IEnumPins > pEnum;
*ppPin = NULL;
HRESULT hr = pFilter->EnumPins(&pEnum);
if(FAILED(hr)) return hr;
ULONG ulFound;
IPin *pPin;
hr = E_FAIL;
while (S_OK == pEnum->Next(1, &pPin, &ulFound)) {
PIN_DIRECTION pindir = (PIN_DIRECTION)3;
pPin->QueryDirection(&pindir);
if (pindir == dirrequired) {
if (iNum == 0) {
*ppPin = pPin; // Return the pin's interface
hr = S_OK; // Found requested pin, so clear error
break;
}
iNum--;
}
pPin->Release();
}
return hr;
}
IPin * GetInPin( IBaseFilter * pFilter, int nPin ) {
CComPtr<IPin> pComPin=0;
GetPin(pFilter, PINDIR_INPUT, nPin, &pComPin);
return pComPin;
}
IPin * GetOutPin( IBaseFilter * pFilter, int nPin ) {
CComPtr<IPin> pComPin=0;
GetPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin);
return pComPin;
}