diff options
-rw-r--r-- | src/cameras/uca_pco.c | 94 | ||||
-rw-r--r-- | src/uca.c | 39 | ||||
-rw-r--r-- | src/uca.h | 76 | ||||
-rw-r--r-- | test/test.c | 9 |
4 files changed, 147 insertions, 71 deletions
diff --git a/src/cameras/uca_pco.c b/src/cameras/uca_pco.c index 7de8955..44ecf95 100644 --- a/src/cameras/uca_pco.c +++ b/src/cameras/uca_pco.c @@ -17,14 +17,6 @@ struct pco_cam_t { #define GET_FG(uca) (((struct pco_cam_t *)(uca->user))->fg) -static uint32_t uca_pco_set_dimensions(struct uca_t *uca, uint32_t *width, uint32_t *height) -{ - Fg_Struct *fg = GET_FG(uca); - Fg_setParameter(fg, FG_WIDTH, width, PORT_A); - Fg_setParameter(fg, FG_HEIGHT, height, PORT_A); - return 0; -} - static uint32_t uca_pco_set_bitdepth(struct uca_t *uca, uint8_t *bitdepth) { /* TODO: it's not possible via CameraLink so do it via frame grabber */ @@ -57,7 +49,64 @@ static uint32_t uca_pco_destroy(struct uca_t *uca) Fg_FreeGrabber(GET_FG(uca)); pco_destroy(GET_PCO(uca)); free(uca->user); - free(uca->camera_name); +} + +static uint32_t uca_pco_set_property(struct uca_t *uca, int32_t property, void *data) +{ + switch (property) { + case UCA_PROP_WIDTH: + Fg_setParameter(GET_FG(uca), FG_WIDTH, (uint32_t *) data, PORT_A); + break; + + case UCA_PROP_HEIGHT: + Fg_setParameter(GET_FG(uca), FG_HEIGHT, (uint32_t *) data, PORT_A); + break; + + case UCA_PROP_EXPOSURE: + uca_pco_set_exposure(uca, (uint32_t *) data); + break; + + case UCA_PROP_FRAMERATE: + break; + + default: + break; + } + return 0; +} + +static uint32_t uca_pco_get_property(struct uca_t *uca, int32_t property, void *data) +{ + struct pco_edge_t *pco = GET_PCO(uca); + + switch (property) { + /* FIXME: how to ensure, that data is large enough? */ + case UCA_PROP_NAME: + { + SC2_Camera_Name_Response name; + if (pco_read_property(pco, GET_CAMERA_NAME, &name, sizeof(name)) == PCO_NOERROR) + strcpy((char *) data, name.szName); + } + break; + + case UCA_PROP_MAX_WIDTH: + { + uint32_t w, h; + pco_get_actual_size(pco, &w, &h); + *((uint32_t *) data) = w; + } + + case UCA_PROP_MAX_HEIGHT: + { + int w, h; + pco_get_actual_size(pco, &w, &h); + *((uint32_t *) data) = h; + } + + default: + break; + } + return 0; } uint32_t uca_pco_init(struct uca_t *uca) @@ -78,25 +127,19 @@ uint32_t uca_pco_init(struct uca_t *uca) /* Camera found, set function pointers... */ uca->cam_destroy = &uca_pco_destroy; - uca->cam_set_dimensions = &uca_pco_set_dimensions; - uca->cam_set_bitdepth = &uca_pco_set_bitdepth; - uca->cam_set_exposure = &uca_pco_set_exposure; - uca->cam_set_delay = &uca_pco_set_delay; + uca->cam_set_property = &uca_pco_set_property; + uca->cam_get_property = &uca_pco_get_property; uca->cam_acquire_image = &uca_pco_acquire_image; - /* ... and some properties */ - pco_get_actual_size(pco, &uca->image_width, &uca->image_height); - - SC2_Camera_Name_Response name; - if (pco_read_property(pco, GET_CAMERA_NAME, &name, sizeof(name)) == PCO_NOERROR) - uca->camera_name = strdup(name.szName); - /* Prepare camera for recording */ pco_set_rec_state(pco, 0); pco_set_timestamp_mode(pco, 2); pco_set_timebase(pco, 1, 1); pco_arm_camera(pco); + if (pco->transfer.DataFormat != (SCCMOS_FORMAT_TOP_CENTER_BOTTOM_CENTER | PCO_CL_DATAFORMAT_5x16)) + pco->transfer.DataFormat = SCCMOS_FORMAT_TOP_CENTER_BOTTOM_CENTER | PCO_CL_DATAFORMAT_5x16; + /* Prepare frame grabber for recording */ int val = FG_CL_8BIT_FULL_10; Fg_setParameter(fg, FG_CAMERA_LINK_CAMTYP, &val, PORT_A); @@ -107,8 +150,15 @@ uint32_t uca_pco_init(struct uca_t *uca) val = FREE_RUN; Fg_setParameter(fg, FG_TRIGGERMODE, &val, PORT_A); - Fg_setParameter(fg, FG_WIDTH, &uca->image_width, PORT_A); - Fg_setParameter(fg, FG_HEIGHT, &uca->image_height, PORT_A); + int width, height; + pco_get_actual_size(pco, &width, &height); + + /* Yes, we really have to take an image twice as large because we set the + * CameraLink interface to 8-bit 10 Taps, but are actually using 5x16 bits. */ + width *= 2; + height *= 2; + Fg_setParameter(fg, FG_WIDTH, &width, PORT_A); + Fg_setParameter(fg, FG_HEIGHT, &height, PORT_A); pco_set_rec_state(pco, 1); @@ -31,14 +31,8 @@ struct uca_t *uca_init() NULL }; /* Set all function pointers to NULL and thus make the class abstract */ - uca->cam_destroy = NULL; - uca->cam_set_dimensions = NULL; - uca->cam_set_bitdepth = NULL; - uca->cam_set_delay = NULL; - uca->cam_set_exposure = NULL; - uca->cam_acquire_image = NULL; - - uca->camera_name = NULL; + uca->cam_set_property = NULL; + uca->cam_get_property = NULL; int i = 0; while (inits[i] != NULL) { @@ -60,3 +54,32 @@ void uca_destroy(struct uca_t *uca) free(uca); } } + +static const char* property_map[] = { + "name", + "width", + "height", + "max-width", + "max-height", + "bit-depth", + "exposure", + "frame-rate", + NULL +}; + +int32_t uca_get_property_id(const char *property_name) +{ + char *name; + int i = 0; + while (property_map[i] != NULL) { + if (!strcmp(property_map[i], property_name)) + return i; + } + return UCA_PROP_INVALID; +} + +const char* uca_get_property_name(int32_t property_id) +{ + /* TODO: guard that thing */ + return property_map[property_id]; +} @@ -27,70 +27,70 @@ typedef uint32_t (*uca_cam_init) (struct uca_t *uca); typedef uint32_t (*uca_cam_destroy) (struct uca_t *uca); /** - * \brief Set dimension of grabbed images - * \param[in] width Width of the image - * \param[in] height Height of the image - * \note input parameters might be changed if dimensions couldn't be set + * \brief Set a property + * \param[in] property_name Name of the property as defined in XXX */ -typedef uint32_t (*uca_cam_set_dimensions) (struct uca_t *uca, uint32_t *width, uint32_t *height); +typedef uint32_t (*uca_cam_set_property) (struct uca_t *uca, int32_t property, void *data); /** - * \brief Set bitdepth of grabbed images + * \brief Set a property + * \param[in] property_name Name of the property as defined in XXX */ -typedef uint32_t (*uca_cam_set_bitdepth) (struct uca_t *uca, uint8_t *bitdepth); +typedef uint32_t (*uca_cam_get_property) (struct uca_t *uca, int32_t property, void *data); /** - * \brief Set exposure time in milliseconds + * \brief Acquire one frame */ -typedef uint32_t (*uca_cam_set_exposure) (struct uca_t *uca, uint32_t *exposure); +typedef uint32_t (*uca_cam_acquire_image) (struct uca_t *uca, void *buffer); /** - * \brief Set delay time in milliseconds + * \brief Initialize the unified camera access interface + * \return Pointer to a uca_t structure */ -typedef uint32_t (*uca_cam_set_delay) (struct uca_t *uca, uint32_t *delay); +struct uca_t *uca_init(); /** - * \brief Acquire one frame + * \brief Free resources of the unified camera access interface */ -typedef uint32_t (*uca_cam_acquire_image) (struct uca_t *uca, void *buffer); - - -#define UCA_NO_ERROR 0 +void uca_destroy(struct uca_t *uca); -#define UCA_ERR_INIT_NOT_FOUND 1 /**< camera probing or initialization failed */ +/** + * \brief Convert a property string to the corresponding ID + */ +int32_t uca_get_property_id(const char *property_name); -#define UCA_ERR_DIMENSION_NOT_SUPPORTED 1 +/** + * \brief Convert a property ID to the corresponding string + */ +const char* uca_get_property_name(int32_t property_id); -#define UCA_ERR_BITDEPTH_NOT_SUPPORTED 1 -#define UCA_BIG_ENDIAN 1 -#define UCA_LITTLE_ENDIAN 2 +#define UCA_NO_ERROR 0 +#define UCA_ERR_INIT_NOT_FOUND 1 /**< camera probing or initialization failed */ +#define UCA_ERR_PROP_INVALID 2 + +/* The property IDs must start with 0 and be continuous */ +#define UCA_PROP_INVALID -1 +#define UCA_PROP_NAME 0 +#define UCA_PROP_WIDTH 1 +#define UCA_PROP_HEIGHT 2 +#define UCA_PROP_MAX_WIDTH 3 +#define UCA_PROP_MAX_HEIGHT 4 +#define UCA_PROP_BITDEPTH 5 +#define UCA_PROP_EXPOSURE 6 +#define UCA_PROP_FRAMERATE 7 struct uca_t { - /* These must be set by uca_*_init() */ - unsigned int image_width; - unsigned int image_height; - unsigned int image_bitdepth; - unsigned int image_flags; - - char *camera_name; - /* Function pointers to camera-specific methods */ - uca_cam_set_dimensions cam_set_dimensions; - uca_cam_set_bitdepth cam_set_bitdepth; - uca_cam_set_exposure cam_set_exposure; - uca_cam_set_delay cam_set_delay; - + uca_cam_set_property cam_set_property; + uca_cam_get_property cam_get_property; uca_cam_acquire_image cam_acquire_image; /* Private */ - uca_cam_destroy cam_destroy; + uca_cam_destroy cam_destroy; void *user; /**< private user data to be used by the camera driver */ }; -struct uca_t *uca_init(); -void uca_destroy(struct uca_t *uca); - #endif diff --git a/test/test.c b/test/test.c index 87e1b21..84df874 100644 --- a/test/test.c +++ b/test/test.c @@ -12,10 +12,13 @@ int main(int argc, char *argv[]) uint32_t width = 2560, height = 2160; - uca->cam_set_dimensions(uca, &width, &height); + uca->cam_set_property(uca, UCA_PROP_WIDTH, &width); + uca->cam_set_property(uca, UCA_PROP_HEIGHT, &height); - if (uca->camera_name != NULL) - printf("Camera name: %s\n", uca->camera_name); + char camera_name[256] = "foobar"; + uca->cam_get_property(uca, UCA_PROP_NAME, camera_name); + + printf("Camera name: %s\n", camera_name); uca_destroy(uca); return 0; |