Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/videoio/src/cap_unicap.cpp
16354 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// Intel License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2008, Xavier Delacour, all rights reserved.
14
// Third party copyrights are property of their respective owners.
15
//
16
// Redistribution and use in source and binary forms, with or without modification,
17
// are permitted provided that the following conditions are met:
18
//
19
// * Redistribution's of source code must retain the above copyright notice,
20
// this list of conditions and the following disclaimer.
21
//
22
// * Redistribution's in binary form must reproduce the above copyright notice,
23
// this list of conditions and the following disclaimer in the documentation
24
// and/or other materials provided with the distribution.
25
//
26
// * The name of Intel Corporation may not be used to endorse or promote products
27
// derived from this software without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall the Intel Corporation or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
//M*/
41
42
// 2008-04-27 Xavier Delacour <[email protected]>
43
44
#include "precomp.hpp"
45
#include <unistd.h>
46
#include <unicap.h>
47
extern "C" {
48
#include <ucil.h>
49
}
50
51
#ifdef NDEBUG
52
#define CV_WARN(message)
53
#else
54
#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
55
#endif
56
57
struct CvCapture_Unicap : public CvCapture
58
{
59
CvCapture_Unicap() { init(); }
60
virtual ~CvCapture_Unicap() { close(); }
61
62
virtual bool open( int index );
63
virtual void close();
64
65
virtual double getProperty(int) const CV_OVERRIDE;
66
virtual bool setProperty(int, double) CV_OVERRIDE;
67
virtual bool grabFrame() CV_OVERRIDE;
68
virtual IplImage* retrieveFrame(int) CV_OVERRIDE;
69
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_UNICAP; }
70
71
bool shutdownDevice();
72
bool initDevice();
73
74
void init()
75
{
76
device_initialized = false;
77
desired_format = 0;
78
desired_size = cvSize(0,0);
79
convert_rgb = false;
80
81
handle = 0;
82
memset( &device, 0, sizeof(device) );
83
memset( &format_spec, 0, sizeof(format_spec) );
84
memset( &format, 0, sizeof(format) );
85
memset( &raw_buffer, 0, sizeof(raw_buffer) );
86
memset( &buffer, 0, sizeof(buffer) );
87
88
raw_frame = frame = 0;
89
}
90
91
bool device_initialized;
92
93
int desired_device;
94
int desired_format;
95
CvSize desired_size;
96
bool convert_rgb;
97
98
unicap_handle_t handle;
99
unicap_device_t device;
100
unicap_format_t format_spec;
101
unicap_format_t format;
102
unicap_data_buffer_t raw_buffer;
103
unicap_data_buffer_t buffer;
104
105
IplImage *raw_frame;
106
IplImage *frame;
107
};
108
109
bool CvCapture_Unicap::shutdownDevice() {
110
bool result = false;
111
CV_FUNCNAME("CvCapture_Unicap::shutdownDevice");
112
__BEGIN__;
113
114
if (!SUCCESS(unicap_stop_capture(handle)))
115
CV_ERROR(CV_StsError, "unicap: failed to stop capture on device\n");
116
117
if (!SUCCESS(unicap_close(handle)))
118
CV_ERROR(CV_StsError, "unicap: failed to close the device\n");
119
120
cvReleaseImage(&raw_frame);
121
cvReleaseImage(&frame);
122
123
device_initialized = false;
124
125
result = true;
126
__END__;
127
return result;
128
}
129
130
bool CvCapture_Unicap::initDevice() {
131
bool result = false;
132
CV_FUNCNAME("CvCapture_Unicap::initDevice");
133
__BEGIN__;
134
135
if (device_initialized && !shutdownDevice())
136
return false;
137
138
if(!SUCCESS(unicap_enumerate_devices(NULL, &device, desired_device)))
139
CV_ERROR(CV_StsError, "unicap: failed to get info for device\n");
140
141
if(!SUCCESS(unicap_open( &handle, &device)))
142
CV_ERROR(CV_StsError, "unicap: failed to open device\n");
143
144
unicap_void_format(&format_spec);
145
146
if (!SUCCESS(unicap_enumerate_formats(handle, &format_spec, &format, desired_format))) {
147
shutdownDevice();
148
CV_ERROR(CV_StsError, "unicap: failed to get video format\n");
149
}
150
151
int i;
152
if (format.sizes)
153
{
154
for (i = format.size_count - 1; i > 0; i--)
155
if (format.sizes[i].width == desired_size.width &&
156
format.sizes[i].height == desired_size.height)
157
break;
158
format.size.width = format.sizes[i].width;
159
format.size.height = format.sizes[i].height;
160
}
161
162
if (!SUCCESS(unicap_set_format(handle, &format))) {
163
shutdownDevice();
164
CV_ERROR(CV_StsError, "unicap: failed to set video format\n");
165
}
166
167
memset(&raw_buffer, 0x0, sizeof(unicap_data_buffer_t));
168
raw_frame = cvCreateImage(cvSize(format.size.width,
169
format.size.height),
170
8, format.bpp / 8);
171
memcpy(&raw_buffer.format, &format, sizeof(raw_buffer.format));
172
raw_buffer.data = (unsigned char*)raw_frame->imageData;
173
raw_buffer.buffer_size = format.size.width *
174
format.size.height * format.bpp / 8;
175
176
memset(&buffer, 0x0, sizeof(unicap_data_buffer_t));
177
memcpy(&buffer.format, &format, sizeof(buffer.format));
178
179
buffer.format.fourcc = UCIL_FOURCC('B','G','R','3');
180
buffer.format.bpp = 24;
181
// * todo support greyscale output
182
// buffer.format.fourcc = UCIL_FOURCC('G','R','E','Y');
183
// buffer.format.bpp = 8;
184
185
frame = cvCreateImage(cvSize(buffer.format.size.width,
186
buffer.format.size.height),
187
8, buffer.format.bpp / 8);
188
buffer.data = (unsigned char*)frame->imageData;
189
buffer.buffer_size = buffer.format.size.width *
190
buffer.format.size.height * buffer.format.bpp / 8;
191
192
if(!SUCCESS(unicap_start_capture(handle))) {
193
shutdownDevice();
194
CV_ERROR(CV_StsError, "unicap: failed to start capture on device\n");
195
}
196
197
device_initialized = true;
198
result = true;
199
__END__;
200
return result;
201
}
202
203
void CvCapture_Unicap::close() {
204
if(device_initialized)
205
shutdownDevice();
206
}
207
208
bool CvCapture_Unicap::grabFrame() {
209
bool result = false;
210
211
CV_FUNCNAME("CvCapture_Unicap::grabFrame");
212
__BEGIN__;
213
214
unicap_data_buffer_t *returned_buffer;
215
216
int retry_count = 100;
217
218
while (retry_count--) {
219
if(!SUCCESS(unicap_queue_buffer(handle, &raw_buffer)))
220
CV_ERROR(CV_StsError, "unicap: failed to queue a buffer on device\n");
221
222
if(SUCCESS(unicap_wait_buffer(handle, &returned_buffer)))
223
{
224
result = true;
225
EXIT;
226
}
227
228
CV_WARN("unicap: failed to wait for buffer on device\n");
229
usleep(100 * 1000);
230
}
231
232
__END__;
233
return result;
234
}
235
236
IplImage * CvCapture_Unicap::retrieveFrame(int) {
237
if (convert_rgb) {
238
ucil_convert_buffer(&buffer, &raw_buffer);
239
return frame;
240
}
241
return raw_frame;
242
}
243
244
double CvCapture_Unicap::getProperty(int id) const
245
{
246
switch (id) {
247
case CV_CAP_PROP_POS_MSEC: break;
248
case CV_CAP_PROP_POS_FRAMES: break;
249
case CV_CAP_PROP_POS_AVI_RATIO: break;
250
case CV_CAP_PROP_FRAME_WIDTH:
251
return desired_size.width;
252
case CV_CAP_PROP_FRAME_HEIGHT:
253
return desired_size.height;
254
case CV_CAP_PROP_FPS: break;
255
case CV_CAP_PROP_FOURCC: break;
256
case CV_CAP_PROP_FRAME_COUNT: break;
257
case CV_CAP_PROP_FORMAT:
258
return desired_format;
259
case CV_CAP_PROP_MODE: break;
260
case CV_CAP_PROP_BRIGHTNESS: break;
261
case CV_CAP_PROP_CONTRAST: break;
262
case CV_CAP_PROP_SATURATION: break;
263
case CV_CAP_PROP_HUE: break;
264
case CV_CAP_PROP_GAIN: break;
265
case CV_CAP_PROP_CONVERT_RGB:
266
return convert_rgb;
267
}
268
269
return 0;
270
}
271
272
bool CvCapture_Unicap::setProperty(int id, double value) {
273
bool reinit = false;
274
275
switch (id) {
276
case CV_CAP_PROP_POS_MSEC: break;
277
case CV_CAP_PROP_POS_FRAMES: break;
278
case CV_CAP_PROP_POS_AVI_RATIO: break;
279
case CV_CAP_PROP_FRAME_WIDTH:
280
desired_size.width = (int)value;
281
reinit = true;
282
break;
283
case CV_CAP_PROP_FRAME_HEIGHT:
284
desired_size.height = (int)value;
285
reinit = true;
286
break;
287
case CV_CAP_PROP_FPS: break;
288
case CV_CAP_PROP_FOURCC: break;
289
case CV_CAP_PROP_FRAME_COUNT: break;
290
case CV_CAP_PROP_FORMAT:
291
desired_format = id;
292
reinit = true;
293
break;
294
case CV_CAP_PROP_MODE: break;
295
case CV_CAP_PROP_BRIGHTNESS: break;
296
case CV_CAP_PROP_CONTRAST: break;
297
case CV_CAP_PROP_SATURATION: break;
298
case CV_CAP_PROP_HUE: break;
299
case CV_CAP_PROP_GAIN: break;
300
case CV_CAP_PROP_CONVERT_RGB:
301
convert_rgb = value != 0;
302
break;
303
}
304
305
if (reinit && !initDevice())
306
return false;
307
308
return true;
309
}
310
311
bool CvCapture_Unicap::open(int index)
312
{
313
close();
314
device_initialized = false;
315
316
desired_device = index < 0 ? 0 : index;
317
desired_format = 0;
318
desired_size = cvSize(320, 240);
319
convert_rgb = true;
320
321
return initDevice();
322
}
323
324
325
CvCapture * cvCreateCameraCapture_Unicap(const int index)
326
{
327
CvCapture_Unicap *cap = new CvCapture_Unicap;
328
if( cap->open(index) )
329
return cap;
330
delete cap;
331
return 0;
332
}
333
334