1 using DirectShowLib;
2 using System;
3 using System.Collections;
4 using System.Windows.Forms;
5
6 namespace CaptureTest
7 {
8 public partial class Form1 : Form
9 {
10 private IBaseFilter theVideoDevice;
11 private IBaseFilter baseGrabFlt ;
12 private int videoHeight;
13 private int videoWidth;
14 private int videoStride;
15 private int WM_GRAPHNOTIFY;
16 private ICaptureGraphBuilder2 m_captureGraphBuilder;
17 private IAMVideoControl m_VidControl;
18 private IVideoWindow m_videoWindow;
19 private IMediaControl m_mediaControl;
20 private IGraphBuilder m_graphBuilder;
21 private IMediaEventEx m_mediaEventEx;
22 private IntPtr hwnVideoWindowOwner;
23 private IntPtr hwnPropertyPageOwner;
24 private bool m_IsPreview;
25
26 public Form1()
27 {
28 InitializeComponent();
29 }
30
31 //1、获取视频采集设备IBaseFilter接口对象的方法
32
33 //获取所有视频设备名称
34 public ArrayList GetVideoInputDevice()
35 { return GetDeviceCollection(FilterCategory.VideoInputDevice); }
36 private ArrayList GetDeviceCollection(Guid DeviceType)
37 {
38 ArrayList returnString = new ArrayList();
39 foreach (DsDevice ds in DsDevice.GetDevicesOfCat(DeviceType))
40 {
41 returnString.Add(ds.Name);
42 }
43 return returnString;
44 }
45
46 //通过获取到的视频设备名称设置采集设备的IBaseFilter对象
47 public bool SetVideoInputDevice(string VideoInputDeviceName)
48 { //创建视频输入设备接口
49 theVideoDevice = CreateFilter(FilterCategory.VideoInputDevice, VideoInputDeviceName);
50 return true;
51 }
52 //通过过滤器类型和过滤器名称获取IBaseFilter接口
53 private IBaseFilter CreateFilter(Guid category, string friendlyname)
54 {
55 object source = null;
56 Guid iid = typeof(IBaseFilter).GUID;
57 foreach (DsDevice device in DsDevice.GetDevicesOfCat(category))
58 {
59 if (device.Name.CompareTo(friendlyname) == 0)
60 {
61 device.Mon.BindToObject(null, null, ref iid, out source);
62 break;
63 }
64 }
65
66 return (IBaseFilter)source;
67 }
68
69 //2、初始化基本的接口对象
70
71 private void InitInterfaces()
72 {
73 int hr = 0;
74
75 // 获取IGraphBuilder接口对象
76 this.m_graphBuilder = (IGraphBuilder)new FilterGraph();
77 //获取ICaptureGraphBuilder2接口对象
78 this.m_captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
79 //获取m_graphBuilder 接口对象的IMediaControl对象
80 this.m_mediaControl = (IMediaControl)this.m_graphBuilder;
81 //获取m_graphBuilder 接口对象的IVideoWindow对象
82 this.m_videoWindow = (IVideoWindow)this.m_graphBuilder;
83 //获取m_graphBuilder 接口对象的IMediaEventEx对象
84 this.m_mediaEventEx = (IMediaEventEx)this.m_graphBuilder;
85 //设置ICaptureGraphBuilder2的IGraphBuilder接口对象为当前对象
86 hr = this.m_captureGraphBuilder.SetFiltergraph(this.m_graphBuilder);
87 DsError.ThrowExceptionForHR(hr);
88 //注册事件到应用程序的窗体上
89 hr = this.m_mediaEventEx.SetNotifyWindow(this.hwnPropertyPageOwner, WM_GRAPHNOTIFY, IntPtr.Zero);
90 DsError.ThrowExceptionForHR(hr);
91 }
92
93 //3、开始视频预览
94 public void VideoPreview()
95 {
96 try
97 {
98
99 int hr = 0;
100 hr = this.m_graphBuilder.AddFilter(theVideoDevice, "Video Capture");
101 DsError.ThrowExceptionForHR(hr);
102
103 // 通过theVideoDevice(IBaseFilter)视频接口对象的Preview Pin预览
104 hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, theVideoDevice, null, null);
105 DsError.ThrowExceptionForHR(hr);
106 var
107
108 //插入SampleGrabber
109 m_pinStill = DsFindPin.ByCategory(theVideoDevice, PinCategory.Still, 0);
110 if (m_pinStill == null)
111 {
112 m_pinStill = DsFindPin.ByCategory(theVideoDevice, PinCategory.Capture, 0);
113 }
114
115
116 // 获取theVideoDevice的IAMVideoControl对象,对于具有Still Pin的对象可以获到,采集设备不具备Still Pin,那么该对象将为Null
117 m_VidControl = theVideoDevice as IAMVideoControl;
118
119 // 设置采集视频参数
120 if (this.videoHeight + this.videoWidth + this.videoStride > 0)
121 {
122 SetConfigParms(m_pinStill, this.videoWidth, this.videoHeight, 24);
123 }
124
125 var
126
127 //开始拍照功能所需的接口对象
128 // 获得SampleGrabber对象接口
129 sampGrabber = new SampleGrabber() as ISampleGrabber;
130
131 // 配置sample grabber
132 baseGrabFlt = sampGrabber as IBaseFilter;
133 ConfigureSampleGrabber(sampGrabber);
134
135 // 将sample grabber添加到图形过滤器中
136 hr = m_graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber");
137 DsError.ThrowExceptionForHR(hr);
138
139 //通过渲染将采集设备的相关输出Pin与sample grabber对象的输入Pin连接起来
140 //如果采集设备提供Still Pin,则通过Still Pin连接,否则直接使用Capture Pin连接
141 if (m_VidControl != null)
142 {
143 hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Still, MediaType.Video, theVideoDevice, null, baseGrabFlt);
144 DsError.ThrowExceptionForHR(hr);
145
146 }
147 else
148 {
149 hr = this.m_captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, theVideoDevice, null, baseGrabFlt);
150 DsError.ThrowExceptionForHR(hr);
151 }
152 //设置抓取图片相关参数
153 SaveSizeInfo(sampGrabber);
154 //拍照功能所需的接口对象添加结束
155
156
157 // 开始将视频窗口绑定到主窗体上
158 hr = this.m_videoWindow.put_Owner(this.hwnVideoWindowOwner);
159 DsError.ThrowExceptionForHR(hr);
160
161 hr = this.m_videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
162 DsError.ThrowExceptionForHR(hr);
163
164 if (this.m_videoWindow != null)
165 {
166 this.m_videoWindow.SetWindowPosition(0, 0, this.videoWidth, this.videoHeight);
167 }
168
169
170 hr = this.m_videoWindow.put_Visible(OABool.True);
171 DsError.ThrowExceptionForHR(hr);
172
173 // 开始预览采集设备采集到的视频
174 hr = this.m_mediaControl.Run();
175
176 DsError.ThrowExceptionForHR(hr);
177 m_IsPreview = true;
178 }
179 catch
180 {
181 m_IsPreview = false;
182 throw new Exception("VideoPreview函数出现异常,视频预览失败!");
183
184 }
185 }
186
187 private void SaveSizeInfo(ISampleGrabber sampGrabber)
188 {
189 throw new NotImplementedException();
190 }
191
192 private void SetConfigParms(object m_pinStill, int videoWidth, int videoHeight, int v)
193 {
194 throw new NotImplementedException();
195 }
196
197 private void ConfigureSampleGrabber(ISampleGrabber sampGrabber)
198 {
199 throw new NotImplementedException();
200 }
201 }
202 }