summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt276
-rw-r--r--src/cameras/uca-mock-camera.c415
-rw-r--r--src/cameras/uca-mock-camera.h67
-rw-r--r--src/cameras/uca-pco-camera.c1396
-rw-r--r--src/cameras/uca-pco-camera.h93
-rw-r--r--src/cameras/uca-pf-camera.c349
-rw-r--r--src/cameras/uca-pf-camera.h76
-rw-r--r--src/cameras/uca-pylon-camera.c391
-rw-r--r--src/cameras/uca-pylon-camera.h74
-rw-r--r--src/cameras/uca-ufo-camera.c495
-rw-r--r--src/cameras/uca-ufo-camera.h78
-rw-r--r--src/uca-camera.c560
-rw-r--r--src/uca-camera.h62
-rw-r--r--src/uca-docs.xml.in4
-rw-r--r--src/uca-plugin-manager.c345
-rw-r--r--src/uca-plugin-manager.h65
-rw-r--r--src/uca.types.in2
17 files changed, 895 insertions, 3853 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 033587e..160c52b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,130 +1,15 @@
cmake_minimum_required(VERSION 2.8)
+project(uca C)
# --- Set sources -------------------------------------------------------------
set(uca_SRCS
uca-camera.c
+ uca-plugin-manager.c
)
set(uca_HDRS
- uca-camera.h)
-
-set(cameras)
-
-# --- Find packages and libraries ---------------------------------------------
-set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
-
-# --- Find camera interfaces
-find_package(PCO)
-find_package(PF)
-find_package(IPE)
-find_package(Pylon)
-find_package(DEXELA)
-
-# --- Find frame grabber interfaces
-find_package(FgLib5)
-find_package(ClSerMe4)
-
-# --- Miscellanous packages
-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)
-
-set(uca_LIBS
- ${GLIB2_LIBRARIES}
- ${GOBJECT2_LIBRARIES})
-
-# --- Build options -----------------------------------------------------------
-option(HAVE_MOCK_CAMERA "Camera: Dummy" ON)
-
-
-# --- Add sources if camera/framegrabber access sources are available ---------
-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})
-
- include_directories(${PF_INCLUDE_DIRS}
- ${CLSERME4_INCLUDE_DIR}
- ${FGLIB5_INCLUDE_DIR})
- endif()
-endif()
-
-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})
-
- include_directories(
- ${PCO_INCLUDE_DIRS}
- ${CLSERME4_INCLUDE_DIR}
- ${FGLIB5_INCLUDE_DIR})
- endif()
-endif()
-
-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})
-
- include_directories(${IPE_INCLUDE_DIRS})
- endif()
-endif()
-
-if (PYLON_FOUND)
- option(HAVE_PYLON_CAMERA "Camera: Pylon based (Basler)" ON)
-
- if (HAVE_PYLON_CAMERA)
- list(APPEND uca_SRCS cameras/uca-pylon-camera.c)
- list(APPEND uca_HDRS cameras/uca-pylon-camera.h)
- list(APPEND cameras "Pylon")
- set(uca_LIBS ${uca_LIBS} ${LIBPYLONCAM_LIBRARIES})
-
- include_directories(${LIBPYLONCAM_INCLUDEDIR})
- link_directories(${LIBPYLONCAM_LIBDIR})
- endif()
-endif()
-
-if (DEXELA_FOUND)
- option(HAVE_DEXELA_CL "Camera: CameraLink-based dexela detector" ON)
-
- if (HAVE_DEXELA_CL)
- list(APPEND uca_SRCS cameras/uca-dexela-camera.c)
- list(APPEND uca_HDRS cameras/uca-dexela-camera.h)
- list(APPEND cameras "Ufo")
-
- set(uca_LIBS ${uca_LIBS} ${DEXELA_LIBRARIES})
-
- include_directories(${DEXELA_INCLUDE_DIRS})
- endif()
-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")
-endif()
+ uca-camera.h
+ uca-plugin-manager.h)
# --- Generate enum file
add_custom_command(
@@ -132,9 +17,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(
@@ -142,39 +27,94 @@ 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 ---------------------------------------------------------------
+
+find_program(INTROSPECTION_SCANNER "g-ir-scanner")
+find_program(INTROSPECTION_COMPILER "g-ir-compiler")
+
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
- ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+ ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+
+set(prefix ${CMAKE_INSTALL_PREFIX})
+if (CI_INSTALL_PREFIX)
+ set(prefix ${CI_INSTALL_PREFIX})
+endif()
+
+set(exec_prefix "\${prefix}")
+set(libdir ${prefix}/${LIB_INSTALL_DIR})
+set(includedir "\${prefix}/include")
+set(VERSION ${UCA_VERSION_STRING})
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/uca.pc.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/uca.pc" @ONLY IMMEDIATE)
-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
VERSION ${UCA_ABI_VERSION}
SOVERSION ${UCA_VERSION_MAJOR})
-target_link_libraries(uca
- ${uca_LIBS})
+target_link_libraries(uca ${UCA_DEPS})
+
+
+# --- Build introspection files -----------------------------------------------
+
+if (INTROSPECTION_SCANNER AND INTROSPECTION_COMPILER)
+ option(WITH_GIR "Build introspection files" ON)
+
+ if (WITH_GIR)
+ set(GIR_PREFIX "Uca-${UCA_ABI_VERSION}")
+ set(GIR_XML "${GIR_PREFIX}.gir")
+ set(GIR_TYPELIB "${GIR_PREFIX}.typelib")
+ set(_gir_input)
+
+ foreach(_src ${uca_SRCS} ${uca_HDRS})
+ list(APPEND _gir_input "${CMAKE_CURRENT_SOURCE_DIR}/${_src}")
+ endforeach()
+
+ add_custom_command(OUTPUT ${GIR_XML}
+ COMMAND ${INTROSPECTION_SCANNER}
+ --namespace=Uca
+ --nsversion=${UCA_ABI_VERSION}
+ --library=uca
+ --no-libtool
+ --include=GObject-2.0
+ --include=GModule-2.0
+ --output ${GIR_XML}
+ --warn-all
+ ${_gir_input}
+ DEPENDS ${uca_SRCS}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+ add_custom_command(OUTPUT ${GIR_TYPELIB}
+ COMMAND ${INTROSPECTION_COMPILER}
+ -o ${GIR_TYPELIB}
+ ${GIR_XML}
+ DEPENDS ${GIR_XML}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+
+ add_custom_target(gir ALL DEPENDS ${GIR_XML} ${GIR_TYPELIB})
+ add_dependencies(gir uca)
+
+ endif()
+endif()
+
# --- Build documentation -----------------------------------------------------
+
pkg_check_modules(GTK_DOC gtk-doc)
if(GTK_DOC_FOUND)
@@ -185,11 +125,12 @@ 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"
"${docs_out}/UcaCamera.html"
+ "${docs_out}/UcaPluginManager.html"
"${docs_out}/style.css"
"${docs_out}/uca.devhelp2"
"${docs_out}/home.png"
@@ -197,18 +138,6 @@ if(GTK_DOC_FOUND)
"${docs_out}/right.png"
"${docs_out}/up.png")
- # Put in uca-docs.xml and uca.types all cameras that are built
- set(_xml_doc_input)
- set(_types_input)
- foreach (_cam ${cameras})
- # add camera to the installed documentation
- list(APPEND reference_files "${docs_out}/Uca${_cam}Camera.html")
-
- string(TOLOWER ${_cam} _cam)
- set(_xml_doc_input "${_xml_doc_input}\n<xi:include href=\"xml/uca-${_cam}-camera.xml\"/>")
- set(_types_input "${_types_input}\nuca_${_cam}_camera_get_type")
- endforeach()
-
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/uca-docs.xml.in
${docs_out}/uca-docs.xml)
@@ -264,42 +193,36 @@ endif()
# --- Install target ----------------------------------------------------------
-# check for 64 bit
-if (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(LIB_INSTALL_DIR "lib64")
-else()
- set(LIB_INSTALL_DIR "lib")
-endif()
install(TARGETS uca
- LIBRARY DESTINATION ${LIB_INSTALL_DIR})
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ COMPONENT libraries)
-install(FILES ${uca_HDRS}
- DESTINATION include/uca)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/uca.pc
+ DESTINATION lib/pkgconfig
+ COMPONENT libraries)
-# --- install pkg-config file
-set(prefix ${CMAKE_INSTALL_PREFIX})
-if (CI_INSTALL_PREFIX)
- set(prefix ${CI_INSTALL_PREFIX})
-endif()
+install(FILES ${uca_HDRS}
+ DESTINATION include/uca
+ COMPONENT headers)
-set(exec_prefix "\${prefix}")
-set(libdir ${prefix}/${LIB_INSTALL_DIR})
-set(includedir "\${prefix}/include")
-set(VERSION ${UCA_VERSION_STRING})
+if(WITH_GIR)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${GIR_XML}
+ DESTINATION share/gir-1.0
+ COMPONENT libraries)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/uca.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/uca.pc" @ONLY IMMEDIATE)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${GIR_TYPELIB}
+ DESTINATION ${LIB_INSTALL_DIR}/girepository-1.0
+ COMPONENT libraries)
+endif()
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/uca.pc DESTINATION lib/pkgconfig)
+# --- Generate package description --------------------------------------------
set(CPACK_PACKAGE_DESCRIPTION "Unified Camera Access library")
-set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Abstract interface for different camera classes and frame grabber devices")
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "GObject-based library for accessing scientific cameras")
set(CPACK_PACKAGE_NAME "libuca")
-# --- Distro specific
-set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.6), libgcc1 (>= 1:4.1)")
-
# this doesn't work when building RPMs on Jenkins
set(CPACK_SET_DESTDIR ON)
@@ -310,13 +233,12 @@ set(CPACK_PACKAGE_VERSION_MINOR ${UCA_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${UCA_VERSION_PATCH})
set(VERSION ${UCA_VERSION_STRING})
-set(CPACK_GENERATOR "DEB;RPM;")
+set(CPACK_GENERATOR "RPM;")
+
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES ".git" "tags" ".bzr" ".swp")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "libuca-${UCA_VERSION_STRING}" CACHE INTERNAL "tarball basename")
-set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${UCA_VERSION_STRING}-${CPACK_PACKAGE_RELEASE}.${CMAKE_SYSTEM_PROCESSOR}")
+set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${UCA_VERSION_STRING}-${CMAKE_SYSTEM_PROCESSOR}")
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../libuca.spec.in"
- "${CMAKE_CURRENT_BINARY_DIR}/../libuca.spec" @ONLY IMMEDIATE)
include(CPack)
diff --git a/src/cameras/uca-mock-camera.c b/src/cameras/uca-mock-camera.c
deleted file mode 100644
index 59c5ae8..0000000
--- a/src/cameras/uca-mock-camera.c
+++ /dev/null
@@ -1,415 +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 <string.h>
-#include "uca-mock-camera.h"
-
-#define UCA_MOCK_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCameraPrivate))
-
-G_DEFINE_TYPE(UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA)
-
-enum {
- PROP_FRAMERATE = N_BASE_PROPERTIES,
- N_PROPERTIES
-};
-
-static const gint mock_overrideables[] = {
- PROP_NAME,
- PROP_SENSOR_WIDTH,
- PROP_SENSOR_HEIGHT,
- PROP_SENSOR_BITDEPTH,
- PROP_SENSOR_HORIZONTAL_BINNING,
- PROP_SENSOR_HORIZONTAL_BINNINGS,
- PROP_SENSOR_VERTICAL_BINNING,
- PROP_SENSOR_VERTICAL_BINNINGS,
- PROP_TRIGGER_MODE,
- PROP_EXPOSURE_TIME,
- PROP_ROI_X,
- PROP_ROI_Y,
- PROP_ROI_WIDTH,
- PROP_ROI_HEIGHT,
- PROP_ROI_HEIGHT_MULTIPLIER,
- PROP_ROI_WIDTH_MULTIPLIER,
- PROP_SENSOR_MAX_FRAME_RATE,
- PROP_HAS_STREAMING,
- PROP_HAS_CAMRAM_RECORDING,
- 0,
-};
-
-static GParamSpec *mock_properties[N_PROPERTIES] = { NULL, };
-
-struct _UcaMockCameraPrivate {
- guint width;
- guint height;
- guint roi_x, roi_y, roi_width, roi_height;
- gfloat frame_rate;
- gfloat max_frame_rate;
- gdouble exposure_time;
- guint8 *dummy_data;
- guint current_frame;
-
- gboolean thread_running;
-
- GThread *grab_thread;
- GValueArray *binnings;
-};
-
-static const char g_digits[10][20] = {
- /* 0 */
- { 0x00, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0xff,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0x00 },
- /* 1 */
- { 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00,
- 0x00, 0x00, 0xff, 0x00 },
- /* 2 */
- { 0x00, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff },
- /* 3 */
- { 0x00, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0x00 },
- /* 4 */
- { 0xff, 0x00, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0x00, 0xff },
- /* 5 */
- { 0xff, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00,
- 0x00, 0xff, 0xff, 0x00,
- 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0x00 },
- /* 6 */
- { 0x00, 0xff, 0xff, 0xff,
- 0xff, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0x00 },
- /* 7 */
- { 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0xff,
- 0x00, 0x00, 0xff, 0x00,
- 0x00, 0xff, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x00 },
- /* 8 */
- { 0x00, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0x00 },
- /* 9 */
- { 0x00, 0xff, 0xff, 0x00,
- 0xff, 0x00, 0x00, 0xff,
- 0x00, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0x00 }
-};
-
-static const guint DIGIT_WIDTH = 4;
-static const guint DIGIT_HEIGHT = 5;
-
-static void print_number(gchar *buffer, guint number, guint x, guint y, guint width)
-{
- for (int i = 0; i < DIGIT_WIDTH; i++) {
- for (int j = 0; j < DIGIT_HEIGHT; j++) {
- buffer[(y+j)*width + (x+i)] = g_digits[number][j*DIGIT_WIDTH+i];
- }
- }
-}
-
-static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
-{
- guint number = priv->current_frame;
- guint divisor = 100000000;
- int x = 10;
- while (divisor > 1) {
- print_number(buffer, number / divisor, x, 10, priv->width);
- number = number % divisor;
- divisor = divisor / 10;
- x += DIGIT_WIDTH + 1;
- }
-}
-
-/**
- * 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);
- g_return_val_if_fail(UCA_IS_MOCK_CAMERA(mock_camera), NULL);
-
- UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(mock_camera);
- UcaCamera *camera = UCA_CAMERA(mock_camera);
- const gulong sleep_time = (gulong) G_USEC_PER_SEC / priv->frame_rate;
-
- while (priv->thread_running) {
- camera->grab_func(priv->dummy_data, camera->user_data);
- g_usleep(sleep_time);
- }
-
- return NULL;
-}
-
-static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
-{
- gboolean transfer_async = FALSE;
- UcaMockCameraPrivate *priv;
- g_return_if_fail(UCA_IS_MOCK_CAMERA(camera));
-
- priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera);
- /* TODO: check that roi_x + roi_width < priv->width */
- priv->dummy_data = (guint8 *) g_malloc0(priv->roi_width * priv->roi_height);
-
- g_object_get(G_OBJECT(camera),
- "transfer-asynchronously", &transfer_async,
- NULL);
-
- /*
- * In case asynchronous transfer is requested, we start a new thread that
- * invokes the grab callback, otherwise nothing will be done here.
- */
- if (transfer_async) {
- GError *tmp_error = NULL;
- priv->thread_running = TRUE;
- priv->grab_thread = g_thread_create(mock_grab_func, camera, TRUE, &tmp_error);
-
- if (tmp_error != NULL) {
- priv->thread_running = FALSE;
- g_propagate_error(error, tmp_error);
- }
- }
-}
-
-static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
-{
- gboolean transfer_async = FALSE;
- UcaMockCameraPrivate *priv;
- g_return_if_fail(UCA_IS_MOCK_CAMERA(camera));
-
- priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera);
- g_free(priv->dummy_data);
- priv->dummy_data = NULL;
-
- g_object_get(G_OBJECT(camera),
- "transfer-asynchronously", &transfer_async,
- NULL);
-
- if (transfer_async) {
- priv->thread_running = FALSE;
- g_thread_join(priv->grab_thread);
- }
-}
-
-static void uca_mock_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
-{
- g_return_if_fail(UCA_IS_MOCK_CAMERA(camera));
- g_return_if_fail(data != NULL);
-
- UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera);
-
- if (*data == NULL)
- *data = g_malloc0(priv->width * priv->height);
-
- g_memmove(*data, priv->dummy_data, priv->width * priv->height);
- print_current_frame(priv, *data);
- priv->current_frame++;
-}
-
-static void uca_mock_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- g_return_if_fail(UCA_IS_MOCK_CAMERA(object));
- UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_EXPOSURE_TIME:
- priv->exposure_time = g_value_get_double(value);
- break;
- case PROP_FRAMERATE:
- priv->frame_rate = g_value_get_float(value);
- break;
- case PROP_ROI_X:
- priv->roi_x = g_value_get_uint(value);
- break;
- case PROP_ROI_Y:
- priv->roi_y = g_value_get_uint(value);
- break;
- case PROP_ROI_WIDTH:
- priv->roi_width = g_value_get_uint(value);
- break;
- case PROP_ROI_HEIGHT:
- priv->roi_height = g_value_get_uint(value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- return;
- }
-}
-
-static void uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_NAME:
- g_value_set_string(value, "mock camera");
- break;
- case PROP_SENSOR_WIDTH:
- g_value_set_uint(value, priv->width);
- break;
- case PROP_SENSOR_HEIGHT:
- g_value_set_uint(value, priv->height);
- break;
- case PROP_SENSOR_BITDEPTH:
- g_value_set_uint(value, 8);
- break;
- case PROP_SENSOR_HORIZONTAL_BINNING:
- g_value_set_uint(value, 1);
- break;
- case PROP_SENSOR_HORIZONTAL_BINNINGS:
- g_value_set_boxed(value, priv->binnings);
- break;
- case PROP_SENSOR_VERTICAL_BINNING:
- g_value_set_uint(value, 1);
- break;
- case PROP_SENSOR_VERTICAL_BINNINGS:
- g_value_set_boxed(value, priv->binnings);
- break;
- case PROP_EXPOSURE_TIME:
- g_value_set_double(value, priv->exposure_time);
- break;
- case PROP_TRIGGER_MODE:
- g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO);
- break;
- case PROP_ROI_X:
- g_value_set_uint(value, priv->roi_x);
- break;
- case PROP_ROI_Y:
- g_value_set_uint(value, priv->roi_y);
- break;
- case PROP_ROI_WIDTH:
- g_value_set_uint(value, priv->roi_width);
- break;
- case PROP_ROI_HEIGHT:
- g_value_set_uint(value, priv->roi_height);
- break;
- case PROP_ROI_WIDTH_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
- case PROP_ROI_HEIGHT_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
- case PROP_SENSOR_MAX_FRAME_RATE:
- g_value_set_float(value, priv->max_frame_rate);
- break;
- case PROP_HAS_STREAMING:
- g_value_set_boolean(value, TRUE);
- break;
- case PROP_HAS_CAMRAM_RECORDING:
- g_value_set_boolean(value, FALSE);
- break;
- case PROP_FRAMERATE:
- g_value_set_float(value, priv->frame_rate);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void uca_mock_camera_finalize(GObject *object)
-{
- UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
-
- if (priv->thread_running) {
- priv->thread_running = FALSE;
- g_thread_join(priv->grab_thread);
- }
-
- g_free(priv->dummy_data);
- g_value_array_free(priv->binnings);
-
- G_OBJECT_CLASS(uca_mock_camera_parent_class)->finalize(object);
-}
-
-static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->set_property = uca_mock_camera_set_property;
- gobject_class->get_property = uca_mock_camera_get_property;
- gobject_class->finalize = uca_mock_camera_finalize;
-
- UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass);
- camera_class->start_recording = uca_mock_camera_start_recording;
- camera_class->stop_recording = uca_mock_camera_stop_recording;
- camera_class->grab = uca_mock_camera_grab;
-
- 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] =
- g_param_spec_float("frame-rate",
- "Frame rate",
- "Number of frames per second that are taken",
- 1.0f, 100.0f, 100.0f,
- G_PARAM_READWRITE);
-
- for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++)
- g_object_class_install_property(gobject_class, id, mock_properties[id]);
-
- g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate));
-}
-
-static void uca_mock_camera_init(UcaMockCamera *self)
-{
- self->priv = UCA_MOCK_CAMERA_GET_PRIVATE(self);
- self->priv->roi_x = 0;
- self->priv->roi_y = 0;
- self->priv->width = self->priv->roi_width = 640;
- self->priv->height = self->priv->roi_height = 480;
- self->priv->frame_rate = self->priv->max_frame_rate = 100000.0f;
- self->priv->grab_thread = NULL;
- self->priv->current_frame = 0;
-
- self->priv->binnings = g_value_array_new(1);
- GValue val = {0};
- g_value_init(&val, G_TYPE_UINT);
- g_value_set_uint(&val, 1);
- g_value_array_append(self->priv->binnings, &val);
-}
diff --git a/src/cameras/uca-mock-camera.h b/src/cameras/uca-mock-camera.h
deleted file mode 100644
index 92030f8..0000000
--- a/src/cameras/uca-mock-camera.h
+++ /dev/null
@@ -1,67 +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 */
-
-#ifndef __UCA_MOCK_CAMERA_H
-#define __UCA_MOCK_CAMERA_H
-
-#include <glib-object.h>
-#include "uca-camera.h"
-
-G_BEGIN_DECLS
-
-#define UCA_TYPE_MOCK_CAMERA (uca_mock_camera_get_type())
-#define UCA_MOCK_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCamera))
-#define UCA_IS_MOCK_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_MOCK_CAMERA))
-#define UCA_MOCK_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_MOCK_CAMERA, UfoMockCameraClass))
-#define UCA_IS_MOCK_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_MOCK_CAMERA))
-#define UCA_MOCK_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCameraClass))
-
-typedef struct _UcaMockCamera UcaMockCamera;
-typedef struct _UcaMockCameraClass UcaMockCameraClass;
-typedef struct _UcaMockCameraPrivate UcaMockCameraPrivate;
-
-/**
- * UcaMockCamera:
- *
- * Creates #UcaMockCamera instances by loading corresponding shared objects. The
- * contents of the #UcaMockCamera structure are private and should only be
- * accessed via the provided API.
- */
-struct _UcaMockCamera {
- /*< private >*/
- UcaCamera parent;
-
- UcaMockCameraPrivate *priv;
-};
-
-/**
- * UcaMockCameraClass:
- *
- * #UcaMockCamera class
- */
-struct _UcaMockCameraClass {
- /*< private >*/
- UcaCameraClass parent;
-};
-
-UcaMockCamera *uca_mock_camera_new(GError **error);
-
-GType uca_mock_camera_get_type(void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c
deleted file mode 100644
index a56392f..0000000
--- a/src/cameras/uca-pco-camera.c
+++ /dev/null
@@ -1,1396 +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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <libpco/libpco.h>
-#include <libpco/sc2_defs.h>
-#include <fgrab_prototyp.h>
-#include "uca-camera.h"
-#include "uca-pco-camera.h"
-#include "uca-enums.h"
-
-#define FG_TRY_PARAM(fg, camobj, param, val_addr, port) \
- { int r = Fg_setParameter(fg, param, val_addr, port); \
- if (r != FG_OK) { \
- g_set_error(error, UCA_PCO_CAMERA_ERROR, \
- UCA_PCO_CAMERA_ERROR_FG_GENERAL, \
- "%s", Fg_getLastErrorDescription(fg)); \
- g_object_unref(camobj); \
- return NULL; \
- } }
-
-#define FG_SET_ERROR(err, fg, err_type) \
- if (err != FG_OK) { \
- g_set_error(error, UCA_PCO_CAMERA_ERROR, \
- err_type, \
- "%s", Fg_getLastErrorDescription(fg)); \
- return; \
- }
-
-#define HANDLE_PCO_ERROR(err) \
- if ((err) != PCO_NOERROR) { \
- g_set_error(error, UCA_PCO_CAMERA_ERROR, \
- UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL,\
- "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)
-
-#define TIMEBASE_INVALID 0xDEAD
-
-/**
- * UcaPcoCameraRecordMode:
- * @UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE: Store all frames and stop if necessary
- * @UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER: Store frames in ring-buffer fashion
- * and overwrite if necessary
- */
-
-/**
- * UcaPcoCameraAcquireMode:
- * @UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO: Take all images
- * @UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL: Use <acq enbl> signal
- */
-
-/**
- * UcaPcoCameraTimestamp:
- * @UCA_PCO_CAMERA_TIMESTAMP_NONE: Don't embed any timestamp
- * @UCA_PCO_CAMERA_TIMESTAMP_BINARY: Embed a BCD-coded timestamp in the first
- * bytes
- * @UCA_PCO_CAMERA_TIMESTAMP_ASCII: Embed a visible ASCII timestamp in the image
- */
-
-/**
- * UcaPcoCameraError:
- * @UCA_PCO_CAMERA_ERROR_LIBPCO_INIT: Initializing libpco failed
- * @UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL: General libpco error
- * @UCA_PCO_CAMERA_ERROR_UNSUPPORTED: Camera type is not supported
- * @UCA_PCO_CAMERA_ERROR_FG_INIT: Framegrabber initialization failed
- * @UCA_PCO_CAMERA_ERROR_FG_GENERAL: General framegrabber error
- * @UCA_PCO_CAMERA_ERROR_FG_ACQUISITION: Framegrabber acquisition error
- */
-GQuark uca_pco_camera_error_quark()
-{
- return g_quark_from_static_string("uca-pco-camera-error-quark");
-}
-
-enum {
- PROP_SENSOR_EXTENDED = N_BASE_PROPERTIES,
- PROP_SENSOR_WIDTH_EXTENDED,
- PROP_SENSOR_HEIGHT_EXTENDED,
- PROP_SENSOR_TEMPERATURE,
- PROP_SENSOR_PIXELRATES,
- PROP_SENSOR_PIXELRATE,
- PROP_SENSOR_ADCS,
- PROP_SENSOR_MAX_ADCS,
- PROP_DELAY_TIME,
- PROP_HAS_DOUBLE_IMAGE_MODE,
- PROP_DOUBLE_IMAGE_MODE,
- PROP_OFFSET_MODE,
- PROP_RECORD_MODE,
- PROP_ACQUIRE_MODE,
- PROP_COOLING_POINT,
- PROP_COOLING_POINT_MIN,
- PROP_COOLING_POINT_MAX,
- PROP_COOLING_POINT_DEFAULT,
- PROP_NOISE_FILTER,
- PROP_TIMESTAMP_MODE,
- N_PROPERTIES
-};
-
-static gint base_overrideables[] = {
- PROP_NAME,
- PROP_SENSOR_WIDTH,
- PROP_SENSOR_HEIGHT,
- PROP_SENSOR_BITDEPTH,
- PROP_SENSOR_HORIZONTAL_BINNING,
- PROP_SENSOR_HORIZONTAL_BINNINGS,
- PROP_SENSOR_VERTICAL_BINNING,
- PROP_SENSOR_VERTICAL_BINNINGS,
- PROP_SENSOR_MAX_FRAME_RATE,
- PROP_EXPOSURE_TIME,
- PROP_TRIGGER_MODE,
- PROP_ROI_X,
- PROP_ROI_Y,
- PROP_ROI_WIDTH,
- PROP_ROI_HEIGHT,
- PROP_ROI_WIDTH_MULTIPLIER,
- PROP_ROI_HEIGHT_MULTIPLIER,
- PROP_HAS_STREAMING,
- PROP_HAS_CAMRAM_RECORDING,
- 0
-};
-
-static GParamSpec *pco_properties[N_PROPERTIES] = { NULL, };
-
-/*
- * This structure defines type-specific properties of PCO cameras.
- */
-typedef struct {
- int camera_type;
- const char *so_file;
- int cl_type;
- int cl_format;
- gfloat max_frame_rate;
- gboolean has_camram;
-} pco_cl_map_entry;
-
-struct _UcaPcoCameraPrivate {
- pco_handle pco;
- pco_cl_map_entry *camera_description;
-
- Fg_Struct *fg;
- guint fg_port;
- dma_mem *fg_mem;
-
- guint frame_width;
- guint frame_height;
- gsize num_bytes;
- guint16 *grab_buffer;
-
- guint16 width, height;
- guint16 width_ex, height_ex;
- guint16 binning_h, binning_v;
- guint16 roi_x, roi_y;
- guint16 roi_width, roi_height;
- guint16 roi_horizontal_steps, roi_vertical_steps;
- GValueArray *horizontal_binnings;
- GValueArray *vertical_binnings;
- GValueArray *pixelrates;
-
- /* The time bases are given as pco time bases (TIMEBASE_NS and so on) */
- guint16 delay_timebase;
- guint16 exposure_timebase;
-
- frameindex_t last_frame;
- guint16 active_segment;
- guint num_recorded_images;
- guint current_image;
-};
-
-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 },
- { 0, NULL, 0, 0, 0.0f, FALSE }
-};
-
-static pco_cl_map_entry *get_pco_cl_map_entry(int camera_type)
-{
- pco_cl_map_entry *entry = pco_cl_map;
-
- while (entry->camera_type != 0) {
- if (entry->camera_type == camera_type)
- return entry;
- entry++;
- }
-
- return NULL;
-}
-
-static guint fill_binnings(UcaPcoCameraPrivate *priv)
-{
- uint16_t *horizontal = NULL;
- uint16_t *vertical = NULL;
- guint num_horizontal, num_vertical;
-
- guint err = pco_get_possible_binnings(priv->pco,
- &horizontal, &num_horizontal,
- &vertical, &num_vertical);
-
- GValue val = {0};
- g_value_init(&val, G_TYPE_UINT);
-
- if (err == PCO_NOERROR) {
- priv->horizontal_binnings = g_value_array_new(num_horizontal);
- priv->vertical_binnings = g_value_array_new(num_vertical);
-
- for (guint i = 0; i < num_horizontal; i++) {
- g_value_set_uint(&val, horizontal[i]);
- g_value_array_append(priv->horizontal_binnings, &val);
- }
-
- for (guint i = 0; i < num_vertical; i++) {
- g_value_set_uint(&val, vertical[i]);
- g_value_array_append(priv->vertical_binnings, &val);
- }
- }
-
- free(horizontal);
- free(vertical);
- return err;
-}
-
-static void fill_pixelrates(UcaPcoCameraPrivate *priv, guint32 rates[4], gint num_rates)
-{
- GValue val = {0};
- g_value_init(&val, G_TYPE_UINT);
- 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_array_append(priv->pixelrates, &val);
- }
-}
-
-static guint override_temperature_range(UcaPcoCameraPrivate *priv)
-{
- int16_t default_temp, min_temp, max_temp;
- guint err = pco_get_cooling_range(priv->pco, &default_temp, &min_temp, &max_temp);
-
- if (err == PCO_NOERROR) {
- GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT];
- spec->minimum = min_temp;
- spec->maximum = max_temp;
- spec->default_value = default_temp;
- }
- else
- g_warning("Unable to retrieve cooling range");
-
- return err;
-}
-
-static void property_override_default_guint_value (GObjectClass *oclass, const gchar *property_name, guint new_default)
-{
- GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (g_object_class_find_property (oclass, property_name));
-
- if (pspec != NULL)
- pspec->default_value = new_default;
- else
- g_warning ("pspec for %s not found\n", property_name);
-}
-
-static void override_maximum_adcs(UcaPcoCameraPrivate *priv)
-{
- GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_SENSOR_ADCS];
- spec->maximum = pco_get_maximum_number_of_adcs(priv->pco);
-}
-
-static gdouble convert_timebase(guint16 timebase)
-{
- switch (timebase) {
- case TIMEBASE_NS:
- return 1e-9;
- case TIMEBASE_US:
- return 1e-6;
- case TIMEBASE_MS:
- return 1e-3;
- default:
- g_warning("Unknown timebase");
- }
- return 1e-3;
-}
-
-static void read_timebase(UcaPcoCameraPrivate *priv)
-{
- pco_get_timebase(priv->pco, &priv->delay_timebase, &priv->exposure_timebase);
-}
-
-static gdouble get_suitable_timebase(gdouble time)
-{
- if (time * 1e3 >= 1.0)
- return TIMEBASE_MS;
- if (time * 1e6 >= 1.0)
- return TIMEBASE_US;
- if (time * 1e9 >= 1.0)
- return TIMEBASE_NS;
- 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);
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
- gpointer data = Fg_getImagePtrEx(priv->fg, frame, priv->fg_port, priv->fg_mem);
-
- if (priv->camera_description->camera_type != CAMERATYPE_PCO_EDGE)
- camera->grab_func(data, camera->user_data);
- else {
- pco_get_reorder_func(priv->pco)(priv->grab_buffer, data, priv->frame_width, priv->frame_height);
- camera->grab_func(priv->grab_buffer, camera->user_data);
- }
-
- return 0;
-}
-
-static gboolean setup_fg_callback(UcaCamera *camera)
-{
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
- struct FgApcControl ctrl;
-
- /* Jeez, as if a NULL pointer would not be good enough. */
- ctrl.data = (struct fg_apc_data *) camera;
- ctrl.version = 0;
- ctrl.func = &fg_callback;
- ctrl.flags = FG_APC_DEFAULTS;
- ctrl.timeout = 1;
-
- if (priv->grab_buffer)
- g_free(priv->grab_buffer);
-
- priv->grab_buffer = g_malloc0(priv->frame_width * priv->frame_height * sizeof(guint16));
-
- return Fg_registerApcHandler(priv->fg, priv->fg_port, &ctrl, FG_APC_CONTROL_BASIC) == FG_OK;
-}
-
-static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
- guint err = PCO_NOERROR;
-
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
- guint16 binned_width, binned_height;
- gboolean use_extended = FALSE;
- gboolean transfer_async = FALSE;
-
- g_object_get (camera, "sensor-extended", &use_extended, NULL);
-
- if (use_extended) {
- binned_width = priv->width_ex;
- binned_height = priv->height_ex;
- }
- else {
- binned_width = priv->width;
- binned_height = priv->height;
- }
-
- binned_width /= priv->binning_h;
- binned_height /= priv->binning_v;
-
- if ((priv->roi_x + priv->roi_width > binned_width) || (priv->roi_y + priv->roi_height > binned_height)) {
- g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED,
- "ROI of size %ix%i @ (%i, %i) is outside of (binned) sensor size %ix%i\n",
- priv->roi_width, priv->roi_height, priv->roi_x, priv->roi_y, binned_width, binned_height);
- return;
- }
-
- /*
- * All parameters are valid. Now, set them on the camera.
- */
- guint16 roi[4] = { priv->roi_x + 1, priv->roi_y + 1, priv->roi_x + priv->roi_width, priv->roi_y + priv->roi_height };
-
- if (pco_set_roi(priv->pco, roi) != PCO_NOERROR) {
- g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL,
- "Could not set ROI via pco_set_roi()");
- return;
- }
-
- g_object_get(G_OBJECT(camera), "transfer-asynchronously", &transfer_async, NULL);
-
- /*
- * FIXME: We cannot set the binning here as this breaks communication with
- * the camera. Setting the binning works _before_ initializing the frame
- * grabber though. However, it is rather inconvenient to initialize and
- * de-initialize the frame grabber for each recording sequence.
- */
-
- /* if (pco_set_binning(priv->pco, priv->binning_h, priv->binning_v) != PCO_NOERROR) */
- /* g_warning("Cannot set binning\n"); */
-
- if (priv->frame_width != priv->roi_width || priv->frame_height != priv->roi_height || priv->fg_mem == NULL) {
- guint fg_width = priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE ? 2 * priv->roi_width : priv->roi_width;
-
- priv->frame_width = priv->roi_width;
- priv->frame_height = priv->roi_height;
- priv->num_bytes = 2;
-
- Fg_setParameter(priv->fg, FG_WIDTH, &fg_width, priv->fg_port);
- Fg_setParameter(priv->fg, FG_HEIGHT, &priv->frame_height, priv->fg_port);
-
- if (priv->fg_mem)
- Fg_FreeMemEx(priv->fg, priv->fg_mem);
-
- const guint num_buffers = 2;
- 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) {
- g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_FG_INIT,
- "%s", Fg_getLastErrorDescription(priv->fg));
- g_object_unref(camera);
- return;
- }
- }
-
- if (transfer_async)
- setup_fg_callback(camera);
-
- if ((priv->camera_description->camera_type == CAMERATYPE_PCO_DIMAX_STD) ||
- (priv->camera_description->camera_type == CAMERATYPE_PCO4000))
- pco_clear_active_segment(priv->pco);
-
- priv->last_frame = 0;
-
- err = pco_arm_camera(priv->pco);
- HANDLE_PCO_ERROR(err);
-
- err = pco_start_recording(priv->pco);
- HANDLE_PCO_ERROR(err);
-
- err = Fg_AcquireEx(priv->fg, priv->fg_port, GRAB_INFINITE, ACQ_STANDARD, priv->fg_mem);
- FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_ACQUISITION);
-}
-
-static void uca_pco_camera_stop_recording(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
-
- guint err = pco_stop_recording(priv->pco);
- HANDLE_PCO_ERROR(err);
-
- err = Fg_stopAcquireEx(priv->fg, priv->fg_port, priv->fg_mem, STOP_SYNC);
- FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_ACQUISITION);
-
- err = Fg_setStatusEx(priv->fg, FG_UNBLOCK_ALL, 0, priv->fg_port, priv->fg_mem);
- if (err == FG_INVALID_PARAMETER)
- g_warning(" Unable to unblock all\n");
-}
-
-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.
- */
-
- guint err = pco_get_active_segment(priv->pco, &priv->active_segment);
- HANDLE_PCO_ERROR(err);
-
- err = pco_get_num_images(priv->pco, priv->active_segment, &priv->num_recorded_images);
- HANDLE_PCO_ERROR(err);
-
- priv->current_image = 1;
-}
-
-static void uca_pco_camera_trigger(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
-
- /* TODO: Check if we can trigger */
- guint32 success = 0;
- pco_force_trigger(priv->pco, &success);
-
- if (!success)
- g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL,
- "Could not trigger frame acquisition");
-}
-
-static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
-{
- static const gint MAX_TIMEOUT = G_MAXINT;
-
- g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
-
- gboolean is_readout = FALSE;
- g_object_get(G_OBJECT(camera), "is-readout", &is_readout, NULL);
-
- if (is_readout) {
- if (priv->current_image == priv->num_recorded_images) {
- *data = NULL;
- return;
- }
-
- /*
- * No joke, the pco firmware allows to read a range of images but
- * implements only reading single images ...
- */
- pco_read_images(priv->pco, priv->active_segment, priv->current_image, priv->current_image);
- priv->current_image++;
- }
-
- 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);
- }
-
- 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);
-
- if (priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE)
- pco_get_reorder_func(priv->pco)((guint16 *) *data, frame, priv->frame_width, priv->frame_height);
- else
- memcpy((gchar *) *data, (gchar *) frame, priv->frame_width * priv->frame_height * priv->num_bytes);
-}
-
-static void uca_pco_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_SENSOR_EXTENDED:
- {
- guint16 format = g_value_get_boolean (value) ? SENSORFORMAT_EXTENDED : SENSORFORMAT_STANDARD;
- pco_set_sensor_format(priv->pco, format);
- }
- break;
-
- case PROP_ROI_X:
- priv->roi_x = g_value_get_uint(value);
- break;
-
- case PROP_ROI_Y:
- priv->roi_y = g_value_get_uint(value);
- break;
-
- 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
- priv->roi_width = width;
- }
- break;
-
- 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
- priv->roi_height = height;
- }
- break;
-
- case PROP_SENSOR_HORIZONTAL_BINNING:
- priv->binning_h = g_value_get_uint(value);
- break;
-
- case PROP_SENSOR_VERTICAL_BINNING:
- priv->binning_v = g_value_get_uint(value);
- break;
-
- case PROP_EXPOSURE_TIME:
- {
- const gdouble time = g_value_get_double(value);
-
- if (priv->exposure_timebase == TIMEBASE_INVALID)
- read_timebase(priv);
-
- /*
- * Lets check if we can express the time in the current time
- * base. If not, we need to adjust that.
- */
- guint16 suitable_timebase = get_suitable_timebase(time);
-
- if (suitable_timebase == TIMEBASE_INVALID) {
- g_warning("Cannot set such a small exposure time");
- }
- else {
- if (suitable_timebase != priv->exposure_timebase) {
- priv->exposure_timebase = suitable_timebase;
- if (pco_set_timebase(priv->pco, priv->delay_timebase, suitable_timebase) != PCO_NOERROR)
- g_warning("Cannot set exposure time base");
- }
-
- gdouble timebase = convert_timebase(suitable_timebase);
- guint32 timesteps = time / timebase;
- if (pco_set_exposure_time(priv->pco, timesteps) != PCO_NOERROR)
- g_warning("Cannot set exposure time");
- }
- }
- break;
-
- case PROP_DELAY_TIME:
- {
- const gdouble time = g_value_get_double(value);
-
- if (priv->delay_timebase == TIMEBASE_INVALID)
- read_timebase(priv);
-
- /*
- * Lets check if we can express the time in the current time
- * base. If not, we need to adjust that.
- */
- guint16 suitable_timebase = get_suitable_timebase(time);
-
- if (suitable_timebase == TIMEBASE_INVALID) {
- if (time == 0.0) {
- /*
- * If we want to suppress any pre-exposure delays, we
- * can set the 0 seconds in whatever time base that is
- * currently active.
- */
- if (pco_set_delay_time(priv->pco, 0) != PCO_NOERROR)
- g_warning("Cannot set zero delay time");
- }
- else
- g_warning("Cannot set such a small exposure time");
- }
- else {
- if (suitable_timebase != priv->delay_timebase) {
- priv->delay_timebase = suitable_timebase;
- if (pco_set_timebase(priv->pco, suitable_timebase, priv->exposure_timebase) != PCO_NOERROR)
- g_warning("Cannot set delay time base");
- }
-
- gdouble timebase = convert_timebase(suitable_timebase);
- guint32 timesteps = time / timebase;
- if (pco_set_delay_time(priv->pco, timesteps) != PCO_NOERROR)
- g_warning("Cannot set delay time");
- }
- }
- break;
-
- case PROP_SENSOR_ADCS:
- {
- 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");
- }
- break;
-
- case PROP_SENSOR_PIXELRATE:
- {
- guint desired_pixel_rate = g_value_get_uint(value);
- guint32 pixel_rate = 0;
-
- 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;
- break;
- }
- }
-
- if (pixel_rate != 0) {
- if (pco_set_pixelrate(priv->pco, pixel_rate) != PCO_NOERROR)
- g_warning("Cannot set pixel rate");
- }
- else
- g_warning("%i Hz is not possible. Please check the \"sensor-pixelrates\" property", desired_pixel_rate);
- }
- break;
-
- case PROP_DOUBLE_IMAGE_MODE:
- if (!pco_is_double_image_mode_available(priv->pco))
- g_warning("Double image mode is not available on this pco model");
- else
- pco_set_double_image_mode(priv->pco, g_value_get_boolean(value));
- break;
-
- case PROP_OFFSET_MODE:
- pco_set_offset_mode(priv->pco, g_value_get_boolean(value));
- break;
-
- case PROP_COOLING_POINT:
- {
- int16_t temperature = (int16_t) g_value_get_int(value);
- pco_set_cooling_temperature(priv->pco, temperature);
- }
- break;
-
- case PROP_RECORD_MODE:
- {
- /* TODO: setting this is not possible for the edge */
- UcaPcoCameraRecordMode mode = (UcaPcoCameraRecordMode) g_value_get_enum(value);
-
- if (mode == UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE)
- pco_set_record_mode(priv->pco, RECORDER_SUBMODE_SEQUENCE);
- else if (mode == UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER)
- pco_set_record_mode(priv->pco, RECORDER_SUBMODE_RINGBUFFER);
- else
- g_warning("Unknown record mode");
- }
- break;
-
- case PROP_ACQUIRE_MODE:
- {
- UcaPcoCameraAcquireMode mode = (UcaPcoCameraAcquireMode) g_value_get_enum(value);
- unsigned int err = PCO_NOERROR;
-
- if (mode == UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO)
- err = pco_set_acquire_mode(priv->pco, ACQUIRE_MODE_AUTO);
- else if (mode == UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL)
- err = pco_set_acquire_mode(priv->pco, ACQUIRE_MODE_EXTERNAL);
- else
- g_warning("Unknown acquire mode");
-
- if (err != PCO_NOERROR)
- g_warning("Cannot set acquire mode");
- }
- break;
-
- case PROP_TRIGGER_MODE:
- {
- UcaCameraTrigger trigger_mode = (UcaCameraTrigger) g_value_get_enum(value);
-
- switch (trigger_mode) {
- case UCA_CAMERA_TRIGGER_AUTO:
- pco_set_trigger_mode(priv->pco, TRIGGER_MODE_AUTOTRIGGER);
- break;
- case UCA_CAMERA_TRIGGER_INTERNAL:
- pco_set_trigger_mode(priv->pco, TRIGGER_MODE_SOFTWARETRIGGER);
- break;
- case UCA_CAMERA_TRIGGER_EXTERNAL:
- pco_set_trigger_mode(priv->pco, TRIGGER_MODE_EXTERNALTRIGGER);
- break;
- }
- }
- break;
-
- case PROP_NOISE_FILTER:
- {
- guint16 filter_mode = g_value_get_boolean(value) ? NOISE_FILTER_MODE_ON : NOISE_FILTER_MODE_OFF;
- pco_set_noise_filter_mode(priv->pco, filter_mode);
- }
- break;
-
- 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 */
- };
- pco_set_timestamp_mode(priv->pco, modes[g_value_get_flags(value)]);
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- return;
- }
-}
-
-static void uca_pco_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_SENSOR_EXTENDED:
- {
- guint16 format;
- pco_get_sensor_format(priv->pco, &format);
- g_value_set_boolean(value, format == SENSORFORMAT_EXTENDED);
- }
- break;
-
- case PROP_SENSOR_WIDTH:
- g_value_set_uint(value, priv->width);
- break;
-
- case PROP_SENSOR_HEIGHT:
- g_value_set_uint(value, priv->height);
- break;
-
- case PROP_SENSOR_WIDTH_EXTENDED:
- g_value_set_uint(value, priv->width_ex < priv->width ? priv->width : priv->width_ex);
- break;
-
- case PROP_SENSOR_HEIGHT_EXTENDED:
- g_value_set_uint(value, priv->height_ex < priv->height ? priv->height : priv->height_ex);
- break;
-
- case PROP_SENSOR_HORIZONTAL_BINNING:
- g_value_set_uint(value, priv->binning_h);
- break;
-
- case PROP_SENSOR_HORIZONTAL_BINNINGS:
- g_value_set_boxed(value, priv->horizontal_binnings);
- break;
-
- case PROP_SENSOR_VERTICAL_BINNING:
- g_value_set_uint(value, priv->binning_v);
- break;
-
- case PROP_SENSOR_VERTICAL_BINNINGS:
- g_value_set_boxed(value, priv->vertical_binnings);
- break;
-
- case PROP_SENSOR_MAX_FRAME_RATE:
- g_value_set_float(value, priv->camera_description->max_frame_rate);
- break;
-
- case PROP_SENSOR_BITDEPTH:
- g_value_set_uint(value, 16);
- break;
-
- case PROP_SENSOR_TEMPERATURE:
- {
- gint32 ccd, camera, power;
- pco_get_temperature(priv->pco, &ccd, &camera, &power);
- g_value_set_double(value, ccd / 10.0);
- }
- break;
-
- case PROP_SENSOR_ADCS:
- {
- /*
- * Up to now, the ADC mode corresponds directly to the number of
- * ADCs in use.
- */
- 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);
- }
- break;
-
- case PROP_SENSOR_MAX_ADCS:
- {
- GParamSpecUInt *spec = (GParamSpecUInt *) pco_properties[PROP_SENSOR_ADCS];
- g_value_set_uint(value, spec->maximum);
- }
- break;
-
- case PROP_SENSOR_PIXELRATES:
- g_value_set_boxed(value, priv->pixelrates);
- break;
-
- case PROP_SENSOR_PIXELRATE:
- {
- guint32 pixelrate;
- pco_get_pixelrate(priv->pco, &pixelrate);
- g_value_set_uint(value, pixelrate);
- }
- break;
-
- case PROP_EXPOSURE_TIME:
- {
- uint32_t exposure_time;
- pco_get_exposure_time(priv->pco, &exposure_time);
-
- if (priv->exposure_timebase == TIMEBASE_INVALID)
- read_timebase(priv);
-
- g_value_set_double(value, convert_timebase(priv->exposure_timebase) * exposure_time);
- }
- break;
-
- case PROP_DELAY_TIME:
- {
- uint32_t delay_time;
- pco_get_delay_time(priv->pco, &delay_time);
-
- if (priv->delay_timebase == TIMEBASE_INVALID)
- read_timebase(priv);
-
- g_value_set_double(value, convert_timebase(priv->delay_timebase) * delay_time);
- }
- break;
-
- case PROP_HAS_DOUBLE_IMAGE_MODE:
- g_value_set_boolean(value, pco_is_double_image_mode_available(priv->pco));
- break;
-
- case PROP_DOUBLE_IMAGE_MODE:
- if (!pco_is_double_image_mode_available(priv->pco))
- g_warning("Double image mode is not available on this pco model");
- else {
- bool on;
- pco_get_double_image_mode(priv->pco, &on);
- g_value_set_boolean(value, on);
- }
- break;
-
- case PROP_OFFSET_MODE:
- {
- bool on;
- pco_get_offset_mode(priv->pco, &on);
- g_value_set_boolean(value, on);
- }
- break;
-
- case PROP_HAS_STREAMING:
- g_value_set_boolean(value, TRUE);
- break;
-
- case PROP_HAS_CAMRAM_RECORDING:
- g_value_set_boolean(value, priv->camera_description->has_camram);
- break;
-
- case PROP_RECORD_MODE:
- {
- guint16 mode;
- pco_get_record_mode(priv->pco, &mode);
-
- if (mode == RECORDER_SUBMODE_SEQUENCE)
- g_value_set_enum(value, UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE);
- else if (mode == RECORDER_SUBMODE_RINGBUFFER)
- g_value_set_enum(value, UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER);
- else
- g_warning("pco record mode not handled");
- }
- break;
-
- case PROP_ACQUIRE_MODE:
- {
- guint16 mode;
- pco_get_acquire_mode(priv->pco, &mode);
-
- if (mode == ACQUIRE_MODE_AUTO)
- g_value_set_enum(value, UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO);
- else if (mode == ACQUIRE_MODE_EXTERNAL)
- g_value_set_enum(value, UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL);
- else
- g_warning("pco acquire mode not handled");
- }
- break;
-
- case PROP_TRIGGER_MODE:
- {
- guint16 mode;
- pco_get_trigger_mode(priv->pco, &mode);
-
- switch (mode) {
- case TRIGGER_MODE_AUTOTRIGGER:
- g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO);
- break;
- case TRIGGER_MODE_SOFTWARETRIGGER:
- g_value_set_enum(value, UCA_CAMERA_TRIGGER_INTERNAL);
- break;
- case TRIGGER_MODE_EXTERNALTRIGGER:
- g_value_set_enum(value, UCA_CAMERA_TRIGGER_EXTERNAL);
- break;
- default:
- g_warning("pco trigger mode not handled");
- }
- }
- break;
-
- case PROP_ROI_X:
- g_value_set_uint(value, priv->roi_x);
- break;
-
- case PROP_ROI_Y:
- g_value_set_uint(value, priv->roi_y);
- break;
-
- case PROP_ROI_WIDTH:
- g_value_set_uint(value, priv->roi_width);
- break;
-
- case PROP_ROI_HEIGHT:
- g_value_set_uint(value, priv->roi_height);
- break;
-
- case PROP_ROI_WIDTH_MULTIPLIER:
- g_value_set_uint(value, priv->roi_horizontal_steps);
- break;
-
- case PROP_ROI_HEIGHT_MULTIPLIER:
- g_value_set_uint(value, priv->roi_vertical_steps);
- break;
-
- case PROP_NAME:
- {
- gchar *name = NULL;
- pco_get_name(priv->pco, &name);
- g_value_set_string(value, name);
- g_free(name);
- }
- break;
-
- case PROP_COOLING_POINT:
- {
- 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);
- }
- break;
-
- case PROP_COOLING_POINT_MIN:
- {
- GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT];
- g_value_set_int(value, spec->minimum);
- }
- break;
-
- case PROP_COOLING_POINT_MAX:
- {
- GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT];
- g_value_set_int(value, spec->maximum);
- }
- break;
-
- case PROP_COOLING_POINT_DEFAULT:
- {
- GParamSpecInt *spec = (GParamSpecInt *) pco_properties[PROP_COOLING_POINT];
- g_value_set_int(value, spec->default_value);
- }
- break;
-
- case PROP_NOISE_FILTER:
- {
- guint16 mode;
- pco_get_noise_filter_mode(priv->pco, &mode);
- g_value_set_boolean(value, mode != NOISE_FILTER_MODE_OFF);
- }
- break;
-
- case PROP_TIMESTAMP_MODE:
- {
- guint16 mode;
- pco_get_timestamp_mode(priv->pco, &mode);
-
- switch (mode) {
- case TIMESTAMP_MODE_OFF:
- g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_NONE);
- break;
- case TIMESTAMP_MODE_BINARY:
- g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_BINARY);
- break;
- case TIMESTAMP_MODE_BINARYANDASCII:
- g_value_set_flags(value,
- UCA_PCO_CAMERA_TIMESTAMP_BINARY | UCA_PCO_CAMERA_TIMESTAMP_ASCII);
- break;
- case TIMESTAMP_MODE_ASCII:
- g_value_set_flags(value, UCA_PCO_CAMERA_TIMESTAMP_ASCII);
- break;
- }
- }
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void uca_pco_camera_finalize(GObject *object)
-{
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object);
-
- if (priv->horizontal_binnings)
- g_value_array_free(priv->horizontal_binnings);
-
- if (priv->vertical_binnings)
- g_value_array_free(priv->vertical_binnings);
-
- if (priv->pixelrates)
- g_value_array_free(priv->pixelrates);
-
- if (priv->fg) {
- if (priv->fg_mem)
- Fg_FreeMemEx(priv->fg, priv->fg_mem);
-
- Fg_FreeGrabber(priv->fg);
- }
-
- if (priv->pco)
- pco_destroy(priv->pco);
-
- g_free(priv->grab_buffer);
-
- G_OBJECT_CLASS(uca_pco_camera_parent_class)->finalize(object);
-}
-
-static void uca_pco_camera_class_init(UcaPcoCameraClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->set_property = uca_pco_camera_set_property;
- gobject_class->get_property = uca_pco_camera_get_property;
- gobject_class->finalize = uca_pco_camera_finalize;
-
- UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass);
- camera_class->start_recording = uca_pco_camera_start_recording;
- camera_class->stop_recording = uca_pco_camera_stop_recording;
- camera_class->start_readout = uca_pco_camera_start_readout;
- camera_class->trigger = uca_pco_camera_trigger;
- camera_class->grab = uca_pco_camera_grab;
-
- for (guint i = 0; base_overrideables[i] != 0; i++)
- g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]);
-
- /**
- * UcaPcoCamera:sensor-extended:
- *
- * Activate larger sensor area that contains surrounding pixels for dark
- * references and dummies. Use #UcaPcoCamera:sensor-width-extended and
- * #UcaPcoCamera:sensor-height-extended to query the resolution of the
- * larger area.
- */
- 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] =
- 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] =
- g_param_spec_uint("sensor-height-extended",
- "Height of extended sensor",
- "Height of the extended sensor in pixels",
- 1, G_MAXUINT, 1,
- G_PARAM_READABLE);
-
- /**
- * UcaPcoCamera:sensor-pixelrate:
- *
- * Read and write the pixel rate or clock of the sensor in terms of Hertz.
- * Make sure to query the possible pixel rates through the
- * #UcaPcoCamera:sensor-pixelrates property. Any other value will be
- * rejected by the camera.
- */
- 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] =
- 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] =
- g_param_spec_string("name",
- "Name of the camera",
- "Name of the camera",
- "", G_PARAM_READABLE);
-
- pco_properties[PROP_SENSOR_TEMPERATURE] =
- g_param_spec_double("sensor-temperature",
- "Temperature of the sensor",
- "Temperature of the sensor in degree Celsius",
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READABLE);
-
- 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] =
- g_param_spec_boolean("double-image-mode",
- "Use double image mode",
- "Use double image mode",
- FALSE, G_PARAM_READWRITE);
-
- 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",
- "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",
- "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",
- "Delay before starting actual exposure",
- 0.0, G_MAXDOUBLE, 0.0,
- G_PARAM_READWRITE);
-
- pco_properties[PROP_NOISE_FILTER] =
- g_param_spec_boolean("noise-filter",
- "Noise filter",
- "Noise filter",
- FALSE, G_PARAM_READWRITE);
-
- /**
- * UcaPcoCamera:cooling-point:
- *
- * The value range is set arbitrarily, because we are not yet connected to
- * the camera and just don't know the cooling range. We override these
- * values in #uca_pco_camera_new().
- */
- 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] =
- 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] =
- 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] =
- 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] =
- g_param_spec_uint("sensor-adcs",
- "Number of ADCs to use",
- "Number of ADCs to use",
- 1, 2, 1,
- G_PARAM_READWRITE);
-
- 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,
- G_PARAM_READABLE);
-
- pco_properties[PROP_TIMESTAMP_MODE] =
- g_param_spec_flags("timestamp-mode",
- "Timestamp mode",
- "Timestamp mode",
- UCA_TYPE_PCO_CAMERA_TIMESTAMP, UCA_PCO_CAMERA_TIMESTAMP_NONE,
- G_PARAM_READWRITE);
-
- for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++)
- g_object_class_install_property(gobject_class, id, pco_properties[id]);
-
- g_type_class_add_private(klass, sizeof(UcaPcoCameraPrivate));
-}
-
-static void uca_pco_camera_init(UcaPcoCamera *self)
-{
- self->priv = UCA_PCO_CAMERA_GET_PRIVATE(self);
- self->priv->fg = NULL;
- self->priv->fg_mem = NULL;
- self->priv->pco = NULL;
- self->priv->horizontal_binnings = NULL;
- self->priv->vertical_binnings = NULL;
- self->priv->pixelrates = NULL;
- self->priv->camera_description = NULL;
- self->priv->last_frame = 0;
- self->priv->grab_buffer = NULL;
-
- self->priv->delay_timebase = TIMEBASE_INVALID;
- self->priv->exposure_timebase = TIMEBASE_INVALID;
-}
diff --git a/src/cameras/uca-pco-camera.h b/src/cameras/uca-pco-camera.h
deleted file mode 100644
index fdb709a..0000000
--- a/src/cameras/uca-pco-camera.h
+++ /dev/null
@@ -1,93 +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 */
-
-#ifndef __UCA_PCO_CAMERA_H
-#define __UCA_PCO_CAMERA_H
-
-#include <glib-object.h>
-#include "uca-camera.h"
-
-G_BEGIN_DECLS
-
-#define UCA_TYPE_PCO_CAMERA (uca_pco_camera_get_type())
-#define UCA_PCO_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCamera))
-#define UCA_IS_PCO_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PCO_CAMERA))
-#define UCA_PCO_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_PCO_CAMERA, UcaPcoCameraClass))
-#define UCA_IS_PCO_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PCO_CAMERA))
-#define UCA_PCO_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraClass))
-
-#define UCA_PCO_CAMERA_ERROR uca_pco_camera_error_quark()
-typedef enum {
- UCA_PCO_CAMERA_ERROR_LIBPCO_INIT,
- UCA_PCO_CAMERA_ERROR_LIBPCO_GENERAL,
- UCA_PCO_CAMERA_ERROR_UNSUPPORTED,
- UCA_PCO_CAMERA_ERROR_FG_INIT,
- UCA_PCO_CAMERA_ERROR_FG_GENERAL,
- UCA_PCO_CAMERA_ERROR_FG_ACQUISITION
-} UcaPcoCameraError;
-
-typedef struct _UcaPcoCamera UcaPcoCamera;
-typedef struct _UcaPcoCameraClass UcaPcoCameraClass;
-typedef struct _UcaPcoCameraPrivate UcaPcoCameraPrivate;
-
-typedef enum {
- UCA_PCO_CAMERA_RECORD_MODE_SEQUENCE,
- UCA_PCO_CAMERA_RECORD_MODE_RING_BUFFER,
-} UcaPcoCameraRecordMode;
-
-typedef enum {
- UCA_PCO_CAMERA_ACQUIRE_MODE_AUTO,
- UCA_PCO_CAMERA_ACQUIRE_MODE_EXTERNAL
-} UcaPcoCameraAcquireMode;
-
-typedef enum {
- UCA_PCO_CAMERA_TIMESTAMP_NONE = 0,
- UCA_PCO_CAMERA_TIMESTAMP_BINARY = 1 << 0,
- UCA_PCO_CAMERA_TIMESTAMP_ASCII = 1 << 1
-} UcaPcoCameraTimestamp;
-
-/**
- * UcaPcoCamera:
- *
- * Creates #UcaPcoCamera instances by loading corresponding shared objects. The
- * contents of the #UcaPcoCamera structure are private and should only be
- * accessed via the provided API.
- */
-struct _UcaPcoCamera {
- /*< private >*/
- UcaCamera parent;
-
- UcaPcoCameraPrivate *priv;
-};
-
-/**
- * UcaPcoCameraClass:
- *
- * #UcaPcoCamera class
- */
-struct _UcaPcoCameraClass {
- /*< private >*/
- UcaCameraClass parent;
-};
-
-UcaPcoCamera *uca_pco_camera_new(GError **error);
-
-GType uca_pco_camera_get_type(void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/cameras/uca-pf-camera.c b/src/cameras/uca-pf-camera.c
deleted file mode 100644
index 5bc8c6b..0000000
--- a/src/cameras/uca-pf-camera.c
+++ /dev/null
@@ -1,349 +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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fgrab_struct.h>
-#include <fgrab_prototyp.h>
-#include <libpf/pfcam.h>
-#include <errno.h>
-#include "uca-camera.h"
-#include "uca-pf-camera.h"
-
-#define FG_TRY_PARAM(fg, camobj, param, val_addr, port) \
- { int r = Fg_setParameter(fg, param, val_addr, port); \
- if (r != FG_OK) { \
- g_set_error(error, UCA_PF_CAMERA_ERROR, \
- UCA_PF_CAMERA_ERROR_FG_GENERAL, \
- "%s", Fg_getLastErrorDescription(fg)); \
- g_object_unref(camobj); \
- return NULL; \
- } }
-
-#define FG_SET_ERROR(err, fg, err_type) \
- if (err != FG_OK) { \
- g_set_error(error, UCA_PF_CAMERA_ERROR, \
- err_type, \
- "%s", Fg_getLastErrorDescription(fg)); \
- return; \
- }
-
-#define UCA_PF_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PF_CAMERA, UcaPfCameraPrivate))
-
-G_DEFINE_TYPE(UcaPfCamera, uca_pf_camera, UCA_TYPE_CAMERA)
-
-/**
- * UcaPfCameraError:
- * @UCA_PF_CAMERA_ERROR_INIT: Initializing pcilib failed
- * @UCA_PF_CAMERA_ERROR_FG_GENERAL: Frame grabber errors
- * @UCA_PF_CAMERA_ERROR_FG_ACQUISITION: Acquisition errors related to the frame
- * grabber
- * @UCA_PF_CAMERA_ERROR_START_RECORDING: Starting failed
- * @UCA_PF_CAMERA_ERROR_STOP_RECORDING: Stopping failed
- */
-GQuark uca_pf_camera_error_quark()
-{
- return g_quark_from_static_string("uca-pf-camera-error-quark");
-}
-
-static gint base_overrideables[] = {
- PROP_NAME,
- PROP_SENSOR_WIDTH,
- PROP_SENSOR_HEIGHT,
- PROP_SENSOR_BITDEPTH,
- PROP_SENSOR_HORIZONTAL_BINNING,
- PROP_SENSOR_HORIZONTAL_BINNINGS,
- PROP_SENSOR_VERTICAL_BINNING,
- PROP_SENSOR_VERTICAL_BINNINGS,
- PROP_SENSOR_MAX_FRAME_RATE,
- PROP_EXPOSURE_TIME,
- PROP_ROI_X,
- PROP_ROI_Y,
- PROP_ROI_WIDTH,
- PROP_ROI_HEIGHT,
- PROP_ROI_WIDTH_MULTIPLIER,
- PROP_ROI_HEIGHT_MULTIPLIER,
- PROP_HAS_STREAMING,
- PROP_HAS_CAMRAM_RECORDING,
- 0
-};
-
-enum {
- PROP_FOO = N_BASE_PROPERTIES,
- N_PROPERTIES
-};
-
-
-struct _UcaPfCameraPrivate {
- guint roi_width;
- guint roi_height;
- guint last_frame;
-
- Fg_Struct *fg;
- guint fg_port;
- 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.
- */
-struct {
- UcaCamera *camera;
-} fg_apc_data;
-
-static int me4_callback(frameindex_t frame, struct fg_apc_data *apc)
-{
- UcaCamera *camera = UCA_CAMERA(apc);
- UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
- camera->grab_func(Fg_getImagePtrEx(priv->fg, frame, priv->fg_port, priv->fg_mem), camera->user_data);
- return 0;
-}
-
-static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PF_CAMERA(camera));
- UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
- guint err = FG_OK;
-
- if (priv->fg_mem == NULL) {
- const guint num_buffers = 2;
- priv->fg_mem = Fg_AllocMemEx(priv->fg, num_buffers * priv->roi_width * priv->roi_height, num_buffers);
-
- if (priv->fg_mem == NULL) {
- g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_FG_ACQUISITION,
- "%s", Fg_getLastErrorDescription(priv->fg));
- g_object_unref(camera);
- return;
- }
- }
-
- gboolean transfer_async = FALSE;
- g_object_get(G_OBJECT(camera),
- "transfer-asynchronously", &transfer_async,
- NULL);
-
- if (transfer_async) {
- struct FgApcControl ctrl = {
- .version = 0,
- .data = (struct fg_apc_data *) camera,
- .func = &me4_callback,
- .flags = FG_APC_DEFAULTS,
- .timeout = 1
- };
-
- err = Fg_registerApcHandler(priv->fg, priv->fg_port, &ctrl, FG_APC_CONTROL_BASIC);
- FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION);
- }
-
- err = Fg_AcquireEx(priv->fg, priv->fg_port, GRAB_INFINITE, ACQ_STANDARD, priv->fg_mem);
- FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION);
-}
-
-static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PF_CAMERA(camera));
- UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
-
- guint err = Fg_stopAcquireEx(priv->fg, priv->fg_port, priv->fg_mem, STOP_SYNC);
- FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION);
-
- err = Fg_setStatusEx(priv->fg, FG_UNBLOCK_ALL, 0, priv->fg_port, priv->fg_mem);
- if (err == FG_INVALID_PARAMETER)
- g_print(" Unable to unblock all\n");
-}
-
-static void uca_pf_camera_start_readout(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PF_CAMERA(camera));
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_IMPLEMENTED,
- "This photon focus camera does not support recording to internal memory");
-}
-
-static void uca_pf_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
-{
- g_return_if_fail(UCA_IS_PF_CAMERA(camera));
- 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);
- }
-
- guint16 *frame = Fg_getImagePtrEx(priv->fg, priv->last_frame, priv->fg_port, priv->fg_mem);
-
- if (*data == NULL)
- *data = g_malloc0(priv->roi_width * priv->roi_height);
-
- memcpy((gchar *) *data, (gchar *) frame, priv->roi_width * priv->roi_height);
-}
-
-static void uca_pf_camera_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);
- return;
- }
-}
-
-static void uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_SENSOR_WIDTH:
- g_value_set_uint(value, 1280);
- break;
- case PROP_SENSOR_HEIGHT:
- g_value_set_uint(value, 1024);
- break;
- case PROP_SENSOR_BITDEPTH:
- g_value_set_uint(value, 8);
- break;
- case PROP_SENSOR_HORIZONTAL_BINNING:
- break;
- case PROP_SENSOR_HORIZONTAL_BINNINGS:
- break;
- case PROP_SENSOR_VERTICAL_BINNING:
- break;
- case PROP_SENSOR_VERTICAL_BINNINGS:
- break;
- case PROP_SENSOR_MAX_FRAME_RATE:
- g_value_set_float(value, 488.0);
- break;
- case PROP_HAS_STREAMING:
- g_value_set_boolean(value, TRUE);
- break;
- case PROP_HAS_CAMRAM_RECORDING:
- g_value_set_boolean(value, FALSE);
- break;
- case PROP_EXPOSURE_TIME:
- break;
- case PROP_ROI_X:
- g_value_set_uint(value, 0);
- break;
- case PROP_ROI_Y:
- g_value_set_uint(value, 0);
- break;
- case PROP_ROI_WIDTH:
- g_value_set_uint(value, 1280);
- break;
- case PROP_ROI_HEIGHT:
- g_value_set_uint(value, 1024);
- break;
- case PROP_ROI_WIDTH_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
- case PROP_ROI_HEIGHT_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
- case PROP_NAME:
- g_value_set_string(value, "Photon Focus MV2-D1280-640-CL");
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void uca_pf_camera_finalize(GObject *object)
-{
- UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(object);
-
- if (priv->fg) {
- if (priv->fg_mem)
- Fg_FreeMemEx(priv->fg, priv->fg_mem);
-
- Fg_FreeGrabber(priv->fg);
- }
-
- G_OBJECT_CLASS(uca_pf_camera_parent_class)->finalize(object);
-}
-
-static void uca_pf_camera_class_init(UcaPfCameraClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->set_property = uca_pf_camera_set_property;
- gobject_class->get_property = uca_pf_camera_get_property;
- gobject_class->finalize = uca_pf_camera_finalize;
-
- UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass);
- camera_class->start_recording = uca_pf_camera_start_recording;
- camera_class->stop_recording = uca_pf_camera_stop_recording;
- camera_class->start_readout = uca_pf_camera_start_readout;
- camera_class->grab = uca_pf_camera_grab;
-
- for (guint i = 0; base_overrideables[i] != 0; i++)
- g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]);
-
- g_type_class_add_private(klass, sizeof(UcaPfCameraPrivate));
-}
-
-static void uca_pf_camera_init(UcaPfCamera *self)
-{
- self->priv = UCA_PF_CAMERA_GET_PRIVATE(self);
- self->priv->fg = NULL;
- self->priv->fg_mem = NULL;
- self->priv->last_frame = 0;
-}
diff --git a/src/cameras/uca-pf-camera.h b/src/cameras/uca-pf-camera.h
deleted file mode 100644
index 7e3fe2c..0000000
--- a/src/cameras/uca-pf-camera.h
+++ /dev/null
@@ -1,76 +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 */
-
-#ifndef __UCA_PF_CAMERA_H
-#define __UCA_PF_CAMERA_H
-
-#include <glib-object.h>
-#include "uca-camera.h"
-
-G_BEGIN_DECLS
-
-#define UCA_TYPE_PF_CAMERA (uca_pf_camera_get_type())
-#define UCA_PF_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PF_CAMERA, UcaPfCamera))
-#define UCA_IS_PF_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PF_CAMERA))
-#define UCA_PF_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_PF_CAMERA, UcaPfCameraClass))
-#define UCA_IS_PF_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PF_CAMERA))
-#define UCA_PF_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PF_CAMERA, UcaPfCameraClass))
-
-#define UCA_PF_CAMERA_ERROR uca_pf_camera_error_quark()
-typedef enum {
- UCA_PF_CAMERA_ERROR_INIT,
- UCA_PF_CAMERA_ERROR_FG_GENERAL,
- UCA_PF_CAMERA_ERROR_FG_ACQUISITION,
- UCA_PF_CAMERA_ERROR_START_RECORDING,
- UCA_PF_CAMERA_ERROR_STOP_RECORDING
-} UcaPfCameraError;
-
-typedef struct _UcaPfCamera UcaPfCamera;
-typedef struct _UcaPfCameraClass UcaPfCameraClass;
-typedef struct _UcaPfCameraPrivate UcaPfCameraPrivate;
-
-/**
- * UcaPfCamera:
- *
- * Creates #UcaPfCamera instances by loading corresponding shared objects. The
- * contents of the #UcaPfCamera structure are private and should only be
- * accessed via the provided API.
- */
-struct _UcaPfCamera {
- /*< private >*/
- UcaCamera parent;
-
- UcaPfCameraPrivate *priv;
-};
-
-/**
- * UcaPfCameraClass:
- *
- * #UcaPfCamera class
- */
-struct _UcaPfCameraClass {
- /*< private >*/
- UcaCameraClass parent;
-};
-
-UcaPfCamera *uca_pf_camera_new(GError **error);
-
-GType uca_pf_camera_get_type(void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/cameras/uca-pylon-camera.c b/src/cameras/uca-pylon-camera.c
deleted file mode 100644
index 541b69b..0000000
--- a/src/cameras/uca-pylon-camera.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* Copyright (C) 2012 Volker Kaiser <volker.kaiser@softwareschneiderei>
- (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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <libpyloncam/pylon_camera.h>
-#include "uca-camera.h"
-#include "uca-pylon-camera.h"
-
-#define UCA_PYLON_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PYLON_CAMERA, UcaPylonCameraPrivate))
-
-G_DEFINE_TYPE(UcaPylonCamera, uca_pylon_camera, UCA_TYPE_CAMERA)
-
-/**
- * UcapylonCameraError:
- * @UCA_PYLON_CAMERA_ERROR_LIBPYLON_INIT: Initializing libpylon failed
- * @UCA_PYLON_CAMERA_ERROR_LIBPYLON_GENERAL: General libpylon error
- * @UCA_PYLON_CAMERA_ERROR_UNSUPPORTED: Camera type is not supported
- * @UCA_PYLON_CAMERA_ERROR_FG_INIT: Framegrabber initialization failed
- * @UCA_PYLON_CAMERA_ERROR_FG_GENERAL: General framegrabber error
- * @UCA_PYLON_CAMERA_ERROR_FG_ACQUISITION: Framegrabber acquisition error
- */
-GQuark uca_pylon_camera_error_quark()
-{
- return g_quark_from_static_string("uca-pylon-camera-error-quark");
-}
-
-enum {
- PROP_ROI_WIDTH_DEFAULT = N_BASE_PROPERTIES,
- PROP_ROI_HEIGHT_DEFAULT,
- PROP_GAIN,
- N_PROPERTIES
-};
-
-static gint base_overrideables[] = {
- PROP_NAME,
- PROP_SENSOR_WIDTH,
- PROP_SENSOR_HEIGHT,
- PROP_SENSOR_BITDEPTH,
- PROP_SENSOR_HORIZONTAL_BINNING,
- PROP_SENSOR_HORIZONTAL_BINNINGS,
- PROP_SENSOR_VERTICAL_BINNING,
- PROP_SENSOR_VERTICAL_BINNINGS,
- PROP_SENSOR_MAX_FRAME_RATE,
- PROP_TRIGGER_MODE,
- PROP_EXPOSURE_TIME,
- PROP_ROI_X,
- PROP_ROI_Y,
- PROP_ROI_WIDTH,
- PROP_ROI_HEIGHT,
- PROP_ROI_WIDTH_MULTIPLIER,
- PROP_ROI_HEIGHT_MULTIPLIER,
- PROP_HAS_STREAMING,
- PROP_HAS_CAMRAM_RECORDING,
- 0
-};
-
-static GParamSpec *pylon_properties[N_PROPERTIES] = { NULL, };
-
-
-struct _UcaPylonCameraPrivate {
- guint bit_depth;
- gsize num_bytes;
-
- guint width;
- guint height;
- guint16 roi_x, roi_y;
- guint16 roi_width, roi_height;
- GValueArray *binnings;
-};
-
-
-static void pylon_get_roi(GObject *object, GError** error)
-{
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object);
- pylon_camera_get_roi(&priv->roi_x, &priv->roi_y, &priv->roi_width, &priv->roi_height, error);
-}
-
-static void pylon_set_roi(GObject *object, GError** error)
-{
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object);
- pylon_camera_set_roi(priv->roi_x, priv->roi_y, priv->roi_width, priv->roi_height, error);
-}
-
-UcaPylonCamera *uca_pylon_camera_new(GError **error)
-{
- UcaPylonCamera *camera = g_object_new(UCA_TYPE_PYLON_CAMERA, NULL);
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(camera);
-
- pylon_camera_new("/usr/local/lib64", "141.52.111.110", error);
-
- if (*error != NULL)
- return NULL;
-
- pylon_camera_get_sensor_size(&priv->width, &priv->height, error);
-
- if (*error != NULL)
- return NULL;
-
- return camera;
-}
-
-static void uca_pylon_camera_start_recording(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PYLON_CAMERA(camera));
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(camera);
-
- priv->num_bytes = 2;
- pylon_camera_start_acquision(error);
-
-}
-
-static void uca_pylon_camera_stop_recording(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_PYLON_CAMERA(camera));
- pylon_camera_stop_acquision(error);
-}
-
-static void uca_pylon_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
-{
- g_return_if_fail(UCA_IS_PYLON_CAMERA(camera));
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(camera);
-
- if (*data == NULL) {
- *data = g_malloc0(priv->width * priv->height * priv->num_bytes);
- }
- pylon_camera_grab(data, error);
-}
-
-static void uca_pylon_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object);
- GError* error = NULL;
-
- switch (property_id) {
- case PROP_SENSOR_HORIZONTAL_BINNING:
- /* intentional fall-through*/
- case PROP_SENSOR_VERTICAL_BINNING:
- /* intentional fall-through*/
- case PROP_TRIGGER_MODE:
- break;
-
- case PROP_ROI_X:
- {
- priv->roi_x = g_value_get_uint(value);
- pylon_set_roi(object, &error);
- }
- break;
-
- case PROP_ROI_Y:
- {
- priv->roi_y = g_value_get_uint(value);
- pylon_set_roi(object, &error);
- }
- break;
-
- case PROP_ROI_WIDTH:
- {
- priv->roi_width = g_value_get_uint(value);
- pylon_set_roi(object, &error);
- }
- break;
-
- case PROP_ROI_HEIGHT:
- {
- priv->roi_height = g_value_get_uint(value);
- pylon_set_roi(object, &error);
- }
- break;
-
- case PROP_EXPOSURE_TIME:
- pylon_camera_set_exposure_time(g_value_get_double(value), &error);
- break;
-
- case PROP_GAIN:
- pylon_camera_set_gain(g_value_get_int(value), &error);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- return;
- }
-}
-
-static void uca_pylon_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object);
- GError* error = NULL;
-
- switch (property_id) {
- case PROP_SENSOR_WIDTH:
- pylon_camera_get_sensor_size(&priv->width, &priv->height, &error);
- g_value_set_uint(value, priv->width);
- break;
-
- case PROP_SENSOR_HEIGHT:
- pylon_camera_get_sensor_size(&priv->width, &priv->height, &error);
- g_value_set_uint(value, priv->height);
- break;
-
- case PROP_SENSOR_BITDEPTH:
- pylon_camera_get_bit_depth(&priv->bit_depth, &error);
- g_value_set_uint(value, priv->bit_depth);
- break;
-
- case PROP_SENSOR_HORIZONTAL_BINNING:
- g_value_set_uint(value, 1);
- break;
-
- case PROP_SENSOR_HORIZONTAL_BINNINGS:
- g_value_set_boxed(value, priv->binnings);
- break;
-
- case PROP_SENSOR_VERTICAL_BINNING:
- g_value_set_uint(value, 1);
- break;
-
- case PROP_SENSOR_VERTICAL_BINNINGS:
- g_value_set_boxed(value, priv->binnings);
- break;
-
- case PROP_SENSOR_MAX_FRAME_RATE:
- g_value_set_float(value, 0.0);
- break;
-
- case PROP_TRIGGER_MODE:
- g_value_set_enum(value, UCA_CAMERA_TRIGGER_AUTO);
- break;
-
- case PROP_HAS_STREAMING:
- g_value_set_boolean(value, FALSE);
- break;
-
- case PROP_HAS_CAMRAM_RECORDING:
- g_value_set_boolean(value, FALSE);
- break;
-
- case PROP_ROI_X:
- {
- pylon_get_roi(object, &error);
- g_value_set_uint(value, priv->roi_x);
- }
- break;
-
- case PROP_ROI_Y:
- {
- pylon_get_roi(object, &error);
- g_value_set_uint(value, priv->roi_y);
- }
- break;
-
- case PROP_ROI_WIDTH:
- {
- pylon_get_roi(object, &error);
- g_value_set_uint(value, priv->roi_width);
- }
- break;
-
- case PROP_ROI_HEIGHT:
- {
- pylon_get_roi(object, &error);
- g_value_set_uint(value, priv->roi_height);
- }
- break;
-
- case PROP_ROI_WIDTH_DEFAULT:
- pylon_camera_get_sensor_size(&priv->width, &priv->height, &error);
- g_value_set_uint(value, priv->width);
- break;
-
- case PROP_ROI_HEIGHT_DEFAULT:
- pylon_camera_get_sensor_size(&priv->width, &priv->height, &error);
- g_value_set_uint(value, priv->height);
- break;
-
- case PROP_GAIN:
- {
- gint gain=0;
- pylon_camera_get_gain(&gain, &error);
- g_value_set_int(value, gain);
- }
- break;
-
- case PROP_ROI_WIDTH_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
-
- case PROP_ROI_HEIGHT_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
-
- case PROP_EXPOSURE_TIME:
- {
- gdouble exp_time = 0.0;
- pylon_camera_get_exposure_time(&exp_time, &error);
- g_value_set_double(value, exp_time);
- }
- break;
-
- case PROP_NAME:
- g_value_set_string(value, "Pylon Camera");
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void uca_pylon_camera_finalize(GObject *object)
-{
- UcaPylonCameraPrivate *priv = UCA_PYLON_CAMERA_GET_PRIVATE(object);
- g_value_array_free(priv->binnings);
-
- G_OBJECT_CLASS(uca_pylon_camera_parent_class)->finalize(object);
-}
-
-static void uca_pylon_camera_class_init(UcaPylonCameraClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->set_property = uca_pylon_camera_set_property;
- gobject_class->get_property = uca_pylon_camera_get_property;
- gobject_class->finalize = uca_pylon_camera_finalize;
-
- UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass);
- camera_class->start_recording = uca_pylon_camera_start_recording;
- camera_class->stop_recording = uca_pylon_camera_stop_recording;
- camera_class->grab = uca_pylon_camera_grab;
-
- for (guint i = 0; base_overrideables[i] != 0; i++)
- g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]);
-
- pylon_properties[PROP_NAME] =
- g_param_spec_string("name",
- "Name of the camera",
- "Name of the camera",
- "", G_PARAM_READABLE);
-
- pylon_properties[PROP_ROI_WIDTH_DEFAULT] =
- g_param_spec_uint("roi-width-default",
- "ROI width default value",
- "ROI width default value",
- 0, G_MAXUINT, 0,
- G_PARAM_READABLE);
-
- pylon_properties[PROP_ROI_HEIGHT_DEFAULT] =
- g_param_spec_uint("roi-height-default",
- "ROI height default value",
- "ROI height default value",
- 0, G_MAXUINT, 0,
- G_PARAM_READABLE);
-
- pylon_properties[PROP_GAIN] =
- g_param_spec_int("gain",
- "gain",
- "gain",
- 0, G_MAXINT, 0,
- G_PARAM_READWRITE);
-
- for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++)
- g_object_class_install_property(gobject_class, id, pylon_properties[id]);
-
- g_type_class_add_private(klass, sizeof(UcaPylonCameraPrivate));
-}
-
-static void uca_pylon_camera_init(UcaPylonCamera *self)
-{
- self->priv = UCA_PYLON_CAMERA_GET_PRIVATE(self);
-
- /* binnings */
- GValue val = {0};
- g_value_init(&val, G_TYPE_UINT);
- g_value_set_uint(&val, 1);
- self->priv->binnings = g_value_array_new(1);
- g_value_array_append(self->priv->binnings, &val);
-}
diff --git a/src/cameras/uca-pylon-camera.h b/src/cameras/uca-pylon-camera.h
deleted file mode 100644
index eebf63c..0000000
--- a/src/cameras/uca-pylon-camera.h
+++ /dev/null
@@ -1,74 +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 */
-
-#ifndef __UCA_PYLON_CAMERA_H
-#define __UCA_PYLON_CAMERA_H
-
-#include <glib-object.h>
-#include "uca-camera.h"
-
-G_BEGIN_DECLS
-
-#define UCA_TYPE_PYLON_CAMERA (uca_pylon_camera_get_type())
-#define UCA_PYLON_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_PYLON_CAMERA, UcaPylonCamera))
-#define UCA_IS_PYLON_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_PYLON_CAMERA))
-#define UCA_PYLON_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UFO_TYPE_PYLON_CAMERA, UfoPylonCameraClass))
-#define UCA_IS_PYLON_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PYLON_CAMERA))
-#define UCA_PYLON_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PYLON_CAMERA, UcaPylonCameraClass))
-
-#define UCA_PYLON_CAMERA_ERROR uca_pylon_camera_error_quark()
-typedef enum {
- UCA_PYLON_CAMERA_ERROR_LIBPYLON_INIT,
- UCA_PYLON_CAMERA_ERROR_LIBPYLON_GENERAL,
- UCA_PYLON_CAMERA_ERROR_UNSUPPORTED,
-} UcaPylonCameraError;
-
-typedef struct _UcaPylonCamera UcaPylonCamera;
-typedef struct _UcaPylonCameraClass UcaPylonCameraClass;
-typedef struct _UcaPylonCameraPrivate UcaPylonCameraPrivate;
-
-/**
- * UcaPylonCamera:
- *
- * Creates #UcaPylonCamera instances by loading corresponding shared objects. The
- * contents of the #UcaPylonCamera structure are private and should only be
- * accessed via the provided API.
- */
-struct _UcaPylonCamera {
- /*< private >*/
- UcaCamera parent;
-
- UcaPylonCameraPrivate *priv;
-};
-
-/**
- * UcaPylonCameraClass:
- *
- * #UcaPylonCamera class
- */
-struct _UcaPylonCameraClass {
- /*< private >*/
- UcaCameraClass parent;
-};
-
-UcaPylonCamera *uca_pylon_camera_new(GError **error);
-
-GType uca_pylon_camera_get_type(void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/cameras/uca-ufo-camera.c b/src/cameras/uca-ufo-camera.c
deleted file mode 100644
index 5f59f4a..0000000
--- a/src/cameras/uca-ufo-camera.c
+++ /dev/null
@@ -1,495 +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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pcilib.h>
-#include <errno.h>
-#include "uca-camera.h"
-#include "uca-ufo-camera.h"
-
-#define PCILIB_SET_ERROR(err, err_type) \
- if (err != 0) { \
- g_set_error(error, UCA_UFO_CAMERA_ERROR, \
- err_type, \
- "pcilib: %s", strerror(err)); \
- return; \
- }
-
-#define UCA_UFO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_UFO_CAMERA, UcaUfoCameraPrivate))
-
-G_DEFINE_TYPE(UcaUfoCamera, uca_ufo_camera, UCA_TYPE_CAMERA)
-
-static const guint SENSOR_WIDTH = 2048;
-static const guint SENSOR_HEIGHT = 1088;
-static const gdouble EXPOSURE_TIME_SCALE = 2.69e6;
-
-/**
- * UcaUfoCameraError:
- * @UCA_UFO_CAMERA_ERROR_INIT: Initializing pcilib failed
- * @UCA_UFO_CAMERA_ERROR_START_RECORDING: Starting failed
- * @UCA_UFO_CAMERA_ERROR_STOP_RECORDING: Stopping failed
- * @UCA_UFO_CAMERA_ERROR_TRIGGER: Triggering a frame failed
- * @UCA_UFO_CAMERA_ERROR_NEXT_EVENT: No event happened
- * @UCA_UFO_CAMERA_ERROR_NO_DATA: No data was transmitted
- * @UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED: Data is potentially corrupted
- */
-GQuark uca_ufo_camera_error_quark()
-{
- return g_quark_from_static_string("uca-ufo-camera-error-quark");
-}
-
-enum {
- PROP_SENSOR_TEMPERATURE = N_BASE_PROPERTIES,
- PROP_FPGA_TEMPERATURE,
- PROP_UFO_START,
- N_MAX_PROPERTIES = 512
-};
-
-static gint base_overrideables[] = {
- PROP_NAME,
- PROP_SENSOR_WIDTH,
- PROP_SENSOR_HEIGHT,
- PROP_SENSOR_HORIZONTAL_BINNING,
- PROP_SENSOR_VERTICAL_BINNING,
- PROP_SENSOR_MAX_FRAME_RATE,
- PROP_SENSOR_BITDEPTH,
- PROP_EXPOSURE_TIME,
- PROP_ROI_X,
- PROP_ROI_Y,
- PROP_ROI_WIDTH,
- PROP_ROI_HEIGHT,
- PROP_ROI_WIDTH_MULTIPLIER,
- PROP_ROI_HEIGHT_MULTIPLIER,
- PROP_HAS_STREAMING,
- PROP_HAS_CAMRAM_RECORDING,
- PROP_TRIGGER_MODE,
- 0,
-};
-
-typedef struct _RegisterInfo {
- gchar *name;
- guint cached_value;
-} RegisterInfo;
-
-static GParamSpec *ufo_properties[N_MAX_PROPERTIES] = { NULL, };
-
-static guint N_PROPERTIES;
-static GHashTable *ufo_property_table; /* maps from prop_id to RegisterInfo* */
-
-struct _UcaUfoCameraPrivate {
- pcilib_t *handle;
- pcilib_timeout_t timeout;
- guint n_bits;
- enum {
- FPGA_48MHZ = 0,
- FPGA_40MHZ
- } frequency;
-};
-
-static void
-error_handler (const char *format, ...)
-{
- va_list args;
- gchar *message;
-
- va_start (args, format);
- message = g_strdup_vprintf (format, args);
- g_warning ("%s", message);
- va_end (args);
-}
-
-static guint
-read_register_value (pcilib_t *handle, const gchar *name)
-{
- pcilib_register_value_t reg_value;
-
- pcilib_read_register(handle, NULL, name, &reg_value);
- return (guint) reg_value;
-}
-
-static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user)
-{
- UcaCamera *camera = UCA_CAMERA(user);
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
- size_t error = 0;
-
- void *buffer = pcilib_get_data(priv->handle, event_id, PCILIB_EVENT_DATA, &error);
-
- if (buffer == NULL) {
- pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
- return PCILIB_STREAMING_CONTINUE;
- }
-
- camera->grab_func(buffer, camera->user_data);
- pcilib_return_data(priv->handle, event_id, PCILIB_EVENT_DATA, buffer);
- pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
-
- return PCILIB_STREAMING_CONTINUE;
-}
-
-UcaUfoCamera *uca_ufo_camera_new(GError **error)
-{
- pcilib_model_t model = PCILIB_MODEL_DETECT;
- pcilib_model_description_t *model_description;
- pcilib_t *handle = pcilib_open("/dev/fpga0", model);
- guint prop = PROP_UFO_START;
- guint adc_resolution;
-
- if (handle == NULL) {
- g_set_error(error, UCA_UFO_CAMERA_ERROR, UCA_UFO_CAMERA_ERROR_INIT,
- "Initializing pcilib failed");
- return NULL;
- }
-
- pcilib_set_error_handler(&error_handler, &error_handler);
-
- /* Generate properties from model description */
- model_description = pcilib_get_model_description(handle);
- ufo_property_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
-
- for (guint i = 0; model_description->registers[i].name != NULL; i++) {
- GParamFlags flags = 0;
- RegisterInfo *reg_info;
- gchar *prop_name;
- pcilib_register_description_t *reg;
- pcilib_register_value_t value;
-
- reg = &model_description->registers[i];
-
- switch (reg->mode) {
- case PCILIB_REGISTER_R:
- flags = G_PARAM_READABLE;
- break;
- case PCILIB_REGISTER_W:
- case PCILIB_REGISTER_W1C:
- flags = G_PARAM_WRITABLE;
- break;
- case PCILIB_REGISTER_RW:
- case PCILIB_REGISTER_RW1C:
- flags = G_PARAM_READWRITE;
- break;
- }
-
- pcilib_read_register (handle, NULL, reg->name, &value);
- reg_info = g_new0 (RegisterInfo, 1);
- reg_info->name = g_strdup (reg->name);
- reg_info->cached_value = (guint32) value;
-
- g_hash_table_insert (ufo_property_table, GINT_TO_POINTER (prop), reg_info);
- prop_name = g_strdup_printf ("ufo-%s", reg->name);
-
- ufo_properties[prop++] = g_param_spec_uint (
- prop_name, reg->description, reg->description,
- 0, G_MAXUINT, reg->defvalue, flags);
-
- g_free (prop_name);
- }
-
- N_PROPERTIES = prop;
-
- UcaUfoCamera *camera = g_object_new(UCA_TYPE_UFO_CAMERA, NULL);
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
-
- priv->frequency = read_register_value (handle, "bit_mode");
- adc_resolution = read_register_value (handle, "adc_resolution");
-
- switch (adc_resolution) {
- case 0:
- priv->n_bits = 10;
- break;
- case 1:
- priv->n_bits = 11;
- break;
- case 2:
- priv->n_bits = 12;
- break;
- }
-
- priv->handle = handle;
-
- return camera;
-}
-
-static void uca_ufo_camera_start_recording(UcaCamera *camera, GError **error)
-{
- UcaUfoCameraPrivate *priv;
- gdouble exposure_time;
- int err;
-
- g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
-
- priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
- err = pcilib_start(priv->handle, PCILIB_EVENT_DATA, PCILIB_EVENT_FLAGS_DEFAULT);
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_START_RECORDING);
-
- gboolean transfer_async = FALSE;
- g_object_get(G_OBJECT(camera),
- "transfer-asynchronously", &transfer_async,
- "exposure-time", &exposure_time,
- NULL);
-
- priv->timeout = ((pcilib_timeout_t) (exposure_time * 1000 + 50.0) * 1000);
-
- if (transfer_async) {
- pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
- pcilib_stream(priv->handle, &event_callback, camera);
- }
-}
-
-static void uca_ufo_camera_stop_recording(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
- int err = pcilib_stop(priv->handle, PCILIB_EVENT_FLAGS_DEFAULT);
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_START_RECORDING);
-}
-
-static void uca_ufo_camera_start_readout(UcaCamera *camera, GError **error)
-{
- g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_IMPLEMENTED,
- "Ufo camera does not support recording to internal memory");
-}
-
-static void uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
-{
- g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
- pcilib_event_id_t event_id;
- pcilib_event_info_t event_info;
- size_t err;
-
- const gsize size = SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16);
-
- err = pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_TRIGGER);
-
- err = pcilib_get_next_event(priv->handle, priv->timeout, &event_id, sizeof(pcilib_event_info_t), &event_info);
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_NEXT_EVENT);
-
- if (*data == NULL)
- *data = g_malloc0(SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16));
-
- gpointer src = pcilib_get_data(priv->handle, event_id, PCILIB_EVENT_DATA, &err);
-
- if (src == NULL)
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_NO_DATA);
-
- /*
- * Apparently, we checked that err equals total size in previous version.
- * This is problematic because errno is positive and size could be equal
- * even when an error condition is met, e.g. with a very small ROI. However,
- * we don't know if src will always be NULL when an error occured.
- */
- /* assert(err == size); */
-
- memcpy(*data, src, size);
-
- /*
- * Another problem here. What does this help us? At this point we have
- * already overwritten the original buffer but can only know here if the
- * data is corrupted.
- */
- err = pcilib_return_data(priv->handle, event_id, PCILIB_EVENT_DATA, data);
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED);
-}
-
-static void
-uca_ufo_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
-{
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_EXPOSURE_TIME:
- {
- const guint frequency = priv->frequency == FPGA_40MHZ ? 40 : 48;
- pcilib_register_value_t reg_value = (pcilib_register_value_t) 129 / frequency * 1000 * 1000 * g_value_get_double(value);
- pcilib_write_register(priv->handle, NULL, "cmosis_exp_time", reg_value);
- }
- break;
- case PROP_ROI_X:
- case PROP_ROI_Y:
- case PROP_ROI_WIDTH:
- case PROP_ROI_HEIGHT:
- g_debug("ROI feature not implemented yet");
- break;
-
- default:
- {
- RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id));
-
- if (reg_info != NULL) {
- pcilib_register_value_t reg_value;
-
- reg_value = g_value_get_uint (value);
- pcilib_write_register(priv->handle, NULL, reg_info->name, reg_value);
- pcilib_read_register (priv->handle, NULL, reg_info->name, &reg_value);
- reg_info->cached_value = (guint) reg_value;
- }
- else
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- }
- return;
- }
-}
-
-
-static void
-uca_ufo_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
-{
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_SENSOR_WIDTH:
- g_value_set_uint(value, SENSOR_WIDTH);
- break;
- case PROP_SENSOR_HEIGHT:
- g_value_set_uint(value, SENSOR_HEIGHT);
- break;
- case PROP_SENSOR_BITDEPTH:
- g_value_set_uint (value, priv->n_bits);
- break;
- case PROP_SENSOR_HORIZONTAL_BINNING:
- g_value_set_uint(value, 1);
- break;
- case PROP_SENSOR_VERTICAL_BINNING:
- g_value_set_uint(value, 1);
- break;
- case PROP_SENSOR_MAX_FRAME_RATE:
- g_value_set_float(value, 340.0);
- break;
- case PROP_SENSOR_TEMPERATURE:
- {
- const double a = priv->frequency == FPGA_48MHZ ? 0.3 : 0.25;
- const double b = priv->frequency == FPGA_48MHZ ? 1000 : 1200;
- guint32 temperature;
-
- temperature = read_register_value (priv->handle, "sensor_temperature");
- g_value_set_double (value, a * (temperature - b));
- }
- break;
- case PROP_FPGA_TEMPERATURE:
- {
- const double a = 503.975 / 1024.0;
- const double b = 273.15;
- guint32 temperature;
-
- temperature = read_register_value (priv->handle, "fpga_temperature");
- g_value_set_double (value, a * temperature - b);
- }
- break;
- case PROP_EXPOSURE_TIME:
- {
- const gdouble frequency = priv->frequency == FPGA_40MHZ ? 40.0 : 48.0;
- g_value_set_double (value, read_register_value (priv->handle, "cmosis_exp_time") * 129 / frequency / 1000 / 1000 );
- }
- break;
- case PROP_HAS_STREAMING:
- g_value_set_boolean(value, TRUE);
- break;
- case PROP_HAS_CAMRAM_RECORDING:
- g_value_set_boolean(value, FALSE);
- break;
- case PROP_ROI_X:
- g_value_set_uint(value, 0);
- break;
- case PROP_ROI_Y:
- g_value_set_uint(value, 0);
- break;
- case PROP_ROI_WIDTH:
- g_value_set_uint(value, SENSOR_WIDTH);
- break;
- case PROP_ROI_HEIGHT:
- g_value_set_uint(value, SENSOR_HEIGHT);
- break;
- case PROP_ROI_WIDTH_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
- case PROP_ROI_HEIGHT_MULTIPLIER:
- g_value_set_uint(value, 1);
- break;
- case PROP_NAME:
- g_value_set_string(value, "Ufo Camera w/ CMOSIS CMV2000");
- break;
- case PROP_TRIGGER_MODE:
- break;
- default:
- {
- RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id));
-
- if (reg_info != NULL)
- g_value_set_uint (value, reg_info->cached_value);
- else
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- }
- break;
- }
-}
-
-static void uca_ufo_camera_finalize(GObject *object)
-{
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(object);
- pcilib_close(priv->handle);
- G_OBJECT_CLASS(uca_ufo_camera_parent_class)->finalize(object);
-}
-
-static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->set_property = uca_ufo_camera_set_property;
- gobject_class->get_property = uca_ufo_camera_get_property;
- gobject_class->finalize = uca_ufo_camera_finalize;
-
- UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass);
- camera_class->start_recording = uca_ufo_camera_start_recording;
- camera_class->stop_recording = uca_ufo_camera_stop_recording;
- camera_class->start_readout = uca_ufo_camera_start_readout;
- camera_class->grab = uca_ufo_camera_grab;
-
- for (guint i = 0; base_overrideables[i] != 0; i++)
- g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]);
-
- ufo_properties[PROP_SENSOR_TEMPERATURE] =
- g_param_spec_double("sensor-temperature",
- "Temperature of the sensor",
- "Temperature of the sensor in degree Celsius",
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READABLE);
-
- ufo_properties[PROP_FPGA_TEMPERATURE] =
- g_param_spec_double("fpga-temperature",
- "Temperature of the FPGA",
- "Temperature of the FPGA in degree Celsius",
- -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
- G_PARAM_READABLE);
-
- /*
- * This automatic property installation includes the properties created
- * dynamically in uca_ufo_camera_new().
- */
- for (guint id = N_BASE_PROPERTIES; id < N_PROPERTIES; id++)
- g_object_class_install_property(gobject_class, id, ufo_properties[id]);
-
- g_type_class_add_private(klass, sizeof(UcaUfoCameraPrivate));
-}
-
-static void uca_ufo_camera_init(UcaUfoCamera *self)
-{
- self->priv = UCA_UFO_CAMERA_GET_PRIVATE(self);
-}
diff --git a/src/cameras/uca-ufo-camera.h b/src/cameras/uca-ufo-camera.h
deleted file mode 100644
index 0b52ffb..0000000
--- a/src/cameras/uca-ufo-camera.h
+++ /dev/null
@@ -1,78 +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 */
-
-#ifndef __UCA_UFO_CAMERA_H
-#define __UCA_UFO_CAMERA_H
-
-#include <glib-object.h>
-#include "uca-camera.h"
-
-G_BEGIN_DECLS
-
-#define UCA_TYPE_UFO_CAMERA (uca_ufo_camera_get_type())
-#define UCA_UFO_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), UCA_TYPE_UFO_CAMERA, UcaUfoCamera))
-#define UCA_IS_UFO_CAMERA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), UCA_TYPE_UFO_CAMERA))
-#define UCA_UFO_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), UCA_TYPE_UFO_CAMERA, UcaUfoCameraClass))
-#define UCA_IS_UFO_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_UFO_CAMERA))
-#define UCA_UFO_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_UFO_CAMERA, UcaUfoCameraClass))
-
-#define UCA_UFO_CAMERA_ERROR uca_ufo_camera_error_quark()
-typedef enum {
- UCA_UFO_CAMERA_ERROR_INIT,
- UCA_UFO_CAMERA_ERROR_START_RECORDING,
- UCA_UFO_CAMERA_ERROR_STOP_RECORDING,
- UCA_UFO_CAMERA_ERROR_TRIGGER,
- UCA_UFO_CAMERA_ERROR_NEXT_EVENT,
- UCA_UFO_CAMERA_ERROR_NO_DATA,
- UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED
-} UcaUfoCameraError;
-
-typedef struct _UcaUfoCamera UcaUfoCamera;
-typedef struct _UcaUfoCameraClass UcaUfoCameraClass;
-typedef struct _UcaUfoCameraPrivate UcaUfoCameraPrivate;
-
-/**
- * UcaUfoCamera:
- *
- * Creates #UcaUfoCamera instances by loading corresponding shared objects. The
- * contents of the #UcaUfoCamera structure are private and should only be
- * accessed via the provided API.
- */
-struct _UcaUfoCamera {
- /*< private >*/
- UcaCamera parent;
-
- UcaUfoCameraPrivate *priv;
-};
-
-/**
- * UcaUfoCameraClass:
- *
- * #UcaUfoCamera class
- */
-struct _UcaUfoCameraClass {
- /*< private >*/
- UcaCameraClass parent;
-};
-
-UcaUfoCamera *uca_ufo_camera_new(GError **error);
-
-GType uca_ufo_camera_get_type(void);
-
-G_END_DECLS
-
-#endif
diff --git a/src/uca-camera.c b/src/uca-camera.c
index d9d2d6a..53b2d7a 100644
--- a/src/uca-camera.c
+++ b/src/uca-camera.c
@@ -15,35 +15,19 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+/**
+ * SECTION:uca-camera
+ * @Short_description: Base class representing a camera
+ * @Title: UcaCamera
+ *
+ * UcaCamera is the base camera from which a real hardware camera derives from.
+ */
+
#include <glib.h>
#include "config.h"
#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
-
-#ifdef HAVE_DEXELA_CL
-#include "cameras/uca-dexela-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)
@@ -52,7 +36,7 @@ G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT)
* UcaCameraTrigger:
* @UCA_CAMERA_TRIGGER_AUTO: Trigger automatically
* @UCA_CAMERA_TRIGGER_EXTERNAL: Trigger from an external source
- * @UCA_CAMERA_TRIGGER_INTERNAL: Trigger internally from software using
+ * @UCA_CAMERA_TRIGGER_SOFTWARE: Trigger from software using
* #uca_camera_trigger
*/
@@ -63,33 +47,31 @@ G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT)
* @UCA_CAMERA_ERROR_NOT_RECORDING: Camera is not recording
* @UCA_CAMERA_ERROR_NO_GRAB_FUNC: No grab callback was set
* @UCA_CAMERA_ERROR_NOT_IMPLEMENTED: Virtual function is not implemented
+ * @UCA_CAMERA_ERROR_END_OF_STREAM: Data stream has ended.
*/
GQuark uca_camera_error_quark()
{
- return g_quark_from_static_string("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
-#ifdef HAVE_DEXELA_CL
- "dexela",
-#endif
- NULL
-};
+/**
+ * UcaUnit:
+ * @UCA_UNIT_NA: Not applicable
+ * @UCA_UNIT_METER: Length in SI meter
+ * @UCA_UNIT_SECOND: Time in SI second
+ * @UCA_UNIT_PIXEL: Number of pixels in one dimension
+ * @UCA_UNIT_DEGREE_CELSIUS: Temperature in degree Celsius
+ * @UCA_UNIT_COUNT: Generic number
+ *
+ * Units should be registered by camera implementations using
+ * uca_camera_register_unit() and can be queried by client programs with
+ * uca_camera_get_unit().
+ */
+
+GQuark uca_unit_quark ()
+{
+ return g_quark_from_static_string ("uca-unit-quark");
+}
enum {
LAST_SIGNAL
@@ -112,6 +94,7 @@ const gchar *uca_camera_props[N_BASE_PROPERTIES] = {
"sensor-max-frame-rate",
"trigger-mode",
"exposure-time",
+ "frames-per-second",
"roi-x0",
"roi-y0",
"roi-width",
@@ -120,6 +103,7 @@ const gchar *uca_camera_props[N_BASE_PROPERTIES] = {
"roi-height-multiplier",
"has-streaming",
"has-camram-recording",
+ "recorded-frames",
"transfer-asynchronously",
"is-recording",
"is-readout"
@@ -133,7 +117,14 @@ 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_unit (GParamSpec *pspec, UcaUnit unit)
+{
+ g_param_spec_set_qdata (pspec, UCA_UNIT_QUARK, GINT_TO_POINTER (unit));
+}
+
+static void
+uca_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object);
@@ -147,26 +138,53 @@ static void uca_camera_set_property(GObject *object, guint property_id, const GV
priv->transfer_async = g_value_get_boolean(value);
break;
+ case PROP_FRAMES_PER_SECOND:
+ {
+ gdouble frames_per_second;
+
+ frames_per_second = g_value_get_double (value);
+ g_object_set (object, "exposure-time", 1. / frames_per_second, NULL);
+ }
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
}
-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);
+ UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE (object);
switch (property_id) {
case PROP_IS_RECORDING:
- g_value_set_boolean(value, priv->is_recording);
+ g_value_set_boolean (value, priv->is_recording);
break;
case PROP_IS_READOUT:
- g_value_set_boolean(value, priv->is_readout);
+ g_value_set_boolean (value, priv->is_readout);
break;
case PROP_TRANSFER_ASYNCHRONOUSLY:
- g_value_set_boolean(value, priv->transfer_async);
+ g_value_set_boolean (value, priv->transfer_async);
+ break;
+
+ case PROP_TRIGGER_MODE:
+ g_value_set_enum (value, UCA_CAMERA_TRIGGER_AUTO);
+ break;
+
+ case PROP_FRAMES_PER_SECOND:
+ {
+ gdouble exposure_time;
+
+ g_object_get (object, "exposure-time", &exposure_time, NULL);
+ g_value_set_double (value, 1. / exposure_time);
+ }
+ break;
+
+ case PROP_RECORDED_FRAMES:
+ g_value_set_uint (value, 0);
break;
default:
@@ -174,11 +192,19 @@ static void uca_camera_get_property(GObject *object, guint property_id, GValue *
}
}
-static void uca_camera_class_init(UcaCameraClass *klass)
+static void
+uca_camera_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (uca_camera_parent_class)->finalize (object);
+}
+
+static void
+uca_camera_class_init (UcaCameraClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = uca_camera_set_property;
gobject_class->get_property = uca_camera_get_property;
+ gobject_class->finalize = uca_camera_finalize;
klass->start_recording = NULL;
klass->stop_recording = NULL;
@@ -310,6 +336,13 @@ static void uca_camera_class_init(UcaCameraClass *klass)
0.0, G_MAXDOUBLE, 1.0,
G_PARAM_READWRITE);
+ camera_properties[PROP_FRAMES_PER_SECOND] =
+ g_param_spec_double(uca_camera_props[PROP_FRAMES_PER_SECOND],
+ "Frames per second",
+ "Frames per second",
+ 0.0, G_MAXDOUBLE, 1.0,
+ G_PARAM_READWRITE);
+
camera_properties[PROP_HAS_STREAMING] =
g_param_spec_boolean(uca_camera_props[PROP_HAS_STREAMING],
"Streaming capability",
@@ -322,6 +355,20 @@ static void uca_camera_class_init(UcaCameraClass *klass)
"Is the camera able to record the data in-camera",
FALSE, G_PARAM_READABLE);
+ /**
+ * UcaCamera:recorded-frames
+ *
+ * Number of frames that are recorded into internal camera memory.
+ *
+ * Since: 1.1
+ */
+ camera_properties[PROP_RECORDED_FRAMES] =
+ g_param_spec_uint(uca_camera_props[PROP_RECORDED_FRAMES],
+ "Number of frames recorded into internal camera memory",
+ "Number of frames recorded into internal camera memory",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE);
+
camera_properties[PROP_TRANSFER_ASYNCHRONOUSLY] =
g_param_spec_boolean(uca_camera_props[PROP_TRANSFER_ASYNCHRONOUSLY],
"Specify whether data should be transfered asynchronously",
@@ -346,7 +393,8 @@ static void uca_camera_class_init(UcaCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaCameraPrivate));
}
-static void uca_camera_init(UcaCamera *camera)
+static void
+uca_camera_init (UcaCamera *camera)
{
camera->grab_func = NULL;
@@ -355,105 +403,21 @@ static void uca_camera_init(UcaCamera *camera)
camera->priv->is_readout = FALSE;
camera->priv->transfer_async = FALSE;
- /*
- * This here would be the best place to instantiate the tango server object,
- * along these lines:
- *
- * // I'd prefer if you expose a single C method, so we don't have to
- * // compile uca-camera.c with g++
- * tango_handle = tango_server_new(camera);
- *
- * void tango_server_new(UcaCamera *camera)
- * {
- * // Do whatever is necessary. In the end you will have some kind of
- * // Tango object t which needs to somehow hook up to the properties. A
- * // list of all available properties can be enumerated with
- * // g_object_class_list_properties(G_OBJECT_CLASS(camera),
- * // &n_properties);
- *
- * // For setting/getting properties, use g_object_get/set_property() or
- * // g_object_get/set() whatever is more suitable.
- * }
- */
-}
-
-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
-
-#ifdef HAVE_DEXELA_CL
- if (!g_strcmp0(type, "dexela"))
- return UCA_CAMERA(uca_dexela_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_set_property_unit (camera_properties[PROP_SENSOR_WIDTH], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_SENSOR_HEIGHT], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_SENSOR_BITDEPTH], UCA_UNIT_COUNT);
+ uca_camera_set_property_unit (camera_properties[PROP_SENSOR_HORIZONTAL_BINNING], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_SENSOR_VERTICAL_BINNING], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_SENSOR_MAX_FRAME_RATE], UCA_UNIT_COUNT);
+ uca_camera_set_property_unit (camera_properties[PROP_EXPOSURE_TIME], UCA_UNIT_SECOND);
+ uca_camera_set_property_unit (camera_properties[PROP_FRAMES_PER_SECOND], UCA_UNIT_COUNT);
+ uca_camera_set_property_unit (camera_properties[PROP_ROI_X], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_ROI_Y], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_ROI_WIDTH], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_ROI_HEIGHT], UCA_UNIT_PIXEL);
+ uca_camera_set_property_unit (camera_properties[PROP_ROI_WIDTH_MULTIPLIER], UCA_UNIT_COUNT);
+ uca_camera_set_property_unit (camera_properties[PROP_ROI_HEIGHT_MULTIPLIER], UCA_UNIT_COUNT);
+ uca_camera_set_property_unit (camera_properties[PROP_RECORDED_FRAMES], UCA_UNIT_COUNT);
}
/**
@@ -465,38 +429,47 @@ UcaCamera *uca_camera_new(const gchar *type, GError **error)
* #UcaCameraGrabFunc callback is set, frames are automatically transfered to
* the client program, otherwise you must use uca_camera_grab().
*/
-void uca_camera_start_recording(UcaCamera *camera, GError **error)
+void
+uca_camera_start_recording (UcaCamera *camera, GError **error)
{
- g_return_if_fail(UCA_IS_CAMERA(camera));
+ UcaCameraClass *klass;
+ GError *tmp_error = NULL;
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+ g_return_if_fail (UCA_IS_CAMERA (camera));
- UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera);
+ klass = UCA_CAMERA_GET_CLASS (camera);
- g_return_if_fail(klass != NULL);
- g_return_if_fail(klass->start_recording != NULL);
+ g_return_if_fail (klass != NULL);
+ g_return_if_fail (klass->start_recording != NULL);
+
+ g_static_mutex_lock (&mutex);
if (camera->priv->is_recording) {
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING,
+ g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING,
"Camera is already recording");
- return;
+ goto start_recording_unlock;
}
if (camera->priv->transfer_async && (camera->grab_func == NULL)) {
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NO_GRAB_FUNC,
+ g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NO_GRAB_FUNC,
"No grab callback function set");
- return;
+ goto start_recording_unlock;
}
- GError *tmp_error = NULL;
(*klass->start_recording)(camera, &tmp_error);
if (tmp_error == NULL) {
camera->priv->is_readout = FALSE;
camera->priv->is_recording = TRUE;
/* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */
- g_object_notify(G_OBJECT(camera), "is-recording");
+ g_object_notify (G_OBJECT (camera), "is-recording");
}
else
- g_propagate_error(error, tmp_error);
+ g_propagate_error (error, tmp_error);
+
+start_recording_unlock:
+ g_static_mutex_unlock (&mutex);
}
/**
@@ -506,32 +479,41 @@ void uca_camera_start_recording(UcaCamera *camera, GError **error)
*
* Stop recording.
*/
-void uca_camera_stop_recording(UcaCamera *camera, GError **error)
+void
+uca_camera_stop_recording (UcaCamera *camera, GError **error)
{
- g_return_if_fail(UCA_IS_CAMERA(camera));
+ UcaCameraClass *klass;
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera);
+ g_return_if_fail (UCA_IS_CAMERA (camera));
- g_return_if_fail(klass != NULL);
- g_return_if_fail(klass->stop_recording != NULL);
+ klass = UCA_CAMERA_GET_CLASS (camera);
- if (!camera->priv->is_recording) {
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING,
- "Camera is not recording");
- return;
- }
+ g_return_if_fail (klass != NULL);
+ g_return_if_fail (klass->stop_recording != NULL);
- GError *tmp_error = NULL;
- (*klass->stop_recording)(camera, &tmp_error);
+ g_static_mutex_lock (&mutex);
- if (tmp_error == NULL) {
- camera->priv->is_readout = FALSE;
- camera->priv->is_recording = FALSE;
- /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */
- g_object_notify(G_OBJECT(camera), "is-recording");
+ if (!camera->priv->is_recording) {
+ g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING,
+ "Camera is not recording");
}
- else
- g_propagate_error(error, tmp_error);
+ else {
+ GError *tmp_error = NULL;
+
+ (*klass->stop_recording)(camera, &tmp_error);
+
+ if (tmp_error == NULL) {
+ camera->priv->is_readout = FALSE;
+ camera->priv->is_recording = FALSE;
+ /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */
+ g_object_notify (G_OBJECT (camera), "is-recording");
+ }
+ else
+ g_propagate_error (error, tmp_error);
+ }
+
+ g_static_mutex_unlock (&mutex);
}
/**
@@ -544,31 +526,84 @@ void uca_camera_stop_recording(UcaCamera *camera, GError **error)
* uca_camera_stop_recording(). Frames have to be picked up with
* ufo_camera_grab().
*/
-void uca_camera_start_readout(UcaCamera *camera, GError **error)
+void
+uca_camera_start_readout (UcaCamera *camera, GError **error)
{
- g_return_if_fail(UCA_IS_CAMERA(camera));
+ UcaCameraClass *klass;
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+ g_return_if_fail (UCA_IS_CAMERA(camera));
- UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera);
+ klass = UCA_CAMERA_GET_CLASS(camera);
- g_return_if_fail(klass != NULL);
- g_return_if_fail(klass->start_readout != NULL);
+ g_return_if_fail (klass != NULL);
+ g_return_if_fail (klass->start_readout != NULL);
+
+ g_static_mutex_lock (&mutex);
if (camera->priv->is_recording) {
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING,
- "Camera is still recording");
- return;
+ g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING,
+ "Camera is still recording");
+ }
+ else {
+ GError *tmp_error = NULL;
+
+ (*klass->start_readout) (camera, &tmp_error);
+
+ if (tmp_error == NULL) {
+ camera->priv->is_readout = TRUE;
+ /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */
+ g_object_notify (G_OBJECT (camera), "is-readout");
+ }
+ else
+ g_propagate_error (error, tmp_error);
}
- GError *tmp_error = NULL;
- (*klass->start_readout)(camera, &tmp_error);
+ g_static_mutex_unlock (&mutex);
+}
- if (tmp_error == NULL) {
- camera->priv->is_readout = TRUE;
- /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */
- g_object_notify(G_OBJECT(camera), "is-readout");
+/**
+ * uca_camera_stop_readout:
+ * @camera: A #UcaCamera object
+ * @error: Location to store a #UcaCameraError error or %NULL
+ *
+ * Stop reading out frames.
+ *
+ * Since: 1.1
+ */
+void
+uca_camera_stop_readout (UcaCamera *camera, GError **error)
+{
+ UcaCameraClass *klass;
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+ g_return_if_fail (UCA_IS_CAMERA(camera));
+
+ klass = UCA_CAMERA_GET_CLASS(camera);
+
+ g_return_if_fail (klass != NULL);
+ g_return_if_fail (klass->start_readout != NULL);
+
+ g_static_mutex_lock (&mutex);
+
+ if (camera->priv->is_recording) {
+ g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING,
+ "Camera is still recording");
}
- else
- g_propagate_error(error, tmp_error);
+ else {
+ GError *tmp_error = NULL;
+
+ (*klass->stop_readout) (camera, &tmp_error);
+
+ if (tmp_error == NULL) {
+ camera->priv->is_readout = FALSE;
+ g_object_notify (G_OBJECT (camera), "is-readout");
+ }
+ else
+ g_propagate_error (error, tmp_error);
+ }
+
+ g_static_mutex_unlock (&mutex);
}
/**
@@ -579,7 +614,8 @@ void uca_camera_start_readout(UcaCamera *camera, GError **error)
*
* Set the grab function that is called whenever a frame is readily transfered.
*/
-void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data)
+void
+uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data)
{
camera->grab_func = func;
camera->user_data = user_data;
@@ -595,22 +631,27 @@ void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointe
* You must have called uca_camera_start_recording() before, otherwise you will
* get a #UCA_CAMERA_ERROR_NOT_RECORDING error.
*/
-void uca_camera_trigger(UcaCamera *camera, GError **error)
+void
+uca_camera_trigger (UcaCamera *camera, GError **error)
{
- g_return_if_fail(UCA_IS_CAMERA(camera));
+ UcaCameraClass *klass;
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera);
+ g_return_if_fail (UCA_IS_CAMERA (camera));
- g_return_if_fail(klass != NULL);
- g_return_if_fail(klass->trigger != NULL);
+ klass = UCA_CAMERA_GET_CLASS (camera);
- if (!camera->priv->is_recording) {
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING,
- "Camera is not recording");
- return;
- }
+ g_return_if_fail (klass != NULL);
+ g_return_if_fail (klass->trigger != NULL);
+
+ g_static_mutex_lock (&mutex);
- (*klass->trigger)(camera, error);
+ if (!camera->priv->is_recording)
+ g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, "Camera is not recording");
+ else
+ (*klass->trigger) (camera, error);
+
+ g_static_mutex_unlock (&mutex);
}
/**
@@ -626,23 +667,96 @@ void uca_camera_trigger(UcaCamera *camera, GError **error)
*
* You must have called uca_camera_start_recording() before, otherwise you will
* get a #UCA_CAMERA_ERROR_NOT_RECORDING error.
+ *
+ * If *data is %NULL after returning from uca_camera_grab() and error is also
+ * %NULL, the data stream has ended. For example, with cameras that support
+ * in-camera memory, all frames have been transfered.
*/
-void uca_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+void
+uca_camera_grab (UcaCamera *camera, gpointer *data, GError **error)
{
- g_return_if_fail(UCA_IS_CAMERA(camera));
+ UcaCameraClass *klass;
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+ g_return_if_fail (UCA_IS_CAMERA(camera));
+
+ klass = UCA_CAMERA_GET_CLASS (camera);
+
+ g_return_if_fail (klass != NULL);
+ g_return_if_fail (klass->grab != NULL);
+ g_return_if_fail (data != NULL);
+
+ g_static_mutex_lock (&mutex);
+
+ if (!camera->priv->is_recording && !camera->priv->is_readout)
+ g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, "Camera is neither recording nor in readout mode");
+ else
+ (*klass->grab) (camera, data, error);
- UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera);
+ g_static_mutex_unlock (&mutex);
+}
- g_return_if_fail(klass != NULL);
- g_return_if_fail(klass->grab != NULL);
- g_return_if_fail(data != NULL);
+/**
+ * uca_camera_register_unit:
+ * @camera: A #UcaCamera object
+ * @prop_name: Name of a property
+ * @unit: #UcaUnit
+ *
+ * Associates @prop_name of @camera with a specific @unit.
+ *
+ * Since: 1.1
+ */
+void
+uca_camera_register_unit (UcaCamera *camera,
+ const gchar *prop_name,
+ UcaUnit unit)
+{
+ UcaCameraClass *klass;
+ GObjectClass *oclass;
+ GParamSpec *pspec;
- if (!camera->priv->is_recording && !camera->priv->is_readout) {
- g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING,
- "Camera is neither recording nor in readout mode");
+ klass = UCA_CAMERA_GET_CLASS (camera);
+ oclass = G_OBJECT_CLASS (klass);
+ pspec = g_object_class_find_property (oclass, prop_name);
+
+ if (pspec == NULL) {
+ g_warning ("Camera does not have property `%s'", prop_name);
return;
}
- (*klass->grab)(camera, data, error);
+ uca_camera_set_property_unit (pspec, unit);
+}
+
+/**
+ * uca_camera_get_unit:
+ * @camera: A #UcaCamera object
+ * @prop_name: Name of a property
+ *
+ * Returns the unit associated with @prop_name of @camera.
+ *
+ * Returns: A #UcaUnit value associated with @prop_name. If there is none, the
+ * value will be #UCA_UNIT_NA.
+ * Since: 1.1
+ */
+UcaUnit
+uca_camera_get_unit (UcaCamera *camera,
+ const gchar *prop_name)
+{
+ UcaCameraClass *klass;
+ GObjectClass *oclass;
+ GParamSpec *pspec;
+ gpointer data;
+
+ klass = UCA_CAMERA_GET_CLASS (camera);
+ oclass = G_OBJECT_CLASS (klass);
+ pspec = g_object_class_find_property (oclass, prop_name);
+
+ if (pspec == NULL) {
+ g_warning ("Camera does not have property `%s'", prop_name);
+ return UCA_UNIT_NA;
+ }
+
+ data = g_param_spec_get_qdata (pspec, UCA_UNIT_QUARK);
+ return data == NULL ? UCA_UNIT_NA : GPOINTER_TO_INT (data);
}
diff --git a/src/uca-camera.h b/src/uca-camera.h
index 8924fa8..87996c6 100644
--- a/src/uca-camera.h
+++ b/src/uca-camera.h
@@ -29,23 +29,36 @@ G_BEGIN_DECLS
#define UCA_IS_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_CAMERA))
#define UCA_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_CAMERA, UcaCameraClass))
-#define UCA_CAMERA_ERROR uca_camera_error_quark()
+#define UCA_CAMERA_ERROR uca_camera_error_quark()
+#define UCA_UNIT_QUARK uca_unit_quark()
+
GQuark uca_camera_error_quark(void);
+GQuark uca_unit_quark(void);
typedef enum {
UCA_CAMERA_ERROR_NOT_FOUND,
UCA_CAMERA_ERROR_RECORDING,
UCA_CAMERA_ERROR_NOT_RECORDING,
UCA_CAMERA_ERROR_NO_GRAB_FUNC,
- UCA_CAMERA_ERROR_NOT_IMPLEMENTED
+ UCA_CAMERA_ERROR_NOT_IMPLEMENTED,
+ UCA_CAMERA_ERROR_END_OF_STREAM
} UcaCameraError;
typedef enum {
UCA_CAMERA_TRIGGER_AUTO,
- UCA_CAMERA_TRIGGER_INTERNAL,
+ UCA_CAMERA_TRIGGER_SOFTWARE,
UCA_CAMERA_TRIGGER_EXTERNAL
} UcaCameraTrigger;
+typedef enum {
+ UCA_UNIT_NA,
+ UCA_UNIT_METER,
+ UCA_UNIT_SECOND,
+ UCA_UNIT_PIXEL,
+ UCA_UNIT_DEGREE_CELSIUS,
+ UCA_UNIT_COUNT
+} UcaUnit;
+
typedef struct _UcaCamera UcaCamera;
typedef struct _UcaCameraClass UcaCameraClass;
typedef struct _UcaCameraPrivate UcaCameraPrivate;
@@ -63,6 +76,7 @@ enum {
PROP_SENSOR_MAX_FRAME_RATE,
PROP_TRIGGER_MODE,
PROP_EXPOSURE_TIME,
+ PROP_FRAMES_PER_SECOND,
PROP_ROI_X,
PROP_ROI_Y,
PROP_ROI_WIDTH,
@@ -71,6 +85,7 @@ enum {
PROP_ROI_HEIGHT_MULTIPLIER,
PROP_HAS_STREAMING,
PROP_HAS_CAMRAM_RECORDING,
+ PROP_RECORDED_FRAMES,
/* These properties are handled internally */
PROP_TRANSFER_ASYNCHRONOUSLY,
@@ -110,24 +125,39 @@ struct _UcaCameraClass {
GObjectClass parent;
void (*start_recording) (UcaCamera *camera, GError **error);
- void (*stop_recording) (UcaCamera *camera, GError **error);
- void (*start_readout) (UcaCamera *camera, GError **error);
- void (*trigger) (UcaCamera *camera, GError **error);
- void (*grab) (UcaCamera *camera, gpointer *data, GError **error);
+ void (*stop_recording) (UcaCamera *camera, GError **error);
+ void (*start_readout) (UcaCamera *camera, GError **error);
+ void (*stop_readout) (UcaCamera *camera, GError **error);
+ void (*trigger) (UcaCamera *camera, GError **error);
+ void (*grab) (UcaCamera *camera, gpointer *data, GError **error);
void (*recording_started) (UcaCamera *camera);
void (*recording_stopped) (UcaCamera *camera);
};
-gchar **uca_camera_get_types();
-UcaCamera *uca_camera_new(const gchar *type, GError **error);
-
-void uca_camera_start_recording(UcaCamera *camera, GError **error);
-void uca_camera_stop_recording(UcaCamera *camera, GError **error);
-void uca_camera_start_readout(UcaCamera *camera, GError **error);
-void uca_camera_trigger(UcaCamera *camera, GError **error);
-void uca_camera_grab(UcaCamera *camera, gpointer *data, GError **error);
-void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data);
+UcaCamera * uca_camera_new (const gchar *type,
+ GError **error);
+void uca_camera_start_recording (UcaCamera *camera,
+ GError **error);
+void uca_camera_stop_recording (UcaCamera *camera,
+ GError **error);
+void uca_camera_start_readout (UcaCamera *camera,
+ GError **error);
+void uca_camera_stop_readout (UcaCamera *camera,
+ GError **error);
+void uca_camera_trigger (UcaCamera *camera,
+ GError **error);
+void uca_camera_grab (UcaCamera *camera,
+ gpointer *data,
+ GError **error);
+void uca_camera_set_grab_func (UcaCamera *camera,
+ UcaCameraGrabFunc func,
+ gpointer user_data);
+void uca_camera_register_unit (UcaCamera *camera,
+ const gchar *prop_name,
+ UcaUnit unit);
+UcaUnit uca_camera_get_unit (UcaCamera *camera,
+ const gchar *prop_name);
GType uca_camera_get_type(void);
diff --git a/src/uca-docs.xml.in b/src/uca-docs.xml.in
index 43a830d..093fd36 100644
--- a/src/uca-docs.xml.in
+++ b/src/uca-docs.xml.in
@@ -16,8 +16,8 @@
<chapter>
<title>Unified Camera Access</title>
- <xi:include href="xml/uca-camera.xml"/>
- ${_xml_doc_input}
+ <xi:include href="xml/uca-camera.xml"/>
+ <xi:include href="xml/uca-plugin-manager.xml"/>
</chapter>
<index id="api-index-full">
diff --git a/src/uca-plugin-manager.c b/src/uca-plugin-manager.c
new file mode 100644
index 0000000..e99f478
--- /dev/null
+++ b/src/uca-plugin-manager.c
@@ -0,0 +1,345 @@
+/* Copyright (C) 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 */
+
+/**
+ * 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:
+ *
+ * Create a plugin manager object to instantiate camera objects.
+ *
+ * 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 value: (element-type utf8) (transfer full): 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_get_camera:
+ * @manager: A #UcaPluginManager
+ * @name: Name of the camera module, that maps to libuca<name>.so
+ * @error: Location for a #GError
+ *
+ * Create a new camera instance with camera @name.
+ *
+ * Returns: (transfer full): A new #UcaCamera object.
+ */
+UcaCamera *
+uca_plugin_manager_get_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..6c3ab4e
--- /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_get_camera (UcaPluginManager *manager,
+ const gchar *name,
+ GError **error);
+GType uca_plugin_manager_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/src/uca.types.in b/src/uca.types.in
index a9ce408..7526948 100644
--- a/src/uca.types.in
+++ b/src/uca.types.in
@@ -1,2 +1,2 @@
uca_camera_get_type
-${_types_input}
+uca_plugin_manager_get_type