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