Use the DirectShow drive camera
There are several ways to drive the small camera. By using DirectShow, it is better to drive the camera flexibility. It has a relatively complex but more efficient method. This article only introduces the simple method, I hope to communicate with you!
Use DirectShow to use the camera, which generally requires the camera's drive to be WDM format, of course, some older drive format DirectShow can also support. DirectSHOW is connected to the driver of the upper application and the lower layer through the Filter Graph Manager. DirectSHOW supports capture of the camera through a Capture Filter, and a capture filter has multiple sockets (PREVIEW) sockets can be used to display an image.
DirectShow controls the entire process of video capture through several COM interfaces, where IGraphBuilder is used to establish a filter, and IcapturegraphBuilder2 is used to establish contacts with the next driver, iVideoWindow, ImediaControl, IMEDIAEVENTEX respectively on the entire process video window, playback process Control with event response,
Below is routine:
CCOMQIPTR
m_pvw;
CCOMQIPTR
m_pmc;
CCOMQIPTR
M_PME;
CComptr
m_pgraph;
CComptr
m_pcapture;
DWORD m_dwGraphRegister; bool bInit (HWND hWnd) {HRESULT hr; // get the interface hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **) & m_pGraph); if (FAILED (hr)) return false; hr = CoCreateInstance (CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **) & m_pCapture); if (FAILED (hr)) return false; m_pMC = m_pGraph; m_pVW = m_pGraph; m_pME = m_pGraph; // obtain information m_pME-> SetNotifyWindow ((OAHWND ) (m_hwnd = hwnd), WM_GraphNotify, 0); // Connect the filter and capture M_PCapture-> setFilterGraph (m_pgraph); // Device join // enumerate device CComptr
PCDE = NULL;
CComptr
PEM = NULL;
hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void **) & pCde); if (FAILED (hr)) return false; pCde-> CreateClassEnumerator (CLSID_VideoInputDeviceCategory, & pEm, 0); if (pEm == NULL) return False; ccomptr
PM = NULL;
Ulong cfetched; ccomptr
PBF = NULL;
IF (PEM-> Next (1, & PM, & CFETCHED) == S_OK) {PM-> BindToObject (0, 0, IID_IBASEFILTER, (Void **) & PBF); PM.Release ();} else {returnaf false;} // add a device to the graph hr = m_pGraph-> AddFilter (pBf, L "Video Capture"); if (FAILED (hr)) return false; // source connected to a jack hr = m_pCapture-> RenderStream (& PIN_CATEGORY_PREVIEW, & MEDIATYPE_Video, PBF, NULL, NULL; IF (Failed (HR)) Return False; pbf.release (); // Set Video Window // Setting the Video Window for a child window hr = m_pvw-> put_owner (((( OAHWND); if (Failed (HR)) Return False; // Setting Window Style M_PVW-> PUT_WINDOWSTYLE (WS_CHILD | WS_CLIPCHILDREN); if (Failed (HR)) Return False; // Settings Window Size CRECTCLIENT; GetClientRect (hwnd, rectclient); m_pvw-> setWindowPosition (0, 0, 320, 240); // Set visual HR = m_pvw-> PUT_Visible (OATRUE); if (Failed (HR)) Return False; // The object is added to the list of ccCompTrProt in the list of run objects;
GetrunningObjectTable (0, & prot); WCHAR C [128]; WSPrintfw (c, l "filtergraph% 08x pid% 08X / 0", (DWORD_PTR) m_pgraph.p, getCurrentProcessId ()); hr = CreateItemmoniker (l "!", C, & PM); failed (HR)) Return False; hr = prot-> register (rotflags_registrationKeepsalive, M_PGRAPH, PM, & m_dwgraphregister); pm.release (); return false;}