summaryrefslogtreecommitdiffstats
path: root/src/uca.h
blob: 4a2919c3c87e1da34554aca8b5ba1ab1d009aaec (plain)
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
#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_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,

    /* pco.edge specific */
    UCA_PROP_TIMESTAMP_MODE,
    UCA_PROP_SCAN_MODE,

    /* 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_ASCII     0x01
#define UCA_TIMESTAMP_BINARY    0x02

/* Trigger mode for UCA_PROP_TRIGGER_MODE */
#define UCA_TRIGGER_AUTO        1   /**< free-run mode */
#define UCA_TRIGGER_SOFTWARE    2
#define UCA_TRIGGER_EXTERNAL    3

#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


/**
 * 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;

    /**
     * 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) */
    } 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.
     */
    enum uca_types {
        uca_uint32t,
        uca_uint8t,
        uca_string
    } type;

    /**
     * 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 */
    } access;
} uca_property_t;

union uca_value {
    uint32_t u32;
    uint8_t u8;
    char *string;
};

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_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_FRAME_TRANSFER  0x10000008
#define UCA_ERR_ALREADY_REGISTERED 0x10000009

/**
 * Keeps a list of cameras and grabbers.
 */
typedef struct uca {
    struct uca_camera *cameras;

    /* private */
    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
 */
enum uca_property_ids uca_get_property_id(const char *property_name);

/**
 * 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);

#define uca_set_void(p, type, value) { *((type *) p) = (type) value; }

#ifdef __cplusplus
}
#endif

#endif