From e26a093b4036083f13265bcbde5eae442d502377 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Thu, 1 Mar 2012 17:23:14 +0100 Subject: First draft at clean pco object construction --- src/CMakeLists.txt | 109 +++++++++++++++--------------- src/cameras/uca-mock-camera.c | 12 ++-- src/cameras/uca-pco-camera.c | 153 ++++++++++++++++++++++++++++++++++++++---- src/cameras/uca-pco-camera.h | 8 +++ src/uca-camera.c | 12 ++-- src/uca-camera.h | 12 ++-- 6 files changed, 221 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7bb66aa..edc9fa5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,18 +2,14 @@ cmake_minimum_required(VERSION 2.8) # --- Set sources ------------------------------------------------------------- set(uca_SRCS - uca.c - uca-cam.c - uca-grabber.c + uca-camera.c ) set(uca_HDRS - uca.h - uca-cam.h - uca-grabber.h + uca-camera.h ) -set(uca_LIBS "") +set(uca_LIBS) # --- Find packages and libraries --------------------------------------------- set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) @@ -31,6 +27,8 @@ find_package(ClSerMe4) find_package(PkgConfig) find_package(Threads) +pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED) +pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED) # --- Build options ----------------------------------------------------------- option(HAVE_DUMMY_CAMERA "Camera: Dummy" OFF) @@ -48,49 +46,58 @@ if (PF_FOUND) endif() endif() -if (PCO_FOUND) +if (PCO_FOUND AND CLSERME4_FOUND AND FGLIB5_FOUND) option(HAVE_PCO_CL "Camera: CameraLink-based pco" ON) if (HAVE_PCO_CL) - set(uca_SRCS ${uca_SRCS} cameras/pco.c) - set(uca_LIBS ${uca_LIBS} ${PCO_LIBRARIES}) - - include_directories(${PCO_INCLUDE_DIRS}) - endif() -endif() - -if (IPE_FOUND) - option(HAVE_IPE_CAMERA "Camera: Custom IPE based on Xilinx FPGA" ON) - - if (HAVE_IPE_CAMERA) - set(uca_SRCS ${uca_SRCS} cameras/ipe.c) - set(uca_LIBS ${uca_LIBS} ${IPE_LIBRARIES}) + set(uca_SRCS ${uca_SRCS} cameras/uca-pco-camera.c) + set(uca_HDRS ${uca_HDRS} cameras/uca-pco-camera.h) - include_directories(${IPE_INCLUDE_DIRS}) - endif() -endif() - -if (CLSERME4_FOUND AND FGLIB5_FOUND) - option(HAVE_ME4 "Grabber: Silicon Software microEnable IV" ON) - if (HAVE_ME4) - set(uca_SRCS ${uca_SRCS} grabbers/me4.c) set(uca_LIBS ${uca_LIBS} + ${PCO_LIBRARIES} ${CLSERME4_LIBRARY} ${FGLIB5_LIBRARY}) include_directories( + ${PCO_INCLUDE_DIRS} ${CLSERME4_INCLUDE_DIR} ${FGLIB5_INCLUDE_DIR}) endif() - - option(HAVE_SIMPLE_CAMERA "Camera: Just grabber based" ON) - if (HAVE_SIMPLE_CAMERA) - set(uca_SRCS ${uca_SRCS} cameras/simple.c) - endif() endif() +#if (IPE_FOUND) +# option(HAVE_IPE_CAMERA "Camera: Custom IPE based on Xilinx FPGA" ON) +# +# if (HAVE_IPE_CAMERA) +# set(uca_SRCS ${uca_SRCS} cameras/ipe.c) +# set(uca_LIBS ${uca_LIBS} ${IPE_LIBRARIES}) +# +# include_directories(${IPE_INCLUDE_DIRS}) +# endif() +#endif() +# +#if (CLSERME4_FOUND AND FGLIB5_FOUND) +# option(HAVE_ME4 "Grabber: Silicon Software microEnable IV" ON) +# if (HAVE_ME4) +# set(uca_SRCS ${uca_SRCS} grabbers/me4.c) +# set(uca_LIBS ${uca_LIBS} +# ${CLSERME4_LIBRARY} +# ${FGLIB5_LIBRARY}) +# +# include_directories( +# ${CLSERME4_INCLUDE_DIR} +# ${FGLIB5_INCLUDE_DIR}) +# endif() +# +# option(HAVE_SIMPLE_CAMERA "Camera: Just grabber based" ON) +# if (HAVE_SIMPLE_CAMERA) +# set(uca_SRCS ${uca_SRCS} cameras/simple.c) +# endif() +#endif() +# if (HAVE_DUMMY_CAMERA) - set(uca_SRCS ${uca_SRCS} cameras/dummy.c) + set(uca_SRCS ${uca_SRCS} cameras/uca-mock-camera.c) + set(uca_HDRS ${uca_HDRS} cameras/uca-mock-camera.h) endif() if (Threads_FOUND) @@ -109,43 +116,33 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/cameras + ${GLIB2_INCLUDE_DIRS} + ${GOBJECT2_INCLUDE_DIRS} ) # --- Build target ------------------------------------------------------------ add_definitions("-std=c99 -Wall") -add_library(uca SHARED ${uca_SRCS}) -set_target_properties(uca PROPERTIES +add_library(uca-gobject SHARED ${uca_SRCS}) + +set_target_properties(uca-gobject PROPERTIES VERSION ${UCA_ABI_VERSION} SOVERSION ${UCA_VERSION_MINOR}) -target_link_libraries(uca ${uca_LIBS}) - - -# >>>> TEMPORARY BUILD TARGET <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED) -pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED) - -include_directories( - ${GLIB2_INCLUDE_DIRS} - ${GOBJECT2_INCLUDE_DIRS} - ${PCO_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/cameras - ) - -add_library(uca-gobject SHARED uca-camera.c cameras/uca-pco-camera.c cameras/uca-mock-camera.c) - target_link_libraries(uca-gobject ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES} - ${PCO_LIBRARIES}) + ${PCO_LIBRARIES} + ${CLSERME4_LIBRARY} + ${FGLIB5_LIBRARY}) # --- Install target ---------------------------------------------------------- set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}") -install(TARGETS uca +install(TARGETS uca-gobject LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -install(FILES uca.h +install(FILES ${uca_HDRS} DESTINATION include/uca) # --- install pkg-config file diff --git a/src/cameras/uca-mock-camera.c b/src/cameras/uca-mock-camera.c index feae389..ba92a67 100644 --- a/src/cameras/uca-mock-camera.c +++ b/src/cameras/uca-mock-camera.c @@ -30,6 +30,8 @@ enum { PROP_0, PROP_SENSOR_WIDTH, PROP_SENSOR_HEIGHT, + N_INTERFACE_PROPERTIES, + N_PROPERTIES }; @@ -44,19 +46,19 @@ struct _UcaMockCameraPrivate { guint16 *dummy_data; }; -static void uca_mock_camera_start_recording(UcaCamera *camera) +static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); g_print("start recording\n"); } -static void uca_mock_camera_stop_recording(UcaCamera *camera) +static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); g_print("stop recording\n"); } -static void uca_mock_camera_grab(UcaCamera *camera, gchar *data) +static void uca_mock_camera_grab(UcaCamera *camera, gchar *data, GError **error) { g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); /* g_memmove(data, camera->priv->dummy_data, camera->priv->width * camera->priv->height * 2); */ @@ -110,8 +112,8 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass) gobject_class->get_property = uca_mock_camera_get_property; gobject_class->finalize = uca_mock_camera_finalize; - for (guint property_id = PROP_0+1; property_id < N_PROPERTIES; property_id++) - g_object_class_override_property(gobject_class, property_id, mock_overrideables[property_id-1]); + for (guint id = PROP_0 + 1; id < N_INTERFACE_PROPERTIES; id++) + g_object_class_override_property(gobject_class, id, mock_overrideables[id-1]); g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate)); } diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c index 9ca52cf..332d3ea 100644 --- a/src/cameras/uca-pco-camera.c +++ b/src/cameras/uca-pco-camera.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include "uca-camera.h" #include "uca-pco-camera.h" @@ -29,47 +31,147 @@ G_DEFINE_TYPE_WITH_CODE(UcaPcoCamera, uca_pco_camera, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(UCA_TYPE_CAMERA, uca_pco_camera_interface_init)); +/** + * UcaPcoCameraError: + * @UCA_PCO_CAMERA_ERROR_LIBPCO_INIT: Initializing libpco failed + * @UCA_PCO_CAMERA_ERROR_UNSUPPORTED: Camera type is not supported + * @UCA_PCO_CAMERA_ERROR_FG_INIT: Framegrabber initialization failed + * @UCA_PCO_CAMERA_ERROR_FG_ERROR: Framegrabber error + */ +GQuark uca_pco_camera_error_quark() +{ + return g_quark_from_static_string("uca-pco-camera-error-quark"); +} + enum { PROP_0, PROP_SENSOR_WIDTH, PROP_SENSOR_HEIGHT, + PROP_SENSOR_BITDEPTH, + N_INTERFACE_PROPERTIES, + + PROP_NAME, N_PROPERTIES }; static const gchar *pco_overrideables[N_PROPERTIES] = { "sensor-width", - "sensor-height" + "sensor-height", + "sensor-bitdepth" +}; + +static GParamSpec *pco_properties[N_PROPERTIES - N_INTERFACE_PROPERTIES - 1] = { NULL, }; + +typedef struct { + int camera_type; + const char *so_file; + int cl_type; + int cl_format; +} pco_cl_map_entry; + +static pco_cl_map_entry pco_cl_map[] = { + { CAMERATYPE_PCO_EDGE, "libFullAreaGray8.so", FG_CL_8BIT_FULL_10, FG_GRAY }, + { CAMERATYPE_PCO4000, "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT, FG_GRAY16 }, + { CAMERATYPE_PCO_DIMAX_STD, "libFullAreaGray16.so", FG_CL_SINGLETAP_8_BIT, FG_GRAY16 }, + { 0, NULL, 0, 0} }; +static pco_cl_map_entry *get_pco_cl_map_entry(int camera_type) +{ + pco_cl_map_entry *entry = pco_cl_map; + + while (entry->camera_type != 0) { + if (entry->camera_type == camera_type) + return entry; + entry++; + } + return NULL; +} + struct _UcaPcoCameraPrivate { pco_handle pco; + + Fg_Struct *fg; + guint fg_port; + dma_mem *fg_mem; + + guint16 width; + guint16 height; }; UcaPcoCamera *uca_pco_camera_new(GError **error) { + /* TODO: find a good way to handle libpco and fg errors */ pco_handle pco = pco_init(); if (pco == NULL) { - /* TODO: throw error */ + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, + "Initializing libpco failed"); return NULL; } UcaPcoCamera *camera = g_object_new(UCA_TYPE_PCO_CAMERA, NULL); - camera->priv->pco = pco; + UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); + priv->pco = pco; + + guint16 camera_type, camera_subtype; + pco_get_camera_type(priv->pco, &camera_type, &camera_subtype); + pco_cl_map_entry *map_entry = get_pco_cl_map_entry(camera_type); + + if (map_entry == NULL) { + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + "Camera type is not supported"); + g_object_unref(camera); + return NULL; + } + + priv->fg_port = PORT_A; + priv->fg = Fg_Init(map_entry->so_file, priv->fg_port); + + if (priv->fg == NULL) { + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + "Initializing framegrabber failed"); + g_object_unref(camera); + return NULL; + } + + guint16 width_ex, height_ex; + pco_get_resolution(priv->pco, &priv->width, &priv->height, &width_ex, &height_ex); + const guint num_buffers = 2; + guint fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width; + priv->fg_mem = Fg_AllocMemEx(priv->fg, fg_width * priv->height * sizeof(uint16_t), num_buffers); + + if (priv->fg_mem == NULL) { + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + "Framegrabber could not allocate DMA buffers"); + g_object_unref(camera); + return NULL; + } + + Fg_setParameter(priv->fg, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port); + Fg_setParameter(priv->fg, FG_FORMAT, &map_entry->cl_format, priv->fg_port); + Fg_setParameter(priv->fg, FG_WIDTH, &fg_width, priv->fg_port); + Fg_setParameter(priv->fg, FG_HEIGHT, &priv->height, priv->fg_port); + + int val = FREE_RUN; + Fg_setParameter(priv->fg, FG_TRIGGERMODE, &val, priv->fg_port); + return camera; } -static void uca_pco_camera_start_recording(UcaCamera *camera) +static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); + pco_start_recording(UCA_PCO_CAMERA_GET_PRIVATE(camera)->pco); } -static void uca_pco_camera_stop_recording(UcaCamera *camera) +static void uca_pco_camera_stop_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); + pco_stop_recording(UCA_PCO_CAMERA_GET_PRIVATE(camera)->pco); } -static void uca_pco_camera_grab(UcaCamera *camera, gchar *data) +static void uca_pco_camera_grab(UcaCamera *camera, gchar *data, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); } @@ -91,10 +193,17 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal switch (property_id) { case PROP_SENSOR_WIDTH: + g_value_set_uint(value, priv->width); + break; + case PROP_SENSOR_HEIGHT: + g_value_set_uint(value, priv->height); + break; + case PROP_NAME: { - uint16_t width_std, height_std, width_ex, height_ex; - if (pco_get_resolution(priv->pco, &width_std, &height_std, &width_ex, &height_ex) == PCO_NOERROR) - g_value_set_uint(value, width_std); + char *name = NULL; + pco_get_name(priv->pco, &name); + g_value_set_string(value, name); + free(name); } break; default: @@ -107,7 +216,15 @@ static void uca_pco_camera_finalize(GObject *object) { UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object); - pco_destroy(priv->pco); + if (priv->fg) { + if (priv->fg_mem) + Fg_FreeMemEx(priv->fg, priv->fg_mem); + + Fg_FreeGrabber(priv->fg); + } + + if (priv->pco) + pco_destroy(priv->pco); G_OBJECT_CLASS(uca_pco_camera_parent_class)->finalize(object); } @@ -126,8 +243,17 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) gobject_class->get_property = uca_pco_camera_get_property; gobject_class->finalize = uca_pco_camera_finalize; - for (guint property_id = PROP_0+1; property_id < N_PROPERTIES; property_id++) - g_object_class_override_property(gobject_class, property_id, pco_overrideables[property_id-1]); + for (guint id = PROP_0 + 1; id < N_INTERFACE_PROPERTIES; id++) + g_object_class_override_property(gobject_class, id, pco_overrideables[id-1]); + + pco_properties[PROP_NAME] = + g_param_spec_string("name", + "Name of the camera", + "Name of the camera", + "", G_PARAM_READABLE); + + for (guint id = N_INTERFACE_PROPERTIES + 1; id < N_PROPERTIES; id++) + g_object_class_install_property(gobject_class, id, pco_properties[id]); g_type_class_add_private(klass, sizeof(UcaPcoCameraPrivate)); } @@ -135,4 +261,7 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) static void uca_pco_camera_init(UcaPcoCamera *self) { self->priv = UCA_PCO_CAMERA_GET_PRIVATE(self); + self->priv->fg = NULL; + self->priv->fg_mem = NULL; + self->priv->pco = NULL; } diff --git a/src/cameras/uca-pco-camera.h b/src/cameras/uca-pco-camera.h index 336cbf6..68e92fa 100644 --- a/src/cameras/uca-pco-camera.h +++ b/src/cameras/uca-pco-camera.h @@ -27,6 +27,14 @@ #define UCA_IS_PCO_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PCO_CAMERA)) #define UCA_PCO_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraClass)) +#define UCA_PCO_CAMERA_ERROR uca_pco_camera_error_quark() +typedef enum { + UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, + UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + UCA_PCO_CAMERA_ERROR_FG_INIT, + UCA_PCO_CAMERA_ERROR_FG_ERROR +} UcaPcoCameraError; + typedef struct _UcaPcoCamera UcaPcoCamera; typedef struct _UcaPcoCameraClass UcaPcoCameraClass; typedef struct _UcaPcoCameraPrivate UcaPcoCameraPrivate; diff --git a/src/uca-camera.c b/src/uca-camera.c index 9fa0666..cb7890b 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -77,7 +77,7 @@ static void uca_camera_default_init(UcaCameraInterface *klass) g_object_interface_install_property(klass, uca_camera_properties[i]); } -void uca_camera_start_recording(UcaCamera *camera) +void uca_camera_start_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_CAMERA(camera)); @@ -86,10 +86,10 @@ void uca_camera_start_recording(UcaCamera *camera) g_return_if_fail(iface != NULL); g_return_if_fail(iface->start_recording != NULL); - (*iface->start_recording)(camera); + (*iface->start_recording)(camera, error); } -void uca_camera_stop_recording(UcaCamera *camera) +void uca_camera_stop_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_CAMERA(camera)); @@ -98,10 +98,10 @@ void uca_camera_stop_recording(UcaCamera *camera) g_return_if_fail(iface != NULL); g_return_if_fail(iface->start_recording != NULL); - (*iface->stop_recording)(camera); + (*iface->stop_recording)(camera, error); } -void uca_camera_grab(UcaCamera *camera, gchar *data) +void uca_camera_grab(UcaCamera *camera, gchar *data, GError **error) { g_return_if_fail(UCA_IS_CAMERA(camera)); @@ -110,6 +110,6 @@ void uca_camera_grab(UcaCamera *camera, gchar *data) g_return_if_fail(iface != NULL); g_return_if_fail(iface->start_recording != NULL); - (*iface->grab)(camera, data); + (*iface->grab)(camera, data, error); } diff --git a/src/uca-camera.h b/src/uca-camera.h index 29010c6..1d66d8f 100644 --- a/src/uca-camera.h +++ b/src/uca-camera.h @@ -37,14 +37,14 @@ struct _UcaCameraInterface { /*< private >*/ GTypeInterface parent; - void (*start_recording) (UcaCamera *camera); - void (*stop_recording) (UcaCamera *camera); - void (*grab) (UcaCamera *camera, gchar *data); + void (*start_recording) (UcaCamera *camera, GError **error); + void (*stop_recording) (UcaCamera *camera, GError **error); + void (*grab) (UcaCamera *camera, gchar *data, GError **error); }; -void uca_camera_start_recording(UcaCamera *camera); -void uca_camera_stop_recording(UcaCamera *camera); -void uca_camera_grab(UcaCamera *camera, gchar *data); +void uca_camera_start_recording(UcaCamera *camera, GError **error); +void uca_camera_stop_recording(UcaCamera *camera, GError **error); +void uca_camera_grab(UcaCamera *camera, gchar *data, GError **error); GType uca_camera_get_type(void); -- cgit v1.2.3