summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Vogelgesang <matthias.vogelgesang@ipe.fzk.de>2011-02-28 11:09:43 +0100
committerMatthias Vogelgesang <matthias.vogelgesang@ipe.fzk.de>2011-02-28 11:09:43 +0100
commitf200da9c7915521f77c6c23e825181da73db474d (patch)
treee44d75bf6dc82284e7b089cc20b1a0e616e44356
parenta10b4d2abbb2aafbcb398f659975d673b0181e8c (diff)
downloaduca-f200da9c7915521f77c6c23e825181da73db474d.tar.gz
uca-f200da9c7915521f77c6c23e825181da73db474d.tar.bz2
uca-f200da9c7915521f77c6c23e825181da73db474d.tar.xz
uca-f200da9c7915521f77c6c23e825181da73db474d.zip
Add support for multiple cameras
-rw-r--r--src/cameras/uca_pco.c72
-rw-r--r--src/cameras/uca_pco.h4
-rw-r--r--src/uca.c89
-rw-r--r--src/uca.h68
-rw-r--r--test/test.c66
5 files changed, 162 insertions, 137 deletions
diff --git a/src/cameras/uca_pco.c b/src/cameras/uca_pco.c
index 33b09d6..8a89fa0 100644
--- a/src/cameras/uca_pco.c
+++ b/src/cameras/uca_pco.c
@@ -19,73 +19,73 @@ struct pco_cam_t {
#define set_void(p, type, value) { *((type *) p) = value; }
-static uint32_t uca_pco_set_bitdepth(struct uca_t *uca, uint8_t *bitdepth)
+static uint32_t uca_pco_set_bitdepth(struct uca_camera_t *cam, uint8_t *bitdepth)
{
/* TODO: it's not possible via CameraLink so do it via frame grabber */
return 0;
}
-static uint32_t uca_pco_set_exposure(struct uca_t *uca, uint32_t *exposure)
+static uint32_t uca_pco_set_exposure(struct uca_camera_t *cam, uint32_t *exposure)
{
uint32_t e, d;
- if (pco_get_delay_exposure(GET_PCO(uca), &d, &e) != PCO_NOERROR)
+ if (pco_get_delay_exposure(GET_PCO(cam), &d, &e) != PCO_NOERROR)
return UCA_ERR_PROP_GENERAL;
- if (pco_set_delay_exposure(GET_PCO(uca), d, *exposure) != PCO_NOERROR)
+ if (pco_set_delay_exposure(GET_PCO(cam), d, *exposure) != PCO_NOERROR)
return UCA_ERR_PROP_GENERAL;
return UCA_NO_ERROR;
}
-static uint32_t uca_pco_set_delay(struct uca_t *uca, uint32_t *delay)
+static uint32_t uca_pco_set_delay(struct uca_camera_t *cam, uint32_t *delay)
{
uint32_t e, d;
- if (pco_get_delay_exposure(GET_PCO(uca), &d, &e) != PCO_NOERROR)
+ if (pco_get_delay_exposure(GET_PCO(cam), &d, &e) != PCO_NOERROR)
return UCA_ERR_PROP_GENERAL;
- if (pco_set_delay_exposure(GET_PCO(uca), *delay, e) != PCO_NOERROR)
+ if (pco_set_delay_exposure(GET_PCO(cam), *delay, e) != PCO_NOERROR)
return UCA_ERR_PROP_GENERAL;
return UCA_NO_ERROR;
}
-static uint32_t uca_pco_acquire_image(struct uca_t *uca, void *buffer)
+static uint32_t uca_pco_acquire_image(struct uca_camera_t *cam, void *buffer)
{
return UCA_NO_ERROR;
}
-static uint32_t uca_pco_destroy(struct uca_t *uca)
+static uint32_t uca_pco_destroy(struct uca_camera_t *cam)
{
- Fg_FreeGrabber(GET_FG(uca));
- pco_destroy(GET_PCO(uca));
- free(uca->user);
+ Fg_FreeGrabber(GET_FG(cam));
+ pco_destroy(GET_PCO(cam));
+ free(cam->user);
return UCA_NO_ERROR;
}
-static uint32_t uca_pco_set_property(struct uca_t *uca, int32_t property, void *data)
+static uint32_t uca_pco_set_property(struct uca_camera_t *cam, int32_t property, void *data)
{
switch (property) {
case UCA_PROP_WIDTH:
- if (Fg_setParameter(GET_FG(uca), FG_WIDTH, (uint32_t *) data, PORT_A) != FG_OK)
+ if (Fg_setParameter(GET_FG(cam), FG_WIDTH, (uint32_t *) data, PORT_A) != FG_OK)
return UCA_ERR_PROP_VALUE_OUT_OF_RANGE;
break;
case UCA_PROP_HEIGHT:
- if (Fg_setParameter(GET_FG(uca), FG_HEIGHT, (uint32_t *) data, PORT_A) != FG_OK)
+ if (Fg_setParameter(GET_FG(cam), FG_HEIGHT, (uint32_t *) data, PORT_A) != FG_OK)
return UCA_ERR_PROP_VALUE_OUT_OF_RANGE;
break;
case UCA_PROP_X_OFFSET:
- if (Fg_setParameter(GET_FG(uca), FG_XOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
+ if (Fg_setParameter(GET_FG(cam), FG_XOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
return UCA_ERR_PROP_VALUE_OUT_OF_RANGE;
break;
case UCA_PROP_Y_OFFSET:
- if (Fg_setParameter(GET_FG(uca), FG_YOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
+ if (Fg_setParameter(GET_FG(cam), FG_YOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
return UCA_ERR_PROP_VALUE_OUT_OF_RANGE;
break;
case UCA_PROP_EXPOSURE:
- return uca_pco_set_exposure(uca, (uint32_t *) data);
+ return uca_pco_set_exposure(cam, (uint32_t *) data);
case UCA_PROP_DELAY:
- return uca_pco_set_delay(uca, (uint32_t *) data);
+ return uca_pco_set_delay(cam, (uint32_t *) data);
default:
return UCA_ERR_PROP_INVALID;
@@ -94,9 +94,9 @@ static uint32_t uca_pco_set_property(struct uca_t *uca, int32_t property, void *
}
-static uint32_t uca_pco_get_property(struct uca_t *uca, int32_t property, void *data)
+static uint32_t uca_pco_get_property(struct uca_camera_t *cam, int32_t property, void *data)
{
- struct pco_edge_t *pco = GET_PCO(uca);
+ struct pco_edge_t *pco = GET_PCO(cam);
switch (property) {
case UCA_PROP_NAME:
@@ -141,12 +141,12 @@ static uint32_t uca_pco_get_property(struct uca_t *uca, int32_t property, void *
break;
case UCA_PROP_X_OFFSET:
- if (Fg_getParameter(GET_FG(uca), FG_XOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
+ if (Fg_getParameter(GET_FG(cam), FG_XOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
return UCA_ERR_PROP_GENERAL;
break;
case UCA_PROP_Y_OFFSET:
- if (Fg_getParameter(GET_FG(uca), FG_YOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
+ if (Fg_getParameter(GET_FG(cam), FG_YOFFSET, (uint32_t *) data, PORT_A) != FG_OK)
return UCA_ERR_PROP_GENERAL;
break;
@@ -176,37 +176,39 @@ static uint32_t uca_pco_get_property(struct uca_t *uca, int32_t property, void *
return UCA_NO_ERROR;
}
-uint32_t uca_pco_alloc(struct uca_t *uca, uint32_t n_buffers)
+uint32_t uca_pco_alloc(struct uca_camera_t *cam, uint32_t n_buffers)
{
}
-uint32_t uca_pco_init(struct uca_t *uca)
+uint32_t uca_pco_init(struct uca_camera_t **cam)
{
- uca->user = (struct pco_cam_t *) malloc(sizeof(struct pco_cam_t));
-
- struct pco_cam_t *pco_cam = uca->user;
+ struct pco_cam_t *pco_cam = (struct pco_cam_t *) malloc(sizeof(struct pco_cam_t));
struct pco_edge_t *pco = pco_cam->pco = pco_init();
if (pco == NULL) {
- free(uca->user);
+ free(pco_cam);
return UCA_ERR_INIT_NOT_FOUND;
}
if ((pco->serial_ref == NULL) || !pco_active(pco)) {
- free(uca->user);
+ free(pco_cam);
pco_destroy(pco);
return UCA_ERR_INIT_NOT_FOUND;
}
Fg_Struct *fg = pco_cam->fg = Fg_Init("libFullAreaGray8.so", 0);
+ struct uca_camera_t *uca = (struct uca_camera_t *) malloc(sizeof(struct uca_camera_t));
+ uca->user = pco_cam;
+ *cam = uca;
+
/* Camera found, set function pointers... */
- uca->cam_destroy = &uca_pco_destroy;
- uca->cam_set_property = &uca_pco_set_property;
- uca->cam_get_property = &uca_pco_get_property;
- uca->cam_alloc = &uca_pco_alloc;
- uca->cam_acquire_image = &uca_pco_acquire_image;
+ uca->destroy = &uca_pco_destroy;
+ uca->set_property = &uca_pco_set_property;
+ uca->get_property = &uca_pco_get_property;
+ uca->alloc = &uca_pco_alloc;
+ uca->acquire_image = &uca_pco_acquire_image;
/* Prepare camera for recording */
pco_set_rec_state(pco, 0);
diff --git a/src/cameras/uca_pco.h b/src/cameras/uca_pco.h
index 07c3ef2..240e675 100644
--- a/src/cameras/uca_pco.h
+++ b/src/cameras/uca_pco.h
@@ -1,8 +1,8 @@
#ifndef __UNIFIED_CAMERA_ACCESS_PCO_H
#define __UNIFIED_CAMERA_ACCESS_PCO_H
-struct uca_t;
+struct uca_camera_t;
-uint32_t uca_pco_init(struct uca_t *uca);
+uint32_t uca_pco_init(struct uca_camera_t **uca);
#endif
diff --git a/src/uca.c b/src/uca.c
index 73dd79e..0e9e184 100644
--- a/src/uca.c
+++ b/src/uca.c
@@ -19,6 +19,7 @@
struct uca_t *uca_init()
{
struct uca_t *uca = (struct uca_t *) malloc(sizeof(struct uca_t));
+ uca->cameras = NULL;
uca_cam_init inits[] = {
#ifdef HAVE_PCO_EDGE
@@ -32,58 +33,70 @@ struct uca_t *uca_init()
#endif
NULL };
- /* Set all function pointers to NULL and thus make the class abstract */
- uca->cam_set_property = NULL;
- uca->cam_get_property = NULL;
- uca->cam_alloc = NULL;
- uca->cam_acquire_image = NULL;
-
int i = 0;
+ struct uca_camera_t* current = NULL;
+
while (inits[i] != NULL) {
+ struct uca_camera_t *cam = NULL;
uca_cam_init init = inits[i];
- if (init(uca) != UCA_ERR_INIT_NOT_FOUND)
- return uca;
+ if (init(&cam) != UCA_ERR_INIT_NOT_FOUND) {
+ if (current == NULL)
+ uca->cameras = current = cam;
+ else {
+ current->next = cam;
+ current = cam;
+ }
+ current->next = NULL;
+ }
i++;
}
- /* No camera found then indicate error */
- free(uca);
- return NULL;
+ if (uca->cameras == NULL) {
+ free(uca);
+ return NULL;
+ }
+ return uca;
}
void uca_destroy(struct uca_t *uca)
{
if (uca != NULL) {
- uca->cam_destroy(uca);
+ struct uca_camera_t *current = uca->cameras, *tmp;
+ while (current != NULL) {
+ tmp = current;
+ current->destroy(current);
+ current = current->next;
+ free(tmp);
+ }
free(uca);
}
}
-static struct uca_property_t property_map[UCA_PROP_LAST] = {
- { "name", uca_na, uca_string },
- { "width", uca_pixel, uca_uint32t },
- { "width.min", uca_pixel, uca_uint32t },
- { "width.max", uca_pixel, uca_uint32t },
- { "height", uca_pixel, uca_uint32t },
- { "height.min", uca_pixel, uca_uint32t },
- { "height.max", uca_pixel, uca_uint32t },
- { "offset.x", uca_pixel, uca_uint32t },
- { "offset.y", uca_pixel, uca_uint32t },
- { "bit-depth", uca_pixel, uca_uint8t },
- { "exposure", uca_us, uca_uint32t },
- { "exposure.min", uca_ns, uca_uint32t },
- { "exposure.max", uca_ms, uca_uint32t },
- { "delay", uca_us, uca_uint32t },
- { "delay.min", uca_ns, uca_uint32t },
- { "delay.max", uca_ms, uca_uint32t },
- { "frame-rate", uca_na, uca_uint32t },
- { "trigger-mode", uca_na, uca_uint32t },
- { "timestamp-mode", uca_na, uca_uint32t },
- { "scan-mode", uca_na, uca_uint32t },
- { "interlace.sample-rate", uca_na, uca_uint32t },
+static struct uca_property_t property_map[UCA_PROP_LAST+1] = {
+ { "name", uca_na, uca_string },
+ { "width", uca_pixel, uca_uint32t },
+ { "width.min", uca_pixel, uca_uint32t },
+ { "width.max", uca_pixel, uca_uint32t },
+ { "height", uca_pixel, uca_uint32t },
+ { "height.min", uca_pixel, uca_uint32t },
+ { "height.max", uca_pixel, uca_uint32t },
+ { "offset.x", uca_pixel, uca_uint32t },
+ { "offset.y", uca_pixel, uca_uint32t },
+ { "bitdepth", uca_bits, uca_uint8t },
+ { "exposure", uca_us, uca_uint32t },
+ { "exposure.min", uca_ns, uca_uint32t },
+ { "exposure.max", uca_ms, uca_uint32t },
+ { "delay", uca_us, uca_uint32t },
+ { "delay.min", uca_ns, uca_uint32t },
+ { "delay.max", uca_ms, uca_uint32t },
+ { "framerate", uca_na, uca_uint32t },
+ { "triggermode", uca_na, uca_uint32t },
+ { "timestampmode", uca_na, uca_uint32t },
+ { "scan-mode", uca_na, uca_uint32t },
+ { "interlace.samplerate", uca_na, uca_uint32t },
{ "interlace.threshold.pixel", uca_na, uca_uint32t },
{ "interlace.threshold.row", uca_na, uca_uint32t },
- { "correction-mode", uca_na, uca_uint32t },
+ { "correctionmode", uca_na, uca_uint32t },
{ NULL, 0, 0 }
};
@@ -96,7 +109,7 @@ int32_t uca_get_property_id(const char *property_name)
return i;
i++;
}
- return UCA_PROP_INVALID;
+ return UCA_ERR_PROP_INVALID;
}
struct uca_property_t *uca_get_full_property(int32_t property_id)
@@ -108,6 +121,6 @@ struct uca_property_t *uca_get_full_property(int32_t property_id)
const char* uca_get_property_name(int32_t property_id)
{
- /* TODO: guard that thing */
- return property_map[property_id].name;
+ if ((property_id >= 0) && (property_id < UCA_PROP_LAST))
+ return property_map[property_id].name;
}
diff --git a/src/uca.h b/src/uca.h
index bf0cc21..c067d9f 100644
--- a/src/uca.h
+++ b/src/uca.h
@@ -14,18 +14,19 @@
#include <stdint.h>
struct uca_t;
+struct uca_camera_t;
struct uca_property_t;
/**
* \brief Camera probing and initialization
* \return UCA_ERR_INIT_NOT_FOUND if camera is not found or could not be initialized
*/
-typedef uint32_t (*uca_cam_init) (struct uca_t *uca);
+typedef uint32_t (*uca_cam_init) (struct uca_camera_t **cam);
/**
* \brief Free camera resouces
*/
-typedef uint32_t (*uca_cam_destroy) (struct uca_t *uca);
+typedef uint32_t (*uca_cam_destroy) (struct uca_camera_t *cam);
/**
* \brief Set a property
@@ -33,31 +34,31 @@ typedef uint32_t (*uca_cam_destroy) (struct uca_t *uca);
* \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.
*/
-typedef uint32_t (*uca_cam_set_property) (struct uca_t *uca, int32_t property, void *data);
+typedef uint32_t (*uca_cam_set_property) (struct uca_camera_t *cam, int32_t property, void *data);
/**
* \brief Set a property
* \param[in] property_name Name of the property as defined in XXX
* \return UCA_ERR_PROP_INVALID if property is not supported on the camera
*/
-typedef uint32_t (*uca_cam_get_property) (struct uca_t *uca, int32_t property, void *data);
+typedef uint32_t (*uca_cam_get_property) (struct uca_camera_t *cam, int32_t property, void *data);
/** \brief Allocate number of buffers
*
* The size of each buffer is width x height x bits
*/
-typedef uint32_t (*uca_cam_alloc) (struct uca_t *uca, uint32_t n_buffers);
+typedef uint32_t (*uca_cam_alloc) (struct uca_camera_t *cam, uint32_t n_buffers);
/**
* \brief Acquire one frame
*/
-typedef uint32_t (*uca_cam_acquire_image) (struct uca_t *uca, void *buffer);
+typedef uint32_t (*uca_cam_acquire_image) (struct uca_camera_t *cam, void *buffer);
/**
* \brief Initialize the unified camera access interface
* \return Pointer to a uca_t structure
*/
-struct uca_t *uca_init();
+struct uca_t *uca_init(void);
/**
* \brief Free resources of the unified camera access interface
@@ -85,7 +86,6 @@ struct uca_property_t *uca_get_full_property(int32_t property_id);
/* 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! */
-#define UCA_PROP_INVALID -1
#define UCA_PROP_NAME 0
#define UCA_PROP_WIDTH 1
#define UCA_PROP_WIDTH_MIN 2
@@ -95,31 +95,29 @@ struct uca_property_t *uca_get_full_property(int32_t property_id);
#define UCA_PROP_HEIGHT_MAX 6
#define UCA_PROP_X_OFFSET 7
#define UCA_PROP_Y_OFFSET 8
-#define UCA_PROP_MAX_WIDTH 9
-#define UCA_PROP_MAX_HEIGHT 10
-#define UCA_PROP_BITDEPTH 11
-#define UCA_PROP_EXPOSURE 12
-#define UCA_PROP_EXPOSURE_MIN 13
-#define UCA_PROP_EXPOSURE_MAX 14
-#define UCA_PROP_DELAY 15
-#define UCA_PROP_DELAY_MIN 16
-#define UCA_PROP_DELAY_MAX 17
-#define UCA_PROP_FRAMERATE 18
-#define UCA_PROP_TRIGGER_MODE 19
+#define UCA_PROP_BITDEPTH 9
+#define UCA_PROP_EXPOSURE 10
+#define UCA_PROP_EXPOSURE_MIN 11
+#define UCA_PROP_EXPOSURE_MAX 12
+#define UCA_PROP_DELAY 13
+#define UCA_PROP_DELAY_MIN 14
+#define UCA_PROP_DELAY_MAX 15
+#define UCA_PROP_FRAMERATE 16
+#define UCA_PROP_TRIGGER_MODE 17
/* pco.edge specific */
-#define UCA_PROP_TIMESTAMP_MODE 20
-#define UCA_PROP_SCAN_MODE 21
+#define UCA_PROP_TIMESTAMP_MODE 18
+#define UCA_PROP_SCAN_MODE 19
/* IPE camera specific */
-#define UCA_PROP_INTERLACE_SAMPLE_RATE 22
-#define UCA_PROP_INTERLACE_PIXEL_THRESH 23
-#define UCA_PROP_INTERLACE_ROW_THRESH 24
+#define UCA_PROP_INTERLACE_SAMPLE_RATE 20
+#define UCA_PROP_INTERLACE_PIXEL_THRESH 21
+#define UCA_PROP_INTERLACE_ROW_THRESH 22
/* Photon Focus specific */
-#define UCA_PROP_CORRECTION_MODE 25
+#define UCA_PROP_CORRECTION_MODE 23
-#define UCA_PROP_LAST 26
+#define UCA_PROP_LAST 24
/* Possible timestamp modes for UCA_PROP_TIMESTAMP_MODE */
#define UCA_TIMESTAMP_ASCII 0x01
@@ -156,18 +154,24 @@ struct uca_property_t {
} type;
};
-struct uca_t {
+struct uca_camera_t {
+ struct uca_camera_t *next;
+
/* Function pointers to camera-specific methods */
- uca_cam_set_property cam_set_property;
- uca_cam_get_property cam_get_property;
- uca_cam_acquire_image cam_acquire_image;
- uca_cam_alloc cam_alloc;
+ uca_cam_set_property set_property;
+ uca_cam_get_property get_property;
+ uca_cam_acquire_image acquire_image;
+ uca_cam_alloc alloc;
/* Private */
- uca_cam_destroy cam_destroy;
+ uca_cam_destroy destroy;
void *user; /**< private user data to be used by the camera driver */
};
+struct uca_t {
+ struct uca_camera_t *cameras;
+};
+
#endif
diff --git a/test/test.c b/test/test.c
index 0f5b6fe..e3d07ff 100644
--- a/test/test.c
+++ b/test/test.c
@@ -26,44 +26,50 @@ int main(int argc, char *argv[])
return 1;
}
+ /* take first camera */
+ struct uca_camera_t *cam = uca->cameras;
+
char string_value[256];
uint32_t uint32_value;
uint8_t uint8_value;
const char *unit_map[] = {
- "px",
- "bits",
- "ns",
- "µs",
- "ms",
- "s",
- "rows",
- ""
+ "px", "bits",
+ "ns", "µs", "ms", "s",
+ "rows", ""
};
- for (int i = 0; i < UCA_PROP_LAST-2; i++) {
- struct uca_property_t *prop = uca_get_full_property(i);
- switch (prop->type) {
- case uca_string:
- if (uca->cam_get_property(uca, i, string_value) != UCA_PROP_INVALID) {
- print_level(count_dots(prop->name));
- printf("%s = %s %s ", prop->name, string_value, unit_map[prop->unit]);
- }
- break;
- case uca_uint32t:
- if (uca->cam_get_property(uca, i, &uint32_value) != UCA_PROP_INVALID) {
- print_level(count_dots(prop->name));
- printf("%s = %i %s ", prop->name, uint32_value, unit_map[prop->unit]);
- }
- break;
- case uca_uint8t:
- if (uca->cam_get_property(uca, i, &uint8_value) != UCA_PROP_INVALID) {
- print_level(count_dots(prop->name));
- printf("%s = %i %s ", prop->name, uint8_value, unit_map[prop->unit]);
- }
- break;
+ while (cam != NULL) {
+ for (int i = 0; i < UCA_PROP_LAST; i++) {
+ struct uca_property_t *prop = uca_get_full_property(i);
+ print_level(count_dots(prop->name));
+ printf("%s = ", prop->name);
+ switch (prop->type) {
+ case uca_string:
+ if (cam->get_property(cam, i, string_value) != UCA_ERR_PROP_INVALID) {
+ printf("%s ", string_value);
+ }
+ else
+ printf("n/a");
+ break;
+ case uca_uint32t:
+ if (cam->get_property(cam, i, &uint32_value) != UCA_ERR_PROP_INVALID) {
+ printf("%i %s", uint32_value, unit_map[prop->unit]);
+ }
+ else
+ printf("n/a");
+ break;
+ case uca_uint8t:
+ if (cam->get_property(cam, i, &uint8_value) != UCA_ERR_PROP_INVALID) {
+ printf("%i %s", uint8_value, unit_map[prop->unit]);
+ }
+ else
+ printf("n/a");
+ break;
+ }
+ printf("\n");
}
- printf("\n");
+ cam = cam->next;
}
uca_destroy(uca);