Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / include / videoInput.h
1 #ifndef _VIDEOINPUT\r
2 #define _VIDEOINPUT\r
3 \r
4 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
5 //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
6 //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
7 //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
8 //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
9 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
10 //THE SOFTWARE.\r
11 \r
12 //////////////////////////////////////////////////////////\r
13 //Written by Theodore Watson - theo.watson@gmail.com    //\r
14 //Do whatever you want with this code but if you find   //\r
15 //a bug or make an improvement I would love to know!    //\r
16 //                                                                                                              //\r
17 //Warning This code is experimental                                     //\r
18 //use at your own risk :)                                                               //\r
19 //////////////////////////////////////////////////////////\r
20 /////////////////////////////////////////////////////////\r
21 /*                     Shoutouts \r
22 \r
23 Thanks to: \r
24                         \r
25                    Dillip Kumar Kara for crossbar code.\r
26                    Zachary Lieberman for getting me into this stuff\r
27                    and for being so generous with time and code.\r
28                    The guys at Potion Design for helping me with VC++\r
29                    Josh Fisher for being a serious C++ nerd :)\r
30                    Golan Levin for helping me debug the strangest \r
31                    and slowest bug in the world!\r
32                    \r
33                    And all the people using this library who send in \r
34                    bugs, suggestions and improvements who keep me working on \r
35                    the next version - yeah thanks a lot ;)\r
36                    \r
37 */\r
38 /////////////////////////////////////////////////////////\r
39 \r
40 \r
41 \r
42 #include <stdlib.h>\r
43 #include <stdio.h>\r
44 #include <math.h>\r
45 #include <string.h>\r
46 #include <wchar.h>\r
47 \r
48 //this is for TryEnterCriticalSection\r
49 #ifndef _WIN32_WINNT\r
50         #   define _WIN32_WINNT 0x400\r
51 #endif\r
52 #include <windows.h>\r
53 \r
54 \r
55 //Example Usage\r
56 /*\r
57         //create a videoInput object\r
58         videoInput VI;\r
59         \r
60         //Prints out a list of available devices and returns num of devices found\r
61         int numDevices = VI.listDevices();      \r
62         \r
63         int device1 = 0;  //this could be any deviceID that shows up in listDevices\r
64         int device2 = 1;  //this could be any deviceID that shows up in listDevices\r
65         \r
66         //if you want to capture at a different frame rate (default is 30) \r
67         //specify it here, you are not guaranteed to get this fps though.\r
68         //VI.setIdealFramerate(dev, 60);        \r
69         \r
70         //setup the first device - there are a number of options:\r
71         \r
72         VI.setupDevice(device1);                                                  //setup the first device with the default settings\r
73         //VI.setupDevice(device1, VI_COMPOSITE);                          //or setup device with specific connection type\r
74         //VI.setupDevice(device1, 320, 240);                              //or setup device with specified video size\r
75         //VI.setupDevice(device1, 320, 240, VI_COMPOSITE);  //or setup device with video size and connection type\r
76 \r
77         //VI.setFormat(device1, VI_NTSC_M);                                     //if your card doesn't remember what format it should be\r
78                                                                                                                 //call this with the appropriate format listed above\r
79                                                                                                                 //NOTE: must be called after setupDevice!\r
80         \r
81         //optionally setup a second (or third, fourth ...) device - same options as above\r
82         VI.setupDevice(device2);                                                  \r
83 \r
84         //As requested width and height can not always be accomodated\r
85         //make sure to check the size once the device is setup\r
86 \r
87         int width       = VI.getWidth(device1);\r
88         int height      = VI.getHeight(device1);\r
89         int size        = VI.getSize(device1);\r
90         \r
91         unsigned char * yourBuffer1 = new unsigned char[size];\r
92         unsigned char * yourBuffer2 = new unsigned char[size];\r
93         \r
94         //to get the data from the device first check if the data is new\r
95         if(VI.isFrameNew(device1)){\r
96                 VI.getPixels(device1, yourBuffer1, false, false);       //fills pixels as a BGR (for openCV) unsigned char array - no flipping\r
97                 VI.getPixels(device1, yourBuffer2, true, true);         //fills pixels as a RGB (for openGL) unsigned char array - flipping!\r
98         }\r
99         \r
100         //same applies to device2 etc\r
101         \r
102         //to get a settings dialog for the device\r
103         VI.showSettingsWindow(device1);\r
104         \r
105         \r
106         //Shut down devices properly\r
107         VI.stopDevice(device1);\r
108         VI.stopDevice(device2);\r
109 */\r
110 \r
111 \r
112 //////////////////////////////////////   VARS AND DEFS   //////////////////////////////////\r
113 \r
114 \r
115 //STUFF YOU CAN CHANGE\r
116 \r
117 //change for verbose debug info\r
118 static bool verbose = true;\r
119 \r
120 //if you need VI to use multi threaded com\r
121 //#define VI_COM_MULTI_THREADED\r
122 \r
123 //STUFF YOU DON'T CHANGE\r
124 \r
125 //videoInput defines\r
126 #define VI_VERSION       0.1995\r
127 #define VI_MAX_CAMERAS  20\r
128 #define VI_NUM_TYPES    18 //DON'T TOUCH\r
129 #define VI_NUM_FORMATS  18 //DON'T TOUCH\r
130 \r
131 //defines for setPhyCon - tuner is not as well supported as composite and s-video \r
132 #define VI_COMPOSITE 0\r
133 #define VI_S_VIDEO   1\r
134 #define VI_TUNER     2\r
135 #define VI_USB       3\r
136 #define VI_1394          4\r
137 \r
138 //defines for formats\r
139 #define VI_NTSC_M       0\r
140 #define VI_PAL_B        1\r
141 #define VI_PAL_D        2\r
142 #define VI_PAL_G        3\r
143 #define VI_PAL_H        4\r
144 #define VI_PAL_I        5\r
145 #define VI_PAL_M        6\r
146 #define VI_PAL_N        7\r
147 #define VI_PAL_NC       8\r
148 #define VI_SECAM_B      9\r
149 #define VI_SECAM_D      10\r
150 #define VI_SECAM_G      11\r
151 #define VI_SECAM_H      12\r
152 #define VI_SECAM_K      13\r
153 #define VI_SECAM_K1     14\r
154 #define VI_SECAM_L      15\r
155 #define VI_NTSC_M_J     16\r
156 #define VI_NTSC_433     17\r
157 \r
158 \r
159 //allows us to directShow classes here with the includes in the cpp\r
160 struct ICaptureGraphBuilder2;\r
161 struct IGraphBuilder;\r
162 struct IBaseFilter;\r
163 struct IAMCrossbar;\r
164 struct IMediaControl;\r
165 struct ISampleGrabber;\r
166 struct IMediaEventEx;\r
167 struct IAMStreamConfig;\r
168 struct _AMMediaType;\r
169 class SampleGrabberCallback;\r
170 typedef _AMMediaType AM_MEDIA_TYPE;\r
171 \r
172 //keeps track of how many instances of VI are being used\r
173 //don't touch\r
174 static int comInitCount = 0;\r
175 \r
176 \r
177 ////////////////////////////////////////   VIDEO DEVICE   ///////////////////////////////////\r
178 \r
179 class videoDevice{\r
180 \r
181         \r
182         public:\r
183                  \r
184                 videoDevice();\r
185                 void setSize(int w, int h);\r
186                 void NukeDownstream(IBaseFilter *pBF);\r
187                 void destroyGraph();\r
188                 ~videoDevice();\r
189                 \r
190                 int videoSize;\r
191                 int width;\r
192                 int height;\r
193                 int tryWidth;\r
194                 int tryHeight;\r
195                 \r
196                 ICaptureGraphBuilder2 *pCaptureGraph;   // Capture graph builder object\r
197                 IGraphBuilder *pGraph;                                  // Graph builder object\r
198             IMediaControl *pControl;                            // Media control object\r
199                 IBaseFilter *pVideoInputFilter;                 // Video Capture filter\r
200                 IBaseFilter *pGrabberF;\r
201                 IBaseFilter * pDestFilter;\r
202                 IAMStreamConfig *streamConf;\r
203                 ISampleGrabber * pGrabber;                      // Grabs frame\r
204                 AM_MEDIA_TYPE * pAmMediaType;\r
205                 \r
206                 IMediaEventEx * pMediaEvent;\r
207                 \r
208                 GUID videoType;\r
209                 long formatType;\r
210                 \r
211                 SampleGrabberCallback * sgCallback;                             \r
212                 \r
213                 bool tryDiffSize;\r
214                 bool useCrossbar;\r
215                 bool readyToCapture;\r
216                 bool sizeSet;\r
217                 bool setupStarted;\r
218                 bool specificFormat;\r
219                 bool autoReconnect;\r
220                 int  nFramesForReconnect;\r
221                 unsigned long nFramesRunning;\r
222                 int  connection;\r
223                 int      storeConn;\r
224                 int  myID;\r
225                 long requestedFrameTime; //ie fps\r
226                 \r
227                 char    nDeviceName[255];\r
228                 WCHAR   wDeviceName[255];\r
229                 \r
230                 unsigned char * pixels;\r
231                 char * pBuffer;\r
232 \r
233 };\r
234 \r
235 \r
236 \r
237 \r
238 //////////////////////////////////////   VIDEO INPUT   /////////////////////////////////////\r
239 \r
240 \r
241 \r
242 class videoInput{\r
243 \r
244         public:\r
245                 videoInput();\r
246                 ~videoInput();\r
247                                 \r
248                 //turns off console messages - default is to print messages\r
249                 static void setVerbose(bool _verbose);\r
250                 \r
251                 //Functions in rough order they should be used.\r
252                 static int listDevices(bool silent = false);\r
253 \r
254                 //needs to be called after listDevices - otherwise returns NULL\r
255                 static char * getDeviceName(int deviceID);\r
256                 \r
257                 //choose to use callback based capture - or single threaded\r
258                 void setUseCallback(bool useCallback);  \r
259                 \r
260                 //call before setupDevice\r
261                 //directshow will try and get the closest possible framerate to what is requested\r
262                 void setIdealFramerate(int deviceID, int idealFramerate);\r
263 \r
264                 //some devices will stop delivering frames after a while - this method gives you the option to try and reconnect\r
265                 //to a device if videoInput detects that a device has stopped delivering frames. \r
266                 //you MUST CALL isFrameNew every app loop for this to have any effect\r
267                 void setAutoReconnectOnFreeze(int deviceNumber, bool doReconnect, int numMissedFramesBeforeReconnect);\r
268                 \r
269                 //Choose one of these four to setup your device\r
270                 bool setupDevice(int deviceID);\r
271                 bool setupDevice(int deviceID, int w, int h);\r
272 \r
273                 //These two are only for capture cards\r
274                 //USB and Firewire cameras souldn't specify connection \r
275                 bool setupDevice(int deviceID, int connection); \r
276                 bool setupDevice(int deviceID, int w, int h, int connection); \r
277                 \r
278                 //If you need to you can set your NTSC/PAL/SECAM\r
279                 //preference here. if it is available it will be used.\r
280                 //see #defines above for available formats - eg VI_NTSC_M or VI_PAL_B\r
281                 //should be called after setupDevice\r
282                 //can be called multiple times\r
283                 bool setFormat(int deviceNumber, int format);   \r
284                                 \r
285                 //Tells you when a new frame has arrived - you should call this if you have specified setAutoReconnectOnFreeze to true\r
286                 bool isFrameNew(int deviceID); \r
287                 \r
288                 bool isDeviceSetup(int deviceID);\r
289                     \r
290                 //Returns the pixels - flipRedAndBlue toggles RGB/BGR flipping - and you can flip the image too\r
291                 unsigned char * getPixels(int deviceID, bool flipRedAndBlue = true, bool flipImage = false);\r
292                 \r
293                 //Or pass in a buffer for getPixels to fill returns true if successful.\r
294                 bool getPixels(int id, unsigned char * pixels, bool flipRedAndBlue = true, bool flipImage = false);\r
295                 \r
296                 //Launches a pop up settings window\r
297                 //For some reason in GLUT you have to call it twice each time. \r
298                 void showSettingsWindow(int deviceID);\r
299                 \r
300                 //Manual control over settings thanks..... \r
301                 //These are experimental for now.\r
302                 bool setVideoSettingFilter(int deviceID, long Property, long lValue, long Flags = NULL, bool useDefaultValue = false);\r
303                 bool setVideoSettingFilterPct(int deviceID, long Property, float pctValue, long Flags = NULL);\r
304                 bool getVideoSettingFilter(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long &currentValue, long &flags, long &defaultValue);\r
305 \r
306                 bool setVideoSettingCamera(int deviceID, long Property, long lValue, long Flags = NULL, bool useDefaultValue = false);\r
307                 bool setVideoSettingCameraPct(int deviceID, long Property, float pctValue, long Flags = NULL);\r
308                 bool getVideoSettingCamera(int deviceID, long Property, long &min, long &max, long &SteppingDelta, long &currentValue, long &flags, long &defaultValue);\r
309 \r
310                 //bool setVideoSettingCam(int deviceID, long Property, long lValue, long Flags = NULL, bool useDefaultValue = false);\r
311 \r
312                 //get width, height and number of pixels\r
313                 int  getWidth(int deviceID);\r
314                 int  getHeight(int deviceID);\r
315                 int  getSize(int deviceID);\r
316                 \r
317                 //completely stops and frees a device\r
318                 void stopDevice(int deviceID);\r
319                 \r
320                 //as above but then sets it up with same settings\r
321                 bool restartDevice(int deviceID);\r
322                 \r
323                 //number of devices available\r
324                 int  devicesFound;\r
325                 \r
326                 long propBrightness;\r
327                 long propContrast;\r
328                 long propHue;\r
329                 long propSaturation;\r
330                 long propSharpness;\r
331                 long propGamma;\r
332                 long propColorEnable;\r
333                 long propWhiteBalance;\r
334                 long propBacklightCompensation;\r
335                 long propGain;\r
336 \r
337                 long propPan;\r
338                 long propTilt;\r
339                 long propRoll;\r
340                 long propZoom;\r
341                 long propExposure;\r
342                 long propIris;\r
343                 long propFocus;\r
344                                 \r
345                 \r
346         private:                \r
347                 void setPhyCon(int deviceID, int conn);                   \r
348                 void setAttemptCaptureSize(int deviceID, int w, int h);   \r
349                 bool setup(int deviceID);\r
350                 void processPixels(unsigned char * src, unsigned char * dst, int width, int height, bool bRGB, bool bFlip);\r
351                 int  start(int deviceID, videoDevice * VD);                   \r
352                 int  getDeviceCount();\r
353                 void getMediaSubtypeAsString(GUID type, char * typeAsString);\r
354                 \r
355                 HRESULT getDevice(IBaseFilter **pSrcFilter, int deviceID, WCHAR * wDeviceName, char * nDeviceName);\r
356                 static HRESULT ShowFilterPropertyPages(IBaseFilter *pFilter);\r
357                 HRESULT SaveGraphFile(IGraphBuilder *pGraph, WCHAR *wszPath);\r
358                 HRESULT routeCrossbar(ICaptureGraphBuilder2 **ppBuild, IBaseFilter **pVidInFilter, int conType, GUID captureMode);\r
359                         \r
360                 //don't touch\r
361                 static bool comInit();\r
362                 static bool comUnInit();\r
363 \r
364                 int  connection;\r
365                 int  callbackSetCount;\r
366                 bool bCallback;\r
367                 \r
368                 GUID CAPTURE_MODE;\r
369                 \r
370                 //Extra video subtypes\r
371                 GUID MEDIASUBTYPE_Y800;\r
372                 GUID MEDIASUBTYPE_Y8;\r
373                 GUID MEDIASUBTYPE_GREY;\r
374 \r
375                 videoDevice * VDList[VI_MAX_CAMERAS];\r
376                 GUID mediaSubtypes[VI_NUM_TYPES];\r
377                 long formatTypes[VI_NUM_FORMATS];\r
378 \r
379                 static void __cdecl basicThread(void * objPtr);\r
380 \r
381                 static char deviceNames[VI_MAX_CAMERAS][255];\r
382 \r
383 }; \r
384   \r
385  #endif\r