diff options
Diffstat (limited to 'src/cameras')
-rw-r--r-- | src/cameras/uca-mock-camera.c | 12 | ||||
-rw-r--r-- | src/cameras/uca-pco-camera.c | 153 | ||||
-rw-r--r-- | src/cameras/uca-pco-camera.h | 8 |
3 files changed, 156 insertions, 17 deletions
diff --git a/src/cameras/uca-mock-camera.c b/src/cameras/uca-mock-camera.c index feae389..ba92a67 100644 --- a/src/cameras/uca-mock-camera.c +++ b/src/cameras/uca-mock-camera.c @@ -30,6 +30,8 @@ enum { PROP_0, PROP_SENSOR_WIDTH, PROP_SENSOR_HEIGHT, + N_INTERFACE_PROPERTIES, + N_PROPERTIES }; @@ -44,19 +46,19 @@ struct _UcaMockCameraPrivate { guint16 *dummy_data; }; -static void uca_mock_camera_start_recording(UcaCamera *camera) +static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); g_print("start recording\n"); } -static void uca_mock_camera_stop_recording(UcaCamera *camera) +static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); g_print("stop recording\n"); } -static void uca_mock_camera_grab(UcaCamera *camera, gchar *data) +static void uca_mock_camera_grab(UcaCamera *camera, gchar *data, GError **error) { g_return_if_fail(UCA_IS_MOCK_CAMERA(camera)); /* g_memmove(data, camera->priv->dummy_data, camera->priv->width * camera->priv->height * 2); */ @@ -110,8 +112,8 @@ static void uca_mock_camera_class_init(UcaMockCameraClass *klass) gobject_class->get_property = uca_mock_camera_get_property; gobject_class->finalize = uca_mock_camera_finalize; - for (guint property_id = PROP_0+1; property_id < N_PROPERTIES; property_id++) - g_object_class_override_property(gobject_class, property_id, mock_overrideables[property_id-1]); + for (guint id = PROP_0 + 1; id < N_INTERFACE_PROPERTIES; id++) + g_object_class_override_property(gobject_class, id, mock_overrideables[id-1]); g_type_class_add_private(klass, sizeof(UcaMockCameraPrivate)); } diff --git a/src/cameras/uca-pco-camera.c b/src/cameras/uca-pco-camera.c index 9ca52cf..332d3ea 100644 --- a/src/cameras/uca-pco-camera.c +++ b/src/cameras/uca-pco-camera.c @@ -18,6 +18,8 @@ #include <stdlib.h> #include <libpco/libpco.h> #include <libpco/sc2_defs.h> +#include <fgrab_struct.h> +#include <fgrab_prototyp.h> #include "uca-camera.h" #include "uca-pco-camera.h" @@ -29,47 +31,147 @@ G_DEFINE_TYPE_WITH_CODE(UcaPcoCamera, uca_pco_camera, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(UCA_TYPE_CAMERA, uca_pco_camera_interface_init)); +/** + * UcaPcoCameraError: + * @UCA_PCO_CAMERA_ERROR_LIBPCO_INIT: Initializing libpco failed + * @UCA_PCO_CAMERA_ERROR_UNSUPPORTED: Camera type is not supported + * @UCA_PCO_CAMERA_ERROR_FG_INIT: Framegrabber initialization failed + * @UCA_PCO_CAMERA_ERROR_FG_ERROR: Framegrabber error + */ +GQuark uca_pco_camera_error_quark() +{ + return g_quark_from_static_string("uca-pco-camera-error-quark"); +} + enum { PROP_0, PROP_SENSOR_WIDTH, PROP_SENSOR_HEIGHT, + PROP_SENSOR_BITDEPTH, + N_INTERFACE_PROPERTIES, + + PROP_NAME, N_PROPERTIES }; static const gchar *pco_overrideables[N_PROPERTIES] = { "sensor-width", - "sensor-height" + "sensor-height", + "sensor-bitdepth" +}; + +static GParamSpec *pco_properties[N_PROPERTIES - N_INTERFACE_PROPERTIES - 1] = { NULL, }; + +typedef struct { + int camera_type; + const char *so_file; + int cl_type; + int cl_format; +} pco_cl_map_entry; + +static pco_cl_map_entry pco_cl_map[] = { + { CAMERATYPE_PCO_EDGE, "libFullAreaGray8.so", FG_CL_8BIT_FULL_10, FG_GRAY }, + { CAMERATYPE_PCO4000, "libDualAreaGray16.so", FG_CL_SINGLETAP_16_BIT, FG_GRAY16 }, + { CAMERATYPE_PCO_DIMAX_STD, "libFullAreaGray16.so", FG_CL_SINGLETAP_8_BIT, FG_GRAY16 }, + { 0, NULL, 0, 0} }; +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) + return entry; + entry++; + } + return NULL; +} + struct _UcaPcoCameraPrivate { pco_handle pco; + + Fg_Struct *fg; + guint fg_port; + dma_mem *fg_mem; + + guint16 width; + guint16 height; }; UcaPcoCamera *uca_pco_camera_new(GError **error) { + /* TODO: find a good way to handle libpco and fg errors */ pco_handle pco = pco_init(); if (pco == NULL) { - /* TODO: throw error */ + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, + "Initializing libpco failed"); return NULL; } UcaPcoCamera *camera = g_object_new(UCA_TYPE_PCO_CAMERA, NULL); - camera->priv->pco = pco; + UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(camera); + priv->pco = pco; + + 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); + + 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; + } + + priv->fg_port = PORT_A; + priv->fg = Fg_Init(map_entry->so_file, priv->fg_port); + + if (priv->fg == NULL) { + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + "Initializing framegrabber failed"); + g_object_unref(camera); + return NULL; + } + + guint16 width_ex, height_ex; + pco_get_resolution(priv->pco, &priv->width, &priv->height, &width_ex, &height_ex); + const guint num_buffers = 2; + guint fg_width = camera_type == CAMERATYPE_PCO_EDGE ? priv->width * 2 : priv->width; + priv->fg_mem = Fg_AllocMemEx(priv->fg, fg_width * priv->height * sizeof(uint16_t), num_buffers); + + if (priv->fg_mem == NULL) { + g_set_error(error, UCA_PCO_CAMERA_ERROR, UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + "Framegrabber could not allocate DMA buffers"); + g_object_unref(camera); + return NULL; + } + + Fg_setParameter(priv->fg, FG_CAMERA_LINK_CAMTYP, &map_entry->cl_type, priv->fg_port); + Fg_setParameter(priv->fg, FG_FORMAT, &map_entry->cl_format, priv->fg_port); + Fg_setParameter(priv->fg, FG_WIDTH, &fg_width, priv->fg_port); + Fg_setParameter(priv->fg, FG_HEIGHT, &priv->height, priv->fg_port); + + int val = FREE_RUN; + Fg_setParameter(priv->fg, FG_TRIGGERMODE, &val, priv->fg_port); + return camera; } -static void uca_pco_camera_start_recording(UcaCamera *camera) +static void uca_pco_camera_start_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); + pco_start_recording(UCA_PCO_CAMERA_GET_PRIVATE(camera)->pco); } -static void uca_pco_camera_stop_recording(UcaCamera *camera) +static void uca_pco_camera_stop_recording(UcaCamera *camera, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); + pco_stop_recording(UCA_PCO_CAMERA_GET_PRIVATE(camera)->pco); } -static void uca_pco_camera_grab(UcaCamera *camera, gchar *data) +static void uca_pco_camera_grab(UcaCamera *camera, gchar *data, GError **error) { g_return_if_fail(UCA_IS_PCO_CAMERA(camera)); } @@ -91,10 +193,17 @@ static void uca_pco_camera_get_property(GObject *object, guint property_id, GVal switch (property_id) { case PROP_SENSOR_WIDTH: + g_value_set_uint(value, priv->width); + break; + case PROP_SENSOR_HEIGHT: + g_value_set_uint(value, priv->height); + break; + case PROP_NAME: { - uint16_t width_std, height_std, width_ex, height_ex; - if (pco_get_resolution(priv->pco, &width_std, &height_std, &width_ex, &height_ex) == PCO_NOERROR) - g_value_set_uint(value, width_std); + char *name = NULL; + pco_get_name(priv->pco, &name); + g_value_set_string(value, name); + free(name); } break; default: @@ -107,7 +216,15 @@ static void uca_pco_camera_finalize(GObject *object) { UcaPcoCameraPrivate *priv = UCA_PCO_CAMERA_GET_PRIVATE(object); - pco_destroy(priv->pco); + if (priv->fg) { + if (priv->fg_mem) + Fg_FreeMemEx(priv->fg, priv->fg_mem); + + Fg_FreeGrabber(priv->fg); + } + + if (priv->pco) + pco_destroy(priv->pco); G_OBJECT_CLASS(uca_pco_camera_parent_class)->finalize(object); } @@ -126,8 +243,17 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) gobject_class->get_property = uca_pco_camera_get_property; gobject_class->finalize = uca_pco_camera_finalize; - for (guint property_id = PROP_0+1; property_id < N_PROPERTIES; property_id++) - g_object_class_override_property(gobject_class, property_id, pco_overrideables[property_id-1]); + for (guint id = PROP_0 + 1; id < N_INTERFACE_PROPERTIES; id++) + g_object_class_override_property(gobject_class, id, pco_overrideables[id-1]); + + pco_properties[PROP_NAME] = + g_param_spec_string("name", + "Name of the camera", + "Name of the camera", + "", G_PARAM_READABLE); + + for (guint id = N_INTERFACE_PROPERTIES + 1; id < N_PROPERTIES; id++) + g_object_class_install_property(gobject_class, id, pco_properties[id]); g_type_class_add_private(klass, sizeof(UcaPcoCameraPrivate)); } @@ -135,4 +261,7 @@ static void uca_pco_camera_class_init(UcaPcoCameraClass *klass) static void uca_pco_camera_init(UcaPcoCamera *self) { self->priv = UCA_PCO_CAMERA_GET_PRIVATE(self); + self->priv->fg = NULL; + self->priv->fg_mem = NULL; + self->priv->pco = NULL; } diff --git a/src/cameras/uca-pco-camera.h b/src/cameras/uca-pco-camera.h index 336cbf6..68e92fa 100644 --- a/src/cameras/uca-pco-camera.h +++ b/src/cameras/uca-pco-camera.h @@ -27,6 +27,14 @@ #define UCA_IS_PCO_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_PCO_CAMERA)) #define UCA_PCO_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_PCO_CAMERA, UcaPcoCameraClass)) +#define UCA_PCO_CAMERA_ERROR uca_pco_camera_error_quark() +typedef enum { + UCA_PCO_CAMERA_ERROR_LIBPCO_INIT, + UCA_PCO_CAMERA_ERROR_UNSUPPORTED, + UCA_PCO_CAMERA_ERROR_FG_INIT, + UCA_PCO_CAMERA_ERROR_FG_ERROR +} UcaPcoCameraError; + typedef struct _UcaPcoCamera UcaPcoCamera; typedef struct _UcaPcoCameraClass UcaPcoCameraClass; typedef struct _UcaPcoCameraPrivate UcaPcoCameraPrivate; |