Stefan Schuermans commited on 2012-05-06 18:37:54
Showing 2 changed files, with 34 additions and 2 deletions.
... | ... |
@@ -207,6 +207,7 @@ static void AppBbmProcFrame(AppBbmState *state) |
207 | 207 |
|
208 | 208 |
// read next frame from file |
209 | 209 |
// - read to mcuf pos 10, so data is placed at pos 12 for MCUF frame |
210 |
+ uint32_t pos_before_frame = state->fi.pointer; |
|
210 | 211 |
uint32_t len; |
211 | 212 |
if (DFS_ReadFile(&state->fi, *state->sectorBuf, |
212 | 213 |
pack.mcuf + 10, &len, state->dataSz + 2) != DFS_OK) |
... | ... |
@@ -221,6 +222,11 @@ static void AppBbmProcFrame(AppBbmState *state) |
221 | 222 |
// get frame duration |
222 | 223 |
uint16_t duration = ntohs(*(uint16_t *)(pack.mcuf + 10)); |
223 | 224 |
debug_app_bbm_printf("%hhu: frame duration %u", state->no, duration); |
225 |
+ // subtract time this frame has already been shown |
|
226 |
+ if (state->thisFrameMs < duration) |
|
227 |
+ duration -= state->thisFrameMs; |
|
228 |
+ else |
|
229 |
+ duration = 0; |
|
224 | 230 |
|
225 | 231 |
// fill in MCUF header |
226 | 232 |
*(uint32_t *)(pack.mcuf + 0) = htonl(0x23542666); |
... | ... |
@@ -237,8 +243,31 @@ static void AppBbmProcFrame(AppBbmState *state) |
237 | 243 |
UdpSend((unsigned char *)&pack, sizeof(pack)); |
238 | 244 |
} |
239 | 245 |
|
246 |
+ // frame duration not more than one second |
|
247 |
+ if (duration <= 1000) { |
|
240 | 248 |
// wait for frame duration |
241 | 249 |
state->nextActMs += duration; |
250 |
+ // next time, a new frame will be read |
|
251 |
+ state->thisFrameMs = 0; |
|
252 |
+ // done |
|
253 |
+ return; |
|
254 |
+ } |
|
255 |
+ |
|
256 |
+ // show same frame again in 1 second |
|
257 |
+ |
|
258 |
+ // jump back to position before this frame |
|
259 |
+ DFS_Seek(&state->fi, pos_before_frame, *state->sectorBuf); |
|
260 |
+ if (state->fi.pointer != pos_before_frame) { |
|
261 |
+ // broken file -> use next file in next iteration |
|
262 |
+ state->haveFile = 0; |
|
263 |
+ debug_app_bbm_printf("%hhu: seek failed", state->no); |
|
264 |
+ return; |
|
265 |
+ } |
|
266 |
+ |
|
267 |
+ // next action in 1 second |
|
268 |
+ state->nextActMs += 1000; |
|
269 |
+ // next time, the frame has been shown 1 second longer |
|
270 |
+ state->thisFrameMs += 1000; |
|
242 | 271 |
} |
243 | 272 |
|
244 | 273 |
/** |
... | ... |
@@ -279,6 +308,7 @@ void AppBbmInit(AppBbmState *state) // (extern) |
279 | 308 |
// initialize internal state |
280 | 309 |
state->idxFile = 0; |
281 | 310 |
state->haveFile = 0; |
311 |
+ state->thisFrameMs = 0; |
|
282 | 312 |
|
283 | 313 |
// initialized, start with first action now |
284 | 314 |
state->isInit = 1; |
... | ... |
@@ -301,8 +331,8 @@ void AppBbmRun(AppBbmState *state) // (extern) |
301 | 331 |
long delta = state->nextActMs - ms; |
302 | 332 |
if (delta > 0) |
303 | 333 |
return; |
304 |
- /* do not catch up - this can harm synchronous playback |
|
305 |
- // if lagging behind more than 100ms, do not try to catch up -> advance time |
|
334 |
+ /* do not manipulate frame time - this can harm synchronous playback |
|
335 |
+ // if lagging behind more than 100ms, do not try to catch up |
|
306 | 336 |
if (delta < -100) |
307 | 337 |
state->nextActMs = ms; |
308 | 338 |
*/ |
... | ... |
@@ -28,6 +28,8 @@ typedef struct app_bbm_state { |
28 | 28 |
uint16_t channels; ///< channels in current movie |
29 | 29 |
uint16_t maxval; ///< maxval of current movie |
30 | 30 |
uint16_t dataSz; ///< size of data in a frame |
31 |
+ uint16_t thisFrameMs; /**< time the current frame has already been |
|
32 |
+ shown when next action triggers */ |
|
31 | 33 |
} AppBbmState; |
32 | 34 |
|
33 | 35 |
/** |
34 | 36 |