diff options
-rw-r--r-- | src/cameras/uca-pco-camera.c | 52 | ||||
-rw-r--r-- | src/uca-camera.c | 52 | ||||
-rw-r--r-- | src/uca-camera.h | 2 |
3 files changed, 99 insertions, 7 deletions
diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c index 58cae1b..850f3a6 100644 --- a/src/cameras/uca-pco-camera.c +++ b/src/cameras/uca-pco-camera.c @@ -139,6 +139,10 @@ struct _UcaPcoCameraPrivate { guint16 height; GValueArray *horizontal_binnings; GValueArray *vertical_binnings; + + guint16 active_segment; + guint num_recorded_images; + guint current_image; }; static pco_cl_map_entry pco_cl_map[] = { @@ -303,7 +307,7 @@ static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error) 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; + return; } if ((priv->camera_description->camera_type == CAMERATYPE_PCO_DIMAX_STD) || @@ -330,12 +334,49 @@ static void uca_pco_camera_stop_recording(UcaCamera *camera, GError **error) FG_SET_ERROR(err, priv->fg, UCA_PCO_CAMERA_ERROR_FG_ACQUISITION); } +static void uca_pco_camera_start_readout(UcaCamera *camera, GError **error) +{ + g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); + UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); + + /* + * TODO: Check if readout mode is possible. This is not the case for the + * edge. + */ + + guint err = pco_get_active_segment(priv->pco, &priv->active_segment); + HANDLE_PCO_ERROR(err); + + err = pco_get_num_images(priv->pco, priv->active_segment, &priv->num_recorded_images); + HANDLE_PCO_ERROR(err); + + priv->current_image = 1; +} + static void uca_pco_camera_grab(UcaCamera *camera, gpointer *data, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); static frameindex_t last_frame = 0; UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); + gboolean is_readout = FALSE; + g_object_get(G_OBJECT(camera), "is-readout", &is_readout, NULL); + + if (is_readout) { + if (priv->current_image == priv->num_recorded_images) { + *data = NULL; + return; + } + + /* + * No joke, the pco firmware allows to read a range of images but + * implements only reading single images ... + */ + pco_read_images(priv->pco, priv->active_segment, + priv->current_image, priv->current_image); + priv->current_image++; + } + pco_request_image(priv->pco); last_frame = Fg_getLastPicNumberBlockingEx(priv->fg, last_frame+1, priv->fg_port, 5, priv->fg_mem); @@ -430,7 +471,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_ROI_X: { guint16 roi[4] = {0}; - guint err = pco_get_roi(priv->pco, roi); + pco_get_roi(priv->pco, roi); g_value_set_uint(value, roi[0]); } break; @@ -438,7 +479,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_ROI_Y: { guint16 roi[4] = {0}; - guint err = pco_get_roi(priv->pco, roi); + pco_get_roi(priv->pco, roi); g_value_set_uint(value, roi[1]); } break; @@ -446,7 +487,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_ROI_WIDTH: { guint16 roi[4] = {0}; - guint err = pco_get_roi(priv->pco, roi); + pco_get_roi(priv->pco, roi); g_value_set_uint(value, (roi[2] - roi[0])); } break; @@ -454,7 +495,7 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal case PROP_ROI_HEIGHT: { guint16 roi[4] = {0}; - guint err = pco_get_roi(priv->pco, roi); + pco_get_roi(priv->pco, roi); g_value_set_uint(value, (roi[3] - roi[1])); } break; @@ -515,6 +556,7 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) UcaCameraClass *camera_class = UCA_CAMERA_CLASS(klass); camera_class->start_recording = uca_pco_camera_start_recording; camera_class->stop_recording = uca_pco_camera_stop_recording; + camera_class->start_readout = uca_pco_camera_start_readout; camera_class->grab = uca_pco_camera_grab; for (guint id = PROP_0 + 1; id < N_INTERFACE_PROPERTIES; id++) diff --git a/src/uca-camera.c b/src/uca-camera.c index 5b30798..628edec 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -75,11 +75,13 @@ enum { PROP_HAS_CAMRAM_RECORDING, PROP_TRANSFER_ASYNCHRONOUSLY, PROP_IS_RECORDING, + PROP_IS_READOUT, N_PROPERTIES }; struct _UcaCameraPrivate { gboolean is_recording; + gboolean is_readout; gboolean transfer_async; }; @@ -250,6 +252,12 @@ static void uca_camera_class_init(UcaCameraClass *klass) "Is the camera currently recording", FALSE, G_PARAM_READABLE); + camera_properties[PROP_IS_READOUT] = + g_param_spec_boolean("is-readout", + "Is camera in readout mode", + "Is camera in readout mode", + FALSE, G_PARAM_READABLE); + for (guint id = PROP_0 + 1; id < N_PROPERTIES; id++) g_object_class_install_property(gobject_class, id, camera_properties[id]); @@ -262,6 +270,7 @@ static void uca_camera_init(UcaCamera *camera) camera->priv = UCA_CAMERA_GET_PRIVATE(camera); camera->priv->is_recording = FALSE; + camera->priv->is_readout = FALSE; camera->priv->transfer_async = FALSE; /* @@ -372,6 +381,7 @@ void uca_camera_start_recording(UcaCamera *camera, GError **error) (*klass->start_recording)(camera, &tmp_error); if (tmp_error == NULL) { + camera->priv->is_readout = FALSE; camera->priv->is_recording = TRUE; /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ g_object_notify(G_OBJECT(camera), "is-recording"); @@ -406,6 +416,7 @@ void uca_camera_stop_recording(UcaCamera *camera, GError **error) (*klass->stop_recording)(camera, &tmp_error); if (tmp_error == NULL) { + camera->priv->is_readout = FALSE; camera->priv->is_recording = FALSE; /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ g_object_notify(G_OBJECT(camera), "is-recording"); @@ -415,6 +426,43 @@ void uca_camera_stop_recording(UcaCamera *camera, GError **error) } /** + * uca_camera_start_readout: + * @camera: A #UcaCamera object + * @error: Location to store a #UcaCameraError error or %NULL + * + * Initiate readout mode for cameras that support + * #UcaCamera:has-camram-recording after calling + * uca_camera_stop_recording(). Frames have to be picked up with + * ufo_camera_grab(). + */ +void uca_camera_start_readout(UcaCamera *camera, GError **error) +{ + g_return_if_fail(UCA_IS_CAMERA(camera)); + + UcaCameraClass *klass = UCA_CAMERA_GET_CLASS(camera); + + g_return_if_fail(klass != NULL); + g_return_if_fail(klass->start_readout != NULL); + + if (camera->priv->is_recording) { + g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING, + "Camera is still recording"); + return; + } + + GError *tmp_error = NULL; + (*klass->start_readout)(camera, &tmp_error); + + if (tmp_error == NULL) { + camera->priv->is_readout = TRUE; + /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ + g_object_notify(G_OBJECT(camera), "is-readout"); + } + else + g_propagate_error(error, tmp_error); +} + +/** * uca_camera_set_grab_func: * @camera: A #UcaCamera object * func: A #UcaCameraGrabFunc callback function @@ -451,9 +499,9 @@ void uca_camera_grab(UcaCamera *camera, gpointer *data, GError **error) g_return_if_fail(klass->grab != NULL); g_return_if_fail(data != NULL); - if (!camera->priv->is_recording) { + if (!camera->priv->is_recording || !camera->priv->is_readout) { g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_RECORDING, - "Camera is not recording"); + "Camera is neither recording nor in readout mode"); return; } diff --git a/src/uca-camera.h b/src/uca-camera.h index 23a0c41..fb703cd 100644 --- a/src/uca-camera.h +++ b/src/uca-camera.h @@ -73,6 +73,7 @@ struct _UcaCameraClass { void (*start_recording) (UcaCamera *camera, GError **error); void (*stop_recording) (UcaCamera *camera, GError **error); + void (*start_readout) (UcaCamera *camera, GError **error); void (*grab) (UcaCamera *camera, gpointer *data, GError **error); void (*recording_started) (UcaCamera *camera); @@ -84,6 +85,7 @@ UcaCamera *uca_camera_new(const gchar *type, GError **error); void uca_camera_start_recording(UcaCamera *camera, GError **error); void uca_camera_stop_recording(UcaCamera *camera, GError **error); +void uca_camera_start_readout(UcaCamera *camera, GError **error); void uca_camera_grab(UcaCamera *camera, gpointer *data, GError **error); void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data); |