📄 mainform.cs
字号:
if( ! GetInterfaces() )
return false;
if( ! SetupGraph() )
return false;
if( ! SetupVideoWindow() )
return false;
#if DEBUG
DsROT.AddGraphToRot( graphBuilder, out rotCookie ); // graphBuilder capGraph
#endif
hr = mediaCtrl.Run();
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
bool hasTuner = DsUtils.ShowTunerPinDialog( capGraph, capFilter, this.Handle );
toolBarBtnTune.Enabled = hasTuner;
return true;
}
catch( Exception ee )
{
MessageBox.Show( this, "Could not start video stream\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
return false;
}
}
/// <summary> make the video preview window to show in videoPanel. </summary>
bool SetupVideoWindow()
{
int hr;
try {
// Set the video window to be a child of the main window
hr = videoWin.put_Owner( videoPanel.Handle );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
// Set video window style
hr = videoWin.put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
// Use helper function to position video window in client rect of owner window
ResizeVideoWindow();
// Make the video window visible, now that it is properly positioned
hr = videoWin.put_Visible( DsHlp.OATRUE );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
hr = mediaEvt.SetNotifyWindow( this.Handle, WM_GRAPHNOTIFY, IntPtr.Zero );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
return true;
}
catch( Exception ee )
{
MessageBox.Show( this, "Could not setup video window\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
return false;
}
}
/// <summary> build the capture graph for grabber. </summary>
bool SetupGraph()
{
int hr;
try {
hr = capGraph.SetFiltergraph( graphBuilder );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
hr = graphBuilder.AddFilter( capFilter, "Ds.NET Video Capture Device" );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
DsUtils.ShowCapPinDialog( capGraph, capFilter, this.Handle );
AMMediaType media = new AMMediaType();
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB24;
media.formatType = FormatType.VideoInfo; // ???
hr = sampGrabber.SetMediaType( media );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
hr = graphBuilder.AddFilter( baseGrabFlt, "Ds.NET Grabber" );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
Guid cat = PinCategory.Preview;
Guid med = MediaType.Video;
hr = capGraph.RenderStream( ref cat, ref med, capFilter, null, null ); // baseGrabFlt
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
cat = PinCategory.Capture;
med = MediaType.Video;
hr = capGraph.RenderStream( ref cat, ref med, capFilter, null, baseGrabFlt ); // baseGrabFlt
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
media = new AMMediaType();
hr = sampGrabber.GetConnectedMediaType( media );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
if( (media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero) )
throw new NotSupportedException( "Unknown Grabber Media Format" );
videoInfoHeader = (VideoInfoHeader) Marshal.PtrToStructure( media.formatPtr, typeof(VideoInfoHeader) );
Marshal.FreeCoTaskMem( media.formatPtr ); media.formatPtr = IntPtr.Zero;
hr = sampGrabber.SetBufferSamples( false );
if( hr == 0 )
hr = sampGrabber.SetOneShot( false );
if( hr == 0 )
hr = sampGrabber.SetCallback( null, 0 );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
return true;
}
catch( Exception)
{
return false;
}
}
/// <summary> create the used COM components and get the interfaces. </summary>
bool GetInterfaces()
{
Type comType = null;
object comObj = null;
try {
comType = Type.GetTypeFromCLSID( Clsid.FilterGraph );
if( comType == null )
throw new NotImplementedException( @"DirectShow FilterGraph not installed/registered!" );
comObj = Activator.CreateInstance( comType );
graphBuilder = (IGraphBuilder) comObj; comObj = null;
Guid clsid = Clsid.CaptureGraphBuilder2;
Guid riid = typeof(ICaptureGraphBuilder2).GUID;
comObj = DsBugWO.CreateDsInstance( ref clsid, ref riid );
capGraph = (ICaptureGraphBuilder2) comObj; comObj = null;
comType = Type.GetTypeFromCLSID( Clsid.SampleGrabber );
if( comType == null )
throw new NotImplementedException( @"DirectShow SampleGrabber not installed/registered!" );
comObj = Activator.CreateInstance( comType );
sampGrabber = (ISampleGrabber) comObj; comObj = null;
mediaCtrl = (IMediaControl) graphBuilder;
videoWin = (IVideoWindow) graphBuilder;
mediaEvt = (IMediaEventEx) graphBuilder;
baseGrabFlt = (IBaseFilter) sampGrabber;
return true;
}
catch( Exception ee )
{
MessageBox.Show( this, "Could not get interfaces\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
return false;
}
finally
{
if( comObj != null )
Marshal.ReleaseComObject( comObj ); comObj = null;
}
}
/// <summary> create the user selected capture device. </summary>
bool CreateCaptureDevice( UCOMIMoniker mon )
{
object capObj = null;
try {
Guid gbf = typeof( IBaseFilter ).GUID;
mon.BindToObject( null, null, ref gbf, out capObj );
capFilter = (IBaseFilter) capObj; capObj = null;
return true;
}
catch( Exception ee )
{
MessageBox.Show( this, "Could not create capture device\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop );
return false;
}
finally
{
if( capObj != null )
Marshal.ReleaseComObject( capObj ); capObj = null;
}
}
/// <summary> do cleanup and release DirectShow. </summary>
void CloseInterfaces()
{
int hr;
try {
#if DEBUG
if( rotCookie != 0 )
DsROT.RemoveGraphFromRot( ref rotCookie );
#endif
if( mediaCtrl != null )
{
hr = mediaCtrl.Stop();
mediaCtrl = null;
}
if( mediaEvt != null )
{
hr = mediaEvt.SetNotifyWindow( IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero );
mediaEvt = null;
}
if( videoWin != null )
{
hr = videoWin.put_Visible( DsHlp.OAFALSE );
hr = videoWin.put_Owner( IntPtr.Zero );
videoWin = null;
}
baseGrabFlt = null;
if( sampGrabber != null )
Marshal.ReleaseComObject( sampGrabber ); sampGrabber = null;
if( capGraph != null )
Marshal.ReleaseComObject( capGraph ); capGraph = null;
if( graphBuilder != null )
Marshal.ReleaseComObject( graphBuilder ); graphBuilder = null;
if( capFilter != null )
Marshal.ReleaseComObject( capFilter ); capFilter = null;
if( capDevices != null )
{
foreach( DsDevice d in capDevices )
d.Dispose();
capDevices = null;
}
}
catch( Exception )
{}
}
/// <summary> resize preview video window to fill client area. </summary>
void ResizeVideoWindow()
{
if( videoWin != null )
{
Rectangle rc = videoPanel.ClientRectangle;
videoWin.SetWindowPosition( 0, 0, rc.Right, rc.Bottom );
}
}
/// <summary> override window fn to handle graph events. </summary>
protected override void WndProc( ref Message m )
{
if( m.Msg == WM_GRAPHNOTIFY )
{
if( mediaEvt != null )
OnGraphNotify();
return;
}
base.WndProc( ref m );
}
/// <summary> graph event (WM_GRAPHNOTIFY) handler. </summary>
void OnGraphNotify()
{
DsEvCode code;
int p1, p2, hr = 0;
do
{
hr = mediaEvt.GetEvent( out code, out p1, out p2, 0 );
if( hr < 0 )
break;
hr = mediaEvt.FreeEventParams( code, p1, p2 );
}
while( hr == 0 );
}
/// <summary> sample callback, NOT USED. </summary>
int ISampleGrabberCB.SampleCB( double SampleTime, IMediaSample pSample )
{
Trace.WriteLine( "!!CB: ISampleGrabberCB.SampleCB" );
return 0;
}
/// <summary> buffer callback, COULD BE FROM FOREIGN THREAD. </summary>
int ISampleGrabberCB.BufferCB( double SampleTime, IntPtr pBuffer, int BufferLen )
{
if( captured || (savedArray == null) )
{
Trace.WriteLine( "!!CB: ISampleGrabberCB.BufferCB" );
return 0;
}
captured = true;
bufferedSize = BufferLen;
Trace.WriteLine( "!!CB: ISampleGrabberCB.BufferCB !GRAB! size = " + BufferLen.ToString() );
if( (pBuffer != IntPtr.Zero) && (BufferLen > 1000) && (BufferLen <= savedArray.Length) )
Marshal.Copy( pBuffer, savedArray, 0, BufferLen );
else
Trace.WriteLine( " !!!GRAB! failed " );
this.BeginInvoke( new CaptureDone( this.OnCaptureDone ) );
return 0;
}
/// <summary> flag to detect first Form appearance </summary>
private bool firstActive;
/// <summary> base filter of the actually used video devices. </summary>
private IBaseFilter capFilter;
/// <summary> graph builder interface. </summary>
private IGraphBuilder graphBuilder;
/// <summary> capture graph builder interface. </summary>
private ICaptureGraphBuilder2 capGraph;
private ISampleGrabber sampGrabber;
/// <summary> control interface. </summary>
private IMediaControl mediaCtrl;
/// <summary> event interface. </summary>
private IMediaEventEx mediaEvt;
/// <summary> video window interface. </summary>
private IVideoWindow videoWin;
/// <summary> grabber filter interface. </summary>
private IBaseFilter baseGrabFlt;
/// <summary> structure describing the bitmap to grab. </summary>
private VideoInfoHeader videoInfoHeader;
private bool captured = true;
private int bufferedSize;
/// <summary> buffer for bitmap data. </summary>
private byte[] savedArray;
/// <summary> list of installed video devices. </summary>
private ArrayList capDevices;
private const int WM_GRAPHNOTIFY = 0x00008001; // message from graph
private const int WS_CHILD = 0x40000000; // attributes for video window
private const int WS_CLIPCHILDREN = 0x02000000;
private const int WS_CLIPSIBLINGS = 0x04000000;
/// <summary> event when callback has finished (ISampleGrabberCB.BufferCB). </summary>
private delegate void CaptureDone();
#if DEBUG
private int rotCookie = 0;
private void MainForm_Load(object sender, System.EventArgs e)
{
}
private void menuItem1_Click(object sender, System.EventArgs e)
{
int hr;
int size = videoInfoHeader.BmiHeader.ImageSize;
savedArray = new byte[ size + 64000 ];
captured = false;
hr = sampGrabber.SetCallback( this, 1 );
timer1.Enabled = true;
menuItem1.Enabled = false;
menuItem2.Enabled = true;
textBox1.ReadOnly = true;
label2.Text = "Sending ...";
}
private void timer1_Tick(object sender, System.EventArgs e)
{
try
{
int hr;
int size = videoInfoHeader.BmiHeader.ImageSize;
savedArray = new byte[ size + 64000 ];
captured = false;
hr = sampGrabber.SetCallback( this, 1 );
MemoryStream ms = new MemoryStream();// Store it in Binary Array as Stream
pictureBox.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] arrImage = ms.GetBuffer();
ms.Close();
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(textBox1.Text), 5020);
server.SendTo(arrImage, iep);
server.Close();
}
catch (Exception){}
}
private void menuItem2_Click(object sender, System.EventArgs e)
{
timer1.Enabled = false;
menuItem2.Enabled = false;
menuItem1.Enabled = true;
textBox1.ReadOnly = false;
label2.Text = "Paused";
}
private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
if ((e.KeyChar <48||e.KeyChar >57)&& (e.KeyChar !=8) && (e.KeyChar !=46)) e.Handled = true;
}
private void menuItem4_Click(object sender, System.EventArgs e)
{
this.Show ();
}
private void menuItem3_Click(object sender, System.EventArgs e)
{
this.Hide ();
}
private void notifyIcon1_DoubleClick(object sender, System.EventArgs e)
{
this.Show ();
}
#endif
}
internal enum PlayState
{
Init, Stopped, Paused, Running
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -