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
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
|
/* 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 …) 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_installation Installation from source
*
* Check out the code from vogelgesang/libuca or untar the tarball. Make sure to
* install CMake and any third party drivers and SDKs that you want to have
* accessed by libuca. Now go into some empty build directory and issue
*
* \verbatim
$ cmake PATH_TO_LIBUCA_SOURCE
$ make
$ make install
\endverbatim
*
* \section intro_quickstart Quick Start
*
* First of all you have to create a new uca handle to initialize the individual
* subsystems
*
* \code uca *u = uca_init(); \endcode
*
* and see if uca_init() did not return NULL. If this is the case, 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
* uca_camera *i = uca->cameras;
* while (i != NULL) {
* // do something with i
* i = i->next;
* }
* \endcode
*
* The uca_camera handle is used to set and retrieve properties:
*
* \code
* uca_camera *cam = uca->cameras;
* uint32_t val = 5000;
* uca_cam_set_property(cam, UCA_PROP_EXPOSURE, &val);
*
* uint32_t width, height;
* uca_cam_get_property(cam, UCA_PROP_WIDTH, &width, NULL);
* uca_cam_get_property(cam, UCA_PROP_HEIGHT, &height, NULL);
* \endcode
*
* \section properties Property system
*
* Each property has a unique id listed in the #uca_property_ids enum.
* Information about each property is given in a uca_property structure that is
* mapped with uca_get_full_property(). The description lists the unit, type and
* access rights.
*
* \section intro_recording Recording
*
* To record in synchronous fashion use uca_cam_grab() like
*
* \code
* void *buffer = (void *) malloc(width * height * bytes_per_pixel);
* uca_cam_start_recording(cam);
* uca_cam_grab(cam, (char *) buffer, NULL);
* uca_cam_stop_recording(cam);
* \endcode
*
* Eventually you will have to cleanup the system by calling
*
* \code uca_destroy(u); \endcode
*
* \section intro_usage Adding new cameras
*
* 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.
*
* \section api_reference API reference
*
* All function definitions can be found in uca.h.
*
*/
/* 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! */
/**
* ID of all supported properties
*/
typedef enum {
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
} uca_property_ids;
/* 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.
*/
typedef enum {
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) */
} uca_unit;
/**
* 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.
*/
typedef enum {
uca_uint32t,
uca_uint8t,
uca_string
} uca_types;
/**
* Access rights determine if uca_cam_get_property() and/or
* uca_cam_set_property() can be used with this property.
*/
typedef enum {
uca_read = 0x01, /**< property can be read */
uca_write = 0x02, /**< property can be written */
uca_readwrite = 0x01 | 0x02 /**< property can be read and written */
} uca_access_rights;
/**
* Describes the current state of the camera.
*
* \see uca_cam_get_state()
*/
typedef enum {
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 */
} uca_cam_state;
/**
* Specify if the callback function keeps the buffer and will call
* ufo_cam_release_buffer() at later time or if after returning the buffer can
* be released automatically.
*
* \since 0.5
*/
typedef enum {
UCA_BUFFER_KEEP, /**< Keep the buffer and call ufo_cam_release_buffer() manually */
UCA_BUFFER_RELEASE /**< Buffer is released upon return */
} uca_buffer_status;
/**
* 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.
* \see uca_get_full_property()
*/
typedef struct {
/**
* 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;
uca_unit unit; /**< Physical unit of this property */
uca_types type; /**< Type of this property */
uca_access_rights access; /**< Access rights of this property */
} uca_property;
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()
* \return Value from uca_buffer_status. If #UCA_BUFFER_KEEP is returned, the
* callee must make sure to call uca_cam_release_buffer(). On the other hand, if
* #UCA_BUFFER_RELEASE is returned this is done by the caller.
*
* \note The meta data parameter is not yet specified but just a place holder.
*/
typedef uca_buffer_status (*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.
*/
typedef struct uca_camera {
struct uca_camera *next;
struct uca_camera_priv* priv;
} uca_camera;
struct uca_grabber_priv;
typedef struct uca_grabber {
struct uca_grabber *next;
struct uca_grabber_priv* priv;
} uca_grabber;
/**
* Keeps a list of cameras and grabbers.
*/
typedef struct {
uca_camera *cameras; /**< Root of detected camera list */
uca_grabber *grabbers; /**< Root of detected grabber list */
} uca;
/**
* 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.
*/
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(uca *u);
/**
* Convert a property string to the corresponding ID
*
* \param[in] property_name Name of the property
* \param[out] prop_id Resulting property ID
* \return Error code
*/
uint32_t uca_get_property_id(const char *property_name, uca_property_ids *prop_id);
/**
* Convert a property ID to the corresponding string
*
* \param property_id ID of a property
* \return If property is found name of the property else NULL
*/
const char* uca_get_property_name(uca_property_ids property_id);
/**
* Return the full property structure for a given ID
*
* \param property_id ID of a property
* \return Property description or NULL if property is not found
*/
uca_property *uca_get_full_property(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(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.
*/
uca_cam_state uca_cam_get_state(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(uca_camera *cam, 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(uca_camera *cam, 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(uca_camera *cam);
/**
* Stop recording.
*
* \param[in] cam A uca_camera object
* \return Error code
*/
uint32_t uca_cam_stop_recording(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(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(uca_camera *cam, uca_cam_grab_callback callback, void *user);
/**
* Release the buffer that was given in the grab callback.
*
* \param[in] cam A uca_camera object
* \param[in] buffer The buffer that was passed to the callback
*
* \see uca_cam_register_callback(), uca_cam_grab_callback
* \since 0.5
*/
uint32_t uca_cam_release_buffer(uca_camera *cam, void *buffer);
/**
* \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(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(uca_camera *cam);
#define uca_set_void(p, type, value) { *((type *) p) = (type) value; }
#ifdef __cplusplus
}
#endif
#endif
|