Source: http://blog.csdn.net/chenice9999/article/details/6968957
Enumeration of camera devices (whether the devices are used or not ):
Int enumdevices ()
{
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); // you can get other info by first parame
If (hR = noerror)
{
Id ++;
Sysfreestring (var. bstrval );
}
Pbag-> release ();
}
PM-> release ();
}
Return ID;
}
Start the camera:
Hwnd m_hwnd;
Igraphbuilder * m_pgb;
Icapturegraphbuilder2 * m_pcapture;
Ibasefilter * m_pbf;
Imediacontrol * m_pmc;
Ivideowindow * m_pvw;
Ccomptr <isamplegrabber> m_pgrabber;
1. initialize graphbuilder
Cocreateinstance (clsid_filtergraph, null, clsctx_inproc_server, iid_igraphbuilder, (void **) & m_pgb );
Cocreateinstance (clsid_capturegraphbuilder2, null, clsctx_inproc, iid_icapturegraphbuilder2, (void **) & m_pcapture );
M_pcapture-> setfiltergraph (m_pgb );
M_pgb-> QueryInterface (iid_imediacontrol, (void **) & m_pmc );
M_pgb-> QueryInterface (iid_ivideowindow, (lpvoid *) & m_pvw );
2. Bind a device to inputfilter
Ccomptr <icreatedevenum> pcreatedevenum;
Cocreateinstance (clsid_systemdeviceenum, null, clsctx_inproc_server, iid_icreatedevenum, (void **) & pcreatedevenum );
Ccomptr <ienummoniker> PEM;
Pcreatedevenum-> createclassenumerator (clsid_videoinputdevicecategory, & PEM, 0 );
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)
{
PM-> bindtoobject (0, 0, iid_ibasefilter, (void **) pfilter );
Sysfreestring (var. bstrval );
}
Pbag-> release ();
}
PM-> release ();
}
3. Create an outputfilter
M_pgrabber.cocreateinstance (clsid_samplegrabber );
Ccomqiptr <ibasefilter, & iid_ibasefilter> pgrabbase (m_pgrabber );
4. Set the video format of samplegrabber
Am_media_type MT;
Zeromemory (& mt, sizeof (am_media_type ));
Mt. majortype = mediatype_video;
Mt. Subtype = mediasubtype_rgb24; // only the output image data type (24bit, 32bit,...) is set here. DirectShow automatically converts the collected image data.
M_pgrabber-> setmediatype (& mt );
5. Add two filters to graphbuilder.
M_pgb-> addfilter (m_pbf, l "capture filter ");
M_pgb-> addfilter (pgrabbase, l "Grabber ");
6. Try to remove renderstream. If it fails, the device cannot be used (for example, occupied by other applications)
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 (L "can't build the graph ");
Return hr;
}
7. Configure samplegrabber
M_pgrabber-> setbuffersamples (false); // if it is set to true, samplegrabber creates an internal buffer and obtains the data of the current frame through getcurrentbuffer.
M_pgrabber-> setoneshot (false); // if it is set to true, it indicates that the callback function is entered only once.
M_pgrabber-> setcallback (& McB, 1); // set callback. If 2nd parameters are set to 0, the first parameter must be the imediasample pointer.
8. Start video capture
M_pmc-> Run ();
Enumeration to set the data format of inputfilter:
Ccomptr <iamstreamconfig> PAM;
M_pcapture-> findinterface (& pin_category_capture, & mediatype_video, m_pbf, iid_iamstreamconfig, reinterpret_cast <void **> (& Pam ));
Int ncount = 0;
Int nsize = 0;
Pam-> getnumberofcapabilities (& ncount, & nsize );
Am_media_type * PMT = NULL;
Video_stream_config_caps SCC;
If (sizeof (video_stream_config_caps) = nsize ){
For (INT I = 0; I <ncount; I ++ ){
PMT = NULL;
HR = Pam-> getstreamcaps (I, & PMT, reinterpret_cast <byte *> (& SCC ));
If (failed (HR ))
{
Continue;
}
If (PMT-> majortype = mediatype_video & PMT-> formattype = format_videoinfo)
{
Pam-> setformat (PMT );
Break;
}
}
}
Release am_media_type resources:
Void 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;
}
}
Bind the video output window:
Create a picture space and set its attributes (type: rectangle, color: Gray)
M_pvw-> put_owner (oahwnd) m_hwnd );
M_pvw-> put_windowstyle (ws_child | ws_clipchildren );
Rect RC;
: Getclientrect (m_hwnd, & rc );
Float FK = (float) McB. lwidth/(float) McB. lheight;
Long RW = FK * RC. bottom;
Int off_x = (RC. Right-RW)/2;
M_pvw-> setwindowposition (off_x, 0, RW, RC. Bottom); // center the captured video
M_pvw-> put_visible (oatrue );
Unbind video output window:
M_pvw-> put_visible (oafalse );
M_pvw-> put_owner (null );