3 CCallback::CCallback() : m_pCallback(NULL), m_cRef(1)
\r
7 CCallback::~CCallback()
\r
14 STDMETHODIMP CCallback::QueryInterface(REFIID riid, void **ppv)
\r
16 if (riid == IID_IUnknown) {
\r
17 *ppv = static_cast<IUnknown*>(this);
\r
18 } else if (riid == IID_ICaptureCallBack) {
\r
19 *ppv = static_cast<ICaptureCallBack*>(this);
\r
22 StringFromIID(riid, &str);
\r
24 return E_NOINTERFACE;
\r
26 reinterpret_cast<IUnknown*>(this)->AddRef();
\r
30 STDMETHODIMP CCallback::CaptureCallback(ULONG dwSize, BYTE *pBuffer)
\r
32 if (m_pCallback(dwSize, pBuffer)) {
\r
38 STDMETHODIMP CCallback::SetCallback(CallbackFn pCallbackFn)
\r
40 m_pCallback = pCallbackFn;
\r
44 STDMETHODIMP_(ULONG) CCallback::AddRef()
\r
46 return InterlockedIncrement(&m_cRef);
\r
49 STDMETHODIMP_(ULONG) CCallback::Release()
\r
51 if( InterlockedDecrement(&m_cRef) == 0)
\r
66 m_pOutputPin = NULL;
\r
72 m_dwFourcc = MAKEFOURCC('Y','U','Y','2');
\r
75 m_dwAvgInterval = 333333;
\r
84 STDMETHODIMP HWCSP::Init()
\r
88 hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_pGB);
\r
92 hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&m_pCGB);
\r
96 hr = m_pCGB->SetFiltergraph(m_pGB);
\r
100 hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
\r
104 hr = m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME);
\r
108 m_pCallback = new CCallback;
\r
109 if (m_pCallback == NULL)
\r
110 hr = E_OUTOFMEMORY;
\r
115 STDMETHODIMP HWCSP::BindSourceFilter()
\r
119 ICreateDevEnum *pCreateDevEnum = NULL;
\r
120 hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&pCreateDevEnum);
\r
124 IEnumMoniker *pEnumMK = NULL;
\r
125 hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMK, 0);
\r
128 pCreateDevEnum->Release();
\r
134 pCreateDevEnum->Release();
\r
139 IMoniker *pMoniKer;
\r
140 hr = pEnumMK->Next(1, &pMoniKer, NULL);
\r
147 IPropertyBag *pBag = NULL;
\r
148 IBaseFilter *temp = NULL;
\r
149 hr = pMoniKer->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
\r
154 hr = pBag->Read(L"FriendlyName", &var, NULL);
\r
157 hr = pMoniKer->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&m_pDF);
\r
160 //Counldn't bind moniker to filter object!!
\r
166 SysFreeString(var.bstrVal);
\r
170 pMoniKer->Release();
\r
175 hr = m_pGB->AddFilter(m_pDF, L"Video Capture");
\r
176 if (hr != S_OK && hr != S_FALSE)
\r
178 //Counldn't add Video Capture filter to our graph!
\r
185 STDMETHODIMP HWCSP::BindTargetFilter()
\r
188 IClassFactory *pClassFactory= NULL;
\r
189 hr = DllGetClassObject(CLSID_HWCFilterClass, IID_IClassFactory, (void**)&pClassFactory);
\r
193 IBaseFilter *pHWCFilter = NULL;
\r
194 pClassFactory->CreateInstance(NULL, IID_IBaseFilter, (void**)&pHWCFilter);
\r
197 SAFE_RELEASE(pClassFactory);
\r
200 m_pSF = pHWCFilter;
\r
204 hr = m_pGB->AddFilter(m_pSF, L"HWCFilter");
\r
207 //Counldn't add HWCFilterr to our graph!
\r
210 SAFE_RELEASE(pClassFactory);
\r
215 STDMETHODIMP HWCSP::ConnectFilters()
\r
219 hr = GetPin(m_pDF, PINDIR_OUTPUT , &m_pOutputPin);
\r
223 hr = GetPin(m_pSF, PINDIR_INPUT , &m_pInputPin);
\r
227 hr = m_pGB->Connect(m_pOutputPin, m_pInputPin);
\r
231 STDMETHODIMP_(void) HWCSP::CloseInterfaces()
\r
237 m_pOutputPin->Disconnect();
\r
239 SAFE_RELEASE(m_pGB);
\r
240 SAFE_RELEASE(m_pCGB);
\r
241 SAFE_RELEASE(m_pMC);
\r
242 SAFE_RELEASE(m_pME);
\r
243 SAFE_RELEASE(m_pOutputPin);
\r
244 SAFE_RELEASE(m_pInputPin);
\r
245 SAFE_RELEASE(m_pDF);
\r
246 SAFE_RELEASE(m_pSF);
\r
247 SAFE_RELEASE(m_pCallback);
\r
250 FreeLibrary(m_hDLL);
\r
255 STDMETHODIMP_(void) HWCSP::DeleteMediaType(AM_MEDIA_TYPE *pmt)
\r
261 if (pmt->cbFormat != 0) {
\r
262 CoTaskMemFree((PVOID)pmt->pbFormat);
\r
264 pmt->pbFormat = NULL;
\r
266 if (pmt->pUnk != NULL) {
\r
267 pmt->pUnk->Release();
\r
271 CoTaskMemFree((PVOID)pmt);
\r
274 STDMETHODIMP HWCSP::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
\r
277 IEnumPins *pEnum = NULL;
\r
285 hr = pFilter->EnumPins(&pEnum);
\r
289 while(pEnum->Next(1, &pPin, 0) == S_OK)
\r
291 PIN_DIRECTION PinDirThis;
\r
292 hr = pPin->QueryDirection(&PinDirThis);
\r
295 SAFE_RELEASE(pPin);
\r
296 SAFE_RELEASE(pEnum);
\r
299 if (PinDir == PinDirThis)
\r
302 SAFE_RELEASE(pEnum);
\r
305 SAFE_RELEASE(pPin);
\r
308 SAFE_RELEASE(pEnum);
\r
312 STDMETHODIMP HWCSP::QueryVideoProcAmp(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)
\r
316 IAMVideoProcAmp *pProcAmp = NULL;
\r
317 hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
\r
324 hr = pProcAmp->GetRange(nProperty, pMin, pMax, pStep, pDefault, &Flags);
\r
326 SAFE_RELEASE(pProcAmp);
\r
330 STDMETHODIMP HWCSP::GetVideoProcAmp(long nProperty, long *pValue)
\r
334 IAMVideoProcAmp *pProcAmp = NULL;
\r
335 hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
\r
340 hr = pProcAmp->Get(nProperty, pValue, &Flags);
\r
344 SAFE_RELEASE(pProcAmp);
\r
348 STDMETHODIMP HWCSP::SetVideoProcAmp(long nProperty, long value)
\r
352 IAMVideoProcAmp *pProcAmp = NULL;
\r
353 hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);
\r
357 hr = pProcAmp->Set(nProperty, value, VideoProcAmp_Flags_Manual);
\r
358 SAFE_RELEASE(pProcAmp);
\r
362 STDMETHODIMP HWCSP::StartPreview()
\r
366 hr = ((IHWCPin*)m_pInputPin)->SetCallback((ICaptureCallBack*)m_pCallback);
\r
374 STDMETHODIMP HWCSP::StopPreview()
\r
377 hr = ((IHWCPin*)m_pInputPin)->SetCallback(NULL);
\r
380 hr = m_pMC->Stop();
\r
383 STDMETHODIMP HWCSP::GetDeviceCaps(ULONG *fourcc, ULONG *width, ULONG *height, ULONG *fps)
\r
386 IAMStreamConfig* vsc = NULL;
\r
387 AM_MEDIA_TYPE* pmt = NULL;
\r
388 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);
\r
392 hr = vsc->GetFormat(&pmt);
\r
401 if (pmt->formattype == FORMAT_VideoInfo)
\r
403 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
\r
404 if (pvi->bmiHeader.biBitCount == 24 && pvi->bmiHeader.biCompression == BI_RGB) {
\r
405 *fourcc = MAKEFOURCC('R', 'G', 'B', '3');
\r
407 *fourcc = (ULONG)pvi->bmiHeader.biCompression;
\r
409 *width = (ULONG)pvi->bmiHeader.biWidth;
\r
410 *height = (ULONG)pvi->bmiHeader.biHeight;
\r
411 *fps = (ULONG)pvi->AvgTimePerFrame;
\r
413 DeleteMediaType(pmt);
\r
420 STDMETHODIMP HWCSP::SetFPS(REFERENCE_TIME inFps)
\r
423 IAMStreamConfig* vsc = NULL;
\r
424 AM_MEDIA_TYPE* pmt = NULL;
\r
425 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);
\r
429 hr = vsc->GetFormat(&pmt);
\r
438 if (pmt->formattype == FORMAT_VideoInfo)
\r
440 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
\r
441 pvi->AvgTimePerFrame = inFps;
\r
442 hr = vsc->SetFormat(pmt);
\r
444 DeleteMediaType(pmt);
\r
450 STDMETHODIMP HWCSP::GetFPS(REFERENCE_TIME *outFps)
\r
453 IAMStreamConfig* vsc = NULL;
\r
454 AM_MEDIA_TYPE* pmt = NULL;
\r
455 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);
\r
459 hr = vsc->GetFormat(&pmt);
\r
468 if (pmt->formattype == FORMAT_VideoInfo)
\r
470 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
\r
471 *outFps = pvi->AvgTimePerFrame;
\r
473 DeleteMediaType(pmt);
\r
480 STDMETHODIMP HWCSP::SetResolution(LONG width, LONG height)
\r
483 IAMStreamConfig* vsc = NULL;
\r
484 AM_MEDIA_TYPE* pmt = NULL;
\r
485 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);
\r
489 hr = vsc->GetFormat(&pmt);
\r
498 if (pmt->formattype == FORMAT_VideoInfo)
\r
500 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
\r
501 pvi->bmiHeader.biWidth = width;
\r
502 pvi->bmiHeader.biHeight = height;
\r
503 pvi->AvgTimePerFrame = 333333;
\r
504 pvi->bmiHeader.biSizeImage = ((width * pvi->bmiHeader.biBitCount) >> 3 ) * height;
\r
505 hr = vsc->SetFormat(pmt);
\r
507 DeleteMediaType(pmt);
\r
513 STDMETHODIMP HWCSP::GetResolution(LONG *width, LONG *height)
\r
516 IAMStreamConfig* vsc = NULL;
\r
517 AM_MEDIA_TYPE* pmt = NULL;
\r
518 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);
\r
522 hr = vsc->GetFormat(&pmt);
\r
531 if (pmt->formattype == FORMAT_VideoInfo)
\r
533 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
\r
534 *width = pvi->bmiHeader.biWidth;
\r
535 *height = pvi->bmiHeader.biHeight;
\r
537 DeleteMediaType(pmt);
\r
543 STDMETHODIMP HWCSP::GetFormats(LPVOID pData)
\r
546 IAMStreamConfig *pSC;
\r
551 HWCParam *param = (HWCParam*)pData;
\r
553 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSC);
\r
557 int iCount = 0, iSize = 0, nIndex = 0;
\r
558 hr = pSC->GetNumberOfCapabilities(&iCount, &iSize);
\r
565 if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
\r
567 for (int iFormat = 0; iFormat < iCount; iFormat++)
\r
569 VIDEO_STREAM_CONFIG_CAPS scc;
\r
570 AM_MEDIA_TYPE *pmtConfig;
\r
571 hr = pSC->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
\r
574 if (pmtConfig != NULL && pmtConfig->formattype == FORMAT_VideoInfo)
\r
576 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
\r
580 DeleteMediaType(pmtConfig);
\r
587 STDMETHODIMP HWCSP::GetFrameSizes(LPVOID pData)
\r
590 IAMStreamConfig *pSC;
\r
595 HWCParam *param = (HWCParam*)pData;
\r
596 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSC);
\r
600 int iCount = 0, iSize = 0, nIndex = 0;
\r
601 hr = pSC->GetNumberOfCapabilities(&iCount, &iSize);
\r
608 if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
\r
610 for (int iFormat = 0; iFormat < iCount; iFormat++)
\r
612 VIDEO_STREAM_CONFIG_CAPS scc;
\r
613 AM_MEDIA_TYPE *pmtConfig;
\r
614 hr = pSC->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
\r
617 if (pmtConfig != NULL && pmtConfig->formattype == FORMAT_VideoInfo)
\r
619 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
\r
623 DeleteMediaType(pmtConfig);
\r
630 STDMETHODIMP HWCSP::SetDefaultValues()
\r
633 IAMStreamConfig *pSConfig;
\r
635 hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSConfig);
\r
639 int iCount = 0, iSize = 0;
\r
640 hr = pSConfig->GetNumberOfCapabilities(&iCount, &iSize);
\r
643 pSConfig->Release();
\r
647 if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
\r
649 for (int iFormat = 0; iFormat < iCount; iFormat++)
\r
651 VIDEO_STREAM_CONFIG_CAPS scc;
\r
652 AM_MEDIA_TYPE *pmtConfig;
\r
654 hr = pSConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
\r
657 if (pmtConfig->formattype == FORMAT_VideoInfo)
\r
659 VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;
\r
660 if ((pvi->bmiHeader.biWidth == m_dwWidth) &&
\r
661 (pvi->bmiHeader.biHeight == m_dwHeight) &&
\r
662 (pvi->bmiHeader.biCompression == m_dwFourcc))
\r
664 pvi->AvgTimePerFrame = (REFERENCE_TIME)m_dwAvgInterval;
\r
665 pSConfig->SetFormat(pmtConfig);
\r
669 DeleteMediaType(pmtConfig);
\r
672 pSConfig->Release();
\r
676 STDMETHODIMP HWCSP::GetFrameIntervals(LPVOID pData)
\r
680 STDMETHODIMP HWCSP::SetCallback(CallbackFn pCallback)
\r
682 if (m_pCallback == NULL) {
\r
685 return m_pCallback->SetCallback(pCallback);
\r
688 static HWCSP *g_pObject = NULL;
\r
690 STDMETHODIMP HWCOpen()
\r
694 g_pObject = new HWCSP();
\r
695 hr = g_pObject->Init();
\r
699 hr = g_pObject->BindSourceFilter();
\r
703 hr = g_pObject->BindTargetFilter();
\r
707 hr = g_pObject->ConnectFilters();
\r
711 hr = g_pObject->SetDefaultValues();
\r
722 STDMETHODIMP HWCClose()
\r
729 STDMETHODIMP HWCStart()
\r
732 return g_pObject->StartPreview();
\r
737 STDMETHODIMP HWCStop()
\r
740 return g_pObject->StopPreview();
\r
745 STDMETHODIMP HWCSetFPS(long num, long denom)
\r
748 REFERENCE_TIME inFps = (REFERENCE_TIME)(10000000 * num / denom);
\r
749 hr = g_pObject->SetFPS(inFps);
\r
753 STDMETHODIMP HWCGetFPS(long *num, long *denom)
\r
756 REFERENCE_TIME outFps = 0;
\r
757 hr = g_pObject->GetFPS(&outFps);
\r
758 if (SUCCEEDED(hr)) {
\r
760 *denom = (long)(10000000 / outFps);
\r
768 STDMETHODIMP HWCSetFormat(long width, long height)
\r
771 hr = g_pObject->SetResolution(width, height);
\r
774 STDMETHODIMP HWCGetFormat()
\r
778 STDMETHODIMP HWCTryFormat()
\r
782 STDMETHODIMP HWCEnumFormat()
\r
787 STDMETHODIMP HWCQueryControl(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)
\r
790 return g_pObject->QueryVideoProcAmp(nProperty, pMin, pMax, pStep, pDefault);
\r
795 STDMETHODIMP HWCSetControlValue(long nProperty, long value)
\r
798 return g_pObject->SetVideoProcAmp(nProperty, value);
\r
803 STDMETHODIMP HWCGetControlValue(long nProperty, long *pVal)
\r
806 return g_pObject->GetVideoProcAmp(nProperty, pVal);
\r
811 STDMETHODIMP HWCEnumFrameSizes()
\r
815 STDMETHODIMP HWCEnumFrameIntervals()
\r
820 HWCFILTER_API HWCSetCallback(CallbackFn pCallback)
\r
822 HRESULT hr = g_pObject->SetCallback(pCallback);
\r
826 HWCFILTER_API HWCCtrl(UINT nCmd, UINT nSize, LPVOID pBuf)
\r
829 HWCParam *param = NULL;
\r
832 param = (HWCParam *)pBuf;
\r
849 hr = HWCSetFPS(param->val1, param->val2);
\r
852 hr = HWCGetFPS(¶m->val1, ¶m->val2);
\r
855 hr = HWCSetFormat(param->val1, param->val2);
\r
864 hr = HWCQueryControl(param->val1, ¶m->val2, ¶m->val3,
\r
865 ¶m->val4, ¶m->val5);
\r
868 hr = HWCSetControlValue(param->val1, param->val2);
\r
871 hr = HWCGetControlValue(param->val1, ¶m->val2);
\r
873 case HWC_ENUM_FSIZES:
\r
875 case HWC_ENUM_INTERVALS:
\r