--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 11.00\r
+# Visual Studio 2010\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hwcfilter", "hwcfilter\hwcfilter.vcxproj", "{DF0AE82C-5AB7-47F5-B3F2-8CE447A7C2FC}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Win32 = Debug|Win32\r
+ Release|Win32 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {DF0AE82C-5AB7-47F5-B3F2-8CE447A7C2FC}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {DF0AE82C-5AB7-47F5-B3F2-8CE447A7C2FC}.Debug|Win32.Build.0 = Debug|Win32\r
+ {DF0AE82C-5AB7-47F5-B3F2-8CE447A7C2FC}.Release|Win32.ActiveCfg = Release|Win32\r
+ {DF0AE82C-5AB7-47F5-B3F2-8CE447A7C2FC}.Release|Win32.Build.0 = Release|Win32\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+========================================================================\r
+ 동적 연결 라이브러리 : hwcfilter 프로젝트 개요\r
+========================================================================\r
+\r
+응용 프로그램 마법사에서 이 hwcfilter DLL을 만들었습니다.\r
+\r
+hwcfilter 응용 프로그램을 구성하는 각 파일에 대한\r
+요약 설명이 포함되어 있습니다.\r
+\r
+\r
+hwcfilter.vcxproj\r
+ 응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.\r
+ 파일을 생성한 Visual C++ 버전에 대한 정보와 응용 프로그램 마법사를 사용하여 선택한 플랫폼,\r
+ 구성 및 프로젝트 기능에 대한 정보가 포함되어 있습니다.\r
+\r
+hwcfilter.vcxproj.filters\r
+ 응용 프로그램 마법사를 사용하여 생성된 VC++ 프로젝트의 필터 파일입니다. \r
+ 이 파일에는 프로젝트의 파일과 필터 간의 연결 정보가 들어 있습니다.\r
+ 이러한 연결은 특정 노드에서 유사한 확장명으로 그룹화된 파일을 표시하기 위해 IDE에서\r
+ 사용됩니다. 예를 들어 ".cpp" 파일은 "소스 파일" 필터와 연결되어 있습니다.\r
+\r
+hwcfilter.cpp\r
+ 기본 DLL 소스 파일입니다.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+기타 표준 파일:\r
+\r
+StdAfx.h, StdAfx.cpp\r
+ 이 파일은 미리 컴파일된 헤더(PCH) 파일 hwcfilter.pch와\r
+ 미리 컴파일된 형식(PCT) 파일 StdAfx.obj를 빌드하는 데 사용됩니다.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
+기타 참고:\r
+\r
+응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는\r
+소스 코드 부분을 나타냅니다.\r
+\r
+/////////////////////////////////////////////////////////////////////////////\r
--- /dev/null
+// dllmain.cpp : DLL ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ ÁøÀÔÁ¡À» Á¤ÀÇÇÕ´Ï´Ù.\r
+#include "stdafx.h"\r
+\r
+BOOL APIENTRY DllMain( HMODULE hModule,\r
+ DWORD ul_reason_for_call,\r
+ LPVOID lpReserved\r
+ )\r
+{\r
+ switch (ul_reason_for_call)\r
+ {\r
+ case DLL_PROCESS_ATTACH:\r
+ case DLL_THREAD_ATTACH:\r
+ case DLL_THREAD_DETACH:\r
+ case DLL_PROCESS_DETACH:\r
+ break;\r
+ }\r
+ return TRUE;\r
+}\r
+\r
--- /dev/null
+\r
+\r
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */\r
+\r
+\r
+ /* File created by MIDL compiler version 7.00.0555 */\r
+/* at Wed Nov 23 21:52:11 2011\r
+ */\r
+/* Compiler settings for HWCCallBack.idl:\r
+ Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
+ protocol : dce , ms_ext, c_ext, robust\r
+ error checks: allocation ref bounds_check enum stub_data \r
+ VC __declspec() decoration level: \r
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+ DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+/* @@MIDL_FILE_HEADING( ) */\r
+\r
+#pragma warning( disable: 4049 ) /* more than 64k source lines */\r
+\r
+\r
+/* verify that the <rpcndr.h> version is high enough to compile this file*/\r
+#ifndef __REQUIRED_RPCNDR_H_VERSION__\r
+#define __REQUIRED_RPCNDR_H_VERSION__ 475\r
+#endif\r
+\r
+#include "rpc.h"\r
+#include "rpcndr.h"\r
+\r
+#ifndef __RPCNDR_H_VERSION__\r
+#error this stub requires an updated version of <rpcndr.h>\r
+#endif // __RPCNDR_H_VERSION__\r
+\r
+#ifndef COM_NO_WINDOWS_H\r
+#include "windows.h"\r
+#include "ole2.h"\r
+#endif /*COM_NO_WINDOWS_H*/\r
+\r
+#ifndef __HWCCallBack_h_h__\r
+#define __HWCCallBack_h_h__\r
+\r
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)\r
+#pragma once\r
+#endif\r
+\r
+/* Forward Declarations */ \r
+\r
+#ifndef __ICaptureCallBack_FWD_DEFINED__\r
+#define __ICaptureCallBack_FWD_DEFINED__\r
+typedef interface ICaptureCallBack ICaptureCallBack;\r
+#endif /* __ICaptureCallBack_FWD_DEFINED__ */\r
+\r
+\r
+/* header files for imported files */\r
+#include "Unknwn.h"\r
+#include <InitGuid.h>\r
+#include <DShow.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+\r
+#ifndef __ICaptureCallBack_INTERFACE_DEFINED__\r
+#define __ICaptureCallBack_INTERFACE_DEFINED__\r
+\r
+/* interface ICaptureCallBack */\r
+/* [full][helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_ICaptureCallBack;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+ \r
+ MIDL_INTERFACE("4C337035-C89E-4B42-9B0C-367444DD70DD")\r
+ ICaptureCallBack : public IUnknown\r
+ {\r
+ public:\r
+ virtual HRESULT STDMETHODCALLTYPE CaptureCallback( \r
+ /* [in] */ ULONG dwSize,\r
+ /* [size_is][in] */ BYTE *pBuffer) = 0;\r
+ \r
+ };\r
+ \r
+#else /* C style interface */\r
+\r
+ typedef struct ICaptureCallBackVtbl\r
+ {\r
+ BEGIN_INTERFACE\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+ ICaptureCallBack * This,\r
+ /* [in] */ REFIID riid,\r
+ /* [annotation][iid_is][out] */ \r
+ __RPC__deref_out void **ppvObject);\r
+ \r
+ ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+ ICaptureCallBack * This);\r
+ \r
+ ULONG ( STDMETHODCALLTYPE *Release )( \r
+ ICaptureCallBack * This);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *CaptureCallback )( \r
+ ICaptureCallBack * This,\r
+ /* [in] */ ULONG dwSize,\r
+ /* [size_is][in] */ BYTE *pBuffer);\r
+ \r
+ END_INTERFACE\r
+ } ICaptureCallBackVtbl;\r
+\r
+ interface ICaptureCallBack\r
+ {\r
+ CONST_VTBL struct ICaptureCallBackVtbl *lpVtbl;\r
+ };\r
+\r
+ \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define ICaptureCallBack_QueryInterface(This,riid,ppvObject) \\r
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define ICaptureCallBack_AddRef(This) \\r
+ ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define ICaptureCallBack_Release(This) \\r
+ ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define ICaptureCallBack_CaptureCallback(This,dwSize,pBuffer) \\r
+ ( (This)->lpVtbl -> CaptureCallback(This,dwSize,pBuffer) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif /* __ICaptureCallBack_INTERFACE_DEFINED__ */\r
+\r
+\r
+/* Additional Prototypes for ALL interfaces */\r
+\r
+/* end of Additional Prototypes */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+\r
--- /dev/null
+#include "stdafx.h"\r
+#include "hwcfilter.h"\r
+#include <VFWMSGS.H>\r
+#include <stdio.h>\r
+\r
+static HMODULE g_hModule = NULL;\r
+static long g_cServerLocks = 0;\r
+static long g_cComponents = 0;\r
+\r
+CHWCPin::CHWCPin(CHWCFilter *pFilter) :\r
+ m_pCFilter(pFilter), m_pConnectedPin(NULL), \r
+ m_pCallback(NULL), m_bReadOnly(FALSE), m_cRef(1)\r
+{\r
+ InterlockedIncrement(&g_cComponents);\r
+}\r
+\r
+CHWCPin::~CHWCPin(void)\r
+{\r
+ InterlockedDecrement(&g_cComponents);\r
+}\r
+\r
+STDMETHODIMP CHWCPin::QueryInterface(REFIID riid, void **ppv)\r
+{\r
+ if (riid == IID_IUnknown) {\r
+ *ppv = (IUnknown*)((IHWCPin*)this);\r
+ } else if (riid == IID_IPin) {\r
+ *ppv = (IPin*)this;\r
+ } else if (riid == IID_IMemInputPin) {\r
+ *ppv = (IMemInputPin*)this;\r
+ } else if (riid == IID_IHWCPin) {\r
+ *ppv = (IHWCPin*)this;\r
+ } else {\r
+ LPWSTR str;\r
+ StringFromIID(riid, &str);\r
+ *ppv = NULL;\r
+ return E_NOINTERFACE;\r
+ }\r
+ reinterpret_cast<IHWCPin*>(this)->AddRef();\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CHWCPin::AddRef()\r
+{\r
+ return InterlockedIncrement(&m_cRef);\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CHWCPin::Release()\r
+{\r
+ if( InterlockedDecrement(&m_cRef) == 0)\r
+ {\r
+ delete this;\r
+ return 0;\r
+ }\r
+ return m_cRef;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)\r
+{\r
+ if ( !pmt )\r
+ return S_OK;\r
+ return S_FALSE;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)\r
+{\r
+ if (pConnector == NULL || pmt == NULL)\r
+ return E_POINTER;\r
+\r
+ if (m_pConnectedPin) {\r
+ return VFW_E_ALREADY_CONNECTED;\r
+ }\r
+ FILTER_STATE fs;\r
+ m_pCFilter->GetState(0, &fs);\r
+ if (fs != State_Stopped) {\r
+ return VFW_E_NOT_STOPPED;\r
+ }\r
+ PIN_DIRECTION pd;\r
+ pConnector->QueryDirection(&pd);\r
+ if (pd == PINDIR_INPUT) {\r
+ return VFW_E_INVALID_DIRECTION;\r
+ }\r
+\r
+ m_pConnectedPin = pConnector;\r
+ m_pConnectedPin->AddRef();\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::Disconnect(void)\r
+{\r
+ HRESULT hr;\r
+ if (m_pConnectedPin == NULL) {\r
+ hr = S_FALSE;\r
+ } else {\r
+ m_pConnectedPin->Release();\r
+ m_pConnectedPin = NULL;\r
+ hr = S_OK;\r
+ }\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::ConnectedTo(IPin **pPin)\r
+{\r
+ if (pPin == NULL)\r
+ return E_POINTER;\r
+\r
+ HRESULT hr;\r
+ if ( m_pConnectedPin == NULL ) {\r
+ hr = VFW_E_NOT_CONNECTED;\r
+ } else {\r
+ m_pConnectedPin->AddRef();\r
+ *pPin = m_pConnectedPin;\r
+ hr = S_OK;\r
+ }\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)\r
+{ \r
+ if (pmt == NULL) {\r
+ return E_POINTER;\r
+ }\r
+ return VFW_E_NOT_CONNECTED;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::QueryPinInfo(PIN_INFO *pInfo)\r
+{\r
+ if (pInfo == NULL)\r
+ return E_POINTER;\r
+\r
+ pInfo->pFilter = (IBaseFilter*)m_pCFilter;\r
+ if (m_pCFilter)\r
+ m_pCFilter->AddRef();\r
+ memcpy((void*)pInfo->achName, (void*)HWCPinName, sizeof(HWCPinName));\r
+ pInfo->dir = PINDIR_INPUT;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::QueryDirection(PIN_DIRECTION *pPinDir)\r
+{\r
+ if (pPinDir == NULL)\r
+ return E_POINTER;\r
+ *pPinDir = PINDIR_INPUT;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::QueryId(LPWSTR *Id)\r
+{\r
+ if (Id == NULL)\r
+ return E_POINTER;\r
+ PVOID pId = CoTaskMemAlloc(sizeof(HWCPinName));\r
+ memcpy((void*)pId, (void*)HWCPinName, sizeof(HWCPinName));\r
+ *Id = (LPWSTR)pId;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::QueryAccept(const AM_MEDIA_TYPE *pmt)\r
+{\r
+ if (pmt == NULL)\r
+ return E_POINTER;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)\r
+{\r
+ if (ppEnum == NULL)\r
+ return E_POINTER;\r
+ return E_NOTIMPL;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::QueryInternalConnections(IPin **ppPin, ULONG *nPin)\r
+{\r
+ return E_NOTIMPL;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::EndOfStream(void)\r
+{\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::BeginFlush(void)\r
+{\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::EndFlush(void)\r
+{\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::NewSegment(REFERENCE_TIME tStart,\r
+ REFERENCE_TIME tStop,\r
+ double dRate)\r
+{\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::GetAllocator(IMemAllocator **ppAllocator)\r
+{\r
+ if (ppAllocator == NULL)\r
+ return E_POINTER;\r
+ return VFW_E_NO_ALLOCATOR;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::NotifyAllocator(IMemAllocator *pAllocator,\r
+ BOOL bReadOnly)\r
+{\r
+ if (pAllocator == NULL)\r
+ return E_POINTER;\r
+\r
+ return NOERROR;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)\r
+{\r
+ return E_NOTIMPL;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::Receive(IMediaSample *pSample)\r
+{\r
+ if (pSample == NULL)\r
+ return E_POINTER;\r
+ if (m_pCallback != NULL) {\r
+ HRESULT hr;\r
+ BYTE* pBuffer = NULL;\r
+ DWORD dwSize = 0;\r
+ dwSize = pSample->GetSize();\r
+ hr = pSample->GetPointer(&pBuffer);\r
+ if (FAILED(hr))\r
+ return hr;\r
+ m_pCallback->CaptureCallback(dwSize, pBuffer);\r
+ }\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::ReceiveMultiple(IMediaSample **pSamples,\r
+ long nSamples, long *nSamplesProcessed)\r
+{\r
+ if (pSamples == NULL)\r
+ return E_POINTER;\r
+ HRESULT hr = S_OK;\r
+ nSamplesProcessed = 0;\r
+ while (nSamples-- > 0) \r
+ {\r
+ hr = Receive(pSamples[*nSamplesProcessed]);\r
+ if (hr != S_OK)\r
+ break;\r
+ (*nSamplesProcessed)++;\r
+ }\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::ReceiveCanBlock(void)\r
+{\r
+ return S_FALSE;\r
+}\r
+\r
+STDMETHODIMP CHWCPin::SetCallback(ICaptureCallBack *pCaptureCB)\r
+{\r
+ if (pCaptureCB == NULL) {\r
+ m_pCallback->Release();\r
+ } else {\r
+ m_pCallback = pCaptureCB;\r
+ m_pCallback->AddRef();\r
+ } \r
+ return S_OK;\r
+}\r
+\r
+CHWCEnumPins::CHWCEnumPins(CHWCFilter *pCHWCFilter, int pos) :\r
+ m_pFilter(pCHWCFilter), m_pos(pos), m_cRef(1)\r
+{\r
+ m_pFilter->AddRef();\r
+ InterlockedIncrement(&g_cComponents);\r
+}\r
+\r
+CHWCEnumPins::~CHWCEnumPins(void)\r
+{\r
+ m_pFilter->Release();\r
+ InterlockedDecrement(&g_cComponents);\r
+}\r
+\r
+STDMETHODIMP CHWCEnumPins::QueryInterface(REFIID riid, void **ppv)\r
+{\r
+ if (ppv == NULL)\r
+ return E_POINTER;\r
+\r
+ if (riid == IID_IUnknown) {\r
+ *ppv = (IUnknown*)this;\r
+ } else if (riid == IID_IEnumPins) {\r
+ *ppv = (IEnumPins*)this;\r
+ } else {\r
+ *ppv = NULL;\r
+ return E_NOINTERFACE;\r
+ }\r
+ reinterpret_cast<IUnknown*>(this)->AddRef();\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CHWCEnumPins::AddRef()\r
+{\r
+ return InterlockedIncrement(&m_cRef);\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CHWCEnumPins::Release()\r
+{\r
+ if (InterlockedDecrement(&m_cRef) == 0) {\r
+ delete this;\r
+ return 0;\r
+ }\r
+ return m_cRef;\r
+}\r
+\r
+STDMETHODIMP CHWCEnumPins::Next(ULONG cPins, IPin **ppPins,\r
+ ULONG *pcFetched)\r
+{\r
+ if (ppPins == NULL)\r
+ return E_POINTER;\r
+\r
+ ULONG fetched;\r
+ if (m_pos < 1 && cPins > 0) {\r
+ IPin *pPin;\r
+ m_pFilter->FindPin(HWCPinName, &pPin);\r
+ *ppPins = pPin;\r
+ pPin->AddRef();\r
+ fetched = 1;\r
+ m_pos++;\r
+ } else {\r
+ fetched = 0;\r
+ }\r
+ if (pcFetched != NULL ) {\r
+ *pcFetched = fetched;\r
+ }\r
+\r
+ return ( fetched == cPins ) ? S_OK : S_FALSE;\r
+}\r
+\r
+STDMETHODIMP CHWCEnumPins::Skip(ULONG cPins)\r
+{\r
+ m_pos += cPins;\r
+ return ( m_pos >= 1 ) ? S_FALSE : S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCEnumPins::Reset(void)\r
+{\r
+ m_pos = 0;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCEnumPins::Clone(IEnumPins **ppEnum)\r
+{\r
+ if (ppEnum == NULL)\r
+ return E_POINTER;\r
+ *ppEnum = new CHWCEnumPins(m_pFilter, m_pos);\r
+ if (*ppEnum == NULL) {\r
+ return E_OUTOFMEMORY;\r
+ }\r
+ return NOERROR;\r
+}\r
+\r
+CHWCFilter::CHWCFilter() : m_pFilterGraph(NULL), m_state(State_Stopped), m_cRef(1)\r
+{\r
+ m_pPin = new CHWCPin(this);\r
+ InterlockedIncrement(&g_cComponents);\r
+}\r
+\r
+CHWCFilter::~CHWCFilter()\r
+{\r
+ InterlockedDecrement(&g_cComponents);\r
+\r
+ if (m_pPin) {\r
+ m_pPin->Release();\r
+ m_pPin = NULL;\r
+ }\r
+ if (m_pFilterGraph) {\r
+ m_pFilterGraph->Release();\r
+ m_pFilterGraph = NULL;\r
+ }\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::QueryInterface(REFIID riid, void **ppv)\r
+{\r
+ if( riid == IID_IUnknown ) {\r
+ *ppv = (IUnknown*)this;\r
+ } else if( riid == IID_IPersist ) {\r
+ *ppv = (IPersist*)this;\r
+ } else if( riid == IID_IMediaFilter ) {\r
+ *ppv = (IMediaFilter*)this;\r
+ } else if( riid == IID_IBaseFilter ) {\r
+ *ppv = (IBaseFilter*)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
+\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CHWCFilter::AddRef()\r
+{\r
+ return InterlockedIncrement(&m_cRef);\r
+}\r
+\r
+STDMETHODIMP_(ULONG) CHWCFilter::Release()\r
+{\r
+ if( InterlockedDecrement(&m_cRef) == 0) {\r
+ delete this;\r
+ return 0;\r
+ }\r
+ return m_cRef;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::GetClassID(CLSID *pClsID)\r
+{\r
+ if (pClsID == NULL)\r
+ return E_POINTER;\r
+ return E_NOTIMPL;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::GetState(DWORD dwMSecs, FILTER_STATE *State)\r
+{\r
+ *State = m_state;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::SetSyncSource(IReferenceClock *pClock)\r
+{\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::GetSyncSource(IReferenceClock **pClock)\r
+{\r
+ *pClock = NULL;\r
+ return NOERROR;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::Stop()\r
+{\r
+ m_pPin->EndFlush();\r
+ m_state = State_Stopped;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::Pause()\r
+{\r
+ m_state = State_Paused;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::Run(REFERENCE_TIME tStart)\r
+{\r
+ if (m_state == State_Stopped){\r
+ HRESULT hr = Pause();\r
+ if (FAILED(hr)) {\r
+ return hr;\r
+ }\r
+ }\r
+ m_state = State_Running;\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::EnumPins(IEnumPins **ppEnum)\r
+{\r
+ if (ppEnum == NULL)\r
+ return E_POINTER;\r
+ *ppEnum = (IEnumPins*)(new CHWCEnumPins(this, 0));\r
+ return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::FindPin(LPCWSTR Id, IPin **ppPin)\r
+{\r
+ if (ppPin == NULL)\r
+ return E_POINTER;\r
+\r
+ if (memcmp((void*)Id, (void*)HWCPinName, sizeof(HWCPinName))) {\r
+ return VFW_E_NOT_FOUND;\r
+ }\r
+\r
+ if (!m_pPin) {\r
+ m_pPin = new CHWCPin(this);\r
+ }\r
+ *ppPin = (IPin*)m_pPin;\r
+ m_pPin->AddRef();\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::QueryFilterInfo(FILTER_INFO *pInfo)\r
+{\r
+ if (pInfo == NULL)\r
+ return E_POINTER;\r
+\r
+ memcpy((void*)pInfo->achName, (void*)HWCFilterName, sizeof(HWCFilterName));\r
+ pInfo->pGraph = m_pFilterGraph;\r
+ if(m_pFilterGraph) {\r
+ m_pFilterGraph->AddRef();\r
+ }\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::JoinFilterGraph(IFilterGraph *pGraph,\r
+ LPCWSTR pName)\r
+{\r
+ m_pFilterGraph = pGraph;\r
+ pGraph->AddRef();\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP CHWCFilter::QueryVendorInfo(LPWSTR* pVendorInfo)\r
+{\r
+ return E_NOTIMPL;\r
+}\r
+\r
+HWCClassFactory::HWCClassFactory(void) : m_cRef(1)\r
+{\r
+}\r
+\r
+HWCClassFactory::~HWCClassFactory(void)\r
+{\r
+}\r
+\r
+STDMETHODIMP HWCClassFactory::QueryInterface(REFIID riid, LPVOID* ppv)\r
+{\r
+ if (riid == IID_IUnknown || riid == IID_IClassFactory) {\r
+ *ppv = (IClassFactory*)this;\r
+ } else {\r
+ *ppv = NULL;\r
+ return E_NOINTERFACE;\r
+ }\r
+\r
+ reinterpret_cast<IUnknown*>(*ppv)->AddRef();\r
+ return S_OK;\r
+}\r
+\r
+STDMETHODIMP_(ULONG) HWCClassFactory::AddRef(void)\r
+{\r
+ return InterlockedIncrement(&m_cRef);\r
+}\r
+\r
+STDMETHODIMP_(ULONG) HWCClassFactory::Release(void)\r
+{\r
+ if (InterlockedDecrement(&m_cRef) == 0) {\r
+ delete this;\r
+ return 0;\r
+ }\r
+ return m_cRef;\r
+}\r
+\r
+STDMETHODIMP HWCClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppv)\r
+{\r
+ HRESULT hr;\r
+ CHWCFilter* pFilter = NULL;\r
+ *ppv = NULL;\r
+\r
+ if (pUnkOuter != NULL) {\r
+ hr = CLASS_E_NOAGGREGATION;\r
+ } else {\r
+ pFilter = new CHWCFilter;\r
+ if (pFilter != NULL) {\r
+ hr = pFilter->QueryInterface(riid, ppv);\r
+ pFilter->Release();\r
+ } else {\r
+ return E_OUTOFMEMORY;\r
+ }\r
+ }\r
+\r
+ return hr;\r
+}\r
+\r
+STDMETHODIMP HWCClassFactory::LockServer(BOOL bLock)\r
+{\r
+ if (bLock) {\r
+ InterlockedIncrement(&g_cServerLocks);\r
+ } else {\r
+ InterlockedDecrement(&g_cServerLocks);\r
+ }\r
+ return S_OK;\r
+}\r
+\r
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)\r
+{\r
+ HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;\r
+ HWCClassFactory *pFactory = NULL;\r
+\r
+ if (rclsid != CLSID_HWCFilterClass) {\r
+ return hr;\r
+ }\r
+\r
+ pFactory = new HWCClassFactory;\r
+ if (pFactory == NULL) {\r
+ hr = E_OUTOFMEMORY;\r
+ } else {\r
+ hr = pFactory->QueryInterface(riid, ppv);\r
+ pFactory->Release();\r
+ }\r
+\r
+ return hr;\r
+}\r
+\r
+STDAPI DllCanUnloadNow(void)\r
+{\r
+ if ((g_cComponents == 0) && (g_cServerLocks == 0)) {\r
+ return S_OK;\r
+ }\r
+ return S_FALSE;\r
+}\r
+\r
+STDAPI DllRegisterServer(void)\r
+{\r
+ return S_OK;\r
+}\r
+\r
+STDAPI DllUnregisterServer(void)\r
+{\r
+ return S_OK;\r
+}\r
--- /dev/null
+LIBRARY\r
+EXPORTS\r
+HWCCtrl PRIVATE\r
+HWCSetCallback PRIVATE
\ No newline at end of file
--- /dev/null
+#ifndef __HWCFILTER_H__\r
+#define __HWCFILTER_H__\r
+\r
+#include "hwcfilter_h.h"\r
+\r
+const IID __declspec(selectany) IID_IHWCPin = {0x33AFDC07,0xC2AB,0x4FC4,{0xBA,0x54,0x65,0xFA,0xDF,0x4B,0x47,0x4D}};\r
+const IID __declspec(selectany) IID_ICaptureCallBack = {0x4C337035,0xC89E,0x4B42,{0x9B,0x0C,0x36,0x74,0x44,0xDD,0x70,0xDD}};\r
+\r
+static const WCHAR HWCPinName[] = L"HWCInputPin\0";\r
+static const WCHAR HWCFilterName[] = L"HWCFilter\0";\r
+\r
+class CHWCFilter;\r
+\r
+class CHWCPin: public IHWCPin, public IMemInputPin\r
+{\r
+public:\r
+ CHWCPin(CHWCFilter *pFilter);\r
+ virtual ~CHWCPin();\r
+ STDMETHODIMP QueryInterface(REFIID riid, void **ppv);\r
+ STDMETHODIMP_(ULONG) AddRef();\r
+ STDMETHODIMP_(ULONG) Release();\r
+\r
+ STDMETHODIMP Connect(IPin * pReceivePin, const AM_MEDIA_TYPE *pmt);\r
+ STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);\r
+ STDMETHODIMP Disconnect();\r
+ STDMETHODIMP ConnectedTo(IPin **pPin);\r
+ STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt);\r
+ STDMETHODIMP QueryPinInfo(PIN_INFO *pInfo);\r
+ STDMETHODIMP QueryDirection(PIN_DIRECTION *pPinDir);\r
+ STDMETHODIMP QueryId(LPWSTR * Id);\r
+ STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt);\r
+ STDMETHODIMP EnumMediaTypes(IEnumMediaTypes **ppEnum);\r
+ STDMETHODIMP QueryInternalConnections(IPin **apPin, ULONG *nPin);\r
+ STDMETHODIMP EndOfStream();\r
+ STDMETHODIMP BeginFlush();\r
+ STDMETHODIMP EndFlush();\r
+ STDMETHODIMP NewSegment( REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate );\r
+ STDMETHODIMP SetCallback(ICaptureCallBack *pCallback);\r
+\r
+ STDMETHODIMP GetAllocator(IMemAllocator **ppAllocator);\r
+ STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly);\r
+ STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps);\r
+ STDMETHODIMP Receive(IMediaSample *pSample); \r
+ STDMETHODIMP ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed);\r
+ STDMETHODIMP ReceiveCanBlock();\r
+\r
+protected:\r
+ CHWCFilter *m_pCFilter;\r
+ IPin *m_pConnectedPin;\r
+ ICaptureCallBack *m_pCallback;\r
+ BOOL m_bReadOnly;\r
+ long m_cRef;\r
+};\r
+\r
+class CHWCEnumPins: public IEnumPins\r
+{\r
+public:\r
+ CHWCEnumPins(CHWCFilter *pFilter, int pos);\r
+ virtual ~CHWCEnumPins();\r
+ STDMETHODIMP QueryInterface(REFIID riid, void **ppv);\r
+ STDMETHODIMP_(ULONG) AddRef();\r
+ STDMETHODIMP_(ULONG) Release();\r
+ STDMETHODIMP Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched);\r
+ STDMETHODIMP Skip(ULONG cPins);\r
+ STDMETHODIMP Reset();\r
+ STDMETHODIMP Clone(IEnumPins **ppEnum);\r
+\r
+protected:\r
+ CHWCFilter *m_pFilter;\r
+ int m_pos;\r
+ long m_cRef;\r
+};\r
+\r
+class CHWCFilter: public IBaseFilter\r
+{\r
+public:\r
+ CHWCFilter();\r
+ virtual ~CHWCFilter();\r
+ STDMETHODIMP QueryInterface(REFIID riid, void **ppv);\r
+ STDMETHODIMP_(ULONG) AddRef();\r
+ STDMETHODIMP_(ULONG) Release();\r
+ STDMETHODIMP GetClassID(CLSID *pClsID);\r
+ STDMETHODIMP Stop();\r
+ STDMETHODIMP Pause();\r
+ STDMETHODIMP Run(REFERENCE_TIME tStart);\r
+ STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State);\r
+ STDMETHODIMP SetSyncSource(IReferenceClock *pClock);\r
+ STDMETHODIMP GetSyncSource(IReferenceClock **pClock);\r
+ STDMETHODIMP EnumPins(IEnumPins **ppEnum);\r
+ STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin);\r
+ STDMETHODIMP QueryFilterInfo(FILTER_INFO *pInfo);\r
+ STDMETHODIMP JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName);\r
+ STDMETHODIMP QueryVendorInfo(LPWSTR *pVendorInfo);\r
+\r
+protected:\r
+ CHWCPin *m_pPin;\r
+ IFilterGraph *m_pFilterGraph;\r
+ FILTER_STATE m_state;\r
+ long m_cRef;\r
+};\r
+\r
+class HWCClassFactory : public IClassFactory\r
+{\r
+public:\r
+ HWCClassFactory();\r
+ virtual ~HWCClassFactory();\r
+\r
+ STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppv);\r
+ STDMETHODIMP_(ULONG) AddRef();\r
+ STDMETHODIMP_(ULONG) Release();\r
+ STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID* ppv);\r
+ STDMETHODIMP LockServer(BOOL bLock);\r
+\r
+private:\r
+ long m_cRef;\r
+};\r
+\r
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv);\r
+\r
+#endif // __HWCFILTER_H__
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup Label="ProjectConfigurations">\r
+ <ProjectConfiguration Include="Debug|Win32">\r
+ <Configuration>Debug</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Release|Win32">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ </ItemGroup>\r
+ <PropertyGroup Label="Globals">\r
+ <ProjectGuid>{DF0AE82C-5AB7-47F5-B3F2-8CE447A7C2FC}</ProjectGuid>\r
+ <Keyword>Win32Proj</Keyword>\r
+ <RootNamespace>hwcfilter</RootNamespace>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+ <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+ <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+ <UseDebugLibraries>false</UseDebugLibraries>\r
+ <WholeProgramOptimization>true</WholeProgramOptimization>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+ <ImportGroup Label="ExtensionSettings">\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <PropertyGroup Label="UserMacros" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <LinkIncremental>true</LinkIncremental>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <LinkIncremental>false</LinkIncremental>\r
+ </PropertyGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>Disabled</Optimization>\r
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HWCFILTER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Windows</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;strmiids.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <ModuleDefinitionFile>hwcfilter.def</ModuleDefinitionFile>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <ClCompile>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <Optimization>MaxSpeed</Optimization>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <IntrinsicFunctions>true</IntrinsicFunctions>\r
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HWCFILTER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Windows</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+ <OptimizeReferences>true</OptimizeReferences>\r
+ <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;strmiids.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <ModuleDefinitionFile>hwcfilter.def</ModuleDefinitionFile>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemGroup>\r
+ <None Include="hwcfilter.def" />\r
+ <None Include="ReadMe.txt" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="hwccallback_h.h" />\r
+ <ClInclude Include="hwcfilter.h" />\r
+ <ClInclude Include="hwcfilter_h.h" />\r
+ <ClInclude Include="hwcsp.h" />\r
+ <ClInclude Include="stdafx.h" />\r
+ <ClInclude Include="targetver.h" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="dllmain.cpp">\r
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ </PrecompiledHeader>\r
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ </PrecompiledHeader>\r
+ </ClCompile>\r
+ <ClCompile Include="hwcfilter.cpp" />\r
+ <ClCompile Include="hwcsp.cpp" />\r
+ <ClCompile Include="stdafx.cpp">\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>\r
+ </ClCompile>\r
+ </ItemGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+ <ImportGroup Label="ExtensionTargets">\r
+ </ImportGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup>\r
+ <Filter Include="소스 파일">\r
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+ </Filter>\r
+ <Filter Include="헤더 파일">\r
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+ </Filter>\r
+ <Filter Include="리소스 파일">\r
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+ </Filter>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <None Include="ReadMe.txt" />\r
+ <None Include="hwcfilter.def">\r
+ <Filter>소스 파일</Filter>\r
+ </None>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="stdafx.h">\r
+ <Filter>헤더 파일</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="targetver.h">\r
+ <Filter>헤더 파일</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="hwcfilter.h">\r
+ <Filter>헤더 파일</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="hwcfilter_h.h">\r
+ <Filter>헤더 파일</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="hwccallback_h.h">\r
+ <Filter>헤더 파일</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="hwcsp.h">\r
+ <Filter>헤더 파일</Filter>\r
+ </ClInclude>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="stdafx.cpp">\r
+ <Filter>소스 파일</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="hwcfilter.cpp">\r
+ <Filter>소스 파일</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="dllmain.cpp">\r
+ <Filter>소스 파일</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="hwcsp.cpp">\r
+ <Filter>소스 파일</Filter>\r
+ </ClCompile>\r
+ </ItemGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+</Project>
\ No newline at end of file
--- /dev/null
+\r
+\r
+/* this ALWAYS GENERATED file contains the definitions for the interfaces */\r
+\r
+\r
+ /* File created by MIDL compiler version 7.00.0555 */\r
+/* at Thu Nov 24 00:56:10 2011\r
+ */\r
+/* Compiler settings for HWCFilter.idl:\r
+ Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 7.00.0555 \r
+ protocol : dce , ms_ext, c_ext, robust\r
+ error checks: allocation ref bounds_check enum stub_data \r
+ VC __declspec() decoration level: \r
+ __declspec(uuid()), __declspec(selectany), __declspec(novtable)\r
+ DECLSPEC_UUID(), MIDL_INTERFACE()\r
+*/\r
+/* @@MIDL_FILE_HEADING( ) */\r
+\r
+#pragma warning( disable: 4049 ) /* more than 64k source lines */\r
+\r
+\r
+/* verify that the <rpcndr.h> version is high enough to compile this file*/\r
+#ifndef __REQUIRED_RPCNDR_H_VERSION__\r
+#define __REQUIRED_RPCNDR_H_VERSION__ 475\r
+#endif\r
+\r
+#include "rpc.h"\r
+#include "rpcndr.h"\r
+\r
+#ifndef __RPCNDR_H_VERSION__\r
+#error this stub requires an updated version of <rpcndr.h>\r
+#endif // __RPCNDR_H_VERSION__\r
+\r
+#ifndef COM_NO_WINDOWS_H\r
+#include "windows.h"\r
+#include "ole2.h"\r
+#endif /*COM_NO_WINDOWS_H*/\r
+\r
+#ifndef __HWCFILTER_H_H__\r
+#define __HWCFILTER_H_H__\r
+\r
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)\r
+#pragma once\r
+#endif\r
+\r
+/* Forward Declarations */ \r
+\r
+#ifndef __IHWCPin_FWD_DEFINED__\r
+#define __IHWCPin_FWD_DEFINED__\r
+typedef interface IHWCPin IHWCPin;\r
+#endif /* __IHWCPin_FWD_DEFINED__ */\r
+\r
+\r
+/* header files for imported files */\r
+#include <oaidl.h>\r
+#include <ocidl.h>\r
+#include "hwccallback_h.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C"{\r
+#endif \r
+\r
+\r
+/* interface __MIDL_itf_HWCFilter_0000_0000 */\r
+/* [local] */ \r
+\r
+// {320D90F3-3150-4D22-8437-1E5C0507CC39}\r
+DEFINE_GUID(CLSID_HWCFilterClass, 0x320d90f3, 0x3150, 0x4d22, 0x84, 0x37, 0x1e, 0x5c, 0x5, 0x7, 0xcc, 0x39);\r
+\r
+\r
+\r
+extern RPC_IF_HANDLE __MIDL_itf_HWCFilter_0000_0000_v0_0_c_ifspec;\r
+extern RPC_IF_HANDLE __MIDL_itf_HWCFilter_0000_0000_v0_0_s_ifspec;\r
+\r
+#ifndef __IHWCPin_INTERFACE_DEFINED__\r
+#define __IHWCPin_INTERFACE_DEFINED__\r
+\r
+/* interface IHWCPin */\r
+/* [full][helpstring][uuid][object] */ \r
+\r
+\r
+EXTERN_C const IID IID_IHWCPin;\r
+\r
+#if defined(__cplusplus) && !defined(CINTERFACE)\r
+ \r
+ MIDL_INTERFACE("33AFDC07-C2AB-4FC4-BA54-65FADF4B474D")\r
+ IHWCPin : public IPin\r
+ {\r
+ public:\r
+ virtual HRESULT STDMETHODCALLTYPE SetCallback( \r
+ ICaptureCallBack *pCaptureCB) = 0;\r
+ \r
+ };\r
+ \r
+#else /* C style interface */\r
+\r
+ typedef struct IHWCPinVtbl\r
+ {\r
+ BEGIN_INTERFACE\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )( \r
+ IHWCPin * This,\r
+ /* [in] */ REFIID riid,\r
+ /* [annotation][iid_is][out] */ \r
+ __RPC__deref_out void **ppvObject);\r
+ \r
+ ULONG ( STDMETHODCALLTYPE *AddRef )( \r
+ IHWCPin * This);\r
+ \r
+ ULONG ( STDMETHODCALLTYPE *Release )( \r
+ IHWCPin * This);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *Connect )( \r
+ IHWCPin * This,\r
+ /* [in] */ IPin *pReceivePin,\r
+ /* [annotation][in] */ \r
+ __in_opt const AM_MEDIA_TYPE *pmt);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *ReceiveConnection )( \r
+ IHWCPin * This,\r
+ /* [in] */ IPin *pConnector,\r
+ /* [in] */ const AM_MEDIA_TYPE *pmt);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *Disconnect )( \r
+ IHWCPin * This);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *ConnectedTo )( \r
+ IHWCPin * This,\r
+ /* [annotation][out] */ \r
+ __out IPin **pPin);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *ConnectionMediaType )( \r
+ IHWCPin * This,\r
+ /* [annotation][out] */ \r
+ __out AM_MEDIA_TYPE *pmt);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *QueryPinInfo )( \r
+ IHWCPin * This,\r
+ /* [annotation][out] */ \r
+ __out PIN_INFO *pInfo);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *QueryDirection )( \r
+ IHWCPin * This,\r
+ /* [annotation][out] */ \r
+ __out PIN_DIRECTION *pPinDir);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *QueryId )( \r
+ IHWCPin * This,\r
+ /* [annotation][out] */ \r
+ __out LPWSTR *Id);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *QueryAccept )( \r
+ IHWCPin * This,\r
+ /* [in] */ const AM_MEDIA_TYPE *pmt);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *EnumMediaTypes )( \r
+ IHWCPin * This,\r
+ /* [annotation][out] */ \r
+ __out IEnumMediaTypes **ppEnum);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *QueryInternalConnections )( \r
+ IHWCPin * This,\r
+ /* [annotation][out] */ \r
+ __out_ecount_part_opt(*nPin, *nPin) IPin **apPin,\r
+ /* [out][in] */ ULONG *nPin);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *EndOfStream )( \r
+ IHWCPin * This);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *BeginFlush )( \r
+ IHWCPin * This);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *EndFlush )( \r
+ IHWCPin * This);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *NewSegment )( \r
+ IHWCPin * This,\r
+ /* [in] */ REFERENCE_TIME tStart,\r
+ /* [in] */ REFERENCE_TIME tStop,\r
+ /* [in] */ double dRate);\r
+ \r
+ HRESULT ( STDMETHODCALLTYPE *SetCallback )( \r
+ IHWCPin * This,\r
+ ICaptureCallBack *pCaptureCB);\r
+ \r
+ END_INTERFACE\r
+ } IHWCPinVtbl;\r
+\r
+ interface IHWCPin\r
+ {\r
+ CONST_VTBL struct IHWCPinVtbl *lpVtbl;\r
+ };\r
+\r
+ \r
+\r
+#ifdef COBJMACROS\r
+\r
+\r
+#define IHWCPin_QueryInterface(This,riid,ppvObject) \\r
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) \r
+\r
+#define IHWCPin_AddRef(This) \\r
+ ( (This)->lpVtbl -> AddRef(This) ) \r
+\r
+#define IHWCPin_Release(This) \\r
+ ( (This)->lpVtbl -> Release(This) ) \r
+\r
+\r
+#define IHWCPin_Connect(This,pReceivePin,pmt) \\r
+ ( (This)->lpVtbl -> Connect(This,pReceivePin,pmt) ) \r
+\r
+#define IHWCPin_ReceiveConnection(This,pConnector,pmt) \\r
+ ( (This)->lpVtbl -> ReceiveConnection(This,pConnector,pmt) ) \r
+\r
+#define IHWCPin_Disconnect(This) \\r
+ ( (This)->lpVtbl -> Disconnect(This) ) \r
+\r
+#define IHWCPin_ConnectedTo(This,pPin) \\r
+ ( (This)->lpVtbl -> ConnectedTo(This,pPin) ) \r
+\r
+#define IHWCPin_ConnectionMediaType(This,pmt) \\r
+ ( (This)->lpVtbl -> ConnectionMediaType(This,pmt) ) \r
+\r
+#define IHWCPin_QueryPinInfo(This,pInfo) \\r
+ ( (This)->lpVtbl -> QueryPinInfo(This,pInfo) ) \r
+\r
+#define IHWCPin_QueryDirection(This,pPinDir) \\r
+ ( (This)->lpVtbl -> QueryDirection(This,pPinDir) ) \r
+\r
+#define IHWCPin_QueryId(This,Id) \\r
+ ( (This)->lpVtbl -> QueryId(This,Id) ) \r
+\r
+#define IHWCPin_QueryAccept(This,pmt) \\r
+ ( (This)->lpVtbl -> QueryAccept(This,pmt) ) \r
+\r
+#define IHWCPin_EnumMediaTypes(This,ppEnum) \\r
+ ( (This)->lpVtbl -> EnumMediaTypes(This,ppEnum) ) \r
+\r
+#define IHWCPin_QueryInternalConnections(This,apPin,nPin) \\r
+ ( (This)->lpVtbl -> QueryInternalConnections(This,apPin,nPin) ) \r
+\r
+#define IHWCPin_EndOfStream(This) \\r
+ ( (This)->lpVtbl -> EndOfStream(This) ) \r
+\r
+#define IHWCPin_BeginFlush(This) \\r
+ ( (This)->lpVtbl -> BeginFlush(This) ) \r
+\r
+#define IHWCPin_EndFlush(This) \\r
+ ( (This)->lpVtbl -> EndFlush(This) ) \r
+\r
+#define IHWCPin_NewSegment(This,tStart,tStop,dRate) \\r
+ ( (This)->lpVtbl -> NewSegment(This,tStart,tStop,dRate) ) \r
+\r
+\r
+#define IHWCPin_SetCallback(This,pCaptureCB) \\r
+ ( (This)->lpVtbl -> SetCallback(This,pCaptureCB) ) \r
+\r
+#endif /* COBJMACROS */\r
+\r
+\r
+#endif /* C style interface */\r
+\r
+\r
+\r
+\r
+#endif /* __IHWCPin_INTERFACE_DEFINED__ */\r
+\r
+\r
+/* Additional Prototypes for ALL interfaces */\r
+\r
+/* end of Additional Prototypes */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // __HWCFILTER_H_H__\r
+\r
+\r
--- /dev/null
+#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
--- /dev/null
+#ifndef __HWCPS_H__\r
+#define __HWCPS_H__\r
+\r
+#ifdef HWCFILTER_EXPORTS\r
+#define HWCFILTER_API extern "C" __declspec(dllexport) HRESULT __stdcall\r
+#else\r
+#define HWCFILTER_API __declspec(dllimport)\r
+#endif\r
+\r
+#include <DShow.h>\r
+#include "hwcfilter.h"\r
+\r
+#define SAFE_RELEASE(x) if (x) { (x)->Release(); (x) = NULL; }\r
+\r
+typedef int (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);\r
+\r
+class CCallback : ICaptureCallBack\r
+{\r
+public:\r
+ CCallback();\r
+ virtual ~CCallback();\r
+ STDMETHODIMP QueryInterface(REFIID riid, void **ppv);\r
+ STDMETHODIMP_(ULONG) AddRef();\r
+ STDMETHODIMP_(ULONG) Release();\r
+ STDMETHODIMP CaptureCallback(ULONG dwSize, BYTE *pBuffer);\r
+ STDMETHODIMP SetCallback(CallbackFn pCallbackFn);\r
+\r
+private:\r
+ long m_cRef;\r
+ CallbackFn m_pCallback;\r
+};\r
+\r
+class HWCSP\r
+{\r
+public:\r
+ HWCSP();\r
+ ~HWCSP();\r
+\r
+ STDMETHODIMP Init();\r
+ \r
+ STDMETHODIMP BindSourceFilter();\r
+ STDMETHODIMP BindTargetFilter();\r
+ STDMETHODIMP ConnectFilters();\r
+ STDMETHODIMP GetDeviceCaps(ULONG *fourcc, ULONG *width, ULONG *height, ULONG *fps);\r
+\r
+ STDMETHODIMP_(void) CloseInterfaces();\r
+ STDMETHODIMP_(void) DeleteMediaType(AM_MEDIA_TYPE *pmt);\r
+\r
+ STDMETHODIMP QueryVideoProcAmp(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault);\r
+ STDMETHODIMP GetVideoProcAmp(long nProperty, long *pValue);\r
+ STDMETHODIMP SetVideoProcAmp(long nProperty, long value);\r
+\r
+ STDMETHODIMP StartPreview();\r
+ STDMETHODIMP StopPreview();\r
+\r
+ STDMETHODIMP SetFPS(REFERENCE_TIME inFps);\r
+ STDMETHODIMP GetFPS(REFERENCE_TIME *outFps);\r
+\r
+ STDMETHODIMP SetResolution(LONG width, LONG height);\r
+ STDMETHODIMP GetResolution(LONG *width, LONG *height);\r
+\r
+ STDMETHODIMP GetFormats(LPVOID pData);\r
+ STDMETHODIMP GetFrameSizes(LPVOID pData);\r
+ STDMETHODIMP GetFrameIntervals(LPVOID pData);\r
+ STDMETHODIMP SetDefaultValues();\r
+\r
+ STDMETHODIMP SetCallback(CallbackFn pCallback);\r
+\r
+private:\r
+ STDMETHODIMP GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);\r
+\r
+ IGraphBuilder *m_pGB ;\r
+ ICaptureGraphBuilder2 *m_pCGB;\r
+ IMediaControl *m_pMC;\r
+ IMediaEventEx *m_pME;\r
+ \r
+ IPin *m_pOutputPin;\r
+ IPin *m_pInputPin;\r
+ IBaseFilter *m_pDF;\r
+ IBaseFilter *m_pSF;\r
+\r
+ CCallback *m_pCallback;\r
+\r
+ HINSTANCE m_hDLL;\r
+ DWORD m_dwFourcc;\r
+ DWORD m_dwWidth;\r
+ DWORD m_dwHeight;\r
+ DWORD m_dwAvgInterval;\r
+};\r
+\r
+enum {\r
+ HWC_OPEN,\r
+ HWC_CLOSE,\r
+ HWC_START,\r
+ HWC_STOP,\r
+ HWC_S_FPS,\r
+ HWC_G_FPS,\r
+ HWC_S_FMT,\r
+ HWC_G_FMT,\r
+ HWC_TRY_FMT,\r
+ HWC_ENUM_FMT,\r
+ HWC_QCTRL,\r
+ HWC_S_CTRL,\r
+ HWC_G_CTRL,\r
+ HWC_ENUM_FSIZES,\r
+ HWC_ENUM_INTERVALS\r
+};\r
+\r
+typedef struct tagHWCParam {\r
+ long val1;\r
+ long val2;\r
+ long val3;\r
+ long val4;\r
+ long val5;\r
+} HWCParam;\r
+\r
+HWCFILTER_API HWCCtrl(UINT nCmd, UINT nSize, LPVOID pBuf);\r
+\r
+HWCFILTER_API HWCSetCallback(CallbackFn pCallback);\r
+\r
+STDMETHODIMP HWCOpen();\r
+STDMETHODIMP HWCClose();\r
+STDMETHODIMP HWCStart();\r
+STDMETHODIMP HWCStop();\r
+\r
+STDMETHODIMP HWCSetFPS(long num, long denom);\r
+STDMETHODIMP HWCGetFPS(long *num, long *denom);\r
+\r
+STDMETHODIMP HWCSetFormat(long width, long height);\r
+STDMETHODIMP HWCGetFormat();\r
+STDMETHODIMP HWCTryFormat();\r
+STDMETHODIMP HWCEnumFormat();\r
+\r
+STDMETHODIMP HWCQueryControl(long nProperty, long *pMin, long *pMax, long *pStep, long *pDefault);\r
+STDMETHODIMP HWCSetControlValue(long nProperty, long value);\r
+STDMETHODIMP HWCGetControlValue(long nProperty, long *pVal);\r
+\r
+STDMETHODIMP HWCEnumFrameSizes();\r
+STDMETHODIMP HWCEnumFrameIntervals();\r
+\r
+#endif // __HWCPS_H__
\ No newline at end of file
--- /dev/null
+// stdafx.cpp : Ç¥ÁØ Æ÷ÇÔ ÆÄÀϸ¸ µé¾î ÀÖ´Â ¼Ò½º ÆÄÀÏÀÔ´Ï´Ù.\r
+// hwcfilter.pch´Â ¹Ì¸® ÄÄÆÄÀÏµÈ Çì´õ°¡ µË´Ï´Ù.\r
+// stdafx.obj¿¡´Â ¹Ì¸® ÄÄÆÄÀÏµÈ Çü½Ä Á¤º¸°¡ Æ÷ÇԵ˴ϴÙ.\r
+\r
+#include "stdafx.h"\r
+\r
+// TODO: ÇÊ¿äÇÑ Ãß°¡ Çì´õ´Â\r
+// ÀÌ ÆÄÀÏÀÌ ¾Æ´Ñ STDAFX.H¿¡¼ ÂüÁ¶ÇÕ´Ï´Ù.\r
--- /dev/null
+// stdafx.h : ÀÚÁÖ »ç¿ëÇÏÁö¸¸ ÀÚÁÖ º¯°æµÇÁö´Â ¾Ê´Â\r
+// Ç¥ÁØ ½Ã½ºÅÛ Æ÷ÇÔ ÆÄÀÏ ¹× ÇÁ·ÎÁ§Æ® °ü·Ã Æ÷ÇÔ ÆÄÀÏÀÌ\r
+// µé¾î ÀÖ´Â Æ÷ÇÔ ÆÄÀÏÀÔ´Ï´Ù.\r
+//\r
+\r
+#pragma once\r
+\r
+#include "targetver.h"\r
+\r
+#define WIN32_LEAN_AND_MEAN // °ÅÀÇ »ç¿ëµÇÁö ¾Ê´Â ³»¿ëÀº Windows Çì´õ¿¡¼ Á¦¿ÜÇÕ´Ï´Ù.\r
+// Windows Çì´õ ÆÄÀÏ:\r
+#include <windows.h>\r
+\r
+\r
+\r
+// TODO: ÇÁ·Î±×·¥¿¡ ÇÊ¿äÇÑ Ãß°¡ Çì´õ´Â ¿©±â¿¡¼ ÂüÁ¶ÇÕ´Ï´Ù.\r
--- /dev/null
+#pragma once\r
+\r
+// SDKDDKVer.h¸¦ Æ÷ÇÔÇϸé ÃÖ°í ¼öÁØÀÇ °¡¿ë¼ºÀ» °¡Áø Windows Ç÷§ÆûÀÌ Á¤Àǵ˴ϴÙ.\r
+\r
+// ÀÌÀü Windows Ç÷§Æû¿¡ ´ëÇØ ÀÀ¿ë ÇÁ·Î±×·¥À» ºôµåÇÏ·Á´Â °æ¿ì¿¡´Â SDKDDKVer.h¸¦ Æ÷ÇÔÇϱâ Àü¿¡\r
+// WinSDKVer.h¸¦ Æ÷ÇÔÇÏ°í _WIN32_WINNT ¸ÅÅ©·Î¸¦ Áö¿øÇÏ·Á´Â Ç÷§ÆûÀ¸·Î ¼³Á¤ÇϽʽÿÀ.\r
+\r
+#include <SDKDDKVer.h>\r
static HINSTANCE g_hInst = NULL;
+static SVCamState *g_state = NULL;
static CTRLFN SVCamCtrl;
static SETCALLBACKFN SVCamSetCallbackFn;
static uint32_t cur_fmt_idx = 0;
static uint32_t cur_frame_idx = 0;
-
-static void *g_vaddr = NULL;
-static qemu_irq *g_irq = NULL;
-
void v4lconvert_yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
uint32_t width, uint32_t height, uint32_t yvu);
static int STDAPICALLTYPE svcam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)
{
+ static uint32_t index = 0;
uint32_t width, height;
width = supported_dst_frames[cur_frame_idx].width;
height = supported_dst_frames[cur_frame_idx].height;
+ void *buf = g_state->vaddr + (g_state->buf_size * index);
switch (supported_dst_pixfmts[cur_fmt_idx].fmt) {
case V4L2_PIX_FMT_YUV420:
- v4lconvert_yuyv_to_yuv420(pBuffer, g_vaddr, width, height, 0);
+ v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 0);
break;
case V4L2_PIX_FMT_YVU420:
- v4lconvert_yuyv_to_yuv420(pBuffer, g_vaddr, width, height, 1);
+ v4lconvert_yuyv_to_yuv420(pBuffer, buf, width, height, 1);
break;
case V4L2_PIX_FMT_YUYV:
- memcpy(g_vaddr, (void*)pBuffer, dwSize);
+ memcpy(buf, (void*)pBuffer, dwSize);
break;
}
- qemu_irq_raise(g_irq[2]);
+ index = !index;
+
+ if (g_state->req_frame) {
+ qemu_irq_raise(g_state->dev.irq[2]);
+ g_state->req_frame = 0;
+ }
return 1;
}
pthread_cond_init(&thread->thread_cond, NULL);
pthread_mutex_init(&thread->mutex_lock, NULL);
- g_vaddr = state->vaddr;
- g_irq = state->dev.irq;
+ g_state = state;
}
// SVCAM_CMD_OPEN
void svcam_device_start_preview(SVCamState* state)
{
HRESULT hr;
+ uint32_t width, height;
SVCamParam *param = state->thread->param;
TRACE("svcam_device_start_preview\n");
param->top = 0;
if (FAILED(hr)) {
param->errCode = EINVAL;
ERR("start preview failed!!!, [HRESULT : 0x%x]\n", hr);
+ return;
}
pthread_mutex_lock(&state->thread->mutex_lock);
state->streamon = 1;
pthread_mutex_unlock(&state->thread->mutex_lock);
+
+ width = supported_dst_frames[cur_frame_idx].width;
+ height = supported_dst_frames[cur_frame_idx].height;
+ state->buf_size = height * ((width * supported_dst_pixfmts[cur_fmt_idx].bpp) >> 3);
}
// SVCAM_CMD_STOP_PREVIEW
pthread_mutex_lock(&state->thread->mutex_lock);
state->streamon = 0;
pthread_mutex_unlock(&state->thread->mutex_lock);
+ state->buf_size = 0;
}
// SVCAM_CMD_S_PARAM