Files
Work/dvcap/VideoCapture.cpp
2024-08-07 09:16:27 -04:00

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;
}