summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/mock/uca-mock-camera.c93
-rw-r--r--plugins/mock/uca-mock-camera.h2
-rw-r--r--plugins/pco/uca-pco-camera.c314
-rw-r--r--plugins/pco/uca-pco-camera.h4
-rw-r--r--plugins/pf/uca-pf-camera.c178
-rw-r--r--plugins/ufo/uca-ufo-camera.c323
6 files changed, 608 insertions, 306 deletions
diff --git a/plugins/mock/uca-mock-camera.c b/plugins/mock/uca-mock-camera.c
index bf3124e..675d5ec 100644
--- a/plugins/mock/uca-mock-camera.c
+++ b/plugins/mock/uca-mock-camera.c
@@ -16,12 +16,17 @@
Franklin St, Fifth Floor, Boston, MA 02110, USA */
#include <gmodule.h>
+#include <gio/gio.h>
#include <string.h>
#include "uca-mock-camera.h"
#define UCA_MOCK_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_MOCK_CAMERA, UcaMockCameraPrivate))
-G_DEFINE_TYPE(UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA)
+static void uca_mock_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaMockCamera, uca_mock_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_mock_initable_iface_init))
enum {
PROP_FRAMERATE = N_BASE_PROPERTIES,
@@ -38,6 +43,7 @@ static const gint mock_overrideables[] = {
PROP_SENSOR_VERTICAL_BINNING,
PROP_SENSOR_VERTICAL_BINNINGS,
PROP_EXPOSURE_TIME,
+ PROP_TRIGGER_MODE,
PROP_ROI_X,
PROP_ROI_Y,
PROP_ROI_WIDTH,
@@ -53,6 +59,8 @@ static const gint mock_overrideables[] = {
static GParamSpec *mock_properties[N_PROPERTIES] = { NULL, };
struct _UcaMockCameraPrivate {
+ UcaCameraTrigger trigger;
+
guint width;
guint height;
guint roi_x, roi_y, roi_width, roi_height;
@@ -134,7 +142,8 @@ static const char g_digits[10][20] = {
static const guint DIGIT_WIDTH = 4;
static const guint DIGIT_HEIGHT = 5;
-static void print_number(gchar *buffer, guint number, guint x, guint y, guint width)
+static void
+print_number(gchar *buffer, guint number, guint x, guint y, guint width)
{
for (int i = 0; i < DIGIT_WIDTH; i++) {
for (int j = 0; j < DIGIT_HEIGHT; j++) {
@@ -143,7 +152,8 @@ static void print_number(gchar *buffer, guint number, guint x, guint y, guint wi
}
}
-static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
+static void
+print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
{
guint number = priv->current_frame;
guint divisor = 10000000;
@@ -157,7 +167,8 @@ static void print_current_frame(UcaMockCameraPrivate *priv, gchar *buffer)
}
}
-static gpointer mock_grab_func(gpointer data)
+static gpointer
+mock_grab_func(gpointer data)
{
UcaMockCamera *mock_camera = UCA_MOCK_CAMERA(data);
g_return_val_if_fail(UCA_IS_MOCK_CAMERA(mock_camera), NULL);
@@ -174,7 +185,8 @@ static gpointer mock_grab_func(gpointer data)
return NULL;
}
-static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
+static void
+uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
{
gboolean transfer_async = FALSE;
UcaMockCameraPrivate *priv;
@@ -204,7 +216,8 @@ static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
}
}
-static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
+static void
+uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
{
gboolean transfer_async = FALSE;
UcaMockCameraPrivate *priv;
@@ -224,22 +237,27 @@ static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
}
}
-static void uca_mock_camera_grab(UcaCamera *camera, gpointer *data, GError **error)
+static void
+uca_mock_camera_trigger (UcaCamera *camera, GError **error)
{
- g_return_if_fail(UCA_IS_MOCK_CAMERA(camera));
- g_return_if_fail(data != NULL);
+}
- UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera);
+static gboolean
+uca_mock_camera_grab (UcaCamera *camera, gpointer data, GError **error)
+{
+ g_return_val_if_fail (UCA_IS_MOCK_CAMERA(camera), FALSE);
- if (*data == NULL)
- *data = g_malloc0(priv->width * priv->height);
+ UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE (camera);
- g_memmove(*data, priv->dummy_data, priv->width * priv->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 uca_mock_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+static void
+uca_mock_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
g_return_if_fail(UCA_IS_MOCK_CAMERA(object));
UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
@@ -263,13 +281,17 @@ static void uca_mock_camera_set_property(GObject *object, guint property_id, con
case PROP_ROI_HEIGHT:
priv->roi_height = g_value_get_uint(value);
break;
+ case PROP_TRIGGER_MODE:
+ priv->trigger = g_value_get_enum (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
return;
}
}
-static void uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+static void
+uca_mock_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
@@ -331,13 +353,17 @@ static void uca_mock_camera_get_property(GObject *object, guint property_id, GVa
case PROP_FRAMERATE:
g_value_set_float(value, priv->frame_rate);
break;
+ case PROP_TRIGGER_MODE:
+ g_value_set_enum (value, priv->trigger);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
}
}
-static void uca_mock_camera_finalize(GObject *object)
+static void
+uca_mock_camera_finalize(GObject *object)
{
UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
@@ -352,7 +378,23 @@ static void uca_mock_camera_finalize(GObject *object)
G_OBJECT_CLASS(uca_mock_camera_parent_class)->finalize(object);
}
-static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
+static gboolean
+ufo_mock_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (UCA_IS_MOCK_CAMERA (initable), FALSE);
+ return TRUE;
+}
+
+static void
+uca_mock_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = ufo_mock_camera_initable_init;
+}
+
+static void
+uca_mock_camera_class_init(UcaMockCameraClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = uca_mock_camera_set_property;
@@ -363,6 +405,7 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
camera_class->start_recording = uca_mock_camera_start_recording;
camera_class->stop_recording = uca_mock_camera_stop_recording;
camera_class->grab = uca_mock_camera_grab;
+ camera_class->trigger = uca_mock_camera_trigger;
for (guint i = 0; mock_overrideables[i] != 0; i++)
g_object_class_override_property(gobject_class, mock_overrideables[i], uca_camera_props[mock_overrideables[i]]);
@@ -380,13 +423,14 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate));
}
-static void uca_mock_camera_init(UcaMockCamera *self)
+static void
+uca_mock_camera_init(UcaMockCamera *self)
{
self->priv = UCA_MOCK_CAMERA_GET_PRIVATE(self);
self->priv->roi_x = 0;
self->priv->roi_y = 0;
- self->priv->width = self->priv->roi_width = 640;
- self->priv->height = self->priv->roi_height = 480;
+ self->priv->width = self->priv->roi_width = 2016;
+ self->priv->height = self->priv->roi_height = 2016;
self->priv->frame_rate = self->priv->max_frame_rate = 100000.0f;
self->priv->grab_thread = NULL;
self->priv->current_frame = 0;
@@ -401,9 +445,8 @@ static void uca_mock_camera_init(UcaMockCamera *self)
uca_camera_register_unit (UCA_CAMERA (self), "frame-rate", UCA_UNIT_COUNT);
}
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
{
- UcaCamera *camera = UCA_CAMERA (g_object_new (UCA_TYPE_MOCK_CAMERA, NULL));
- return camera;
+ return UCA_TYPE_MOCK_CAMERA;
}
diff --git a/plugins/mock/uca-mock-camera.h b/plugins/mock/uca-mock-camera.h
index 9ee9190..bfbd166 100644
--- a/plugins/mock/uca-mock-camera.h
+++ b/plugins/mock/uca-mock-camera.h
@@ -58,8 +58,6 @@ struct _UcaMockCameraClass {
UcaCameraClass parent;
};
-GType uca_mock_camera_get_type(void);
-
G_END_DECLS
#endif
diff --git a/plugins/pco/uca-pco-camera.c b/plugins/pco/uca-pco-camera.c
index bb7bd5a..4a0cce6 100644
--- a/plugins/pco/uca-pco-camera.c
+++ b/plugins/pco/uca-pco-camera.c
@@ -15,6 +15,7 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+#include <gio/gio.h>
#include <gmodule.h>
#include <stdlib.h>
#include <stdio.h>
@@ -26,14 +27,13 @@
#include "uca-pco-camera.h"
#include "uca-enums.h"
-#define FG_TRY_PARAM(fg, camobj, param, val_addr, port) \
+#define FG_TRY_PARAM(fg, error, param, val_addr, port) \
{ int r = Fg_setParameter(fg, param, val_addr, port); \
if (r != FG_OK) { \
- g_set_error(error, UCA_PCO_CAMERA_ERROR, \
+ g_set_error (error, UCA_PCO_CAMERA_ERROR, \
UCA_PCO_CAMERA_ERROR_FG_GENERAL, \
"%s", Fg_getLastErrorDescription(fg)); \
- g_object_unref(camobj); \
- return NULL; \
+ return FALSE; \
} }
#define FG_SET_ERROR(err, fg, err_type) \
@@ -54,7 +54,11 @@
#define UCA_PCO_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraPrivate))
-G_DEFINE_TYPE(UcaPcoCamera, uca_pco_camera, UCA_TYPE_CAMERA)
+static void uca_pco_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaPcoCamera, uca_pco_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_pco_camera_initable_iface_init))
#define TIMEBASE_INVALID 0xDEAD
@@ -149,7 +153,7 @@ static GParamSpec *pco_properties[N_PROPERTIES] = { NULL, };
* This structure defines type-specific properties of PCO cameras.
*/
typedef struct {
- int camera_type;
+ int type;
const char *so_file;
int cl_type;
int cl_format;
@@ -158,8 +162,9 @@ typedef struct {
} pco_cl_map_entry;
struct _UcaPcoCameraPrivate {
+ GError *construct_error;
pco_handle pco;
- pco_cl_map_entry *camera_description;
+ pco_cl_map_entry *description;
Fg_Struct *fg;
guint fg_port;
@@ -193,7 +198,7 @@ struct _UcaPcoCameraPrivate {
static pco_cl_map_entry pco_cl_map[] = {
{ CAMERATYPE_PCO_EDGE, "libFullAreaGray8.so", FG_CL_8BIT_FULL_10, FG_GRAY, 30.0f, FALSE },
{ CAMERATYPE_PCO4000, "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT, FG_GRAY16, 5.0f, TRUE },
- { CAMERATYPE_PCO_DIMAX_STD, "libDualAreaGray16.so", FG_CL_SINGLETAP_8_BIT, FG_GRAY16, 1279.0f, TRUE },
+ { CAMERATYPE_PCO_DIMAX_STD, "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT, FG_GRAY16, 1279.0f, TRUE },
{ 0, NULL, 0, 0, 0.0f, FALSE }
};
@@ -201,8 +206,8 @@ static pco_cl_map_entry *get_pco_cl_map_entry(int camera_type)
{
pco_cl_map_entry *entry = pco_cl_map;
- while (entry->camera_type != 0) {
- if (entry->camera_type == camera_type)
+ while (entry->type != 0) {
+ if (entry->type == camera_type)
return entry;
entry++;
}
@@ -249,7 +254,7 @@ fill_pixelrates(UcaPcoCameraPrivate *priv, guint32 rates[4], gint num_rates)
{
GValue val = {0};
g_value_init(&val, G_TYPE_UINT);
- priv->pixelrates = g_value_array_new(num_rates);
+ priv->pixelrates = g_value_array_new (num_rates);
for (gint i = 0; i < num_rates; i++) {
g_value_set_uint(&val, (guint) rates[i]);
@@ -330,7 +335,7 @@ get_suitable_timebase(gdouble time)
static gdouble
get_internal_delay (UcaPcoCamera *camera)
{
- if (camera->priv->camera_description->camera_type == CAMERATYPE_PCO_DIMAX_STD) {
+ if (camera->priv->description->type == CAMERATYPE_PCO_DIMAX_STD) {
gdouble sensor_rate;
g_object_get (camera, "sensor-pixelrate", &sensor_rate, NULL);
@@ -350,7 +355,7 @@ fg_callback(frameindex_t frame, struct fg_apc_data *apc)
UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
gpointer data = Fg_getImagePtrEx(priv->fg, frame, priv->fg_port, priv->fg_mem);
- if (priv->camera_description->camera_type != CAMERATYPE_PCO_EDGE)
+ if (priv->description->type != CAMERATYPE_PCO_EDGE)
camera->grab_func(data, camera->user_data);
else {
pco_get_reorder_func(priv->pco)(priv->grab_buffer, data, priv->frame_width, priv->frame_height);
@@ -392,7 +397,7 @@ check_pco_property_error (guint err, guint property_id)
}
static void
-uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
+uca_pco_camera_start_recording (UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
guint err = PCO_NOERROR;
@@ -447,7 +452,7 @@ uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
/* g_warning("Cannot set binning\n"); */
if (priv->frame_width != priv->roi_width || priv->frame_height != priv->roi_height || priv->fg_mem == NULL) {
- guint fg_width = priv->camera_description->camera_type == CAMERATYPE_PCO_EDGE ? 2 * priv->roi_width : priv->roi_width;
+ guint fg_width = priv->description->type == CAMERATYPE_PCO_EDGE ? 2 * priv->roi_width : priv->roi_width;
priv->frame_width = priv->roi_width;
priv->frame_height = priv->roi_height;
@@ -474,8 +479,8 @@ uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
if (transfer_async)
setup_fg_callback(camera);
- if ((priv->camera_description->camera_type == CAMERATYPE_PCO_DIMAX_STD) ||
- (priv->camera_description->camera_type == CAMERATYPE_PCO4000))
+ if ((priv->description->type == CAMERATYPE_PCO_DIMAX_STD) ||
+ (priv->description->type == CAMERATYPE_PCO4000))
pco_clear_active_segment(priv->pco);
priv->last_frame = 0;
@@ -491,11 +496,10 @@ uca_pco_camera_start_recording(UcaCamera *camera, GError **error)
}
static void
-uca_pco_camera_stop_recording(UcaCamera *camera, GError **error)
+uca_pco_camera_stop_recording (UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_PCO_CAMERA(camera));
UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
-
guint err = pco_stop_recording(priv->pco);
HANDLE_PCO_ERROR(err);
@@ -561,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 = G_MAXINT;
+ 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;
@@ -576,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;
}
/*
@@ -591,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->camera_description->camera_type == CAMERATYPE_PCO_EDGE)
- pco_get_reorder_func(priv->pco)((guint16 *) *data, frame, priv->frame_width, priv->frame_height);
+ if (priv->description->type == CAMERATYPE_PCO_EDGE)
+ 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
@@ -915,7 +920,7 @@ uca_pco_camera_get_property(GObject *object, guint property_id, GValue *value, G
break;
case PROP_SENSOR_MAX_FRAME_RATE:
- g_value_set_float(value, priv->camera_description->max_frame_rate);
+ g_value_set_float(value, priv->description->max_frame_rate);
break;
case PROP_SENSOR_BITDEPTH:
@@ -1023,7 +1028,7 @@ uca_pco_camera_get_property(GObject *object, guint property_id, GValue *value, G
break;
case PROP_HAS_CAMRAM_RECORDING:
- g_value_set_boolean(value, priv->camera_description->has_camram);
+ g_value_set_boolean(value, priv->description->has_camram);
break;
case PROP_RECORDED_FRAMES:
@@ -1179,27 +1184,63 @@ uca_pco_camera_finalize(GObject *object)
UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object);
if (priv->horizontal_binnings)
- g_value_array_free(priv->horizontal_binnings);
+ g_value_array_free (priv->horizontal_binnings);
if (priv->vertical_binnings)
- g_value_array_free(priv->vertical_binnings);
+ g_value_array_free (priv->vertical_binnings);
if (priv->pixelrates)
- g_value_array_free(priv->pixelrates);
+ g_value_array_free (priv->pixelrates);
if (priv->fg) {
if (priv->fg_mem)
Fg_FreeMemEx(priv->fg, priv->fg_mem);
- Fg_FreeGrabber(priv->fg);
+ Fg_FreeGrabber (priv->fg);
}
if (priv->pco)
- pco_destroy(priv->pco);
+ pco_destroy (priv->pco);
+
+ g_free (priv->grab_buffer);
+ g_clear_error (&priv->construct_error);
+
+ G_OBJECT_CLASS (uca_pco_camera_parent_class)->finalize (object);
+}
- g_free(priv->grab_buffer);
+static gboolean
+uca_pco_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ UcaPcoCamera *camera;
+ UcaPcoCameraPrivate *priv;
+
+ g_return_val_if_fail (UCA_IS_PCO_CAMERA (initable), FALSE);
+
+ if (cancellable != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ camera = UCA_PCO_CAMERA (initable);
+ priv = camera->priv;
+
+ if (priv->construct_error != NULL) {
+ if (error)
+ *error = g_error_copy (priv->construct_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
- G_OBJECT_CLASS(uca_pco_camera_parent_class)->finalize(object);
+static void
+uca_pco_camera_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = uca_pco_camera_initable_init;
}
static void
@@ -1387,62 +1428,43 @@ uca_pco_camera_class_init(UcaPcoCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaPcoCameraPrivate));
}
-static void
-uca_pco_camera_init(UcaPcoCamera *self)
+static gboolean
+setup_pco_camera (UcaPcoCameraPrivate *priv)
{
- UcaCamera *camera;
-
- self->priv = UCA_PCO_CAMERA_GET_PRIVATE(self);
- self->priv->fg = NULL;
- self->priv->fg_mem = NULL;
- self->priv->pco = NULL;
- self->priv->horizontal_binnings = NULL;
- self->priv->vertical_binnings = NULL;
- self->priv->pixelrates = NULL;
- self->priv->camera_description = NULL;
- self->priv->last_frame = 0;
- self->priv->grab_buffer = NULL;
+ pco_cl_map_entry *map_entry;
+ guint16 roi[4];
+ guint16 camera_type;
+ guint16 camera_subtype;
- self->priv->delay_timebase = TIMEBASE_INVALID;
- self->priv->exposure_timebase = TIMEBASE_INVALID;
+ priv->pco = pco_init();
- camera = UCA_CAMERA (self);
- uca_camera_register_unit (camera, "sensor-width-extended", UCA_UNIT_PIXEL);
- uca_camera_register_unit (camera, "sensor-height-extended", UCA_UNIT_PIXEL);
- uca_camera_register_unit (camera, "sensor-temperature", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point-min", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point-max", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "cooling-point-default", UCA_UNIT_DEGREE_CELSIUS);
- uca_camera_register_unit (camera, "sensor-adcs", UCA_UNIT_COUNT);
- uca_camera_register_unit (camera, "sensor-max-adcs", UCA_UNIT_COUNT);
- uca_camera_register_unit (camera, "delay-time", UCA_UNIT_SECOND);
-}
+ if (priv->pco == NULL) {
+ g_set_error (&priv->construct_error,
+ UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT,
+ "Initializing libpco failed");
+ return FALSE;
+ }
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
-{
- pco_handle pco = pco_init();
+ pco_get_camera_type (priv->pco, &camera_type, &camera_subtype);
+ map_entry = get_pco_cl_map_entry (camera_type);
- if (pco == NULL) {
- g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT,
- "Initializing libpco failed");
- return NULL;
+ if (map_entry == NULL) {
+ g_set_error (&priv->construct_error,
+ UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED,
+ "Camera type is not supported");
+ return FALSE;
}
- UcaPcoCamera *camera = g_object_new(UCA_TYPE_PCO_CAMERA, NULL);
- UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera);
- priv->pco = pco;
+ priv->description = map_entry;
- pco_get_active_segment(priv->pco, &priv->active_segment);
- pco_get_resolution(priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex);
- pco_get_binning(priv->pco, &priv->binning_h, &priv->binning_v);
- pco_set_storage_mode(pco, STORAGE_MODE_RECORDER);
- pco_set_auto_transfer(pco, 1);
+ pco_get_active_segment (priv->pco, &priv->active_segment);
+ pco_get_resolution (priv->pco, &priv->width, &priv->height, &priv->width_ex, &priv->height_ex);
+ pco_get_binning (priv->pco, &priv->binning_h, &priv->binning_v);
+ pco_set_storage_mode (priv->pco, STORAGE_MODE_RECORDER);
+ pco_set_auto_transfer (priv->pco, 1);
- guint16 roi[4];
- pco_get_roi(priv->pco, roi);
- pco_get_roi_steps(priv->pco, &priv->roi_horizontal_steps, &priv->roi_vertical_steps);
+ pco_get_roi (priv->pco, roi);
+ pco_get_roi_steps (priv->pco, &priv->roi_horizontal_steps, &priv->roi_vertical_steps);
priv->roi_x = roi[0] - 1;
priv->roi_y = roi[1] - 1;
@@ -1450,61 +1472,103 @@ uca_camera_impl_new (GError **error)
priv->roi_height = roi[3] - roi[1] + 1;
priv->num_recorded_images = 0;
- guint16 camera_type, camera_subtype;
- pco_get_camera_type(priv->pco, &camera_type, &camera_subtype);
- pco_cl_map_entry *map_entry = get_pco_cl_map_entry(camera_type);
- priv->camera_description = map_entry;
+ return TRUE;
+}
- if (map_entry == NULL) {
- g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED,
- "Camera type is not supported");
- g_object_unref(camera);
- return NULL;
- }
+static gboolean
+setup_frame_grabber (UcaPcoCameraPrivate *priv)
+{
+ guint32 fg_width;
+ guint32 fg_height;
+ int val;
priv->fg_port = PORT_A;
- priv->fg = Fg_Init(map_entry->so_file, priv->fg_port);
+ priv->fg = Fg_Init (priv->description->so_file, priv->fg_port);
if (priv->fg == NULL) {
- 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;
+ g_set_error (&priv->construct_error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_FG_INIT,
+ "%s", Fg_getLastErrorDescription(priv->fg));
+ return FALSE;
}
- const guint32 fg_height = priv->height;
- const guint32 fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width;
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_CAMERA_LINK_CAMTYP, &priv->description->cl_type, priv->fg_port);
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_FORMAT, &priv->description->cl_format, priv->fg_port);
- FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port);
- FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &map_entry->cl_format, priv->fg_port);
- FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &fg_width, priv->fg_port);
- FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &fg_height, priv->fg_port);
+ fg_width = priv->description->type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width;
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_WIDTH, &fg_width, priv->fg_port);
- int val = FREE_RUN;
- FG_TRY_PARAM(priv->fg, camera, FG_TRIGGERMODE, &val, priv->fg_port);
+ fg_height = priv->height;
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_HEIGHT, &fg_height, priv->fg_port);
- fill_binnings(priv);
+ val = FREE_RUN;
+ FG_TRY_PARAM (priv->fg, &priv->construct_error, FG_TRIGGERMODE, &val, priv->fg_port);
- /*
- * Here we override property ranges because we didn't know them at property
- * installation time.
- */
- GObjectClass *camera_class = G_OBJECT_CLASS (UCA_CAMERA_GET_CLASS (camera));
- property_override_default_guint_value (camera_class, "roi-width", priv->width);
- property_override_default_guint_value (camera_class, "roi-height", priv->height);
+ return TRUE;
+}
+
+static void
+override_property_ranges (UcaPcoCamera *camera)
+{
+ UcaPcoCameraPrivate *priv;
+ GObjectClass *oclass;
+
+ priv = UCA_PCO_CAMERA_GET_PRIVATE (camera);
+ oclass = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera));
+ property_override_default_guint_value (oclass, "roi-width", priv->width);
+ property_override_default_guint_value (oclass, "roi-height", priv->height);
guint32 rates[4] = {0};
gint num_rates = 0;
- if (pco_get_available_pixelrates(priv->pco, rates, &num_rates) == PCO_NOERROR) {
- GObjectClass *pco_camera_class = G_OBJECT_CLASS (UCA_PCO_CAMERA_GET_CLASS (camera));
-
- fill_pixelrates(priv, rates, num_rates);
- property_override_default_guint_value (pco_camera_class, "sensor-pixelrate", rates[0]);
+ if (pco_get_available_pixelrates (priv->pco, rates, &num_rates) == PCO_NOERROR) {
+ fill_pixelrates (priv, rates, num_rates);
+ property_override_default_guint_value (oclass, "sensor-pixelrate", rates[0]);
}
override_temperature_range (priv);
override_maximum_adcs (priv);
+}
+
+static void
+uca_pco_camera_init (UcaPcoCamera *self)
+{
+ UcaCamera *camera;
+ UcaPcoCameraPrivate *priv;
+
+ self->priv = priv = UCA_PCO_CAMERA_GET_PRIVATE (self);
- return UCA_CAMERA (camera);
+ priv->fg_mem = NULL;
+ priv->description = NULL;
+ priv->last_frame = 0;
+ priv->grab_buffer = NULL;
+ priv->construct_error = NULL;
+ priv->delay_timebase = TIMEBASE_INVALID;
+ priv->exposure_timebase = TIMEBASE_INVALID;
+
+ if (!setup_pco_camera (priv))
+ return;
+
+ if (!setup_frame_grabber (priv))
+ return;
+
+ fill_binnings (priv);
+ override_property_ranges (self);
+
+ camera = UCA_CAMERA (self);
+ uca_camera_register_unit (camera, "sensor-width-extended", UCA_UNIT_PIXEL);
+ uca_camera_register_unit (camera, "sensor-height-extended", UCA_UNIT_PIXEL);
+ uca_camera_register_unit (camera, "sensor-temperature", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point-min", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point-max", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "cooling-point-default", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "sensor-adcs", UCA_UNIT_COUNT);
+ uca_camera_register_unit (camera, "sensor-max-adcs", UCA_UNIT_COUNT);
+ uca_camera_register_unit (camera, "delay-time", UCA_UNIT_SECOND);
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
+{
+ return UCA_TYPE_PCO_CAMERA;
}
diff --git a/plugins/pco/uca-pco-camera.h b/plugins/pco/uca-pco-camera.h
index d134fb1..347c27c 100644
--- a/plugins/pco/uca-pco-camera.h
+++ b/plugins/pco/uca-pco-camera.h
@@ -57,8 +57,8 @@ typedef enum {
typedef enum {
UCA_PCO_CAMERA_TIMESTAMP_NONE,
UCA_PCO_CAMERA_TIMESTAMP_BINARY,
- UCA_PCO_CAMERA_TIMESTAMP_ASCII,
- UCA_PCO_CAMERA_TIMESTAMP_BOTH
+ UCA_PCO_CAMERA_TIMESTAMP_BOTH,
+ UCA_PCO_CAMERA_TIMESTAMP_ASCII
} UcaPcoCameraTimestamp;
/**
diff --git a/plugins/pf/uca-pf-camera.c b/plugins/pf/uca-pf-camera.c
index 473ffd3..b7967be 100644
--- a/plugins/pf/uca-pf-camera.c
+++ b/plugins/pf/uca-pf-camera.c
@@ -15,6 +15,7 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+#include <gio/gio.h>
#include <gmodule.h>
#include <stdlib.h>
#include <stdio.h>
@@ -32,7 +33,6 @@
g_set_error(error, UCA_PF_CAMERA_ERROR, \
UCA_PF_CAMERA_ERROR_FG_GENERAL, \
"%s", Fg_getLastErrorDescription(fg)); \
- g_object_unref(camobj); \
return NULL; \
} }
@@ -46,7 +46,11 @@
#define UCA_PF_CAMERA_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UCA_TYPE_PF_CAMERA, UcaPfCameraPrivate))
-G_DEFINE_TYPE(UcaPfCamera, uca_pf_camera, UCA_TYPE_CAMERA)
+static void uca_pf_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaPfCamera, uca_pf_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_pf_camera_initable_iface_init))
/**
* UcaPfCameraError:
@@ -91,6 +95,7 @@ enum {
struct _UcaPfCameraPrivate {
+ GError *construct_error;
guint roi_width;
guint roi_height;
guint last_frame;
@@ -107,7 +112,8 @@ struct {
UcaCamera *camera;
} fg_apc_data;
-static int me4_callback(frameindex_t frame, struct fg_apc_data *apc)
+static int
+me4_callback(frameindex_t frame, struct fg_apc_data *apc)
{
UcaCamera *camera = UCA_CAMERA(apc);
UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
@@ -115,7 +121,8 @@ static int me4_callback(frameindex_t frame, struct fg_apc_data *apc)
return 0;
}
-static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
+static void
+uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_PF_CAMERA(camera));
UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
@@ -155,7 +162,8 @@ static void uca_pf_camera_start_recording(UcaCamera *camera, GError **error)
FG_SET_ERROR(err, priv->fg, UCA_PF_CAMERA_ERROR_FG_ACQUISITION);
}
-static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
+static void
+uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_PF_CAMERA(camera));
UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
@@ -168,34 +176,39 @@ static void uca_pf_camera_stop_recording(UcaCamera *camera, GError **error)
g_print(" Unable to unblock all\n");
}
-static void uca_pf_camera_start_readout(UcaCamera *camera, GError **error)
+static void
+uca_pf_camera_start_readout(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_PF_CAMERA(camera));
g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NOT_IMPLEMENTED,
"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 uca_pf_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+static void
+uca_pf_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
switch (property_id) {
default:
@@ -204,7 +217,8 @@ static void uca_pf_camera_set_property(GObject *object, guint property_id, const
}
}
-static void uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+static void
+uca_pf_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
switch (property_id) {
case PROP_SENSOR_WIDTH:
@@ -263,7 +277,8 @@ static void uca_pf_camera_get_property(GObject *object, guint property_id, GValu
}
}
-static void uca_pf_camera_finalize(GObject *object)
+static void
+uca_pf_camera_finalize(GObject *object)
{
UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(object);
@@ -274,10 +289,54 @@ static void uca_pf_camera_finalize(GObject *object)
Fg_FreeGrabber(priv->fg);
}
+ g_clear_error (&priv->construct_error);
+
G_OBJECT_CLASS(uca_pf_camera_parent_class)->finalize(object);
}
-static void uca_pf_camera_class_init(UcaPfCameraClass *klass)
+static gboolean
+uca_pf_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ UcaPfCamera *camera;
+ UcaPfCameraPrivate *priv;
+
+ g_return_val_if_fail (UCA_IS_PF_CAMERA (initable), FALSE);
+
+ if (cancellable != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ camera = UCA_PF_CAMERA (initable);
+ priv = camera->priv;
+
+ if (priv->construct_error != NULL) {
+ if (error)
+ *error = g_error_copy (priv->construct_error);
+
+ return FALSE;
+ }
+
+ if (priv->fg == NULL) {
+ g_set_error (error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
+ "%s", Fg_getLastErrorDescription (NULL));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+uca_pf_camera_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = uca_pf_camera_initable_init;
+}
+
+static void
+uca_pf_camera_class_init(UcaPfCameraClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = uca_pf_camera_set_property;
@@ -296,57 +355,56 @@ static void uca_pf_camera_class_init(UcaPfCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaPfCameraPrivate));
}
-static void uca_pf_camera_init(UcaPfCamera *self)
+static gboolean
+try_fg_param (UcaPfCameraPrivate *priv,
+ int param,
+ const gpointer value)
{
- self->priv = UCA_PF_CAMERA_GET_PRIVATE(self);
- self->priv->fg = NULL;
- self->priv->fg_mem = NULL;
- self->priv->last_frame = 0;
+ if (Fg_setParameter (priv->fg, param, value, priv->fg_port) != FG_OK) {
+ g_set_error (&priv->construct_error, UCA_PF_CAMERA_ERROR,
+ UCA_PF_CAMERA_ERROR_FG_GENERAL,
+ "%s", Fg_getLastErrorDescription (priv->fg));
+ return FALSE;
+ }
+
+ return TRUE;
}
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+static void
+uca_pf_camera_init (UcaPfCamera *self)
{
+ UcaPfCameraPrivate *priv;
static const gchar *so_file = "libFullAreaGray8.so";
- static const int camera_link_type = FG_CL_8BIT_FULL_8;
- static const int camera_format = FG_GRAY;
-
- /*
- gint num_ports;
- if (pfPortInit(&num_ports) < 0) {
- g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
- "Could not initialize ports");
- return NULL;
- }
-
- if (pfDeviceOpen(0) < 0) {
- g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
- "Could not open device");
- return NULL;
- }
- */
+ static const int link_type = FG_CL_8BIT_FULL_8;
+ static const int format = FG_GRAY;
- UcaPfCamera *camera = g_object_new(UCA_TYPE_PF_CAMERA, NULL);
- UcaPfCameraPrivate *priv = UCA_PF_CAMERA_GET_PRIVATE(camera);
+ self->priv = priv = UCA_PF_CAMERA_GET_PRIVATE(self);
+ priv->construct_error = NULL;
priv->fg_port = PORT_A;
- priv->fg = Fg_Init(so_file, priv->fg_port);
-
- /* TODO: get this from the camera */
+ priv->fg = Fg_Init (so_file, priv->fg_port);
+ priv->fg_mem = NULL;
+ priv->last_frame = 0;
priv->roi_width = 1280;
priv->roi_height = 1024;
- if (priv->fg == NULL) {
- g_set_error(error, UCA_PF_CAMERA_ERROR, UCA_PF_CAMERA_ERROR_INIT,
- "%s", Fg_getLastErrorDescription(priv->fg));
- g_object_unref(camera);
- return NULL;
- }
+ if (priv->fg != NULL) {
+ if (!try_fg_param (priv, FG_CAMERA_LINK_CAMTYP, (const gpointer) &link_type))
+ return;
- FG_TRY_PARAM(priv->fg, camera, FG_CAMERA_LINK_CAMTYP, &camera_link_type, priv->fg_port);
- FG_TRY_PARAM(priv->fg, camera, FG_FORMAT, &camera_format, priv->fg_port);
- FG_TRY_PARAM(priv->fg, camera, FG_WIDTH, &priv->roi_width, priv->fg_port);
- FG_TRY_PARAM(priv->fg, camera, FG_HEIGHT, &priv->roi_height, priv->fg_port);
+ if (!try_fg_param (priv, FG_FORMAT, (const gpointer) &format))
+ return;
- return UCA_CAMERA (camera);
+ if (!try_fg_param (priv, FG_WIDTH, &priv->roi_width))
+ return;
+
+ if (!try_fg_param (priv, FG_HEIGHT, &priv->roi_height))
+ return;
+ }
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
+{
+ return UCA_TYPE_PF_CAMERA;
}
diff --git a/plugins/ufo/uca-ufo-camera.c b/plugins/ufo/uca-ufo-camera.c
index c4e05b0..145c2ee 100644
--- a/plugins/ufo/uca-ufo-camera.c
+++ b/plugins/ufo/uca-ufo-camera.c
@@ -15,6 +15,7 @@
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110, USA */
+#include <gio/gio.h>
#include <gmodule.h>
#include <stdlib.h>
#include <stdio.h>
@@ -33,9 +34,22 @@
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))
-G_DEFINE_TYPE(UcaUfoCamera, uca_ufo_camera, UCA_TYPE_CAMERA)
+static void uca_ufo_camera_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (UcaUfoCamera, uca_ufo_camera, UCA_TYPE_CAMERA,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ uca_ufo_camera_initable_iface_init))
static const guint SENSOR_WIDTH = 2048;
static const guint SENSOR_HEIGHT = 1088;
@@ -80,7 +94,6 @@ static gint base_overrideables[] = {
PROP_ROI_HEIGHT_MULTIPLIER,
PROP_HAS_STREAMING,
PROP_HAS_CAMRAM_RECORDING,
- PROP_TRIGGER_MODE,
0,
};
@@ -92,9 +105,11 @@ typedef struct _RegisterInfo {
static GParamSpec *ufo_properties[N_MAX_PROPERTIES] = { NULL, };
static guint N_PROPERTIES;
-static GHashTable *ufo_property_table; /* maps from prop_id to RegisterInfo* */
struct _UcaUfoCameraPrivate {
+ GError *construct_error;
+ GHashTable *property_table; /* maps from prop_id to RegisterInfo* */
+ GThread *async_thread;
pcilib_t *handle;
pcilib_timeout_t timeout;
guint n_bits;
@@ -102,7 +117,6 @@ struct _UcaUfoCameraPrivate {
FPGA_48MHZ = 0,
FPGA_40MHZ
} frequency;
- UcaCameraTrigger trigger;
};
static void
@@ -126,7 +140,8 @@ read_register_value (pcilib_t *handle, const gchar *name)
return (guint) reg_value;
}
-static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user)
+static int
+event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user)
{
UcaCamera *camera = UCA_CAMERA(user);
UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
@@ -134,47 +149,32 @@ static int event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info,
void *buffer = pcilib_get_data(priv->handle, event_id, PCILIB_EVENT_DATA, &error);
- if (buffer == NULL) {
- pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
+ if (buffer == NULL)
return PCILIB_STREAMING_CONTINUE;
- }
- camera->grab_func(buffer, camera->user_data);
- pcilib_return_data(priv->handle, event_id, PCILIB_EVENT_DATA, buffer);
- pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
+ camera->grab_func (buffer, camera->user_data);
+ pcilib_return_data (priv->handle, event_id, PCILIB_EVENT_DATA, buffer);
return PCILIB_STREAMING_CONTINUE;
}
-G_MODULE_EXPORT UcaCamera *
-uca_camera_impl_new (GError **error)
+static guint
+update_properties (UcaUfoCameraPrivate *priv)
{
- pcilib_model_t model = PCILIB_MODEL_DETECT;
- pcilib_model_description_t *model_description;
- pcilib_t *handle = pcilib_open("/dev/fpga0", model);
- guint prop = PROP_UFO_START;
- guint adc_resolution;
-
- if (handle == NULL) {
- g_set_error(error, UCA_UFO_CAMERA_ERROR, UCA_UFO_CAMERA_ERROR_INIT,
- "Initializing pcilib failed");
- return NULL;
- }
+ guint prop;
+ pcilib_model_description_t *description;
- pcilib_set_error_handler(&error_handler, &error_handler);
+ prop = PROP_UFO_START;
+ description = pcilib_get_model_description (priv->handle);
- /* Generate properties from model description */
- model_description = pcilib_get_model_description(handle);
- ufo_property_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
-
- for (guint i = 0; model_description->registers[i].name != NULL; i++) {
+ for (guint i = 0; description->registers[i].name != NULL; i++) {
GParamFlags flags = 0;
RegisterInfo *reg_info;
gchar *prop_name;
pcilib_register_description_t *reg;
pcilib_register_value_t value;
- reg = &model_description->registers[i];
+ reg = &description->registers[i];
switch (reg->mode) {
case PCILIB_REGISTER_R:
@@ -190,12 +190,12 @@ uca_camera_impl_new (GError **error)
break;
}
- pcilib_read_register (handle, NULL, reg->name, &value);
+ pcilib_read_register (priv->handle, NULL, reg->name, &value);
reg_info = g_new0 (RegisterInfo, 1);
reg_info->name = g_strdup (reg->name);
reg_info->cached_value = (guint32) value;
- g_hash_table_insert (ufo_property_table, GINT_TO_POINTER (prop), reg_info);
+ g_hash_table_insert (priv->property_table, GINT_TO_POINTER (prop), reg_info);
prop_name = g_strdup_printf ("ufo-%s", reg->name);
ufo_properties[prop++] = g_param_spec_uint (
@@ -205,13 +205,32 @@ uca_camera_impl_new (GError **error)
g_free (prop_name);
}
- N_PROPERTIES = prop;
+ return prop;
+}
- UcaUfoCamera *camera = g_object_new(UCA_TYPE_UFO_CAMERA, NULL);
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+static gboolean
+setup_pcilib (UcaUfoCameraPrivate *priv)
+{
+ pcilib_model_t model;
+ guint adc_resolution;
+
+ model = PCILIB_MODEL_DETECT;
+ priv->handle = pcilib_open("/dev/fpga0", model);
- priv->frequency = read_register_value (handle, "bit_mode");
- adc_resolution = read_register_value (handle, "adc_resolution");
+ if (priv->handle == NULL) {
+ g_set_error (&priv->construct_error,
+ UCA_UFO_CAMERA_ERROR, UCA_UFO_CAMERA_ERROR_INIT,
+ "Initializing pcilib failed");
+ return FALSE;
+ }
+
+ pcilib_set_error_handler (&error_handler, &error_handler);
+
+ priv->property_table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_free);
+ N_PROPERTIES = update_properties (priv);
+ priv->frequency = read_register_value (priv->handle, "bit_mode");
+ adc_resolution = read_register_value (priv->handle, "adc_resolution");
switch (adc_resolution) {
case 0:
@@ -225,59 +244,115 @@ uca_camera_impl_new (GError **error)
break;
}
- priv->handle = handle;
+ return TRUE;
+}
+
+static void
+set_control_bit (UcaUfoCameraPrivate *priv, guint bit, gboolean set)
+{
+ static const gchar *name = "control";
+ pcilib_register_value_t flags;
+ pcilib_register_value_t mask;
+
+ pcilib_read_register (priv->handle, NULL, name, &flags);
+ mask = 1 << bit;
+
+ if (set)
+ flags |= mask;
+ else
+ flags = flags & ~mask;
- return UCA_CAMERA (camera);
+ pcilib_write_register(priv->handle, NULL, name, flags);
}
-static void uca_ufo_camera_start_recording(UcaCamera *camera, GError **error)
+static void
+set_streaming (UcaUfoCameraPrivate *priv, gboolean enable)
+{
+ set_control_bit (priv, 11, enable);
+}
+
+static gpointer
+stream_async (UcaCamera *camera)
{
UcaUfoCameraPrivate *priv;
+ priv = UCA_UFO_CAMERA_GET_PRIVATE (camera);
+ pcilib_stream (priv->handle, &event_callback, camera);
+
+ return NULL;
+}
+
+static void
+uca_ufo_camera_start_recording(UcaCamera *camera, GError **error)
+{
+ UcaUfoCameraPrivate *priv;
+ UcaCameraTrigger trigger;
gdouble exposure_time;
- int err;
+ gboolean transfer_async;
+ int err;
g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+
+ g_object_get (G_OBJECT(camera),
+ "transfer-asynchronously", &transfer_async,
+ "exposure-time", &exposure_time,
+ "trigger-mode", &trigger,
+ NULL);
+
err = pcilib_start(priv->handle, PCILIB_EVENT_DATA, PCILIB_EVENT_FLAGS_DEFAULT);
PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_START_RECORDING);
- gboolean transfer_async = FALSE;
- g_object_get(G_OBJECT(camera),
- "transfer-asynchronously", &transfer_async,
- "exposure-time", &exposure_time,
- "trigger-mode", &priv->trigger,
- NULL);
+ if (trigger == UCA_CAMERA_TRIGGER_AUTO)
+ set_streaming (priv, TRUE);
priv->timeout = ((pcilib_timeout_t) (exposure_time * 1000 + 50.0) * 1000);
- if (transfer_async) {
- pcilib_trigger(priv->handle, PCILIB_EVENT0, 0, NULL);
- pcilib_stream(priv->handle, &event_callback, camera);
- }
+ if (transfer_async)
+ priv->async_thread = g_thread_create ((GThreadFunc) stream_async, camera, TRUE, error);
}
-static void uca_ufo_camera_stop_recording(UcaCamera *camera, GError **error)
+static void
+uca_ufo_camera_stop_recording(UcaCamera *camera, GError **error)
{
+ UcaUfoCameraPrivate *priv;
+ UcaCameraTrigger trigger;
g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
- int err = pcilib_stop(priv->handle, PCILIB_EVENT_FLAGS_DEFAULT);
- PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_START_RECORDING);
+
+ priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+
+ g_object_get (G_OBJECT (camera), "trigger-mode", &trigger, NULL);
+
+ if (priv->async_thread) {
+ int err = pcilib_stop(priv->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
+ PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_STOP_RECORDING);
+ g_thread_join(priv->async_thread);
+ priv->async_thread = NULL;
+ }
+
+ int err = pcilib_stop (priv->handle, PCILIB_EVENT_FLAGS_DEFAULT);
+ PCILIB_SET_ERROR(err, UCA_UFO_CAMERA_ERROR_STOP_RECORDING);
+
+ if (trigger == UCA_CAMERA_TRIGGER_AUTO)
+ set_streaming (priv, FALSE);
}
-static void uca_ufo_camera_start_readout(UcaCamera *camera, GError **error)
+static void
+uca_ufo_camera_start_readout(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_UFO_CAMERA(camera));
}
-static void uca_ufo_camera_stop_readout(UcaCamera *camera, GError **error)
+static void
+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;
@@ -285,21 +360,13 @@ static void uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **erro
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_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);
-
- if (*data == NULL)
- *data = g_malloc0(SENSOR_WIDTH * SENSOR_HEIGHT * sizeof(guint16));
+ 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);
- 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.
@@ -309,15 +376,29 @@ static void uca_ufo_camera_grab(UcaCamera *camera, gpointer *data, GError **erro
*/
/* 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
+uca_ufo_camera_trigger (UcaCamera *camera, GError **error)
+{
+ UcaUfoCameraPrivate *priv;
+ g_return_if_fail (UCA_IS_UFO_CAMERA(camera));
+
+ priv = UCA_UFO_CAMERA_GET_PRIVATE(camera);
+
+ /* XXX: What is PCILIB_EVENT0? */
+ pcilib_trigger (priv->handle, PCILIB_EVENT0, 0, NULL);
}
static void
@@ -340,19 +421,18 @@ uca_ufo_camera_set_property(GObject *object, guint property_id, const GValue *va
g_debug("ROI feature not implemented yet");
break;
- case PROP_TRIGGER_MODE:
- priv->trigger = g_value_get_enum (value);
- break;
-
default:
{
- RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id));
+ RegisterInfo *reg_info;
+
+ reg_info = g_hash_table_lookup (priv->property_table,
+ GINT_TO_POINTER (property_id));
if (reg_info != NULL) {
pcilib_register_value_t reg_value;
reg_value = g_value_get_uint (value);
- pcilib_write_register(priv->handle, NULL, reg_info->name, reg_value);
+ pcilib_write_register (priv->handle, NULL, reg_info->name, reg_value);
pcilib_read_register (priv->handle, NULL, reg_info->name, &reg_value);
reg_info->cached_value = (guint) reg_value;
}
@@ -441,12 +521,9 @@ uca_ufo_camera_get_property(GObject *object, guint property_id, GValue *value, G
case PROP_NAME:
g_value_set_string(value, "Ufo Camera w/ CMOSIS CMV2000");
break;
- case PROP_TRIGGER_MODE:
- g_value_set_enum (value, priv->trigger);
- break;
default:
{
- RegisterInfo *reg_info = g_hash_table_lookup (ufo_property_table, GINT_TO_POINTER (property_id));
+ RegisterInfo *reg_info = g_hash_table_lookup (priv->property_table, GINT_TO_POINTER (property_id));
if (reg_info != NULL)
g_value_set_uint (value, reg_info->cached_value);
@@ -457,14 +534,56 @@ uca_ufo_camera_get_property(GObject *object, guint property_id, GValue *value, G
}
}
-static void uca_ufo_camera_finalize(GObject *object)
+static void
+uca_ufo_camera_finalize(GObject *object)
{
- UcaUfoCameraPrivate *priv = UCA_UFO_CAMERA_GET_PRIVATE(object);
- pcilib_close(priv->handle);
- G_OBJECT_CLASS(uca_ufo_camera_parent_class)->finalize(object);
+ UcaUfoCameraPrivate *priv;
+
+ priv = UCA_UFO_CAMERA_GET_PRIVATE (object);
+
+ pcilib_close (priv->handle);
+ g_clear_error (&priv->construct_error);
+
+ G_OBJECT_CLASS (uca_ufo_camera_parent_class)->finalize (object);
}
-static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
+static gboolean
+ufo_ufo_camera_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ UcaUfoCamera *camera;
+ UcaUfoCameraPrivate *priv;
+
+ g_return_val_if_fail (UCA_IS_UFO_CAMERA (initable), FALSE);
+
+ if (cancellable != NULL) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ camera = UCA_UFO_CAMERA (initable);
+ priv = camera->priv;
+
+ if (priv->construct_error != NULL) {
+ if (error)
+ *error = g_error_copy (priv->construct_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+uca_ufo_camera_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = ufo_ufo_camera_initable_init;
+}
+
+static void
+uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->set_property = uca_ufo_camera_set_property;
@@ -477,6 +596,7 @@ static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
camera_class->start_readout = uca_ufo_camera_start_readout;
camera_class->stop_readout = uca_ufo_camera_stop_readout;
camera_class->grab = uca_ufo_camera_grab;
+ camera_class->trigger = uca_ufo_camera_trigger;
for (guint i = 0; base_overrideables[i] != 0; i++)
g_object_class_override_property(gobject_class, base_overrideables[i], uca_camera_props[base_overrideables[i]]);
@@ -505,7 +625,26 @@ static void uca_ufo_camera_class_init(UcaUfoCameraClass *klass)
g_type_class_add_private(klass, sizeof(UcaUfoCameraPrivate));
}
-static void uca_ufo_camera_init(UcaUfoCamera *self)
+static void
+uca_ufo_camera_init(UcaUfoCamera *self)
+{
+ UcaCamera *camera;
+ UcaUfoCameraPrivate *priv;
+
+ self->priv = priv = UCA_UFO_CAMERA_GET_PRIVATE(self);
+ priv->construct_error = NULL;
+ priv->async_thread = NULL;
+
+ if (!setup_pcilib (priv))
+ return;
+
+ camera = UCA_CAMERA (self);
+ uca_camera_register_unit (camera, "sensor-temperature", UCA_UNIT_DEGREE_CELSIUS);
+ uca_camera_register_unit (camera, "fpga-temperature", UCA_UNIT_DEGREE_CELSIUS);
+}
+
+G_MODULE_EXPORT GType
+uca_camera_get_type (void)
{
- self->priv = UCA_UFO_CAMERA_GET_PRIVATE(self);
+ return UCA_TYPE_UFO_CAMERA;
}