diff options
| -rw-r--r-- | .bzrignore | 1 | ||||
| -rw-r--r-- | .gitignore | 16 | ||||
| -rw-r--r-- | CMakeLists.txt | 12 | ||||
| -rw-r--r-- | NEWS | 17 | ||||
| -rw-r--r-- | docs/manual.md | 46 | ||||
| -rw-r--r-- | docs/mock.html | 49 | ||||
| -rw-r--r-- | docs/style.css | 7 | ||||
| -rw-r--r-- | misc/README.rst | 29 | ||||
| -rw-r--r-- | misc/opencv-2.2.0.patch | 374 | ||||
| -rw-r--r-- | plugins/mock/uca-mock-camera.c | 93 | ||||
| -rw-r--r-- | plugins/mock/uca-mock-camera.h | 2 | ||||
| -rw-r--r-- | plugins/pco/uca-pco-camera.c | 314 | ||||
| -rw-r--r-- | plugins/pco/uca-pco-camera.h | 4 | ||||
| -rw-r--r-- | plugins/pf/uca-pf-camera.c | 178 | ||||
| -rw-r--r-- | plugins/ufo/uca-ufo-camera.c | 323 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | src/libuca.pc.in | 1 | ||||
| -rw-r--r-- | src/scangobj.sh.in | 2 | ||||
| -rw-r--r-- | src/uca-camera.c | 38 | ||||
| -rw-r--r-- | src/uca-camera.h | 9 | ||||
| -rw-r--r-- | src/uca-plugin-manager.c | 125 | ||||
| -rw-r--r-- | src/uca-plugin-manager.h | 9 | ||||
| -rw-r--r-- | src/uca.types.in | 3 | ||||
| -rw-r--r-- | test/test-mock.c | 25 | ||||
| -rw-r--r-- | tools/benchmark.c | 11 | ||||
| -rw-r--r-- | tools/gen-doc.c | 83 | ||||
| -rw-r--r-- | tools/grab-async.c | 2 | ||||
| -rw-r--r-- | tools/grab.c | 4 | ||||
| -rw-r--r-- | tools/gui/control.c | 30 | ||||
| -rw-r--r-- | tools/perf-overhead.c | 2 | 
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 @@ -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) @@ -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 — 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 — 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 ≤ <em>sensor-width</em> ≤ -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 ≤ <em>sensor-height</em> ≤ -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 ≤ <em>sensor-bitdepth</em> ≤ 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 ≤ <em>sensor-horizontal-binning</em> ≤ -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 ≤ <em>sensor-vertical-binning</em> ≤ -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 ≤ <em>sensor-max-frame-rate</em> ≤ 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 ≤ <em>exposure-time</em> ≤ 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 ≤ <em>frames-per-second</em> ≤ 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 ≤ <em>roi-x0</em> ≤ -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 ≤ <em>roi-y0</em> ≤ -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 ≤ <em>roi-width</em> ≤ -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 ≤ <em>roi-height</em> ≤ -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 ≤ <em>roi-width-multiplier</em> ≤ -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 ≤ <em>roi-height-multiplier</em> ≤ -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 ≤ <em>recorded-frames</em> ≤ -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, ®_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" ≤ <em>%s</em> ≤ "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);  | 
