+#include "hwcsp.h"\r
+\r
+CCallback::CCallback() : m_pCallback(NULL), m_cRef(1)\r
+{\r
+}\r
+\r
+CCallback::~CCallback()\r
+{\r
+ if (m_pCallback) {\r
+ m_pCallback = NULL;\r
+ }\r
+}\r
+\r
+STDMETHODIMP CCallback::QueryInterface(REFIID riid, void **ppv)\r
+{\r
+ if (riid == IID_IUnknown) {\r
+ *ppv = static_cast<IUnknown*>(this);\r
+ } else if (riid == IID_ICaptureCallBack) {\r
+ *ppv = static_cast<ICaptureCallBack*>(this);\r
+ } else {\r
+ LPWSTR str;\r
+ StringFromIID(riid, &str);\r
+ *ppv = NULL;\r
+ return E_NOINTERFACE;\r
+ }\r
+ reinterpret_cast<IUnknown*>(this)->AddRef();\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CCallback::CaptureCallback(ULONG dwSize, BYTE *pBuffer)\r
+{ \r
+ if (m_pCallback(dwSize, pBuffer)) {\r
+ return S_OK;\r
+ }\r
+ return E_FAIL;\r
+}\r
+\r
+STDMETHODIMP CCallback::SetCallback(CallbackFn pCallbackFn)\r
+{\r
+ m_pCallback = pCallbackFn;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CCallback::AddRef()\r
+{\r
+ return InterlockedIncrement(&m_cRef);\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CCallback::Release()\r
+{\r
+ if( InterlockedDecrement(&m_cRef) == 0)\r
+ {\r
+ delete this;\r
+ return 0;\r
+ }\r
+ return m_cRef;\r
+}\r
+\r
+HWCSP::HWCSP()\r
+{\r
+ CoInitialize(NULL);\r
+ m_pGB = NULL;\r
+ m_pCGB = NULL;\r
+ m_pMC = NULL;\r
+ m_pME = NULL;\r
+ m_pOutputPin = NULL;\r
+ m_pInputPin = NULL;\r
+ m_pDF = NULL;\r
+ m_pSF = NULL;\r
+ m_hDLL = NULL;\r
+ m_pCallback = NULL;\r
+ m_dwFourcc = MAKEFOURCC('Y','U','Y','2');\r
+ m_dwWidth = 640;\r
+ m_dwHeight = 480;\r
+ m_dwAvgInterval = 333333;\r
+}\r
+\r
+HWCSP::~HWCSP()\r
+{\r
+ CloseInterfaces();\r
+ CoUninitialize();\r
+}\r
+\r
+STDMETHODIMP HWCSP::Init()\r
+{\r
+ HRESULT hr;\r
+\r
+ hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_pGB);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&m_pCGB);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = m_pCGB->SetFiltergraph(m_pGB);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ m_pCallback = new CCallback;\r
+ if (m_pCallback == NULL)\r
+ hr = E_OUTOFMEMORY;\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::BindSourceFilter()\r
+{\r
+ HRESULT hr;\r
+ \r
+ ICreateDevEnum *pCreateDevEnum = NULL;\r
+ hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void**)&pCreateDevEnum);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ IEnumMoniker *pEnumMK = NULL;\r
+ hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumMK, 0);\r
+ if (FAILED(hr))\r
+ {\r
+ pCreateDevEnum->Release();\r
+ return hr;\r
+ }\r
+ \r
+ if (!pEnumMK)\r
+ {\r
+ pCreateDevEnum->Release();\r
+ return E_FAIL;\r
+ }\r
+ pEnumMK->Reset();\r
+\r
+ IMoniker *pMoniKer;\r
+ hr = pEnumMK->Next(1, &pMoniKer, NULL);\r
+ if (hr == S_FALSE)\r
+ {\r
+ hr = E_FAIL;\r
+ }\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ IPropertyBag *pBag = NULL;\r
+ IBaseFilter *temp = NULL;\r
+ hr = pMoniKer->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);\r
+ if(SUCCEEDED(hr)) \r
+ {\r
+ VARIANT var;\r
+ var.vt = VT_BSTR;\r
+ hr = pBag->Read(L"FriendlyName", &var, NULL);\r
+ if (hr == NOERROR)\r
+ {\r
+ hr = pMoniKer->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&m_pDF);\r
+ if (FAILED(hr))\r
+ {\r
+ //Counldn't bind moniker to filter object!!\r
+ }\r
+ else\r
+ {\r
+ m_pDF->AddRef();\r
+ }\r
+ SysFreeString(var.bstrVal);\r
+ }\r
+ pBag->Release();\r
+ }\r
+ pMoniKer->Release();\r
+ }\r
+\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ hr = m_pGB->AddFilter(m_pDF, L"Video Capture");\r
+ if (hr != S_OK && hr != S_FALSE)\r
+ {\r
+ //Counldn't add Video Capture filter to our graph!\r
+ }\r
+ }\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::BindTargetFilter()\r
+{\r
+ HRESULT hr;\r
+ IClassFactory *pClassFactory= NULL;\r
+ hr = DllGetClassObject(CLSID_HWCFilterClass, IID_IClassFactory, (void**)&pClassFactory);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ IBaseFilter *pHWCFilter = NULL;\r
+ pClassFactory->CreateInstance(NULL, IID_IBaseFilter, (void**)&pHWCFilter);\r
+ if (FAILED(hr))\r
+ {\r
+ SAFE_RELEASE(pClassFactory);\r
+ return hr;\r
+ }\r
+ m_pSF = pHWCFilter;\r
+\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ hr = m_pGB->AddFilter(m_pSF, L"HWCFilter");\r
+ if (FAILED(hr))\r
+ {\r
+ //Counldn't add HWCFilterr to our graph!\r
+ }\r
+ }\r
+ SAFE_RELEASE(pClassFactory);\r
+ \r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::ConnectFilters()\r
+{\r
+ HRESULT hr;\r
+\r
+ hr = GetPin(m_pDF, PINDIR_OUTPUT , &m_pOutputPin);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = GetPin(m_pSF, PINDIR_INPUT , &m_pInputPin);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = m_pGB->Connect(m_pOutputPin, m_pInputPin);\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP_(void) HWCSP::CloseInterfaces() \r
+{\r
+ if (m_pMC)\r
+ m_pMC->Stop();\r
+ \r
+ if (m_pOutputPin)\r
+ m_pOutputPin->Disconnect();\r
+\r
+ SAFE_RELEASE(m_pGB);\r
+ SAFE_RELEASE(m_pCGB);\r
+ SAFE_RELEASE(m_pMC);\r
+ SAFE_RELEASE(m_pME);\r
+ SAFE_RELEASE(m_pOutputPin);\r
+ SAFE_RELEASE(m_pInputPin);\r
+ SAFE_RELEASE(m_pDF);\r
+ SAFE_RELEASE(m_pSF);\r
+ SAFE_RELEASE(m_pCallback);\r
+\r
+ if (m_hDLL) {\r
+ FreeLibrary(m_hDLL);\r
+ m_hDLL = NULL;\r
+ }\r
+}\r
+\r
+STDMETHODIMP_(void) HWCSP::DeleteMediaType(AM_MEDIA_TYPE *pmt)\r
+{\r
+ if (pmt == NULL) {\r
+ return;\r
+ }\r
+\r
+ if (pmt->cbFormat != 0) {\r
+ CoTaskMemFree((PVOID)pmt->pbFormat);\r
+ pmt->cbFormat = 0;\r
+ pmt->pbFormat = NULL;\r
+ }\r
+ if (pmt->pUnk != NULL) {\r
+ pmt->pUnk->Release();\r
+ pmt->pUnk = NULL;\r
+ }\r
+\r
+ CoTaskMemFree((PVOID)pmt);\r
+}\r
+\r
+STDMETHODIMP HWCSP::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)\r
+{\r
+ HRESULT hr;\r
+ IEnumPins *pEnum = NULL;\r
+ IPin *pPin = NULL;\r
+\r
+ if (ppPin == NULL)\r
+ {\r
+ return E_POINTER;\r
+ }\r
+\r
+ hr = pFilter->EnumPins(&pEnum);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ while(pEnum->Next(1, &pPin, 0) == S_OK)\r
+ {\r
+ PIN_DIRECTION PinDirThis;\r
+ hr = pPin->QueryDirection(&PinDirThis);\r
+ if (FAILED(hr))\r
+ {\r
+ SAFE_RELEASE(pPin);\r
+ SAFE_RELEASE(pEnum);\r
+ return hr;\r
+ }\r
+ if (PinDir == PinDirThis)\r
+ {\r
+ *ppPin = pPin;\r
+ SAFE_RELEASE(pEnum);\r
+ return S_OK;\r
+ }\r
+ SAFE_RELEASE(pPin);\r
+ }\r
+\r
+ SAFE_RELEASE(pEnum);\r
+ return S_FALSE;\r
+}\r
+\r
+STDMETHODIMP HWCSP::QueryVideoProcAmp(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)\r
+{\r
+ HRESULT hr;\r
+\r
+ IAMVideoProcAmp *pProcAmp = NULL;\r
+ hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
+ if (FAILED(hr))\r
+ {\r
+ return hr;\r
+ }\r
+\r
+ long Flags;\r
+ hr = pProcAmp->GetRange(nProperty, pMin, pMax, pStep, pDefault, &Flags);\r
+\r
+ SAFE_RELEASE(pProcAmp);\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::GetVideoProcAmp(long nProperty, long *pValue)\r
+{\r
+ HRESULT hr;\r
+\r
+ IAMVideoProcAmp *pProcAmp = NULL;\r
+ hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ long Flags;\r
+ hr = pProcAmp->Get(nProperty, pValue, &Flags);\r
+ if (FAILED(hr))\r
+ {\r
+ }\r
+ SAFE_RELEASE(pProcAmp);\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::SetVideoProcAmp(long nProperty, long value)\r
+{\r
+ HRESULT hr;\r
+\r
+ IAMVideoProcAmp *pProcAmp = NULL;\r
+ hr = m_pDF->QueryInterface(IID_IAMVideoProcAmp, (void**)&pProcAmp);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = pProcAmp->Set(nProperty, value, VideoProcAmp_Flags_Manual);\r
+ SAFE_RELEASE(pProcAmp);\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::StartPreview()\r
+{\r
+ HRESULT hr;\r
+\r
+ hr = ((IHWCPin*)m_pInputPin)->SetCallback((ICaptureCallBack*)m_pCallback);\r
+ if (FAILED(hr)) \r
+ return hr;\r
+\r
+ hr = m_pMC->Run();\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::StopPreview()\r
+{\r
+ HRESULT hr;\r
+ hr = ((IHWCPin*)m_pInputPin)->SetCallback(NULL);\r
+\r
+ if (SUCCEEDED(hr))\r
+ hr = m_pMC->Stop();\r
+ return hr;\r
+}\r
+STDMETHODIMP HWCSP::GetDeviceCaps(ULONG *fourcc, ULONG *width, ULONG *height, ULONG *fps)\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig* vsc = NULL;\r
+ AM_MEDIA_TYPE* pmt = NULL;\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = vsc->GetFormat(&pmt);\r
+ if (FAILED(hr)) \r
+ {\r
+ vsc->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (pmt != NULL)\r
+ {\r
+ if (pmt->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
+ if (pvi->bmiHeader.biBitCount == 24 && pvi->bmiHeader.biCompression == BI_RGB) {\r
+ *fourcc = MAKEFOURCC('R', 'G', 'B', '3');\r
+ } else {\r
+ *fourcc = (ULONG)pvi->bmiHeader.biCompression;\r
+ }\r
+ *width = (ULONG)pvi->bmiHeader.biWidth;\r
+ *height = (ULONG)pvi->bmiHeader.biHeight;\r
+ *fps = (ULONG)pvi->AvgTimePerFrame;\r
+ }\r
+ DeleteMediaType(pmt);\r
+ }\r
+ vsc->Release();\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::SetFPS(REFERENCE_TIME inFps)\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig* vsc = NULL;\r
+ AM_MEDIA_TYPE* pmt = NULL;\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = vsc->GetFormat(&pmt);\r
+ if (FAILED(hr))\r
+ {\r
+ vsc->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (pmt != NULL)\r
+ {\r
+ if (pmt->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
+ pvi->AvgTimePerFrame = inFps;\r
+ hr = vsc->SetFormat(pmt);\r
+ }\r
+ DeleteMediaType(pmt);\r
+ }\r
+ vsc->Release();\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::GetFPS(REFERENCE_TIME *outFps)\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig* vsc = NULL;\r
+ AM_MEDIA_TYPE* pmt = NULL;\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = vsc->GetFormat(&pmt);\r
+ if (FAILED(hr))\r
+ {\r
+ vsc->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (pmt != NULL)\r
+ {\r
+ if (pmt->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
+ *outFps = pvi->AvgTimePerFrame;\r
+ }\r
+ DeleteMediaType(pmt);\r
+ }\r
+ vsc->Release();\r
+ return hr;\r
+}\r
+\r
+\r
+STDMETHODIMP HWCSP::SetResolution(LONG width, LONG height)\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig* vsc = NULL;\r
+ AM_MEDIA_TYPE* pmt = NULL;\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = vsc->GetFormat(&pmt);\r
+ if (FAILED(hr))\r
+ {\r
+ vsc->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (pmt != NULL)\r
+ {\r
+ if (pmt->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
+ pvi->bmiHeader.biWidth = width;\r
+ pvi->bmiHeader.biHeight = height;\r
+ pvi->AvgTimePerFrame = 333333;\r
+ pvi->bmiHeader.biSizeImage = ((width * pvi->bmiHeader.biBitCount) >> 3 ) * height;\r
+ hr = vsc->SetFormat(pmt);\r
+ }\r
+ DeleteMediaType(pmt);\r
+ }\r
+ vsc->Release();\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::GetResolution(LONG *width, LONG *height)\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig* vsc = NULL;\r
+ AM_MEDIA_TYPE* pmt = NULL;\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pDF, IID_IAMStreamConfig, (void**)&vsc);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = vsc->GetFormat(&pmt);\r
+ if (FAILED(hr))\r
+ {\r
+ vsc->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (pmt != NULL)\r
+ {\r
+ if (pmt->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmt->pbFormat;\r
+ *width = pvi->bmiHeader.biWidth;\r
+ *height = pvi->bmiHeader.biHeight;\r
+ }\r
+ DeleteMediaType(pmt);\r
+ }\r
+ vsc->Release();\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::GetFormats(LPVOID pData)\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig *pSC;\r
+\r
+ if (pData == NULL)\r
+ return E_POINTER;\r
+\r
+ HWCParam *param = (HWCParam*)pData;\r
+\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSC);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ int iCount = 0, iSize = 0, nIndex = 0;\r
+ hr = pSC->GetNumberOfCapabilities(&iCount, &iSize);\r
+ if (FAILED(hr))\r
+ {\r
+ pSC->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))\r
+ {\r
+ for (int iFormat = 0; iFormat < iCount; iFormat++)\r
+ {\r
+ VIDEO_STREAM_CONFIG_CAPS scc;\r
+ AM_MEDIA_TYPE *pmtConfig;\r
+ hr = pSC->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ if (pmtConfig != NULL && pmtConfig->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
+ // processing!!!!\r
+ }\r
+ }\r
+ DeleteMediaType(pmtConfig);\r
+ }\r
+ }\r
+ pSC->Release();\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::GetFrameSizes(LPVOID pData)\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig *pSC;\r
+\r
+ if (pData == NULL)\r
+ return E_POINTER;\r
+\r
+ HWCParam *param = (HWCParam*)pData;\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSC);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ int iCount = 0, iSize = 0, nIndex = 0;\r
+ hr = pSC->GetNumberOfCapabilities(&iCount, &iSize);\r
+ if (FAILED(hr))\r
+ {\r
+ pSC->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))\r
+ {\r
+ for (int iFormat = 0; iFormat < iCount; iFormat++)\r
+ {\r
+ VIDEO_STREAM_CONFIG_CAPS scc;\r
+ AM_MEDIA_TYPE *pmtConfig;\r
+ hr = pSC->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ if (pmtConfig != NULL && pmtConfig->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
+ // processing!!!!\r
+ }\r
+ }\r
+ DeleteMediaType(pmtConfig);\r
+ }\r
+ }\r
+ pSC->Release();\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::SetDefaultValues()\r
+{\r
+ HRESULT hr;\r
+ IAMStreamConfig *pSConfig;\r
+\r
+ hr = m_pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, 0, m_pDF, IID_IAMStreamConfig, (void**)&pSConfig);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ int iCount = 0, iSize = 0;\r
+ hr = pSConfig->GetNumberOfCapabilities(&iCount, &iSize);\r
+ if (FAILED(hr))\r
+ {\r
+ pSConfig->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))\r
+ {\r
+ for (int iFormat = 0; iFormat < iCount; iFormat++)\r
+ {\r
+ VIDEO_STREAM_CONFIG_CAPS scc;\r
+ AM_MEDIA_TYPE *pmtConfig;\r
+\r
+ hr = pSConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ if (pmtConfig->formattype == FORMAT_VideoInfo)\r
+ {\r
+ VIDEOINFOHEADER* pvi = (VIDEOINFOHEADER*)pmtConfig->pbFormat;\r
+ if ((pvi->bmiHeader.biWidth == m_dwWidth) && \r
+ (pvi->bmiHeader.biHeight == m_dwHeight) && \r
+ (pvi->bmiHeader.biCompression == m_dwFourcc)) \r
+ {\r
+ pvi->AvgTimePerFrame = (REFERENCE_TIME)m_dwAvgInterval;\r
+ pSConfig->SetFormat(pmtConfig);\r
+ }\r
+ }\r
+ }\r
+ DeleteMediaType(pmtConfig);\r
+ }\r
+ }\r
+ pSConfig->Release();\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSP::GetFrameIntervals(LPVOID pData)\r
+{\r
+}\r
+\r
+STDMETHODIMP HWCSP::SetCallback(CallbackFn pCallback)\r
+{\r
+ if (m_pCallback == NULL) {\r
+ return E_FAIL;\r
+ }\r
+ return m_pCallback->SetCallback(pCallback);\r
+}\r
+\r
+static HWCSP *g_pObject = NULL;\r
+\r
+STDMETHODIMP HWCOpen()\r
+{\r
+ HRESULT hr;\r
+\r
+ g_pObject = new HWCSP();\r
+ hr = g_pObject->Init();\r
+ if (FAILED(hr))\r
+ goto error_failed;\r
+\r
+ hr = g_pObject->BindSourceFilter();\r
+ if (hr != S_OK)\r
+ goto error_failed;\r
+\r
+ hr = g_pObject->BindTargetFilter();\r
+ if (FAILED(hr))\r
+ goto error_failed;\r
+\r
+ hr = g_pObject->ConnectFilters();\r
+ if (FAILED(hr))\r
+ goto error_failed;\r
+\r
+ hr = g_pObject->SetDefaultValues();\r
+ if (FAILED(hr))\r
+ goto error_failed;\r
+\r
+ return NOERROR;\r
+\r
+error_failed:\r
+ delete g_pObject;\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCClose()\r
+{\r
+ if (g_pObject)\r
+ delete g_pObject;\r
+ return NOERROR;\r
+}\r
+\r
+STDMETHODIMP HWCStart()\r
+{\r
+ if (g_pObject)\r
+ return g_pObject->StartPreview();\r
+\r
+ return E_FAIL;\r
+}\r
+\r
+STDMETHODIMP HWCStop()\r
+{\r
+ if (g_pObject)\r
+ return g_pObject->StopPreview();\r
+\r
+ return E_FAIL;\r
+}\r
+\r
+STDMETHODIMP HWCSetFPS(long num, long denom)\r
+{\r
+ HRESULT hr;\r
+ REFERENCE_TIME inFps = (REFERENCE_TIME)(10000000 * num / denom);\r
+ hr = g_pObject->SetFPS(inFps);\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCGetFPS(long *num, long *denom)\r
+{\r
+ HRESULT hr;\r
+ REFERENCE_TIME outFps = 0;\r
+ hr = g_pObject->GetFPS(&outFps);\r
+ if (SUCCEEDED(hr)) {\r
+ *num = 1;\r
+ *denom = (long)(10000000 / outFps);\r
+ } else {\r
+ *num = 0;\r
+ *denom = 0;\r
+ }\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCSetFormat(long width, long height)\r
+{\r
+ HRESULT hr;\r
+ hr = g_pObject->SetResolution(width, height);\r
+ return hr;\r
+}\r
+STDMETHODIMP HWCGetFormat()\r
+{\r
+ return NOERROR;\r
+}\r
+STDMETHODIMP HWCTryFormat()\r
+{\r
+ return NOERROR;\r
+}\r
+STDMETHODIMP HWCEnumFormat()\r
+{\r
+ return NOERROR;\r
+}\r
+\r
+STDMETHODIMP HWCQueryControl(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault)\r
+{\r
+ if (g_pObject)\r
+ return g_pObject->QueryVideoProcAmp(nProperty, pMin, pMax, pStep, pDefault);\r
+\r
+ return E_FAIL;\r
+}\r
+\r
+STDMETHODIMP HWCSetControlValue(long nProperty, long value)\r
+{\r
+ if (g_pObject)\r
+ return g_pObject->SetVideoProcAmp(nProperty, value);\r
+\r
+ return E_FAIL;\r
+}\r
+\r
+STDMETHODIMP HWCGetControlValue(long nProperty, long *pVal)\r
+{\r
+ if (g_pObject)\r
+ return g_pObject->GetVideoProcAmp(nProperty, pVal);\r
+\r
+ return E_FAIL;\r
+}\r
+\r
+STDMETHODIMP HWCEnumFrameSizes()\r
+{\r
+ return NOERROR;\r
+}\r
+STDMETHODIMP HWCEnumFrameIntervals()\r
+{\r
+ return NOERROR;\r
+}\r
+\r
+HWCFILTER_API HWCSetCallback(CallbackFn pCallback)\r
+{\r
+ HRESULT hr = g_pObject->SetCallback(pCallback);\r
+ return hr;\r
+}\r
+\r
+HWCFILTER_API HWCCtrl(UINT nCmd, UINT nSize, LPVOID pBuf)\r
+{\r
+ HRESULT hr;\r
+ HWCParam *param = NULL;\r
+ \r
+ if (nSize && pBuf)\r
+ param = (HWCParam *)pBuf;\r
+\r
+ switch (nCmd)\r
+ {\r
+ case HWC_OPEN:\r
+ hr = HWCOpen();\r
+ break;\r
+ case HWC_CLOSE:\r
+ hr = HWCClose();\r
+ break;\r
+ case HWC_START:\r
+ hr = HWCStart();\r
+ break;\r
+ case HWC_STOP:\r
+ hr = HWCStop();\r
+ break;\r
+ case HWC_S_FPS:\r
+ hr = HWCSetFPS(param->val1, param->val2);\r
+ break;\r
+ case HWC_G_FPS:\r
+ hr = HWCGetFPS(¶m->val1, ¶m->val2);\r
+ break;\r
+ case HWC_S_FMT:\r
+ hr = HWCSetFormat(param->val1, param->val2);\r
+ break;\r
+ case HWC_G_FMT:\r
+ break;\r
+ case HWC_TRY_FMT:\r
+ break;\r
+ case HWC_ENUM_FMT:\r
+ break;\r
+ case HWC_QCTRL:\r
+ hr = HWCQueryControl(param->val1, ¶m->val2, ¶m->val3,\r
+ ¶m->val4, ¶m->val5);\r
+ break;\r
+ case HWC_S_CTRL:\r
+ hr = HWCSetControlValue(param->val1, param->val2);\r
+ break;\r
+ case HWC_G_CTRL:\r
+ hr = HWCGetControlValue(param->val1, ¶m->val2);\r
+ break;\r
+ case HWC_ENUM_FSIZES:\r
+ break;\r
+ case HWC_ENUM_INTERVALS:\r
+ break;\r
+ default:\r
+ hr = E_INVALIDARG;\r
+ break;\r
+ }\r
+ return hr;\r
+}
\ No newline at end of file