112 lines
3.6 KiB
C++
112 lines
3.6 KiB
C++
#include <dvcap/VideoCapture.hpp>
|
|
|
|
bool VideoCapture::locateDevice(ComPointer<IBaseFilter> &baseFilter,BString &deviceName)
|
|
{
|
|
ComInitializer comInit;
|
|
ComPointer<ICreateDevEnum> deviceEnumerator;
|
|
ComPointer<IEnumMoniker> enumMoniker;
|
|
ComPointer<IMoniker> moniker;
|
|
ComResult comResult;
|
|
ULONG cFetched;
|
|
|
|
baseFilter.Release();
|
|
comResult=deviceEnumerator.createInstance(CLSID_SystemDeviceEnum,IID_ICreateDevEnum);
|
|
if(comResult.error())return false;
|
|
comResult=deviceEnumerator->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,(IEnumMoniker**)enumMoniker,0);
|
|
if(comResult.error())return false;
|
|
while(enumMoniker->Next(1,(IMoniker**)moniker,&cFetched)==S_OK)
|
|
{
|
|
ComPointer<IPropertyBag> propertyBag;
|
|
moniker->BindToStorage(0,0,IID_IPropertyBag,(void **)(IPropertyBag**)propertyBag);
|
|
BString devName;
|
|
Variant varName;
|
|
comResult=propertyBag->Read(L"FriendlyName", &varName.getVARIANT(),0);
|
|
varName.getData(devName);
|
|
if(!comResult.error()&&devName==deviceName)
|
|
{
|
|
comResult=moniker->BindToObject(0,0,IID_IBaseFilter,(void**)(IBaseFilter**)baseFilter);
|
|
break;
|
|
}
|
|
}
|
|
return baseFilter.isOkay();
|
|
}
|
|
|
|
bool VideoCapture::capture(BString &deviceName)
|
|
{
|
|
ComPointer<IBaseFilter> baseFilter;
|
|
ComPointer<IGraphBuilder> graph;
|
|
// CComPtr<IGraphBuilder> pGraph;
|
|
CComPtr<ICaptureGraphBuilder2> pBuilder;
|
|
CComPtr<IBaseFilter> ppf;
|
|
CComPtr<IBaseFilter> pSrc;
|
|
ComResult comResult;
|
|
|
|
if(!locateDevice(baseFilter,deviceName))return false;
|
|
// comResult=pGraph.CoCreateInstance(CLSID_FilterGraph);
|
|
comResult=graph.createInstance(CLSID_FilterGraph);
|
|
if(!comResult.success())return false;
|
|
|
|
|
|
comResult=pBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2);
|
|
if(!comResult.success())return false;
|
|
pBuilder->SetFiltergraph(graph);
|
|
comResult=graph->AddFilter(baseFilter,L"Capture");
|
|
if(!comResult.success())return false;
|
|
comResult=pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi,L"d:\\cap.avi",&ppf,0);
|
|
if(!comResult.success())return false;
|
|
|
|
comResult=pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pSrc,0,ppf);
|
|
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Interleaved,pSrc,0,ppf);
|
|
// if(!comResult.success())return false;
|
|
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pSrc,0,0);
|
|
// if(!comResult.success())return false;
|
|
|
|
|
|
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pSrc,0,ppf);
|
|
// if(!comResult.success())return false;
|
|
// comResult=pBuilder->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,pSrc,0,0);
|
|
// if(!comResult.success())return false;
|
|
|
|
const long ONE_SECOND = 10000000;
|
|
REFERENCE_TIME rtStart = 5 * ONE_SECOND;
|
|
REFERENCE_TIME rtStop = 10 * ONE_SECOND;
|
|
comResult=pBuilder->ControlStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,pSrc,&rtStart,&rtStop,0,0);
|
|
if(comResult.error())
|
|
{
|
|
::OutputDebugString("Failed ControlStream\n");
|
|
return false;
|
|
}
|
|
CComQIPtr<IMediaControl> pControl(graph);
|
|
CComQIPtr<IMediaEventEx> pEvent(graph);
|
|
comResult=pControl->Run();
|
|
if(comResult.error())
|
|
{
|
|
::OutputDebugString("Run Error...\n");
|
|
return false;
|
|
}
|
|
while (1)
|
|
{
|
|
long evCode, lParam1, lParam2;
|
|
comResult=pEvent->GetEvent(&evCode, &lParam1, &lParam2, 100);
|
|
if(comResult.success())
|
|
{
|
|
comResult=pEvent->FreeEventParams(evCode, lParam1, lParam2);
|
|
if(evCode == EC_STREAM_CONTROL_STARTED)
|
|
{
|
|
::printf("Starting capture...\n");
|
|
}
|
|
else if (evCode == EC_STREAM_CONTROL_STOPPED)
|
|
{
|
|
::printf("Control Stopped...\n");
|
|
break;
|
|
}
|
|
}
|
|
else break;
|
|
}
|
|
pControl->Stop();
|
|
printf("... Done\n");
|
|
// baseFilter->Release();
|
|
return true;
|
|
}
|
|
|