1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
|
/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu>
(Karlsruhe Institute of Technology)
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
#ifndef __UNIFIED_CAMERA_ACCESS_H
#define __UNIFIED_CAMERA_ACCESS_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file uca.h
* \brief Abstract camera model
*
* The uca_t structure represents a common interface for cameras regardless of
* their connectivity. Each camera that adheres to this model must provide an
* initialization function that probes the device and sets all function pointers
* to their respective implementation.
*/
/**
* \mainpage
*
* \section intro_sec Introduction
*
* libuca is a thin wrapper to make different cameras and their access
* interfaces (via CameraLink, PCIe, Thunderbolt …) accessible in an easy way.
* It builds support for cameras, when it can find the necessary dependencies,
* so there is no need to have camera SDKs installed when you don't own a
* camera.
*
* \section intro_quickstart Quick Start
*
* First you would create a new uca_t structure
*
* \code struct uca_t *uca = uca_init() \endcode
*
* and see if it is not NULL. If it is NULL, no camera or frame grabber was
* found. If you build with HAVE_DUMMY_CAMERA, there will always be at least the
* dummy camera available.
*
* You can then iterate through all available cameras using
*
* \code
* struct uca_camera_t *i = uca->cameras;
* while (i != NULL) {
* // do something with i
* i = i->next;
* }
* \endcode
*
* With such a uca_camera_t structure, you can set properties, retrieve
* properties or start grabbing frames. Be aware, to check bit depth and frame
* dimensions in order to allocate enough memory.
*
* \section intro_usage Adding new cameras
*
* Up to now, new cameras have to be integrated into libuca directly. Later on,
* we might provide a plugin mechanism. To add a new camera, add
* cameras/new-cam.c and cameras/new-cam.h to the source tree and change
* CMakeLists.txt to include these files. Furthermore, if this camera relies on
* external dependencies, these have to be found first via the CMake system.
*
* The new camera must export exactly one function: uca_new_camera_init() which
* checks if (given the grabber) the camera is available and sets the function
* pointers to access the camera accordingly.
*/
/* The property IDs must start with 0 and must be continuous. Whenever this
* library is released, the IDs must not change to guarantee binary compatibility! */
enum uca_property_ids {
UCA_PROP_NAME = 0,
UCA_PROP_WIDTH,
UCA_PROP_WIDTH_MIN,
UCA_PROP_WIDTH_MAX,
UCA_PROP_HEIGHT,
UCA_PROP_HEIGHT_MIN,
UCA_PROP_HEIGHT_MAX,
UCA_PROP_X_OFFSET,
UCA_PROP_X_OFFSET_MIN,
UCA_PROP_X_OFFSET_MAX,
UCA_PROP_Y_OFFSET,
UCA_PROP_Y_OFFSET_MIN,
UCA_PROP_Y_OFFSET_MAX,
UCA_PROP_BINNING_X,
UCA_PROP_BINNING_Y,
UCA_PROP_BITDEPTH,
UCA_PROP_EXPOSURE,
UCA_PROP_EXPOSURE_MIN,
UCA_PROP_EXPOSURE_MAX,
UCA_PROP_DELAY,
UCA_PROP_DELAY_MIN,
UCA_PROP_DELAY_MAX,
UCA_PROP_FRAMERATE,
UCA_PROP_TEMPERATURE_SENSOR,
UCA_PROP_TEMPERATURE_CAMERA,
UCA_PROP_TRIGGER_MODE,
UCA_PROP_TRIGGER_EXPOSURE,
UCA_PROP_PGA_GAIN,
UCA_PROP_PGA_GAIN_MIN,
UCA_PROP_PGA_GAIN_MAX,
UCA_PROP_PGA_GAIN_STEPS,
UCA_PROP_ADC_GAIN,
UCA_PROP_ADC_GAIN_MIN,
UCA_PROP_ADC_GAIN_MAX,
UCA_PROP_ADC_GAIN_STEPS,
/* grabber specific */
UCA_PROP_GRAB_TIMEOUT,
UCA_PROP_GRAB_SYNCHRONOUS,
UCA_PROP_GRAB_AUTO,
/* pco.edge specific */
UCA_PROP_TIMESTAMP_MODE,
UCA_PROP_SCAN_MODE,
UCA_PROP_HOTPIXEL_CORRECTION,
/* IPE camera specific */
UCA_PROP_INTERLACE_SAMPLE_RATE,
UCA_PROP_INTERLACE_PIXEL_THRESH,
UCA_PROP_INTERLACE_ROW_THRESH,
/* Photon Focus specific */
UCA_PROP_CORRECTION_MODE,
UCA_PROP_LAST
};
/* Possible timestamp modes for UCA_PROP_TIMESTAMP_MODE */
#define UCA_TIMESTAMP_NONE 0x00
#define UCA_TIMESTAMP_ASCII 0x01
#define UCA_TIMESTAMP_BINARY 0x02
/* Trigger mode for UCA_PROP_TRIGGER_MODE */
#define UCA_TRIGGER_AUTO 0 /**< free-run mode */
#define UCA_TRIGGER_SOFTWARE 1 /**< software trigger via uca_cam_trigger() */
#define UCA_TRIGGER_EXTERNAL 2 /**< external hardware trigger */
#define UCA_TRIGGER_EXTERNAL_EXPOSURE 3 /**< hardware trigger controlling exposure */
#define UCA_TRIGGER_EXP_CAMERA 1 /**< camera-controlled exposure time */
#define UCA_TRIGGER_EXP_LEVEL 2 /**< level-controlled (trigger signal) exposure time */
/* Correction modes for UCA_PROP_CORRECTION_MODE */
#define UCA_CORRECT_OFFSET 0x01
#define UCA_CORRECT_HOTPIXEL 0x02
#define UCA_CORRECT_GAIN 0x04
/**
* The physical unit of this property.
*
* This is important in order to let the camera drivers know, how to convert
* the values into their respective target value. It is also used for human
* interfaces.
*/
enum uca_unit {
uca_pixel, /**< number of pixels */
uca_bits, /**< number of bits */
uca_ns, /**< nanoseconds */
uca_us, /**< microseconds */
uca_ms, /**< milliseconds */
uca_s, /**< seconds */
uca_rows, /**< number of rows */
uca_fps, /**< frames per second */
uca_dc, /**< degree celsius */
uca_bool, /**< 1 or 0 for true and false */
uca_na /**< no unit available (for example modes) */
};
/**
* The data type of this property.
*
* When using uca_cam_set_property() and uca_cam_get_property() this field
* must be respected and correct data transfered, as the values are
* interpreted like defined here.
*/
enum uca_types {
uca_uint32t,
uca_uint8t,
uca_string
};
/**
* Access rights determine if uca_cam_get_property() and/or
* uca_cam_set_property() can be used with this property.
*/
enum uca_access_rights {
uca_read = 0x01, /**< property can be read */
uca_write = 0x02, /**< property can be written */
uca_readwrite = 0x01 | 0x02 /**< property can be read and written */
};
/**
* Describes the current state of the camera.
*/
enum uca_cam_state {
UCA_CAM_CONFIGURABLE, /**< Camera can be configured and is not recording */
UCA_CAM_ARMED, /**< Camera is ready for recording */
UCA_CAM_RECORDING, /**< Camera is currently recording */
UCA_CAM_READOUT /**< Camera recorded and is currently in readout mode */
};
/**
* A uca_property_t describes a vendor-independent property used by cameras and
* frame grabbers. It basically consists of a human-readable name, a physical
* unit, a type and some access rights.
*/
typedef struct uca_property {
/**
* A human-readable string for this property.
*
* A name is defined in a tree-like structure, to build some form of
* hierarchical namespace. To define a parent-child-relationship a dot '.'
* is used. For example "image.width.min" might be the name for the minimal
* acceptable frame width.
*/
const char *name;
enum uca_unit unit;
enum uca_types type;
enum uca_access_rights access;
} uca_property_t;
union uca_value {
uint32_t u32;
uint8_t u8;
char *string;
};
/**
* Grab callback.
*
* Register such a callback function with uca_cam_register_callback() to
* receive data as soon as it is delivered.
*
* \param[in] image_number Current frame number
* \param[in] buffer Image data
* \param[in] meta_data Meta data provided by the camera specifying per-frame
* data.
* \param[in] user User data registered in uca_cam_register_callback()
*
* \note The meta data parameter is not yet specified but just a place holder.
*/
typedef void (*uca_cam_grab_callback) (uint64_t image_number, void *buffer, void *meta_data, void *user);
extern const char *uca_unit_map[]; /**< maps unit numbers to corresponding strings */
/**
* An error code is a 32 bit integer with the following format (x:y means x bits
* for purpose y):
*
* [ 31 (MSB) ... ... 0 (LSB) ]
* [ 4:lvl | 4:rsv | 4:class | 4:source | 16:code ]
*
* where
*
* - lvl describes severity such as warning or failure,
* - rsv is reserved,
* - class describes the general class of the error,
* - source describes where the error occured and
* - code is the actual error condition
*
* UCA_ERR_MASK_*s can be used to mask the desired field of the error code.
*
*/
#define UCA_NO_ERROR 0x00000000
#define UCA_ERR_MASK_CODE 0xF000FFFF
#define UCA_ERR_MASK_SOURCE 0x000F0000
#define UCA_ERR_MASK_TYPE 0x00F00000
#define UCA_ERR_MASK_RESRV 0x0F000000
#define UCA_ERR_MASK_LEVEL 0xF0000000
#define UCA_ERR_GRABBER 0x00010000
#define UCA_ERR_CAMERA 0x00020000
#define UCA_ERR_INIT 0x00100000 /**< error during initialization */
#define UCA_ERR_PROP 0x00200000 /**< error while setting/getting property */
#define UCA_ERR_CALLBACK 0x00300000 /**< callback-related errors */
#define UCA_ERR_TRIGGER 0x00400000 /**< errors concerning trigger */
#define UCA_ERR_CONFIGURATION 0x00500000 /**< errors related to configuration steps */
#define UCA_ERR_FAILURE 0x10000000
#define UCA_ERR_WARNING 0x20000000
#define UCA_ERR_UNCLASSIFIED 0x10000001
#define UCA_ERR_NOT_FOUND 0x10000002
#define UCA_ERR_INVALID 0x10000003
#define UCA_ERR_NO_MEMORY 0x10000004
#define UCA_ERR_OUT_OF_RANGE 0x10000005
#define UCA_ERR_ACQUIRE 0x10000006
#define UCA_ERR_IS_RECORDING 0x10000007 /**< error because device is recording */
#define UCA_ERR_NOT_RECORDING 0x10000008
#define UCA_ERR_FRAME_TRANSFER 0x10000009
#define UCA_ERR_ALREADY_REGISTERED 0x1000000A
#define UCA_ERR_NOT_IMPLEMENTED 0x1000000B
#define UCA_ERR_NO_MORE_IMAGES 0x1000000C
struct uca_camera_priv;
/**
* uca_camera is an opaque structure that is only accessed with the uca_cam_*
* methods.
*/
struct uca_camera {
struct uca_camera *next;
struct uca_camera_priv* priv;
};
struct uca_grabber_priv;
struct uca_grabber {
struct uca_grabber *next;
struct uca_grabber_priv* priv;
};
/**
* Keeps a list of cameras and grabbers.
*/
typedef struct uca {
struct uca_camera *cameras;
struct uca_grabber *grabbers;
} uca_t;
/**
* Initialize the unified camera access interface.
*
* \param[in] config_filename Configuration file in JSON format for cameras
* relying on external calibration data. It is ignored when no JSON parser can
* be found at compile time or config_filename is NULL.
*
* \return Pointer to a uca structure
*
* \note uca_init() is thread-safe if a Pthread-implementation is available.
*/
struct uca *uca_init(const char *config_filename);
/**
* Free resources of the unified camera access interface
*
* \note uca_destroy() is thread-safe if a Pthread-implementation is available.
*/
void uca_destroy(struct uca *u);
/**
* Convert a property string to the corresponding ID
*/
uint32_t uca_get_property_id(const char *property_name, enum uca_property_ids *prop_id);
/**
* Convert a property ID to the corresponding string
*/
const char* uca_get_property_name(enum uca_property_ids property_id);
/**
* Return the full property structure for a given ID
*/
uca_property_t *uca_get_full_property(enum uca_property_ids property_id);
/**
* Allocates buffer memory for the internal frame grabber.
*
* The allocation is just a hint to the underlying camera driver. It might
* ignore this or pass this information on to a related frame grabber.
*
* \param[in] cam A uca_camera object
* \param[in] n_buffers Number of sub-buffers with size frame_width*frame_height.
* \return Error code
*/
uint32_t uca_cam_alloc(struct uca_camera *cam, uint32_t n_buffers);
/**
* Retrieve current state of the camera.
*
* \param[in] cam A uca_camera object
* \return A value from the uca_cam_state enum representing the current state of
* the camera.
*/
enum uca_cam_state uca_cam_get_state(struct uca_camera *cam);
/**
* Set a camera property.
*
* \param[in] cam The camera whose properties are to be set.
* \param[in] cam A uca_camera object
* \param[in] property ID of the property as defined in XXX
* \param[out] data Where to read the property's value from
*
* \return UCA_ERR_PROP_INVALID if property is not supported on the camera or
* UCA_ERR_PROP_VALUE_OUT_OF_RANGE if value cannot be set.
*/
uint32_t uca_cam_set_property(struct uca_camera *cam, enum uca_property_ids property, void *data);
/**
* Get a property.
*
* \param[in] cam A uca_camera object
* \param[in] property ID of the property as defined in XXX
* \param[out] data Where to store the property's value
* \param[in] num Number of bytes of string storage. Ignored for uca_uint8t
* and uca_uint32t properties.
*
* \return UCA_ERR_PROP_INVALID if property is not supported on the camera
*/
uint32_t uca_cam_get_property(struct uca_camera *cam, enum uca_property_ids property, void *data, size_t num);
/**
* Begin recording.
*
* Usually this also involves the frame acquisition of the frame grabber but is
* hidden by this function.
*
* \param[in] cam A uca_camera object
* \return Error code
*/
uint32_t uca_cam_start_recording(struct uca_camera *cam);
/**
* Stop recording.
*
* \param[in] cam A uca_camera object
* \return Error code
*/
uint32_t uca_cam_stop_recording(struct uca_camera *cam);
/**
* Send a software trigger signal to start a sensor read-out.
*
* This method is only useful when UCA_PROP_TRIGGER_MODE is set to
* UCA_TRIGGER_SOFTWARE.
*
* \param[in] cam A uca_camera object
* \return Error code
*/
uint32_t uca_cam_trigger(struct uca_camera *cam);
/**
* Register callback for given frame grabber. To actually start receiving
* frames, call uca_grabber_acquire().
*
* \param[in] cam A uca_camera object
* \param[in] callback Callback function for when a frame arrived
* \param[in] user User data that is passed to the callback function
* \return Error code
*/
uint32_t uca_cam_register_callback(struct uca_camera *cam, uca_cam_grab_callback callback, void *user);
/**
* \brief Grab one image from the camera
*
* The grabbing involves a memory copy because we might have to decode the image
* coming from the camera, which the frame grabber is not able to do.
*
* \param[in] cam A uca_camera object
* \param[in] buffer Destination buffer
* \param[in] meta_data Meta data provided by the camera specifying per-frame
* data.
* \return Error code
*
* \note The meta data parameter is not yet specified but just a place holder.
*
*/
uint32_t uca_cam_grab(struct uca_camera *cam, char *buffer, void *meta_data);
/**
* \brief Initiate read out for recording based cameras like pco.dimax or
* Photron SAx
*
* This function merely starts read out and requires that recording has stopped
* with uca_cam_stop_recording. To retrieve the image data, you have still have
* to use uca_cam_grab.
*
* \param[in] cam A uca_camera object
* \return Error code
*/
uint32_t uca_cam_readout(struct uca_camera *cam);
#define uca_set_void(p, type, value) { *((type *) p) = (type) value; }
#ifdef __cplusplus
}
#endif
#endif
|