// CCaptureVideo video capture Class header file //////////////////////////////////////// ///////////////////////////// # If! Defined (afx_capturevideo_h1_f5345aa4_a39f_4b07_b843_3d87c4287aa01_encoded _) # Define afx_capturevideo_h1_f5345aa4_a39f_4b07_b843_3d87c4287aa01_encoded _ //////////////////////////////////////// ///////////////////////////// // CaptureVideo. h: header file //////////////////////////////////////// ///////////////////////////// # If _ msc_ver> 1000 # Pragma once # Endif // _ msc_ver> 1000 # Include <atlbase. h> # Include <windows. h> # Include <dshow. h> # Ifndef safe_release # Define safe_release (X )/ If (null! = X )/ {/ X-> release ();/ X = NULL ;/ } # Endif Class csamplegrabbercb; Class ccapturevideo: Public cwnd { Friend class csamplegrabbercb; Public: Void graboneframe (bool bgrab ); Hresult Init (INT ideviceid, hwnd ); Int enumdevices (hwnd hlist ); Ccapturevideo (); Virtual ~ Ccapturevideo (); Private: HWND m_hWnd; IGraphBuilder * m_pGB; ICaptureGraphBuilder2 * m_pCapture; IBaseFilter * m_pBF; IMediaControl * m_pMC; IVideoWindow * m_pVW; CComPtr <ISampleGrabber> m_pGrabber; Protected: Void FreeMediaType (AM_MEDIA_TYPE & mt ); Bool BindFilter (int deviceId, IBaseFilter ** pFilter ); Void ResizeVideoWindow (); HRESULT SetupVideoWindow (); HRESULT InitCaptureGraphBuilder (); }; # Endif //! Defined (afx_capturevideo_h1_f5345aa4_a39f_4b07_b843_3d87c4287aa01_encoded _) //------------------------------------------------------------------- // The implementation file CaptureVideo. cpp of the CCaptureVideo video capture class //------------------------------------------------------------------- // CaptureVideo. cpp: implementation of the CCaptureVideo class. // //////////////////////////////////////// ///////////////////////////// # Include "stdafx. h" # Include "CaptureVideo. h" # Ifdef _ DEBUG # Undef THIS_FILE Static char THIS_FILE [] =__ FILE __; # Define new DEBUG_NEW # Endif BOOL bOneShot = FALSE; // global variable Class CSampleGrabberCB: public ISampleGrabberCB { Public: Long lWidth; Long lHeight; TCHAR m_szFileName [MAX_PATH]; // bitmap file name CSampleGrabberCB (){ Strcpy (m_szFileName, "c: // donaldo.bmp "); } STDMETHODIMP _ (ULONG) AddRef () {return 2 ;} STDMETHODIMP _ (ULONG) Release () {return 1 ;} Stdmethodimp QueryInterface (refiid riid, void ** GMM ){ If (riid = iid_isamplegrabbercb | riid = iid_iunknown ){ * GMM = (void *) static_cast <isamplegrabbercb *> (this ); Return noerror; } Return e_nointerface; } Stdmethodimp samplecb (double sampletime, imediasample * psample ){ Return 0; } Stdmethodimp buffercb (double dblsampletime, byte * pbuffer, long lbuffersize ){ If (! Boneshot) return 0; If (! Pbuffer) return e_pointer; Savebitmap (pbuffer, lbuffersize ); Boneshot = false; Return 0; } // Create a bitmap file Bool savebitmap (byte * pbuffer, long lbuffersize) { Handle HF = createfile ( M_szfilename, generic_write, file_assist_read, null, Create_always, null, null ); If (HF = invalid_handle_value) return 0; // Write the file header Bitmapfileheader BFH; Memset (& BFH, 0, sizeof (BFH )); BFH. bftype = 'mb '; BFH. bfsize = sizeof (BFH) + lbuffersize + sizeof (bitmapinfoheader ); BFH. bfoffbits = sizeof (bitmapinfoheader) + sizeof (bitmapfileheader ); DWORD dwwritten = 0; Writefile (HF, & BFH, sizeof (BFH), & dwwritten, null ); // Write bitmap format Bitmapinfoheader BiH; Memset (& BiH, 0, sizeof (BiH )); BiH. bisize = sizeof (BiH ); BiH. biwidth = lwidth; BiH. biheight = lheight; BiH. biplanes = 1; BiH. bibitcount = 24; Writefile (HF, & BiH, sizeof (BiH), & dwwritten, null ); // Write bitmap data Writefile (HF, pbuffer, lbuffersize, & dwwritten, null ); Closehandle (HF ); Return 0; } }; Csamplegrabbercb MCB; //////////////////////////////////////// ////////////////////////////// // Construction/destruction //////////////////////////////////////// ////////////////////////////// Ccapturevideo: ccapturevideo () { // Com library intialization If (failed (coinitialize (null)/*, coinit_apartmentthreaded )))*/ { Afxmessagebox ("coinitialize failed! /R/N "); Return; } M_hwnd = NULL; M_pvw = NULL; M_pmc = NULL; M_pGB = NULL; M_pCapture = NULL; } CCaptureVideo ::~ CCaptureVideo () { // Stop media playback If (m_pMC) m_pMC-> Stop (); If (m_pVW ){ M_pVW-> put_Visible (OAFALSE ); M_pVW-> put_Owner (NULL ); } SAFE_RELEASE (m_pCapture ); SAFE_RELEASE (m_pMC ); SAFE_RELEASE (m_pGB ); SAFE_RELEASE (m_pBF ); CoUninitialize (); } Int CCaptureVideo: EnumDevices (HWND hList) { If (! HList) Return-1; Int id = 0;// Enumerate video capturing devices ICreateDevEnum * pCreateDevEnum; HRESULT hr = CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **) & pCreateDevEnum ); If (hr! = NOERROR) return-1; CComPtr <IEnumMoniker> pEm; Hr = pCreateDevEnum-> CreateClassEnumerator (CLSID_VideoInputDeviceCategory, & pEm, 0 ); If (HR! = Noerror) Return-1; PEM-> Reset (); Ulong cfetched; Imoniker * PM; While (hR = PEM-> next (1, & PM, & cfetched), HR = s_ OK) { Ipropertybag * pbag; HR = PM-> bindtostorage (0, 0, iid_ipropertybag, (void **) & pbag ); If (succeeded (HR )) { Variant var; Var. Vt = vt_bstr; HR = pbag-> Read (L "friendlyname", & var, null ); If (hR = noerror) { Tchar STR [2048]; Id ++; Widechartomultibyte (cp_acp, 0, var. bstrval,-1, STR, 2048, null, null ); : Sendmessage (hlist, cb_addstring, 0, (lparam) Str ); Sysfreestring (var. bstrval ); } Pbag-> release (); } PM-> Release (); } Return id; } HRESULT CCaptureVideo: Init (int iDeviceID, HWND hWnd) { HRESULT hr; Hr = InitCaptureGraphBuilder (); If (FAILED (hr )){ AfxMessageBox ("Failed to get video interfaces! "); Return hr; } // Bind Device Filter. We know the device because the id was passed in If (! BindFilter (iDeviceID, & m_pBF) return S_FALSE; Hr = m_pGB-> AddFilter (m_pBF, L "Capture Filter "); // Hr = m_pCapture-> RenderStream (& PIN_CATEGORY_PREVIEW, & MEDIATYPE_Video, // M_pBF, NULL, NULL ); // Create a sample grabber Hr = m_pGrabber.CoCreateInstance (CLSID_SampleGrabber ); If (! M_pGrabber ){ Afxmessagebox ("fail to create samplegrabber, maybe qedit. dll is not registered? "); Return hr; } Ccomqiptr <ibasefilter, & iid_ibasefilter> pgrabbase (m_pgrabber ); // Set the video format Am_media_type MT; Zeromemory (& mt, sizeof (am_media_type )); Mt. majortype = mediatype_video; Mt. Subtype = mediasubtype_rgb24; HR = m_pgrabber-> setmediatype (& mt ); If (failed (HR )){ Afxmessagebox ("fail to set media type! "); Return hr; } HR = m_pgb-> addfilter (pgrabbase, l "Grabber "); If (failed (HR )){ Afxmessagebox ("fail to put sample grabber in graph "); Return hr; } // Try to render preview/capture pin Hr = m_pCapture-> RenderStream (& PIN_CATEGORY_PREVIEW, & MEDIATYPE_Video, m_pBF, pGrabBase, NULL ); If (FAILED (hr )) Hr = m_pCapture-> RenderStream (& PIN_CATEGORY_CAPTURE, & MEDIATYPE_Video, m_pBF, pGrabBase, NULL ); If (FAILED (hr )){ AfxMessageBox ("Can't build the graph "); Return hr; } Hr = m_pGrabber-> GetConnectedMediaType (& mt ); If (FAILED (hr )){ AfxMessageBox ("Failt to read the connected media type "); Return hr; } VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) mt. pbFormat; MCB. lWidth = vih-> bmiHeader. biWidth; MCB. lHeight = vih-> bmiHeader. biHeight; FreeMediaType (mt ); Hr = m_pGrabber-> SetBufferSamples (FALSE ); HR = m_pgrabber-> setoneshot (false ); HR = m_pgrabber-> setcallback (& McB, 1 ); // Set the video capture window M_hwnd = hwnd; Setupvideowindow (); HR = m_pmc-> Run (); // start video capture If (failed (HR) {afxmessagebox ("couldn't run the graph! "); Return hr ;} Return s_ OK; } Bool ccapturevideo: bindfilter (INT DeviceID, ibasefilter ** pfilter) { If (DeviceID <0) Return false; // Enumerate all Video Capture Devices Ccomptr <icreatedevenum> pcreatedevenum; Hresult hR = cocreateinstance (clsid_systemdeviceenum, null, clsctx_inproc_server, Iid_icreatedevenum, (void **) & pcreatedevenum ); If (HR! = Noerror) { Return false; } Ccomptr <ienummoniker> PEM; HR = pcreatedevenum-> createclassenumerator (clsid_videoinputdevicecategory, & PEM, 0 ); If (HR! = Noerror) { Return false; } PEM-> Reset (); Ulong cfetched; Imoniker * PM; Int Index = 0; While (hR = PEM-> next (1, & PM, & cfetched), HR = s_ OK, index <= DeviceID) { Ipropertybag * pbag; HR = PM-> bindtostorage (0, 0, iid_ipropertybag, (void **) & pbag ); If (succeeded (HR )) { Variant var; Var. Vt = vt_bstr; HR = pbag-> Read (L "friendlyname", & var, null ); If (hR = noerror) { If (Index = DeviceID) { PM-> BindToObject (0, 0, IID_IBaseFilter, (void **) pFilter ); } SysFreeString (var. bstrVal ); } PBag-> Release (); } PM-> Release (); Index ++; } Return true; } HRESULT CCaptureVideo: InitCaptureGraphBuilder () { HRESULT hr; // Create the IGraphBuilder Interface Hr = CoCreateInstance (CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **) & m_pGB ); // Create ICaptureGraphBuilder2 Interface Hr = CoCreateInstance (CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void **) & m_pCapture ); If (FAILED (hr) return hr; M_pCapture-> SetFiltergraph (m_pGB ); Hr = m_pGB-> QueryInterface (IID_IMediaControl, (void **) & m_pMC ); If (FAILED (hr) return hr; Hr = m_pGB-> QueryInterface (IID_IVideoWindow, (LPVOID *) & m_pVW ); If (FAILED (hr) return hr; Return hr; } HRESULT CCaptureVideo: SetupVideoWindow () { HRESULT hr; Hr = m_pVW-> put_Owner (OAHWND) m_hWnd ); If (FAILED (hr) return hr; Hr = m_pVW-> put_WindowStyle (WS_CHILD | WS_CLIPCHILDREN ); If (FAILED (hr) return hr; ResizeVideoWindow (); Hr = m_pVW-> put_Visible (OATRUE ); Return hr; } Void CCaptureVideo: ResizeVideoWindow () { If (m_pVW ){ // Fill the image with the entire window CRect rc; : Getclientrect (m_hwnd, & rc ); M_pvw-> setwindowposition (0, 0, RC. Right, RC. Bottom ); } } Void ccapturevideo: graboneframe (bool bgrab) { Boneshot = bgrab; } Void ccapturevideo: freemediatype (am_media_type & mt) { If (mt. cbformat! = 0 ){ Cotaskmemfree (pvoid) Mt. pbformat ); // Strictly unnecessary but tidier Mt. cbformat = 0; Mt. pbformat = NULL; } If (mt. Punk! = NULL ){ Mt. Punk-> release (); Mt. Punk = NULL; } } |