diff options
author | Matthias Vogelgesang <matthias.vogelgesang@gmail.com> | 2012-06-20 13:45:10 +0200 |
---|---|---|
committer | Matthias Vogelgesang <matthias.vogelgesang@gmail.com> | 2012-06-20 13:58:03 +0200 |
commit | fc49419b57283919654680d4ee2bc0b4a4537e3e (patch) | |
tree | 0a1d7c0a164152b33f7e0277b4347a362fc547fb | |
parent | 4d07f8c3e9a99242bfbd373722731025235d1968 (diff) | |
download | libuca-fc49419b57283919654680d4ee2bc0b4a4537e3e.tar.gz libuca-fc49419b57283919654680d4ee2bc0b4a4537e3e.tar.bz2 libuca-fc49419b57283919654680d4ee2bc0b4a4537e3e.tar.xz libuca-fc49419b57283919654680d4ee2bc0b4a4537e3e.zip |
Re-implement asynchronous data acquisition
-rw-r--r-- | src/cameras/uca-pco-camera.c | 47 | ||||
-rw-r--r-- | test/CMakeLists.txt | 5 | ||||
-rw-r--r-- | test/grab-async.c | 116 | ||||
-rw-r--r-- | test/grab.c | 10 |
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, |