bzr branch
http://suren.me/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> |
|
185
by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode |
10 |
#include <sys/stat.h> |
11 |
#include <sys/types.h> |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
12 |
#include <pthread.h> |
13 |
#include <assert.h> |
|
14 |
||
15 |
#include <ufodecode.h> |
|
16 |
||
245
by Suren A. Chilingaryan
First stand-alone ipecamera implementation |
17 |
#include <pcilib.h> |
18 |
#include <pcilib/tools.h> |
|
19 |
#include <pcilib/error.h> |
|
276
by Suren A. Chilingaryan
Update to new version of pcitool |
20 |
#include <pcilib/timing.h> |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
21 |
|
162
by Suren A. Chilingaryan
UFO5 size estimation |
22 |
#include "model.h" |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
23 |
#include "private.h" |
24 |
#include "reader.h" |
|
25 |
||
274
by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested) |
26 |
|
27 |
#define GET_REG(reg, var) \
|
|
28 |
if (!err) { \
|
|
29 |
err = pcilib_read_register_by_id(pcilib, ctx->reg, &var); \
|
|
30 |
if (err) { \
|
|
31 |
pcilib_error("Error reading %s register", model_info->registers[ctx->reg].name); \
|
|
32 |
} \
|
|
33 |
}
|
|
34 |
||
35 |
#define SET_REG(reg, val) \
|
|
36 |
if (!err) { \
|
|
37 |
err = pcilib_write_register_by_id(pcilib, ctx->reg, val); \
|
|
38 |
if (err) { \
|
|
39 |
pcilib_error("Error writting %s register", model_info->registers[ctx->reg].name); \
|
|
40 |
} \
|
|
41 |
}
|
|
42 |
||
275
by Suren A. Chilingaryan
Fix some warnings and add debugging information into the build |
43 |
/*
|
44 |
#define CHECK_FRAME_MAGIC(buf) \
|
|
45 |
memcmp(buf, ((void*)frame_magic) + 1, sizeof(frame_magic) - 1)
|
|
46 |
*/
|
|
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
47 |
|
48 |
#define CHECK_FRAME_MAGIC(buf) \
|
|
49 |
memcmp(((ipecamera_payload_t*)(buf)) + 1, &frame_magic[1], sizeof(frame_magic) - sizeof(ipecamera_payload_t))
|
|
50 |
||
51 |
static ipecamera_payload_t frame_magic[3] = { 0x51111111, 0x52222222, 0x53333333 }; |
|
52 |
||
53 |
||
54 |
||
55 |
int ipecamera_compute_buffer_size(ipecamera_t *ctx, ipecamera_format_t format, size_t header_size, size_t lines) { |
|
56 |
// const size_t header_size = 8 * sizeof(ipecamera_payload_t);
|
|
57 |
const size_t footer_size = CMOSIS_FRAME_TAIL_SIZE; |
|
58 |
||
59 |
size_t max_channels; |
|
175
by Suren A. Chilingaryan
Support both UFO4 and UFO5 frame formats |
60 |
size_t line_size, raw_size, padded_blocks; |
61 |
||
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
62 |
switch (format) { |
63 |
case IPECAMERA_FORMAT_CMOSIS: |
|
282
by Suren A. Chilingaryan
Support HighFlex-based ipecamera |
64 |
case IPECAMERA_FORMAT_CMOSIS20: |
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
65 |
max_channels = CMOSIS_MAX_CHANNELS; |
282
by Suren A. Chilingaryan
Support HighFlex-based ipecamera |
66 |
line_size = ctx->data_line_size; |
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
67 |
break; |
175
by Suren A. Chilingaryan
Support both UFO4 and UFO5 frame formats |
68 |
default: |
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
69 |
pcilib_warning("Unsupported version (%u) of frame format...", format); |
70 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
71 |
}
|
|
72 |
||
73 |
raw_size = lines * line_size; |
|
74 |
raw_size *= max_channels / ctx->cmosis_outputs; |
|
75 |
raw_size += header_size + footer_size; |
|
248
by Suren A. Chilingaryan
Support CMOSIS bug resulting in missing payload |
76 |
|
77 |
#ifdef IPECAMERA_BUG_MISSING_PAYLOAD
|
|
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
78 |
// As I understand, the first 32-byte packet is missing, so we need to substract 32 (both CMOSIS and CMOSIS20)
|
79 |
raw_size -= 32; |
|
248
by Suren A. Chilingaryan
Support CMOSIS bug resulting in missing payload |
80 |
#endif /* IPECAMERA_BUG_MISSING_PAYLOAD */ |
168
by Suren A. Chilingaryan
Support 12-bit modes |
81 |
|
82 |
padded_blocks = raw_size / IPECAMERA_DMA_PACKET_LENGTH + ((raw_size % IPECAMERA_DMA_PACKET_LENGTH)?1:0); |
|
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
83 |
|
249
by Suren A. Chilingaryan
Simplify size tracking in the reader |
84 |
ctx->roi_raw_size = raw_size; |
85 |
ctx->roi_padded_size = padded_blocks * IPECAMERA_DMA_PACKET_LENGTH; |
|
168
by Suren A. Chilingaryan
Support 12-bit modes |
86 |
|
162
by Suren A. Chilingaryan
UFO5 size estimation |
87 |
return 0; |
88 |
}
|
|
89 |
||
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
90 |
|
91 |
static int ipecamera_parse_header(ipecamera_t *ctx, ipecamera_payload_t *buf, size_t buf_size) { |
|
282
by Suren A. Chilingaryan
Support HighFlex-based ipecamera |
92 |
int err; |
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
93 |
int last = buf[0] & 1; |
94 |
int version = (buf[0] >> 1) & 7; |
|
95 |
size_t size = 0, n_lines; |
|
96 |
ipecamera_format_t format = IPECAMERA_FORMAT_CMOSIS; |
|
97 |
||
98 |
switch (version) { |
|
99 |
case 0: |
|
100 |
n_lines = ((uint32_t*)buf)[5] & 0x7FF; |
|
101 |
ctx->frame[ctx->buffer_pos].event.info.seqnum = buf[6] & 0xFFFFFF; |
|
102 |
ctx->frame[ctx->buffer_pos].event.info.offset = (buf[7] & 0xFFFFFF) * 80; |
|
103 |
break; |
|
104 |
case 1: |
|
105 |
n_lines = ((uint32_t*)buf)[5] & 0xFFFF; |
|
106 |
if (!n_lines) { |
|
107 |
pcilib_error("The frame header claims 0 lines in the data"); |
|
108 |
return 0; |
|
109 |
}
|
|
110 |
||
111 |
ctx->frame[ctx->buffer_pos].event.info.seqnum = buf[6] & 0xFFFFFF; |
|
112 |
ctx->frame[ctx->buffer_pos].event.info.offset = (buf[7] & 0xFFFFFF) * 80; |
|
113 |
format = (buf[6] >> 24)&0x0F; |
|
114 |
break; |
|
115 |
default: |
|
116 |
ipecamera_debug(HARDWARE, "Incorrect version of the frame header, ignoring broken data..."); |
|
117 |
return 0; |
|
118 |
}
|
|
119 |
gettimeofday(&ctx->frame[ctx->buffer_pos].event.info.timestamp, NULL); |
|
120 |
||
121 |
ipecamera_debug(FRAME_HEADERS, "frame %lu: %x %x %x %x", ctx->frame[ctx->buffer_pos].event.info.seqnum, buf[0], buf[1], buf[2], buf[3]); |
|
122 |
ipecamera_debug(FRAME_HEADERS, "frame %lu: %x %x %x %x", ctx->frame[ctx->buffer_pos].event.info.seqnum, buf[4], buf[5], buf[6], buf[7]); |
|
123 |
||
124 |
while ((!last)&&((size + CMOSIS_FRAME_HEADER_SIZE) <= buf_size)) { |
|
125 |
size += CMOSIS_FRAME_HEADER_SIZE; |
|
126 |
last = buf[size] & 1; |
|
127 |
}
|
|
128 |
||
129 |
size += CMOSIS_FRAME_HEADER_SIZE; |
|
282
by Suren A. Chilingaryan
Support HighFlex-based ipecamera |
130 |
|
131 |
err = ipecamera_compute_buffer_size(ctx, format, size, n_lines); |
|
132 |
if (err) return 0; |
|
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
133 |
|
134 |
// Returns total size of found headers or 0 on the error
|
|
135 |
return size; |
|
136 |
}
|
|
137 |
||
138 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
139 |
static inline int ipecamera_new_frame(ipecamera_t *ctx) { |
140 |
ctx->frame[ctx->buffer_pos].event.raw_size = ctx->cur_size; |
|
141 |
||
249
by Suren A. Chilingaryan
Simplify size tracking in the reader |
142 |
if (ctx->cur_size < ctx->roi_raw_size) { |
165
by Suren A. Chilingaryan
Minor fix for frame partitioning |
143 |
ctx->frame[ctx->buffer_pos].event.info.flags |= PCILIB_EVENT_INFO_FLAG_BROKEN; |
144 |
}
|
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
145 |
|
146 |
ctx->buffer_pos = (++ctx->event_id) % ctx->buffer_size; |
|
147 |
ctx->cur_size = 0; |
|
148 |
||
149 |
ctx->frame[ctx->buffer_pos].event.info.type = PCILIB_EVENT0; |
|
150 |
ctx->frame[ctx->buffer_pos].event.info.flags = 0; |
|
151 |
ctx->frame[ctx->buffer_pos].event.image_ready = 0; |
|
152 |
||
153 |
if ((ctx->event_id == ctx->autostop.evid)&&(ctx->event_id)) { |
|
154 |
ctx->run_reader = 0; |
|
155 |
return 1; |
|
156 |
}
|
|
157 |
||
245
by Suren A. Chilingaryan
First stand-alone ipecamera implementation |
158 |
if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) { |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
159 |
ctx->run_reader = 0; |
160 |
return 1; |
|
161 |
}
|
|
162 |
||
163 |
return 0; |
|
164 |
}
|
|
165 |
||
166 |
static int ipecamera_data_callback(void *user, pcilib_dma_flags_t flags, size_t bufsize, void *buf) { |
|
167 |
int res; |
|
168 |
int eof = 0; |
|
251
by Suren A. Chilingaryan
Use pcitool debugging API |
169 |
|
170 |
static unsigned long packet_id = 0; |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
171 |
|
172 |
#ifdef IPECAMERA_BUG_MULTIFRAME_PACKETS
|
|
143
by Suren A. Chilingaryan
Send padding data to rawdata_callback |
173 |
size_t real_size; |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
174 |
size_t extra_data = 0; |
175 |
#endif /* IPECAMERA_BUG_MULTIFRAME_PACKETS */ |
|
240
by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options |
176 |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
177 |
ipecamera_t *ctx = (ipecamera_t*)user; |
178 |
||
184
by Suren A. Chilingaryan
Fix splitting of frames in case of MULTIFRAME_PACKETS camera bug |
179 |
#if defined(IPECAMERA_BUG_INCOMPLETE_PACKETS)||defined(IPECAMERA_BUG_MULTIFRAME_PACKETS)
|
180 |
static pcilib_event_id_t invalid_frame_id = (pcilib_event_id_t)-1; |
|
181 |
#endif
|
|
185
by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode |
182 |
|
251
by Suren A. Chilingaryan
Use pcitool debugging API |
183 |
packet_id++; |
184 |
ipecamera_debug_buffer(RAW_PACKETS, bufsize, buf, PCILIB_DEBUG_BUFFER_MKDIR, "frame%4lu/frame%9lu", ctx->event_id, packet_id); |
|
185 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
186 |
if (!ctx->cur_size) { |
267
by Suren A. Chilingaryan
Handle frame headers split between 2 packets |
187 |
#ifdef IPECAMERA_BUG_MULTIFRAME_HEADERS
|
188 |
if (ctx->saved_header_size) { |
|
189 |
void *buf2 = alloca(ctx->saved_header_size + bufsize); |
|
190 |
if (!buf2) { |
|
191 |
pcilib_error("Error allocating %zu bytes of memory in stack", ctx->saved_header_size + bufsize); |
|
192 |
return -PCILIB_ERROR_MEMORY; |
|
193 |
}
|
|
194 |
memcpy(buf2, ctx->saved_header, ctx->saved_header_size); |
|
195 |
memcpy(buf2 + ctx->saved_header_size, buf, bufsize); |
|
196 |
||
197 |
buf = buf2; |
|
198 |
bufsize += ctx->saved_header_size; |
|
199 |
||
200 |
ctx->saved_header_size = 0; |
|
201 |
}
|
|
202 |
#endif /* IPECAMERA_BUG_MULTIFRAME_HEADERS */ |
|
203 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
204 |
#if defined(IPECAMERA_BUG_INCOMPLETE_PACKETS)||defined(IPECAMERA_BUG_MULTIFRAME_PACKETS)
|
205 |
size_t startpos; |
|
267
by Suren A. Chilingaryan
Handle frame headers split between 2 packets |
206 |
for (startpos = 0; (startpos + CMOSIS_ENTITY_SIZE) <= bufsize; startpos += sizeof(ipecamera_payload_t)) { |
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
207 |
if (!CHECK_FRAME_MAGIC(buf + startpos)) break; |
182
by Suren A. Chilingaryan
Skip non-informative packets on DMA |
208 |
}
|
209 |
||
267
by Suren A. Chilingaryan
Handle frame headers split between 2 packets |
210 |
if ((startpos + CMOSIS_ENTITY_SIZE) > bufsize) { |
251
by Suren A. Chilingaryan
Use pcitool debugging API |
211 |
ipecamera_debug_buffer(RAW_PACKETS, bufsize, NULL, 0, "frame%4lu/frame%9lu.invalid", ctx->event_id, packet_id); |
184
by Suren A. Chilingaryan
Fix splitting of frames in case of MULTIFRAME_PACKETS camera bug |
212 |
|
213 |
if (invalid_frame_id != ctx->event_id) { |
|
254
by Suren A. Chilingaryan
Report extra padding only if IPECAMERA_DEBUG_HARDWARE is set |
214 |
ipecamera_debug(HARDWARE, "No frame magic in DMA packet of %u bytes, current event %lu", bufsize, ctx->event_id); |
184
by Suren A. Chilingaryan
Fix splitting of frames in case of MULTIFRAME_PACKETS camera bug |
215 |
invalid_frame_id = ctx->event_id; |
216 |
}
|
|
217 |
||
218 |
return PCILIB_STREAMING_CONTINUE; |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
219 |
}
|
220 |
||
221 |
if (startpos) { |
|
143
by Suren A. Chilingaryan
Send padding data to rawdata_callback |
222 |
// pass padding to rawdata callback
|
223 |
if (ctx->event.params.rawdata.callback) { |
|
224 |
res = ctx->event.params.rawdata.callback(0, NULL, PCILIB_EVENT_FLAG_RAW_DATA_ONLY, startpos, buf, ctx->event.params.rawdata.user); |
|
225 |
if (res <= 0) { |
|
226 |
if (res < 0) return res; |
|
227 |
ctx->run_reader = 0; |
|
228 |
}
|
|
229 |
}
|
|
230 |
||
231 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
232 |
buf += startpos; |
233 |
bufsize -= startpos; |
|
234 |
}
|
|
235 |
#endif /* IPECAMERA_BUG_INCOMPLETE_PACKETS */ |
|
236 |
||
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
237 |
if ((bufsize >= CMOSIS_FRAME_HEADER_SIZE)&&(!CHECK_FRAME_MAGIC(buf))) { |
238 |
// We should handle the case when multi-header is split between multiple DMA packets
|
|
239 |
if (!ipecamera_parse_header(ctx, buf, bufsize)) |
|
240 |
return PCILIB_STREAMING_CONTINUE; |
|
267
by Suren A. Chilingaryan
Handle frame headers split between 2 packets |
241 |
|
242 |
#ifdef IPECAMERA_BUG_MULTIFRAME_HEADERS
|
|
243 |
} else if ((bufsize >= CMOSIS_ENTITY_SIZE)&&(!CHECK_FRAME_MAGIC(buf))) { |
|
244 |
memcpy(ctx->saved_header, buf, bufsize); |
|
245 |
ctx->saved_header_size = bufsize; |
|
246 |
return PCILIB_STREAMING_REQ_FRAGMENT; |
|
247 |
#endif /* IPECAMERA_BUG_MULTIFRAME_HEADERS */ |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
248 |
} else { |
267
by Suren A. Chilingaryan
Handle frame headers split between 2 packets |
249 |
ipecamera_debug(HARDWARE, "Frame magic is not found in the remaining DMA packet consisting of %u bytes, ignoring broken data...", bufsize); |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
250 |
return PCILIB_STREAMING_CONTINUE; |
251 |
}
|
|
252 |
}
|
|
253 |
||
254 |
#ifdef IPECAMERA_BUG_MULTIFRAME_PACKETS
|
|
143
by Suren A. Chilingaryan
Send padding data to rawdata_callback |
255 |
// for rawdata_callback with complete padding
|
256 |
real_size = bufsize; |
|
257 |
||
249
by Suren A. Chilingaryan
Simplify size tracking in the reader |
258 |
if (ctx->cur_size + bufsize > ctx->roi_raw_size) { |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
259 |
size_t need; |
260 |
||
267
by Suren A. Chilingaryan
Handle frame headers split between 2 packets |
261 |
for (need = ctx->roi_raw_size - ctx->cur_size; (need + CMOSIS_ENTITY_SIZE) <= bufsize; need += sizeof(uint32_t)) { |
261
by Suren A. Chilingaryan
Support for new CMOSIS 20MPix camera |
262 |
if (!CHECK_FRAME_MAGIC(buf + need)) break; |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
263 |
}
|
264 |
||
267
by Suren A. Chilingaryan
Handle frame headers split between 2 packets |
265 |
if ((need + CMOSIS_ENTITY_SIZE) <= bufsize) { |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
266 |
extra_data = bufsize - need; |
267 |
eof = 1; |
|
268 |
}
|
|
240
by Suren A. Chilingaryan
Fix frame size computation in ipecamera and few debuging options |
269 |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
270 |
// just rip of padding
|
249
by Suren A. Chilingaryan
Simplify size tracking in the reader |
271 |
bufsize = ctx->roi_raw_size - ctx->cur_size; |
251
by Suren A. Chilingaryan
Use pcitool debugging API |
272 |
ipecamera_debug_buffer(RAW_PACKETS, bufsize, buf, 0, "frame%4lu/frame%9lu.partial", ctx->event_id, packet_id); |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
273 |
}
|
274 |
#endif /* IPECAMERA_BUG_MULTIFRAME_PACKETS */ |
|
275 |
||
276 |
if (ctx->parse_data) { |
|
249
by Suren A. Chilingaryan
Simplify size tracking in the reader |
277 |
if (ctx->cur_size + bufsize > ctx->padded_size) { |
278 |
pcilib_error("Unexpected event data, we are expecting at maximum (%zu) bytes, but (%zu) already read", ctx->padded_size, ctx->cur_size + bufsize); |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
279 |
return -PCILIB_ERROR_TOOBIG; |
280 |
}
|
|
281 |
||
263
by Suren A. Chilingaryan
Add handling of a bug when IPECamera producing a dublicate 16 bytes at 4096 offset |
282 |
if (bufsize) { |
283 |
#ifdef IPECAMERA_BUG_REPEATING_DATA
|
|
284 |
if ((bufsize > 16)&&(ctx->cur_size > 16)) { |
|
285 |
if (!memcmp(ctx->buffer + ctx->buffer_pos * ctx->padded_size + ctx->cur_size - 16, buf, 16)) { |
|
286 |
pcilib_warning("Skipping repeating bytes at offset %zu of frame %zu", ctx->cur_size, ctx->event_id); |
|
287 |
buf += 16; |
|
288 |
bufsize -=16; |
|
289 |
}
|
|
290 |
}
|
|
291 |
#endif /* IPECAMERA_BUG_REPEATING_DATA */ |
|
245
by Suren A. Chilingaryan
First stand-alone ipecamera implementation |
292 |
memcpy(ctx->buffer + ctx->buffer_pos * ctx->padded_size + ctx->cur_size, buf, bufsize); |
263
by Suren A. Chilingaryan
Add handling of a bug when IPECamera producing a dublicate 16 bytes at 4096 offset |
293 |
}
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
294 |
}
|
295 |
||
296 |
ctx->cur_size += bufsize; |
|
297 |
||
249
by Suren A. Chilingaryan
Simplify size tracking in the reader |
298 |
if (ctx->cur_size >= ctx->roi_raw_size) { |
239
by Suren A. Chilingaryan
ipecamera hack |
299 |
eof = 1; |
300 |
}
|
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
301 |
|
302 |
if (ctx->event.params.rawdata.callback) { |
|
303 |
res = ctx->event.params.rawdata.callback(ctx->event_id, (pcilib_event_info_t*)(ctx->frame + ctx->buffer_pos), (eof?PCILIB_EVENT_FLAG_EOF:PCILIB_EVENT_FLAGS_DEFAULT), bufsize, buf, ctx->event.params.rawdata.user); |
|
304 |
if (res <= 0) { |
|
305 |
if (res < 0) return res; |
|
306 |
ctx->run_reader = 0; |
|
307 |
}
|
|
308 |
}
|
|
309 |
||
310 |
if (eof) { |
|
137
by Suren A. Chilingaryan
Stop reader thread on pcilib_stop |
311 |
if ((ipecamera_new_frame(ctx))||(!ctx->run_reader)) { |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
312 |
return PCILIB_STREAMING_STOP; |
313 |
}
|
|
314 |
||
315 |
#ifdef IPECAMERA_BUG_MULTIFRAME_PACKETS
|
|
316 |
if (extra_data) { |
|
185
by Suren A. Chilingaryan
More fixes to frame separation in multiframe mode; debugging mode |
317 |
return ipecamera_data_callback(user, flags, extra_data, buf + (real_size - extra_data)); |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
318 |
}
|
319 |
#endif /* IPECAMERA_BUG_MULTIFRAME_PACKETS */ |
|
320 |
}
|
|
321 |
||
322 |
return PCILIB_STREAMING_REQ_FRAGMENT; |
|
323 |
}
|
|
324 |
||
325 |
void *ipecamera_reader_thread(void *user) { |
|
326 |
int err; |
|
327 |
ipecamera_t *ctx = (ipecamera_t*)user; |
|
274
by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested) |
328 |
#ifdef IPECAMERA_BUG_STUCKED_BUSY
|
329 |
pcilib_register_value_t saved, value; |
|
330 |
pcilib_t *pcilib = ctx->event.pcilib; |
|
331 |
const pcilib_model_description_t *model_info = pcilib_get_model_description(pcilib); |
|
332 |
#endif /* IPECAMERA_BUG_STUCKED_BUSY */ |
|
333 |
||
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
334 |
while (ctx->run_reader) { |
245
by Suren A. Chilingaryan
First stand-alone ipecamera implementation |
335 |
err = pcilib_stream_dma(ctx->event.pcilib, ctx->rdma, 0, 0, PCILIB_DMA_FLAG_MULTIPACKET, IPECAMERA_DMA_TIMEOUT, &ipecamera_data_callback, user); |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
336 |
if (err) { |
337 |
if (err == PCILIB_ERROR_TIMEOUT) { |
|
249
by Suren A. Chilingaryan
Simplify size tracking in the reader |
338 |
if (ctx->cur_size >= ctx->roi_raw_size) ipecamera_new_frame(ctx); |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
339 |
#ifdef IPECAMERA_BUG_INCOMPLETE_PACKETS
|
340 |
else if (ctx->cur_size > 0) ipecamera_new_frame(ctx); |
|
341 |
#endif /* IPECAMERA_BUG_INCOMPLETE_PACKETS */ |
|
245
by Suren A. Chilingaryan
First stand-alone ipecamera implementation |
342 |
if (pcilib_check_deadline(&ctx->autostop.timestamp, 0)) { |
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
343 |
ctx->run_reader = 0; |
344 |
break; |
|
345 |
}
|
|
274
by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested) |
346 |
#ifdef IPECAMERA_BUG_STUCKED_BUSY
|
347 |
GET_REG(status2_reg, value); |
|
275
by Suren A. Chilingaryan
Fix some warnings and add debugging information into the build |
348 |
if ((!err)&&(value&0x2FFFFFFF)) { |
274
by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested) |
349 |
pcilib_warning("Camera stuck in busy, trying to recover..."); |
350 |
GET_REG(control_reg, saved); |
|
282
by Suren A. Chilingaryan
Support HighFlex-based ipecamera |
351 |
SET_REG(control_reg, IPECAMERA_IDLE|(saved&0xFFFF0000)); |
274
by Suren A. Chilingaryan
Add another workaround to handle cameras stuck in busy (disabled and untested) |
352 |
while ((value&0x2FFFFFFF)&&(ctx->run_reader)) { |
353 |
usleep(IPECAMERA_NOFRAME_SLEEP); |
|
354 |
}
|
|
355 |
}
|
|
356 |
#endif /* IPECAMERA_BUG_STUCKED_BUSY */ |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
357 |
usleep(IPECAMERA_NOFRAME_SLEEP); |
358 |
} else pcilib_error("DMA error while reading IPECamera frames, error: %i", err); |
|
252
by Suren A. Chilingaryan
Cleanup |
359 |
}
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
360 |
}
|
361 |
||
362 |
ctx->run_streamer = 0; |
|
363 |
||
252
by Suren A. Chilingaryan
Cleanup |
364 |
if (ctx->cur_size) |
365 |
pcilib_info("partialy read frame after stop signal, %zu bytes in the buffer", ctx->cur_size); |
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
366 |
|
367 |
return NULL; |
|
368 |
}
|