resend MCUF frame after 1s when playing BBM
Stefan Schuermans

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