summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Vogelgesang <matthias.vogelgesang@gmail.com>2012-06-20 13:45:10 +0200
committerMatthias Vogelgesang <matthias.vogelgesang@gmail.com>2012-06-20 13:58:03 +0200
commitfc49419b57283919654680d4ee2bc0b4a4537e3e (patch)
tree0a1d7c0a164152b33f7e0277b4347a362fc547fb
parent4d07f8c3e9a99242bfbd373722731025235d1968 (diff)
downloaduca-fc49419b57283919654680d4ee2bc0b4a4537e3e.tar.gz
uca-fc49419b57283919654680d4ee2bc0b4a4537e3e.tar.bz2
uca-fc49419b57283919654680d4ee2bc0b4a4537e3e.tar.xz
uca-fc49419b57283919654680d4ee2bc0b4a4537e3e.zip
Re-implement asynchronous data acquisition
-rw-r--r--src/cameras/uca-pco-camera.c47
-rw-r--r--test/CMakeLists.txt5
-rw-r--r--test/grab-async.c116
-rw-r--r--test/grab.c10
4 files changed, 125 insertions, 53 deletions
diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c
index 871be73..821e2c3 100644
--- a/src/cameras/uca-pco-camera.c
+++ b/src/cameras/uca-pco-camera.c
@@ -158,6 +158,7 @@ struct _UcaPcoCameraPrivate {
guint frame_width;
guint frame_height;
gsize num_bytes;
+ guint16 *grab_buffer;
guint16 width, height;
guint16 width_ex, height_ex;
@@ -392,6 +393,43 @@ UcaPcoCamera *uca_pco_camera_new(GError **error)
return camera;
}
+static int fg_callback(frameindex_t frame, struct fg_apc_data *apc)
+{
+ UcaCamera *camera = UCA_CAMERA(apc);
+ UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
+ gpointer data = Fg_getImagePtrEx(priv->fg, frame, priv->fg_port, priv->fg_mem);
+
+ if (priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE) {
+ pco_get_reorder_func(priv->pco)(priv->grab_buffer, data, priv->frame_width, priv->frame_height);
+ camera->grab_func(priv->grab_buffer, camera->user_data);
+ }
+ else {
+ camera->grab_func(data, camera->user_data);
+ }
+
+ return 0;
+}
+
+static gboolean setup_fg_callback(UcaCamera *camera)
+{
+ UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
+ struct FgApcControl ctrl;
+
+ /* Jeez, as if a NULL pointer would not be good enough. */
+ ctrl.data = (struct fg_apc_data *) camera;
+ ctrl.version = 0;
+ ctrl.func = &fg_callback;
+ ctrl.flags = FG_APC_DEFAULTS;
+ ctrl.timeout = 1;
+
+ if (priv->grab_buffer)
+ g_free(priv->grab_buffer);
+
+ priv->grab_buffer = g_malloc0(priv->frame_width * priv->frame_height * sizeof(guint16));
+
+ return Fg_registerApcHandler(priv->fg, priv->fg_port, &ctrl, FG_APC_CONTROL_BASIC) == FG_OK;
+}
+
static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
@@ -400,6 +438,7 @@ static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
guint16 binned_width, binned_height;
gboolean use_extended = FALSE;
+ gboolean transfer_async = FALSE;
g_object_get (camera, "sensor-extended", &use_extended, NULL);
@@ -428,6 +467,8 @@ static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
guint16 roi[4] = { priv->roi_x + 1, priv->roi_y + 1, priv->roi_x + priv->roi_width, priv->roi_y + priv->roi_height };
pco_set_roi(priv->pco, roi);
+ g_object_get(G_OBJECT(camera), "transfer-asynchronously", &transfer_async, NULL);
+
/*
* FIXME: We cannot set the binning here as this breaks communication with
* the camera. Setting the binning works _before_ initializing the frame
@@ -461,6 +502,9 @@ static void 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))
pco_clear_active_segment(priv->pco);
@@ -1082,6 +1126,8 @@ static void uca_pco_camera_finalize(GObject *object)
if (priv->pco)
pco_destroy(priv->pco);
+ g_free(priv->grab_buffer);
+
G_OBJECT_CLASS(uca_pco_camera_parent_class)->finalize(object);
}
@@ -1254,6 +1300,7 @@ static void uca_pco_camera_init(UcaPcoCamera *self)
self->priv->pixelrates = NULL;
self->priv->camera_description = NULL;
self->priv->last_frame = 0;
+ self->priv->grab_buffer = NULL;
self->priv->delay_timebase = TIMEBASE_INVALID;
self->priv->exposure_timebase = TIMEBASE_INVALID;
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8de0058..428a56a 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -17,11 +17,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/run.py ${CMAKE_CURRENT_BINARY_DIR})
# --- Build targets -----------------------------------------------------------
#add_executable(enum enum.c)
-#add_executable(grab-async grab-async.c)
#add_executable(benchmark benchmark.c)
#target_link_libraries(enum uca)
-#target_link_libraries(grab-async uca)
#target_link_libraries(benchmark uca)
include_directories(
@@ -31,7 +29,10 @@ include_directories(
)
add_executable(grab grab.c)
+add_executable(grab-async grab-async.c)
+
target_link_libraries(grab uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES})
+target_link_libraries(grab-async uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES})
if (GTK2_FOUND)
include_directories(${GTK2_INCLUDE_DIRS})
diff --git a/test/grab-async.c b/test/grab-async.c
index 53cf9ad..e1ec114 100644
--- a/test/grab-async.c
+++ b/test/grab-async.c
@@ -15,66 +15,88 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+#include <glib-object.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h>
-#include "uca.h"
+#include "uca-camera.h"
-struct image_props {
- uint32_t width;
- uint32_t height;
- uint32_t bits;
-};
+static UcaCamera *camera = NULL;
-uca_buffer_status grab_callback(uint64_t image_number, void *buffer, void *meta_data, void *user)
+typedef struct {
+ guint roi_width;
+ guint roi_height;
+ guint counter;
+} CallbackData;
+
+static void sigint_handler(int signal)
{
- struct image_props *props = (struct image_props *) user;
- const int pixel_size = props->bits == 8 ? 1 : 2;
- char filename[256];
+ printf("Closing down libuca\n");
+ uca_camera_stop_recording(camera, NULL);
+ g_object_unref(camera);
+ exit(signal);
+}
- sprintf(filename, "out-%04i.raw", (int) image_number);
+static void grab_callback(gpointer data, gpointer user_data)
+{
+ CallbackData *cbd = (CallbackData *) user_data;
+ gchar *filename = g_strdup_printf("frame-%04i.raw", cbd->counter++);
FILE *fp = fopen(filename, "wb");
- fwrite(buffer, props->width * props->height, pixel_size, fp);
- fclose(fp);
- printf("grabbed picture %i at %p (%ix%i @ %i bits)\n",
- (int) image_number, buffer,
- props->width, props->height, props->bits);
-
- return UCA_BUFFER_RELEASE;
+ fwrite(data, sizeof(guint16), cbd->roi_width * cbd->roi_height, fp);
+ g_print(".");
+ fclose(fp);
+ g_free(filename);
}
int main(int argc, char *argv[])
{
- uca *u = uca_init(NULL);
- if (u == NULL) {
- printf("Couldn't find a camera\n");
- return 1;
- }
-
- /* take first camera */
- uca_camera *cam = u->cameras;
-
- uint32_t val = 5000;
- uca_cam_set_property(cam, UCA_PROP_EXPOSURE, &val);
- val = 0;
- uca_cam_set_property(cam, UCA_PROP_DELAY, &val);
+ CallbackData cbd;
+ guint sensor_width, sensor_height;
+ gchar *name;
+ GError *error = NULL;
+ (void) signal(SIGINT, sigint_handler);
- struct image_props props;
- uca_cam_get_property(cam, UCA_PROP_WIDTH, &props.width, 0);
- uca_cam_get_property(cam, UCA_PROP_HEIGHT, &props.height, 0);
- uca_cam_get_property(cam, UCA_PROP_BITDEPTH, &props.bits, 0);
+ g_type_init();
+ camera = uca_camera_new("pco", &error);
- uca_cam_alloc(cam, 10);
-
- uca_cam_start_recording(cam);
- uca_cam_register_callback(cam, &grab_callback, &props);
- printf("grabbing for 1 second ... ");
- fflush(stdout);
- sleep(1);
- uca_cam_stop_recording(cam);
- printf("done\n");
+ if (camera == NULL) {
+ g_print("Error during initialization: %s\n", error->message);
+ return 1;
+ }
- uca_destroy(u);
- return 0;
+ g_object_get(G_OBJECT(camera),
+ "name", &name,
+ "sensor-width", &sensor_width,
+ "sensor-height", &sensor_height,
+ NULL);
+
+ g_object_set(G_OBJECT(camera),
+ "roi-x0", 0,
+ "roi-y0", 0,
+ "roi-width", sensor_width,
+ "roi-height", sensor_height,
+ "transfer-asynchronously", TRUE,
+ NULL);
+
+ g_object_get(G_OBJECT(camera),
+ "roi-width", &cbd.roi_width,
+ "roi-height", &cbd.roi_height,
+ NULL);
+
+ g_print("Camera: %s\n", name);
+ g_free(name);
+
+ g_print("Start asynchronous recording\n");
+ cbd.counter = 0;
+ uca_camera_set_grab_func(camera, grab_callback, &cbd);
+ uca_camera_start_recording(camera, &error);
+ g_assert_no_error(error);
+ g_usleep(2 * G_USEC_PER_SEC);
+
+ g_print(" done\n");
+ uca_camera_stop_recording(camera, NULL);
+ g_object_unref(camera);
+
+ return error != NULL ? 1 : 0;
}
diff --git a/test/grab.c b/test/grab.c
index 2a9d9ea..c4b3f3c 100644
--- a/test/grab.c
+++ b/test/grab.c
@@ -21,12 +21,9 @@
#include <stdlib.h>
#include "uca-camera.h"
-#define handle_error(errno) {if ((errno) != UCA_NO_ERROR) printf("error at <%s:%i>\n", \
- __FILE__, __LINE__);}
-
static UcaCamera *camera = NULL;
-void sigint_handler(int signal)
+static void sigint_handler(int signal)
{
printf("Closing down libuca\n");
uca_camera_stop_recording(camera, NULL);
@@ -41,6 +38,7 @@ int main(int argc, char *argv[])
guint sensor_width, sensor_height, sensor_width_extended, sensor_height_extended;
guint roi_width, roi_height, roi_x, roi_y;
guint bits, sensor_rate;
+ gchar *name;
g_type_init();
camera = uca_camera_new("pco", &error);
@@ -55,6 +53,7 @@ int main(int argc, char *argv[])
"sensor-height", &sensor_height,
"sensor-width-extended", &sensor_width_extended,
"sensor-height-extended", &sensor_height_extended,
+ "name", &name,
NULL);
g_object_set(G_OBJECT(camera),
@@ -76,6 +75,9 @@ int main(int argc, char *argv[])
"sensor-pixelrate", &sensor_rate,
NULL);
+ g_print("Camera: %s\n", name);
+ g_free(name);
+
g_print("Sensor: %ix%i px (extended: %ix%i), ROI %ix%i @ (%i, %i) and %i Hz\n",
sensor_width, sensor_height,
sensor_width_extended, sensor_height_extended,