├── README └── vcam_vs_2010_demo_video_capture_project ├── Debug ├── register_run_as_administrator.bat ├── unregister_run_as_administrator.bat └── vcam_vs_2010.ax ├── vcam_vs_2010.sln └── vcam_vs_2010 ├── Dll.cpp ├── Filters.cpp ├── Filters.def ├── Filters.h ├── ReadMe.txt ├── dllmain.cpp ├── stdafx.cpp ├── stdafx.h ├── targetver.h ├── vcam_vs_2010.cpp ├── vcam_vs_2010.vcxproj ├── vcam_vs_2010.vcxproj.filters └── vcam_vs_2010.vcxproj.user /README: -------------------------------------------------------------------------------- 1 | simple demo "virtual camera" (fake camera) input. 2 | originally from http://tmhare.mvps.org/downloads.htm 3 | 4 | There is a "higher quality" dshow virtual inputter here: 5 | 6 | https://github.com/rdp/screen-capture-recorder-to-video-windows-free 7 | 8 | It also doesn't handle paused graphs well/right yet. 9 | in fillBuffer: 10 | // If graph is inactive stop cueing samples 11 | //if(!m_pParent->m_bActive || m_pParent->m_bEOF) 12 | // return S_FALSE; 13 | 14 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/Debug/register_run_as_administrator.bat: -------------------------------------------------------------------------------- 1 | @rem avoid a DllRegisterServer in ScreenCap Filter failed. Return code was: 0x80070005 2 | regsvr32 "%~dp0\vcam_vs_2010.ax" -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/Debug/unregister_run_as_administrator.bat: -------------------------------------------------------------------------------- 1 | @rem avoid a DllRegisterServer in ScreenCap Filter failed. Return code was: 0x80070005 2 | regsvr32 /u %~dp0\vcam_vs_2010.ax 3 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/Debug/vcam_vs_2010.ax: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdp/open-source-directshow-video-capture-demo-filter/779875ee22cb0df8e3ce5b099db5a766b75e1888/vcam_vs_2010_demo_video_capture_project/Debug/vcam_vs_2010.ax -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual C++ Express 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcam_vs_2010", "vcam_vs_2010\vcam_vs_2010.vcxproj", "{BE657D45-8F6A-461D-B019-8E57FE305329}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {BE657D45-8F6A-461D-B019-8E57FE305329}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {BE657D45-8F6A-461D-B019-8E57FE305329}.Debug|Win32.Build.0 = Debug|Win32 14 | {BE657D45-8F6A-461D-B019-8E57FE305329}.Release|Win32.ActiveCfg = Release|Win32 15 | {BE657D45-8F6A-461D-B019-8E57FE305329}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/Dll.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // This file contains routines to register / Unregister the 3 | // Directshow filter 'Virtual Cam' 4 | // We do not use the inbuilt BaseClasses routines as we need to register as 5 | // a capture source 6 | ////////////////////////////////////////////////////////////////////////// 7 | #include "stdafx.h" 8 | #pragma comment(lib, "kernel32") 9 | #pragma comment(lib, "user32") 10 | #pragma comment(lib, "gdi32") 11 | #pragma comment(lib, "advapi32") 12 | #pragma comment(lib, "winmm") 13 | #pragma comment(lib, "ole32") 14 | #pragma comment(lib, "oleaut32") 15 | 16 | #ifdef _DEBUG 17 | #pragma comment(lib, "strmbasd") 18 | #else 19 | #pragma comment(lib, "strmbase") 20 | #endif 21 | 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "filters.h" 28 | 29 | #define CreateComObject(clsid, iid, var) CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, iid, (void **)&var); 30 | 31 | STDAPI AMovieSetupRegisterServer( CLSID clsServer, LPCWSTR szDescription, LPCWSTR szFileName, LPCWSTR szThreadingModel = L"Both", LPCWSTR szServerType = L"InprocServer32" ); 32 | STDAPI AMovieSetupUnregisterServer( CLSID clsServer ); 33 | 34 | 35 | 36 | // {8E14549A-DB61-4309-AFA1-3578E927E933} 37 | DEFINE_GUID(CLSID_VirtualCam, 38 | 0x8e14549a, 0xdb61, 0x4309, 0xaf, 0xa1, 0x35, 0x78, 0xe9, 0x27, 0xe9, 0x33); 39 | 40 | 41 | const AMOVIESETUP_MEDIATYPE AMSMediaTypesVCam = 42 | { 43 | &MEDIATYPE_Video, 44 | &MEDIASUBTYPE_NULL 45 | }; 46 | 47 | const AMOVIESETUP_PIN AMSPinVCam= 48 | { 49 | L"Output", // Pin string name 50 | FALSE, // Is it rendered 51 | TRUE, // Is it an output 52 | FALSE, // Can we have none 53 | FALSE, // Can we have many 54 | &CLSID_NULL, // Connects to filter 55 | NULL, // Connects to pin 56 | 1, // Number of types 57 | &AMSMediaTypesVCam // Pin Media types 58 | }; 59 | 60 | const AMOVIESETUP_FILTER AMSFilterVCam = 61 | { 62 | &CLSID_VirtualCam, // Filter CLSID 63 | L"Virtual Cam", // String name 64 | MERIT_DO_NOT_USE, // Filter merit 65 | 1, // Number pins 66 | &AMSPinVCam // Pin details 67 | }; 68 | 69 | CFactoryTemplate g_Templates[] = 70 | { 71 | { 72 | L"Virtual Cam", 73 | &CLSID_VirtualCam, 74 | CVCam::CreateInstance, 75 | NULL, 76 | &AMSFilterVCam 77 | }, 78 | 79 | }; 80 | 81 | int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 82 | 83 | STDAPI RegisterFilters( BOOL bRegister ) 84 | { 85 | HRESULT hr = NOERROR; 86 | WCHAR achFileName[MAX_PATH]; 87 | char achTemp[MAX_PATH]; 88 | ASSERT(g_hInst != 0); 89 | 90 | if( 0 == GetModuleFileNameA(g_hInst, achTemp, sizeof(achTemp))) 91 | return AmHresultFromWin32(GetLastError()); 92 | 93 | MultiByteToWideChar(CP_ACP, 0L, achTemp, lstrlenA(achTemp) + 1, 94 | achFileName, NUMELMS(achFileName)); 95 | 96 | hr = CoInitialize(0); 97 | if(bRegister) 98 | { 99 | hr = AMovieSetupRegisterServer(CLSID_VirtualCam, L"Virtual Cam", achFileName, L"Both", L"InprocServer32"); 100 | } 101 | 102 | if( SUCCEEDED(hr) ) 103 | { 104 | IFilterMapper2 *fm = 0; 105 | hr = CreateComObject( CLSID_FilterMapper2, IID_IFilterMapper2, fm ); 106 | if( SUCCEEDED(hr) ) 107 | { 108 | if(bRegister) 109 | { 110 | IMoniker *pMoniker = 0; 111 | REGFILTER2 rf2; 112 | rf2.dwVersion = 1; 113 | rf2.dwMerit = MERIT_DO_NOT_USE; 114 | rf2.cPins = 1; 115 | rf2.rgPins = &AMSPinVCam; 116 | hr = fm->RegisterFilter(CLSID_VirtualCam, L"Virtual Cam", &pMoniker, &CLSID_VideoInputDeviceCategory, NULL, &rf2); 117 | } 118 | else 119 | { 120 | hr = fm->UnregisterFilter(&CLSID_VideoInputDeviceCategory, 0, CLSID_VirtualCam); 121 | } 122 | } 123 | 124 | // release interface 125 | // 126 | if(fm) 127 | fm->Release(); 128 | } 129 | 130 | if( SUCCEEDED(hr) && !bRegister ) 131 | hr = AMovieSetupUnregisterServer( CLSID_VirtualCam ); 132 | 133 | CoFreeUnusedLibraries(); 134 | CoUninitialize(); 135 | return hr; 136 | } 137 | 138 | STDAPI DllRegisterServer() 139 | { 140 | return RegisterFilters(TRUE); 141 | } 142 | 143 | STDAPI DllUnregisterServer() 144 | { 145 | return RegisterFilters(FALSE); 146 | } 147 | 148 | extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); 149 | 150 | BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) 151 | { 152 | return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved); 153 | } 154 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/Filters.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #pragma warning(disable:4244) 3 | #pragma warning(disable:4711) 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "filters.h" 10 | 11 | ////////////////////////////////////////////////////////////////////////// 12 | // CVCam is the source filter which masquerades as a capture device 13 | ////////////////////////////////////////////////////////////////////////// 14 | CUnknown * WINAPI CVCam::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) 15 | { 16 | ASSERT(phr); 17 | CUnknown *punk = new CVCam(lpunk, phr); 18 | return punk; 19 | } 20 | 21 | CVCam::CVCam(LPUNKNOWN lpunk, HRESULT *phr) : 22 | CSource(NAME("Virtual Cam"), lpunk, CLSID_VirtualCam) 23 | { 24 | ASSERT(phr); 25 | CAutoLock cAutoLock(&m_cStateLock); 26 | // Create the one and only output pin 27 | m_paStreams = (CSourceStream **) new CVCamStream*[1]; 28 | m_paStreams[0] = new CVCamStream(phr, this, L"Virtual Cam"); 29 | } 30 | 31 | HRESULT CVCam::QueryInterface(REFIID riid, void **ppv) 32 | { 33 | //Forward request for IAMStreamConfig & IKsPropertySet to the pin 34 | if(riid == _uuidof(IAMStreamConfig) || riid == _uuidof(IKsPropertySet)) 35 | return m_paStreams[0]->QueryInterface(riid, ppv); 36 | else 37 | return CSource::QueryInterface(riid, ppv); 38 | } 39 | 40 | ////////////////////////////////////////////////////////////////////////// 41 | // CVCamStream is the one and only output pin of CVCam which handles 42 | // all the stuff. 43 | ////////////////////////////////////////////////////////////////////////// 44 | CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) : 45 | CSourceStream(NAME("Virtual Cam"),phr, pParent, pPinName), m_pParent(pParent) 46 | { 47 | // Set the default media type as 320x240x24@15 48 | GetMediaType(4, &m_mt); 49 | } 50 | 51 | CVCamStream::~CVCamStream() 52 | { 53 | } 54 | 55 | HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv) 56 | { 57 | // Standard OLE stuff 58 | if(riid == _uuidof(IAMStreamConfig)) 59 | *ppv = (IAMStreamConfig*)this; 60 | else if(riid == _uuidof(IKsPropertySet)) 61 | *ppv = (IKsPropertySet*)this; 62 | else 63 | return CSourceStream::QueryInterface(riid, ppv); 64 | 65 | AddRef(); 66 | return S_OK; 67 | } 68 | 69 | 70 | ////////////////////////////////////////////////////////////////////////// 71 | // This is the routine where we create the data being output by the Virtual 72 | // Camera device. 73 | ////////////////////////////////////////////////////////////////////////// 74 | 75 | HRESULT CVCamStream::FillBuffer(IMediaSample *pms) 76 | { 77 | REFERENCE_TIME rtNow; 78 | 79 | REFERENCE_TIME avgFrameTime = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame; 80 | 81 | rtNow = m_rtLastTime; 82 | m_rtLastTime += avgFrameTime; 83 | 84 | 85 | BYTE *pData; 86 | long lDataLen; 87 | pms->GetPointer(&pData); 88 | lDataLen = pms->GetSize(); 89 | for(int i = 0; i < lDataLen; ++i) 90 | pData[i] = rand(); 91 | 92 | // set PTS (presentation) timestamps... 93 | CRefTime now; 94 | m_pParent->StreamTime(now); 95 | REFERENCE_TIME endThisFrame = now + avgFrameTime; 96 | pms->SetTime((REFERENCE_TIME *) &now, &endThisFrame); 97 | pms->SetSyncPoint(TRUE); 98 | // not sure on this one...probably should be true only for our first packet 99 | // pms->SetDiscontinuity(FALSE); 100 | 101 | return NOERROR; 102 | } // FillBuffer 103 | 104 | 105 | // 106 | // Notify 107 | // Ignore quality management messages sent from the downstream filter 108 | STDMETHODIMP CVCamStream::Notify(IBaseFilter * pSender, Quality q) 109 | { 110 | return E_NOTIMPL; 111 | } // Notify 112 | 113 | ////////////////////////////////////////////////////////////////////////// 114 | // This is called when the output format has been negotiated 115 | ////////////////////////////////////////////////////////////////////////// 116 | HRESULT CVCamStream::SetMediaType(const CMediaType *pmt) 117 | { 118 | DECLARE_PTR(VIDEOINFOHEADER, pvi, pmt->Format()); 119 | HRESULT hr = CSourceStream::SetMediaType(pmt); 120 | return hr; 121 | } 122 | 123 | // See Directshow help topic for IAMStreamConfig for details on this method 124 | HRESULT CVCamStream::GetMediaType(int iPosition, CMediaType *pmt) 125 | { 126 | if(iPosition < 0) return E_INVALIDARG; 127 | if(iPosition > 8) return VFW_S_NO_MORE_ITEMS; 128 | 129 | if(iPosition == 0) 130 | { 131 | *pmt = m_mt; 132 | return S_OK; 133 | } 134 | 135 | DECLARE_PTR(VIDEOINFOHEADER, pvi, pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER))); 136 | ZeroMemory(pvi, sizeof(VIDEOINFOHEADER)); 137 | 138 | pvi->bmiHeader.biCompression = BI_RGB; 139 | pvi->bmiHeader.biBitCount = 24; 140 | pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 141 | pvi->bmiHeader.biWidth = 80 * iPosition; 142 | pvi->bmiHeader.biHeight = 60 * iPosition; 143 | pvi->bmiHeader.biPlanes = 1; 144 | pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); 145 | pvi->bmiHeader.biClrImportant = 0; 146 | 147 | pvi->AvgTimePerFrame = 1000000; 148 | 149 | SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered. 150 | SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle 151 | 152 | pmt->SetType(&MEDIATYPE_Video); 153 | pmt->SetFormatType(&FORMAT_VideoInfo); 154 | pmt->SetTemporalCompression(FALSE); 155 | 156 | // Work out the GUID for the subtype from the header info. 157 | const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader); 158 | pmt->SetSubtype(&SubTypeGUID); 159 | pmt->SetSampleSize(pvi->bmiHeader.biSizeImage); 160 | 161 | return NOERROR; 162 | 163 | } // GetMediaType 164 | 165 | // This method is called to see if a given output format is supported 166 | HRESULT CVCamStream::CheckMediaType(const CMediaType *pMediaType) 167 | { 168 | VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)(pMediaType->Format()); 169 | if(*pMediaType != m_mt) 170 | return E_INVALIDARG; 171 | return S_OK; 172 | } // CheckMediaType 173 | 174 | // This method is called after the pins are connected to allocate buffers to stream data 175 | HRESULT CVCamStream::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties) 176 | { 177 | CAutoLock cAutoLock(m_pFilter->pStateLock()); 178 | HRESULT hr = NOERROR; 179 | 180 | VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) m_mt.Format(); 181 | pProperties->cBuffers = 1; 182 | pProperties->cbBuffer = pvi->bmiHeader.biSizeImage; 183 | 184 | ALLOCATOR_PROPERTIES Actual; 185 | hr = pAlloc->SetProperties(pProperties,&Actual); 186 | 187 | if(FAILED(hr)) return hr; 188 | if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL; 189 | 190 | return NOERROR; 191 | } // DecideBufferSize 192 | 193 | // Called when graph is run 194 | HRESULT CVCamStream::OnThreadCreate() 195 | { 196 | m_rtLastTime = 0; 197 | return NOERROR; 198 | } // OnThreadCreate 199 | 200 | 201 | ////////////////////////////////////////////////////////////////////////// 202 | // IAMStreamConfig 203 | ////////////////////////////////////////////////////////////////////////// 204 | 205 | HRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt) 206 | { 207 | DECLARE_PTR(VIDEOINFOHEADER, pvi, m_mt.pbFormat); 208 | m_mt = *pmt; 209 | IPin* pin; 210 | ConnectedTo(&pin); 211 | if(pin) 212 | { 213 | IFilterGraph *pGraph = m_pParent->GetGraph(); 214 | pGraph->Reconnect(this); 215 | } 216 | return S_OK; 217 | } 218 | 219 | HRESULT STDMETHODCALLTYPE CVCamStream::GetFormat(AM_MEDIA_TYPE **ppmt) 220 | { 221 | *ppmt = CreateMediaType(&m_mt); 222 | return S_OK; 223 | } 224 | 225 | HRESULT STDMETHODCALLTYPE CVCamStream::GetNumberOfCapabilities(int *piCount, int *piSize) 226 | { 227 | *piCount = 8; 228 | *piSize = sizeof(VIDEO_STREAM_CONFIG_CAPS); 229 | return S_OK; 230 | } 231 | 232 | HRESULT STDMETHODCALLTYPE CVCamStream::GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC) 233 | { 234 | *pmt = CreateMediaType(&m_mt); 235 | DECLARE_PTR(VIDEOINFOHEADER, pvi, (*pmt)->pbFormat); 236 | 237 | if (iIndex == 0) iIndex = 4; 238 | 239 | pvi->bmiHeader.biCompression = BI_RGB; 240 | pvi->bmiHeader.biBitCount = 24; 241 | pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 242 | pvi->bmiHeader.biWidth = 80 * iIndex; 243 | pvi->bmiHeader.biHeight = 60 * iIndex; 244 | pvi->bmiHeader.biPlanes = 1; 245 | pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader); 246 | pvi->bmiHeader.biClrImportant = 0; 247 | 248 | SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered. 249 | SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle 250 | 251 | (*pmt)->majortype = MEDIATYPE_Video; 252 | (*pmt)->subtype = MEDIASUBTYPE_RGB24; 253 | (*pmt)->formattype = FORMAT_VideoInfo; 254 | (*pmt)->bTemporalCompression = FALSE; 255 | (*pmt)->bFixedSizeSamples= FALSE; 256 | (*pmt)->lSampleSize = pvi->bmiHeader.biSizeImage; 257 | (*pmt)->cbFormat = sizeof(VIDEOINFOHEADER); 258 | 259 | DECLARE_PTR(VIDEO_STREAM_CONFIG_CAPS, pvscc, pSCC); 260 | 261 | pvscc->guid = FORMAT_VideoInfo; 262 | pvscc->VideoStandard = AnalogVideo_None; 263 | pvscc->InputSize.cx = 640; 264 | pvscc->InputSize.cy = 480; 265 | pvscc->MinCroppingSize.cx = 80; 266 | pvscc->MinCroppingSize.cy = 60; 267 | pvscc->MaxCroppingSize.cx = 640; 268 | pvscc->MaxCroppingSize.cy = 480; 269 | pvscc->CropGranularityX = 80; 270 | pvscc->CropGranularityY = 60; 271 | pvscc->CropAlignX = 0; 272 | pvscc->CropAlignY = 0; 273 | 274 | pvscc->MinOutputSize.cx = 80; 275 | pvscc->MinOutputSize.cy = 60; 276 | pvscc->MaxOutputSize.cx = 640; 277 | pvscc->MaxOutputSize.cy = 480; 278 | pvscc->OutputGranularityX = 0; 279 | pvscc->OutputGranularityY = 0; 280 | pvscc->StretchTapsX = 0; 281 | pvscc->StretchTapsY = 0; 282 | pvscc->ShrinkTapsX = 0; 283 | pvscc->ShrinkTapsY = 0; 284 | pvscc->MinFrameInterval = 200000; //50 fps 285 | pvscc->MaxFrameInterval = 50000000; // 0.2 fps 286 | pvscc->MinBitsPerSecond = (80 * 60 * 3 * 8) / 5; 287 | pvscc->MaxBitsPerSecond = 640 * 480 * 3 * 8 * 50; 288 | 289 | return S_OK; 290 | } 291 | 292 | ////////////////////////////////////////////////////////////////////////// 293 | // IKsPropertySet 294 | ////////////////////////////////////////////////////////////////////////// 295 | 296 | 297 | HRESULT CVCamStream::Set(REFGUID guidPropSet, DWORD dwID, void *pInstanceData, 298 | DWORD cbInstanceData, void *pPropData, DWORD cbPropData) 299 | {// Set: Cannot set any properties. 300 | return E_NOTIMPL; 301 | } 302 | 303 | // Get: Return the pin category (our only property). 304 | HRESULT CVCamStream::Get( 305 | REFGUID guidPropSet, // Which property set. 306 | DWORD dwPropID, // Which property in that set. 307 | void *pInstanceData, // Instance data (ignore). 308 | DWORD cbInstanceData, // Size of the instance data (ignore). 309 | void *pPropData, // Buffer to receive the property data. 310 | DWORD cbPropData, // Size of the buffer. 311 | DWORD *pcbReturned // Return the size of the property. 312 | ) 313 | { 314 | if (guidPropSet != AMPROPSETID_Pin) return E_PROP_SET_UNSUPPORTED; 315 | if (dwPropID != AMPROPERTY_PIN_CATEGORY) return E_PROP_ID_UNSUPPORTED; 316 | if (pPropData == NULL && pcbReturned == NULL) return E_POINTER; 317 | 318 | if (pcbReturned) *pcbReturned = sizeof(GUID); 319 | if (pPropData == NULL) return S_OK; // Caller just wants to know the size. 320 | if (cbPropData < sizeof(GUID)) return E_UNEXPECTED;// The buffer is too small. 321 | 322 | *(GUID *)pPropData = PIN_CATEGORY_CAPTURE; 323 | return S_OK; 324 | } 325 | 326 | // QuerySupported: Query whether the pin supports the specified property. 327 | HRESULT CVCamStream::QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport) 328 | { 329 | if (guidPropSet != AMPROPSETID_Pin) return E_PROP_SET_UNSUPPORTED; 330 | if (dwPropID != AMPROPERTY_PIN_CATEGORY) return E_PROP_ID_UNSUPPORTED; 331 | // We support getting this property, but not setting it. 332 | if (pTypeSupport) *pTypeSupport = KSPROPERTY_SUPPORT_GET; 333 | return S_OK; 334 | } 335 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/Filters.def: -------------------------------------------------------------------------------- 1 | LIBRARY vcam_vs_2010.ax 2 | EXPORTS 3 | DllMain PRIVATE 4 | DllGetClassObject PRIVATE 5 | DllCanUnloadNow PRIVATE 6 | DllRegisterServer PRIVATE 7 | DllUnregisterServer PRIVATE 8 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/Filters.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define DECLARE_PTR(type, ptr, expr) type* ptr = (type*)(expr); 4 | 5 | EXTERN_C const GUID CLSID_VirtualCam; 6 | 7 | class CVCamStream; 8 | class CVCam : public CSource 9 | { 10 | public: 11 | ////////////////////////////////////////////////////////////////////////// 12 | // IUnknown 13 | ////////////////////////////////////////////////////////////////////////// 14 | static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr); 15 | STDMETHODIMP QueryInterface(REFIID riid, void **ppv); 16 | 17 | IFilterGraph *GetGraph() {return m_pGraph;} 18 | 19 | private: 20 | CVCam(LPUNKNOWN lpunk, HRESULT *phr); 21 | }; 22 | 23 | class CVCamStream : public CSourceStream, public IAMStreamConfig, public IKsPropertySet 24 | { 25 | public: 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | // IUnknown 29 | ////////////////////////////////////////////////////////////////////////// 30 | STDMETHODIMP QueryInterface(REFIID riid, void **ppv); 31 | STDMETHODIMP_(ULONG) AddRef() { return GetOwner()->AddRef(); } \ 32 | STDMETHODIMP_(ULONG) Release() { return GetOwner()->Release(); } 33 | 34 | ////////////////////////////////////////////////////////////////////////// 35 | // IQualityControl 36 | ////////////////////////////////////////////////////////////////////////// 37 | STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); 38 | 39 | ////////////////////////////////////////////////////////////////////////// 40 | // IAMStreamConfig 41 | ////////////////////////////////////////////////////////////////////////// 42 | HRESULT STDMETHODCALLTYPE SetFormat(AM_MEDIA_TYPE *pmt); 43 | HRESULT STDMETHODCALLTYPE GetFormat(AM_MEDIA_TYPE **ppmt); 44 | HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(int *piCount, int *piSize); 45 | HRESULT STDMETHODCALLTYPE GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC); 46 | 47 | ////////////////////////////////////////////////////////////////////////// 48 | // IKsPropertySet 49 | ////////////////////////////////////////////////////////////////////////// 50 | HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwID, void *pInstanceData, DWORD cbInstanceData, void *pPropData, DWORD cbPropData); 51 | HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, void *pInstanceData,DWORD cbInstanceData, void *pPropData, DWORD cbPropData, DWORD *pcbReturned); 52 | HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport); 53 | 54 | ////////////////////////////////////////////////////////////////////////// 55 | // CSourceStream 56 | ////////////////////////////////////////////////////////////////////////// 57 | CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName); 58 | ~CVCamStream(); 59 | 60 | HRESULT FillBuffer(IMediaSample *pms); 61 | HRESULT DecideBufferSize(IMemAllocator *pIMemAlloc, ALLOCATOR_PROPERTIES *pProperties); 62 | HRESULT CheckMediaType(const CMediaType *pMediaType); 63 | HRESULT GetMediaType(int iPosition, CMediaType *pmt); 64 | HRESULT SetMediaType(const CMediaType *pmt); 65 | HRESULT OnThreadCreate(void); 66 | 67 | private: 68 | CVCam *m_pParent; 69 | REFERENCE_TIME m_rtLastTime; 70 | HBITMAP m_hLogoBmp; 71 | CCritSec m_cSharedState; 72 | IReferenceClock *m_pClock; 73 | 74 | }; 75 | 76 | 77 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/ReadMe.txt: -------------------------------------------------------------------------------- 1 | This is vcam "capture source filter" http://tmhare.mvps.org/downloads.htm 2 | updated for VS 2010 3 | 4 | To use it, you'll need to install VS 2010 express, the Microsoft SDK thus: 5 | http://betterlogic.com/roger/?p=3096 6 | 7 | Then examine the project properties and tweak the paths to match your own system. 8 | 9 | In sum, what was necessary was creating a new VS 2010 "dll" project, import the old files, 10 | adding #include "stdafx.h" to each, and adding the paths as stated in the above blog. 11 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | 4 | BOOL APIENTRY DllMain( HMODULE hModule, 5 | DWORD ul_reason_for_call, 6 | LPVOID lpReserved 7 | ) 8 | { 9 | switch (ul_reason_for_call) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | case DLL_THREAD_ATTACH: 13 | case DLL_THREAD_DETACH: 14 | case DLL_PROCESS_DETACH: 15 | break; 16 | } 17 | return TRUE; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // vcam_vs_2010.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/vcam_vs_2010.cpp: -------------------------------------------------------------------------------- 1 | // vcam_vs_2010.cpp : Defines the exported functions for the DLL application. 2 | // 3 | 4 | #include "stdafx.h" 5 | 6 | 7 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/vcam_vs_2010.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {BE657D45-8F6A-461D-B019-8E57FE305329} 15 | Win32Proj 16 | vcam_vs_2010 17 | 18 | 19 | 20 | DynamicLibrary 21 | true 22 | Unicode 23 | 24 | 25 | DynamicLibrary 26 | false 27 | true 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | .ax 43 | G:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include; 44 | $(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib;G:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses\Debug 45 | 46 | 47 | false 48 | .ax 49 | 50 | 51 | 52 | Use 53 | Level3 54 | Disabled 55 | WIN32;_DEBUG;_WINDOWS;_USRDLL;VCAM_VS_2010_EXPORTS;%(PreprocessorDefinitions) 56 | 57 | 58 | Windows 59 | true 60 | Filters.def 61 | 62 | 63 | 64 | 65 | Level3 66 | Use 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_WINDOWS;_USRDLL;VCAM_VS_2010_EXPORTS;%(PreprocessorDefinitions) 71 | 72 | 73 | Windows 74 | true 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Create 93 | Create 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/vcam_vs_2010.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | Source Files 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files 43 | 44 | 45 | Source Files 46 | 47 | 48 | -------------------------------------------------------------------------------- /vcam_vs_2010_demo_video_capture_project/vcam_vs_2010/vcam_vs_2010.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | c:\Program Files (x86)\VideoLAN\VLC\vlc.exe 5 | WindowsLocalDebugger 6 | 7 | --------------------------------------------------------------------------------