693f1e87154947811c9ac21a092b5aefe1f38836
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

1) /*
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

2)  * EtherPix library
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

3)  *
Stefan Schuermans update copyright year

Stefan Schuermans authored 7 years ago

4)  * Copyright 2010-2017 Stefan Schuermans <stefan schuermans info>
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

5)  *
6)  * This program is free software: you can redistribute it and/or modify
7)  * it under the terms of the GNU General Public License as published by
8)  * the Free Software Foundation, version 3 of the License.
9)  *
10)  *
11)  * This program is distributed in the hope that it will be useful,
12)  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13)  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14)  * GNU General Public License for more details.
15)  *
16)  * You should have received a copy of the GNU Lesser General Public License
17)  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18)  */
19) 
20) #include <sys/time.h>
21) #include <stdlib.h>
22) 
Stefan Schuermans move internal includes

Stefan Schuermans authored 7 years ago

23) #include "net.h" // first because of winsock2.h ordering
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

24) #include <etherpix/display.h>
25) #include <etherpix/displayer.h>
26) #include <etherpix/msg.h>
27) #include <etherpix/types.h>
Stefan Schuermans move internal includes

Stefan Schuermans authored 7 years ago

28) #include "displayer.h"
29) #include "thread.h"
30) #include "types.h"
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

31) 
32) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

33)  * \brief create a new EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

34)  *
35)  * A displayer manages a display and ensures that a the current
36)  * image data is sent often enough to the distributors so
37)  * that the pixels do detect a timeout and turn off automatically.
38)  * The displayer uses a thread to do this.
39)  * Initially, the new displayer is inactive and has to be activated
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

40)  * using etp_displayer_activate().
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

41)  *
42)  * \param[in] sz_config_file name of config file to read
43)  * \param[in] p_msg_func message callback function or NULL
44)  * \param[in] p_msg_ctx user context for message callback
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

45)  * \return pointer to new EtherPix displayer on success
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

46)  *         or NULL on error
47)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

48) etp_displayer_t *etp_displayer_create(const char *sz_config_file,
49)                                       etp_msg_func_p_t p_msg_func,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

50)                                       void *p_msg_ctx)
51) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

52)   etp_displayer_t *p_displayer;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

53) 
54)   /* set up basic structure and display */
55) 
56)   /* create displayer structure */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

57)   p_displayer = (etp_displayer_t *)calloc(1, sizeof (etp_displayer_t));
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

58)   if (!p_displayer) {
59)     if (p_msg_func)
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

60)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

61)                  "out of memory\n");
62)     return NULL;
63)   }
64) 
65)   /* set up flags */
66)   p_displayer->active = 0; /* not sending data to distributors */
67)   p_displayer->send   = 1; /* send first data as soon as active */
68)   p_displayer->end    = 0; /* do not end yet */
69) 
70)   /* set up managed display */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

71)   p_displayer->p_display = etp_display_create(sz_config_file,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

72)                                               p_msg_func, p_msg_ctx);
73)   if (!p_displayer->p_display) {
74)     free(p_displayer);
75)     if (p_msg_func)
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

76)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

77)                  "could not create display\n");
78)     return NULL;
79)   }
80) 
81)   /* set up output thread */
82) 
83)   /* initialize mutex */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

84)   if (!etp_thread_mutex_init(&p_displayer->mtx)) {
85)     etp_display_free(p_displayer->p_display);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

86)     free(p_displayer);
87)     if (p_msg_func)
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

88)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

89)                  "could not initialize mutex\n");
90)     return NULL;
91)   }
92) 
93)   /* initialize condition */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

94)   if (!etp_thread_cond_init(&p_displayer->cond)) {
95)     etp_thread_mutex_destroy(&p_displayer->mtx);
96)     etp_display_free(p_displayer->p_display);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

97)     free(p_displayer);
98)     if (p_msg_func)
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

99)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

100)                  "could not initialize condition\n");
101)     return NULL;
102)   }
103) 
104)   /* create thread */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

105)   if (!etp_thread_create(&p_displayer->tid, etp_displayer_thread,
Stefan Schuermans v1.0.6

Stefan Schuermans authored 13 years ago

106)                         (void *)p_displayer)) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

107)     etp_thread_cond_destroy(&p_displayer->cond);
108)     etp_thread_mutex_destroy(&p_displayer->mtx);
109)     etp_display_free(p_displayer->p_display);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

110)     free(p_displayer);
111)     if (p_msg_func)
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

112)       p_msg_func(p_msg_ctx, etp_msg_type_err,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

113)                  "could not create thread\n");
114)     return NULL;
115)   }
116) 
117)   return p_displayer;
118) }
119) 
120) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

121)  * \brief free a EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

122)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

123)  * \param[in] p_displayer pointer to EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

124)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

125) void etp_displayer_free(etp_displayer_t *p_displayer)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

126) {
127)   /* tear down thread */
128)   p_displayer->end = 1;
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

129)   etp_thread_cond_signal(&p_displayer->cond);
130)   etp_thread_join(p_displayer->tid);
131)   etp_thread_cond_destroy(&p_displayer->cond);
132)   etp_thread_mutex_destroy(&p_displayer->mtx);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

133) 
134)   /* free managed display */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

135)   etp_display_free(p_displayer->p_display);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

136) 
137)   /* free basic structure */
138)   free(p_displayer);
139) }
140) 
141) /**
142)  * \brief get size of display managed by displayer
143)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

144)  * \param[in] p_displayer pointer to EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

145)  * \param[out] p_width width of display
146)  * \param[out] p_height height of display
147)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

148) void etp_displayer_get_size(etp_displayer_t *p_displayer,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

149)                             unsigned int *p_width, unsigned int *p_height)
150) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

151)   etp_thread_mutex_lock(&p_displayer->mtx);
152)   etp_display_get_size(p_displayer->p_display, p_width, p_height);
153)   etp_thread_mutex_unlock(&p_displayer->mtx);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

154) }
155) 
156) /**
157)  * \brief activate the displayer
158)  *
159)  * set the displayer to active, i.e. make it send image data
160)  * to the distributors automatically,
161)  * this function might trigger sending of data if the last
162)  * sending time was too long ago
163)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

164)  * \param[in] p_displayer pointer to EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

165)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

166) void etp_displayer_activate(etp_displayer_t *p_displayer)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

167) {
168)   p_displayer->active = 1;
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

169)   etp_thread_cond_signal(&p_displayer->cond);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

170) }
171) 
172) /**
173)  * \brief deactivate the displayer
174)  *
175)  * set the displayer to deactive, i.e. prevent it from sening image
176)  * data to the distributors automatically,
177)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

178)  * \param[in] p_displayer pointer to EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

179)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

180) void etp_displayer_deactivate(etp_displayer_t *p_displayer)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

181) {
182)   p_displayer->active = 0;
183)   /* no need to signal condition: thread does not need to do something yet */
184) }
185) 
186) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

187)  * \brief clear image data to output on EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

188)  *
189)  * clears the stored image data
190)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

191)  * \param[in] p_displayer pointer to EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

192)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

193) void etp_displayer_data_clear(etp_displayer_t *p_displayer)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

194) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

195)   etp_thread_mutex_lock(&p_displayer->mtx);
196)   etp_display_data_clear(p_displayer->p_display);
197)   etp_thread_mutex_unlock(&p_displayer->mtx);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

198) }
199) 
200) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

201)  * \brief set image data to output on EtherPix display
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

202)  *
203)  * updates (part of) the stored image data
204)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

205)  * \param[in] p_displayer pointer to EtherPix displayer
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

206)  * \param[in] p_data pointer to rectangular section of image data
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

207)  * \param[in] stride_x stride between two pixels in X direction
208)  * \param[in] stride_y stride between two pixels in Y direction
209)  * \param[in] x X coordinate of left side of rectangular area
210)  * \param[in] y Y coordinate of top side of rectangular area
211)  * \param[in] width with of rectangular area
212)  * \param[in] height height of rectangular area
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

213)  * \param[in] pixfmt format of pixel data
214)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

215) void etp_displayer_data_fmt(etp_displayer_t *p_displayer, etp_u8_t *p_data,
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

216)                             int stride_x, int stride_y,
217)                             unsigned int x, unsigned int y,
218)                             unsigned int width, unsigned int height,
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

219)                             etp_pixfmt_t pixfmt)
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

220) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

221)   etp_thread_mutex_lock(&p_displayer->mtx);
222)   etp_display_data_fmt(p_displayer->p_display, p_data, stride_x, stride_y,
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

223)                        x, y, width, height, pixfmt);
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

224)   etp_thread_mutex_unlock(&p_displayer->mtx);
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

225) }
226) 
227) /**
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

228)  * \brief set image data to output on EtherPix display
Stefan Schuermans support BGR input in additi...

Stefan Schuermans authored 7 years ago

229)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

230)  * see etp_displayer_data_fmt for documentation
231)  * pixfmt is fixed to etp_pixfmt_rgb24
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

232)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

233) void etp_displayer_data(etp_displayer_t *p_displayer, etp_u8_t *p_data,
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

234)                         int stride_x, int stride_y,
235)                         unsigned int x, unsigned int y,
236)                         unsigned int width, unsigned int height)
237) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

238)   etp_displayer_data_fmt(p_displayer, p_data, stride_x, stride_y,
239)                          x, y, width, height, etp_pixfmt_rgb24);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

240) }
241) 
242) /**
243)  * \brief trigger immediate sending of new image data to distributors
244)  *
245)  * this only works if the displayer is active
246)  *
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

247)  * \param[in] p_displayer pointer to EtherPix displayer
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

248)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

249) void etp_displayer_send(etp_displayer_t *p_displayer)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

250) {
251)   p_displayer->send = 1;
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

252)   etp_thread_cond_signal(&p_displayer->cond);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

253) }
254) 
255) /**
256)  * \brief output thread of displayer object
257)  *
258)  * \param[in] vp_displayer pointer to displayer object
259)  * \return unused, always NULL
260)  */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

261) ETP_THREAD_FUNC(etp_displayer_thread)
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

262) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

263)   etp_displayer_t *p_displayer = (etp_displayer_t *)vp_displayer;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

264)   struct timeval last, now, delta;
265)   int timed_send;
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

266)   int interval_ms = ETP_MCUF_MAX_FRAME_INTERVAL_MS;
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

267) 
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

268)   etp_thread_mutex_lock(&p_displayer->mtx);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

269) 
270)   gettimeofday(&last, NULL); /* initialize last to some valid time */
271) 
272)   /* while thread shall not end */
273)   while (!p_displayer->end) {
274) 
275)     /* active */
276)     if (p_displayer->active) {
277) 
278)       /* get current time */
279)       gettimeofday(&now, NULL);
280)       /* get time since sending last frame */
281)       delta.tv_sec = now.tv_sec - last.tv_sec;
282)       delta.tv_usec = now.tv_usec - last.tv_usec;
283)       if (delta.tv_usec < 0) {
284)         delta.tv_usec += 1000000;
285)         ++delta.tv_sec;
286)       }
287)       /* check if late enough for timed send */
Stefan Schuermans v1.0.6

Stefan Schuermans authored 13 years ago

288)       timed_send = delta.tv_sec > interval_ms / 1000
289)                  || (delta.tv_sec == interval_ms / 1000
290)                      && delta.tv_usec >= (interval_ms % 1000) * 1000);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

291) 
292)       /* send if send requested or late enough */
293)       if (p_displayer->send || timed_send) {
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

294)         etp_display_send(p_displayer->p_display); /* send */
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

295)         last = now;                               /* remember last send time */
296)         p_displayer->send = 0;                    /* clear send request */
297)       }
298) 
299)       /* sleep until next frame has to be sent */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

300)       etp_thread_cond_timedwait(&p_displayer->cond, &p_displayer->mtx,
Stefan Schuermans v1.0.6

Stefan Schuermans authored 13 years ago

301)                                 &last, interval_ms);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

302) 
303)     } /* if (p_displayer->active) */
304) 
305)     /* inactive */
306)     else {
307) 
308)       /* sleep */
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

309)       etp_thread_cond_wait(&p_displayer->cond, &p_displayer->mtx);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

310) 
311)     } /* if (p_displayer->active) ... else */
312) 
313)   } /* while(!p_displayer->end) */
314) 
Stefan Schuermans rename "FlexiPix" to "Ether...

Stefan Schuermans authored 7 years ago

315)   etp_thread_mutex_unlock(&p_displayer->mtx);
Stefan Schuermans v1.0.0

Stefan Schuermans authored 13 years ago

316) 
Stefan Schuermans update Windows support

Stefan Schuermans authored 7 years ago

317)   return ETP_THREAD_RETURN_OK;