summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cameras/uca-pco-camera.c52
-rw-r--r--src/uca-camera.c52
-rw-r--r--src/uca-camera.h2
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);