2,542
社区成员
发帖
与我相关
我的任务
分享
#include <DShow.h>
#include <qedit.h>
#include <iostream>
#pragma comment(lib, "Strmiids.lib")
#pragma comment(lib, "Quartz.lib")
AM_MEDIA_TYPE g_StillMediaType;
class SampleGrabberCallback : public ISampleGrabberCB
{
public:
// Fake referance counting.
STDMETHODIMP_(ULONG) AddRef() { return 1; }
STDMETHODIMP_(ULONG) Release() { return 2; }
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject)
{
if (NULL == ppvObject) return E_POINTER;
if (riid == __uuidof(IUnknown))
{
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
}
if (riid == __uuidof(ISampleGrabberCB))
{
*ppvObject = static_cast<ISampleGrabberCB*>(this);
return S_OK;
}
return E_NOTIMPL;
}
STDMETHODIMP SampleCB(double Time, IMediaSample *pSample)
{
return E_NOTIMPL;
}
STDMETHODIMP BufferCB(double Time, BYTE *pBuffer, long BufferLen)
{
if ((g_StillMediaType.majortype != MEDIATYPE_Video) ||
(g_StillMediaType.formattype != FORMAT_VideoInfo) ||
(g_StillMediaType.cbFormat < sizeof(VIDEOINFOHEADER)) ||
(g_StillMediaType.pbFormat == NULL))
{
return VFW_E_INVALIDMEDIATYPE;
}
HANDLE hf = CreateFile(L"C:\\Example.bmp", GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
if (hf == INVALID_HANDLE_VALUE)
{
return E_FAIL;
}
long cbBitmapInfoSize = g_StillMediaType.cbFormat - SIZE_PREHEADER;
VIDEOINFOHEADER *pVideoHeader =
(VIDEOINFOHEADER*)g_StillMediaType.pbFormat;
BITMAPFILEHEADER bfh;
ZeroMemory(&bfh, sizeof(bfh));
bfh.bfType = 'MB'; // Little-endian for "MB".
bfh.bfSize = sizeof( bfh ) + BufferLen + cbBitmapInfoSize;
bfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + cbBitmapInfoSize;
// Write the file header.
DWORD dwWritten = 0;
WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );
WriteFile(hf, HEADER(pVideoHeader), cbBitmapInfoSize, &dwWritten, NULL);
WriteFile( hf, pBuffer, BufferLen, &dwWritten, NULL );
CloseHandle( hf );
return S_OK;
}
};
// Global instance of the class.
SampleGrabberCallback g_StillCapCB;
HRESULT InitCaptureGraphBuilder(IGraphBuilder **ppGraph,
ICaptureGraphBuilder2 **ppBuild)
{
if (!ppGraph || !ppBuild)
return E_POINTER;
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuild = NULL;
HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
(void**)&pGraph);
if (SUCCEEDED(hr))
{
pBuild->SetFiltergraph(pGraph);
*ppBuild = pBuild;
*ppGraph = pGraph;
return S_OK;
}
else
{
pBuild->Release();
}
}
return hr;
}
int main()
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED );
IGraphBuilder *pGraph = NULL;
ICaptureGraphBuilder2 *pBuild = NULL;
InitCaptureGraphBuilder(&pGraph, &pBuild);
ICreateDevEnum *pDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
(void**)&pDevEnum);
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0);
IMoniker *pMoniker = NULL;
ULONG cFetched = 0;
while(pEnum->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void**)&pPropBag);
if (FAILED(hr))
{
pMoniker->Release();
continue;
}
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"DesCription", &varName, 0);
if (FAILED(hr))
{
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
}
VariantClear(&varName);
pPropBag->Release();
//pMoniker->Release();
}
IBaseFilter *pCap = NULL;
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
hr = pGraph->AddFilter(pCap, L"Capture Filter");
IMediaControl *pContorl = NULL;
hr = pGraph->QueryInterface(IID_IMediaControl, (void**)&pContorl);
hr = pContorl->Run();
IAMVideoControl *pAMVidControl = NULL;
hr = pCap->QueryInterface(IID_IAMVideoControl, (void**)&pAMVidControl);
IPin *pPin = 0;
hr = pBuild->FindPin(pCap, PINDIR_OUTPUT, &PIN_CATEGORY_STILL, 0,
FALSE, 0, &pPin);
hr = pAMVidControl->SetMode(pPin, VideoControlFlag_Trigger);
//pPin->Release();
//pAMVidControl->Release();
// Add the Sample Grabber filter to the graph.
IBaseFilter *pSG_Filter;
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pSG_Filter);
hr = pGraph->AddFilter(pSG_Filter, L"SampleGrab");
// Add the Null Renderer filter to the graph.
IBaseFilter *pNull;
hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void**)&pNull);
hr = pGraph->AddFilter(pNull, L"NullRender");
hr = pBuild->RenderStream(
&PIN_CATEGORY_STILL, // Connect this pin ...
&MEDIATYPE_Video, // with this media type ...
pCap, // on this filter ...
pSG_Filter, // to the Sample Grabber ...
pNull); // ... and finally to the Null Renderer.
ISampleGrabber *pGrabber;
pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pGrabber);
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pGrabber->SetMediaType(&mt);
pGrabber->SetOneShot(FALSE);
pGrabber->SetBufferSamples(TRUE);
pGrabber->SetCallback(&g_StillCapCB, 0);
//hr = pGrabber->GetConnectedMediaType(&g_StillMediaType);
getchar();
pGrabber->Release();
//FreeMediaType(g_StillMediaType);
pCap->Release();
pMoniker->Release();
pGraph->Release();
pBuild->Release();
CoUninitialize();
return 0;
}