DirectShowSamples-2007-July\Samples\Capture\DxSnap
Capture.cs
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->/****************************************************************************
WhiletheunderlyinglibrariesarecoveredbyLGPL,thissampleisreleased
aspublicdomain.Itisdistributedinthehopethatitwillbeuseful,but
WITHOUTANYWARRANTY;withouteventheimpliedwarrantyofMERCHANTABILITY
orFITNESSFORAPARTICULARPURPOSE.
*****************************************************************************/
usingSystem;
usingSystem.Drawing;
usingSystem.Drawing.Imaging;
usingSystem.Collections;
usingSystem.Runtime.InteropServices;
usingSystem.Threading;
usingSystem.Diagnostics;
usingSystem.Windows.Forms;
usingDirectShowLib;
namespaceSnapShot
{
///<summary>SummarydescriptionforMainForm.</summary>
internalclassCapture:ISampleGrabberCB,IDisposable
{
#regionMembervariables
///<summary>graphbuilderinterface.</summary>
privateIFilterGraph2m_FilterGraph=null;
//UsedtosnappictureonStillpin
privateIAMVideoControlm_VidControl=null;
privateIPinm_pinStill=null;
///<summary>sowecanwaitfortheasyncjobtofinish</summary>
privateManualResetEventm_PictureReady=null;
privateboolm_WantOne=false;
///<summary>Dimensionsoftheimage,calculatedonceinconstructorforperf.</summary>
privateintm_videoWidth;
privateintm_videoHeight;
privateintm_stride;
///<summary>bufferforbitmapdata.Alwaysreleasebycaller</summary>
privateIntPtrm_ipBuffer=IntPtr.Zero;
#ifDEBUG
//Allowyouto"Connecttoremotegraph"fromGraphEdit
DsROTEntrym_rot=null;
#endif
#endregion
#regionAPIs
[DllImport("Kernel32.dll",EntryPoint="RtlMoveMemory")]
privatestaticexternvoidCopyMemory(IntPtrDestination,IntPtrSource,[MarshalAs(UnmanagedType.U4)]intLength);
#endregion
//Zerobaseddeviceindexanddeviceparamsandoutputwindow
publicCapture(intiDeviceNum,intiWidth,intiHeight,shortiBPP,ControlhControl)
{
DsDevice[]capDevices;
//Getthecollectionofvideodevices
capDevices=DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
if(iDeviceNum+1>capDevices.Length)
{
thrownewException("Novideocapturedevicesfoundatthatindex!");
}
try
{
//Setupthecapturegraph
SetupGraph(capDevices[iDeviceNum],iWidth,iHeight,iBPP,hControl);
//tellthecallbacktoignorenewimages
m_PictureReady=newManualResetEvent(false);
}
catch
{
Dispose();
throw;
}
}
///<summary>releaseeverything.</summary>
publicvoidDispose()
{
#ifDEBUG
if(m_rot!=null)
{
m_rot.Dispose();
}
#endif
CloseInterfaces();
if(m_PictureReady!=null)
{
m_PictureReady.Close();
}
}
//Destructor
~Capture()
{
Dispose();
}
///<summary>
///GettheimagefromtheStillpin.Thereturnedimagecanturnedintoabitmapwith
///Bitmapb=newBitmap(cam.Width,cam.Height,cam.Stride,PixelFormat.Format24bppRgb,m_ip);
///Iftheimageisupsidedown,youcanfixitwith
///b.RotateFlip(RotateFlipType.RotateNoneFlipY);
///</summary>
///<returns>ReturnedpointertobefreedbycallerwithMarshal.FreeCoTaskMem</returns>
publicIntPtrClick()
{
inthr;
//getreadytowaitfornewimage
m_PictureReady.Reset();
m_ipBuffer=Marshal.AllocCoTaskMem(Math.Abs(m_stride)*m_videoHeight);
try
{
m_WantOne=true;
//Ifweareusingastillpin,askforapicture
if(m_VidControl!=null)
{
//Tellthecameratosendanimage
hr=m_VidControl.SetMode(m_pinStill,VideoControlFlags.Trigger);
DsError.ThrowExceptionForHR(hr);
}
//Startwaiting
if(!m_PictureReady.WaitOne(9000,false))
{
thrownewException("Timeoutwaitingtogetpicture");
}
}
catch
{
Marshal.FreeCoTaskMem(m_ipBuffer);
m_ipBuffer=IntPtr.Zero;
throw;
}
//Gotone
returnm_ipBuffer;
}
publicintWidth
{
get
{
returnm_videoWidth;
}
}
publicintHeight
{
get
{
returnm_videoHeight;
}
}
publicintStride
{
get
{
returnm_stride;
}
}
///<summary>buildthecapturegraphforgrabber.</summary>
privatevoidSetupGraph(DsDevicedev,intiWidth,intiHeight,shortiBPP,ControlhControl)
{
inthr;
ISampleGrabbersampGrabber=null;
IBaseFiltercapFilter=null;
IPinpCaptureOut=null;
IPinpSampleIn=null;
IPinpRenderIn=null;
//Getthegraphbuilderobject
m_FilterGraph=newFilterGraph()asIFilterGraph2;
try
{
#ifDEBUG
m_rot=newDsROTEntry(m_FilterGraph);
#endif
//addthevideoinputdevice
hr=m_FilterGraph.AddSourceFilterForMoniker(dev.Mon,null,dev.Name,outcapFilter);
DsError.ThrowExceptionForHR(hr);
//Findthestillpin
m_pinStill=DsFindPin.ByCategory(capFilter,PinCategory.Still,0);
//Didn'tfindone.Isthereapreviewpin?
if(m_pinStill==null)
{
m_pinStill=DsFindPin.ByCategory(capFilter,PinCategory.Preview,0);
}
//Stillhaven'tfoundone.Needtoputasplitterinsowehave
//onestreamtocapturethebitmapfrom,andonetodisplay.Ok,we
//don't*have*todoitthatway,butwearegoingtoanyway.
if(m_pinStill==null)
{
IPinpRaw=null;
IPinpSmart=null;
//Thereisnostillpin
m_VidControl=null;
//Addasplitter
IBaseFilteriSmartTee=(IBaseFilter)newSmartTee();
try
{
hr=m_FilterGraph.AddFilter(iSmartTee,"SmartTee");
DsError.ThrowExceptionForHR(hr);
//Findthefindthecapturepinfromthevideodeviceandthe
//inputpinforthesplitter,andconnnectthem
pRaw=DsFindPin.ByCategory(capFilter,PinCategory.Capture,0);
pSmart=DsFindPin.ByDirection(iSmartTee,PinDirection.Input,0);
hr=m_FilterGraph.Connect(pRaw,pSmart);
DsError.ThrowExceptionForHR(hr);
//Nowsetthecaptureandstillpins(fromthesplitter)
m_pinStill=DsFindPin.ByName(iSmartTee,"Preview");
pCaptureOut=DsFindPin.ByName(iSmartTee,"Capture");
//Ifanyofthedefaultconfigitemsareset,performtheconfig
//ontheactualvideodevice(ratherthanthesplitter)
if(iHeight+iWidth+iBPP>0)
{
SetConfigParms(pRaw,iWidth,iHeight,iBPP);
}
}
finally
{
if(pRaw!=null)
{
Marshal.ReleaseComObject(pRaw);
}
if(pRaw!=pSmart)
{
Marshal.ReleaseComObject(pSmart);
}
if(pRaw!=iSmartTee)
{
Marshal.ReleaseComObject(iSmartTee);
}
}
}
else
{
//Getacontrolpointer(usedinClick())
m_VidControl=capFilterasIAMVideoControl;
pCaptureOut=DsFindPin.ByCategory(capFilter,PinCategory.Capture,0);
//Ifanyofthedefaultconfigitemsareset
if(iHeight+iWidth+iBPP>0)
{
SetConfigParms(m_pinStill,iWidth,iHeight,iBPP);
}
}
//GettheSampleGrabberinterface
sampGrabber=newSampleGrabber()asISampleGrabber;
//Configurethesamplegrabber
IBaseFilterbaseGrabFlt=sampGrabberasIBaseFilter;
ConfigureSampleGrabber(sampGrabber);
pSampleIn=DsFindPin.ByDirection(baseGrabFlt,PinDirection.Input,0);
//Getthedefaultvideorenderer
IBaseFilterpRenderer=newVideoRendererDefault()asIBaseFilter;
hr=m_FilterGraph.AddFilter(pRenderer,"Renderer");
DsError.ThrowExceptionForHR(hr);
pRenderIn=DsFindPin.ByDirection(pRenderer,PinDirection.Input,0);
//Addthesamplegrabbertothegraph
hr=m_FilterGraph.AddFilter(baseGrabFlt,"Ds.NETGrabber");
DsError.ThrowExceptionForHR(hr);
if(m_VidControl==null)
{
//ConnecttheStillpintothesamplegrabber
hr=m_FilterGraph.Connect(m_pinStill,pSampleIn);
DsError.ThrowExceptionForHR(hr);
//Connectthecapturepintotherenderer
hr=m_FilterGraph.Connect(pCaptureOut,pRenderIn);
DsError.ThrowExceptionForHR(hr);
}
else
{
//Connectthecapturepintotherenderer
hr=m_FilterGraph.Connect(pCaptureOut,pRenderIn);
DsError.ThrowExceptionForHR(hr);
//ConnecttheStillpintothesamplegrabber
hr=m_FilterGraph.Connect(m_pinStill,pSampleIn);
DsError.ThrowExceptionForHR(hr);
}
//Learnthevideoproperties
SaveSizeInfo(sampGrabber);
ConfigVideoWindow(hControl);
//Startthegraph
IMediaControlmediaCtrl=m_FilterGraphasIMediaControl;
hr=mediaCtrl.Run();
DsError.ThrowExceptionForHR(hr);
}
finally
{
if(sampGrabber!=null)
{
Marshal.ReleaseComObject(sampGrabber);
sampGrabber=null;
}
if(pCaptureOut!=null)
{
Marshal.ReleaseComObject(pCaptureOut);
pCaptureOut=null;
}
if(pRenderIn!=null)
{
Marshal.ReleaseComObject(pRenderIn);
pRenderIn=null;
}
if(pSampleIn!=null)
{
Marshal.ReleaseComObject(pSampleIn);
pSampleIn=null;
}
}
}
privatevoidSaveSizeInfo(ISampleGrabbersampGrabber)
{
inthr;
//GetthemediatypefromtheSampleGrabber
AMMediaTypemedia=newAMMediaType();
hr=sampGrabber.GetConnectedMediaType(media);
DsError.ThrowExceptionForHR(hr);
if((media.formatType!=FormatType.VideoInfo)||(media.formatPtr==IntPtr.Zero))
{
thrownewNotSupportedException("UnknownGrabberMediaFormat");
}
//Grabthesizeinfo
VideoInfoHeadervideoInfoHeader=(VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr,typeof(VideoInfoHeader));
m_videoWidth=videoInfoHeader.BmiHeader.Width;
m_videoHeight=videoInfoHeader.BmiHeader.Height;
m_stride=m_videoWidth*(videoInfoHeader.BmiHeader.BitCount/8);
DsUtils.FreeAMMediaType(media);
media=null;
}
//SetthevideowindowwithinthecontrolspecifiedbyhControl
privatevoidConfigVideoWindow(ControlhControl)
{
inthr;
IVideoWindowivw=m_FilterGraphasIVideoWindow;
//Settheparent
hr=ivw.put_Owner(hControl.Handle);
DsError.ThrowExceptionForHR(hr);
//Turnoffcaptions,etc
hr=ivw.put_WindowStyle(WindowStyle.Child|WindowStyle.ClipChildren|WindowStyle.ClipSiblings);
DsError.ThrowExceptionForHR(hr);
//Yes,makeitvisible
hr=ivw.put_Visible(OABool.True);
DsError.ThrowExceptionForHR(hr);
//Movetoupperleftcorner
Rectanglerc=hControl.ClientRectangle;
hr=ivw.SetWindowPosition(0,0,rc.Right,rc.Bottom);
DsError.ThrowExceptionForHR(hr);
}
privatevoidConfigureSampleGrabber(ISampleGrabbersampGrabber)
{
inthr;
AMMediaTypemedia=newAMMediaType();
//SetthemediatypetoVideo/RBG24
media.majorType=MediaType.Video;
media.subType=MediaSubType.RGB24;
media.formatType=FormatType.VideoInfo;
hr=sampGrabber.SetMediaType(media);
DsError.ThrowExceptionForHR(hr);
DsUtils.FreeAMMediaType(media);
media=null;
//Configurethesamplegrabber
hr=sampGrabber.SetCallback(this,1);
DsError.ThrowExceptionForHR(hr);
}
//SettheFramerate,andvideosize
privatevoidSetConfigParms(IPinpStill,intiWidth,intiHeight,shortiBPP)
{
inthr;
AMMediaTypemedia;
VideoInfoHeaderv;
IAMStreamConfigvideoStreamConfig=pStillasIAMStreamConfig;
//Gettheexistingformatblock
hr=videoStreamConfig.GetFormat(outmedia);
DsError.ThrowExceptionForHR(hr);
try
{
//copyoutthevideoinfoheader
v=newVideoInfoHeader();
Marshal.PtrToStructure(media.formatPtr,v);
//ifoverridingthewidth,setthewidth
if(iWidth>0)
{
v.BmiHeader.Width=iWidth;
}
//ifoverridingtheHeight,settheHeight
if(iHeight>0)
{
v.BmiHeader.Height=iHeight;
}
//ifoverridingthebitsperpixel
if(iBPP>0)
{
v.BmiHeader.BitCount=iBPP;
}
//Copythemediastructureback
Marshal.StructureToPtr(v,media.formatPtr,false);
//Setthenewformat
hr=videoStreamConfig.SetFormat(media);
DsError.ThrowExceptionForHR(hr);
}
finally
{
DsUtils.FreeAMMediaType(media);
media=null;
}
}
///<summary>Shutdowncapture</summary>
privatevoidCloseInterfaces()
{
inthr;
try
{
if(m_FilterGraph!=null)
{
IMediaControlmediaCtrl=m_FilterGraphasIMediaControl;
//Stopthegraph
hr=mediaCtrl.Stop();
}
}
catch(Exceptionex)
{
Debug.WriteLine(ex);
}
if(m_FilterGraph!=null)
{
Marshal.ReleaseComObject(m_FilterGraph);
m_FilterGraph=null;
}
if(m_VidControl!=null)
{
Marshal.ReleaseComObject(m_VidControl);
m_VidControl=null;
}
if(m_pinStill!=null)
{
Marshal.ReleaseComObject(m_pinStill);
m_pinStill=null;
}
}
///<summary>samplecallback,NOTUSED.</summary>
intISampleGrabberCB.SampleCB(doubleSampleTime,IMediaSamplepSample)
{
Marshal.ReleaseComObject(pSample);
return0;
}
///<summary>buffercallback,COULDBEFROMFOREIGNTHREAD.</summary>
intISampleGrabberCB.BufferCB(doubleSampleTime,IntPtrpBuffer,intBufferLen)
{
//NotethatwedependononlybeingcalledoncepercalltoClick.Otherwise
//asecondcallcanoverwritethepreviousimage.
Debug.Assert(BufferLen==Math.Abs(m_stride)*m_videoHeight,"Incorrectbufferlength");
if(m_WantOne)
{
m_WantOne=false;
Debug.Assert(m_ipBuffer!=IntPtr.Zero,"Unitializedbuffer");
//Savethebuffer
CopyMemory(m_ipBuffer,pBuffer,BufferLen);
//Pictureisready.
m_PictureReady.Set();
}
return0;
}
}
}
Form1.cs
![ContractedBlock.gif](https://i-blog.csdnimg.cn/blog_migrate/0be121fa5b8988fbabbbc526af3b0fc0.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->/****************************************************************************
WhiletheunderlyinglibrariesarecoveredbyLGPL,thissampleisreleased
aspublicdomain.Itisdistributedinthehopethatitwillbeuseful,but
WITHOUTANYWARRANTY;withouteventheimpliedwarrantyofMERCHANTABILITY
orFITNESSFORAPARTICULARPURPOSE.
*****************************************************************************/
usingSystem;
usingSystem.Drawing;
usingSystem.Collections;
usingSystem.ComponentModel;
usingSystem.Windows.Forms;
usingSystem.Runtime.InteropServices;
usingSystem.Drawing.Imaging;
namespaceSnapShot
{
///<summary>
///SummarydescriptionforForm1.
///</summary>
publicclassForm1:System.Windows.Forms.Form
{
privateSystem.Windows.Forms.Buttonbutton1;
privateSystem.Windows.Forms.PictureBoxpictureBox1;
///<summary>
///Requireddesignervariable.
///</summary>
privateSystem.ComponentModel.Containercomponents=null;
privateSystem.Windows.Forms.PictureBoxpictureBox2;
privateCapturecam;
publicForm1()
{
//
//RequiredforWindowsFormDesignersupport
//
InitializeComponent();
constintVIDEODEVICE=0;//zerobasedindexofvideocapturedevicetouse
constintVIDEOWIDTH=640;//Dependsonvideodevicecaps
constintVIDEOHEIGHT=480;//Dependsonvideodevicecaps
constintVIDEOBITSPERPIXEL=24;//BitsPerPixelvaluesdeterminedbydevice
cam=newCapture(VIDEODEVICE,VIDEOWIDTH,VIDEOHEIGHT,VIDEOBITSPERPIXEL,pictureBox2);
}
///<summary>
///Cleanupanyresourcesbeingused.
///</summary>
protectedoverridevoidDispose(booldisposing)
{
if(disposing)
{
if(components!=null)
{
components.Dispose();
}
}
base.Dispose(disposing);
if(m_ip!=IntPtr.Zero)
{
Marshal.FreeCoTaskMem(m_ip);
m_ip=IntPtr.Zero;
}
}
#regionWindowsFormDesignergeneratedcode
///<summary>
///RequiredmethodforDesignersupport-donotmodify
///thecontentsofthismethodwiththecodeeditor.
///</summary>
privatevoidInitializeComponent()
{
this.button1=newSystem.Windows.Forms.Button();
this.pictureBox1=newSystem.Windows.Forms.PictureBox();
this.pictureBox2=newSystem.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit();
this.SuspendLayout();
//
//button1
//
this