summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cameras/uca-mock-camera.c67
-rw-r--r--src/uca-camera.c28
-rw-r--r--src/uca-camera.h7
3 files changed, 97 insertions, 5 deletions
diff --git a/src/cameras/uca-mock-camera.c b/src/cameras/uca-mock-camera.c
index 8dacf5d..b1c325e 100644
--- a/src/cameras/uca-mock-camera.c
+++ b/src/cameras/uca-mock-camera.c
@@ -59,23 +59,84 @@ struct _UcaMockCameraPrivate {
guint framerate;
guint16 *dummy_data;
+ gboolean thread_running;
+
+ GThread *grab_thread;
GValueArray *binnings;
};
+/**
+ * uca_mock_camera_new:
+ * @error: Location for error
+ *
+ * Create a new #UcaMockCamera object.
+ *
+ * Returns: A newly created #UcaMockCamera object
+ */
UcaMockCamera *uca_mock_camera_new(GError **error)
{
UcaMockCamera *camera = g_object_new(UCA_TYPE_MOCK_CAMERA, NULL);
return camera;
}
+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);
+
+ UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(mock_camera);
+ UcaCamera *camera = UCA_CAMERA(mock_camera);
+ const gulong sleep_time = G_USEC_PER_SEC / priv->framerate;
+
+ while (priv->thread_running) {
+ camera->grab_func(NULL, camera->user_data);
+ g_usleep(sleep_time);
+ }
+
+ return NULL;
+}
+
static void uca_mock_camera_start_recording(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_MOCK_CAMERA(camera));
+
+ /*
+ * In case asynchronous transfer is requested, we start a new thread that
+ * invokes the grab callback, otherwise nothing will be done here.
+ */
+
+ UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera);
+ gboolean transfer_async = FALSE;
+ g_object_get(G_OBJECT(camera),
+ "transfer-asynchronously", &transfer_async,
+ NULL);
+
+ if (transfer_async) {
+ GError *tmp_error = NULL;
+ priv->thread_running = TRUE;
+ priv->grab_thread = g_thread_create(mock_grab_func, camera, TRUE, &tmp_error);
+
+ if (tmp_error != NULL) {
+ priv->thread_running = FALSE;
+ g_propagate_error(error, tmp_error);
+ }
+ }
}
static void uca_mock_camera_stop_recording(UcaCamera *camera, GError **error)
{
g_return_if_fail(UCA_IS_MOCK_CAMERA(camera));
+
+ UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(camera);
+ gboolean transfer_async = FALSE;
+ g_object_get(G_OBJECT(camera),
+ "transfer-asynchronously", &transfer_async,
+ NULL);
+
+ if (transfer_async) {
+ priv->thread_running = FALSE;
+ g_thread_join(priv->grab_thread);
+ }
}
static void uca_mock_camera_grab(UcaCamera *camera, gpointer data, GError **error)
@@ -145,6 +206,11 @@ static void uca_mock_camera_finalize(GObject *object)
{
UcaMockCameraPrivate *priv = UCA_MOCK_CAMERA_GET_PRIVATE(object);
+ if (priv->thread_running) {
+ priv->thread_running = FALSE;
+ g_thread_join(priv->grab_thread);
+ }
+
g_free(priv->dummy_data);
g_value_array_free(priv->binnings);
@@ -185,6 +251,7 @@ static void uca_mock_camera_init(UcaMockCamera *self)
self->priv->width = 640;
self->priv->height = 480;
self->priv->dummy_data = (guint16 *) g_malloc0(self->priv->width * self->priv->height);
+ self->priv->grab_thread = NULL;
self->priv->binnings = g_value_array_new(1);
GValue val = {0};
diff --git a/src/uca-camera.c b/src/uca-camera.c
index 88b6ddd..ac04b86 100644
--- a/src/uca-camera.c
+++ b/src/uca-camera.c
@@ -64,7 +64,16 @@ static GParamSpec *camera_properties[N_PROPERTIES] = { NULL, };
static void uca_camera_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ UcaCameraPrivate *priv = UCA_CAMERA_GET_PRIVATE(object);
+
+ switch (property_id) {
+ case PROP_TRANSFER_ASYNCHRONOUSLY:
+ priv->transfer_async = g_value_get_boolean(value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ }
}
static void uca_camera_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
@@ -76,6 +85,10 @@ static void uca_camera_get_property(GObject *object, guint property_id, GValue *
g_value_set_boolean(value, priv->is_recording);
break;
+ case PROP_TRANSFER_ASYNCHRONOUSLY:
+ g_value_set_boolean(value, priv->transfer_async);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
}
@@ -180,6 +193,8 @@ static void uca_camera_class_init(UcaCameraClass *klass)
static void uca_camera_init(UcaCamera *camera)
{
+ camera->grab_func = NULL;
+
camera->priv = UCA_CAMERA_GET_PRIVATE(camera);
camera->priv->is_recording = FALSE;
camera->priv->transfer_async = FALSE;
@@ -230,6 +245,12 @@ void uca_camera_start_recording(UcaCamera *camera, GError **error)
return;
}
+ if (camera->priv->transfer_async && (camera->grab_func == NULL)) {
+ g_set_error(error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NO_GRAB_FUNC,
+ "No grab callback function set");
+ return;
+ }
+
GError *tmp_error = NULL;
(*klass->start_recording)(camera, &tmp_error);
@@ -280,9 +301,10 @@ void uca_camera_stop_recording(UcaCamera *camera, GError **error)
*
* Set the grab function that is called whenever a frame is readily transfered.
*/
-void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func)
+void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data)
{
- /* TODO: implement */
+ camera->grab_func = func;
+ camera->user_data = user_data;
}
void uca_camera_grab(UcaCamera *camera, gpointer data, GError **error)
diff --git a/src/uca-camera.h b/src/uca-camera.h
index dc5901a..0370466 100644
--- a/src/uca-camera.h
+++ b/src/uca-camera.h
@@ -30,7 +30,8 @@
#define UCA_CAMERA_ERROR uca_camera_error_quark()
typedef enum {
UCA_CAMERA_ERROR_RECORDING,
- UCA_CAMERA_ERROR_NOT_RECORDING
+ UCA_CAMERA_ERROR_NOT_RECORDING,
+ UCA_CAMERA_ERROR_NO_GRAB_FUNC
} UcaCameraError;
typedef struct _UcaCamera UcaCamera;
@@ -51,6 +52,8 @@ struct _UcaCamera {
GObject parent;
UcaCameraGrabFunc grab_func;
+ gpointer user_data;
+
UcaCameraPrivate *priv;
};
@@ -74,7 +77,7 @@ struct _UcaCameraClass {
void uca_camera_start_recording(UcaCamera *camera, GError **error);
void uca_camera_stop_recording(UcaCamera *camera, GError **error);
void uca_camera_grab(UcaCamera *camera, gpointer data, GError **error);
-void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func);
+void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data);
GType uca_camera_get_type(void);