summaryrefslogtreecommitdiffstats
path: root/ipecamera/events.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-12-12 05:45:35 +0100
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-12-12 05:45:35 +0100
commit2e4e8a00b27182a155cb10f0a00e44977bfcd5cf (patch)
tree86afd1b7ceb834dbb3cedf8d55c3ac0734947333 /ipecamera/events.c
parent7a4cfb9e546c496792d3fe0c61c822c66ad0128f (diff)
downloadipecamera-2e4e8a00b27182a155cb10f0a00e44977bfcd5cf.tar.gz
ipecamera-2e4e8a00b27182a155cb10f0a00e44977bfcd5cf.tar.bz2
ipecamera-2e4e8a00b27182a155cb10f0a00e44977bfcd5cf.tar.xz
ipecamera-2e4e8a00b27182a155cb10f0a00e44977bfcd5cf.zip
multithread preprocessing of ipecamera frames and code reorganization
Diffstat (limited to 'ipecamera/events.c')
-rw-r--r--ipecamera/events.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/ipecamera/events.c b/ipecamera/events.c
new file mode 100644
index 0000000..58d2971
--- /dev/null
+++ b/ipecamera/events.c
@@ -0,0 +1,121 @@
+#define _IPECAMERA_IMAGE_C
+#define _BSD_SOURCE
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include <ufodecode.h>
+
+#include "../tools.h"
+#include "../error.h"
+
+#include "pcilib.h"
+#include "public.h"
+#include "private.h"
+#include "events.h"
+
+int ipecamera_stream(pcilib_context_t *vctx, pcilib_event_callback_t callback, void *user) {
+ int err = 0;
+ int do_stop = 0;
+
+ ipecamera_event_info_t info;
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return PCILIB_ERROR_NOTINITIALIZED;
+ }
+
+ ctx->streaming = 1;
+ ctx->run_streamer = 1;
+
+ if (!ctx->started) {
+ err = ipecamera_start(vctx, PCILIB_EVENTS_ALL, PCILIB_EVENT_FLAGS_DEFAULT);
+ if (err) {
+ ctx->streaming = 0;
+ return err;
+ }
+
+ do_stop = 1;
+ }
+
+ // This loop iterates while the generation
+ while ((ctx->run_streamer)||(ctx->reported_id != ctx->event_id)) {
+ while (ctx->reported_id != ctx->event_id) {
+ if ((ctx->event_id - ctx->reported_id) > (ctx->buffer_size - IPECAMERA_RESERVE_BUFFERS)) ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1) - IPECAMERA_RESERVE_BUFFERS;
+ else ++ctx->reported_id;
+
+ memcpy(&info, ctx->frame + ((ctx->reported_id-1)%ctx->buffer_size), sizeof(ipecamera_event_info_t));
+
+ if ((ctx->event_id - ctx->reported_id) < ctx->buffer_size) {
+ err = callback(ctx->reported_id, (pcilib_event_info_t*)&info, user);
+ if (err <= 0) {
+ if (err < 0) err = -err;
+ break;
+ }
+ }
+ }
+ usleep(IPECAMERA_NOFRAME_SLEEP);
+ }
+
+ ctx->streaming = 0;
+
+ if (do_stop) {
+ ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT);
+ }
+
+
+ return err;
+}
+
+int ipecamera_next_event(pcilib_context_t *vctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, size_t info_size, pcilib_event_info_t *info) {
+ struct timeval tv;
+ ipecamera_t *ctx = (ipecamera_t*)vctx;
+
+ if (!ctx) {
+ pcilib_error("IPECamera imaging is not initialized");
+ return PCILIB_ERROR_NOTINITIALIZED;
+ }
+
+ if (!ctx->started) {
+ pcilib_error("IPECamera is not in grabbing mode");
+ return PCILIB_ERROR_INVALID_REQUEST;
+ }
+
+ if (ctx->reported_id == ctx->event_id) {
+ if (timeout) {
+ pcilib_calc_deadline(&tv, timeout);
+
+ while ((pcilib_calc_time_to_deadline(&tv) > 0)&&(ctx->reported_id == ctx->event_id))
+ usleep(IPECAMERA_NOFRAME_SLEEP);
+ }
+
+ if (ctx->reported_id == ctx->event_id) return PCILIB_ERROR_TIMEOUT;
+ }
+
+retry:
+ if ((ctx->event_id - ctx->reported_id) > (ctx->buffer_size - IPECAMERA_RESERVE_BUFFERS)) ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1) - IPECAMERA_RESERVE_BUFFERS;
+ else ++ctx->reported_id;
+
+ if (evid) *evid = ctx->reported_id;
+
+ if (info) {
+ if (info_size >= sizeof(ipecamera_event_info_t))
+ memcpy(info, ctx->frame + ((ctx->reported_id-1)%ctx->buffer_size), sizeof(ipecamera_event_info_t));
+ else if (info_size >= sizeof(pcilib_event_info_t))
+ memcpy(info, ctx->frame + ((ctx->reported_id-1)%ctx->buffer_size), sizeof(pcilib_event_info_t));
+ else
+ return PCILIB_ERROR_INVALID_ARGUMENT;
+ }
+
+ if ((ctx->event_id - ctx->reported_id) >= ctx->buffer_size) goto retry;
+
+ return 0;
+}
+