Stefan Schuermans commited on 2012-05-06 15:58:09
Showing 2 changed files, with 75 additions and 4 deletions.
... | ... |
@@ -11,6 +11,7 @@ |
11 | 11 |
#include "debug.h" |
12 | 12 |
#include "dosfs.h" |
13 | 13 |
#include "nethelp.h" |
14 |
+#include "udp.h" |
|
14 | 15 |
#include "timing.h" |
15 | 16 |
|
16 | 17 |
///< BBM file header |
... | ... |
@@ -46,7 +47,7 @@ static char AppBbmNextName(AppBbmState *state, char *filename, |
46 | 47 |
// no playlist dir -> deactivate application |
47 | 48 |
state->isInit = 0; |
48 | 49 |
debug_app_bbm_printf("%hhu: cannot open directory %s", |
49 |
- state->no, filename); |
|
50 |
+ state->no, dirname); |
|
50 | 51 |
return -1; |
51 | 52 |
} |
52 | 53 |
|
... | ... |
@@ -130,7 +131,8 @@ static void AppBbmParseHeader(AppBbmState *state) |
130 | 131 |
debug_app_bbm_printf("%hhu: invalid dimensions in BBM file", state->no); |
131 | 132 |
return; // retry with next file in next iteration |
132 | 133 |
} |
133 |
- if (state->height * state->width * state->channels > 1000) { |
|
134 |
+ state->dataSz = state->height * state->width * state->channels; |
|
135 |
+ if (state->dataSz > 1000) { |
|
134 | 136 |
debug_app_bbm_printf("%hhu: BBM frame size too large", state->no); |
135 | 137 |
return; // retry with next file in next iteration |
136 | 138 |
} |
... | ... |
@@ -147,7 +149,23 @@ static void AppBbmParseHeader(AppBbmState *state) |
147 | 149 |
return; // retry with next file in next iteration |
148 | 150 |
} |
149 | 151 |
|
152 |
+ // read frame start mrker |
|
153 |
+ uint8_t framestart[4]; |
|
154 |
+ if (DFS_ReadFile(&state->fi, *state->sectorBuf, |
|
155 |
+ framestart, &len, sizeof(framestart)) != DFS_OK) |
|
156 |
+ len = 0; |
|
157 |
+ if (len < sizeof(framestart)) { |
|
158 |
+ debug_app_bbm_printf("%hhu: truncated BBM file", state->no); |
|
159 |
+ return; // retry with next file in next iteration |
|
160 |
+ } |
|
161 |
+ if (memcmp(framestart, "frms", 4) != 0) { |
|
162 |
+ debug_app_bbm_printf("%hhu: invalid frame start marker in BBM file", |
|
163 |
+ state->no); |
|
164 |
+ return; // retry with next file in next iteration |
|
165 |
+ } |
|
166 |
+ |
|
150 | 167 |
// a file has been found and opened, header is parsed |
168 |
+ state->haveFile = 1; |
|
151 | 169 |
debug_app_bbm_printf("%hhu: header parsed: %hux%hu-%hu/%hu", state->no, |
152 | 170 |
state->width, state->height, state->channels, |
153 | 171 |
state->maxval + 1); |
... | ... |
@@ -176,6 +194,53 @@ static void AppBbmNextFile(AppBbmState *state) |
176 | 194 |
AppBbmParseHeader(state); |
177 | 195 |
} |
178 | 196 |
|
197 |
+/** |
|
198 |
+ * @brief process next frame |
|
199 |
+ * @param[in,out] state internal state of application |
|
200 |
+ */ |
|
201 |
+static void AppBbmProcFrame(AppBbmState *state) |
|
202 |
+{ |
|
203 |
+ struct packet { |
|
204 |
+ struct UdpPacket udp; |
|
205 |
+ uint8_t mcuf[12 + state->dataSz]; |
|
206 |
+ } pack; |
|
207 |
+ |
|
208 |
+ // read next frame from file |
|
209 |
+ // - read to mcuf pos 10, so data is placed at pos 12 for MCUF frame |
|
210 |
+ uint32_t len; |
|
211 |
+ if (DFS_ReadFile(&state->fi, *state->sectorBuf, |
|
212 |
+ pack.mcuf + 10, &len, state->dataSz + 2) != DFS_OK) |
|
213 |
+ len = 0; |
|
214 |
+ if (len < state->dataSz + 2) { |
|
215 |
+ // end of file reached -> use next file in next iteration |
|
216 |
+ state->haveFile = 0; |
|
217 |
+ debug_app_bbm_printf("%hhu: end of file", state->no); |
|
218 |
+ return; |
|
219 |
+ } |
|
220 |
+ |
|
221 |
+ // get frame duration |
|
222 |
+ uint16_t duration = ntohs(*(uint16_t *)(pack.mcuf + 10)); |
|
223 |
+ debug_app_bbm_printf("%hhu: frame duration %u", state->no, duration); |
|
224 |
+ |
|
225 |
+ // fill in MCUF header |
|
226 |
+ *(uint32_t *)(pack.mcuf + 0) = htonl(0x23542666); |
|
227 |
+ *(uint16_t *)(pack.mcuf + 4) = htons(state->height); |
|
228 |
+ *(uint16_t *)(pack.mcuf + 6) = htons(state->width); |
|
229 |
+ *(uint16_t *)(pack.mcuf + 8) = htons(state->channels); |
|
230 |
+ *(uint16_t *)(pack.mcuf + 10) = htons(state->maxval); |
|
231 |
+ |
|
232 |
+ // send MCUF frame |
|
233 |
+ if (state->haveAddr) { |
|
234 |
+ memcpy(pack.udp.IpHdr.Dest, state->addr, sizeof(pack.udp.IpHdr.Dest)); |
|
235 |
+ pack.udp.UdpHdr.SrcPort = htons(2323); |
|
236 |
+ pack.udp.UdpHdr.DestPort = htons(2323); |
|
237 |
+ UdpSend((unsigned char *)&pack, sizeof(pack)); |
|
238 |
+ } |
|
239 |
+ |
|
240 |
+ // wait for frame duration |
|
241 |
+ state->nextActMs += duration; |
|
242 |
+} |
|
243 |
+ |
|
179 | 244 |
/** |
180 | 245 |
* @brief initialize BBM play application |
181 | 246 |
* @param[in,out] state internal state of application |
... | ... |
@@ -223,8 +288,12 @@ void AppBbmRun(AppBbmState *state) // (extern) |
223 | 288 |
// time for next action not yet reached -> leave |
224 | 289 |
unsigned long ms; |
225 | 290 |
TimingGetMs(&ms); |
226 |
- if ((long)(state->nextActMs - ms) > 0) |
|
291 |
+ long delta = state->nextActMs - ms; |
|
292 |
+ if (delta > 0) |
|
227 | 293 |
return; |
294 |
+ // if lagging behing more than 100ms, do not try to catch up -> advance time |
|
295 |
+ if (delta < -100) |
|
296 |
+ state->nextActMs = ms; |
|
228 | 297 |
|
229 | 298 |
// no file -> open next one |
230 | 299 |
if (!state->haveFile) { |
... | ... |
@@ -232,6 +301,7 @@ void AppBbmRun(AppBbmState *state) // (extern) |
232 | 301 |
return; // do not work too much in one step / app might be deactivated now |
233 | 302 |
} |
234 | 303 |
|
235 |
- // TODO |
|
304 |
+ // process next frame |
|
305 |
+ AppBbmProcFrame(state); |
|
236 | 306 |
} |
237 | 307 |
|
... | ... |
@@ -26,6 +26,7 @@ typedef struct app_bbm_state { |
26 | 26 |
uint16_t width; ///< width of current movie |
27 | 27 |
uint16_t channels; ///< channels in current movie |
28 | 28 |
uint16_t maxval; ///< maxval of current movie |
29 |
+ uint16_t dataSz; ///< size of data in a frame |
|
29 | 30 |
} AppBbmState; |
30 | 31 |
|
31 | 32 |
/** |
32 | 33 |