diff options
-rw-r--r-- | NEWS | 20 | ||||
-rw-r--r-- | docs/manual.md | 43 | ||||
-rw-r--r-- | docs/style.css | 95 | ||||
-rw-r--r-- | src/CMakeLists.txt | 113 | ||||
-rw-r--r-- | src/cameras/uca-mock-camera.c | 30 | ||||
-rw-r--r-- | src/cameras/uca-mock-camera.h | 2 | ||||
-rw-r--r-- | src/cameras/uca-pco-camera.c | 304 | ||||
-rw-r--r-- | src/cameras/uca-pco-camera.h | 2 | ||||
-rw-r--r-- | src/cameras/uca-pf-camera.c | 102 | ||||
-rw-r--r-- | src/cameras/uca-pf-camera.h | 2 | ||||
-rw-r--r-- | src/cameras/uca-ufo-camera.c | 6 | ||||
-rw-r--r-- | src/cameras/uca-ufo-camera.h | 2 | ||||
-rw-r--r-- | src/uca-camera.c | 122 | ||||
-rw-r--r-- | src/uca-plugin-manager.c | 327 | ||||
-rw-r--r-- | src/uca-plugin-manager.h | 65 | ||||
-rw-r--r-- | test/CMakeLists.txt | 18 | ||||
-rw-r--r-- | test/benchmark.c | 32 | ||||
-rw-r--r-- | test/control.c | 234 | ||||
-rw-r--r-- | test/enum.c | 88 | ||||
-rw-r--r-- | test/grab-async.c | 44 | ||||
-rw-r--r-- | test/grab.c | 40 | ||||
-rw-r--r-- | test/grab_pylon.c | 96 | ||||
-rwxr-xr-x | test/run.py | 31 | ||||
-rw-r--r-- | test/test-mock.c | 181 |
24 files changed, 1107 insertions, 892 deletions
@@ -1,3 +1,23 @@ +Changes in libuca 1.1 +===================== + +Plugin System +------------- + +A new plugin manager is used to instantiate camera objects from a shared +library. Instead of calling `uca_camera_new`, a plugin manager is created that +looks in pre- and user-defined directories for DSOs that match +`libuca[A-Za-z].so` and used to instantiate: + + UcaPluginManager *manager; + UcaCamera *camera; + + manager = uca_plugin_manager_new (); + camera = uca_plugin_manager_new_camera (manager, "foo", &error); + +The plugin manager adds a dependency on GModule (pkg-config package +`gmodule-2.0`) that is part of GLib. + Changes in libuca 1.0 aka 0.6 ============================= diff --git a/docs/manual.md b/docs/manual.md index 0373010..5600d3f 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -107,6 +107,7 @@ necessary header files: ~~~ {.c} #include <glib-object.h> +#include <uca-plugin-manager.h> #include <uca-camera.h> ~~~ @@ -116,6 +117,7 @@ Then you need to setup the type system: int main (int argc, char *argv[]) { + UcaPluginManager *manager; UcaCamera *camera; GError *error = NULL; /* this _must_ be set to NULL */ @@ -124,10 +126,12 @@ main (int argc, char *argv[]) Now you can instantiate new camera _objects_. Each camera is identified by a human-readable string, in this case we want to access any pco camera that is -supported by [libpco][]: +supported by [libpco][]. To instantiate a camera we have to create a plugin +manager first: ~~~ {.c} - camera = uca_camera_new ("pco", &error); + manager = uca_plugin_manager_new (); + camera = uca_plugin_manager_new_camera (manager, "pco", &error); ~~~ Errors are indicated with a returned value `NULL` and `error` set to a value @@ -252,38 +256,19 @@ communicate with the camera. Now we will go into more detail. We have already seen how to instantiate a camera object from a name. If you have more than one camera connected to a machine, you will most likely want the user decide which to use. To do so, you can enumerate all camera strings with -`uca_camera_get_types`: +`uca_plugin_manager_get_available_cameras`: ~~~ {.c} - gchar **types; + GList *types; - types = uca_camera_get_types (); + types = uca_camera_get_available_cameras (manager); - for (guint i = 0; types[i] != NULL; i++) - g_print ("%s\n", types[i]); + for (GList *it = g_list_first; it != NULL; it = g_list_next (it)) + g_print ("%s\n", (gchar *) it->data); - /* free the string array */ - g_strfreev (types); -~~~ - -If you _know_ which camera you want to use you can instantiate the sub-classed -camera object directly. In this case we create a pco-based camera: - -~~~ {.c} -#include <glib-object.h> -#include <uca/uca-camera-pco.h> - -int -main (int argc, char *argv[]) -{ - UcaPcoCamera *camera; - GError *error = NULL; - - g_type_init (); - camera = uca_pco_camera_new (&error); - g_object_unref (camera); - return 0; -} + /* free the strings and the list */ + g_list_foreach (types, (GFunc) g_free, NULL); + g_list_free (types); ~~~ [last section]: #first-look-at-the-api diff --git a/docs/style.css b/docs/style.css index a9fc9ca..646a097 100644 --- a/docs/style.css +++ b/docs/style.css @@ -1,35 +1,34 @@ - /* --- Reset ------------------------------------------------------ */ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, -p, blockquote, th, td { - margin: 0; +p, blockquote, th, td { + margin: 0; padding: 0; } table { - border-collapse: collapse; + border-collapse: collapse; border-spacing: 0; } fieldset, img { - border: 0; - } - address, caption, cite, dfn, th, var { + border: 0; +} +address, caption, cite, dfn, th, var { font-style: normal; - font-weight: normal; - } - caption, th { + font-weight: normal; +} +caption, th { text-align: left; } h1, h2, h3, h4, h5, h6 { - font-size: 100%; + font-size: 100%; font-weight: normal; } q:before, q:after { - content: ''; - } - abbr, acronym { + content: ''; +} +abbr, acronym { border: 0; } @@ -52,10 +51,6 @@ p { margin-bottom: 24px; } -/* p > code { */ -/* font-size: 0.8em; */ -/* } */ - h1, h2, h3, h4, h5, h6 { margin-bottom: 24px; font-family: "Droid Sans", sans-serif; @@ -65,6 +60,9 @@ h1, h2, h3, h4, h5, h6 { h1 { font-size: 1.5em; line-height: 1em; + margin-top: 2em; + padding-bottom: 0.5em; + border-bottom: 2px dotted #bbb; } h2 { @@ -87,11 +85,29 @@ h5, h6 { line-height: 1.5em; } -h1 > a, h2 > a, h3 > a, h4 > a, h5 > a, h6 > a { - color: black; +h1 > a { + color: #555; + text-decoration: none; +} + +a { + color: #8e3557; text-decoration: none; } +a:hover { + color: #88a33e; +} + +h1:hover :after, +h2:hover :after, +h3:hover :after, +h4:hover :after, +h5:hover :after, +h6:hover :after { + content: " \2191"; +} + pre { margin-bottom: 24px; line-height: 1.2em; @@ -103,19 +119,58 @@ code { } ul, ol { + list-style-position: inside; + padding-left: 1em; + text-indent: -1em; + margin-left: 0; margin-bottom: 24px; } +li + li { + margin-top: 0.1em; +} + ul ul, ol ol { margin: 0 0 0 24px; } +table { + width: 100%; + margin-bottom: 24px; +} + +th { + color: #555; + font-family: 'Droid Sans', sans-serif; + font-weight: bold; + border-bottom: 1px dotted #bbb; +} + +td, th { + padding: 2px; +} + +dl { + margin-bottom: 24px; +} + +dt { + font-style: italic; +} + +dd { + margin-top: 12px; + padding-left: 1em; +} + .title { font-size: xx-large; + color: #555; } .author { font-size: 1.25em; font-weight: normal; + color: #555; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9508c5c..e186975 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,13 +3,17 @@ cmake_minimum_required(VERSION 2.8) # --- Set sources ------------------------------------------------------------- set(uca_SRCS uca-camera.c + uca-plugin-manager.c ) set(uca_HDRS - uca-camera.h) + uca-camera.h + uca-plugin-manager.h) set(cameras) +set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}") + # --- Find packages and libraries --------------------------------------------- set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) @@ -28,10 +32,25 @@ find_package(PkgConfig) find_program(GLIB2_MKENUMS glib-mkenums REQUIRED) pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED) pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED) +pkg_check_modules(GMODULE2 gmodule-2.0>=2.24 REQUIRED) + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/cameras + ${GLIB2_INCLUDE_DIRS} + ${GOBJECT2_INCLUDE_DIRS}) + +# --- Configure step +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/config.h) set(uca_LIBS - ${GLIB2_LIBRARIES} - ${GOBJECT2_LIBRARIES}) + ${GLIB2_LIBRARIES} + ${GOBJECT2_LIBRARIES} + ${GMODULE2_LIBRARIES}) + +set(uca_enum_hdrs uca-camera.h) # --- Build options ----------------------------------------------------------- option(HAVE_MOCK_CAMERA "Camera: Dummy" ON) @@ -42,18 +61,20 @@ if (PF_FOUND) option(HAVE_PHOTON_FOCUS "Camera: Photon Focus MV2-D1280-640-CL-8" ON) if (HAVE_PHOTON_FOCUS AND CLSERME4_FOUND AND FGLIB5_FOUND) - list(APPEND uca_SRCS cameras/uca-pf-camera.c) - list(APPEND uca_HDRS cameras/uca-pf-camera.h) - list(APPEND cameras "Pf") - - set(uca_LIBS ${uca_LIBS} - ${CLSERME4_LIBRARY} - ${FGLIB5_LIBRARY} - ${PF_LIBRARIES}) + list(APPEND uca_enum_hdrs cameras/uca-pf-camera.h) - include_directories(${PF_INCLUDE_DIRS} + include_directories( + ${PF_INCLUDE_DIRS} ${CLSERME4_INCLUDE_DIR} ${FGLIB5_INCLUDE_DIR}) + + add_library(ucapf SHARED cameras/uca-pf-camera.c) + + target_link_libraries(ucapf + ${uca_LIBS} + ${CLSERME4_LIBRARY} + ${FGLIB5_LIBRARY} + ${PF_LIBRARIES}) endif() endif() @@ -61,19 +82,23 @@ if (PCO_FOUND AND CLSERME4_FOUND AND FGLIB5_FOUND) option(HAVE_PCO_CL "Camera: CameraLink-based pco" ON) if (HAVE_PCO_CL) - list(APPEND uca_SRCS cameras/uca-pco-camera.c) - list(APPEND uca_HDRS cameras/uca-pco-camera.h) - list(APPEND cameras "Pco") - - set(uca_LIBS ${uca_LIBS} - ${PCO_LIBRARIES} - ${CLSERME4_LIBRARY} - ${FGLIB5_LIBRARY}) + list(APPEND uca_enum_hdrs cameras/uca-pco-camera.h) include_directories( ${PCO_INCLUDE_DIRS} ${CLSERME4_INCLUDE_DIR} ${FGLIB5_INCLUDE_DIR}) + + add_library(ucapco SHARED cameras/uca-pco-camera.c) + + target_link_libraries(ucapco + ${uca_LIBS} + ${PCO_LIBRARIES} + ${CLSERME4_LIBRARY} + ${FGLIB5_LIBRARY}) + + install(TARGETS ucapco + LIBRARY DESTINATION ${LIB_INSTALL_DIR}/uca) endif() endif() @@ -81,13 +106,18 @@ if (IPE_FOUND) option(HAVE_UFO_CAMERA "Camera: Custom based on Xilinx FPGA" ON) if (HAVE_UFO_CAMERA) - list(APPEND uca_SRCS cameras/uca-ufo-camera.c) - list(APPEND uca_HDRS cameras/uca-ufo-camera.h) - list(APPEND cameras "Ufo") - - set(uca_LIBS ${uca_LIBS} ${IPE_LIBRARIES}) + list(APPEND uca_enum_hdrs cameras/uca-ufo-camera.h) include_directories(${IPE_INCLUDE_DIRS}) + + add_library(ucaufo SHARED cameras/uca-ufo-camera.c) + target_link_libraries(ucaufo + ${uca_LIBS} + ${IPE_LIBRARIES} + ) + + install(TARGETS ucaufo + LIBRARY DESTINATION ${LIB_INSTALL_DIR}/uca) endif() endif() @@ -107,9 +137,9 @@ if (PYLON_FOUND) endif() if (HAVE_MOCK_CAMERA) - list(APPEND uca_SRCS cameras/uca-mock-camera.c) - list(APPEND uca_HDRS cameras/uca-mock-camera.h) - list(APPEND cameras "Mock") + add_library(ucamock SHARED cameras/uca-mock-camera.c) + install(TARGETS ucamock + LIBRARY DESTINATION ${LIB_INSTALL_DIR}/uca) endif() # --- Generate enum file @@ -118,9 +148,9 @@ add_custom_command( COMMAND ${GLIB2_MKENUMS} ARGS --template uca-enums.h.template - ${uca_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h + ${uca_enum_hdrs} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${uca_HDRS} + DEPENDS ${uca_enum_hdrs} ${CMAKE_CURRENT_SOURCE_DIR}/uca-enums.h.template) add_custom_command( @@ -128,29 +158,18 @@ add_custom_command( COMMAND ${GLIB2_MKENUMS} ARGS --template uca-enums.c.template - ${uca_HDRS} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c + ${uca_enum_hdrs} > ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - DEPENDS ${uca_HDRS} + DEPENDS ${uca_enum_hdrs} ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h ${CMAKE_CURRENT_SOURCE_DIR}/uca-enums.c.template ) -# --- Configure step -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in - ${CMAKE_CURRENT_BINARY_DIR}/config.h) - -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} +add_library(uca SHARED + ${uca_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c) set_target_properties(uca PROPERTIES @@ -171,7 +190,7 @@ if(GTK_DOC_FOUND) set(docs_out "${docs_dir}/reference") file(MAKE_DIRECTORY ${docs_out}) - set(reference_files + set(reference_files "${docs_out}/index.html" "${docs_out}/api-index-full.html" "${docs_out}/ch01.html" @@ -255,7 +274,7 @@ set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}") install(TARGETS uca LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -install(FILES ${uca_HDRS} +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 59c5ae8..7cd4689 100644 --- a/src/cameras/uca-mock-camera.c +++ b/src/cameras/uca-mock-camera.c @@ -15,6 +15,7 @@ with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA */ +#include <gmodule.h> #include <string.h> #include "uca-mock-camera.h" @@ -156,20 +157,6 @@ static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer) } } -/** - * uca_mock_camera_new: - * @error: Location for error - * - * Create a new #UcaMockCamera object. - * - * Returns: A newly created #UcaMockCamera object - */ -UcaMockCamera *uca_mock_camera_new(GError **error) -{ - UcaMockCamera *camera = g_object_new(UCA_TYPE_MOCK_CAMERA, NULL); - return camera; -} - static gpointer mock_grab_func(gpointer data) { UcaMockCamera *mock_camera = UCA_MOCK_CAMERA(data); @@ -208,7 +195,7 @@ static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error) if (transfer_async) { GError *tmp_error = NULL; priv->thread_running = TRUE; - priv->grab_thread = g_thread_create(mock_grab_func, camera, TRUE, &tmp_error); + priv->grab_thread = g_thread_create(mock_grab_func, camera, TRUE, &tmp_error); if (tmp_error != NULL) { priv->thread_running = FALSE; @@ -232,7 +219,7 @@ static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error) NULL); if (transfer_async) { - priv->thread_running = FALSE; + priv->thread_running = FALSE; g_thread_join(priv->grab_thread); } } @@ -358,7 +345,7 @@ static void uca_mock_camera_finalize(GObject *object) UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object); if (priv->thread_running) { - priv->thread_running = FALSE; + priv->thread_running = FALSE; g_thread_join(priv->grab_thread); } @@ -383,7 +370,7 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass) for (guint i = 0; mock_overrideables[i] != 0; i++) g_object_class_override_property(gobject_class, mock_overrideables[i], uca_camera_props[mock_overrideables[i]]); - mock_properties[PROP_FRAMERATE] = + mock_properties[PROP_FRAMERATE] = g_param_spec_float("frame-rate", "Frame rate", "Number of frames per second that are taken", @@ -413,3 +400,10 @@ static void uca_mock_camera_init(UcaMockCamera *self) g_value_set_uint(&val, 1); g_value_array_append(self->priv->binnings, &val); } + +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error) +{ + UcaCamera *camera = UCA_CAMERA (g_object_new (UCA_TYPE_MOCK_CAMERA, NULL)); + return camera; +} diff --git a/src/cameras/uca-mock-camera.h b/src/cameras/uca-mock-camera.h index 92030f8..9ee9190 100644 --- a/src/cameras/uca-mock-camera.h +++ b/src/cameras/uca-mock-camera.h @@ -58,8 +58,6 @@ struct _UcaMockCameraClass { UcaCameraClass parent; }; -UcaMockCamera *uca_mock_camera_new(GError **error); - GType uca_mock_camera_get_type(void); G_END_DECLS diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c index a56392f..8bf2936 100644 --- a/src/cameras/uca-pco-camera.c +++ b/src/cameras/uca-pco-camera.c @@ -15,6 +15,7 @@ with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA */ +#include <gmodule.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -50,7 +51,7 @@ "libpco error %x", err); \ return; \ } - + #define UCA_PCO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraPrivate)) G_DEFINE_TYPE(UcaPcoCamera, uca_pco_camera, UCA_TYPE_CAMERA) @@ -186,7 +187,7 @@ struct _UcaPcoCameraPrivate { guint current_image; }; -static pco_cl_map_entry pco_cl_map[] = { +static pco_cl_map_entry pco_cl_map[] = { { CAMERATYPE_PCO_EDGE, "libFullAreaGray8.so", FG_CL_8BIT_FULL_10, FG_GRAY, 30.0f, FALSE }, { CAMERATYPE_PCO4000, "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT, FG_GRAY16, 5.0f, TRUE }, { CAMERATYPE_PCO_DIMAX_STD, "libFullAreaGray16.so", FG_CL_SINGLETAP_8_BIT, FG_GRAY16, 1279.0f, TRUE }, @@ -200,7 +201,7 @@ static pco_cl_map_entry *get_pco_cl_map_entry(int camera_type) while (entry->camera_type != 0) { if (entry->camera_type == camera_type) return entry; - entry++; + entry++; } return NULL; @@ -212,8 +213,8 @@ static guint fill_binnings(UcaPcoCameraPrivate *priv) uint16_t *vertical = NULL; guint num_horizontal, num_vertical; - guint err = pco_get_possible_binnings(priv->pco, - &horizontal, &num_horizontal, + guint err = pco_get_possible_binnings(priv->pco, + &horizontal, &num_horizontal, &vertical, &num_vertical); GValue val = {0}; @@ -246,7 +247,7 @@ static void fill_pixelrates(UcaPcoCameraPrivate *priv, guint32 rates[4], gint nu priv->pixelrates = g_value_array_new(num_rates); for (gint i = 0; i < num_rates; i++) { - g_value_set_uint(&val, (guint) rates[i]); + g_value_set_uint(&val, (guint) rates[i]); g_value_array_append(priv->pixelrates, &val); } } @@ -315,93 +316,6 @@ static gdouble get_suitable_timebase(gdouble time) return TIMEBASE_INVALID; } -UcaPcoCamera *uca_pco_camera_new(GError **error) -{ - pco_handle pco = pco_init(); - - if (pco == NULL) { - 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); - UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); - priv->pco = pco; - - pco_get_resolution(priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex); - pco_get_binning(priv->pco, &priv->binning_h, &priv->binning_v); - pco_set_storage_mode(pco, STORAGE_MODE_RECORDER); - pco_set_auto_transfer(pco, 1); - - guint16 roi[4]; - pco_get_roi(priv->pco, roi); - pco_get_roi_steps(priv->pco, &priv->roi_horizontal_steps, &priv->roi_vertical_steps); - - priv->roi_x = roi[0] - 1; - priv->roi_y = roi[1] - 1; - priv->roi_width = roi[2] - roi[0] + 1; - priv->roi_height = roi[3] - roi[1] + 1; - - 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); - priv->camera_description = map_entry; - - 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_FG_INIT, - "%s", Fg_getLastErrorDescription(priv->fg)); - g_object_unref(camera); - return NULL; - } - - const guint32 fg_height = priv->height; - const guint32 fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width; - - FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port); - FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &map_entry->cl_format, priv->fg_port); - FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &fg_width, priv->fg_port); - FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &fg_height, priv->fg_port); - - int val = FREE_RUN; - FG_TRY_PARAM(priv->fg, camera, FG_TRIGGERMODE, &val, priv->fg_port); - - fill_binnings(priv); - - /* - * Here we override property ranges because we didn't know them at property - * installation time. - */ - GObjectClass *camera_class = G_OBJECT_CLASS (UCA_CAMERA_GET_CLASS (camera)); - property_override_default_guint_value (camera_class, "roi-width", priv->width); - property_override_default_guint_value (camera_class, "roi-height", priv->height); - - guint32 rates[4] = {0}; - gint num_rates = 0; - - if (pco_get_available_pixelrates(priv->pco, rates, &num_rates) == PCO_NOERROR) { - GObjectClass *pco_camera_class = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera)); - - fill_pixelrates(priv, rates, num_rates); - property_override_default_guint_value (pco_camera_class, "sensor-pixelrate", rates[0]); - } - - override_temperature_range (priv); - override_maximum_adcs (priv); - - return camera; -} - static int fg_callback(frameindex_t frame, struct fg_apc_data *apc) { UcaCamera *camera = UCA_CAMERA(apc); @@ -506,7 +420,7 @@ static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error) Fg_FreeMemEx(priv->fg, priv->fg_mem); const guint num_buffers = 2; - priv->fg_mem = Fg_AllocMemEx(priv->fg, + priv->fg_mem = Fg_AllocMemEx(priv->fg, num_buffers * priv->frame_width * priv->frame_height * sizeof(uint16_t), num_buffers); if (priv->fg_mem == NULL) { @@ -557,9 +471,9 @@ static void uca_pco_camera_start_readout(UcaCamera *camera, GError **error) g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); - /* + /* * TODO: Check if readout mode is possible. This is not the case for the - * edge. + * edge. */ guint err = pco_get_active_segment(priv->pco, &priv->active_segment); @@ -582,7 +496,7 @@ static void uca_pco_camera_trigger(UcaCamera *camera, GError **error) if (!success) g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL, - "Could not trigger frame acquisition"); + "Could not trigger frame acquisition"); } static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error) @@ -611,7 +525,7 @@ static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **erro pco_request_image(priv->pco); priv->last_frame = Fg_getLastPicNumberBlockingEx(priv->fg, priv->last_frame+1, priv->fg_port, MAX_TIMEOUT, priv->fg_mem); - + if (priv->last_frame <= 0) { guint err = FG_OK + 1; FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_GENERAL); @@ -620,7 +534,7 @@ static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **erro guint16 *frame = Fg_getImagePtrEx(priv->fg, priv->last_frame, priv->fg_port, priv->fg_mem); if (*data == NULL) - *data = g_malloc0(priv->frame_width * priv->frame_height * priv->num_bytes); + *data = g_malloc0(priv->frame_width * priv->frame_height * priv->num_bytes); if (priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE) pco_get_reorder_func(priv->pco)((guint16 *) *data, frame, priv->frame_width, priv->frame_height); @@ -635,7 +549,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons switch (property_id) { case PROP_SENSOR_EXTENDED: { - guint16 format = g_value_get_boolean (value) ? SENSORFORMAT_EXTENDED : SENSORFORMAT_STANDARD; + guint16 format = g_value_get_boolean (value) ? SENSORFORMAT_EXTENDED : SENSORFORMAT_STANDARD; pco_set_sensor_format(priv->pco, format); } break; @@ -651,7 +565,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons case PROP_ROI_WIDTH: { guint width = g_value_get_uint(value); - + if (width % priv->roi_horizontal_steps) g_warning("ROI width %i is not a multiple of %i", width, priv->roi_horizontal_steps); else @@ -662,7 +576,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons case PROP_ROI_HEIGHT: { guint height = g_value_get_uint(value); - + if (height % priv->roi_vertical_steps) g_warning("ROI height %i is not a multiple of %i", height, priv->roi_vertical_steps); else @@ -681,7 +595,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons case PROP_EXPOSURE_TIME: { const gdouble time = g_value_get_double(value); - + if (priv->exposure_timebase == TIMEBASE_INVALID) read_timebase(priv); @@ -692,7 +606,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons guint16 suitable_timebase = get_suitable_timebase(time); if (suitable_timebase == TIMEBASE_INVALID) { - g_warning("Cannot set such a small exposure time"); + g_warning("Cannot set such a small exposure time"); } else { if (suitable_timebase != priv->exposure_timebase) { @@ -712,7 +626,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons case PROP_DELAY_TIME: { const gdouble time = g_value_get_double(value); - + if (priv->delay_timebase == TIMEBASE_INVALID) read_timebase(priv); @@ -733,7 +647,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons g_warning("Cannot set zero delay time"); } else - g_warning("Cannot set such a small exposure time"); + g_warning("Cannot set such a small exposure time"); } else { if (suitable_timebase != priv->delay_timebase) { @@ -752,7 +666,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons case PROP_SENSOR_ADCS: { - const guint num_adcs = g_value_get_uint(value); + const guint num_adcs = g_value_get_uint(value); if (pco_set_adc_mode(priv->pco, num_adcs) != PCO_NOERROR) g_warning("Cannot set the number of ADCs per pixel\n"); } @@ -765,7 +679,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons for (guint i = 0; i < priv->pixelrates->n_values; i++) { if (g_value_get_uint(g_value_array_get_nth(priv->pixelrates, i)) == desired_pixel_rate) { - pixel_rate = desired_pixel_rate; + pixel_rate = desired_pixel_rate; break; } } @@ -792,7 +706,7 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons case PROP_COOLING_POINT: { - int16_t temperature = (int16_t) g_value_get_int(value); + int16_t temperature = (int16_t) g_value_get_int(value); pco_set_cooling_temperature(priv->pco, temperature); } break; @@ -856,11 +770,11 @@ static void uca_pco_camera_set_property(GObject *object, guint property_id, cons case PROP_TIMESTAMP_MODE: { guint16 modes[] = { - TIMESTAMP_MODE_OFF, /* 0 */ - TIMESTAMP_MODE_BINARY, /* 1 = 1 << 0 */ - TIMESTAMP_MODE_ASCII, /* 2 = 1 << 1 */ - TIMESTAMP_MODE_BINARYANDASCII, /* 3 = 1 << 0 | 1 << 1 */ - }; + TIMESTAMP_MODE_OFF, /* 0 */ + TIMESTAMP_MODE_BINARY, /* 1 = 1 << 0 */ + TIMESTAMP_MODE_ASCII, /* 2 = 1 << 1 */ + TIMESTAMP_MODE_BINARYANDASCII, /* 3 = 1 << 0 | 1 << 1 */ + }; pco_set_timestamp_mode(priv->pco, modes[g_value_get_flags(value)]); } break; @@ -878,25 +792,25 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal switch (property_id) { case PROP_SENSOR_EXTENDED: { - guint16 format; + guint16 format; pco_get_sensor_format(priv->pco, &format); g_value_set_boolean(value, format == SENSORFORMAT_EXTENDED); } break; - case PROP_SENSOR_WIDTH: + case PROP_SENSOR_WIDTH: g_value_set_uint(value, priv->width); break; - case PROP_SENSOR_HEIGHT: + case PROP_SENSOR_HEIGHT: g_value_set_uint(value, priv->height); break; - case PROP_SENSOR_WIDTH_EXTENDED: + case PROP_SENSOR_WIDTH_EXTENDED: g_value_set_uint(value, priv->width_ex < priv->width ? priv->width : priv->width_ex); break; - case PROP_SENSOR_HEIGHT_EXTENDED: + case PROP_SENSOR_HEIGHT_EXTENDED: g_value_set_uint(value, priv->height_ex < priv->height ? priv->height : priv->height_ex); break; @@ -926,7 +840,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_SENSOR_TEMPERATURE: { - gint32 ccd, camera, power; + gint32 ccd, camera, power; pco_get_temperature(priv->pco, &ccd, &camera, &power); g_value_set_double(value, ccd / 10.0); } @@ -938,7 +852,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal * Up to now, the ADC mode corresponds directly to the number of * ADCs in use. */ - pco_adc_mode mode; + pco_adc_mode mode; if (pco_get_adc_mode(priv->pco, &mode) != PCO_NOERROR) g_warning("Cannot read number of ADCs per pixel"); g_value_set_uint(value, mode); @@ -958,7 +872,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_SENSOR_PIXELRATE: { - guint32 pixelrate; + guint32 pixelrate; pco_get_pixelrate(priv->pco, &pixelrate); g_value_set_uint(value, pixelrate); } @@ -1048,7 +962,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_TRIGGER_MODE: { - guint16 mode; + guint16 mode; pco_get_trigger_mode(priv->pco, &mode); switch (mode) { @@ -1091,7 +1005,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal g_value_set_uint(value, priv->roi_vertical_steps); break; - case PROP_NAME: + case PROP_NAME: { gchar *name = NULL; pco_get_name(priv->pco, &name); @@ -1102,7 +1016,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_COOLING_POINT: { - int16_t temperature; + int16_t temperature; if (pco_get_cooling_temperature(priv->pco, &temperature) != PCO_NOERROR) g_warning("Cannot read cooling temperature\n"); g_value_set_int(value, temperature); @@ -1140,7 +1054,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_TIMESTAMP_MODE: { - guint16 mode; + guint16 mode; pco_get_timestamp_mode(priv->pco, &mode); switch (mode) { @@ -1151,7 +1065,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_BINARY); break; case TIMESTAMP_MODE_BINARYANDASCII: - g_value_set_flags(value, + g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_BINARY | UCA_PCO_CAMERA_TIMESTAMP_ASCII); break; case TIMESTAMP_MODE_ASCII: @@ -1220,20 +1134,20 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) * #UcaPcoCamera:sensor-height-extended to query the resolution of the * larger area. */ - pco_properties[PROP_SENSOR_EXTENDED] = + pco_properties[PROP_SENSOR_EXTENDED] = g_param_spec_boolean("sensor-extended", "Use extended sensor format", "Use extended sensor format", FALSE, G_PARAM_READWRITE); - pco_properties[PROP_SENSOR_WIDTH_EXTENDED] = + pco_properties[PROP_SENSOR_WIDTH_EXTENDED] = g_param_spec_uint("sensor-width-extended", "Width of extended sensor", "Width of the extended sensor in pixels", 1, G_MAXUINT, 1, G_PARAM_READABLE); - pco_properties[PROP_SENSOR_HEIGHT_EXTENDED] = + pco_properties[PROP_SENSOR_HEIGHT_EXTENDED] = g_param_spec_uint("sensor-height-extended", "Height of extended sensor", "Height of the extended sensor in pixels", @@ -1248,21 +1162,21 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) * #UcaPcoCamera:sensor-pixelrates property. Any other value will be * rejected by the camera. */ - pco_properties[PROP_SENSOR_PIXELRATE] = + pco_properties[PROP_SENSOR_PIXELRATE] = g_param_spec_uint("sensor-pixelrate", "Pixel rate", "Pixel rate", 1, G_MAXUINT, 1, G_PARAM_READWRITE); - pco_properties[PROP_SENSOR_PIXELRATES] = + pco_properties[PROP_SENSOR_PIXELRATES] = g_param_spec_value_array("sensor-pixelrates", "Array of possible sensor pixel rates", "Array of possible sensor pixel rates", pco_properties[PROP_SENSOR_PIXELRATE], G_PARAM_READABLE); - pco_properties[PROP_NAME] = + pco_properties[PROP_NAME] = g_param_spec_string("name", "Name of the camera", "Name of the camera", @@ -1275,38 +1189,38 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READABLE); - pco_properties[PROP_HAS_DOUBLE_IMAGE_MODE] = + pco_properties[PROP_HAS_DOUBLE_IMAGE_MODE] = g_param_spec_boolean("has-double-image-mode", "Is double image mode supported by this model", "Is double image mode supported by this model", FALSE, G_PARAM_READABLE); - pco_properties[PROP_DOUBLE_IMAGE_MODE] = + pco_properties[PROP_DOUBLE_IMAGE_MODE] = g_param_spec_boolean("double-image-mode", "Use double image mode", "Use double image mode", FALSE, G_PARAM_READWRITE); - pco_properties[PROP_OFFSET_MODE] = + pco_properties[PROP_OFFSET_MODE] = g_param_spec_boolean("offset-mode", "Use offset mode", "Use offset mode", FALSE, G_PARAM_READWRITE); - pco_properties[PROP_RECORD_MODE] = - g_param_spec_enum("record-mode", + pco_properties[PROP_RECORD_MODE] = + g_param_spec_enum("record-mode", "Record mode", "Record mode", UCA_TYPE_PCO_CAMERA_RECORD_MODE, UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE, G_PARAM_READWRITE); - pco_properties[PROP_ACQUIRE_MODE] = - g_param_spec_enum("acquire-mode", + pco_properties[PROP_ACQUIRE_MODE] = + g_param_spec_enum("acquire-mode", "Acquire mode", "Acquire mode", UCA_TYPE_PCO_CAMERA_ACQUIRE_MODE, UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO, G_PARAM_READWRITE); - + pco_properties[PROP_DELAY_TIME] = g_param_spec_double("delay-time", "Delay time", @@ -1314,7 +1228,7 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE); - pco_properties[PROP_NOISE_FILTER] = + pco_properties[PROP_NOISE_FILTER] = g_param_spec_boolean("noise-filter", "Noise filter", "Noise filter", @@ -1327,42 +1241,42 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) * the camera and just don't know the cooling range. We override these * values in #uca_pco_camera_new(). */ - pco_properties[PROP_COOLING_POINT] = + pco_properties[PROP_COOLING_POINT] = g_param_spec_int("cooling-point", "Cooling point of the camera", "Cooling point of the camera in degree celsius", 0, 10, 5, G_PARAM_READWRITE); - pco_properties[PROP_COOLING_POINT_MIN] = + pco_properties[PROP_COOLING_POINT_MIN] = g_param_spec_int("cooling-point-min", "Minimum cooling point", "Minimum cooling point in degree celsius", G_MININT, G_MAXINT, 0, G_PARAM_READABLE); - pco_properties[PROP_COOLING_POINT_MAX] = + pco_properties[PROP_COOLING_POINT_MAX] = g_param_spec_int("cooling-point-max", "Maximum cooling point", "Maximum cooling point in degree celsius", G_MININT, G_MAXINT, 0, G_PARAM_READABLE); - pco_properties[PROP_COOLING_POINT_DEFAULT] = + pco_properties[PROP_COOLING_POINT_DEFAULT] = g_param_spec_int("cooling-point-default", "Default cooling point", "Default cooling point in degree celsius", G_MININT, G_MAXINT, 0, G_PARAM_READABLE); - - pco_properties[PROP_SENSOR_ADCS] = + + pco_properties[PROP_SENSOR_ADCS] = g_param_spec_uint("sensor-adcs", "Number of ADCs to use", "Number of ADCs to use", - 1, 2, 1, + 1, 2, 1, G_PARAM_READWRITE); - pco_properties[PROP_SENSOR_MAX_ADCS] = + pco_properties[PROP_SENSOR_MAX_ADCS] = g_param_spec_uint("sensor-max-adcs", "Maximum number of ADCs", "Maximum number of ADCs that can be set with \"sensor-adcs\"", - 1, G_MAXUINT, 1, + 1, G_MAXUINT, 1, G_PARAM_READABLE); pco_properties[PROP_TIMESTAMP_MODE] = @@ -1394,3 +1308,91 @@ static void uca_pco_camera_init(UcaPcoCamera *self) self->priv->delay_timebase = TIMEBASE_INVALID; self->priv->exposure_timebase = TIMEBASE_INVALID; } + +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error) +{ + pco_handle pco = pco_init(); + + if (pco == NULL) { + 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); + UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); + priv->pco = pco; + + pco_get_resolution(priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex); + pco_get_binning(priv->pco, &priv->binning_h, &priv->binning_v); + pco_set_storage_mode(pco, STORAGE_MODE_RECORDER); + pco_set_auto_transfer(pco, 1); + + guint16 roi[4]; + pco_get_roi(priv->pco, roi); + pco_get_roi_steps(priv->pco, &priv->roi_horizontal_steps, &priv->roi_vertical_steps); + + priv->roi_x = roi[0] - 1; + priv->roi_y = roi[1] - 1; + priv->roi_width = roi[2] - roi[0] + 1; + priv->roi_height = roi[3] - roi[1] + 1; + + 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); + priv->camera_description = map_entry; + + 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_FG_INIT, + "%s", Fg_getLastErrorDescription(priv->fg)); + g_object_unref(camera); + return NULL; + } + + const guint32 fg_height = priv->height; + const guint32 fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width; + + FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port); + FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &map_entry->cl_format, priv->fg_port); + FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &fg_width, priv->fg_port); + FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &fg_height, priv->fg_port); + + int val = FREE_RUN; + FG_TRY_PARAM(priv->fg, camera, FG_TRIGGERMODE, &val, priv->fg_port); + + fill_binnings(priv); + + /* + * Here we override property ranges because we didn't know them at property + * installation time. + */ + GObjectClass *camera_class = G_OBJECT_CLASS (UCA_CAMERA_GET_CLASS (camera)); + property_override_default_guint_value (camera_class, "roi-width", priv->width); + property_override_default_guint_value (camera_class, "roi-height", priv->height); + + guint32 rates[4] = {0}; + gint num_rates = 0; + + if (pco_get_available_pixelrates(priv->pco, rates, &num_rates) == PCO_NOERROR) { + GObjectClass *pco_camera_class = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera)); + + fill_pixelrates(priv, rates, num_rates); + property_override_default_guint_value (pco_camera_class, "sensor-pixelrate", rates[0]); + } + + override_temperature_range (priv); + override_maximum_adcs (priv); + + return UCA_CAMERA (camera); +} diff --git a/src/cameras/uca-pco-camera.h b/src/cameras/uca-pco-camera.h index fdb709a..73ae44e 100644 --- a/src/cameras/uca-pco-camera.h +++ b/src/cameras/uca-pco-camera.h @@ -84,8 +84,6 @@ struct _UcaPcoCameraClass { UcaCameraClass parent; }; -UcaPcoCamera *uca_pco_camera_new(GError **error); - GType uca_pco_camera_get_type(void); G_END_DECLS diff --git a/src/cameras/uca-pf-camera.c b/src/cameras/uca-pf-camera.c index 5bc8c6b..35b5edd 100644 --- a/src/cameras/uca-pf-camera.c +++ b/src/cameras/uca-pf-camera.c @@ -15,6 +15,7 @@ with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA */ +#include <gmodule.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -99,52 +100,6 @@ struct _UcaPfCameraPrivate { dma_mem *fg_mem; }; -UcaPfCamera *uca_pf_camera_new(GError **error) -{ - static const gchar *so_file = "libFullAreaGray8.so"; - static const int camera_link_type = FG_CL_8BIT_FULL_8; - static const int camera_format = FG_GRAY; - - /* - gint num_ports; - if (pfPortInit(&num_ports) < 0) { - g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, - "Could not initialize ports"); - return NULL; - } - - if (pfDeviceOpen(0) < 0) { - g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, - "Could not open device"); - return NULL; - } - */ - - UcaPfCamera *camera = g_object_new(UCA_TYPE_PF_CAMERA, NULL); - UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); - - priv->fg_port = PORT_A; - priv->fg = Fg_Init(so_file, priv->fg_port); - - /* TODO: get this from the camera */ - priv->roi_width = 1280; - priv->roi_height = 1024; - - if (priv->fg == NULL) { - g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, - "%s", Fg_getLastErrorDescription(priv->fg)); - g_object_unref(camera); - return NULL; - } - - FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &camera_link_type, priv->fg_port); - FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &camera_format, priv->fg_port); - FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &priv->roi_width, priv->fg_port); - FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &priv->roi_height, priv->fg_port); - - return camera; -} - /* * We just embed our private structure here. */ @@ -226,7 +181,7 @@ static void uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); priv->last_frame = Fg_getLastPicNumberBlockingEx(priv->fg, priv->last_frame+1, priv->fg_port, 5, priv->fg_mem); - + if (priv->last_frame <= 0) { guint err = FG_OK + 1; FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_GENERAL); @@ -252,10 +207,10 @@ static void uca_pf_camera_set_property(GObject *object, guint property_id, const static void uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { - case PROP_SENSOR_WIDTH: + case PROP_SENSOR_WIDTH: g_value_set_uint(value, 1280); break; - case PROP_SENSOR_HEIGHT: + case PROP_SENSOR_HEIGHT: g_value_set_uint(value, 1024); break; case PROP_SENSOR_BITDEPTH: @@ -298,7 +253,7 @@ static void uca_pf_camera_get_property(GObject *object, guint property_id, GValu case PROP_ROI_HEIGHT_MULTIPLIER: g_value_set_uint(value, 1); break; - case PROP_NAME: + case PROP_NAME: g_value_set_string(value, "Photon Focus MV2-D1280-640-CL"); break; default: @@ -347,3 +302,50 @@ static void uca_pf_camera_init(UcaPfCamera *self) self->priv->fg_mem = NULL; self->priv->last_frame = 0; } + +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error) +{ + static const gchar *so_file = "libFullAreaGray8.so"; + static const int camera_link_type = FG_CL_8BIT_FULL_8; + static const int camera_format = FG_GRAY; + + /* + gint num_ports; + if (pfPortInit(&num_ports) < 0) { + g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, + "Could not initialize ports"); + return NULL; + } + + if (pfDeviceOpen(0) < 0) { + g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, + "Could not open device"); + return NULL; + } + */ + + UcaPfCamera *camera = g_object_new(UCA_TYPE_PF_CAMERA, NULL); + UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera); + + priv->fg_port = PORT_A; + priv->fg = Fg_Init(so_file, priv->fg_port); + + /* TODO: get this from the camera */ + priv->roi_width = 1280; + priv->roi_height = 1024; + + if (priv->fg == NULL) { + g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT, + "%s", Fg_getLastErrorDescription(priv->fg)); + g_object_unref(camera); + return NULL; + } + + FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &camera_link_type, priv->fg_port); + FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &camera_format, priv->fg_port); + FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &priv->roi_width, priv->fg_port); + FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &priv->roi_height, priv->fg_port); + + return UCA_CAMERA (camera); +} diff --git a/src/cameras/uca-pf-camera.h b/src/cameras/uca-pf-camera.h index 7e3fe2c..3a309aa 100644 --- a/src/cameras/uca-pf-camera.h +++ b/src/cameras/uca-pf-camera.h @@ -67,8 +67,6 @@ struct _UcaPfCameraClass { UcaCameraClass parent; }; -UcaPfCamera *uca_pf_camera_new(GError **error); - GType uca_pf_camera_get_type(void); G_END_DECLS diff --git a/src/cameras/uca-ufo-camera.c b/src/cameras/uca-ufo-camera.c index 5f59f4a..7542fdf 100644 --- a/src/cameras/uca-ufo-camera.c +++ b/src/cameras/uca-ufo-camera.c @@ -15,6 +15,7 @@ with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA */ +#include <gmodule.h> #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -143,7 +144,8 @@ static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, return PCILIB_STREAMING_CONTINUE; } -UcaUfoCamera *uca_ufo_camera_new(GError **error) +G_MODULE_EXPORT UcaCamera * +uca_camera_impl_new (GError **error) { pcilib_model_t model = PCILIB_MODEL_DETECT; pcilib_model_description_t *model_description; @@ -223,7 +225,7 @@ UcaUfoCamera *uca_ufo_camera_new(GError **error) priv->handle = handle; - return camera; + return UCA_CAMERA (camera); } static void uca_ufo_camera_start_recording(UcaCamera *camera, GError **error) diff --git a/src/cameras/uca-ufo-camera.h b/src/cameras/uca-ufo-camera.h index 0b52ffb..7030389 100644 --- a/src/cameras/uca-ufo-camera.h +++ b/src/cameras/uca-ufo-camera.h @@ -69,8 +69,6 @@ struct _UcaUfoCameraClass { UcaCameraClass parent; }; -UcaUfoCamera *uca_ufo_camera_new(GError **error); - GType uca_ufo_camera_get_type(void); G_END_DECLS diff --git a/src/uca-camera.c b/src/uca-camera.c index 78adae3..e34bf62 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -20,26 +20,6 @@ #include "uca-camera.h" #include "uca-enums.h" -#ifdef HAVE_PCO_CL -#include "cameras/uca-pco-camera.h" -#endif - -#ifdef HAVE_PYLON_CAMERA -#include "cameras/uca-pylon-camera.h" -#endif - -#ifdef HAVE_MOCK_CAMERA -#include "cameras/uca-mock-camera.h" -#endif - -#ifdef HAVE_UFO_CAMERA -#include "cameras/uca-ufo-camera.h" -#endif - -#ifdef HAVE_PHOTON_FOCUS -#include "cameras/uca-pf-camera.h" -#endif - #define UCA_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_CAMERA, UcaCameraPrivate)) G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT) @@ -65,25 +45,6 @@ GQuark uca_camera_error_quark() return g_quark_from_static_string("uca-camera-error-quark"); } -static gchar *uca_camera_types[] = { -#ifdef HAVE_PCO_CL - "pco", -#endif -#ifdef HAVE_PYLON_CAMERA - "pylon", -#endif -#ifdef HAVE_MOCK_CAMERA - "mock", -#endif -#ifdef HAVE_UFO_CAMERA - "ufo", -#endif -#ifdef HAVE_PHOTON_FOCUS - "pf", -#endif - NULL -}; - enum { LAST_SIGNAL }; @@ -126,7 +87,8 @@ struct _UcaCameraPrivate { gboolean transfer_async; }; -static void uca_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +static void +uca_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object); @@ -145,7 +107,8 @@ static void uca_camera_set_property(GObject *object, guint property_id, const GV } } -static void uca_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +static void +uca_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object); @@ -167,7 +130,8 @@ static void uca_camera_get_property(GObject *object, guint property_id, GValue * } } -static void uca_camera_class_init(UcaCameraClass *klass) +static void +uca_camera_class_init(UcaCameraClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); gobject_class->set_property = uca_camera_set_property; @@ -370,80 +334,6 @@ static void uca_camera_init(UcaCamera *camera) */ } -static UcaCamera *uca_camera_new_from_type(const gchar *type, GError **error) -{ -#ifdef HAVE_MOCK_CAMERA - if (!g_strcmp0(type, "mock")) - return UCA_CAMERA(uca_mock_camera_new(error)); -#endif - -#ifdef HAVE_PCO_CL - if (!g_strcmp0(type, "pco")) - return UCA_CAMERA(uca_pco_camera_new(error)); -#endif - -#ifdef HAVE_PYLON_CAMERA - if (!g_strcmp0(type, "pylon")) - return UCA_CAMERA(uca_pylon_camera_new(error)); -#endif - -#ifdef HAVE_UFO_CAMERA - if (!g_strcmp0(type, "ufo")) - return UCA_CAMERA(uca_ufo_camera_new(error)); -#endif - -#ifdef HAVE_PHOTON_FOCUS - if (!g_strcmp0(type, "pf")) - return UCA_CAMERA(uca_pf_camera_new(error)); -#endif - - return NULL; -} - -/** - * uca_camera_get_types: - * - * Enumerate all camera types that can be instantiated with uca_camera_new(). - * - * Returns: An array of strings with camera types. The list should be freed with - * g_strfreev(). - */ -gchar **uca_camera_get_types() -{ - return g_strdupv(uca_camera_types); -} - -/** - * uca_camera_new: - * @type: Type name of the camera - * @error: Location to store an error or %NULL - * - * Factory method for instantiating cameras by names listed in - * uca_camera_get_types(). - * - * Returns: A new #UcaCamera of the correct type or %NULL if type was not found - */ -UcaCamera *uca_camera_new(const gchar *type, GError **error) -{ - UcaCamera *camera = NULL; - GError *tmp_error = NULL; - - camera = uca_camera_new_from_type(type, &tmp_error); - - if (tmp_error != NULL) { - g_propagate_error(error, tmp_error); - return NULL; - } - - if ((tmp_error == NULL) && (camera == NULL)) { - g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_FOUND, - "Camera type %s not found", type); - return NULL; - } - - return camera; -} - /** * uca_camera_start_recording: * @camera: A #UcaCamera object diff --git a/src/uca-plugin-manager.c b/src/uca-plugin-manager.c new file mode 100644 index 0000000..5678e83 --- /dev/null +++ b/src/uca-plugin-manager.c @@ -0,0 +1,327 @@ +/** + * SECTION:uca-plugin-manager + * @Short_description: Load an #UcaFilter from a shared object + * @Title: UcaPluginManager + * + * The plugin manager opens shared object modules searched for in locations + * specified with uca_plugin_manager_add_path(). A #UcaCamera can be + * instantiated with uca_plugin_manager_new_camera() with a one-to-one mapping + * between filter name xyz and module name libucaxyz.so. Any errors are reported + * as one of #UcaPluginManagerError codes. To get a list of available camera + * names call uca_plugin_manager_get_available_cameras(). + * + * By default, any path listed in the %UCA_CAMERA_PATH environment variable is + * added to the search path. + * + * @Since: 1.1 + */ +#include <gmodule.h> +#include "uca-plugin-manager.h" + +G_DEFINE_TYPE (UcaPluginManager, uca_plugin_manager, G_TYPE_OBJECT) + +#define UCA_PLUGIN_MANAGER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerPrivate)) + +struct _UcaPluginManagerPrivate { + GList *search_paths; +}; + +static const gchar *MODULE_PATTERN = "libuca([A-Za-z]+)"; + +typedef UcaCamera * (*GetCameraFunc) (GError **error); + +/** + * UcaPluginManagerError: + * @UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND: The module could not be found + * @UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN: Module could not be opened + * @UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND: Necessary entry symbol was not + * found + * + * Possible errors that uca_plugin_manager_get_filter() can return. + */ +GQuark +uca_plugin_manager_error_quark (void) +{ + return g_quark_from_static_string ("uca-plugin-manager-error-quark"); +} + +/** + * uca_plugin_manager_new: + * @config: (allow-none): A #UcaConfiguration object or %NULL. + * + * Create a plugin manager object to instantiate filter objects. When a config + * object is passed to the constructor, its search-path property is added to the + * internal search paths. + * + * Return value: A new plugin manager object. + */ +UcaPluginManager * +uca_plugin_manager_new () +{ + return UCA_PLUGIN_MANAGER (g_object_new (UCA_TYPE_PLUGIN_MANAGER, NULL)); +} + +/** + * uca_plugin_manager_add_path: + * @manager: A #UcaPluginManager + * @path: Path to look for camera modules + * + * Add a search path to the plugin manager. + */ +void +uca_plugin_manager_add_path (UcaPluginManager *manager, + const gchar *path) +{ + g_return_if_fail (UCA_IS_PLUGIN_MANAGER (manager)); + + if (g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { + UcaPluginManagerPrivate *priv; + + priv = manager->priv; + priv->search_paths = g_list_append (priv->search_paths, + g_strdup (path)); + } +} + +static GList * +get_camera_module_paths (const gchar *path) +{ + GRegex *pattern; + GDir *dir; + GList *result = NULL; + + pattern = g_regex_new (MODULE_PATTERN, 0, 0, NULL); + dir = g_dir_open (path, 0, NULL); + + if (dir != NULL) { + GMatchInfo *match_info = NULL; + const gchar *name = g_dir_read_name (dir); + + while (name != NULL) { + if (g_regex_match (pattern, name, 0, &match_info)) + result = g_list_append (result, g_build_filename (path, name, NULL)); + + g_match_info_free (match_info); + name = g_dir_read_name (dir); + } + } + + return result; +} + +static GList * +scan_search_paths (GList *search_paths) +{ + GList *camera_paths = NULL; + + for (GList *it = g_list_first (search_paths); it != NULL; it = g_list_next (it)) { + camera_paths = g_list_concat (camera_paths, + get_camera_module_paths ((const gchar*) it->data)); + } + + return camera_paths; +} + +static void +transform_camera_module_path_to_name (gchar *path, GList **result) +{ + GRegex *pattern; + GMatchInfo *match_info; + + pattern = g_regex_new (MODULE_PATTERN, 0, 0, NULL); + g_regex_match (pattern, path, 0, &match_info); + + *result = g_list_append (*result, g_match_info_fetch (match_info, 1)); + g_match_info_free (match_info); +} + +static void +list_free_full (GList *list) +{ + g_list_foreach (list, (GFunc) g_free, NULL); + g_list_free (list); +} + +/** + * uca_plugin_manager_get_available_cameras: + * + * @manager: A #UcaPluginManager + * + * Return: A list with strings of available camera names. You have to free the + * individual strings with g_list_foreach(list, (GFunc) g_free, NULL) and the + * list itself with g_list_free. + */ +GList * +uca_plugin_manager_get_available_cameras (UcaPluginManager *manager) +{ + UcaPluginManagerPrivate *priv; + GList *camera_paths; + GList *camera_names = NULL; + + g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager), NULL); + + priv = manager->priv; + camera_paths = scan_search_paths (priv->search_paths); + + g_list_foreach (camera_paths, (GFunc) transform_camera_module_path_to_name, &camera_names); + list_free_full (camera_paths); + + return camera_names; +} + +static gchar * +find_camera_module_path (GList *search_paths, const gchar *name) +{ + gchar *result = NULL; + GList *paths; + + paths = scan_search_paths (search_paths); + + for (GList *it = g_list_first (paths); it != NULL; it = g_list_next (it)) { + gchar *path = (gchar *) it->data; + gchar *basename = g_path_get_basename ((gchar *) path); + + if (g_strrstr (basename, name)) { + result = g_strdup (path); + g_free (basename); + break; + } + + g_free (basename); + } + + list_free_full (paths); + return result; +} + +/** + * uca_plugin_manager_new_camera: + * @manager: A #UcaPluginManager + * @name: Name of the camera module, that maps to libuca<name>.so + * @error: Location for a #GError + */ +UcaCamera * +uca_plugin_manager_new_camera (UcaPluginManager *manager, + const gchar *name, + GError **error) +{ + UcaPluginManagerPrivate *priv; + UcaCamera *camera; + GModule *module; + GetCameraFunc *func; + gchar *module_path; + GError *tmp_error = NULL; + + const gchar *symbol_name = "uca_camera_impl_new"; + + g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager) && (name != NULL), NULL); + + priv = manager->priv; + module_path = find_camera_module_path (priv->search_paths, name); + + if (module_path == NULL) { + g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND, + "Camera module `%s' not found", name); + return NULL; + } + + module = g_module_open (module_path, G_MODULE_BIND_LAZY); + g_free (module_path); + + if (!module) { + g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN, + "Camera module `%s' could not be opened: %s", name, g_module_error ()); + return NULL; + } + + func = g_malloc0 (sizeof (GetCameraFunc)); + + if (!g_module_symbol (module, symbol_name, (gpointer *) func)) { + g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND, + "%s", g_module_error ()); + g_free (func); + + if (!g_module_close (module)) + g_warning ("%s", g_module_error ()); + + return NULL; + } + + camera = (*func) (&tmp_error); + + if (tmp_error != NULL) { + g_propagate_error (error, tmp_error); + return NULL; + } + + return camera; +} + +static void +uca_plugin_manager_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +uca_plugin_manager_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + switch (property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +uca_plugin_manager_dispose (GObject *object) +{ + G_OBJECT_CLASS (uca_plugin_manager_parent_class)->dispose (object); +} + +static void +uca_plugin_manager_finalize (GObject *object) +{ + UcaPluginManagerPrivate *priv = UCA_PLUGIN_MANAGER_GET_PRIVATE (object); + + g_list_foreach (priv->search_paths, (GFunc) g_free, NULL); + g_list_free (priv->search_paths); + + G_OBJECT_CLASS (uca_plugin_manager_parent_class)->finalize (object); +} + +static void +uca_plugin_manager_class_init (UcaPluginManagerClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->get_property = uca_plugin_manager_get_property; + gobject_class->set_property = uca_plugin_manager_set_property; + gobject_class->dispose = uca_plugin_manager_dispose; + gobject_class->finalize = uca_plugin_manager_finalize; + + g_type_class_add_private (klass, sizeof (UcaPluginManagerPrivate)); +} + +static void +uca_plugin_manager_init (UcaPluginManager *manager) +{ + UcaPluginManagerPrivate *priv; + const gchar *uca_camera_path; + + manager->priv = priv = UCA_PLUGIN_MANAGER_GET_PRIVATE (manager); + priv->search_paths = NULL; + + uca_camera_path = g_getenv ("UCA_CAMERA_PATH"); + + if (uca_camera_path != NULL) + uca_plugin_manager_add_path (manager, uca_camera_path); + + uca_plugin_manager_add_path (manager, "/usr/lib/uca"); + uca_plugin_manager_add_path (manager, "/usr/lib64/uca"); + uca_plugin_manager_add_path (manager, "/usr/local/lib/uca"); + uca_plugin_manager_add_path (manager, "/usr/local/lib64/uca"); +} diff --git a/src/uca-plugin-manager.h b/src/uca-plugin-manager.h new file mode 100644 index 0000000..9291857 --- /dev/null +++ b/src/uca-plugin-manager.h @@ -0,0 +1,65 @@ +#ifndef __UCA_PLUGIN_MANAGER_H +#define __UCA_PLUGIN_MANAGER_H + +#include <glib-object.h> +#include "uca-camera.h" + +G_BEGIN_DECLS + +#define UCA_TYPE_PLUGIN_MANAGER (uca_plugin_manager_get_type()) +#define UCA_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManager)) +#define UCA_IS_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PLUGIN_MANAGER)) +#define UCA_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerClass)) +#define UCA_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PLUGIN_MANAGER)) +#define UCA_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PLUGIN_MANAGER, UcaPluginManagerClass)) + +#define UCA_PLUGIN_MANAGER_ERROR uca_plugin_manager_error_quark() +GQuark uca_plugin_manager_error_quark(void); + +typedef enum { + UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND, + UCA_PLUGIN_MANAGER_ERROR_MODULE_OPEN, + UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND +} UcaPluginManagerError; + +typedef struct _UcaPluginManager UcaPluginManager; +typedef struct _UcaPluginManagerClass UcaPluginManagerClass; +typedef struct _UcaPluginManagerPrivate UcaPluginManagerPrivate; + +/** + * UcaPluginManager: + * + * Creates #UcaFilter instances by loading corresponding shared objects. The + * contents of the #UcaPluginManager structure are private and should only be + * accessed via the provided API. + */ +struct _UcaPluginManager { + /*< private >*/ + GObject parent_instance; + + UcaPluginManagerPrivate *priv; +}; + +/** + * UcaPluginManagerClass: + * + * #UcaPluginManager class + */ +struct _UcaPluginManagerClass { + /*< private >*/ + GObjectClass parent_class; +}; + +UcaPluginManager *uca_plugin_manager_new (void); +void uca_plugin_manager_add_path (UcaPluginManager *manager, + const gchar *path); +GList *uca_plugin_manager_get_available_cameras + (UcaPluginManager *manager); +UcaCamera *uca_plugin_manager_new_camera (UcaPluginManager *manager, + const gchar *name, + GError **error); +GType uca_plugin_manager_get_type (void); + +G_END_DECLS + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ce45d71..e4e60dc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,10 +10,7 @@ pkg_check_modules(GTHREAD2 gthread-2.0) pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED) pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED) -#include_directories(${CMAKE_SOURCE_DIR}/src) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/control.glade ${CMAKE_CURRENT_BINARY_DIR}) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run.py ${CMAKE_CURRENT_BINARY_DIR}) # --- Build targets ----------------------------------------------------------- include_directories( @@ -44,14 +41,7 @@ target_link_libraries(benchmark uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) target_link_libraries(grab uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) target_link_libraries(grab-async uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) -add_executable(grab_pylon grab_pylon.c) -target_link_libraries(grab_pylon uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) - -if (NOT DEFINED WITH_CONTROL_GUI) - set(WITH_CONTROL_GUI TRUE) -endif() - -if (GTK2_FOUND AND WITH_CONTROL_GUI) +if (GTK2_FOUND) include_directories(${GTK2_INCLUDE_DIRS}) add_executable(control @@ -81,6 +71,6 @@ if (HAVE_MOCK_CAMERA) ${CMAKE_CURRENT_BINARY_DIR}/gtester.xsl) endif() -add_executable(test-all test-all.c) -target_link_libraries(test-all uca - ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) +#add_executable(test-all test-all.c) +#target_link_libraries(test-all uca +# ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) diff --git a/test/benchmark.c b/test/benchmark.c index 0b4f6f8..ef99fd1 100644 --- a/test/benchmark.c +++ b/test/benchmark.c @@ -20,6 +20,7 @@ #include <string.h> #include <stdlib.h> #include "uca-camera.h" +#include "uca-plugin-manager.h" typedef void (*GrabFrameFunc) (UcaCamera *camera, gpointer buffer, guint n_frames); @@ -37,20 +38,25 @@ sigint_handler(int signal) static void print_usage (void) { - gchar **types; + GList *types; + UcaPluginManager *manager; - g_print ("Usage: benchmark ("); - types = uca_camera_get_types (); + manager = uca_plugin_manager_new (); + g_print ("Usage: benchmark [ "); + types = uca_plugin_manager_get_available_cameras (manager); - for (guint i = 0; types[i] != NULL; i++) { - if (types[i+1] == NULL) - g_print ("%s)", types[i]); - else - g_print ("%s | ", types[i]); + if (types == NULL) { + g_print ("] -- no camera plugin found\n"); + return; } - g_print ("\n"); - g_strfreev (types); + for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { + gchar *name = (gchar *) it->data; + if (g_list_next (it) == NULL) + g_print ("%s ]\n", name); + else + g_print ("%s, ", name); + } } static void @@ -227,10 +233,12 @@ benchmark (UcaCamera *camera) int main (int argc, char *argv[]) { + UcaPluginManager *manager; GIOChannel *log_channel; GError *error = NULL; (void) signal (SIGINT, sigint_handler); + g_type_init(); if (argc < 2) { print_usage(); @@ -241,8 +249,8 @@ main (int argc, char *argv[]) g_assert_no_error (error); g_log_set_handler (NULL, G_LOG_LEVEL_MASK, log_handler, log_channel); - g_type_init(); - camera = uca_camera_new(argv[1], &error); + manager = uca_plugin_manager_new (); + camera = uca_plugin_manager_new_camera (manager, argv[1], &error); if (camera == NULL) { g_error ("Initialization: %s", error->message); diff --git a/test/control.c b/test/control.c index eaa88e3..5a7b702 100644 --- a/test/control.c +++ b/test/control.c @@ -26,6 +26,7 @@ #include "config.h" #include "uca-camera.h" +#include "uca-plugin-manager.h" #include "egg-property-tree-view.h" @@ -48,20 +49,17 @@ typedef struct { int pixel_size; } ThreadData; -typedef struct { - ThreadData *thread_data; - GtkTreeStore *tree_store; -} ValueCellData; - enum { COLUMN_NAME = 0, COLUMN_VALUE, COLUMN_EDITABLE, NUM_COLUMNS }; + +static UcaPluginManager *plugin_manager; - -static void convert_8bit_to_rgb(guchar *output, guchar *input, int width, int height) +static void +convert_8bit_to_rgb (guchar *output, guchar *input, int width, int height) { for (int i = 0, j = 0; i < width*height; i++) { output[j++] = input[i]; @@ -70,7 +68,8 @@ static void convert_8bit_to_rgb(guchar *output, guchar *input, int width, int he } } -static void convert_16bit_to_rgb(guchar *output, guchar *input, int width, int height) +static void +convert_16bit_to_rgb (guchar *output, guchar *input, int width, int height) { guint16 *in = (guint16 *) input; guint16 min = G_MAXUINT16, max = 0; @@ -96,54 +95,58 @@ static void convert_16bit_to_rgb(guchar *output, guchar *input, int width, int h } } -static void *grab_thread(void *args) +static void * +grab_thread (void *args) { ThreadData *data = (ThreadData *) args; gchar filename[FILENAME_MAX] = {0,}; gint counter = 0; while (data->running) { - uca_camera_grab(data->camera, (gpointer) &data->buffer, NULL); + uca_camera_grab (data->camera, (gpointer) &data->buffer, NULL); if (data->store) { - snprintf(filename, FILENAME_MAX, "frame-%i-%08i.raw", data->timestamp, counter++); - FILE *fp = fopen(filename, "wb"); - fwrite(data->buffer, data->width*data->height, data->pixel_size, fp); - fclose(fp); + snprintf (filename, FILENAME_MAX, "frame-%i-%08i.raw", data->timestamp, counter++); + FILE *fp = fopen (filename, "wb"); + fwrite (data->buffer, data->width*data->height, data->pixel_size, fp); + fclose (fp); } /* FIXME: We should actually check if this is really a new frame and * just do nothing if it is an already displayed one. */ if (data->pixel_size == 1) - convert_8bit_to_rgb(data->pixels, data->buffer, data->width, data->height); + convert_8bit_to_rgb (data->pixels, data->buffer, data->width, data->height); else if (data->pixel_size == 2) { - convert_16bit_to_rgb(data->pixels, data->buffer, data->width, data->height); + convert_16bit_to_rgb (data->pixels, data->buffer, data->width, data->height); } - gdk_threads_enter(); - gdk_flush(); - gtk_image_clear(GTK_IMAGE(data->image)); - gtk_image_set_from_pixbuf(GTK_IMAGE(data->image), data->pixbuf); - gtk_widget_queue_draw_area(data->image, 0, 0, data->width, data->height); - gdk_threads_leave(); + gdk_threads_enter (); + gdk_flush (); + gtk_image_clear (GTK_IMAGE (data->image)); + gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf); + gtk_widget_queue_draw_area (data->image, 0, 0, data->width, data->height); + gdk_threads_leave (); } return NULL; } -gboolean on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) +gboolean +on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data) { return FALSE; } -void on_destroy(GtkWidget *widget, gpointer data) +void +on_destroy (GtkWidget *widget, gpointer data) { ThreadData *td = (ThreadData *) data; td->running = FALSE; - g_object_unref(td->camera); - gtk_main_quit(); + g_object_unref (td->camera); + gtk_main_quit (); } -static void on_toolbutton_run_clicked(GtkWidget *widget, gpointer args) +static void +on_toolbutton_run_clicked (GtkWidget *widget, gpointer args) { ThreadData *data = (ThreadData *) args; @@ -153,184 +156,195 @@ static void on_toolbutton_run_clicked(GtkWidget *widget, gpointer args) GError *error = NULL; data->running = TRUE; - uca_camera_start_recording(data->camera, &error); + uca_camera_start_recording (data->camera, &error); if (error != NULL) { - g_printerr("Failed to start recording: %s\n", error->message); + g_printerr ("Failed to start recording: %s\n", error->message); return; } - if (!g_thread_create(grab_thread, data, FALSE, &error)) { - g_printerr("Failed to create thread: %s\n", error->message); + if (!g_thread_create (grab_thread, data, FALSE, &error)) { + g_printerr ("Failed to create thread: %s\n", error->message); return; } } -static void on_toolbutton_stop_clicked(GtkWidget *widget, gpointer args) +static void +on_toolbutton_stop_clicked (GtkWidget *widget, gpointer args) { ThreadData *data = (ThreadData *) args; data->running = FALSE; data->store = FALSE; GError *error = NULL; - uca_camera_stop_recording(data->camera, &error); + uca_camera_stop_recording (data->camera, &error); if (error != NULL) - g_printerr("Failed to stop: %s\n", error->message); + g_printerr ("Failed to stop: %s\n", error->message); } -static void on_toolbutton_record_clicked(GtkWidget *widget, gpointer args) +static void +on_toolbutton_record_clicked (GtkWidget *widget, gpointer args) { ThreadData *data = (ThreadData *) args; - data->timestamp = (int) time(0); + data->timestamp = (int) time (0); data->store = TRUE; GError *error = NULL; - gtk_statusbar_push(data->statusbar, data->statusbar_context_id, "Recording..."); + gtk_statusbar_push (data->statusbar, data->statusbar_context_id, "Recording..."); if (data->running != TRUE) { data->running = TRUE; - uca_camera_start_recording(data->camera, &error); + uca_camera_start_recording (data->camera, &error); - if (!g_thread_create(grab_thread, data, FALSE, &error)) - g_printerr("Failed to create thread: %s\n", error->message); + if (!g_thread_create (grab_thread, data, FALSE, &error)) + g_printerr ("Failed to create thread: %s\n", error->message); } } -static void create_main_window(GtkBuilder *builder, const gchar* camera_name) +static void +create_main_window (GtkBuilder *builder, const gchar* camera_name) { static ThreadData td; GError *error = NULL; - UcaCamera *camera = uca_camera_new(camera_name, &error); + UcaCamera *camera = uca_plugin_manager_new_camera (plugin_manager, camera_name, &error); if ((camera == NULL) || (error != NULL)) { - g_error("%s\n", error->message); - gtk_main_quit(); + g_error ("%s\n", error->message); + gtk_main_quit (); } guint bits_per_sample; - g_object_get(camera, + g_object_get (camera, "roi-width", &td.width, "roi-height", &td.height, "sensor-bitdepth", &bits_per_sample, NULL); - GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window")); - GtkWidget *image = GTK_WIDGET(gtk_builder_get_object(builder, "image")); + GtkWidget *window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); + GtkWidget *image = GTK_WIDGET (gtk_builder_get_object (builder, "image")); GtkWidget *property_tree_view = egg_property_tree_view_new (G_OBJECT (camera)); GtkContainer *scrolled_property_window = GTK_CONTAINER (gtk_builder_get_object (builder, "scrolledwindow2")); gtk_container_add (scrolled_property_window, property_tree_view); gtk_widget_show_all (GTK_WIDGET (scrolled_property_window)); - GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, td.width, td.height); - gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf); + GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, td.width, td.height); + gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf); td.pixel_size = bits_per_sample > 8 ? 2 : 1; td.image = image; td.pixbuf = pixbuf; - td.buffer = (guchar *) g_malloc(td.pixel_size * td.width * td.height); - td.pixels = gdk_pixbuf_get_pixels(pixbuf); + td.buffer = (guchar *) g_malloc (td.pixel_size * td.width * td.height); + td.pixels = gdk_pixbuf_get_pixels (pixbuf); td.running = FALSE; - td.statusbar = GTK_STATUSBAR(gtk_builder_get_object(builder, "statusbar")); - td.statusbar_context_id = gtk_statusbar_get_context_id(td.statusbar, "Recording Information"); + td.statusbar = GTK_STATUSBAR (gtk_builder_get_object (builder, "statusbar")); + td.statusbar_context_id = gtk_statusbar_get_context_id (td.statusbar, "Recording Information"); td.store = FALSE; td.camera = camera; - td.property_model = GTK_TREE_MODEL(gtk_builder_get_object(builder, "camera-properties")); - - g_signal_connect(window, "destroy", G_CALLBACK(on_destroy), &td); - g_signal_connect(gtk_builder_get_object(builder, "toolbutton_run"), - "clicked", G_CALLBACK(on_toolbutton_run_clicked), &td); - g_signal_connect(gtk_builder_get_object(builder, "toolbutton_stop"), - "clicked", G_CALLBACK(on_toolbutton_stop_clicked), &td); - g_signal_connect(gtk_builder_get_object(builder, "toolbutton_record"), - "clicked", G_CALLBACK(on_toolbutton_record_clicked), &td); - - gtk_widget_show(image); - gtk_widget_show(window); + td.property_model = GTK_TREE_MODEL (gtk_builder_get_object (builder, "camera-properties")); + + g_signal_connect (window, "destroy", G_CALLBACK (on_destroy), &td); + g_signal_connect (gtk_builder_get_object (builder, "toolbutton_run"), + "clicked", G_CALLBACK (on_toolbutton_run_clicked), &td); + g_signal_connect (gtk_builder_get_object (builder, "toolbutton_stop"), + "clicked", G_CALLBACK (on_toolbutton_stop_clicked), &td); + g_signal_connect (gtk_builder_get_object (builder, "toolbutton_record"), + "clicked", G_CALLBACK (on_toolbutton_record_clicked), &td); + + gtk_widget_show (image); + gtk_widget_show (window); } -static void on_button_proceed_clicked(GtkWidget *widget, gpointer data) +static void +on_button_proceed_clicked (GtkWidget *widget, gpointer data) { - GtkBuilder *builder = GTK_BUILDER(data); - GtkWidget *choice_window = GTK_WIDGET(gtk_builder_get_object(builder, "choice-window")); - GtkTreeView *treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview-cameras")); - GtkListStore *list_store = GTK_LIST_STORE(gtk_builder_get_object(builder, "camera-types")); + GtkBuilder *builder = GTK_BUILDER (data); + GtkWidget *choice_window = GTK_WIDGET (gtk_builder_get_object (builder, "choice-window")); + GtkTreeView *treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview-cameras")); + GtkListStore *list_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "camera-types")); - GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview); - GList *selected_rows = gtk_tree_selection_get_selected_rows(selection, NULL); + GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview); + GList *selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL); GtkTreeIter iter; - gtk_widget_destroy(choice_window); - gboolean valid = gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, selected_rows->data); + gtk_widget_destroy (choice_window); + gboolean valid = gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), &iter, selected_rows->data); if (valid) { gchar *data; - gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, 0, &data, -1); - create_main_window(builder, data); - g_free(data); + gtk_tree_model_get (GTK_TREE_MODEL (list_store), &iter, 0, &data, -1); + create_main_window (builder, data); + g_free (data); } - g_list_foreach(selected_rows, (GFunc) gtk_tree_path_free, NULL); - g_list_free(selected_rows); + g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL); + g_list_free (selected_rows); } -static void on_treeview_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data) +static void +on_treeview_keypress (GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_KEY_Return) - gtk_widget_grab_focus(GTK_WIDGET(data)); + gtk_widget_grab_focus (GTK_WIDGET (data)); } -static void create_choice_window(GtkBuilder *builder) +static void +create_choice_window (GtkBuilder *builder) { - gchar **camera_types = uca_camera_get_types(); + GList *camera_types = uca_plugin_manager_get_available_cameras (plugin_manager); - GtkWidget *choice_window = GTK_WIDGET(gtk_builder_get_object(builder, "choice-window")); - GtkTreeView *treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview-cameras")); - GtkListStore *list_store = GTK_LIST_STORE(gtk_builder_get_object(builder, "camera-types")); - GtkButton *proceed_button = GTK_BUTTON(gtk_builder_get_object(builder, "button-proceed")); + GtkWidget *choice_window = GTK_WIDGET (gtk_builder_get_object (builder, "choice-window")); + GtkTreeView *treeview = GTK_TREE_VIEW (gtk_builder_get_object (builder, "treeview-cameras")); + GtkListStore *list_store = GTK_LIST_STORE (gtk_builder_get_object (builder, "camera-types")); + GtkButton *proceed_button = GTK_BUTTON (gtk_builder_get_object (builder, "button-proceed")); GtkTreeIter iter; - for (guint i = 0; camera_types[i] != NULL; i++) { - gtk_list_store_append(list_store, &iter); - gtk_list_store_set(list_store, &iter, 0, camera_types[i], -1); + for (GList *it = g_list_first (camera_types); it != NULL; it = g_list_next (it)) { + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, 0, g_strdup ((gchar *) it->data), -1); } - gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list_store), &iter); + gboolean valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter); if (valid) { - GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview); - gtk_tree_selection_unselect_all(selection); - gtk_tree_selection_select_path(selection, gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter)); + GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview); + gtk_tree_selection_unselect_all (selection); + gtk_tree_selection_select_path (selection, gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter)); } - g_strfreev(camera_types); - g_signal_connect(proceed_button, "clicked", G_CALLBACK(on_button_proceed_clicked), builder); - g_signal_connect(treeview, "key-press-event", G_CALLBACK(on_treeview_keypress), proceed_button); - gtk_widget_show_all(GTK_WIDGET(choice_window)); + g_signal_connect (proceed_button, "clicked", G_CALLBACK (on_button_proceed_clicked), builder); + g_signal_connect (treeview, "key-press-event", G_CALLBACK (on_treeview_keypress), proceed_button); + gtk_widget_show_all (GTK_WIDGET (choice_window)); + + g_list_foreach (camera_types, (GFunc) g_free, NULL); + g_list_free (camera_types); } -int main(int argc, char *argv[]) +int +main (int argc, char *argv[]) { GError *error = NULL; - g_thread_init(NULL); - gdk_threads_init(); - gtk_init(&argc, &argv); + g_thread_init (NULL); + gdk_threads_init (); + gtk_init (&argc, &argv); - GtkBuilder *builder = gtk_builder_new(); + GtkBuilder *builder = gtk_builder_new (); - if (!gtk_builder_add_from_file(builder, CONTROL_GLADE_PATH, &error)) { - g_print("Error: %s\n", error->message); + if (!gtk_builder_add_from_file (builder, CONTROL_GLADE_PATH, &error)) { + g_print ("Error: %s\n", error->message); return 1; } - create_choice_window(builder); - gtk_builder_connect_signals(builder, NULL); + plugin_manager = uca_plugin_manager_new (); + create_choice_window (builder); + gtk_builder_connect_signals (builder, NULL); - gdk_threads_enter(); - gtk_main(); - gdk_threads_leave(); + gdk_threads_enter (); + gtk_main (); + gdk_threads_leave (); + g_object_unref (plugin_manager); return 0; } diff --git a/test/enum.c b/test/enum.c deleted file mode 100644 index 75ca596..0000000 --- a/test/enum.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> - (Karlsruhe Institute of Technology) - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2.1 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - details. - - You should have received a copy of the GNU Lesser General Public License along - with this library; if not, write to the Free Software Foundation, Inc., 51 - Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <stdio.h> -#include "uca.h" - -int count_dots(const char *s) -{ - int res = 0; - while (*(s++) != '\0') - if (*s == '.') - res++; - return res; -} - -void print_level(int depth) -{ - for (int i = 0; i < depth; i++) - printf("| "); - printf("|-- "); -} - -int main(int argc, char *argv[]) -{ - uca *u = uca_init(NULL); - if (u == NULL) { - printf("Couldn't find a camera\n"); - return 1; - } - - /* take first camera */ - uca_camera *cam = u->cameras; - - const size_t num_bytes = 256; - char string_value[num_bytes]; - uint32_t uint32_value; - uint8_t uint8_value; - - while (cam != NULL) { - for (int i = 0; i < UCA_PROP_LAST; i++) { - uca_property *prop = uca_get_full_property(i); - print_level(count_dots(prop->name)); - printf("%s = ", prop->name); - switch (prop->type) { - case uca_string: - if (uca_cam_get_property(cam, i, string_value, num_bytes) == UCA_NO_ERROR) { - printf("%s ", string_value); - } - else - printf("n/a"); - break; - case uca_uint32t: - if (uca_cam_get_property(cam, i, &uint32_value, 0) == UCA_NO_ERROR) { - printf("%u %s", uint32_value, uca_unit_map[prop->unit]); - } - else - printf("n/a"); - break; - case uca_uint8t: - if (uca_cam_get_property(cam, i, &uint8_value, 0) == UCA_NO_ERROR) { - printf("%u %s", uint8_value, uca_unit_map[prop->unit]); - } - else - printf("n/a"); - break; - } - printf("\n"); - } - cam = cam->next; - } - - uca_destroy(u); - return 0; -} diff --git a/test/grab-async.c b/test/grab-async.c index e1ec114..6132829 100644 --- a/test/grab-async.c +++ b/test/grab-async.c @@ -19,6 +19,7 @@ #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include "uca-plugin-manager.h" #include "uca-camera.h" static UcaCamera *camera = NULL; @@ -29,7 +30,8 @@ typedef struct { guint counter; } CallbackData; -static void sigint_handler(int signal) +static void +sigint_handler(int signal) { printf("Closing down libuca\n"); uca_camera_stop_recording(camera, NULL); @@ -37,7 +39,8 @@ static void sigint_handler(int signal) exit(signal); } -static void grab_callback(gpointer data, gpointer user_data) +static void +grab_callback(gpointer data, gpointer user_data) { CallbackData *cbd = (CallbackData *) user_data; gchar *filename = g_strdup_printf("frame-%04i.raw", cbd->counter++); @@ -49,16 +52,49 @@ static void grab_callback(gpointer data, gpointer user_data) g_free(filename); } -int main(int argc, char *argv[]) +static void +print_usage (void) +{ + GList *types; + UcaPluginManager *manager; + + manager = uca_plugin_manager_new (); + g_print ("Usage: benchmark [ "); + types = uca_plugin_manager_get_available_cameras (manager); + + if (types == NULL) { + g_print ("] -- no camera plugin found\n"); + return; + } + + for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { + gchar *name = (gchar *) it->data; + if (g_list_next (it) == NULL) + g_print ("%s ]\n", name); + else + g_print ("%s, ", name); + } +} + +int +main(int argc, char *argv[]) { CallbackData cbd; guint sensor_width, sensor_height; gchar *name; + UcaPluginManager *manager; GError *error = NULL; (void) signal(SIGINT, sigint_handler); g_type_init(); - camera = uca_camera_new("pco", &error); + + if (argc < 2) { + print_usage(); + return 1; + } + + manager = uca_plugin_manager_new (); + camera = uca_plugin_manager_new_camera (manager, argv[1], &error); if (camera == NULL) { g_print("Error during initialization: %s\n", error->message); diff --git a/test/grab.c b/test/grab.c index 41e6d88..e507d69 100644 --- a/test/grab.c +++ b/test/grab.c @@ -19,6 +19,7 @@ #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include "uca-plugin-manager.h" #include "uca-camera.h" static UcaCamera *camera = NULL; @@ -31,26 +32,33 @@ static void sigint_handler(int signal) exit(signal); } -static void print_usage(void) +static void +print_usage (void) { - gchar **types; - - g_print("Usage: grab ("); - types = uca_camera_get_types(); - - for (guint i = 0; types[i] != NULL; i++) { - if (types[i+1] == NULL) - g_print("%s)", types[i]); - else - g_print("%s | ", types[i]); + GList *types; + UcaPluginManager *manager; + + manager = uca_plugin_manager_new (); + g_print ("Usage: benchmark [ "); + types = uca_plugin_manager_get_available_cameras (manager); + + if (types == NULL) { + g_print ("] -- no camera plugin found\n"); + return; } - g_print("\n"); - g_strfreev(types); + for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { + gchar *name = (gchar *) it->data; + if (g_list_next (it) == NULL) + g_print ("%s ]\n", name); + else + g_print ("%s, ", name); + } } int main(int argc, char *argv[]) { + UcaPluginManager *manager; GError *error = NULL; (void) signal(SIGINT, sigint_handler); @@ -59,13 +67,15 @@ int main(int argc, char *argv[]) guint bits; gchar *name; + g_type_init(); + if (argc < 2) { print_usage(); return 1; } - g_type_init(); - camera = uca_camera_new(argv[1], &error); + manager = uca_plugin_manager_new (); + camera = uca_plugin_manager_new_camera (manager, argv[1], &error); if (camera == NULL) { g_print("Error during initialization: %s\n", error->message); diff --git a/test/grab_pylon.c b/test/grab_pylon.c deleted file mode 100644 index 2f9b5a0..0000000 --- a/test/grab_pylon.c +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (C) 2011, 2012 Matthias Vogelgesang <matthias.vogelgesang@kit.edu> - (Karlsruhe Institute of Technology) - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2.1 of the License, or (at your - option) any later version. - - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - details. - - You should have received a copy of the GNU Lesser General Public License along - with this library; if not, write to the Free Software Foundation, Inc., 51 - Franklin St, Fifth Floor, Boston, MA 02110, USA */ - -#include <glib-object.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include "uca-camera.h" - -#define handle_error(errno) {if ((errno) != UCA_NO_ERROR) printf("error at <%s:%i>\n", \ - __FILE__, __LINE__);} - -static UcaCamera *camera = NULL; - -void sigint_handler(int signal) -{ - printf("Closing down libuca\n"); - uca_camera_stop_recording(camera, NULL); - g_object_unref(camera); - exit(signal); -} - -int main(int argc, char *argv[]) -{ - GError *error = NULL; - (void) signal(SIGINT, sigint_handler); - - g_type_init(); - camera = uca_camera_new("pylon", &error); - - if (camera == NULL) { - g_print("Couldn't initialize camera\n"); - return 1; - } - - guint width, height, bits; - g_object_get(G_OBJECT(camera), - "sensor-width", &width, - "sensor-height", &height, - "sensor-bitdepth", &bits, - NULL); - - const int pixel_size = bits == 8 ? 1 : 2; - g_print("allocate buffer %u, %u, %d\n", width, height, pixel_size); - gpointer buffer = g_malloc0(width * height * pixel_size); - - gchar filename[FILENAME_MAX]; - - for (int i = 0; i < 2; i++) { - gint counter = 0; - g_print("Start recording\n"); - uca_camera_start_recording(camera, &error); - g_assert_no_error(error); - - while (counter < 10) { - g_print(" grab frame ... "); - uca_camera_grab(camera, &buffer, &error); - if (error != NULL) { - g_print("\nError: %s\n", error->message); - goto cleanup; - } - g_print("done\n"); - - snprintf(filename, FILENAME_MAX, "frame-%08i.raw", counter++); - FILE *fp = fopen(filename, "wb"); - fwrite(buffer, width*height, pixel_size, fp); - fclose(fp); - //g_usleep(2 * G_USEC_PER_SEC); - } - - g_print("Stop recording\n"); - uca_camera_stop_recording(camera, &error); - g_assert_no_error(error); - } - -cleanup: - uca_camera_stop_recording(camera, NULL); - g_object_unref(camera); - g_free(buffer); - - return error != NULL ? 1 : 0; -} diff --git a/test/run.py b/test/run.py deleted file mode 100755 index 7982617..0000000 --- a/test/run.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python - -import Tkinter -import threading -import subprocess - -class App(object): - def __init__(self, parent): - self.parent = parent - self.canvas = Tkinter.Canvas(root, width=300, height=300) - self.canvas.pack() - self.rect = self.canvas.create_rectangle(0, 0, 300, 300, fill='yellow') - self.run_button = Tkinter.Button(parent, text='Start grabbing', command=self.run_click) - self.run_button.pack() - - def run_grab(self): - proc = subprocess.Popen(['./grab']) - proc.wait() - self.canvas.itemconfig(self.rect, fill='red') - self.run_button.config(state=Tkinter.NORMAL, text='Close', command=self.parent.destroy) - - def run_click(self): - self.canvas.itemconfig(self.rect, fill='green') - self.run_button.config(state=Tkinter.DISABLED) - thread = threading.Thread(None, self.run_grab) - thread.start() - -if __name__ == '__main__': - root = Tkinter.Tk() - app = App(root) - root.mainloop() diff --git a/test/test-mock.c b/test/test-mock.c index 7594a3a..ca16c59 100644 --- a/test/test-mock.c +++ b/test/test-mock.c @@ -1,176 +1,195 @@ #include <glib.h> #include "uca-camera.h" -#include "cameras/uca-mock-camera.h" +#include "uca-plugin-manager.h" typedef struct { - UcaMockCamera *camera; + UcaPluginManager *manager; + UcaCamera *camera; } Fixture; -static void fixture_setup(Fixture *fixture, gconstpointer data) +static void +fixture_setup (Fixture *fixture, gconstpointer data) { GError *error = NULL; - fixture->camera = uca_mock_camera_new(&error); - g_assert(error == NULL); - g_assert(fixture->camera); + + fixture->manager = uca_plugin_manager_new (); + uca_plugin_manager_add_path (fixture->manager, "./src"); + + fixture->camera = uca_plugin_manager_new_camera (fixture->manager, "mock", &error); + g_assert (error == NULL); + g_assert (fixture->camera); } -static void fixture_teardown(Fixture *fixture, gconstpointer data) +static void +fixture_teardown (Fixture *fixture, gconstpointer data) { - g_object_unref(fixture->camera); + g_object_unref (fixture->camera); + g_object_unref (fixture->manager); } -static void on_property_change(gpointer instance, GParamSpec *pspec, gpointer user_data) +static void +on_property_change (gpointer instance, GParamSpec *pspec, gpointer user_data) { gboolean *success = (gboolean *) user_data; *success = TRUE; } -static void test_factory() +static void +test_factory (Fixture *fixture, gconstpointer data) { GError *error = NULL; - UcaCamera *camera = uca_camera_new("fox994m3a0yxmy", &error); - g_assert_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_FOUND); - g_assert(camera == NULL); + UcaCamera *camera = uca_plugin_manager_new_camera (fixture->manager, "fox994m3a0yxmy", &error); + g_assert_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND); + g_assert (camera == NULL); } -static void test_recording(Fixture *fixture, gconstpointer data) +static void +test_recording (Fixture *fixture, gconstpointer data) { GError *error = NULL; - UcaCamera *camera = UCA_CAMERA(fixture->camera); + UcaCamera *camera = UCA_CAMERA (fixture->camera); - uca_camera_stop_recording(camera, &error); - g_assert_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING); - g_error_free(error); + uca_camera_stop_recording (camera, &error); + g_assert_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING); + g_error_free (error); error = NULL; - uca_camera_start_recording(camera, &error); - g_assert_no_error(error); - uca_camera_stop_recording(camera, &error); - g_assert_no_error(error); + uca_camera_start_recording (camera, &error); + g_assert_no_error (error); + uca_camera_stop_recording (camera, &error); + g_assert_no_error (error); } -static void test_recording_signal(Fixture *fixture, gconstpointer data) +static void +test_recording_signal (Fixture *fixture, gconstpointer data) { - UcaCamera *camera = UCA_CAMERA(fixture->camera); + UcaCamera *camera = UCA_CAMERA (fixture->camera); gboolean success = FALSE; - g_signal_connect(G_OBJECT(camera), "notify::is-recording", + g_signal_connect (G_OBJECT (camera), "notify::is-recording", (GCallback) on_property_change, &success); - uca_camera_start_recording(camera, NULL); - g_assert(success == TRUE); + uca_camera_start_recording (camera, NULL); + g_assert (success == TRUE); success = FALSE; - uca_camera_stop_recording(camera, NULL); - g_assert(success == TRUE); + uca_camera_stop_recording (camera, NULL); + g_assert (success == TRUE); } -static void grab_func(gpointer data, gpointer user_data) +static void +grab_func (gpointer data, gpointer user_data) { guint *count = (guint *) user_data; *count += 1; } -static void test_recording_async(Fixture *fixture, gconstpointer data) +static void +test_recording_async (Fixture *fixture, gconstpointer data) { - UcaCamera *camera = UCA_CAMERA(fixture->camera); + UcaCamera *camera = UCA_CAMERA (fixture->camera); guint count = 0; - uca_camera_set_grab_func(camera, grab_func, &count); + uca_camera_set_grab_func (camera, grab_func, &count); - g_object_set(G_OBJECT(camera), + g_object_set (G_OBJECT (camera), "frame-rate", 10.0, "transfer-asynchronously", TRUE, NULL); GError *error = NULL; - uca_camera_start_recording(camera, &error); - g_assert_no_error(error); + uca_camera_start_recording (camera, &error); + g_assert_no_error (error); /* * We sleep for an 1/8 of a second at 10 frames per second, thus we should * record 2 frames. */ - g_usleep(G_USEC_PER_SEC / 8); + g_usleep (G_USEC_PER_SEC / 8); - uca_camera_stop_recording(camera, &error); - g_assert_no_error(error); - g_assert_cmpint(count, ==, 2); + uca_camera_stop_recording (camera, &error); + g_assert_no_error (error); + g_assert_cmpint (count, ==, 2); } -static void test_recording_property(Fixture *fixture, gconstpointer data) +static void +test_recording_property (Fixture *fixture, gconstpointer data) { - UcaCamera *camera = UCA_CAMERA(fixture->camera); + UcaCamera *camera = UCA_CAMERA (fixture->camera); gboolean is_recording = FALSE; - uca_camera_start_recording(camera, NULL); - g_object_get(G_OBJECT(camera), + uca_camera_start_recording (camera, NULL); + g_object_get (G_OBJECT (camera), "is-recording", &is_recording, NULL); - g_assert(is_recording == TRUE); + g_assert (is_recording == TRUE); - uca_camera_stop_recording(camera, NULL); - g_object_get(G_OBJECT(camera), + uca_camera_stop_recording (camera, NULL); + g_object_get (G_OBJECT (camera), "is-recording", &is_recording, NULL); - g_assert(is_recording == FALSE); + g_assert (is_recording == FALSE); } -static void test_base_properties(Fixture *fixture, gconstpointer data) +static void +test_base_properties (Fixture *fixture, gconstpointer data) { - UcaCamera *camera = UCA_CAMERA(fixture->camera); + UcaCamera *camera = UCA_CAMERA (fixture->camera); guint n_properties = 0; - GParamSpec **properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(camera), &n_properties); + GParamSpec **properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (camera), &n_properties); GValue val = {0}; for (guint i = 0; i < n_properties; i++) { - g_value_init(&val, properties[i]->value_type); - g_object_get_property(G_OBJECT(camera), properties[i]->name, &val); - g_value_unset(&val); + g_value_init (&val, properties[i]->value_type); + g_object_get_property (G_OBJECT (camera), properties[i]->name, &val); + g_value_unset (&val); } - g_free(properties); + g_free (properties); } -static void test_binnings_properties(Fixture *fixture, gconstpointer data) +static void +test_binnings_properties (Fixture *fixture, gconstpointer data) { - UcaCamera *camera = UCA_CAMERA(fixture->camera); + UcaCamera *camera = UCA_CAMERA (fixture->camera); GValueArray *array = NULL; - g_object_get(G_OBJECT(camera), + g_object_get (G_OBJECT (camera), "sensor-horizontal-binnings", &array, NULL); - GValue *value = g_value_array_get_nth(array, 0); - g_assert(value != NULL); - g_assert(g_value_get_uint(value) == 1); + GValue *value = g_value_array_get_nth (array, 0); + g_assert (value != NULL); + g_assert (g_value_get_uint (value) == 1); } -static void test_signal(Fixture *fixture, gconstpointer data) +static void +test_signal (Fixture *fixture, gconstpointer data) { - UcaCamera *camera = UCA_CAMERA(fixture->camera); + UcaCamera *camera = UCA_CAMERA (fixture->camera); gboolean success = FALSE; - g_signal_connect(camera, "notify::frame-rate", (GCallback) on_property_change, &success); - g_object_set(G_OBJECT(camera), + g_signal_connect (camera, "notify::frame-rate", (GCallback) on_property_change, &success); + g_object_set (G_OBJECT (camera), "frame-rate", 30.0, NULL); - g_assert(success == TRUE); + g_assert (success == TRUE); } -int main(int argc, char *argv[]) +int main (int argc, char *argv[]) { - g_type_init(); - g_test_init(&argc, &argv, NULL); - g_test_bug_base("http://ufo.kit.edu/ufo/ticket"); - - g_test_add_func("/factory", test_factory); - g_test_add("/recording", Fixture, NULL, fixture_setup, test_recording, fixture_teardown); - g_test_add("/recording/signal", Fixture, NULL, fixture_setup, test_recording_signal, fixture_teardown); - g_test_add("/recording/asynchronous", Fixture, NULL, fixture_setup, test_recording_async, fixture_teardown); - g_test_add("/properties/base", Fixture, NULL, fixture_setup, test_base_properties, fixture_teardown); - g_test_add("/properties/recording", Fixture, NULL, fixture_setup, test_recording_property, fixture_teardown); - g_test_add("/properties/binnings", Fixture, NULL, fixture_setup, test_binnings_properties, fixture_teardown); - g_test_add("/signal", Fixture, NULL, fixture_setup, test_signal, fixture_teardown); - - return g_test_run(); + g_type_init (); + + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("http://ufo.kit.edu/ufo/ticket"); + + g_test_add ("/factory", Fixture, NULL, fixture_setup, test_factory, fixture_teardown); + g_test_add ("/recording", Fixture, NULL, fixture_setup, test_recording, fixture_teardown); + g_test_add ("/recording/signal", Fixture, NULL, fixture_setup, test_recording_signal, fixture_teardown); + g_test_add ("/recording/asynchronous", Fixture, NULL, fixture_setup, test_recording_async, fixture_teardown); + g_test_add ("/properties/base", Fixture, NULL, fixture_setup, test_base_properties, fixture_teardown); + g_test_add ("/properties/recording", Fixture, NULL, fixture_setup, test_recording_property, fixture_teardown); + g_test_add ("/properties/binnings", Fixture, NULL, fixture_setup, test_binnings_properties, fixture_teardown); + g_test_add ("/signal", Fixture, NULL, fixture_setup, test_signal, fixture_teardown); + + return g_test_run (); } |