summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.bzrignore1
-rw-r--r--.gitignore16
-rw-r--r--CMakeLists.txt12
-rw-r--r--NEWS17
-rw-r--r--docs/manual.md46
-rw-r--r--docs/mock.html49
-rw-r--r--docs/style.css7
-rw-r--r--misc/README.rst29
-rw-r--r--misc/opencv-2.2.0.patch374
-rw-r--r--plugins/mock/uca-mock-camera.c93
-rw-r--r--plugins/mock/uca-mock-camera.h2
-rw-r--r--plugins/pco/uca-pco-camera.c314
-rw-r--r--plugins/pco/uca-pco-camera.h4
-rw-r--r--plugins/pf/uca-pf-camera.c178
-rw-r--r--plugins/ufo/uca-ufo-camera.c323
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/libuca.pc.in1
-rw-r--r--src/scangobj.sh.in2
-rw-r--r--src/uca-camera.c38
-rw-r--r--src/uca-camera.h9
-rw-r--r--src/uca-plugin-manager.c125
-rw-r--r--src/uca-plugin-manager.h9
-rw-r--r--src/uca.types.in3
-rw-r--r--test/test-mock.c25
-rw-r--r--tools/benchmark.c11
-rw-r--r--tools/gen-doc.c83
-rw-r--r--tools/grab-async.c2
-rw-r--r--tools/grab.c4
-rw-r--r--tools/gui/control.c30
-rw-r--r--tools/perf-overhead.c2
30 files changed, 975 insertions, 839 deletions
diff --git a/.bzrignore b/.bzrignore
deleted file mode 100644
index 6e92f57..0000000
--- a/.bzrignore
+++ /dev/null
@@ -1 +0,0 @@
-tags
diff --git a/.gitignore b/.gitignore
index 5ee492f..1d7e824 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,17 @@
-CMakeFiles
*~
*.cmake
+*.orig
+*.rpm
+_CPack_Packages
+build/
+CMakeFiles
+install_manifest.txt
+libuca.spec
Makefile
+src/config.h
src/libuca.so*
+tags
test/
-libuca.spec
-src/config.h
-*.rpm
-install_manifest.txt
-_CPack_Packages
-*.orig
tools/benchmark
tools/gen-doc
tools/grab
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 03abdad..39c421e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,8 +3,8 @@ project(uca C)
set(TARNAME "libuca")
set(UCA_VERSION_MAJOR "1")
-set(UCA_VERSION_MINOR "1")
-set(UCA_VERSION_PATCH "0")
+set(UCA_VERSION_MINOR "2")
+set(UCA_VERSION_PATCH "0dev")
set(UCA_DESCRIPTION "Unified Camera Access")
set(UCA_VERSION_STRING "${UCA_VERSION_MAJOR}.${UCA_VERSION_MINOR}.${UCA_VERSION_PATCH}")
@@ -55,17 +55,21 @@ find_program(GLIB2_MKENUMS glib-mkenums REQUIRED)
pkg_check_modules(GLIB2 glib-2.0>=2.24 REQUIRED)
pkg_check_modules(GOBJECT2 gobject-2.0>=2.24 REQUIRED)
pkg_check_modules(GMODULE2 gmodule-2.0>=2.24 REQUIRED)
+pkg_check_modules(GIO2 gio-2.0>=2.24 REQUIRED)
include_directories(
${CMAKE_CURRENT_BINARY_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src
${GLIB2_INCLUDE_DIRS}
- ${GOBJECT2_INCLUDE_DIRS})
+ ${GOBJECT2_INCLUDE_DIRS}
+ ${GMODULE2_INCLUDE_DIRS}
+ ${GIO2_INCLUDE_DIRS})
set(UCA_DEPS
${GLIB2_LIBRARIES}
${GOBJECT2_LIBRARIES}
- ${GMODULE2_LIBRARIES})
+ ${GMODULE2_LIBRARIES}
+ ${GIO2_LIBRARIES})
add_subdirectory(src)
add_subdirectory(plugins)
diff --git a/NEWS b/NEWS
index 700ee4d..e26e520 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,20 @@
+Changes in libuca 1.2
+=====================
+
+API break
+---------
+
+The interface of uca_camera_grab() has changed. The buffer must be provided as a
+void pointer (or gpointer in GLib speak), _not_ the address of a void pointer.
+Furthermore, uca_camera_grab() returns TRUE if grabbing an image was successful
+and FALSE if not.
+
+The plugin manager does not call the plugins "constructor" function directly but
+instantiates it via the GInitable initialization function. Therefore, all
+plugins must implement initialization code in the objects init function and flag
+errors in the init method from the GInitable interface.
+
+
Changes in libuca 1.1
=====================
diff --git a/docs/manual.md b/docs/manual.md
index 0dd9c66..85584df 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -185,22 +185,18 @@ To synchronously grab frames, first start the camera:
g_assert_no_error (error);
~~~
-Now you have two options with regard to memory buffers. If you already have a
-suitable sized buffer, just pass it to `uca_camera_grab`. Otherwise pass a
-pointer pointing to `NULL` (this is different from a `NULL` pointer!). In this
-case memory will be allocated for you:
+Now, you have to allocate a suitably sized buffer and pass it to
+`uca_camera_grab`.
~~~ {.c}
- gpointer buffer_1 = NULL; /* A pointer pointing to NULL */
- gpointer buffer_2 = g_malloc0 (640 * 480 * 2);
+ gpointer buffer = g_malloc0 (640 * 480 * 2);
- /* Memory will be allocated. Remember to free it! */
- uca_camera_grab (camera, &buffer_1, &error);
-
- /* Memory buffer will be used */
- uca_camera_grab (camera, &buffer_2, &error);
+ uca_camera_grab (camera, buffer, &error);
~~~
+You have to make sure that the buffer is large enough by querying the size of
+the region of interest and the number of bits that are transferred.
+
### Getting and setting camera parameters
@@ -405,7 +401,7 @@ pm = Uca.PluginManager()
print(pm.get_available_cameras())
# Load a camera
-cam = pm.get_camera('pco')
+cam = pm.get_camerav('pco', [])
# You can read and write properties in two ways
cam.set_properties(exposure_time=0.05)
@@ -417,6 +413,32 @@ of the target language. For example with Python, the namespace prefix `uca_`
becomes the module name `Uca` and dashes separating property names become
underscores.
+Integration with Numpy is relatively straightforward. The most important thing
+is to get the data pointer from a Numpy array to pass it to `uca_camera_grab`:
+
+~~~ {.python}
+import numpy as np
+
+def create_array_from(camera):
+ """Create a suitably sized Numpy array and return it together with the
+ arrays data pointer"""
+ bits = camera.props.sensor_bitdepth
+ dtype = np.uint16 if bits > 8 else np.uint8
+ a = np.zeros((cam.props.roi_height, cam.props.roi_width), dtype=dtype)
+ return a, a.__array_interface__['data'][0]
+
+# Suppose 'camera' is a already available, you would get the camera data like
+# this:
+a, buf = create_array_from(camera)
+camera.start_recording()
+camera.grab(buf)
+
+# Now data is in 'a' and we can use Numpy functions on it
+print(np.mean(a))
+
+camera.stop_recording()
+~~~
+
# Integrating new cameras
diff --git a/docs/mock.html b/docs/mock.html
index 0d38fc8..a2db94d 100644
--- a/docs/mock.html
+++ b/docs/mock.html
@@ -1,70 +1,73 @@
-<html><head><link rel="stylesheet" href="style.css" type="text/css" /><link href='http://fonts.googleapis.com/css?family=Droid+Sans:400,700|Droid+Serif:400,400italic|Inconsolata' rel='stylesheet' type='text/css'><title>mock &mdash; properties</title></head><body><div id="header"><h1 class="title">Property documentation of mock</h1><h2>Properties</h2><ul id="toc"><li><code><a href=#name>"name"</a></code></li><li><code><a href=#sensor-width>"sensor-width"</a></code></li><li><code><a href=#sensor-height>"sensor-height"</a></code></li><li><code><a href=#sensor-bitdepth>"sensor-bitdepth"</a></code></li><li><code><a href=#sensor-horizontal-binning>"sensor-horizontal-binning"</a></code></li><li><code><a href=#sensor-horizontal-binnings>"sensor-horizontal-binnings"</a></code></li><li><code><a href=#sensor-vertical-binning>"sensor-vertical-binning"</a></code></li><li><code><a href=#sensor-vertical-binnings>"sensor-vertical-binnings"</a></code></li><li><code><a href=#sensor-max-frame-rate>"sensor-max-frame-rate"</a></code></li><li><code><a href=#trigger-mode>"trigger-mode"</a></code></li><li><code><a href=#exposure-time>"exposure-time"</a></code></li><li><code><a href=#roi-x0>"roi-x0"</a></code></li><li><code><a href=#roi-y0>"roi-y0"</a></code></li><li><code><a href=#roi-width>"roi-width"</a></code></li><li><code><a href=#roi-height>"roi-height"</a></code></li><li><code><a href=#roi-width-multiplier>"roi-width-multiplier"</a></code></li><li><code><a href=#roi-height-multiplier>"roi-height-multiplier"</a></code></li><li><code><a href=#has-streaming>"has-streaming"</a></code></li><li><code><a href=#has-camram-recording>"has-camram-recording"</a></code></li><li><code><a href=#transfer-asynchronously>"transfer-asynchronously"</a></code></li><li><code><a href=#is-recording>"is-recording"</a></code></li><li><code><a href=#is-readout>"is-readout"</a></code></li><li><code><a href=#frame-rate>"frame-rate"</a></code></li></ul><h2>Details</h2><dl><dt id="name"><a href="#toc">name</a></dt>
+<html><head><link rel="stylesheet" href="style.css" type="text/css" /><link href='http://fonts.googleapis.com/css?family=Droid+Sans:400,700|Droid+Serif:400,400italic|Inconsolata' rel='stylesheet' type='text/css'><title>Basic camera &mdash; properties</title></head><body><div id="header"><h1 class="title">Property documentation of Basic camera</h1><h2>Properties</h2><ul id="toc"><li><code><a href=#name>"name"</a></code></li><li><code><a href=#sensor-width>"sensor-width"</a></code></li><li><code><a href=#sensor-height>"sensor-height"</a></code></li><li><code><a href=#sensor-bitdepth>"sensor-bitdepth"</a></code></li><li><code><a href=#sensor-horizontal-binning>"sensor-horizontal-binning"</a></code></li><li><code><a href=#sensor-horizontal-binnings>"sensor-horizontal-binnings"</a></code></li><li><code><a href=#sensor-vertical-binning>"sensor-vertical-binning"</a></code></li><li><code><a href=#sensor-vertical-binnings>"sensor-vertical-binnings"</a></code></li><li><code><a href=#sensor-max-frame-rate>"sensor-max-frame-rate"</a></code></li><li><code><a href=#trigger-mode>"trigger-mode"</a></code></li><li><code><a href=#exposure-time>"exposure-time"</a></code></li><li><code><a href=#frames-per-second>"frames-per-second"</a></code></li><li><code><a href=#roi-x0>"roi-x0"</a></code></li><li><code><a href=#roi-y0>"roi-y0"</a></code></li><li><code><a href=#roi-width>"roi-width"</a></code></li><li><code><a href=#roi-height>"roi-height"</a></code></li><li><code><a href=#roi-width-multiplier>"roi-width-multiplier"</a></code></li><li><code><a href=#roi-height-multiplier>"roi-height-multiplier"</a></code></li><li><code><a href=#has-streaming>"has-streaming"</a></code></li><li><code><a href=#has-camram-recording>"has-camram-recording"</a></code></li><li><code><a href=#recorded-frames>"recorded-frames"</a></code></li><li><code><a href=#transfer-asynchronously>"transfer-asynchronously"</a></code></li><li><code><a href=#is-recording>"is-recording"</a></code></li><li><code><a href=#is-readout>"is-readout"</a></code></li></ul><h2>Details</h2><dl><dt id="name"><a href="#toc">name</a></dt>
<dd><pre><code class="prop-type">"name" : gchararray : Read-only</code></pre>
<p>Name of the camera</p>
</dd><dt id="sensor-width"><a href="#toc">sensor-width</a></dt>
<dd><pre><code class="prop-type">"sensor-width" : guint : Read-only</code></pre>
<p>Width of the sensor in pixels</p>
-</dd><dt id="sensor-height"><a href="#toc">sensor-height</a></dt>
+<p>Possible values: 1 &#8804; <em>sensor-width</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="sensor-height"><a href="#toc">sensor-height</a></dt>
<dd><pre><code class="prop-type">"sensor-height" : guint : Read-only</code></pre>
<p>Height of the sensor in pixels</p>
-</dd><dt id="sensor-bitdepth"><a href="#toc">sensor-bitdepth</a></dt>
+<p>Possible values: 1 &#8804; <em>sensor-height</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="sensor-bitdepth"><a href="#toc">sensor-bitdepth</a></dt>
<dd><pre><code class="prop-type">"sensor-bitdepth" : guint : Read-only</code></pre>
<p>Number of bits per pixel</p>
-</dd><dt id="sensor-horizontal-binning"><a href="#toc">sensor-horizontal-binning</a></dt>
+<p>Possible values: 1 &#8804; <em>sensor-bitdepth</em> &#8804; 32</p><p>Default value: 1</p></dd><dt id="sensor-horizontal-binning"><a href="#toc">sensor-horizontal-binning</a></dt>
<dd><pre><code class="prop-type">"sensor-horizontal-binning" : guint : Read / Write</code></pre>
<p>Number of sensor ADCs that are combined to one pixel in horizontal direction</p>
-</dd><dt id="sensor-horizontal-binnings"><a href="#toc">sensor-horizontal-binnings</a></dt>
+<p>Possible values: 1 &#8804; <em>sensor-horizontal-binning</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="sensor-horizontal-binnings"><a href="#toc">sensor-horizontal-binnings</a></dt>
<dd><pre><code class="prop-type">"sensor-horizontal-binnings" : GValueArray : Read-only</code></pre>
<p>Array of possible binnings in horizontal direction</p>
</dd><dt id="sensor-vertical-binning"><a href="#toc">sensor-vertical-binning</a></dt>
<dd><pre><code class="prop-type">"sensor-vertical-binning" : guint : Read / Write</code></pre>
<p>Number of sensor ADCs that are combined to one pixel in vertical direction</p>
-</dd><dt id="sensor-vertical-binnings"><a href="#toc">sensor-vertical-binnings</a></dt>
+<p>Possible values: 1 &#8804; <em>sensor-vertical-binning</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="sensor-vertical-binnings"><a href="#toc">sensor-vertical-binnings</a></dt>
<dd><pre><code class="prop-type">"sensor-vertical-binnings" : GValueArray : Read-only</code></pre>
<p>Array of possible binnings in vertical direction</p>
</dd><dt id="sensor-max-frame-rate"><a href="#toc">sensor-max-frame-rate</a></dt>
<dd><pre><code class="prop-type">"sensor-max-frame-rate" : gfloat : Read-only</code></pre>
<p>Maximum frame rate at full frame resolution</p>
-</dd><dt id="trigger-mode"><a href="#toc">trigger-mode</a></dt>
+<p>Possible values: 0.0e+00 &#8804; <em>sensor-max-frame-rate</em> &#8804; 3.4e+38</p><p>Default value: 1.0e+00</p></dd><dt id="trigger-mode"><a href="#toc">trigger-mode</a></dt>
<dd><pre><code class="prop-type">"trigger-mode" : UcaCameraTrigger : Read / Write</code></pre>
<p>Trigger mode</p>
-</dd><dt id="exposure-time"><a href="#toc">exposure-time</a></dt>
+<p>Possible values: <table><tr><th>Enum name</th><th>Value</th><tr><td><code>UCA_CAMERA_TRIGGER_AUTO</code></td><td>0</td></tr><tr><td><code>UCA_CAMERA_TRIGGER_SOFTWARE</code></td><td>1</td></tr><tr><td><code>UCA_CAMERA_TRIGGER_EXTERNAL</code></td><td>2</td></tr></table></p></dd><dt id="exposure-time"><a href="#toc">exposure-time</a></dt>
<dd><pre><code class="prop-type">"exposure-time" : gdouble : Read / Write</code></pre>
<p>Exposure time in seconds</p>
-</dd><dt id="roi-x0"><a href="#toc">roi-x0</a></dt>
+<p>Possible values: 0.0e+00 &#8804; <em>exposure-time</em> &#8804; 1.8e+308</p><p>Default value: 1.0e+00</p></dd><dt id="frames-per-second"><a href="#toc">frames-per-second</a></dt>
+<dd><pre><code class="prop-type">"frames-per-second" : gdouble : Read / Write</code></pre>
+<p>Frames per second</p>
+<p>Possible values: 0.0e+00 &#8804; <em>frames-per-second</em> &#8804; 1.8e+308</p><p>Default value: 1.0e+00</p></dd><dt id="roi-x0"><a href="#toc">roi-x0</a></dt>
<dd><pre><code class="prop-type">"roi-x0" : guint : Read / Write</code></pre>
<p>Horizontal coordinate</p>
-</dd><dt id="roi-y0"><a href="#toc">roi-y0</a></dt>
+<p>Possible values: 0 &#8804; <em>roi-x0</em> &#8804; -1</p><p>Default value: 0</p></dd><dt id="roi-y0"><a href="#toc">roi-y0</a></dt>
<dd><pre><code class="prop-type">"roi-y0" : guint : Read / Write</code></pre>
<p>Vertical coordinate</p>
-</dd><dt id="roi-width"><a href="#toc">roi-width</a></dt>
+<p>Possible values: 0 &#8804; <em>roi-y0</em> &#8804; -1</p><p>Default value: 0</p></dd><dt id="roi-width"><a href="#toc">roi-width</a></dt>
<dd><pre><code class="prop-type">"roi-width" : guint : Read / Write</code></pre>
<p>Width of the region of interest</p>
-</dd><dt id="roi-height"><a href="#toc">roi-height</a></dt>
+<p>Possible values: 1 &#8804; <em>roi-width</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="roi-height"><a href="#toc">roi-height</a></dt>
<dd><pre><code class="prop-type">"roi-height" : guint : Read / Write</code></pre>
<p>Height of the region of interest</p>
-</dd><dt id="roi-width-multiplier"><a href="#toc">roi-width-multiplier</a></dt>
+<p>Possible values: 1 &#8804; <em>roi-height</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="roi-width-multiplier"><a href="#toc">roi-width-multiplier</a></dt>
<dd><pre><code class="prop-type">"roi-width-multiplier" : guint : Read-only</code></pre>
<p>Minimum possible step size of horizontal ROI</p>
-</dd><dt id="roi-height-multiplier"><a href="#toc">roi-height-multiplier</a></dt>
+<p>Possible values: 1 &#8804; <em>roi-width-multiplier</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="roi-height-multiplier"><a href="#toc">roi-height-multiplier</a></dt>
<dd><pre><code class="prop-type">"roi-height-multiplier" : guint : Read-only</code></pre>
<p>Minimum possible step size of vertical ROI</p>
-</dd><dt id="has-streaming"><a href="#toc">has-streaming</a></dt>
+<p>Possible values: 1 &#8804; <em>roi-height-multiplier</em> &#8804; -1</p><p>Default value: 1</p></dd><dt id="has-streaming"><a href="#toc">has-streaming</a></dt>
<dd><pre><code class="prop-type">"has-streaming" : gboolean : Read-only</code></pre>
<p>Is the camera able to stream the data</p>
-</dd><dt id="has-camram-recording"><a href="#toc">has-camram-recording</a></dt>
+<p>Default value: <code>TRUE</code></p></dd><dt id="has-camram-recording"><a href="#toc">has-camram-recording</a></dt>
<dd><pre><code class="prop-type">"has-camram-recording" : gboolean : Read-only</code></pre>
<p>Is the camera able to record the data in-camera</p>
-</dd><dt id="transfer-asynchronously"><a href="#toc">transfer-asynchronously</a></dt>
+<p>Default value: <code>FALSE</code></p></dd><dt id="recorded-frames"><a href="#toc">recorded-frames</a></dt>
+<dd><pre><code class="prop-type">"recorded-frames" : guint : Read-only</code></pre>
+<p>Number of frames recorded into internal camera memory</p>
+<p>Possible values: 0 &#8804; <em>recorded-frames</em> &#8804; -1</p><p>Default value: 0</p></dd><dt id="transfer-asynchronously"><a href="#toc">transfer-asynchronously</a></dt>
<dd><pre><code class="prop-type">"transfer-asynchronously" : gboolean : Read / Write</code></pre>
<p>Specify whether data should be transfered asynchronously using a specified callback</p>
-</dd><dt id="is-recording"><a href="#toc">is-recording</a></dt>
+<p>Default value: <code>FALSE</code></p></dd><dt id="is-recording"><a href="#toc">is-recording</a></dt>
<dd><pre><code class="prop-type">"is-recording" : gboolean : Read-only</code></pre>
<p>Is the camera currently recording</p>
-</dd><dt id="is-readout"><a href="#toc">is-readout</a></dt>
+<p>Default value: <code>FALSE</code></p></dd><dt id="is-readout"><a href="#toc">is-readout</a></dt>
<dd><pre><code class="prop-type">"is-readout" : gboolean : Read-only</code></pre>
<p>Is camera in readout mode</p>
-</dd><dt id="frame-rate"><a href="#toc">frame-rate</a></dt>
-<dd><pre><code class="prop-type">"frame-rate" : gfloat : Read / Write</code></pre>
-<p>Number of frames per second that are taken</p>
-</dd></dl></body></html>
+<p>Default value: <code>FALSE</code></p></dd></dl></body></html>
diff --git a/docs/style.css b/docs/style.css
index beccf45..41651e1 100644
--- a/docs/style.css
+++ b/docs/style.css
@@ -140,8 +140,9 @@ ol ol {
}
table {
- width: 100%;
+ margin-top: 1em;
margin-bottom: 24px;
+ padding: 1em;
}
th {
@@ -152,7 +153,9 @@ th {
}
td, th {
- padding: 2px;
+ padding-right: 1em;
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
}
dl {
diff --git a/misc/README.rst b/misc/README.rst
deleted file mode 100644
index baf0f22..0000000
--- a/misc/README.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-================================
-Patches for third party software
-================================
-
-OpenCV
-======
-
-OpenCV is a cross-platform, open source computer vision toolkit. We provide
-patches that integrate libuca in OpenCV in order to use all UCA-supported
-cameras within OpenCV like::
-
- CvCapture *capture = cvCaptureFromCAM(CV_CAP_UCA);
- cvNamedWindow("foo", CV_WINDOW_AUTOSIZE);
-
- IplImage *frame;
- frame = cvQueryFrame(capture);
- cvShowImage("foo", frame);
-
- cvDestroyWindow("foo");
- cvReleaseCapture(&capture);
-
-Patches
--------
-
-We only supply patches for stable releases of OpenCV. Apply them using
-
- ``patch -p0 < opencv-x.y.z.patch``
-
-inside the top-level directory of the source directory of OpenCV x.y.z.
diff --git a/misc/opencv-2.2.0.patch b/misc/opencv-2.2.0.patch
deleted file mode 100644
index f7297e9..0000000
--- a/misc/opencv-2.2.0.patch
+++ /dev/null
@@ -1,374 +0,0 @@
-=== modified file 'CMakeLists.txt'
---- CMakeLists.txt 2011-03-24 16:43:57 +0000
-+++ CMakeLists.txt 2011-03-25 08:34:03 +0000
-@@ -289,6 +289,7 @@
- set(WITH_GSTREAMER ON CACHE BOOL "Include Gstreamer support")
- set(WITH_V4L ON CACHE BOOL "Include Video 4 Linux support")
- set(WITH_XINE OFF CACHE BOOL "Include Xine support (GPL)")
-+ set(WITH_UCA OFF CACHE BOOL "Include Unified Camera Access support")
- endif()
- set(WITH_PVAPI ON CACHE BOOL "Include Prosilica GigE support")
- set(WITH_1394 ON CACHE BOOL "Include IEEE1394 support")
-@@ -437,6 +438,13 @@
- set(HAVE_CAMV4L2 FALSE)
- endif()
-
-+ if(WITH_UCA)
-+ CHECK_MODULE(uca HAVE_UCA)
-+ CHECK_INCLUDE_FILE(uca.h HAVE_UCA)
-+ else()
-+ set(HAVE_UCA FALSE)
-+ endif()
-+
- if(NOT OPENCV_BUILD_3RDPARTY_LIBS)
- if(WITH_PNG)
- include(FindPNG)
-@@ -1367,6 +1375,7 @@
- message(STATUS " V4L/V4L2: ${HAVE_CAMV4L}/${HAVE_CAMV4L2}")
- endif()
- message(STATUS " Xine: ${HAVE_XINE}")
-+message(STATUS " Unified Camera Access: ${HAVE_UCA}")
- endif()
-
- if(APPLE)
-
-=== modified file 'cvconfig.h.cmake'
---- cvconfig.h.cmake 2011-03-24 16:43:57 +0000
-+++ cvconfig.h.cmake 2011-03-25 10:41:09 +0000
-@@ -31,6 +31,9 @@
- /* IEEE1394 capturing support - libdc1394 v2.x */
- #cmakedefine HAVE_DC1394_2
-
-+/* Unified Camera Access - libuca 0.4.0 */
-+#cmakedefine HAVE_UCA
-+
- /* ffmpeg in Gentoo */
- #cmakedefine HAVE_GENTOO_FFMPEG
-
-
-=== modified file 'modules/highgui/CMakeLists.txt'
---- modules/highgui/CMakeLists.txt 2011-03-24 16:43:57 +0000
-+++ modules/highgui/CMakeLists.txt 2011-03-25 09:33:17 +0000
-@@ -118,6 +118,10 @@
- set(highgui_srcs ${highgui_srcs} src/cap_dc1394.cpp)
- endif()
-
-+ if(HAVE_UCA)
-+ set(highgui_srcs ${highgui_srcs} src/cap_uca.cpp)
-+ endif()
-+
- if(HAVE_FFMPEG)
- set(highgui_srcs ${highgui_srcs} src/cap_ffmpeg.cpp)
- if(BZIP2_LIBRARIES)
-
-=== modified file 'modules/highgui/include/opencv2/highgui/highgui_c.h'
---- modules/highgui/include/opencv2/highgui/highgui_c.h 2011-03-24 16:43:57 +0000
-+++ modules/highgui/include/opencv2/highgui/highgui_c.h 2011-03-25 08:55:31 +0000
-@@ -288,7 +288,9 @@
-
- CV_CAP_DSHOW =700, // DirectShow (via videoInput)
-
-- CV_CAP_PVAPI =800 // PvAPI, Prosilica GigE SDK
-+ CV_CAP_PVAPI =800, // PvAPI, Prosilica GigE SDK
-+
-+ CV_CAP_UCA =900 // Unified Camera Access for CameraLink and IPE camera
- };
-
- /* start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) */
-
-=== modified file 'modules/highgui/src/cap.cpp'
---- modules/highgui/src/cap.cpp 2011-03-24 16:43:57 +0000
-+++ modules/highgui/src/cap.cpp 2011-03-25 10:39:36 +0000
-@@ -123,6 +123,7 @@
- CV_CAP_MIL,
- CV_CAP_QT,
- CV_CAP_UNICAP,
-+ CV_CAP_UCA,
- -1
- };
-
-@@ -142,7 +143,7 @@
- defined(HAVE_CAMV4L) || defined (HAVE_CAMV4L2) || defined(HAVE_GSTREAMER) || \
- defined(HAVE_DC1394_2) || defined(HAVE_DC1394) || defined(HAVE_CMU1394) || \
- defined(HAVE_GSTREAMER) || defined(HAVE_MIL) || defined(HAVE_QUICKTIME) || \
-- defined(HAVE_UNICAP) || defined(HAVE_PVAPI)
-+ defined(HAVE_UNICAP) || defined(HAVE_PVAPI) || defined(HAVE_UCA)
- // local variable to memorize the captured device
- CvCapture *capture;
- #endif
-@@ -168,7 +169,7 @@
- case CV_CAP_VFW:
- #ifdef HAVE_VFW
- capture = cvCreateCameraCapture_VFW (index);
-- if (capture)
-+ if (capture)
- return capture;
- #endif
- #if defined (HAVE_CAMV4L) || defined (HAVE_CAMV4L2)
-@@ -241,6 +242,14 @@
- return capture;
- break;
- #endif
-+
-+ #ifdef HAVE_UCA
-+ case CV_CAP_UCA:
-+ capture = cvCreateCameraCapture_UCA (index);
-+ if (capture)
-+ return capture;
-+ break;
-+ #endif
-
- }
- }
-
-=== added file 'modules/highgui/src/cap_uca.cpp'
---- modules/highgui/src/cap_uca.cpp 1970-01-01 00:00:00 +0000
-+++ modules/highgui/src/cap_uca.cpp 2011-03-25 11:31:07 +0000
-@@ -0,0 +1,234 @@
-+/*M///////////////////////////////////////////////////////////////////////////////////////
-+//
-+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
-+//
-+// By downloading, copying, installing or using the software you agree to this license.
-+// If you do not agree to this license, do not download, install,
-+// copy or use the software.
-+//
-+//
-+// Intel License Agreement
-+// For Open Source Computer Vision Library
-+//
-+// Copyright (C) 2008, Nils Hasler, all rights reserved.
-+// Third party copyrights are property of their respective owners.
-+//
-+// Redistribution and use in source and binary forms, with or without modification,
-+// are permitted provided that the following conditions are met:
-+//
-+// * Redistribution's of source code must retain the above copyright notice,
-+// this list of conditions and the following disclaimer.
-+//
-+// * Redistribution's in binary form must reproduce the above copyright notice,
-+// this list of conditions and the following disclaimer in the documentation
-+// and/or other materials provided with the distribution.
-+//
-+// * The name of Intel Corporation may not be used to endorse or promote products
-+// derived from this software without specific prior written permission.
-+//
-+// This software is provided by the copyright holders and contributors "as is" and
-+// any express or implied warranties, including, but not limited to, the implied
-+// warranties of merchantability and fitness for a particular purpose are disclaimed.
-+// In no event shall the Intel Corporation or contributors be liable for any direct,
-+// indirect, incidental, special, exemplary, or consequential damages
-+// (including, but not limited to, procurement of substitute goods or services;
-+// loss of use, data, or profits; or business interruption) however caused
-+// and on any theory of liability, whether in contract, strict liability,
-+// or tort (including negligence or otherwise) arising in any way out of
-+// the use of this software, even if advised of the possibility of such damage.
-+//
-+//M*/
-+
-+// Author: Matthias Vogelgesang <matthias.vogelgesang@kit.edu>
-+//
-+// Karlsruhe Institute of Technology (KIT)
-+// Institute for Data Processing and Electronics
-+//
-+
-+
-+#include "precomp.hpp"
-+#include <unistd.h>
-+#include <string.h>
-+#include <uca/uca.h>
-+#include <uca/uca-cam.h>
-+
-+#ifdef NDEBUG
-+#define CV_WARN(message)
-+#else
-+#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
-+#endif
-+
-+static bool is_initialized = false;
-+
-+class CvCapture_UCA : public CvCapture
-+{
-+ public:
-+ CvCapture_UCA() { init(); }
-+ virtual ~CvCapture_UCA() { close(); }
-+
-+ virtual bool open(int);
-+ virtual void close();
-+
-+ virtual double getProperty(int);
-+ virtual bool setProperty(int, double);
-+ virtual bool grabFrame();
-+ virtual IplImage* retrieveFrame(int);
-+
-+ protected:
-+ void init();
-+ char *buffer;
-+ IplImage *frame;
-+
-+ private:
-+ struct uca *uca_handle;
-+ struct uca_camera *device;
-+ int width;
-+ int height;
-+ int bit_depth; // in terms of IplImage structure
-+ int pixel_size;
-+};
-+
-+void CvCapture_UCA::init()
-+{
-+ buffer = NULL;
-+ frame = NULL;
-+ width = 0;
-+ height = 0;
-+ bit_depth = 0;
-+ pixel_size = 0;
-+}
-+
-+bool CvCapture_UCA::grabFrame()
-+{
-+ if (!buffer)
-+ return false;
-+
-+ device->grab(device, buffer, NULL);
-+ return true;
-+}
-+
-+IplImage * CvCapture_UCA::retrieveFrame(int)
-+{
-+ if (!frame)
-+ frame = cvCreateImage(cvSize(width, height), bit_depth, 1);
-+
-+ memcpy (frame->imageData, buffer, width*height*pixel_size);
-+ return frame;
-+}
-+
-+bool CvCapture_UCA::open(int index)
-+{
-+ //CV_FUNCNAME("cvCaptureFromCAM_UCA");
-+
-+ __BEGIN__;
-+
-+ if (!is_initialized) {
-+ is_initialized = true;
-+ }
-+
-+ uca_handle = uca_init(NULL);
-+ if (uca_handle == NULL)
-+ return false;
-+
-+ device = uca_handle->cameras;
-+
-+ device->get_property(device, UCA_PROP_WIDTH, &width, 0);
-+ device->get_property(device, UCA_PROP_HEIGHT, &height, 0);
-+
-+ int bits = 0;
-+ device->get_property(device, UCA_PROP_BITDEPTH, &bits, 0);
-+ bit_depth = (bits == 8) ? IPL_DEPTH_8U : IPL_DEPTH_16U;
-+
-+ pixel_size = (bits == 8) ? 1 : 2;
-+ buffer = new char[width*height*pixel_size];
-+ uca_cam_alloc(device, 10);
-+
-+ device->start_recording(device);
-+
-+ __END__;
-+ return true;
-+}
-+
-+void CvCapture_UCA::close()
-+{
-+ if (device)
-+ device->stop_recording(device);
-+ if (uca_handle);
-+ uca_destroy(uca_handle);
-+ delete[] buffer;
-+}
-+
-+double CvCapture_UCA::getProperty( int propId )
-+{
-+ switch(propId) {
-+ case CV_CAP_PROP_POS_MSEC:
-+ case CV_CAP_PROP_POS_FRAMES:
-+ case CV_CAP_PROP_POS_AVI_RATIO:
-+ break;
-+ case CV_CAP_PROP_FRAME_WIDTH:
-+ return (double) width;
-+ case CV_CAP_PROP_FRAME_HEIGHT:
-+ return (double) height;
-+ case CV_CAP_PROP_FPS:
-+ case CV_CAP_PROP_FOURCC:
-+ break;
-+ case CV_CAP_PROP_FRAME_COUNT:
-+ return (double) device->current_frame;
-+ case CV_CAP_PROP_FORMAT:
-+ case CV_CAP_PROP_MODE:
-+ case CV_CAP_PROP_BRIGHTNESS:
-+ case CV_CAP_PROP_CONTRAST:
-+ case CV_CAP_PROP_SATURATION:
-+ case CV_CAP_PROP_HUE:
-+ case CV_CAP_PROP_GAIN:
-+ case CV_CAP_PROP_CONVERT_RGB:
-+ break;
-+ default:
-+ CV_WARN("UCA: unhandled property");
-+ break;
-+ }
-+ return false;
-+}
-+
-+bool CvCapture_UCA::setProperty( int propId, double value )
-+{
-+ switch(propId) {
-+ case CV_CAP_PROP_POS_MSEC:
-+ break;
-+ case CV_CAP_PROP_POS_FRAMES:
-+ break;
-+ case CV_CAP_PROP_POS_AVI_RATIO:
-+ break;
-+ case CV_CAP_PROP_FRAME_WIDTH:
-+ break;
-+ case CV_CAP_PROP_FRAME_HEIGHT:
-+ break;
-+ case CV_CAP_PROP_FPS:
-+ break;
-+ case CV_CAP_PROP_FOURCC:
-+ case CV_CAP_PROP_FRAME_COUNT:
-+ case CV_CAP_PROP_FORMAT:
-+ case CV_CAP_PROP_MODE:
-+ case CV_CAP_PROP_BRIGHTNESS:
-+ case CV_CAP_PROP_CONTRAST:
-+ case CV_CAP_PROP_SATURATION:
-+ case CV_CAP_PROP_HUE:
-+ case CV_CAP_PROP_GAIN:
-+ case CV_CAP_PROP_CONVERT_RGB:
-+ break;
-+ default:
-+ CV_WARN("UCA: unhandled property");
-+ }
-+ return false;
-+}
-+
-+CvCapture *cvCreateCameraCapture_UCA(int index)
-+{
-+ CvCapture_UCA* capture = new CvCapture_UCA;
-+
-+ if (capture->open(index))
-+ return capture;
-+
-+ delete capture;
-+ return false;
-+}
-
-=== modified file 'modules/highgui/src/precomp.hpp'
---- modules/highgui/src/precomp.hpp 2011-03-24 16:43:57 +0000
-+++ modules/highgui/src/precomp.hpp 2011-03-25 09:29:34 +0000
-@@ -113,6 +113,7 @@
- CvCapture * cvCreateCameraCapture_DC1394_2( int index );
- CvCapture* cvCreateCameraCapture_MIL( int index );
- CvCapture * cvCreateCameraCapture_CMU( int index );
-+CvCapture * cvCreateCameraCapture_UCA( int index );
- CV_IMPL CvCapture * cvCreateCameraCapture_TYZX( int index );
- CvCapture* cvCreateFileCapture_Win32( const char* filename );
- CvCapture* cvCreateCameraCapture_VFW( int index );
-
diff --git a/plugins/mock/uca-mock-camera.c b/plugins/mock/uca-mock-camera.c
index bf3124e..675d5ec 100644
--- a/plugins/mock/uca-mock-camera.c
+++ b/plugins/mock/uca-mock-camera.c
@@ -16,12 +16,17 @@
Franklin St, Fifth Floor, Boston, MA 02110, USA */
#include <gmodule.h>
+#include <gio/gio.h>
#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)
+static void uca_mock_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_mock_initable_iface_init))
enum {
PROP_FRAMERATE = N_BASE_PROPERTIES,
@@ -38,6 +43,7 @@ static const gint mock_overrideables[] = {
PROP_SENSOR_VERTICAL_BINNING,
PROP_SENSOR_VERTICAL_BINNINGS,
PROP_EXPOSURE_TIME,
+ PROP_TRIGGER_MODE,
PROP_ROI_X,
PROP_ROI_Y,
PROP_ROI_WIDTH,
@@ -53,6 +59,8 @@ static const gint mock_overrideables[] = {
static GParamSpec *mock_properties[N_PROPERTIES] = { NULL, };
struct _UcaMockCameraPrivate {
+ UcaCameraTrigger trigger;
+
guint width;
guint height;
guint roi_x, roi_y, roi_width, roi_height;
@@ -134,7 +142,8 @@ static const char g_digits[10][20] = {
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)
+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++) {
@@ -143,7 +152,8 @@ static void print_number(gchar *buffer, guint number, guint x, guint y, guint wi
}
}
-static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
+static void
+print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
{
guint number = priv->current_frame;
guint divisor = 10000000;
@@ -157,7 +167,8 @@ static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
}
}
-static gpointer mock_grab_func(gpointer data)
+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);
@@ -174,7 +185,8 @@ static gpointer mock_grab_func(gpointer data)
return NULL;
}
-static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
+static void
+uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
{
gboolean transfer_async = FALSE;
UcaMockCameraPrivate *priv;
@@ -204,7 +216,8 @@ static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
}
}
-static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
+static void
+uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
{
gboolean transfer_async = FALSE;
UcaMockCameraPrivate *priv;
@@ -224,22 +237,27 @@ static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
}
}
-static void uca_mock_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static void
+uca_mock_camera_trigger (UcaCamera *camera, 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);
+static gboolean
+uca_mock_camera_grab (UcaCamera *camera, gpointer data, GError **error)
+{
+ g_return_val_if_fail (UCA_IS_MOCK_CAMERA(camera), FALSE);
- if (*data == NULL)
- *data = g_malloc0(priv->width * priv->height);
+ UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE (camera);
- g_memmove(*data, priv->dummy_data, priv->width * priv->height);
- print_current_frame(priv, *data);
+ g_memmove (data, priv->dummy_data, priv->roi_width * priv->roi_height);
+ print_current_frame (priv, data);
priv->current_frame++;
+
+ return TRUE;
}
-static void uca_mock_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+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);
@@ -263,13 +281,17 @@ static void uca_mock_camera_set_property(GObject *object, guint property_id, con
case PROP_ROI_HEIGHT:
priv->roi_height = g_value_get_uint(value);
break;
+ case PROP_TRIGGER_MODE:
+ priv->trigger = g_value_get_enum (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)
+static void
+uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
@@ -331,13 +353,17 @@ static void uca_mock_camera_get_property(GObject *object, guint property_id, GVa
case PROP_FRAMERATE:
g_value_set_float(value, priv->frame_rate);
break;
+ case PROP_TRIGGER_MODE:
+ g_value_set_enum (value, priv->trigger);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
}
}
-static void uca_mock_camera_finalize(GObject *object)
+static void
+uca_mock_camera_finalize(GObject *object)
{
UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
@@ -352,7 +378,23 @@ static void uca_mock_camera_finalize(GObject *object)
G_OBJECT_CLASS(uca_mock_camera_parent_class)->finalize(object);
}
-static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
+static gboolean
+ufo_mock_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (UCA_IS_MOCK_CAMERA (initable), FALSE);
+ return TRUE;
+}
+
+static void
+uca_mock_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = ufo_mock_camera_initable_init;
+}
+
+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;
@@ -363,6 +405,7 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *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;
+ camera_class->trigger = uca_mock_camera_trigger;
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]]);
@@ -380,13 +423,14 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate));
}
-static void uca_mock_camera_init(UcaMockCamera *self)
+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->width = self->priv->roi_width = 2016;
+ self->priv->height = self->priv->roi_height = 2016;
self->priv->frame_rate = self->priv->max_frame_rate = 100000.0f;
self->priv->grab_thread = NULL;
self->priv->current_frame = 0;
@@ -401,9 +445,8 @@ static void uca_mock_camera_init(UcaMockCamera *self)
uca_camera_register_unit (UCA_CAMERA (self), "frame-rate", UCA_UNIT_COUNT);
}
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
{
- UcaCamera *camera = UCA_CAMERA (g_object_new (UCA_TYPE_MOCK_CAMERA, NULL));
- return camera;
+ return UCA_TYPE_MOCK_CAMERA;
}
diff --git a/plugins/mock/uca-mock-camera.h b/plugins/mock/uca-mock-camera.h
index 9ee9190..bfbd166 100644
--- a/plugins/mock/uca-mock-camera.h
+++ b/plugins/mock/uca-mock-camera.h
@@ -58,8 +58,6 @@ struct _UcaMockCameraClass {
UcaCameraClass parent;
};
-GType uca_mock_camera_get_type(void);
-
G_END_DECLS
#endif
diff --git a/plugins/pco/uca-pco-camera.c b/plugins/pco/uca-pco-camera.c
index bb7bd5a..4a0cce6 100644
--- a/plugins/pco/uca-pco-camera.c
+++ b/plugins/pco/uca-pco-camera.c
@@ -15,6 +15,7 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+#include <gio/gio.h>
#include <gmodule.h>
#include <stdlib.h>
#include <stdio.h>
@@ -26,14 +27,13 @@
#include "uca-pco-camera.h"
#include "uca-enums.h"
-#define FG_TRY_PARAM(fg, camobj, param, val_addr, port) \
+#define FG_TRY_PARAM(fg, error, 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, \
+ g_set_error (error, UCA_PCO_CAMERA_ERROR, \
UCA_PCO_CAMERA_ERROR_FG_GENERAL, \
"%s", Fg_getLastErrorDescription(fg)); \
- g_object_unref(camobj); \
- return NULL; \
+ return FALSE; \
} }
#define FG_SET_ERROR(err, fg, err_type) \
@@ -54,7 +54,11 @@
#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)
+static void uca_pco_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaPcoCamera, uca_pco_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_pco_camera_initable_iface_init))
#define TIMEBASE_INVALID 0xDEAD
@@ -149,7 +153,7 @@ static GParamSpec *pco_properties[N_PROPERTIES] = { NULL, };
* This structure defines type-specific properties of PCO cameras.
*/
typedef struct {
- int camera_type;
+ int type;
const char *so_file;
int cl_type;
int cl_format;
@@ -158,8 +162,9 @@ typedef struct {
} pco_cl_map_entry;
struct _UcaPcoCameraPrivate {
+ GError *construct_error;
pco_handle pco;
- pco_cl_map_entry *camera_description;
+ pco_cl_map_entry *description;
Fg_Struct *fg;
guint fg_port;
@@ -193,7 +198,7 @@ struct _UcaPcoCameraPrivate {
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, "libDualAreaGray16.so", FG_CL_SINGLETAP_8_BIT, FG_GRAY16, 1279.0f, TRUE },
+ { CAMERATYPE_PCO_DIMAX_STD, "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT, FG_GRAY16, 1279.0f, TRUE },
{ 0, NULL, 0, 0, 0.0f, FALSE }
};
@@ -201,8 +206,8 @@ 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)
+ while (entry->type != 0) {
+ if (entry->type == camera_type)
return entry;
entry++;
}
@@ -249,7 +254,7 @@ 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);
+ priv->pixelrates = g_value_array_new (num_rates);
for (gint i = 0; i < num_rates; i++) {
g_value_set_uint(&val, (guint) rates[i]);
@@ -330,7 +335,7 @@ get_suitable_timebase(gdouble time)
static gdouble
get_internal_delay (UcaPcoCamera *camera)
{
- if (camera->priv->camera_description->camera_type == CAMERATYPE_PCO_DIMAX_STD) {
+ if (camera->priv->description->type == CAMERATYPE_PCO_DIMAX_STD) {
gdouble sensor_rate;
g_object_get (camera, "sensor-pixelrate", &sensor_rate, NULL);
@@ -350,7 +355,7 @@ fg_callback(frameindex_t frame, struct fg_apc_data *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)
+ if (priv->description->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);
@@ -392,7 +397,7 @@ check_pco_property_error (guint err, guint property_id)
}
static void
-uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
+uca_pco_camera_start_recording (UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
guint err = PCO_NOERROR;
@@ -447,7 +452,7 @@ uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
/* 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;
+ guint fg_width = priv->description->type == CAMERATYPE_PCO_EDGE ? 2 * priv->roi_width : priv->roi_width;
priv->frame_width = priv->roi_width;
priv->frame_height = priv->roi_height;
@@ -474,8 +479,8 @@ uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
if (transfer_async)
setup_fg_callback(camera);
- if ((priv->camera_description->camera_type == CAMERATYPE_PCO_DIMAX_STD) ||
- (priv->camera_description->camera_type == CAMERATYPE_PCO4000))
+ if ((priv->description->type == CAMERATYPE_PCO_DIMAX_STD) ||
+ (priv->description->type == CAMERATYPE_PCO4000))
pco_clear_active_segment(priv->pco);
priv->last_frame = 0;
@@ -491,11 +496,10 @@ uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
}
static void
-uca_pco_camera_stop_recording(UcaCamera *camera, GError **error)
+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);
@@ -561,12 +565,12 @@ uca_pco_camera_trigger(UcaCamera *camera, GError **error)
"Could not trigger frame acquisition");
}
-static void
-uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static gboolean
+uca_pco_camera_grab(UcaCamera *camera, gpointer data, GError **error)
{
- static const gint MAX_TIMEOUT = G_MAXINT;
+ static const gint MAX_TIMEOUT = 5;
- g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_PCO_CAMERA(camera), FALSE);
UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
gboolean is_readout = FALSE;
@@ -576,7 +580,7 @@ uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
if (priv->current_image == priv->num_recorded_images) {
g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_END_OF_STREAM,
"End of data stream");
- return;
+ return FALSE;
}
/*
@@ -591,19 +595,20 @@ uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
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);
+ g_set_error (error, UCA_PCO_CAMERA_ERROR,
+ UCA_PCO_CAMERA_ERROR_FG_GENERAL,
+ "%s", Fg_getLastErrorDescription(priv->fg));
+ return FALSE;
}
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);
+ if (priv->description->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);
+ memcpy((gchar *) data, (gchar *) frame, priv->frame_width * priv->frame_height * priv->num_bytes);
+
+ return TRUE;
}
static void
@@ -915,7 +920,7 @@ uca_pco_camera_get_property(GObject *object, guint property_id, GValue *value, G
break;
case PROP_SENSOR_MAX_FRAME_RATE:
- g_value_set_float(value, priv->camera_description->max_frame_rate);
+ g_value_set_float(value, priv->description->max_frame_rate);
break;
case PROP_SENSOR_BITDEPTH:
@@ -1023,7 +1028,7 @@ uca_pco_camera_get_property(GObject *object, guint property_id, GValue *value, G
break;
case PROP_HAS_CAMRAM_RECORDING:
- g_value_set_boolean(value, priv->camera_description->has_camram);
+ g_value_set_boolean(value, priv->description->has_camram);
break;
case PROP_RECORDED_FRAMES:
@@ -1179,27 +1184,63 @@ 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);
+ g_value_array_free (priv->horizontal_binnings);
if (priv->vertical_binnings)
- g_value_array_free(priv->vertical_binnings);
+ g_value_array_free (priv->vertical_binnings);
if (priv->pixelrates)
- g_value_array_free(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);
+ Fg_FreeGrabber (priv->fg);
}
if (priv->pco)
- pco_destroy(priv->pco);
+ pco_destroy (priv->pco);
+
+ g_free (priv->grab_buffer);
+ g_clear_error (&priv->construct_error);
+
+ G_OBJECT_CLASS (uca_pco_camera_parent_class)->finalize (object);
+}
- g_free(priv->grab_buffer);
+static gboolean
+uca_pco_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ UcaPcoCamera *camera;
+ UcaPcoCameraPrivate *priv;
+
+ g_return_val_if_fail (UCA_IS_PCO_CAMERA (initable), FALSE);
+
+ if (cancellable != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ camera = UCA_PCO_CAMERA (initable);
+ priv = camera->priv;
+
+ if (priv->construct_error != NULL) {
+ if (error)
+ *error = g_error_copy (priv->construct_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
- G_OBJECT_CLASS(uca_pco_camera_parent_class)->finalize(object);
+static void
+uca_pco_camera_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = uca_pco_camera_initable_init;
}
static void
@@ -1387,62 +1428,43 @@ uca_pco_camera_class_init(UcaPcoCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaPcoCameraPrivate));
}
-static void
-uca_pco_camera_init(UcaPcoCamera *self)
+static gboolean
+setup_pco_camera (UcaPcoCameraPrivate *priv)
{
- UcaCamera *camera;
-
- 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;
+ pco_cl_map_entry *map_entry;
+ guint16 roi[4];
+ guint16 camera_type;
+ guint16 camera_subtype;
- self->priv->delay_timebase = TIMEBASE_INVALID;
- self->priv->exposure_timebase = TIMEBASE_INVALID;
+ priv->pco = pco_init();
- camera = UCA_CAMERA (self);
- uca_camera_register_unit (camera, "sensor-width-extended", UCA_UNIT_PIXEL);
- uca_camera_register_unit (camera, "sensor-height-extended", UCA_UNIT_PIXEL);
- uca_camera_register_unit (camera, "sensor-temperature", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point-min", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point-max", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point-default", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "sensor-adcs", UCA_UNIT_COUNT);
- uca_camera_register_unit (camera, "sensor-max-adcs", UCA_UNIT_COUNT);
- uca_camera_register_unit (camera, "delay-time", UCA_UNIT_SECOND);
-}
+ if (priv->pco == NULL) {
+ g_set_error (&priv->construct_error,
+ UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT,
+ "Initializing libpco failed");
+ return FALSE;
+ }
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
-{
- pco_handle pco = pco_init();
+ pco_get_camera_type (priv->pco, &camera_type, &camera_subtype);
+ map_entry = get_pco_cl_map_entry (camera_type);
- if (pco == NULL) {
- g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT,
- "Initializing libpco failed");
- return NULL;
+ if (map_entry == NULL) {
+ g_set_error (&priv->construct_error,
+ UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED,
+ "Camera type is not supported");
+ return FALSE;
}
- UcaPcoCamera *camera = g_object_new(UCA_TYPE_PCO_CAMERA, NULL);
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
- priv->pco = pco;
+ priv->description = map_entry;
- pco_get_active_segment(priv->pco, &priv->active_segment);
- 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);
+ pco_get_active_segment (priv->pco, &priv->active_segment);
+ 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 (priv->pco, STORAGE_MODE_RECORDER);
+ pco_set_auto_transfer (priv->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);
+ 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;
@@ -1450,61 +1472,103 @@ uca_camera_impl_new (GError **error)
priv->roi_height = roi[3] - roi[1] + 1;
priv->num_recorded_images = 0;
- 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;
+ return TRUE;
+}
- 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;
- }
+static gboolean
+setup_frame_grabber (UcaPcoCameraPrivate *priv)
+{
+ guint32 fg_width;
+ guint32 fg_height;
+ int val;
priv->fg_port = PORT_A;
- priv->fg = Fg_Init(map_entry->so_file, priv->fg_port);
+ priv->fg = Fg_Init (priv->description->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;
+ g_set_error (&priv->construct_error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_FG_INIT,
+ "%s", Fg_getLastErrorDescription(priv->fg));
+ return FALSE;
}
- 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, &priv->construct_error, FG_CAMERA_LINK_CAMTYP, &priv->description->cl_type, priv->fg_port);
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_FORMAT, &priv->description->cl_format, priv->fg_port);
- 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);
+ fg_width = priv->description->type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width;
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_WIDTH, &fg_width, priv->fg_port);
- int val = FREE_RUN;
- FG_TRY_PARAM(priv->fg, camera, FG_TRIGGERMODE, &val, priv->fg_port);
+ fg_height = priv->height;
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_HEIGHT, &fg_height, priv->fg_port);
- fill_binnings(priv);
+ val = FREE_RUN;
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_TRIGGERMODE, &val, priv->fg_port);
- /*
- * 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);
+ return TRUE;
+}
+
+static void
+override_property_ranges (UcaPcoCamera *camera)
+{
+ UcaPcoCameraPrivate *priv;
+ GObjectClass *oclass;
+
+ priv = UCA_PCO_CAMERA_GET_PRIVATE (camera);
+ oclass = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera));
+ property_override_default_guint_value (oclass, "roi-width", priv->width);
+ property_override_default_guint_value (oclass, "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]);
+ if (pco_get_available_pixelrates (priv->pco, rates, &num_rates) == PCO_NOERROR) {
+ fill_pixelrates (priv, rates, num_rates);
+ property_override_default_guint_value (oclass, "sensor-pixelrate", rates[0]);
}
override_temperature_range (priv);
override_maximum_adcs (priv);
+}
+
+static void
+uca_pco_camera_init (UcaPcoCamera *self)
+{
+ UcaCamera *camera;
+ UcaPcoCameraPrivate *priv;
+
+ self->priv = priv = UCA_PCO_CAMERA_GET_PRIVATE (self);
- return UCA_CAMERA (camera);
+ priv->fg_mem = NULL;
+ priv->description = NULL;
+ priv->last_frame = 0;
+ priv->grab_buffer = NULL;
+ priv->construct_error = NULL;
+ priv->delay_timebase = TIMEBASE_INVALID;
+ priv->exposure_timebase = TIMEBASE_INVALID;
+
+ if (!setup_pco_camera (priv))
+ return;
+
+ if (!setup_frame_grabber (priv))
+ return;
+
+ fill_binnings (priv);
+ override_property_ranges (self);
+
+ camera = UCA_CAMERA (self);
+ uca_camera_register_unit (camera, "sensor-width-extended", UCA_UNIT_PIXEL);
+ uca_camera_register_unit (camera, "sensor-height-extended", UCA_UNIT_PIXEL);
+ uca_camera_register_unit (camera, "sensor-temperature", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point-min", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point-max", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point-default", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "sensor-adcs", UCA_UNIT_COUNT);
+ uca_camera_register_unit (camera, "sensor-max-adcs", UCA_UNIT_COUNT);
+ uca_camera_register_unit (camera, "delay-time", UCA_UNIT_SECOND);
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
+{
+ return UCA_TYPE_PCO_CAMERA;
}
diff --git a/plugins/pco/uca-pco-camera.h b/plugins/pco/uca-pco-camera.h
index d134fb1..347c27c 100644
--- a/plugins/pco/uca-pco-camera.h
+++ b/plugins/pco/uca-pco-camera.h
@@ -57,8 +57,8 @@ typedef enum {
typedef enum {
UCA_PCO_CAMERA_TIMESTAMP_NONE,
UCA_PCO_CAMERA_TIMESTAMP_BINARY,
- UCA_PCO_CAMERA_TIMESTAMP_ASCII,
- UCA_PCO_CAMERA_TIMESTAMP_BOTH
+ UCA_PCO_CAMERA_TIMESTAMP_BOTH,
+ UCA_PCO_CAMERA_TIMESTAMP_ASCII
} UcaPcoCameraTimestamp;
/**
diff --git a/plugins/pf/uca-pf-camera.c b/plugins/pf/uca-pf-camera.c
index 473ffd3..b7967be 100644
--- a/plugins/pf/uca-pf-camera.c
+++ b/plugins/pf/uca-pf-camera.c
@@ -15,6 +15,7 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+#include <gio/gio.h>
#include <gmodule.h>
#include <stdlib.h>
#include <stdio.h>
@@ -32,7 +33,6 @@
g_set_error(error, UCA_PF_CAMERA_ERROR, \
UCA_PF_CAMERA_ERROR_FG_GENERAL, \
"%s", Fg_getLastErrorDescription(fg)); \
- g_object_unref(camobj); \
return NULL; \
} }
@@ -46,7 +46,11 @@
#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)
+static void uca_pf_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaPfCamera, uca_pf_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_pf_camera_initable_iface_init))
/**
* UcaPfCameraError:
@@ -91,6 +95,7 @@ enum {
struct _UcaPfCameraPrivate {
+ GError *construct_error;
guint roi_width;
guint roi_height;
guint last_frame;
@@ -107,7 +112,8 @@ struct {
UcaCamera *camera;
} fg_apc_data;
-static int me4_callback(frameindex_t frame, struct fg_apc_data *apc)
+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);
@@ -115,7 +121,8 @@ static int me4_callback(frameindex_t frame, struct fg_apc_data *apc)
return 0;
}
-static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
+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);
@@ -155,7 +162,8 @@ static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION);
}
-static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
+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);
@@ -168,34 +176,39 @@ static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
g_print(" Unable to unblock all\n");
}
-static void uca_pf_camera_start_readout(UcaCamera *camera, GError **error)
+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)
+static gboolean
+uca_pf_camera_grab(UcaCamera *camera, gpointer data, GError **error)
{
- g_return_if_fail(UCA_IS_PF_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_PF_CAMERA (camera), FALSE);
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);
+ 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);
+ g_set_error (error, UCA_PF_CAMERA_ERROR,
+ UCA_PF_CAMERA_ERROR_FG_ACQUISITION,
+ "%s", Fg_getLastErrorDescription(priv->fg));
+ return FALSE;
}
- 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);
+ guint16 *frame = Fg_getImagePtrEx (priv->fg, priv->last_frame,
+ priv->fg_port, priv->fg_mem);
- memcpy((gchar *) *data, (gchar *) frame, priv->roi_width * priv->roi_height);
+ memcpy((gchar *) data, (gchar *) frame, priv->roi_width * priv->roi_height);
+ return TRUE;
}
-static void uca_pf_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+static void
+uca_pf_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch (property_id) {
default:
@@ -204,7 +217,8 @@ static void uca_pf_camera_set_property(GObject *object, guint property_id, const
}
}
-static void uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+static void
+uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
switch (property_id) {
case PROP_SENSOR_WIDTH:
@@ -263,7 +277,8 @@ static void uca_pf_camera_get_property(GObject *object, guint property_id, GValu
}
}
-static void uca_pf_camera_finalize(GObject *object)
+static void
+uca_pf_camera_finalize(GObject *object)
{
UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(object);
@@ -274,10 +289,54 @@ static void uca_pf_camera_finalize(GObject *object)
Fg_FreeGrabber(priv->fg);
}
+ g_clear_error (&priv->construct_error);
+
G_OBJECT_CLASS(uca_pf_camera_parent_class)->finalize(object);
}
-static void uca_pf_camera_class_init(UcaPfCameraClass *klass)
+static gboolean
+uca_pf_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ UcaPfCamera *camera;
+ UcaPfCameraPrivate *priv;
+
+ g_return_val_if_fail (UCA_IS_PF_CAMERA (initable), FALSE);
+
+ if (cancellable != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ camera = UCA_PF_CAMERA (initable);
+ priv = camera->priv;
+
+ if (priv->construct_error != NULL) {
+ if (error)
+ *error = g_error_copy (priv->construct_error);
+
+ return FALSE;
+ }
+
+ if (priv->fg == NULL) {
+ g_set_error (error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
+ "%s", Fg_getLastErrorDescription (NULL));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+uca_pf_camera_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = uca_pf_camera_initable_init;
+}
+
+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;
@@ -296,57 +355,56 @@ static void uca_pf_camera_class_init(UcaPfCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaPfCameraPrivate));
}
-static void uca_pf_camera_init(UcaPfCamera *self)
+static gboolean
+try_fg_param (UcaPfCameraPrivate *priv,
+ int param,
+ const gpointer value)
{
- self->priv = UCA_PF_CAMERA_GET_PRIVATE(self);
- self->priv->fg = NULL;
- self->priv->fg_mem = NULL;
- self->priv->last_frame = 0;
+ if (Fg_setParameter (priv->fg, param, value, priv->fg_port) != FG_OK) {
+ g_set_error (&priv->construct_error, UCA_PF_CAMERA_ERROR,
+ UCA_PF_CAMERA_ERROR_FG_GENERAL,
+ "%s", Fg_getLastErrorDescription (priv->fg));
+ return FALSE;
+ }
+
+ return TRUE;
}
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+static void
+uca_pf_camera_init (UcaPfCamera *self)
{
+ UcaPfCameraPrivate *priv;
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;
- }
- */
+ static const int link_type = FG_CL_8BIT_FULL_8;
+ static const int format = FG_GRAY;
- UcaPfCamera *camera = g_object_new(UCA_TYPE_PF_CAMERA, NULL);
- UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
+ self->priv = priv = UCA_PF_CAMERA_GET_PRIVATE(self);
+ priv->construct_error = NULL;
priv->fg_port = PORT_A;
- priv->fg = Fg_Init(so_file, priv->fg_port);
-
- /* TODO: get this from the camera */
+ priv->fg = Fg_Init (so_file, priv->fg_port);
+ priv->fg_mem = NULL;
+ priv->last_frame = 0;
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;
- }
+ if (priv->fg != NULL) {
+ if (!try_fg_param (priv, FG_CAMERA_LINK_CAMTYP, (const gpointer) &link_type))
+ return;
- 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);
+ if (!try_fg_param (priv, FG_FORMAT, (const gpointer) &format))
+ return;
- return UCA_CAMERA (camera);
+ if (!try_fg_param (priv, FG_WIDTH, &priv->roi_width))
+ return;
+
+ if (!try_fg_param (priv, FG_HEIGHT, &priv->roi_height))
+ return;
+ }
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
+{
+ return UCA_TYPE_PF_CAMERA;
}
diff --git a/plugins/ufo/uca-ufo-camera.c b/plugins/ufo/uca-ufo-camera.c
index c4e05b0..145c2ee 100644
--- a/plugins/ufo/uca-ufo-camera.c
+++ b/plugins/ufo/uca-ufo-camera.c
@@ -15,6 +15,7 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+#include <gio/gio.h>
#include <gmodule.h>
#include <stdlib.h>
#include <stdio.h>
@@ -33,9 +34,22 @@
return; \
}
+#define PCILIB_SET_ERROR_RETURN_FALSE(err, err_type) \
+ if (err != 0) { \
+ g_set_error(error, UCA_UFO_CAMERA_ERROR, \
+ err_type, \
+ "%s:%i pcilib: %s (errcode = %d)", \
+ __FILE__, __LINE__, strerror(err), err);\
+ return FALSE; \
+ }
+
#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 void uca_ufo_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaUfoCamera, uca_ufo_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_ufo_camera_initable_iface_init))
static const guint SENSOR_WIDTH = 2048;
static const guint SENSOR_HEIGHT = 1088;
@@ -80,7 +94,6 @@ static gint base_overrideables[] = {
PROP_ROI_HEIGHT_MULTIPLIER,
PROP_HAS_STREAMING,
PROP_HAS_CAMRAM_RECORDING,
- PROP_TRIGGER_MODE,
0,
};
@@ -92,9 +105,11 @@ typedef struct _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 {
+ GError *construct_error;
+ GHashTable *property_table; /* maps from prop_id to RegisterInfo* */
+ GThread *async_thread;
pcilib_t *handle;
pcilib_timeout_t timeout;
guint n_bits;
@@ -102,7 +117,6 @@ struct _UcaUfoCameraPrivate {
FPGA_48MHZ = 0,
FPGA_40MHZ
} frequency;
- UcaCameraTrigger trigger;
};
static void
@@ -126,7 +140,8 @@ read_register_value (pcilib_t *handle, const gchar *name)
return (guint) reg_value;
}
-static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user)
+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);
@@ -134,47 +149,32 @@ static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info,
void *buffer = pcilib_get_data(priv->handle, event_id, PCILIB_EVENT_DATA, &error);
- if (buffer == NULL) {
- pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
+ if (buffer == 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);
+ camera->grab_func (buffer, camera->user_data);
+ pcilib_return_data (priv->handle, event_id, PCILIB_EVENT_DATA, buffer);
return PCILIB_STREAMING_CONTINUE;
}
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+static guint
+update_properties (UcaUfoCameraPrivate *priv)
{
- 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;
- }
+ guint prop;
+ pcilib_model_description_t *description;
- pcilib_set_error_handler(&error_handler, &error_handler);
+ prop = PROP_UFO_START;
+ description = pcilib_get_model_description (priv->handle);
- /* 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++) {
+ for (guint i = 0; 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];
+ reg = &description->registers[i];
switch (reg->mode) {
case PCILIB_REGISTER_R:
@@ -190,12 +190,12 @@ uca_camera_impl_new (GError **error)
break;
}
- pcilib_read_register (handle, NULL, reg->name, &value);
+ pcilib_read_register (priv->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);
+ g_hash_table_insert (priv->property_table, GINT_TO_POINTER (prop), reg_info);
prop_name = g_strdup_printf ("ufo-%s", reg->name);
ufo_properties[prop++] = g_param_spec_uint (
@@ -205,13 +205,32 @@ uca_camera_impl_new (GError **error)
g_free (prop_name);
}
- N_PROPERTIES = prop;
+ return prop;
+}
- UcaUfoCamera *camera = g_object_new(UCA_TYPE_UFO_CAMERA, NULL);
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+static gboolean
+setup_pcilib (UcaUfoCameraPrivate *priv)
+{
+ pcilib_model_t model;
+ guint adc_resolution;
+
+ model = PCILIB_MODEL_DETECT;
+ priv->handle = pcilib_open("/dev/fpga0", model);
- priv->frequency = read_register_value (handle, "bit_mode");
- adc_resolution = read_register_value (handle, "adc_resolution");
+ if (priv->handle == NULL) {
+ g_set_error (&priv->construct_error,
+ UCA_UFO_CAMERA_ERROR, UCA_UFO_CAMERA_ERROR_INIT,
+ "Initializing pcilib failed");
+ return FALSE;
+ }
+
+ pcilib_set_error_handler (&error_handler, &error_handler);
+
+ priv->property_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_free);
+ N_PROPERTIES = update_properties (priv);
+ priv->frequency = read_register_value (priv->handle, "bit_mode");
+ adc_resolution = read_register_value (priv->handle, "adc_resolution");
switch (adc_resolution) {
case 0:
@@ -225,59 +244,115 @@ uca_camera_impl_new (GError **error)
break;
}
- priv->handle = handle;
+ return TRUE;
+}
+
+static void
+set_control_bit (UcaUfoCameraPrivate *priv, guint bit, gboolean set)
+{
+ static const gchar *name = "control";
+ pcilib_register_value_t flags;
+ pcilib_register_value_t mask;
+
+ pcilib_read_register (priv->handle, NULL, name, &flags);
+ mask = 1 << bit;
+
+ if (set)
+ flags |= mask;
+ else
+ flags = flags & ~mask;
- return UCA_CAMERA (camera);
+ pcilib_write_register(priv->handle, NULL, name, flags);
}
-static void uca_ufo_camera_start_recording(UcaCamera *camera, GError **error)
+static void
+set_streaming (UcaUfoCameraPrivate *priv, gboolean enable)
+{
+ set_control_bit (priv, 11, enable);
+}
+
+static gpointer
+stream_async (UcaCamera *camera)
{
UcaUfoCameraPrivate *priv;
+ priv = UCA_UFO_CAMERA_GET_PRIVATE (camera);
+ pcilib_stream (priv->handle, &event_callback, camera);
+
+ return NULL;
+}
+
+static void
+uca_ufo_camera_start_recording(UcaCamera *camera, GError **error)
+{
+ UcaUfoCameraPrivate *priv;
+ UcaCameraTrigger trigger;
gdouble exposure_time;
- int err;
+ gboolean transfer_async;
+ int err;
g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+
+ g_object_get (G_OBJECT(camera),
+ "transfer-asynchronously", &transfer_async,
+ "exposure-time", &exposure_time,
+ "trigger-mode", &trigger,
+ NULL);
+
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,
- "trigger-mode", &priv->trigger,
- NULL);
+ if (trigger == UCA_CAMERA_TRIGGER_AUTO)
+ set_streaming (priv, TRUE);
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);
- }
+ if (transfer_async)
+ priv->async_thread = g_thread_create ((GThreadFunc) stream_async, camera, TRUE, error);
}
-static void uca_ufo_camera_stop_recording(UcaCamera *camera, GError **error)
+static void
+uca_ufo_camera_stop_recording(UcaCamera *camera, GError **error)
{
+ UcaUfoCameraPrivate *priv;
+ UcaCameraTrigger trigger;
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);
+
+ priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+
+ g_object_get (G_OBJECT (camera), "trigger-mode", &trigger, NULL);
+
+ if (priv->async_thread) {
+ int err = pcilib_stop(priv->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
+ PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_STOP_RECORDING);
+ g_thread_join(priv->async_thread);
+ priv->async_thread = NULL;
+ }
+
+ int err = pcilib_stop (priv->handle, PCILIB_EVENT_FLAGS_DEFAULT);
+ PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_STOP_RECORDING);
+
+ if (trigger == UCA_CAMERA_TRIGGER_AUTO)
+ set_streaming (priv, FALSE);
}
-static void uca_ufo_camera_start_readout(UcaCamera *camera, GError **error)
+static void
+uca_ufo_camera_start_readout(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
}
-static void uca_ufo_camera_stop_readout(UcaCamera *camera, GError **error)
+static void
+uca_ufo_camera_stop_readout(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
}
-static void uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static gboolean
+uca_ufo_camera_grab(UcaCamera *camera, gpointer data, GError **error)
{
- g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_UFO_CAMERA(camera), FALSE);
UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
pcilib_event_id_t event_id;
pcilib_event_info_t event_info;
@@ -285,21 +360,13 @@ static void uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **erro
const gsize size = SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16);
- if (priv->trigger != UCA_CAMERA_TRIGGER_EXTERNAL) {
- 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));
+ err = pcilib_get_next_event (priv->handle, priv->timeout, &event_id, sizeof(pcilib_event_info_t), &event_info);
+ PCILIB_SET_ERROR_RETURN_FALSE (err, UCA_UFO_CAMERA_ERROR_NEXT_EVENT);
- gpointer src = pcilib_get_data(priv->handle, event_id, PCILIB_EVENT_DATA, (size_t *) &err);
+ gpointer src = pcilib_get_data (priv->handle, event_id, PCILIB_EVENT_DATA, (size_t *) &err);
if (src == NULL)
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_NO_DATA);
+ PCILIB_SET_ERROR_RETURN_FALSE (err, UCA_UFO_CAMERA_ERROR_NO_DATA);
/*
* Apparently, we checked that err equals total size in previous version.
@@ -309,15 +376,29 @@ static void uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **erro
*/
/* assert(err == size); */
- memcpy(*data, src, 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);
+ err = pcilib_return_data (priv->handle, event_id, PCILIB_EVENT_DATA, data);
+ PCILIB_SET_ERROR_RETURN_FALSE (err, UCA_UFO_CAMERA_ERROR_MAYBE_CORRUPTED);
+
+ return TRUE;
+}
+
+static void
+uca_ufo_camera_trigger (UcaCamera *camera, GError **error)
+{
+ UcaUfoCameraPrivate *priv;
+ g_return_if_fail (UCA_IS_UFO_CAMERA(camera));
+
+ priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+
+ /* XXX: What is PCILIB_EVENT0? */
+ pcilib_trigger (priv->handle, PCILIB_EVENT0, 0, NULL);
}
static void
@@ -340,19 +421,18 @@ uca_ufo_camera_set_property(GObject *object, guint property_id, const GValue *va
g_debug("ROI feature not implemented yet");
break;
- case PROP_TRIGGER_MODE:
- priv->trigger = g_value_get_enum (value);
- break;
-
default:
{
- RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id));
+ RegisterInfo *reg_info;
+
+ reg_info = g_hash_table_lookup (priv->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_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;
}
@@ -441,12 +521,9 @@ uca_ufo_camera_get_property(GObject *object, guint property_id, GValue *value, G
case PROP_NAME:
g_value_set_string(value, "Ufo Camera w/ CMOSIS CMV2000");
break;
- case PROP_TRIGGER_MODE:
- g_value_set_enum (value, priv->trigger);
- break;
default:
{
- RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id));
+ RegisterInfo *reg_info = g_hash_table_lookup (priv->property_table, GINT_TO_POINTER (property_id));
if (reg_info != NULL)
g_value_set_uint (value, reg_info->cached_value);
@@ -457,14 +534,56 @@ uca_ufo_camera_get_property(GObject *object, guint property_id, GValue *value, G
}
}
-static void uca_ufo_camera_finalize(GObject *object)
+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);
+ UcaUfoCameraPrivate *priv;
+
+ priv = UCA_UFO_CAMERA_GET_PRIVATE (object);
+
+ pcilib_close (priv->handle);
+ g_clear_error (&priv->construct_error);
+
+ G_OBJECT_CLASS (uca_ufo_camera_parent_class)->finalize (object);
}
-static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
+static gboolean
+ufo_ufo_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ UcaUfoCamera *camera;
+ UcaUfoCameraPrivate *priv;
+
+ g_return_val_if_fail (UCA_IS_UFO_CAMERA (initable), FALSE);
+
+ if (cancellable != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ camera = UCA_UFO_CAMERA (initable);
+ priv = camera->priv;
+
+ if (priv->construct_error != NULL) {
+ if (error)
+ *error = g_error_copy (priv->construct_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+uca_ufo_camera_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = ufo_ufo_camera_initable_init;
+}
+
+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;
@@ -477,6 +596,7 @@ static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
camera_class->start_readout = uca_ufo_camera_start_readout;
camera_class->stop_readout = uca_ufo_camera_stop_readout;
camera_class->grab = uca_ufo_camera_grab;
+ camera_class->trigger = uca_ufo_camera_trigger;
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]]);
@@ -505,7 +625,26 @@ static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaUfoCameraPrivate));
}
-static void uca_ufo_camera_init(UcaUfoCamera *self)
+static void
+uca_ufo_camera_init(UcaUfoCamera *self)
+{
+ UcaCamera *camera;
+ UcaUfoCameraPrivate *priv;
+
+ self->priv = priv = UCA_UFO_CAMERA_GET_PRIVATE(self);
+ priv->construct_error = NULL;
+ priv->async_thread = NULL;
+
+ if (!setup_pcilib (priv))
+ return;
+
+ camera = UCA_CAMERA (self);
+ uca_camera_register_unit (camera, "sensor-temperature", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "fpga-temperature", UCA_UNIT_DEGREE_CELSIUS);
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
{
- self->priv = UCA_UFO_CAMERA_GET_PRIVATE(self);
+ return UCA_TYPE_UFO_CAMERA;
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fcacfa0..c3a037f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -85,6 +85,9 @@ if (INTROSPECTION_SCANNER AND INTROSPECTION_COMPILER)
list(APPEND _gir_input "${CMAKE_CURRENT_SOURCE_DIR}/${_src}")
endforeach()
+ list(APPEND _gir_input "${CMAKE_CURRENT_BINARY_DIR}/uca-enums.h")
+ list(APPEND _gir_input "${CMAKE_CURRENT_BINARY_DIR}/uca-enums.c")
+
add_custom_command(OUTPUT ${GIR_XML}
COMMAND ${INTROSPECTION_SCANNER}
--namespace=Uca
@@ -199,7 +202,7 @@ install(TARGETS uca
COMPONENT libraries)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libuca.pc
- DESTINATION lib/pkgconfig
+ DESTINATION ${LIB_INSTALL_DIR}/pkgconfig
COMPONENT libraries)
install(FILES ${uca_HDRS}
diff --git a/src/libuca.pc.in b/src/libuca.pc.in
index 6401368..3ca4dbe 100644
--- a/src/libuca.pc.in
+++ b/src/libuca.pc.in
@@ -11,3 +11,4 @@ Description: @UCA_DESCRIPTION@
Version: @VERSION@
Libs: -L${libdir} -luca
Cflags: -I${includedir_old} -I${includedir_new}
+Requires: glib-2.0 gobject-2.0
diff --git a/src/scangobj.sh.in b/src/scangobj.sh.in
index 65766b6..088d67e 100644
--- a/src/scangobj.sh.in
+++ b/src/scangobj.sh.in
@@ -1 +1 @@
-LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}:/opt/pylon/lib64:/opt/pylon/genicam/bin/Linux64_x64 CC=gcc CFLAGS="${GTK_DOC_CFLAGS}" LDFLAGS="${GTK_DOC_LDFLAGS} -L${CMAKE_CURRENT_BINARY_DIR} -L${CMAKE_CURRENT_BINARY_DIR} -luca `pkg-config --libs gtk+-2.0`" gtkdoc-scangobj --module=uca
+LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}:/opt/pylon/lib64:/opt/pylon/genicam/bin/Linux64_x64 CC=gcc CFLAGS="${GTK_DOC_CFLAGS}" LDFLAGS="${GTK_DOC_LDFLAGS} -L${CMAKE_CURRENT_BINARY_DIR} -luca `pkg-config --libs gtk+-2.0`" gtkdoc-scangobj --module=uca
diff --git a/src/uca-camera.c b/src/uca-camera.c
index 8905a95..5073a57 100644
--- a/src/uca-camera.c
+++ b/src/uca-camera.c
@@ -116,6 +116,7 @@ struct _UcaCameraPrivate {
gboolean is_recording;
gboolean is_readout;
gboolean transfer_async;
+ UcaCameraTrigger trigger;
};
static void
@@ -148,6 +149,10 @@ uca_camera_set_property (GObject *object, guint property_id, const GValue *value
}
break;
+ case PROP_TRIGGER_MODE:
+ priv->trigger = g_value_get_enum (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
@@ -172,7 +177,7 @@ uca_camera_get_property(GObject *object, guint property_id, GValue *value, GPara
break;
case PROP_TRIGGER_MODE:
- g_value_set_enum (value, UCA_CAMERA_TRIGGER_AUTO);
+ g_value_set_enum (value, priv->trigger);
break;
case PROP_FRAMES_PER_SECOND:
@@ -403,6 +408,7 @@ uca_camera_init (UcaCamera *camera)
camera->priv->is_recording = FALSE;
camera->priv->is_readout = FALSE;
camera->priv->transfer_async = FALSE;
+ camera->priv->trigger = UCA_CAMERA_TRIGGER_AUTO;
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);
@@ -669,34 +675,31 @@ uca_camera_trigger (UcaCamera *camera, GError **error)
/**
* uca_camera_grab:
* @camera: A #UcaCamera object
- * @data: Pointer to pointer to the data. Must not be %NULL.
+ * @data: (type gulong): Pointer to suitably sized data buffer. Must not be
+ * %NULL.
* @error: Location to store a #UcaCameraError error or %NULL
*
- * Grab a frame a single frame and store the result in @data. If the pointer
- * pointing to the data is %NULL, memory will be allocated otherwise it will be
- * used to store the frame. If memory is allocated by uca_camera_grab() it must
- * be freed by the caller.
+ * Grab a frame a single frame and store the result in @data.
*
* 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)
+gboolean
+uca_camera_grab (UcaCamera *camera, gpointer data, GError **error)
{
UcaCameraClass *klass;
+ gboolean result;
+
+ /* FIXME: this prevents accessing two independent cameras simultanously. */
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
- g_return_if_fail (UCA_IS_CAMERA(camera));
+ g_return_val_if_fail (UCA_IS_CAMERA(camera), FALSE);
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_return_val_if_fail (klass != NULL, FALSE);
+ g_return_val_if_fail (klass->grab != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
g_static_mutex_lock (&mutex);
@@ -704,11 +707,12 @@ uca_camera_grab (UcaCamera *camera, gpointer *data, GError **error)
g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, "Camera is neither recording nor in readout mode");
else {
g_static_mutex_lock (&access_lock);
- (*klass->grab) (camera, data, error);
+ result = (*klass->grab) (camera, data, error);
g_static_mutex_unlock (&access_lock);
}
g_static_mutex_unlock (&mutex);
+ return result;
}
/**
diff --git a/src/uca-camera.h b/src/uca-camera.h
index 87996c6..f6fdace 100644
--- a/src/uca-camera.h
+++ b/src/uca-camera.h
@@ -129,7 +129,7 @@ struct _UcaCameraClass {
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);
+ gboolean (*grab) (UcaCamera *camera, gpointer data, GError **error);
void (*recording_started) (UcaCamera *camera);
void (*recording_stopped) (UcaCamera *camera);
@@ -147,9 +147,10 @@ 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);
+gboolean uca_camera_grab (UcaCamera *camera,
+ gpointer data,
+ GError **error)
+ __attribute__((nonnull (2)));
void uca_camera_set_grab_func (UcaCamera *camera,
UcaCameraGrabFunc func,
gpointer user_data);
diff --git a/src/uca-plugin-manager.c b/src/uca-plugin-manager.c
index e99f478..5013981 100644
--- a/src/uca-plugin-manager.c
+++ b/src/uca-plugin-manager.c
@@ -32,6 +32,7 @@
*
* @Since: 1.1
*/
+#include <gio/gio.h>
#include <gmodule.h>
#include "uca-plugin-manager.h"
@@ -45,7 +46,7 @@ struct _UcaPluginManagerPrivate {
static const gchar *MODULE_PATTERN = "libuca([A-Za-z]+)";
-typedef UcaCamera * (*GetCameraFunc) (GError **error);
+typedef GType (*GetTypeFunc) (void);
/**
* UcaPluginManagerError:
@@ -208,39 +209,22 @@ find_camera_module_path (GList *search_paths, const gchar *name)
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)
+static GType
+get_camera_type (UcaPluginManagerPrivate *priv,
+ const gchar *name,
+ GError **error)
{
- UcaPluginManagerPrivate *priv;
- UcaCamera *camera;
GModule *module;
- GetCameraFunc *func;
gchar *module_path;
- GError *tmp_error = NULL;
+ GetTypeFunc *func;
+ const gchar *symbol_name = "uca_camera_get_type";
- 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;
+ "Camera module `%s' not found", name);
+ return G_TYPE_NONE;
}
module = g_module_open (module_path, G_MODULE_BIND_LAZY);
@@ -249,10 +233,10 @@ uca_plugin_manager_get_camera (UcaPluginManager *manager,
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;
+ return G_TYPE_NONE;
}
- func = g_malloc0 (sizeof (GetCameraFunc));
+ func = g_malloc0 (sizeof (GetTypeFunc));
if (!g_module_symbol (module, symbol_name, (gpointer *) func)) {
g_set_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_SYMBOL_NOT_FOUND,
@@ -262,15 +246,90 @@ uca_plugin_manager_get_camera (UcaPluginManager *manager,
if (!g_module_close (module))
g_warning ("%s", g_module_error ());
- return NULL;
+ return G_TYPE_NONE;
}
- camera = (*func) (&tmp_error);
+ return (*func) ();
+}
- if (tmp_error != NULL) {
- g_propagate_error (error, tmp_error);
+/**
+ * uca_plugin_manager_get_camerav:
+ * @manager: A #UcaPluginManager
+ * @name: Name of the camera module, that maps to libuca<name>.so
+ * @n_parameters: number of parameters in @parameters
+ * @parameters: (array length=n_parameters): the parameters to use to construct
+ * the camera
+ * @error: Location for a #GError or %NULL
+ *
+ * Create a new camera instance with camera @name.
+ *
+ * Returns: (transfer full): A new #UcaCamera object.
+ * @Since: 1.2
+ */
+UcaCamera *
+uca_plugin_manager_get_camerav (UcaPluginManager *manager,
+ const gchar *name,
+ guint n_parameters,
+ GParameter *parameters,
+ GError **error)
+{
+ UcaPluginManagerPrivate *priv;
+ UcaCamera *camera;
+ GType type;
+
+ g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager) && (name != NULL), NULL);
+
+ priv = manager->priv;
+ type = get_camera_type (priv, name, error);
+
+ if (type == G_TYPE_NONE)
return NULL;
- }
+
+ camera = (UcaCamera *) g_initable_newv (type, n_parameters, parameters,
+ NULL, error);
+
+ return camera;
+}
+
+/**
+ * uca_plugin_manager_get_camera: (skip)
+ * @manager: A #UcaPluginManager
+ * @name: Name of the camera module, that maps to libuca<name>.so
+ * @error: Location for a #GError
+ * @first_prop_name: (allow-none): name of the first property, or %NULL if no
+ * properties
+ * @...: value of the first property, followed by and other property value
+ * pairs, and ended by %NULL.
+ *
+ * Create a new camera instance with camera @name.
+ *
+ * Returns: (transfer full): A new #UcaCamera object.
+ * @Since: 1.2: Pass construction properties.
+ */
+UcaCamera *
+uca_plugin_manager_get_camera (UcaPluginManager *manager,
+ const gchar *name,
+ GError **error,
+ const gchar *first_prop_name,
+ ...)
+{
+ UcaPluginManagerPrivate *priv;
+ UcaCamera *camera;
+ GType type;
+ va_list var_args;
+
+ g_return_val_if_fail (UCA_IS_PLUGIN_MANAGER (manager) && (name != NULL), NULL);
+
+ priv = manager->priv;
+ type = get_camera_type (priv, name, error);
+
+ if (type == G_TYPE_NONE)
+ return NULL;
+
+ va_start (var_args, first_prop_name);
+ camera = (UcaCamera *) g_initable_new (type, NULL, error,
+ first_prop_name, var_args);
+ va_end (var_args);
return camera;
}
diff --git a/src/uca-plugin-manager.h b/src/uca-plugin-manager.h
index 6c3ab4e..10fe9d1 100644
--- a/src/uca-plugin-manager.h
+++ b/src/uca-plugin-manager.h
@@ -55,9 +55,16 @@ 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,
+UcaCamera *uca_plugin_manager_get_camerav (UcaPluginManager *manager,
const gchar *name,
+ guint n_parameters,
+ GParameter *parameters,
GError **error);
+UcaCamera *uca_plugin_manager_get_camera (UcaPluginManager *manager,
+ const gchar *name,
+ GError **error,
+ const gchar *first_prop_name,
+ ...);
GType uca_plugin_manager_get_type (void);
G_END_DECLS
diff --git a/src/uca.types.in b/src/uca.types.in
index 7526948..76acc2b 100644
--- a/src/uca.types.in
+++ b/src/uca.types.in
@@ -1,2 +1,5 @@
uca_camera_get_type
+uca_camera_error_get_type
+uca_camera_trigger_get_type
uca_plugin_manager_get_type
+uca_unit_get_type
diff --git a/test/test-mock.c b/test/test-mock.c
index 85c1ba4..7876f5b 100644
--- a/test/test-mock.c
+++ b/test/test-mock.c
@@ -8,15 +8,31 @@ typedef struct {
UcaCamera *camera;
} Fixture;
+static gchar *
+build_mock_plugin_path (void)
+{
+ gchar *cwd;
+ gchar *plugin_path;
+
+ cwd = g_get_current_dir ();
+ plugin_path = g_build_filename (cwd, "plugins", "mock", NULL);
+ g_free (cwd);
+ return plugin_path;
+}
+
static void
fixture_setup (Fixture *fixture, gconstpointer data)
{
+ gchar *plugin_path;
GError *error = NULL;
- fixture->manager = uca_plugin_manager_new ();
- uca_plugin_manager_add_path (fixture->manager, "./src");
+ plugin_path = build_mock_plugin_path ();
+ g_setenv ("UCA_CAMERA_PATH", plugin_path, TRUE);
+ g_free (plugin_path);
- fixture->camera = uca_plugin_manager_get_camera (fixture->manager, "mock", &error);
+ fixture->manager = uca_plugin_manager_new ();
+ fixture->camera = uca_plugin_manager_get_camera (fixture->manager,
+ "mock", &error, NULL);
g_assert (error == NULL);
g_assert (fixture->camera);
}
@@ -39,7 +55,8 @@ static void
test_factory (Fixture *fixture, gconstpointer data)
{
GError *error = NULL;
- UcaCamera *camera = uca_plugin_manager_get_camera (fixture->manager, "fox994m3a0yxmy", &error);
+ UcaCamera *camera = uca_plugin_manager_get_camera (fixture->manager,
+ "fox994m3a0yxmy", &error, NULL);
g_assert_error (error, UCA_PLUGIN_MANAGER_ERROR, UCA_PLUGIN_MANAGER_ERROR_MODULE_NOT_FOUND);
g_assert (camera == NULL);
}
diff --git a/tools/benchmark.c b/tools/benchmark.c
index bff8b50..0939d78 100644
--- a/tools/benchmark.c
+++ b/tools/benchmark.c
@@ -100,7 +100,8 @@ grab_frames_sync (UcaCamera *camera, gpointer buffer, guint n_frames)
uca_camera_start_recording (camera, &error);
for (guint i = 0; i < n_frames; i++) {
- uca_camera_grab(camera, &buffer, &error);
+ if (!uca_camera_grab (camera, buffer, &error))
+ g_warning ("Data stream ended");
if (error != NULL) {
g_warning ("Error grabbing frame %02i/%i: `%s'", i, n_frames, error->message);
@@ -115,8 +116,12 @@ grab_frames_sync (UcaCamera *camera, gpointer buffer, guint n_frames)
static void
grab_callback (gpointer data, gpointer user_data)
{
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
guint *n_acquired_frames = user_data;
+
+ g_static_mutex_lock (&mutex);
*n_acquired_frames += 1;
+ g_static_mutex_unlock (&mutex);
}
static void
@@ -136,7 +141,6 @@ grab_frames_async (UcaCamera *camera, gpointer buffer, guint n_frames)
;
uca_camera_stop_recording (camera, &error);
-
}
static void
@@ -204,6 +208,7 @@ benchmark (UcaCamera *camera)
g_print ("# Sensor size: %ix%i\n", sensor_width, sensor_height);
g_print ("# ROI size: %ix%i\n", roi_width, roi_height);
g_print ("# Exposure time: %fs\n", exposure);
+ g_print ("# Bits: %i\n", bits);
/* Synchronous frame acquisition */
g_print ("# %-10s%-10s%-10s%-16s%-16s\n", "type", "n_frames", "n_runs", "frames/s", "MiB/s");
@@ -250,7 +255,7 @@ main (int argc, char *argv[])
g_log_set_handler (NULL, G_LOG_LEVEL_MASK, log_handler, log_channel);
manager = uca_plugin_manager_new ();
- camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+ camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
if (camera == NULL) {
g_error ("Initialization: %s", error->message);
diff --git a/tools/gen-doc.c b/tools/gen-doc.c
index f555a5f..d27bdd8 100644
--- a/tools/gen-doc.c
+++ b/tools/gen-doc.c
@@ -67,9 +67,9 @@ print_property_toc (GParamSpec **pspecs, guint n_props)
g_print ("<h2>Properties</h2><ul id=\"toc\">");
for (guint i = 0; i < n_props; i++) {
- GParamSpec *pspec = pspecs[i];
+ GParamSpec *pspec = pspecs[i];
const gchar *name = g_param_spec_get_name (pspec);
-
+
g_print ("<li><code><a href=#%s>\"%s\"</a></code></li>", name, name);
}
@@ -77,21 +77,90 @@ print_property_toc (GParamSpec **pspecs, guint n_props)
}
static void
+print_value_info (GParamSpec *pspec)
+{
+ gchar *default_value = NULL;
+ GString *range = g_string_new("");
+
+#define MAKE_RANGE(spec_type, fmt) \
+ { \
+ spec_type *spec = (spec_type *) pspec; \
+ g_string_printf (range, \
+ fmt" &#8804; <em>%s</em> &#8804; "fmt, \
+ spec->minimum, \
+ g_param_spec_get_name (pspec), \
+ spec->maximum); \
+ default_value = g_strdup_printf (fmt, spec->default_value); \
+ }
+
+ switch (pspec->value_type) {
+ case G_TYPE_BOOLEAN:
+ {
+ GParamSpecBoolean *spec = (GParamSpecBoolean *) pspec;
+ default_value = spec->default_value ? g_strdup ("<code>TRUE</code>") : g_strdup ("<code>FALSE</code>");
+ }
+ break;
+
+ case G_TYPE_UINT:
+ MAKE_RANGE (GParamSpecUInt, "%i");
+ break;
+
+ case G_TYPE_FLOAT:
+ MAKE_RANGE (GParamSpecFloat, "%.1e");
+ break;
+
+ case G_TYPE_DOUBLE:
+ MAKE_RANGE (GParamSpecDouble, "%.1e");
+ break;
+ }
+
+#undef MAKE_RANGE
+
+ if (g_type_is_a (pspec->value_type, G_TYPE_ENUM)) {
+ GParamSpecEnum *spec = (GParamSpecEnum *) pspec;
+
+ if (spec->enum_class->n_values > 0) {
+ g_string_printf (range, "<table><tr><th>Enum name</th><th>Value</th>");
+
+ for (guint i = 0; i < spec->enum_class->n_values; i++) {
+ GEnumValue *v = &spec->enum_class->values[i];
+ g_string_append_printf (range,
+ "<tr><td><code>%s</code></td><td>%i</td></tr>",
+ v->value_name, v->value);
+ }
+
+ g_string_append_printf (range, "</table>");
+ }
+ }
+
+ if (range->len > 0)
+ g_print ("<p>Possible values: %s</p>", range->str);
+
+ if (default_value != NULL) {
+ g_print ("<p>Default value: %s</p>", default_value);
+ g_free (default_value);
+ }
+
+ g_string_free (range, TRUE);
+}
+
+static void
print_property_descriptions (GParamSpec **pspecs, guint n_props)
{
g_print ("<h2>Details</h2><dl>");
for (guint i = 0; i < n_props; i++) {
- GParamSpec *pspec = pspecs[i];
+ GParamSpec *pspec = pspecs[i];
const gchar *name = g_param_spec_get_name (pspec);
g_print ("<dt id=\"%s\"><a href=\"#toc\">%s</a></dt>\n", name, name);
g_print ("<dd>");
- g_print ("<pre><code class=\"prop-type\">\"%s\" : %s : %s</code></pre>\n",
- name,
+ g_print ("<pre><code class=\"prop-type\">\"%s\" : %s : %s</code></pre>\n",
+ name,
g_type_name (pspec->value_type),
get_flags_description (pspec));
g_print ("<p>%s</p>\n", g_param_spec_get_blurb (pspec));
+ print_value_info (pspec);
g_print ("</dd>");
}
@@ -104,7 +173,7 @@ print_properties (UcaCamera *camera)
GObjectClass *oclass;
GParamSpec **pspecs;
guint n_props;
-
+
oclass = G_OBJECT_GET_CLASS (camera);
pspecs = g_object_class_list_properties (oclass, &n_props);
@@ -136,7 +205,7 @@ int main(int argc, char *argv[])
}
else {
name = argv[1];
- camera = uca_plugin_manager_get_camera (manager, name, &error);
+ camera = uca_plugin_manager_get_camera (manager, name, &error, NULL);
}
if (camera == NULL) {
diff --git a/tools/grab-async.c b/tools/grab-async.c
index 2c4bf04..00f2879 100644
--- a/tools/grab-async.c
+++ b/tools/grab-async.c
@@ -94,7 +94,7 @@ main(int argc, char *argv[])
}
manager = uca_plugin_manager_new ();
- camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+ camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
if (camera == NULL) {
g_print("Error during initialization: %s\n", error->message);
diff --git a/tools/grab.c b/tools/grab.c
index 1518997..e8e91be 100644
--- a/tools/grab.c
+++ b/tools/grab.c
@@ -75,7 +75,7 @@ int main(int argc, char *argv[])
}
manager = uca_plugin_manager_new ();
- camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+ camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
if (camera == NULL) {
g_print("Error during initialization: %s\n", error->message);
@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
while (counter < 5) {
g_print(" grab frame ... ");
g_timer_start(timer);
- uca_camera_grab(camera, &buffer, &error);
+ uca_camera_grab(camera, buffer, &error);
if (error != NULL) {
g_print("\nError: %s\n", error->message);
diff --git a/tools/gui/control.c b/tools/gui/control.c
index f74e0f1..c177f07 100644
--- a/tools/gui/control.c
+++ b/tools/gui/control.c
@@ -135,6 +135,8 @@ update_pixbuf_dimensions (ThreadData *data)
if (data->pixbuf != NULL)
g_object_unref (data->pixbuf);
+ data->display_width = (gint) data->width * data->zoom_factor;
+ data->display_height = (gint) data->height * data->zoom_factor;
data->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, data->display_width, data->display_height);
data->pixels = gdk_pixbuf_get_pixels (data->pixbuf);
gtk_image_set_from_pixbuf (GTK_IMAGE (data->image), data->pixbuf);
@@ -159,7 +161,8 @@ preview_frames (void *args)
gpointer buffer;
buffer = ring_buffer_get_current_pointer (data->buffer);
- uca_camera_grab (data->camera, &buffer, &error);
+ uca_camera_trigger (data->camera, &error);
+ uca_camera_grab (data->camera, buffer, &error);
if (error == NULL) {
convert_grayscale_to_rgb (data, buffer);
@@ -189,7 +192,7 @@ record_frames (gpointer args)
while (data->state == RECORDING) {
buffer = ring_buffer_get_current_pointer (data->buffer);
- uca_camera_grab (data->camera, &buffer, NULL);
+ uca_camera_grab (data->camera, buffer, NULL);
if (error == NULL) {
ring_buffer_proceed (data->buffer);
@@ -343,7 +346,7 @@ download_frames (ThreadData *data)
while (error == NULL) {
buffer = ring_buffer_get_current_pointer (data->buffer);
- uca_camera_grab (data->camera, &buffer, &error);
+ uca_camera_grab (data->camera, buffer, &error);
ring_buffer_proceed (data->buffer);
gdk_threads_enter ();
gtk_adjustment_set_value (data->download_adjustment, current_frame++);
@@ -415,13 +418,25 @@ on_zoom_changed (GtkComboBox *widget, ThreadData *data)
gtk_combo_box_get_active_iter (widget, &iter);
gtk_tree_model_get (model, &iter, FACTOR_COLUMN, &factor, -1);
- data->display_width = (gint) data->width * factor;
- data->display_height = (gint) data->height * factor;
data->zoom_factor = factor;
update_pixbuf_dimensions (data);
}
static void
+on_roi_width_changed (GObject *object, GParamSpec *pspec, ThreadData *data)
+{
+ g_object_get (object, "roi-width", &data->width, NULL);
+ update_pixbuf_dimensions (data);
+}
+
+static void
+on_roi_height_changed (GObject *object, GParamSpec *pspec, ThreadData *data)
+{
+ g_object_get (object, "roi-height", &data->height, NULL);
+ update_pixbuf_dimensions (data);
+}
+
+static void
create_main_window (GtkBuilder *builder, const gchar* camera_name)
{
static ThreadData td;
@@ -442,7 +457,7 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
guint width, height;
GError *error = NULL;
- camera = uca_plugin_manager_get_camera (plugin_manager, camera_name, &error);
+ camera = uca_plugin_manager_get_camera (plugin_manager, camera_name, &error, NULL);
if ((camera == NULL) || (error != NULL)) {
g_error ("%s\n", error->message);
@@ -455,6 +470,9 @@ create_main_window (GtkBuilder *builder, const gchar* camera_name)
"sensor-bitdepth", &bits_per_sample,
NULL);
+ g_signal_connect (camera, "notify::roi-width", (GCallback) on_roi_width_changed, &td);
+ g_signal_connect (camera, "notify::roi-height", (GCallback) on_roi_height_changed, &td);
+
histogram_view = egg_histogram_view_new ();
property_tree_view = egg_property_tree_view_new (G_OBJECT (camera));
property_window = GTK_CONTAINER (gtk_builder_get_object (builder, "property-window"));
diff --git a/tools/perf-overhead.c b/tools/perf-overhead.c
index 6735e6f..7661dbc 100644
--- a/tools/perf-overhead.c
+++ b/tools/perf-overhead.c
@@ -163,7 +163,7 @@ main (int argc, char *argv[])
}
manager = uca_plugin_manager_new ();
- camera = uca_plugin_manager_get_camera (manager, argv[1], &error);
+ camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL);
if (camera == NULL) {
g_print ("Error during initialization: %s\n", error->message);