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); | 
