From 0ef77576760e3b384ff15f6155c6073ab96fc8c7 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Wed, 10 Apr 2013 09:02:09 +0200 Subject: grab takes -n and -t parameters now --- tools/CMakeLists.txt | 2 +- tools/grab.c | 238 +++++++++++++++++++++++++++-------------------- tools/gui/CMakeLists.txt | 3 +- tools/gui/ring-buffer.c | 64 ------------- tools/gui/ring-buffer.h | 28 ------ tools/ring-buffer.c | 70 ++++++++++++++ tools/ring-buffer.h | 29 ++++++ 7 files changed, 238 insertions(+), 196 deletions(-) delete mode 100644 tools/gui/ring-buffer.c delete mode 100644 tools/gui/ring-buffer.h create mode 100644 tools/ring-buffer.c create mode 100644 tools/ring-buffer.h diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 0e4d28e..66cbd6b 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -21,7 +21,7 @@ set(libs uca ${GLIB2_LIBRARIES} ${GOBJECT2_LIBRARIES}) add_executable(gen-doc gen-doc.c) target_link_libraries(gen-doc ${libs}) -add_executable(grab grab.c) +add_executable(grab grab.c ring-buffer.c) target_link_libraries(grab ${libs}) add_executable(grab-async grab-async.c) diff --git a/tools/grab.c b/tools/grab.c index e8e91be..bbe9269 100644 --- a/tools/grab.c +++ b/tools/grab.c @@ -21,140 +21,174 @@ #include #include "uca-plugin-manager.h" #include "uca-camera.h" +#include "ring-buffer.h" -static UcaCamera *camera = NULL; -static void sigint_handler(int signal) -{ - printf("Closing down libuca\n"); - uca_camera_stop_recording(camera, NULL); - g_object_unref(camera); - exit(signal); -} +typedef struct { + gint n_frames; + gdouble duration; +} Options; -static void -print_usage (void) + +static gchar * +get_camera_list (void) { GList *types; + GString *str; UcaPluginManager *manager; manager = uca_plugin_manager_new (); - g_print ("Usage: benchmark [ "); types = uca_plugin_manager_get_available_cameras (manager); + str = g_string_new ("[ "); + + if (types != NULL) { + for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { + gchar *name = (gchar *) it->data; - if (types == NULL) { - g_print ("] -- no camera plugin found\n"); - return; + if (g_list_next (it) == NULL) + g_string_append_printf (str, "%s ]", name); + else + g_string_append_printf (str, "%s, ", name); + } } + else { + g_string_append (str, "]"); + } + + g_object_unref (manager); + return g_string_free (str, FALSE); +} - for (GList *it = g_list_first (types); it != NULL; it = g_list_next (it)) { - gchar *name = (gchar *) it->data; - if (g_list_next (it) == NULL) - g_print ("%s ]\n", name); - else - g_print ("%s, ", name); +static void +store_frames (RingBuffer *buffer) +{ + guint n_frames; + gsize size; + + size = ring_buffer_get_block_size (buffer); + n_frames = ring_buffer_get_num_blocks (buffer); + + for (gint i = 0; i < n_frames; i++) { + FILE *fp; + gchar *filename; + gpointer data; + + filename = g_strdup_printf ("frame-%08i.raw", i); + fp = fopen(filename, "wb"); + data = ring_buffer_get_pointer (buffer, i); + + fwrite (data, size, 1, fp); + fclose (fp); + g_free (filename); } } -int main(int argc, char *argv[]) +static GError * +record_frames (UcaCamera *camera, Options *opts) { + guint roi_width; + guint roi_height; + guint bits; + guint pixel_size; + gsize size; + gint n_frames; + guint n_allocated; + GTimer *timer; + RingBuffer *buffer; + GError *error = NULL; + + g_object_get (G_OBJECT (camera), + "roi-width", &roi_width, + "roi-height", &roi_height, + "sensor-bitdepth", &bits, + NULL); + + pixel_size = bits == 8 ? 1 : 2; + size = roi_width * roi_height * pixel_size; + n_allocated = opts->n_frames > 0 ? opts->n_frames : 256; + buffer = ring_buffer_new (size, n_allocated); + timer = g_timer_new(); + + g_print("Start recording: %ix%i at %i bits/pixel\n", + roi_width, roi_height, bits); + + uca_camera_start_recording(camera, &error); + + if (error != NULL) + return error; + + n_frames = 0; + g_timer_start(timer); + + while (n_frames < opts->n_frames || g_timer_elapsed (timer, NULL) < opts->duration) { + uca_camera_grab (camera, ring_buffer_get_current_pointer (buffer), &error); + ring_buffer_proceed (buffer); + + if (error != NULL) + return error; + + n_frames++; + } + + g_print ("Stop recording\n"); + uca_camera_stop_recording (camera, &error); + store_frames (buffer); + ring_buffer_free (buffer); + g_timer_destroy (timer); + + return error; +} + +int +main (int argc, char *argv[]) +{ + GOptionContext *context; UcaPluginManager *manager; + UcaCamera *camera; + gchar *cam_list; GError *error = NULL; - (void) signal(SIGINT, sigint_handler); - guint sensor_width, sensor_height; - guint roi_width, roi_height, roi_x, roi_y, roi_width_multiplier, roi_height_multiplier; - guint bits; - gchar *name; + static Options opts = { + .n_frames = -1, + .duration = -1.0 + }; + + static GOptionEntry entries[] = { + { "num-frames", 'n', 0, G_OPTION_ARG_INT, &opts.n_frames, "Number of frames to acquire", "N" }, + { "time", 't', 0, G_OPTION_ARG_DOUBLE, &opts.duration, "Duration in seconds", NULL }, + { NULL } + }; g_type_init(); + cam_list = get_camera_list (); + context = g_option_context_new (cam_list); + g_option_context_add_main_entries (context, entries, NULL); + g_free (cam_list); + + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_print ("Failed parsing arguments: %s\n", error->message); + exit (1); + } + if (argc < 2) { - print_usage(); - return 1; + g_print ("%s\n", g_option_context_get_help (context, TRUE, NULL)); + exit (0); } manager = uca_plugin_manager_new (); camera = uca_plugin_manager_get_camera (manager, argv[1], &error, NULL); if (camera == NULL) { - g_print("Error during initialization: %s\n", error->message); - return 1; - } - - g_object_get(G_OBJECT(camera), - "sensor-width", &sensor_width, - "sensor-height", &sensor_height, - "name", &name, - NULL); - - g_object_set(G_OBJECT(camera), - "exposure-time", 0.001, - "roi-x0", 0, - "roi-y0", 0, - "roi-width", 1000, - "roi-height", sensor_height, - NULL); - - g_object_get(G_OBJECT(camera), - "roi-width", &roi_width, - "roi-height", &roi_height, - "roi-width-multiplier", &roi_width_multiplier, - "roi-height-multiplier", &roi_height_multiplier, - "roi-x0", &roi_x, - "roi-y0", &roi_y, - "sensor-bitdepth", &bits, - NULL); - - g_print("Camera: %s\n", name); - g_free(name); - - g_print("Sensor: %ix%i px\n", sensor_width, sensor_height); - g_print("ROI: %ix%i @ (%i, %i), steps: %i, %i\n", - roi_width, roi_height, roi_x, roi_y, roi_width_multiplier, roi_height_multiplier); - - const int pixel_size = bits == 8 ? 1 : 2; - gpointer buffer = g_malloc0(roi_width * roi_height * pixel_size); - gchar filename[FILENAME_MAX]; - GTimer *timer = g_timer_new(); - - for (int i = 0; i < 1; i++) { - gint counter = 0; - g_print("Start recording\n"); - uca_camera_start_recording(camera, &error); - g_assert_no_error(error); - - while (counter < 5) { - g_print(" grab frame ... "); - g_timer_start(timer); - uca_camera_grab(camera, buffer, &error); - - if (error != NULL) { - g_print("\nError: %s\n", error->message); - goto cleanup; - } - - g_timer_stop(timer); - g_print("done (took %3.5fs)\n", g_timer_elapsed(timer, NULL)); - - snprintf(filename, FILENAME_MAX, "frame-%08i.raw", counter++); - FILE *fp = fopen(filename, "wb"); - fwrite(buffer, roi_width * roi_height, pixel_size, fp); - fclose(fp); - g_usleep(2 * G_USEC_PER_SEC); - } - - g_print("Stop recording\n"); - uca_camera_stop_recording(camera, &error); - g_assert_no_error(error); + g_print ("Error during initialization: %s\n", error->message); + exit (1); } - g_timer_destroy(timer); + error = record_frames (camera, &opts); -cleanup: - uca_camera_stop_recording(camera, NULL); - g_object_unref(camera); - g_free(buffer); + if (error != NULL) + g_print ("Error: %s\n", error->message); + g_object_unref (camera); return error != NULL ? 1 : 0; } diff --git a/tools/gui/CMakeLists.txt b/tools/gui/CMakeLists.txt index 1000ac6..07f597b 100644 --- a/tools/gui/CMakeLists.txt +++ b/tools/gui/CMakeLists.txt @@ -18,6 +18,7 @@ include_directories( ${GOBJECT2_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR}/../../src/ ${CMAKE_CURRENT_SOURCE_DIR}/../../src + ${CMAKE_CURRENT_SOURCE_DIR}/../ ) if (GTK2_FOUND) @@ -25,7 +26,7 @@ if (GTK2_FOUND) add_executable(control control.c - ring-buffer.c + ../ring-buffer.c # yes this sucks and should be fixed egg-property-cell-renderer.c egg-property-tree-view.c egg-histogram-view.c) diff --git a/tools/gui/ring-buffer.c b/tools/gui/ring-buffer.c deleted file mode 100644 index ec2638c..0000000 --- a/tools/gui/ring-buffer.c +++ /dev/null @@ -1,64 +0,0 @@ - -#include -#include "ring-buffer.h" - -RingBuffer * -ring_buffer_new (gsize block_size, - gsize n_blocks) -{ - RingBuffer *buffer; - - buffer = g_new0 (RingBuffer, 1); - buffer->block_size = block_size; - buffer->n_blocks_total = n_blocks; - buffer->n_blocks_used = 0; - buffer->current_index = 0; - buffer->data = g_malloc0_n (n_blocks, block_size); - - return buffer; -} - -void -ring_buffer_free (RingBuffer *buffer) -{ - g_free (buffer->data); - g_free (buffer); -} - -void -ring_buffer_reset (RingBuffer *buffer) -{ - buffer->n_blocks_used = 0; - buffer->current_index = 0; -} - -gpointer -ring_buffer_get_current_pointer (RingBuffer *buffer) -{ - return buffer->data + (buffer->current_index % buffer->n_blocks_total) * buffer->block_size; -} - -gpointer -ring_buffer_get_pointer (RingBuffer *buffer, - guint index) -{ - g_assert (index < buffer->n_blocks_total); - return buffer->data + ((buffer->current_index - buffer->n_blocks_used + index) % buffer->n_blocks_total) * buffer->block_size; -} - -guint -ring_buffer_get_num_blocks (RingBuffer *buffer) -{ - return buffer->n_blocks_used; -} - -void -ring_buffer_proceed (RingBuffer *buffer) -{ - buffer->current_index++; - - if (buffer->n_blocks_used < buffer->n_blocks_total) - buffer->n_blocks_used++; - else - buffer->current_index = buffer->current_index % buffer->n_blocks_total; -} diff --git a/tools/gui/ring-buffer.h b/tools/gui/ring-buffer.h deleted file mode 100644 index 9966eb7..0000000 --- a/tools/gui/ring-buffer.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef RING_BUFFER_H -#define RING_BUFFER_H - -#include - -G_BEGIN_DECLS - -typedef struct { - guchar *data; - gsize block_size; - guint n_blocks_total; - guint n_blocks_used; - guint current_index; -} RingBuffer; - -RingBuffer * ring_buffer_new (gsize block_size, - gsize n_blocks); -void ring_buffer_free (RingBuffer *buffer); -void ring_buffer_reset (RingBuffer *buffer); -gpointer ring_buffer_get_current_pointer (RingBuffer *buffer); -gpointer ring_buffer_get_pointer (RingBuffer *buffer, - guint index); -guint ring_buffer_get_num_blocks (RingBuffer *buffer); -void ring_buffer_proceed (RingBuffer *buffer); - -G_END_DECLS - -#endif diff --git a/tools/ring-buffer.c b/tools/ring-buffer.c new file mode 100644 index 0000000..039024f --- /dev/null +++ b/tools/ring-buffer.c @@ -0,0 +1,70 @@ + +#include +#include "ring-buffer.h" + +RingBuffer * +ring_buffer_new (gsize block_size, + gsize n_blocks) +{ + RingBuffer *buffer; + + buffer = g_new0 (RingBuffer, 1); + buffer->block_size = block_size; + buffer->n_blocks_total = n_blocks; + buffer->n_blocks_used = 0; + buffer->current_index = 0; + buffer->data = g_malloc0_n (n_blocks, block_size); + + return buffer; +} + +void +ring_buffer_free (RingBuffer *buffer) +{ + g_free (buffer->data); + g_free (buffer); +} + +void +ring_buffer_reset (RingBuffer *buffer) +{ + buffer->n_blocks_used = 0; + buffer->current_index = 0; +} + +gsize +ring_buffer_get_block_size (RingBuffer *buffer) +{ + return buffer->block_size; +} + +gpointer +ring_buffer_get_current_pointer (RingBuffer *buffer) +{ + return buffer->data + (buffer->current_index % buffer->n_blocks_total) * buffer->block_size; +} + +gpointer +ring_buffer_get_pointer (RingBuffer *buffer, + guint index) +{ + g_assert (index < buffer->n_blocks_total); + return buffer->data + ((buffer->current_index - buffer->n_blocks_used + index) % buffer->n_blocks_total) * buffer->block_size; +} + +guint +ring_buffer_get_num_blocks (RingBuffer *buffer) +{ + return buffer->n_blocks_used; +} + +void +ring_buffer_proceed (RingBuffer *buffer) +{ + buffer->current_index++; + + if (buffer->n_blocks_used < buffer->n_blocks_total) + buffer->n_blocks_used++; + else + buffer->current_index = buffer->current_index % buffer->n_blocks_total; +} diff --git a/tools/ring-buffer.h b/tools/ring-buffer.h new file mode 100644 index 0000000..a3758cb --- /dev/null +++ b/tools/ring-buffer.h @@ -0,0 +1,29 @@ +#ifndef RING_BUFFER_H +#define RING_BUFFER_H + +#include + +G_BEGIN_DECLS + +typedef struct { + guchar *data; + gsize block_size; + guint n_blocks_total; + guint n_blocks_used; + guint current_index; +} RingBuffer; + +RingBuffer * ring_buffer_new (gsize block_size, + gsize n_blocks); +void ring_buffer_free (RingBuffer *buffer); +void ring_buffer_reset (RingBuffer *buffer); +gsize ring_buffer_get_block_size (RingBuffer *buffer); +gpointer ring_buffer_get_current_pointer (RingBuffer *buffer); +gpointer ring_buffer_get_pointer (RingBuffer *buffer, + guint index); +guint ring_buffer_get_num_blocks (RingBuffer *buffer); +void ring_buffer_proceed (RingBuffer *buffer); + +G_END_DECLS + +#endif -- cgit v1.2.3