Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2485 | - | 1 | //***************************************************************************************** |
2 | // File: WebCamLib.h |
||
3 | // Project: WebcamLib |
||
4 | // Author(s): John Conwell |
||
5 | // Gary Caldwell |
||
6 | // |
||
7 | // Declares the webcam DirectShow wrapper used by TouchlessLib |
||
8 | //***************************************************************************************** |
||
9 | |||
10 | #pragma once |
||
11 | |||
12 | using namespace System; |
||
13 | using namespace System::Collections::Generic; |
||
14 | using namespace System::Runtime::InteropServices; |
||
15 | |||
16 | namespace WebCamLib |
||
17 | { |
||
18 | /// <summary> |
||
19 | /// Store webcam name, index |
||
20 | /// </summary> |
||
21 | public ref class CameraInfo |
||
22 | { |
||
23 | public: |
||
24 | CameraInfo( int index, String^ name ); |
||
25 | |||
26 | property int Index |
||
27 | { |
||
28 | int get(); |
||
29 | private: void set( int value ); |
||
30 | } |
||
31 | |||
32 | property String^ Name |
||
33 | { |
||
34 | String^ get(); |
||
35 | private: void set( String^ value ); |
||
36 | } |
||
37 | |||
38 | private: |
||
39 | int index; |
||
40 | String^ name; |
||
41 | }; |
||
42 | |||
43 | public enum class PropertyTypeMask : int |
||
44 | { |
||
45 | CameraControlPropertyMask = 0x01000, |
||
46 | VideoProcAmpPropertyMask = 0x02000, |
||
47 | }; |
||
48 | |||
49 | // Source: https://msdn.microsoft.com/en-us/library/aa925325.aspx |
||
50 | public enum class CameraControlProperty : int |
||
51 | { |
||
52 | Pan_degrees, |
||
53 | Tilt_degrees, |
||
54 | Roll_degrees, |
||
55 | Zoom_mm, |
||
56 | Exposure_lgSec, |
||
57 | Iris_10f, |
||
58 | FocalLength_mm, |
||
59 | Flash, |
||
60 | }; |
||
61 | |||
62 | // Source: https://msdn.microsoft.com/en-us/library/aa920611.aspx |
||
63 | public enum class VideoProcAmpProperty : int |
||
64 | { |
||
65 | Brightness, |
||
66 | Contrast, |
||
67 | Hue, |
||
68 | Saturation, |
||
69 | Sharpness, |
||
70 | Gamma, |
||
71 | ColorEnable, |
||
72 | WhiteBalance, |
||
73 | BacklightCompensation, |
||
74 | Gain, |
||
75 | }; |
||
76 | |||
77 | public enum class CameraProperty : int |
||
78 | { |
||
79 | Pan_degrees = WebCamLib::CameraControlProperty::Pan_degrees | PropertyTypeMask::CameraControlPropertyMask, |
||
80 | Tilt_degrees = WebCamLib::CameraControlProperty::Tilt_degrees | PropertyTypeMask::CameraControlPropertyMask, |
||
81 | Roll_degrees = WebCamLib::CameraControlProperty::Roll_degrees | PropertyTypeMask::CameraControlPropertyMask, |
||
82 | Zoom_mm = WebCamLib::CameraControlProperty::Zoom_mm | PropertyTypeMask::CameraControlPropertyMask, |
||
83 | Exposure_lgSec = WebCamLib::CameraControlProperty::Exposure_lgSec | PropertyTypeMask::CameraControlPropertyMask, |
||
84 | Iris_10f = WebCamLib::CameraControlProperty::Iris_10f | PropertyTypeMask::CameraControlPropertyMask, |
||
85 | FocalLength_mm = WebCamLib::CameraControlProperty::FocalLength_mm | PropertyTypeMask::CameraControlPropertyMask, |
||
86 | Flash = WebCamLib::CameraControlProperty::Flash | PropertyTypeMask::CameraControlPropertyMask, |
||
87 | Brightness = WebCamLib::VideoProcAmpProperty::Brightness | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
88 | Contrast = WebCamLib::VideoProcAmpProperty::Contrast | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
89 | Hue = WebCamLib::VideoProcAmpProperty::Hue | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
90 | Saturation = WebCamLib::VideoProcAmpProperty::Saturation | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
91 | Sharpness = WebCamLib::VideoProcAmpProperty::Sharpness | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
92 | Gamma = WebCamLib::VideoProcAmpProperty::Gamma | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
93 | ColorEnable = WebCamLib::VideoProcAmpProperty::ColorEnable | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
94 | WhiteBalance = WebCamLib::VideoProcAmpProperty::WhiteBalance | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
95 | BacklightCompensation = WebCamLib::VideoProcAmpProperty::BacklightCompensation | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
96 | Gain = WebCamLib::VideoProcAmpProperty::Gain | PropertyTypeMask::VideoProcAmpPropertyMask, |
||
97 | }; |
||
98 | |||
99 | public ref class CameraPropertyCapabilities |
||
100 | { |
||
101 | public: |
||
102 | CameraPropertyCapabilities( int cameraIndex, CameraProperty prop, bool isGetSupported, bool isSetSupported, bool isGetRangeSupported ); |
||
103 | |||
104 | property int CameraIndex |
||
105 | { |
||
106 | int get(); |
||
107 | private: void set( int cameraIndex ); |
||
108 | } |
||
109 | |||
110 | property CameraProperty Property |
||
111 | { |
||
112 | CameraProperty get(); |
||
113 | private: void set( CameraProperty value ); |
||
114 | } |
||
115 | |||
116 | property bool IsGetSupported |
||
117 | { |
||
118 | bool get(); |
||
119 | private: void set( bool value ); |
||
120 | } |
||
121 | |||
122 | property bool IsSetSupported |
||
123 | { |
||
124 | bool get(); |
||
125 | private: void set( bool value ); |
||
126 | } |
||
127 | |||
128 | property bool IsGetRangeSupported |
||
129 | { |
||
130 | bool get(); |
||
131 | private: void set( bool value ); |
||
132 | } |
||
133 | |||
134 | property bool IsSupported |
||
135 | { |
||
136 | bool get(); |
||
137 | } |
||
138 | |||
139 | property bool IsFullySupported |
||
140 | { |
||
141 | bool get(); |
||
142 | } |
||
143 | |||
144 | private: |
||
145 | int cameraIndex; |
||
146 | CameraProperty prop; |
||
147 | bool isGetSupported, isSetSupported, isGetRangeSupported; |
||
148 | }; |
||
149 | |||
150 | /// <summary> |
||
151 | /// DirectShow wrapper around a web cam, used for image capture |
||
152 | /// </summary> |
||
153 | public ref class CameraMethods |
||
154 | { |
||
155 | public: |
||
156 | /// <summary> |
||
157 | /// Initializes information about all web cams connected to machine |
||
158 | /// </summary> |
||
159 | CameraMethods(); |
||
160 | |||
161 | /// <summary> |
||
162 | /// Delegate used by DirectShow to pass back captured images from webcam |
||
163 | /// </summary> |
||
164 | delegate void CaptureCallbackDelegate( |
||
165 | int dwSize, |
||
166 | [MarshalAsAttribute(UnmanagedType::LPArray, ArraySubType = UnmanagedType::I1, SizeParamIndex = 0)] array<System::Byte>^ abData); |
||
167 | |||
168 | /// <summary> |
||
169 | /// Event callback to capture images from webcam |
||
170 | /// </summary> |
||
171 | event CaptureCallbackDelegate^ OnImageCapture; |
||
172 | |||
173 | /// <summary> |
||
174 | /// Retrieve information about a specific camera |
||
175 | /// Use the count property to determine valid indicies to pass in |
||
176 | /// </summary> |
||
177 | CameraInfo^ GetCameraInfo(int camIndex); |
||
178 | |||
179 | /// <summary> |
||
180 | /// Start the camera associated with the input handle |
||
181 | /// </summary> |
||
182 | bool StartCamera(int camIndex, interior_ptr<int> width, interior_ptr<int> height, interior_ptr<int> bpp); |
||
183 | |||
184 | /// <summary> |
||
185 | /// Start the camera associated with the input handle |
||
186 | /// </summary> |
||
187 | void StartCamera(int camIndex, interior_ptr<int> width, interior_ptr<int> height, interior_ptr<int> bpp, interior_ptr<bool> successful); |
||
188 | |||
189 | #pragma region Camera Property Support |
||
190 | void IsPropertySupported( CameraProperty prop, interior_ptr<bool> result ); |
||
191 | |||
192 | bool IsPropertySupported( CameraProperty prop ); |
||
193 | |||
194 | void GetProperty( CameraProperty prop, bool isValue, interior_ptr<long> value, interior_ptr<bool> bAuto, interior_ptr<bool> successful ); |
||
195 | |||
196 | bool GetProperty( CameraProperty prop, bool isValue, interior_ptr<long> value, interior_ptr<bool> bAuto ); |
||
197 | |||
198 | void GetProperty_value( CameraProperty prop, interior_ptr<long> value, interior_ptr<bool> bAuto, interior_ptr<bool> successful ); |
||
199 | |||
200 | bool GetProperty_value( CameraProperty prop, interior_ptr<long> value, interior_ptr<bool> bAuto ); |
||
201 | |||
202 | void GetProperty_percentage( CameraProperty prop, interior_ptr<long> percentage, interior_ptr<bool> bAuto, interior_ptr<bool> successful); |
||
203 | |||
204 | bool GetProperty_percentage( CameraProperty prop, interior_ptr<long> percentage, interior_ptr<bool> bAuto ); |
||
205 | |||
206 | void SetProperty( CameraProperty prop, bool isValue, long value, bool bAuto, interior_ptr<bool> successful ); |
||
207 | |||
208 | bool SetProperty( CameraProperty prop, bool isValue, long value, bool bAuto ); |
||
209 | |||
210 | void SetProperty_value( CameraProperty prop, long value, bool bAuto, interior_ptr<bool> successful ); |
||
211 | |||
212 | bool SetProperty_value( CameraProperty prop, long value, bool bAuto ); |
||
213 | |||
214 | void SetProperty_value( CameraProperty prop, long value, bool bAuto, bool throwValidationError, interior_ptr<bool> successful ); |
||
215 | |||
216 | bool SetProperty_value( CameraProperty prop, long value, bool bAuto, bool throwValidationError ); |
||
217 | |||
218 | void SetProperty_percentage( CameraProperty prop, long percentage, bool bAuto, interior_ptr<bool> successful ); |
||
219 | |||
220 | bool SetProperty_percentage( CameraProperty prop, long percentage, bool bAuto ); |
||
221 | |||
222 | void PropertyHasRange( CameraProperty prop, interior_ptr<bool> successful ); |
||
223 | |||
224 | bool PropertyHasRange( CameraProperty prop ); |
||
225 | |||
226 | void GetPropertyRange( CameraProperty prop, interior_ptr<long> min, interior_ptr<long> max, interior_ptr<long> steppingDelta, interior_ptr<long> defaults, interior_ptr<bool> bAuto, interior_ptr<bool> successful ); |
||
227 | |||
228 | bool GetPropertyRange( CameraProperty prop, interior_ptr<long> min, interior_ptr<long> max, interior_ptr<long> steppingDelta, interior_ptr<long> defaults, interior_ptr<bool> bAuto ); |
||
229 | |||
230 | void ValidatePropertyValue( CameraProperty prop, long value, interior_ptr<bool> successful ); |
||
231 | |||
232 | bool ValidatePropertyValue( CameraProperty prop, long value ); |
||
233 | |||
234 | CameraPropertyCapabilities^ GetPropertyCapability( CameraProperty prop ); |
||
235 | |||
236 | property IDictionary<CameraProperty, CameraPropertyCapabilities^> ^ PropertyCapabilities |
||
237 | { |
||
238 | IDictionary<CameraProperty, CameraPropertyCapabilities^> ^ get(); |
||
239 | } |
||
240 | #pragma endregion |
||
241 | |||
242 | void GetCaptureSizes(int index, IList<Tuple<int,int,int>^> ^ sizes); |
||
243 | |||
244 | property IList<Tuple<int,int,int>^> ^ CaptureSizes |
||
245 | { |
||
246 | IList<Tuple<int,int,int>^> ^ get(); |
||
247 | } |
||
248 | |||
249 | /// <summary> |
||
250 | /// Stops the currently running camera and cleans up any global resources |
||
251 | /// </summary> |
||
252 | void Cleanup(); |
||
253 | |||
254 | /// <summary> |
||
255 | /// Stops the currently running camera |
||
256 | /// </summary> |
||
257 | void StopCamera(); |
||
258 | |||
259 | /// <summary> |
||
260 | /// Show the properties dialog for the specified webcam |
||
261 | /// </summary> |
||
262 | void DisplayCameraPropertiesDialog(int camIndex); |
||
263 | |||
264 | /// <summary> |
||
265 | /// Count of the number of cameras installed |
||
266 | /// </summary> |
||
267 | property int Count; |
||
268 | |||
269 | /// <summary> |
||
270 | /// Queries which camera is currently running via StartCamera(), -1 for none |
||
271 | /// </summary> |
||
272 | property int ActiveCameraIndex |
||
273 | { |
||
274 | int get() |
||
275 | { |
||
276 | return activeCameraIndex; |
||
277 | } |
||
278 | } |
||
279 | |||
280 | /// <summary> |
||
281 | /// IDisposable |
||
282 | /// </summary> |
||
283 | ~CameraMethods(); |
||
284 | |||
285 | protected: |
||
286 | /// <summary> |
||
287 | /// Finalizer |
||
288 | /// </summary> |
||
289 | !CameraMethods(); |
||
290 | |||
291 | #pragma region Camera Property Support |
||
292 | bool IsCameraControlProperty( CameraProperty prop ); |
||
293 | |||
294 | bool IsVideoProcAmpProperty( CameraProperty prop ); |
||
295 | |||
296 | bool IsPropertyMaskEqual( CameraProperty prop, PropertyTypeMask mask ); |
||
297 | |||
298 | WebCamLib::CameraControlProperty GetCameraControlProperty( CameraProperty prop ); |
||
299 | |||
300 | WebCamLib::VideoProcAmpProperty GetVideoProcAmpProperty( CameraProperty prop ); |
||
301 | |||
302 | bool IsPropertySupported( WebCamLib::CameraControlProperty prop ); |
||
303 | |||
304 | bool IsPropertySupported( WebCamLib::VideoProcAmpProperty prop ); |
||
305 | |||
306 | bool GetPropertyRange( WebCamLib::CameraControlProperty prop, interior_ptr<long> min, interior_ptr<long> max, interior_ptr<long> steppingDelta, interior_ptr<long> defaults, interior_ptr<bool> bAuto ); |
||
307 | |||
308 | bool GetPropertyRange( WebCamLib::VideoProcAmpProperty prop, interior_ptr<long> min, interior_ptr<long> max, interior_ptr<long> steppingDelta, interior_ptr<long> defaults, interior_ptr<bool> bAuto ); |
||
309 | |||
310 | bool GetProperty_value( WebCamLib::CameraControlProperty prop, interior_ptr<long> value, interior_ptr<bool> bAuto ); |
||
311 | |||
312 | bool GetProperty_value( WebCamLib::VideoProcAmpProperty prop, interior_ptr<long> value, interior_ptr<bool> bAuto ); |
||
313 | |||
314 | bool SetProperty_value( WebCamLib::CameraControlProperty prop, long value, bool bAuto ); |
||
315 | |||
316 | bool SetProperty_value( WebCamLib::VideoProcAmpProperty prop, long value, bool bAuto ); |
||
317 | #pragma endregion |
||
318 | |||
319 | private: |
||
320 | /// <summary> |
||
321 | /// Pinned pointer to delegate for CaptureCallbackDelegate |
||
322 | /// Keeps the delegate instance in one spot |
||
323 | /// </summary> |
||
324 | GCHandle ppCaptureCallback; |
||
325 | |||
326 | /// <summary> |
||
327 | /// Initialize information about webcams installed on machine |
||
328 | /// </summary> |
||
329 | void RefreshCameraList(); |
||
330 | |||
331 | /// <summary> |
||
332 | /// Has dispose already happened? |
||
333 | /// </summary> |
||
334 | bool disposed; |
||
335 | |||
336 | /// <summary> |
||
337 | /// Which camera is running? -1 for none |
||
338 | /// </summary> |
||
339 | int activeCameraIndex; |
||
340 | |||
341 | /// <summary> |
||
342 | /// Releases all unmanaged resources |
||
343 | /// </summary> |
||
344 | void CleanupCameraInfo(); |
||
345 | |||
346 | /// <summary> |
||
347 | /// Setup the callback functionality for DirectShow |
||
348 | /// </summary> |
||
349 | HRESULT ConfigureSampleGrabber(IBaseFilter *pIBaseFilter); |
||
350 | |||
351 | HRESULT SetCaptureFormat(IBaseFilter* pCap, int width, int height, int bpp ); |
||
352 | }; |
||
353 | |||
354 | // Forward declarations of callbacks |
||
355 | typedef void (__stdcall *PFN_CaptureCallback)(DWORD dwSize, BYTE* pbData); |
||
356 | PFN_CaptureCallback g_pfnCaptureCallback = NULL; |
||
357 | |||
358 | /// <summary> |
||
359 | /// Lightweight SampleGrabber callback interface |
||
360 | /// </summary> |
||
361 | class SampleGrabberCB : public ISampleGrabberCB |
||
362 | { |
||
363 | public: |
||
364 | SampleGrabberCB() |
||
365 | { |
||
366 | m_nRefCount = 0; |
||
367 | } |
||
368 | |||
369 | virtual HRESULT STDMETHODCALLTYPE SampleCB(double SampleTime, IMediaSample *pSample) |
||
370 | { |
||
371 | return E_FAIL; |
||
372 | } |
||
373 | |||
374 | virtual HRESULT STDMETHODCALLTYPE BufferCB(double SampleTime, BYTE *pBuffer, long BufferLen) |
||
375 | { |
||
376 | if (g_pfnCaptureCallback != NULL) |
||
377 | { |
||
378 | g_pfnCaptureCallback(BufferLen, pBuffer); |
||
379 | } |
||
380 | |||
381 | return S_OK; |
||
382 | } |
||
383 | |||
384 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) |
||
385 | { |
||
386 | return E_FAIL; // Not a very accurate implementation |
||
387 | } |
||
388 | |||
389 | virtual ULONG STDMETHODCALLTYPE AddRef() |
||
390 | { |
||
391 | return ++m_nRefCount; |
||
392 | } |
||
393 | |||
394 | virtual ULONG STDMETHODCALLTYPE Release() |
||
395 | { |
||
396 | int n = --m_nRefCount; |
||
397 | if (n <= 0) |
||
398 | { |
||
399 | delete this; |
||
400 | } |
||
401 | return n; |
||
402 | } |
||
403 | |||
404 | private: |
||
405 | int m_nRefCount; |
||
406 | }; |
||
407 | } |