Visual c ++ programming for camera video capture and storage

Source: Internet
Author: User
Http://www.mscto.com/vc/2009022674609.htmlanother Use the sample grabber filter to capture images


Visual c ++ programming video capture by cameras released at: 09:16:49 Source: Author: Click: 798 Preface

DirectShow is a set of development kits provided by Microsoft for streaming media processing on the Windows platform and released together with the DirectX Development Kit. DirectShow provides powerful support for capturing and playback of Multimedia Streams. Using DirectShow to develop applications, we can easily capture data from the acquisition card that supports the WDM driver model, and perform corresponding post-processing and even storage into files.

DirectShow is based on COM. To compile DirectShow applications, you need to understand the basic knowledge of COM Client programming. DirectShow provides a large number of interfaces, but it is not easy to find in programming. If you can build a video capture class to encapsulate some common actions, it is more convenient.

  Programming Logic

To create a video capture application more easily, DirectShow provides an object called capture graph builder. Capture graph Builder provides the icapturegraphbuilder2 interface, which can be used to create and control capture.
Graph.

To create a video capturing program, you must first obtain and initialize the icapturegraphbuilder2 interface, and then select an appropriate video capturing device. After the device is selected, create a capture filter for the device and call addfilter
Add filter to filter graph.

If you only want to use a camera for real-time monitoring, you only need to call icapturegraphbuilder2: renderstream on the basis of the above:

Icapturegraphbuilder2 * pbuild; // capture graph Builder
// Some initialization code is omitted
Ibasefilter * pcap; // video capture filter.
// The initialization and addition of filter graph code are omitted.
Pbuild-> renderstream (& pin_category_preview, & mediatype_video, pcap, null, null );

DirectShow provides a method to capture static images: Use the sample grabber filter. Follow these three steps:

Step 1: Define a class to implement the callback interface isamplegrabbercb for sample grabber:

Class csamplegrabbercb: Public isamplegrabbercb
{
// Complete it in the class provided later
}
Csamplegrabbercb MCB;

Step 2: Call renderstream to connect still pin, sample grabber, and default Renderer Filter.

Step 3: Configure sample grabber to capture data.

Implementation of ccapturevideo for video capturing

// Ccapturevideo video capture Class header file
//////////////////////////////////////// /////////////////////////////
# If! Defined (afx_capturevideo_h1_f5345aa4 _ a3arrayf_4b07_b843_3d87c4287aa0 _ included _)
# Define afx_capturevideo_h1_f5345aa4 _ a3arrayf_4b07_b843_3d87c4287aa0 _ included _
//////////////////////////////////////// /////////////////////////////
// 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 _ a3arrayf_4b07_b843_3d87c4287aa0 _ included _)
//-------------------------------------------------------------------
// 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)
{
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;
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.