`
touchinsert
  • 浏览: 1280491 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

[引]C# WinForm DirectShow视频采集及图片抓取实例DxSnap

 
阅读更多

DirectShowSamples-2007-July\Samples\Capture\DxSnap

Capture.cs

Capture.cs
<!--<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

Form1.cs
<!--<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<span st
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics