bzr branch
http://darksoft.org/webbzr/alps/ipecamera
277
by Suren A. Chilingaryan
Build RPM |
1 |
#define _DEFAULT_SOURCE
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
2 |
#define _BSD_SOURCE
|
3 |
#define _GNU_SOURCE
|
|
4 |
||
5 |
#include <stdio.h> |
|
6 |
#include <stdlib.h> |
|
7 |
#include <unistd.h> |
|
8 |
#include <string.h> |
|
9 |
#include <sys/time.h> |
|
10 |
#include <pthread.h> |
|
11 |
#include <assert.h> |
|
12 |
||
13 |
#include <ufodecode.h> |
|
14 |
||
245
by Suren A. Chilingaryan
First stand-alone ipecamera implementation |
15 |
#include <pcilib.h> |
16 |
#include <pcilib/tools.h> |
|
17 |
#include <pcilib/error.h> |
|
276
by Suren A. Chilingaryan
Update to new version of pcitool |
18 |
#include <pcilib/timing.h> |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
19 |
|
245
by Suren A. Chilingaryan
First stand-alone ipecamera implementation |
20 |
#include "ipecamera.h" |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
21 |
#include "private.h" |
22 |
#include "events.h" |
|
23 |
||
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
24 |
#define LOCK(lock_name) \
|
25 |
err = pcilib_lock(ctx->lock_name##_lock); \
|
|
26 |
if (err) { \
|
|
27 |
pcilib_error("IPECamera is busy"); \
|
|
28 |
return PCILIB_ERROR_BUSY; \
|
|
29 |
} \
|
|
30 |
ctx->lock_name##_locked = 1;
|
|
31 |
||
32 |
#define UNLOCK(lock_name) \
|
|
33 |
if (ctx->lock_name##_locked) { \
|
|
34 |
pcilib_unlock(ctx->lock_name##_lock); \
|
|
35 |
ctx->lock_name##_locked = 0; \
|
|
36 |
}
|
|
37 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
38 |
int ipecamera_stream(pcilib_context_t *vctx, pcilib_event_callback_t callback, void *user) { |
132
by Suren A. Chilingaryan
Minor fixes and improvements |
39 |
int run_flag = 1; |
128
by Suren A. Chilingaryan
Fix handling of return values from frame decoder and event callback |
40 |
int res, err = 0; |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
41 |
int do_stop = 0; |
42 |
||
43 |
ipecamera_event_info_t info; |
|
44 |
ipecamera_t *ctx = (ipecamera_t*)vctx; |
|
45 |
||
46 |
if (!ctx) { |
|
47 |
pcilib_error("IPECamera imaging is not initialized"); |
|
48 |
return PCILIB_ERROR_NOTINITIALIZED; |
|
49 |
}
|
|
50 |
||
262
by Suren A. Chilingaryan
Introduce API debugging |
51 |
ipecamera_debug(API, "ipecamera: start streaming"); |
52 |
||
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
53 |
LOCK(stream); |
54 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
55 |
ctx->streaming = 1; |
56 |
ctx->run_streamer = 1; |
|
57 |
||
58 |
if (!ctx->started) { |
|
59 |
err = ipecamera_start(vctx, PCILIB_EVENTS_ALL, PCILIB_EVENT_FLAGS_DEFAULT); |
|
60 |
if (err) { |
|
61 |
ctx->streaming = 0; |
|
62 |
return err; |
|
63 |
}
|
|
64 |
||
65 |
do_stop = 1; |
|
66 |
}
|
|
67 |
||
144
by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode |
68 |
if (ctx->parse_data) { |
69 |
// This loop iterates while the generation
|
|
70 |
while ((run_flag)&&((ctx->run_streamer)||(ctx->reported_id != ctx->event_id))) { |
|
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
71 |
#ifdef IPECAMERA_ANNOUNCE_READY
|
144
by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode |
72 |
while (((!ctx->preproc)&&(ctx->reported_id != ctx->event_id))||((ctx->preproc)&&(ctx->reported_id != ctx->preproc_id))) { |
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
73 |
#else /* IPECAMERA_ANNOUNCE_READY */ |
144
by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode |
74 |
while (ctx->reported_id != ctx->event_id) { |
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
75 |
#endif /* IPECAMERA_ANNOUNCE_READY */ |
270
by Suren A. Chilingaryan
More lost event debugging |
76 |
if ((ctx->event_id - ctx->reported_id) > (ctx->buffer_size - IPECAMERA_RESERVE_BUFFERS)) { |
77 |
ipecamera_debug(HARDWARE, "Skipping events %zu to %zu as preprocessing is too slow. We are currently %zu buffers beyond, but only %zu buffers are available and safety limit is %zu", |
|
78 |
ctx->reported_id, ctx->event_id - (ctx->buffer_size - 1 - IPECAMERA_RESERVE_BUFFERS), ctx->event_id - ctx->reported_id, ctx->buffer_size, IPECAMERA_RESERVE_BUFFERS); |
|
79 |
ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1 - IPECAMERA_RESERVE_BUFFERS); |
|
80 |
} else ++ctx->reported_id; |
|
144
by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode |
81 |
|
82 |
memcpy(&info, ctx->frame + ((ctx->reported_id-1)%ctx->buffer_size), sizeof(ipecamera_event_info_t)); |
|
83 |
||
84 |
if ((ctx->event_id - ctx->reported_id) < ctx->buffer_size) { |
|
85 |
res = callback(ctx->reported_id, (pcilib_event_info_t*)&info, user); |
|
86 |
if (res <= 0) { |
|
87 |
if (res < 0) err = -res; |
|
88 |
run_flag = 0; |
|
89 |
break; |
|
90 |
}
|
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
91 |
}
|
92 |
}
|
|
144
by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode |
93 |
usleep(IPECAMERA_NOFRAME_SLEEP); |
94 |
}
|
|
95 |
} else { |
|
96 |
while ((run_flag)&&(ctx->run_streamer)) { |
|
97 |
usleep(IPECAMERA_NOFRAME_SLEEP); |
|
98 |
}
|
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
99 |
}
|
100 |
||
101 |
ctx->streaming = 0; |
|
102 |
||
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
103 |
UNLOCK(stream); |
104 |
||
262
by Suren A. Chilingaryan
Introduce API debugging |
105 |
ipecamera_debug(API, "ipecamera: streaming finished"); |
106 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
107 |
if (do_stop) { |
108 |
ipecamera_stop(vctx, PCILIB_EVENT_FLAGS_DEFAULT); |
|
109 |
}
|
|
110 |
||
111 |
return err; |
|
112 |
}
|
|
113 |
||
114 |
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) { |
|
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
115 |
int err; |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
116 |
struct timeval tv; |
117 |
ipecamera_t *ctx = (ipecamera_t*)vctx; |
|
118 |
||
119 |
if (!ctx) { |
|
120 |
pcilib_error("IPECamera imaging is not initialized"); |
|
121 |
return PCILIB_ERROR_NOTINITIALIZED; |
|
122 |
}
|
|
123 |
||
124 |
if (!ctx->started) { |
|
125 |
pcilib_error("IPECamera is not in grabbing mode"); |
|
126 |
return PCILIB_ERROR_INVALID_REQUEST; |
|
127 |
}
|
|
144
by Suren A. Chilingaryan
Do not call the normall callback in the raw-data-only mode |
128 |
|
129 |
if (!ctx->parse_data) { |
|
130 |
pcilib_error("RAWData only mode is requested"); |
|
131 |
return PCILIB_ERROR_INVALID_REQUEST; |
|
132 |
}
|
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
133 |
|
262
by Suren A. Chilingaryan
Introduce API debugging |
134 |
ipecamera_debug(API, "ipecamera: next_event"); |
135 |
||
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
136 |
LOCK(stream); |
137 |
||
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
138 |
#ifdef IPECAMERA_ANNOUNCE_READY
|
139 |
if (((!ctx->preproc)&&(ctx->reported_id == ctx->event_id))||((ctx->preproc)&&(ctx->reported_id == ctx->preproc_id))) { |
|
140 |
#else /* IPECAMERA_ANNOUNCE_READY */ |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
141 |
if (ctx->reported_id == ctx->event_id) { |
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
142 |
#endif /* IPECAMERA_ANNOUNCE_READY */ |
143 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
144 |
if (timeout) { |
154
by Suren A. Chilingaryan
Support infinite timeouts in the get_next_frame |
145 |
if (timeout == PCILIB_TIMEOUT_INFINITE) { |
146 |
#ifdef IPECAMERA_ANNOUNCE_READY
|
|
244
by Suren A. Chilingaryan
Check if camera still started if INFINITE timeout is passed to ipecamera_get_next_event |
147 |
while ((ctx->started)&&(((!ctx->preproc)&&(ctx->reported_id == ctx->event_id))||((ctx->preproc)&&(ctx->reported_id == ctx->preproc_id)))) { |
154
by Suren A. Chilingaryan
Support infinite timeouts in the get_next_frame |
148 |
#else /* IPECAMERA_ANNOUNCE_READY */ |
244
by Suren A. Chilingaryan
Check if camera still started if INFINITE timeout is passed to ipecamera_get_next_event |
149 |
while ((ctx->started)&&(ctx->reported_id == ctx->event_id)) { |
154
by Suren A. Chilingaryan
Support infinite timeouts in the get_next_frame |
150 |
#endif /* IPECAMERA_ANNOUNCE_READY */ |
151 |
usleep(IPECAMERA_NOFRAME_SLEEP); |
|
152 |
}
|
|
240
by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options |
153 |
} else { |
154
by Suren A. Chilingaryan
Support infinite timeouts in the get_next_frame |
154 |
pcilib_calc_deadline(&tv, timeout); |
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
155 |
|
156 |
#ifdef IPECAMERA_ANNOUNCE_READY
|
|
173
by Suren A. Chilingaryan
Bail out from ipecamera_get_next_event if camera is stopped during the wait |
157 |
while ((ctx->started)&&(pcilib_calc_time_to_deadline(&tv) > 0)&&(((!ctx->preproc)&&(ctx->reported_id == ctx->event_id))||((ctx->preproc)&&(ctx->reported_id == ctx->preproc_id)))) { |
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
158 |
#else /* IPECAMERA_ANNOUNCE_READY */ |
173
by Suren A. Chilingaryan
Bail out from ipecamera_get_next_event if camera is stopped during the wait |
159 |
while ((ctx->started)&&(pcilib_calc_time_to_deadline(&tv) > 0)&&(ctx->reported_id == ctx->event_id)) { |
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
160 |
#endif /* IPECAMERA_ANNOUNCE_READY */ |
173
by Suren A. Chilingaryan
Bail out from ipecamera_get_next_event if camera is stopped during the wait |
161 |
usleep(IPECAMERA_NOFRAME_SLEEP); |
154
by Suren A. Chilingaryan
Support infinite timeouts in the get_next_frame |
162 |
}
|
133
by Suren A. Chilingaryan
In preprocessing mode, announce the events only after reconstruction is done |
163 |
}
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
164 |
}
|
165 |
||
173
by Suren A. Chilingaryan
Bail out from ipecamera_get_next_event if camera is stopped during the wait |
166 |
if (ctx->reported_id == ctx->event_id) { |
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
167 |
UNLOCK(stream); |
262
by Suren A. Chilingaryan
Introduce API debugging |
168 |
ipecamera_debug(API, "ipecamera: next_event timed out"); |
173
by Suren A. Chilingaryan
Bail out from ipecamera_get_next_event if camera is stopped during the wait |
169 |
return PCILIB_ERROR_TIMEOUT; |
170 |
}
|
|
154
by Suren A. Chilingaryan
Support infinite timeouts in the get_next_frame |
171 |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
172 |
}
|
173 |
||
174 |
retry: |
|
270
by Suren A. Chilingaryan
More lost event debugging |
175 |
if ((ctx->event_id - ctx->reported_id) > (ctx->buffer_size - IPECAMERA_RESERVE_BUFFERS)) { |
176 |
ipecamera_debug(HARDWARE, "Skipping events %zu to %zu as preprocessing is too slow. We are currently %zu buffers beyond, but only %zu buffers are available and safety limit is %zu", |
|
177 |
ctx->reported_id, ctx->event_id - (ctx->buffer_size - 1 - IPECAMERA_RESERVE_BUFFERS), ctx->event_id - ctx->reported_id, ctx->buffer_size, IPECAMERA_RESERVE_BUFFERS); |
|
178 |
ctx->reported_id = ctx->event_id - (ctx->buffer_size - 1 - IPECAMERA_RESERVE_BUFFERS); |
|
179 |
} else ++ctx->reported_id; |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
180 |
|
181 |
if (evid) *evid = ctx->reported_id; |
|
182 |
||
183 |
if (info) { |
|
184 |
if (info_size >= sizeof(ipecamera_event_info_t)) |
|
185 |
memcpy(info, ctx->frame + ((ctx->reported_id-1)%ctx->buffer_size), sizeof(ipecamera_event_info_t)); |
|
186 |
else if (info_size >= sizeof(pcilib_event_info_t)) |
|
187 |
memcpy(info, ctx->frame + ((ctx->reported_id-1)%ctx->buffer_size), sizeof(pcilib_event_info_t)); |
|
262
by Suren A. Chilingaryan
Introduce API debugging |
188 |
else { |
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
189 |
UNLOCK(stream); |
262
by Suren A. Chilingaryan
Introduce API debugging |
190 |
ipecamera_debug(API, "ipecamera: next_event returned a error"); |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
191 |
return PCILIB_ERROR_INVALID_ARGUMENT; |
262
by Suren A. Chilingaryan
Introduce API debugging |
192 |
}
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
193 |
}
|
190.1.2
by Suren A. Chilingaryan
Fix lock-up under the frame-flood, when the frame rate is significantly faster than processing |
194 |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
195 |
if ((ctx->event_id - ctx->reported_id) >= ctx->buffer_size) goto retry; |
190.1.2
by Suren A. Chilingaryan
Fix lock-up under the frame-flood, when the frame rate is significantly faster than processing |
196 |
|
265
by Suren A. Chilingaryan
Use new locking subsystem to ensure integrity |
197 |
UNLOCK(stream); |
198 |
||
262
by Suren A. Chilingaryan
Introduce API debugging |
199 |
ipecamera_debug(API, "ipecamera: next_event returned"); |
200 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
201 |
return 0; |
202 |
}
|
|
203 |
||
283
by Suren A. Chilingaryan
Added ipecamera_get_last_event_id() to public API |
204 |
pcilib_event_id_t ipecamera_get_last_event_id(ipecamera_t *ctx) { |
205 |
return ctx->event_id; |
|
206 |
}
|