YARP
Yet Another Robot Platform
VfwGrabber.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 RobotCub Consortium
3  * Authors: Paul Fitzpatrick
4  * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
5  *
6  */
7 
8 // based on material from cvcap_vfw.cpp from the OpenCV library.
9 // changes are under the GPL. Statement for original material follows.
10 
11 
12 /*M///////////////////////////////////////////////////////////////////////////////////////
13 //
14 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
15 //
16 // By downloading, copying, installing or using the software you agree to this license.
17 // If you do not agree to this license, do not download, install,
18 // copy or use the software.
19 //
20 //
21 // Intel License Agreement
22 // For Open Source Computer Vision Library
23 //
24 // Copyright (C) 2000, Intel Corporation, all rights reserved.
25 // Third party copyrights are property of their respective owners.
26 //
27 // Redistribution and use in source and binary forms, with or without modification,
28 // are permitted provided that the following conditions are met:
29 //
30 // * Redistribution's of source code must retain the above copyright notice,
31 // this list of conditions and the following disclaimer.
32 //
33 // * Redistribution's in binary form must reproduce the above copyright notice,
34 // this list of conditions and the following disclaimer in the documentation
35 // and/or other materials provided with the distribution.
36 //
37 // * The name of Intel Corporation may not be used to endorse or promote products
38 // derived from this software without specific prior written permission.
39 //
40 // This software is provided by the copyright holders and contributors "as is" and
41 // any express or implied warranties, including, but not limited to, the implied
42 // warranties of merchantability and fitness for a particular purpose are disclaimed.
43 // In no event shall the Intel Corporation or contributors be liable for any direct,
44 // indirect, incidental, special, exemplary, or consequential damages
45 // (including, but not limited to, procurement of substitute goods or services;
46 // loss of use, data, or profits; or business interruption) however caused
47 // and on any theory of liability, whether in contract, strict liability,
48 // or tort (including negligence or otherwise) arising in any way out of
49 // the use of this software, even if advised of the possibility of such damage.
50 //
51 //M*/
52 
53 
54 #include <windows.h>
55 #include <VfwGrabber.h>
56 using namespace yarp::dev;
57 
58 #include <cstdio>
59 
60 #include <vfw.h>
61 
62 // MINGW headers are incomplete at time of writing
63 #ifdef __MINGW__
64 #include <vfw_extra_from_wine.h>
67 #ifndef True
68 #define True TRUE
69 #endif
70 #endif
71 
72 #include <yarp/sig/Image.h>
73 
75 
76 
77 typedef struct CvCaptureCAM_VFW
78 {
80  HWND capWnd;
82  DWORD fourcc;
83  HIC hic;
85 }
87 
88 static LRESULT PASCAL FrameCallbackProc( HWND hWnd, VIDEOHDR* hdr )
89 {
90  CvCaptureCAM_VFW* capture = 0;
91 
92  if (!hWnd) return FALSE;
93 
94  capture = (CvCaptureCAM_VFW*)capGetUserData(hWnd);
95  capture->hdr = hdr;
96 
97  printf("Frame arrived!\n");
98 
99  //hdr->lpData;
100  //hdr->dwBytesUsed;
101 
102  return (LRESULT)TRUE;
103 }
104 
105 
106 // Initialize camera input
107 static int icvOpenCAM_VFW( CvCaptureCAM_VFW* capture, int wIndex )
108 {
109  char szDeviceName[80];
110  char szDeviceVersion[80];
111  HWND hWndC = 0;
112 
113  if( (unsigned)wIndex >= 10 )
114  wIndex = 0;
115 
116  for( ; wIndex < 10; wIndex++ )
117  {
118  if( capGetDriverDescription( wIndex, szDeviceName,
119  sizeof (szDeviceName), szDeviceVersion,
120  sizeof (szDeviceVersion)))
121  {
122  printf("Possible input: %s\n", szDeviceName);
123  hWndC = capCreateCaptureWindow ( "My Own Capture Window",
124  WS_POPUP | WS_CHILD, 0, 0, 320, 240, 0, 0);
125  if( capDriverConnect (hWndC, wIndex))
126  break;
127  DestroyWindow( hWndC );
128  hWndC = 0;
129  }
130  }
131 
132  capture->capWnd = 0;
133  if( hWndC )
134  {
135  printf("got a window\n");
136  capture->capWnd = hWndC;
137  capture->hdr = 0;
138  capture->hic = 0;
139  capture->fourcc = (DWORD)-1;
140 
141  memset( &capture->caps, 0, sizeof(capture->caps));
142  capDriverGetCaps( hWndC, &capture->caps, sizeof(&capture->caps));
143  ::MoveWindow( hWndC, 0, 0, 320, 240, TRUE );
144  capSetUserData( hWndC, (size_t)capture );
146  CAPTUREPARMS p;
147  capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
148  p.dwRequestMicroSecPerFrame = 66667/2;
149  capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
150  //capPreview( hWndC, 1 );
151  capPreviewScale(hWndC,FALSE);
152  capPreviewRate(hWndC,1);
153  }
154  return capture->capWnd != 0;
155 }
156 
157 static void icvCloseCAM_VFW( CvCaptureCAM_VFW* capture )
158 {
159  if( capture && capture->capWnd )
160  {
161  capSetCallbackOnFrame( capture->capWnd, NULL );
162  capDriverDisconnect( capture->capWnd );
163  DestroyWindow( capture->capWnd );
164  if( capture->hic )
165  {
166  ICDecompressEnd( capture->hic );
167  ICClose( capture->hic );
168  }
169 
170  capture->capWnd = 0;
171  capture->hic = 0;
172  capture->hdr = 0;
173  capture->fourcc = 0;
174  }
175 }
176 
177 
178 static int icvGrabFrameCAM_VFW( CvCaptureCAM_VFW* capture )
179 {
180  if( capture->capWnd )
181  {
182  SendMessage( capture->capWnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0 );
183  return 1;
184  }
185  return 0;
186 }
187 
188 
189 static BITMAPINFOHEADER icvBitmapHeader( int width, int height, int bpp, int compression = BI_RGB )
190 {
191  BITMAPINFOHEADER bmih;
192  memset( &bmih, 0, sizeof(bmih));
193  bmih.biSize = sizeof(bmih);
194  bmih.biWidth = width;
195  bmih.biHeight = height;
196  bmih.biBitCount = (WORD)bpp;
197  bmih.biCompression = compression;
198  bmih.biPlanes = 1;
199 
200  return bmih;
201 }
202 
204 {
205  bool done = false;
206  if( capture->capWnd )
207  {
208  BITMAPINFO vfmt;
209  memset( &vfmt, 0, sizeof(vfmt));
210  int sz = capGetVideoFormat( capture->capWnd, &vfmt, sizeof(vfmt));
211 
212  if( capture->hdr && capture->hdr->lpData && sz != 0 )
213  {
214  long code = ICERR_OK;
215  char* frame_data = (char*)capture->hdr->lpData;
216 
217  if( vfmt.bmiHeader.biCompression != BI_RGB ||
218  vfmt.bmiHeader.biBitCount != 24 )
219  {
220  printf("funky format\n");
221  BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader;
222  BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 );
223  code = ICERR_ERROR;
224 
225  if( capture->hic == 0 ||
226  capture->fourcc != vfmt0.biCompression ||
227  vfmt0.biWidth != capture->frame.width() ||
228  vfmt0.biHeight != capture->frame.height() )
229  {
230  if( capture->hic )
231  {
232  ICDecompressEnd( capture->hic );
233  ICClose( capture->hic );
234  }
235  capture->hic = ICOpen( MAKEFOURCC('V','I','D','C'),
236  vfmt0.biCompression, ICMODE_DECOMPRESS );
237  if( capture->hic &&
238  ICDecompressBegin( capture->hic, &vfmt0, &vfmt1 ) == ICERR_OK )
239  {
240 
241  capture->frame.setTopIsLowIndex(false);
242  capture->frame.resize(vfmt0.biWidth, vfmt0.biHeight);
243 
244  code = ICDecompress( capture->hic, 0,
245  &vfmt0, capture->hdr->lpData,
246  &vfmt1, capture->frame.getRawImage() );
247  if (code == ICERR_OK) {
248  done = true;
249  }
250 
251  }
252  }
253  }
254 
255  if( code == ICERR_OK )
256  {
257  if (!done) {
258 
259  capture->frame.setTopIsLowIndex(false);
260  capture->frame.setExternal(frame_data,
261  vfmt.bmiHeader.biWidth,
262  vfmt.bmiHeader.biHeight);
263  }
264  return &capture->frame;
265  }
266  }
267  }
268 
269  return 0;
270 }
271 
272 
273 
274 #define HELPER(x) (*((CvCaptureCAM_VFW *)(x)))
275 
277  system_resource = new CvCaptureCAM_VFW;
278  if (system_resource!=NULL) {
279  int index = config.check("index",
280  yarp::os::Value(0),
281  "VFW device index").asInt();
282  int result = icvOpenCAM_VFW(&HELPER(system_resource),index);
283  if (!result) {
284  printf("failed to find camera\n");
285  close();
286  }
287  }
288  return system_resource!=NULL;
289 }
290 
292  if (system_resource!=NULL) {
293  icvCloseCAM_VFW(&HELPER(system_resource));
294  delete &HELPER(system_resource);
295  system_resource = NULL;
296  }
297  return true;
298 }
299 
301  icvGrabFrameCAM_VFW(&HELPER(system_resource));
302  Image *img = icvRetrieveFrameCAM_VFW(&HELPER(system_resource));
303  //printf("image size %d %d\n", img->width(), img->height());
304  image.copy(*img);
305  _width = img->width();
306  _height = img->height();
307  return img->width()>0;
308 }
struct CvCaptureCAM_VFW CvCaptureCAM_VFW
static int icvOpenCAM_VFW(CvCaptureCAM_VFW *capture, int wIndex)
Definition: VfwGrabber.cpp:107
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition: Image.cpp:530
static BITMAPINFOHEADER icvBitmapHeader(int width, int height, int bpp, int compression=BI_RGB)
Definition: VfwGrabber.cpp:189
yarp::sig::ImageOf< yarp::sig::PixelBgr > Image
Definition: VfwGrabber.cpp:74
#define capDriverConnect(handle, device)
delete image
Definition: IplImage.cpp:897
bool copy(const Image &alt)
Copy operator.
Definition: Image.cpp:811
static LRESULT PASCAL FrameCallbackProc(HWND hWnd, VIDEOHDR *hdr)
Definition: VfwGrabber.cpp:88
static Image * icvRetrieveFrameCAM_VFW(CvCaptureCAM_VFW *capture)
Definition: VfwGrabber.cpp:203
A base class for nested structures that can be searched.
Definition: Searchable.h:56
VIDEOHDR * hdr
Definition: VfwGrabber.cpp:81
int width() const
Gets width of image in pixels.
Definition: Image.h:134
CAPDRIVERCAPS caps
Definition: VfwGrabber.cpp:79
static void icvCloseCAM_VFW(CvCaptureCAM_VFW *capture)
Definition: VfwGrabber.cpp:157
#define HELPER(x)
Definition: VfwGrabber.cpp:274
#define capDriverDisconnect(handle)
#define capSetCallbackOnFrame(handle, callback)
#define capSetUserData(handle, userData)
void resize(int imgWidth, int imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
Definition: Image.cpp:459
#define capPreviewScale(handle, flag)
An interface for the device drivers.
#define capCaptureGetSetup(handle, memory, size)
void setTopIsLowIndex(bool flag)
control whether image has origin at top left (default) or bottom left.
Definition: Image.h:328
#define capGetUserData(handle)
void setExternal(const void *data, int imgWidth, int imgHeight)
Use this to wrap an external image.
Definition: Image.cpp:845
virtual void close() override
Definition: TcpRosStream.h:98
static int icvGrabFrameCAM_VFW(CvCaptureCAM_VFW *capture)
Definition: VfwGrabber.cpp:178
virtual bool getImage(yarp::sig::ImageOf< yarp::sig::PixelRgb > &image)
Get an rgb image from the frame grabber, if required demosaicking/color reconstruction is applied...
Definition: VfwGrabber.cpp:300
A single value (typically within a Bottle).
Definition: Value.h:36
virtual bool check(const ConstString &key) const =0
Check if there exists a property of the given name.
virtual bool close()
Close the DeviceDriver.
Definition: VfwGrabber.cpp:291
virtual bool open(yarp::os::Searchable &config)
Open the DeviceDriver.
Definition: VfwGrabber.cpp:276
#define capPreviewRate(handle, rate)
#define capCaptureSetSetup(handle, memory, size)
#define WM_CAP_GRAB_FRAME_NOSTOP
#define capGetVideoFormat(handle, memory, size)
int height() const
Gets height of image in pixels.
Definition: Image.h:140
#define capDriverGetCaps(handle, memory, size)