diff options
-rw-r--r-- | NEWS | 17 | ||||
-rw-r--r-- | docs/manual.md | 18 | ||||
-rw-r--r-- | plugins/mock/uca-mock-camera.c | 18 | ||||
-rw-r--r-- | plugins/pco/uca-pco-camera.c | 23 | ||||
-rw-r--r-- | plugins/pf/uca-pf-camera.c | 24 | ||||
-rw-r--r-- | plugins/ufo/uca-ufo-camera.c | 38 | ||||
-rw-r--r-- | src/uca-camera.c | 30 | ||||
-rw-r--r-- | src/uca-camera.h | 9 | ||||
-rw-r--r-- | tools/benchmark.c | 2 | ||||
-rw-r--r-- | tools/grab.c | 2 | ||||
-rw-r--r-- | tools/gui/control.c | 6 |
11 files changed, 104 insertions, 83 deletions
@@ -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..0b81bdb 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 diff --git a/plugins/mock/uca-mock-camera.c b/plugins/mock/uca-mock-camera.c index c7561ab..675d5ec 100644 --- a/plugins/mock/uca-mock-camera.c +++ b/plugins/mock/uca-mock-camera.c @@ -242,20 +242,18 @@ uca_mock_camera_trigger (UcaCamera *camera, GError **error) { } -static void -uca_mock_camera_grab (UcaCamera *camera, gpointer *data, GError **error) +static gboolean +uca_mock_camera_grab (UcaCamera *camera, gpointer data, GError **error) { - g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); - g_return_if_fail(data != NULL); + g_return_val_if_fail (UCA_IS_MOCK_CAMERA(camera), FALSE); - UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera); + UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE (camera); - if (*data == NULL) - *data = g_malloc0(priv->roi_width * priv->roi_height); - - g_memmove(*data, priv->dummy_data, priv->roi_width * priv->roi_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 diff --git a/plugins/pco/uca-pco-camera.c b/plugins/pco/uca-pco-camera.c index de68001..4a0cce6 100644 --- a/plugins/pco/uca-pco-camera.c +++ b/plugins/pco/uca-pco-camera.c @@ -565,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 = 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; @@ -580,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; } /* @@ -595,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->description->type == CAMERATYPE_PCO_EDGE) - pco_get_reorder_func(priv->pco)((guint16 *) *data, frame, priv->frame_width, priv->frame_height); + 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 diff --git a/plugins/pf/uca-pf-camera.c b/plugins/pf/uca-pf-camera.c index 085fde5..b7967be 100644 --- a/plugins/pf/uca-pf-camera.c +++ b/plugins/pf/uca-pf-camera.c @@ -184,25 +184,27 @@ uca_pf_camera_start_readout(UcaCamera *camera, GError **error) "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 diff --git a/plugins/ufo/uca-ufo-camera.c b/plugins/ufo/uca-ufo-camera.c index f68614e..93c13a8 100644 --- a/plugins/ufo/uca-ufo-camera.c +++ b/plugins/ufo/uca-ufo-camera.c @@ -34,6 +34,15 @@ 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)) static void uca_ufo_camera_initable_iface_init (GInitableIface *iface); @@ -301,10 +310,10 @@ 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; @@ -313,20 +322,17 @@ uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error) 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_trigger (priv->handle, PCILIB_EVENT0, 0, NULL); + PCILIB_SET_ERROR_RETURN_FALSE (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); + 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); - if (*data == NULL) - *data = g_malloc0(SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16)); - - 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. @@ -336,15 +342,17 @@ uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **error) */ /* 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 diff --git a/src/uca-camera.c b/src/uca-camera.c index 8905a95..ec4b418 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -669,34 +669,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 +701,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/tools/benchmark.c b/tools/benchmark.c index 170a96c..f262a06 100644 --- a/tools/benchmark.c +++ b/tools/benchmark.c @@ -100,7 +100,7 @@ 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); + uca_camera_grab(camera, buffer, &error); if (error != NULL) { g_warning ("Error grabbing frame %02i/%i: `%s'", i, n_frames, error->message); diff --git a/tools/grab.c b/tools/grab.c index b020279..e8e91be 100644 --- a/tools/grab.c +++ b/tools/grab.c @@ -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 192859c..b17040f 100644 --- a/tools/gui/control.c +++ b/tools/gui/control.c @@ -161,7 +161,7 @@ preview_frames (void *args) gpointer buffer; buffer = ring_buffer_get_current_pointer (data->buffer); - uca_camera_grab (data->camera, &buffer, &error); + uca_camera_grab (data->camera, buffer, &error); if (error == NULL) { convert_grayscale_to_rgb (data, buffer); @@ -191,7 +191,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); @@ -345,7 +345,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++); |