From f588f10b6fc6e452d42a66abc56028fe21cd56c2 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Mon, 28 Feb 2011 14:26:32 +0100 Subject: Prepare for frame grabber abstraction --- src/CMakeLists.txt | 31 +++++-- src/cameras/pco.c | 245 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/cameras/pco.h | 8 ++ src/cameras/uca_pco.c | 244 ------------------------------------------------- src/cameras/uca_pco.h | 8 -- src/config.h.in | 3 +- src/grabbers/me4.c | 0 src/grabbers/me4.h | 0 src/uca-cam.c | 62 +++++++++++++ src/uca-cam.h | 172 +++++++++++++++++++++++++++++++++++ src/uca-grabber.c | 0 src/uca-grabber.h | 46 ++++++++++ src/uca.c | 71 +++------------ src/uca.h | 153 +------------------------------ test/test.c | 1 + 15 files changed, 570 insertions(+), 474 deletions(-) create mode 100644 src/cameras/pco.c create mode 100644 src/cameras/pco.h delete mode 100644 src/cameras/uca_pco.c delete mode 100644 src/cameras/uca_pco.h create mode 100644 src/grabbers/me4.c create mode 100644 src/grabbers/me4.h create mode 100644 src/uca-cam.c create mode 100644 src/uca-cam.h create mode 100644 src/uca-grabber.c create mode 100644 src/uca-grabber.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d319ac3..e863137 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,10 +3,12 @@ cmake_minimum_required(VERSION 2.8) # --- Set sources ------------------------------------------------------------- set(uca_SRCS uca.c + uca-cam.c ) set(uca_HDRS uca.h + uca-cam.h ) set(uca_LIBS "") @@ -21,32 +23,45 @@ find_package(PCO) find_package(FgLib5) find_package(ClSerMe4) -# --- Add sources if camera access sources are available ---------------------- -if(PCO_FOUND AND CLSERME4_FOUND AND FGLIB5_FOUND) +# --- Add sources if camera/framegrabber access sources are available --------- +if(PCO_FOUND) set(HAVE_PCO_EDGE TRUE) set(uca_SRCS ${uca_SRCS} - cameras/uca_pco.c + cameras/pco.c ) set(uca_LIBS ${uca_LIBS} - ${CLSERME4_LIBRARY} - ${FGLIB5_LIBRARY} ${PCO_LIBRARIES} ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} - ${CLSERME4_INCLUDE_DIR} - ${FGLIB5_INCLUDE_DIR} ${PCO_INCLUDE_DIRS} ) endif() if(CLSERME4_FOUND AND FGLIB5_FOUND) - set(HAVE_ME4_FRAMEGRABBER TRUE) + set(HAVE_ME4 TRUE) + + set(uca_SRCS + ${uca_SRCS} + grabbers/me4.c + ) + + set(uca_LIBS + ${uca_LIBS} + ${CLSERME4_LIBRARY} + ${FGLIB5_LIBRARY} + ) + + include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CLSERME4_INCLUDE_DIR} + ${FGLIB5_INCLUDE_DIR} + ) endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in diff --git a/src/cameras/pco.c b/src/cameras/pco.c new file mode 100644 index 0000000..88f1e23 --- /dev/null +++ b/src/cameras/pco.c @@ -0,0 +1,245 @@ + +#include +#include +#include +#include +#include +#include +#include "uca.h" +#include "uca-cam.h" +#include "pco.h" + +struct pco_cam_t { + struct pco_edge_t *pco; + Fg_Struct *fg; +}; + +#define GET_PCO(uca) (((struct pco_cam_t *)(uca->user))->pco) +#define GET_FG(uca) (((struct pco_cam_t *)(uca->user))->fg) + +#define set_void(p, type, value) { *((type *) p) = value; } + + +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_camera_t *cam, uint32_t *exposure) +{ + uint32_t e, d; + if (pco_get_delay_exposure(GET_PCO(cam), &d, &e) != PCO_NOERROR) + return UCA_ERR_PROP_GENERAL; + 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_camera_t *cam, uint32_t *delay) +{ + uint32_t e, d; + if (pco_get_delay_exposure(GET_PCO(cam), &d, &e) != PCO_NOERROR) + return UCA_ERR_PROP_GENERAL; + 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_camera_t *cam, void *buffer) +{ + return UCA_NO_ERROR; +} + +static uint32_t uca_pco_destroy(struct uca_camera_t *cam) +{ + 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_camera_t *cam, enum uca_property_ids property, void *data) +{ + switch (property) { + case UCA_PROP_WIDTH: + 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(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(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(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(cam, (uint32_t *) data); + + case UCA_PROP_DELAY: + return uca_pco_set_delay(cam, (uint32_t *) data); + + default: + return UCA_ERR_PROP_INVALID; + } + return UCA_NO_ERROR; +} + + +static uint32_t uca_pco_get_property(struct uca_camera_t *cam, enum uca_property_ids property, void *data) +{ + struct pco_edge_t *pco = GET_PCO(cam); + + switch (property) { + case UCA_PROP_NAME: + { + /* FIXME: how to ensure, that buffer is large enough? */ + 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_WIDTH: + { + int w, h; + if (pco_get_actual_size(pco, &w, &h) == PCO_NOERROR) + set_void(data, uint32_t, w); + } + break; + + case UCA_PROP_WIDTH_MIN: + set_void(data, uint32_t, 1); + break; + + case UCA_PROP_WIDTH_MAX: + set_void(data, uint32_t, pco->description.wMaxHorzResStdDESC); + break; + + case UCA_PROP_HEIGHT: + { + int w, h; + if (pco_get_actual_size(pco, &w, &h) == PCO_NOERROR) + set_void(data, uint32_t, h); + } + break; + + case UCA_PROP_HEIGHT_MIN: + set_void(data, uint32_t, 1); + break; + + case UCA_PROP_HEIGHT_MAX: + set_void(data, uint32_t, pco->description.wMaxVertResStdDESC); + break; + + case UCA_PROP_X_OFFSET: + 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(cam), FG_YOFFSET, (uint32_t *) data, PORT_A) != FG_OK) + return UCA_ERR_PROP_GENERAL; + break; + + case UCA_PROP_DELAY_MIN: + set_void(data, uint32_t, pco->description.dwMinDelayDESC); + break; + + case UCA_PROP_DELAY_MAX: + set_void(data, uint32_t, pco->description.dwMaxDelayDESC); + break; + + case UCA_PROP_EXPOSURE_MIN: + set_void(data, uint32_t, pco->description.dwMinExposureDESC); + break; + + case UCA_PROP_EXPOSURE_MAX: + set_void(data, uint32_t, pco->description.dwMaxExposureDESC); + break; + + case UCA_PROP_BITDEPTH: + set_void(data, uint8_t, 16); + break; + + default: + return UCA_ERR_PROP_INVALID; + } + return UCA_NO_ERROR; +} + +uint32_t uca_pco_alloc(struct uca_camera_t *cam, uint32_t n_buffers) +{ + +} + +uint32_t uca_pco_init(struct uca_camera_t **cam) +{ + 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(pco_cam); + return UCA_ERR_INIT_NOT_FOUND; + } + + if ((pco->serial_ref == NULL) || !pco_active(pco)) { + 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; + + /* Camera found, set function pointers... */ + 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); + 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); + + val = FG_GRAY; + Fg_setParameter(fg, FG_FORMAT, &val, PORT_A); + + val = FREE_RUN; + Fg_setParameter(fg, FG_TRIGGERMODE, &val, 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; + Fg_setParameter(fg, FG_WIDTH, &width, PORT_A); + Fg_setParameter(fg, FG_HEIGHT, &height, PORT_A); + + uca->state = UCA_CAM_CONFIGURABLE; + *cam = uca; + + return UCA_NO_ERROR; +} diff --git a/src/cameras/pco.h b/src/cameras/pco.h new file mode 100644 index 0000000..240e675 --- /dev/null +++ b/src/cameras/pco.h @@ -0,0 +1,8 @@ +#ifndef __UNIFIED_CAMERA_ACCESS_PCO_H +#define __UNIFIED_CAMERA_ACCESS_PCO_H + +struct uca_camera_t; + +uint32_t uca_pco_init(struct uca_camera_t **uca); + +#endif diff --git a/src/cameras/uca_pco.c b/src/cameras/uca_pco.c deleted file mode 100644 index cd727b9..0000000 --- a/src/cameras/uca_pco.c +++ /dev/null @@ -1,244 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include "uca.h" -#include "uca_pco.h" - -struct pco_cam_t { - struct pco_edge_t *pco; - Fg_Struct *fg; -}; - -#define GET_PCO(uca) (((struct pco_cam_t *)(uca->user))->pco) -#define GET_FG(uca) (((struct pco_cam_t *)(uca->user))->fg) - -#define set_void(p, type, value) { *((type *) p) = value; } - - -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_camera_t *cam, uint32_t *exposure) -{ - uint32_t e, d; - if (pco_get_delay_exposure(GET_PCO(cam), &d, &e) != PCO_NOERROR) - return UCA_ERR_PROP_GENERAL; - 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_camera_t *cam, uint32_t *delay) -{ - uint32_t e, d; - if (pco_get_delay_exposure(GET_PCO(cam), &d, &e) != PCO_NOERROR) - return UCA_ERR_PROP_GENERAL; - 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_camera_t *cam, void *buffer) -{ - return UCA_NO_ERROR; -} - -static uint32_t uca_pco_destroy(struct uca_camera_t *cam) -{ - 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_camera_t *cam, enum uca_property_ids property, void *data) -{ - switch (property) { - case UCA_PROP_WIDTH: - 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(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(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(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(cam, (uint32_t *) data); - - case UCA_PROP_DELAY: - return uca_pco_set_delay(cam, (uint32_t *) data); - - default: - return UCA_ERR_PROP_INVALID; - } - return UCA_NO_ERROR; -} - - -static uint32_t uca_pco_get_property(struct uca_camera_t *cam, enum uca_property_ids property, void *data) -{ - struct pco_edge_t *pco = GET_PCO(cam); - - switch (property) { - case UCA_PROP_NAME: - { - /* FIXME: how to ensure, that buffer is large enough? */ - 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_WIDTH: - { - int w, h; - if (pco_get_actual_size(pco, &w, &h) == PCO_NOERROR) - set_void(data, uint32_t, w); - } - break; - - case UCA_PROP_WIDTH_MIN: - set_void(data, uint32_t, 1); - break; - - case UCA_PROP_WIDTH_MAX: - set_void(data, uint32_t, pco->description.wMaxHorzResStdDESC); - break; - - case UCA_PROP_HEIGHT: - { - int w, h; - if (pco_get_actual_size(pco, &w, &h) == PCO_NOERROR) - set_void(data, uint32_t, h); - } - break; - - case UCA_PROP_HEIGHT_MIN: - set_void(data, uint32_t, 1); - break; - - case UCA_PROP_HEIGHT_MAX: - set_void(data, uint32_t, pco->description.wMaxVertResStdDESC); - break; - - case UCA_PROP_X_OFFSET: - 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(cam), FG_YOFFSET, (uint32_t *) data, PORT_A) != FG_OK) - return UCA_ERR_PROP_GENERAL; - break; - - case UCA_PROP_DELAY_MIN: - set_void(data, uint32_t, pco->description.dwMinDelayDESC); - break; - - case UCA_PROP_DELAY_MAX: - set_void(data, uint32_t, pco->description.dwMaxDelayDESC); - break; - - case UCA_PROP_EXPOSURE_MIN: - set_void(data, uint32_t, pco->description.dwMinExposureDESC); - break; - - case UCA_PROP_EXPOSURE_MAX: - set_void(data, uint32_t, pco->description.dwMaxExposureDESC); - break; - - case UCA_PROP_BITDEPTH: - set_void(data, uint8_t, 16); - break; - - default: - return UCA_ERR_PROP_INVALID; - } - return UCA_NO_ERROR; -} - -uint32_t uca_pco_alloc(struct uca_camera_t *cam, uint32_t n_buffers) -{ - -} - -uint32_t uca_pco_init(struct uca_camera_t **cam) -{ - 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(pco_cam); - return UCA_ERR_INIT_NOT_FOUND; - } - - if ((pco->serial_ref == NULL) || !pco_active(pco)) { - 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; - - /* Camera found, set function pointers... */ - 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); - 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); - - val = FG_GRAY; - Fg_setParameter(fg, FG_FORMAT, &val, PORT_A); - - val = FREE_RUN; - Fg_setParameter(fg, FG_TRIGGERMODE, &val, 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; - Fg_setParameter(fg, FG_WIDTH, &width, PORT_A); - Fg_setParameter(fg, FG_HEIGHT, &height, PORT_A); - - uca->state = UCA_CAM_CONFIGURABLE; - *cam = uca; - - return UCA_NO_ERROR; -} diff --git a/src/cameras/uca_pco.h b/src/cameras/uca_pco.h deleted file mode 100644 index 240e675..0000000 --- a/src/cameras/uca_pco.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __UNIFIED_CAMERA_ACCESS_PCO_H -#define __UNIFIED_CAMERA_ACCESS_PCO_H - -struct uca_camera_t; - -uint32_t uca_pco_init(struct uca_camera_t **uca); - -#endif diff --git a/src/config.h.in b/src/config.h.in index 301b731..5bd20c1 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -1,5 +1,6 @@ -#cmakedefine HAVE_ME4_FRAMEGRABBER +#cmakedefine HAVE_ME4 + #cmakedefine HAVE_PCO_EDGE #cmakedefine HAVE_PHOTON_FOCUS #cmakedefine HAVE_PHOTRON_FASTCAM diff --git a/src/grabbers/me4.c b/src/grabbers/me4.c new file mode 100644 index 0000000..e69de29 diff --git a/src/grabbers/me4.h b/src/grabbers/me4.h new file mode 100644 index 0000000..e69de29 diff --git a/src/uca-cam.c b/src/uca-cam.c new file mode 100644 index 0000000..a51a5ae --- /dev/null +++ b/src/uca-cam.c @@ -0,0 +1,62 @@ + +#include +#include "uca.h" +#include "uca-cam.h" + +enum uca_cam_state uca_get_camera_state(struct uca_camera_t *cam) +{ + return cam->state; +} + +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 }, + { "correctionmode", uca_na, uca_uint32t }, + { NULL, 0, 0 } +}; + +enum uca_property_ids uca_get_property_id(const char *property_name) +{ + char *name; + int i = 0; + while (property_map[i].name != NULL) { + if (!strcmp(property_map[i].name, property_name)) + return i; + i++; + } + return UCA_ERR_PROP_INVALID; +} + +struct uca_property_t *uca_get_full_property(enum uca_property_ids property_id) +{ + if ((property_id >= 0) && (property_id < UCA_PROP_LAST)) + return &property_map[property_id]; + return NULL; +} + +const char* uca_get_property_name(enum uca_property_ids property_id) +{ + if ((property_id >= 0) && (property_id < UCA_PROP_LAST)) + return property_map[property_id].name; +} diff --git a/src/uca-cam.h b/src/uca-cam.h new file mode 100644 index 0000000..99ed5f2 --- /dev/null +++ b/src/uca-cam.h @@ -0,0 +1,172 @@ +#ifndef __UNIFIED_CAMERA_ACCESS_CAM_H +#define __UNIFIED_CAMERA_ACCESS_CAM_H + +#include + +struct uca_camera_t; +struct uca_property_t; + +enum uca_property_ids; + +/* + * --- non-virtual methods ---------------------------------------------------- + */ +enum uca_cam_state uca_get_camera_state(struct uca_camera_t *cam); + + +/* + * --- virtual methods -------------------------------------------------------- + */ + +/** + * \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_camera_t **cam); + +/** + * \brief Free camera resouces + */ +typedef uint32_t (*uca_cam_destroy) (struct uca_camera_t *cam); + +/** + * \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 or + * UCA_ERR_PROP_VALUE_OUT_OF_RANGE if value cannot be set. + */ +typedef uint32_t (*uca_cam_set_property) (struct uca_camera_t *cam, enum uca_property_ids 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_camera_t *cam, enum uca_property_ids 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_camera_t *cam, uint32_t n_buffers); + +/** + * \brief Acquire one frame + */ +typedef uint32_t (*uca_cam_acquire_image) (struct uca_camera_t *cam, void *buffer); + +/** + * \brief Convert a property string to the corresponding ID + */ +enum uca_property_ids uca_get_property_id(const char *property_name); + +/** + * \brief Convert a property ID to the corresponding string + */ +const char* uca_get_property_name(enum uca_property_ids property_id); + +/** + * \brief Return the full property structure for a given ID + */ +struct uca_property_t *uca_get_full_property(enum uca_property_ids 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! */ +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_Y_OFFSET, + 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_TRIGGER_MODE, + + /* 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_TRIGGERMODE */ +#define UCA_TRIGGER_AUTO 1 +#define UCA_TRIGGER_INTERNAL 2 +#define UCA_TRIGGER_EXTERNAL 3 + +/* Correction modes for UCA_PROP_CORRECTION_MODE */ +#define UCA_CORRECT_OFFSET 0x01 +#define UCA_CORRECT_HOTPIXEL 0x02 +#define UCA_CORRECT_GAIN 0x04 + +/** + * \brief Describe a camera property + */ +struct uca_property_t { + const char *name; + + enum uca_unit { + uca_pixel, + uca_bits, + uca_ns, + uca_us, + uca_ms, + uca_s, + uca_rows, + uca_na + } unit; + + enum uca_types { + uca_uint32t, + uca_uint8t, + uca_string + } type; +}; + +enum uca_cam_state { + UCA_CAM_ERROR, + UCA_CAM_CONFIGURABLE, + UCA_CAM_ARMED, + UCA_CAM_RECORDING, +}; + +struct uca_camera_t { + struct uca_camera_t *next; + + /* Function pointers to camera-specific methods */ + 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 destroy; + enum uca_cam_state state; + + void *user; /**< private user data to be used by the camera driver */ +}; + +#endif diff --git a/src/uca-grabber.c b/src/uca-grabber.c new file mode 100644 index 0000000..e69de29 diff --git a/src/uca-grabber.h b/src/uca-grabber.h new file mode 100644 index 0000000..b01f453 --- /dev/null +++ b/src/uca-grabber.h @@ -0,0 +1,46 @@ +#ifndef __UNIFIED_CAMERA_ACCESS_GRABBER_H +#define __UNIFIED_CAMERA_ACCESS_GRABBER_H + +/* + * --- virtual methods -------------------------------------------------------- + */ + +/** + * \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_grabber_init) (struct uca_grabber_t **grabber); + +/** + * \brief Free camera resouces + */ +typedef uint32_t (*uca_grabber_destroy) (struct uca_grabber_t *grabber); + +/** + * \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 or + * UCA_ERR_PROP_VALUE_OUT_OF_RANGE if value cannot be set. + */ +typedef uint32_t (*uca_grabber_set_property) (struct uca_grabber_t *grabber, enum uca_property_ids 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_grabber_get_property) (struct uca_grabber_t *grabber, enum uca_property_ids property, void *data); + + +struct uca_grabber_t { + struct uca_grabber_t *next; + + /* Function pointers to grabber-specific methods */ + uca_grabber_set_property set_property; + uca_grabber_get_property get_property; + + /* Private */ + void *user; +}; + +#endif diff --git a/src/uca.c b/src/uca.c index f86864c..1d0a515 100644 --- a/src/uca.c +++ b/src/uca.c @@ -2,21 +2,27 @@ #include "config.h" #include "uca.h" +#include "uca-cam.h" +#include "uca-grabber.h" + +#ifdef HAVE_ME4 +#include "grabbers/me4.h" +#endif #ifdef HAVE_PCO_EDGE -#include "cameras/uca_pco.h" +#include "cameras/pco.h" #endif #ifdef HAVE_PHOTON_FOCUS -#include "cameras/uca_pf.h" +#include "cameras/pf.h" #endif #ifdef HAVE_IPE_CAM -#include "cameras/uca_ipe.h" +#include "cameras/ipe.h" #endif #ifdef HAVE_PHOTRON_FASTCAM -#include "cameras/uca_photron.h" +#include "cameras/photron.h" #endif @@ -79,60 +85,3 @@ void uca_destroy(struct uca_t *uca) } } -enum uca_cam_state uca_get_camera_state(struct uca_camera_t *cam) -{ - return cam->state; -} - -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 }, - { "correctionmode", uca_na, uca_uint32t }, - { NULL, 0, 0 } -}; - -enum uca_property_ids uca_get_property_id(const char *property_name) -{ - char *name; - int i = 0; - while (property_map[i].name != NULL) { - if (!strcmp(property_map[i].name, property_name)) - return i; - i++; - } - return UCA_ERR_PROP_INVALID; -} - -struct uca_property_t *uca_get_full_property(enum uca_property_ids property_id) -{ - if ((property_id >= 0) && (property_id < UCA_PROP_LAST)) - return &property_map[property_id]; - return NULL; -} - -const char* uca_get_property_name(enum uca_property_ids property_id) -{ - 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 4034457..206aaec 100644 --- a/src/uca.h +++ b/src/uca.h @@ -11,52 +11,10 @@ * to their respective implementation. */ -#include - struct uca_t; struct uca_camera_t; struct uca_property_t; -enum uca_camera_state; -enum uca_property_ids; - -/** - * \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_camera_t **cam); - -/** - * \brief Free camera resouces - */ -typedef uint32_t (*uca_cam_destroy) (struct uca_camera_t *cam); - -/** - * \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 or - * UCA_ERR_PROP_VALUE_OUT_OF_RANGE if value cannot be set. - */ -typedef uint32_t (*uca_cam_set_property) (struct uca_camera_t *cam, enum uca_property_ids 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_camera_t *cam, enum uca_property_ids 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_camera_t *cam, uint32_t n_buffers); - -/** - * \brief Acquire one frame - */ -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 @@ -68,20 +26,6 @@ struct uca_t *uca_init(void); */ void uca_destroy(struct uca_t *uca); -enum uca_cam_state uca_get_camera_state(struct uca_camera_t *cam); - - -/** - * \brief Convert a property string to the corresponding ID - */ -enum uca_property_ids uca_get_property_id(const char *property_name); - -/** - * \brief Convert a property ID to the corresponding string - */ -const char* uca_get_property_name(enum uca_property_ids property_id); - -struct uca_property_t *uca_get_full_property(enum uca_property_ids property_id); #define UCA_NO_ERROR 0 #define UCA_ERR_INIT_NOT_FOUND 1 /**< camera probing or initialization failed */ @@ -89,104 +33,9 @@ struct uca_property_t *uca_get_full_property(enum uca_property_ids property_id); #define UCA_ERR_PROP_GENERAL 3 /**< error occured reading/writing the property */ #define UCA_ERR_PROP_VALUE_OUT_OF_RANGE 4 /**< error occured writing the property */ - -/* 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_Y_OFFSET, - 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_TRIGGER_MODE, - - /* 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_TRIGGERMODE */ -#define UCA_TRIGGER_AUTO 1 -#define UCA_TRIGGER_INTERNAL 2 -#define UCA_TRIGGER_EXTERNAL 3 - -/* Correction modes for UCA_PROP_CORRECTION_MODE */ -#define UCA_CORRECT_OFFSET 0x01 -#define UCA_CORRECT_HOTPIXEL 0x02 -#define UCA_CORRECT_GAIN 0x04 - -struct uca_property_t { - const char *name; - - enum uca_unit { - uca_pixel, - uca_bits, - uca_ns, - uca_us, - uca_ms, - uca_s, - uca_rows, - uca_na - } unit; - - enum uca_types { - uca_uint32t, - uca_uint8t, - uca_string - } type; -}; - -enum uca_cam_state { - UCA_CAM_ERROR, - UCA_CAM_CONFIGURABLE, - UCA_CAM_ARMED, - UCA_CAM_RECORDING, -}; - -struct uca_camera_t { - struct uca_camera_t *next; - - /* Function pointers to camera-specific methods */ - 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 destroy; - enum uca_cam_state state; - - void *user; /**< private user data to be used by the camera driver */ -}; - struct uca_t { struct uca_camera_t *cameras; + struct uca_grabber_t *grabbers; }; diff --git a/test/test.c b/test/test.c index e3d07ff..4a39ab2 100644 --- a/test/test.c +++ b/test/test.c @@ -1,6 +1,7 @@ #include #include "uca.h" +#include "uca-cam.h" int count_dots(const char *s) { -- cgit v1.2.3