implement adapting maximum frame duration
Stefan Schuermans

Stefan Schuermans commited on 2019-05-02 19:46:26
Showing 5 changed files, with 121 additions and 1 deletions.

... ...
@@ -450,6 +450,8 @@ int main(int argCnt, char **args)
450 450
            "     cut movie to time span from begin (in ms) till end (in ms)\n"
451 451
            "  -dur <duration>\n"
452 452
            "     adapt duration (in ms) of movie\n"
453
+           "  -maxframedur <duration>\n"
454
+           "     adapt maximum duration (in ms) per frame\n"
453 455
            "  -d <first> <count>\n"
454 456
            "     delete frames\n"
455 457
            "  -t <width>x<height>-<channels>/<colors> <test_mode> <duration>\n"
... ...
@@ -728,6 +730,22 @@ int main(int argCnt, char **args)
728 730
       } else
729 731
         printf("missing new duration for movie for \"-dur\"\n");
730 732
     }
733
+    // adapt maximum frame duration
734
+    else if (strcmp(args[i], "-maxframedur") == 0) {
735
+      if (i + 1 < argCnt) {
736
+        unsigned int duration;
737
+        i++;
738
+        if (sscanf(args[i], "%u", &duration) != 1)
739
+          printf("invalid duration \"%s\"\n", args[i]);
740
+        else if (pMovie == NULL)
741
+          printf("no movie loaded to adapt maximum frame duration of\n");
742
+        else {
743
+          BlinkenMovieAdaptMaxFrameDuration(pMovie, duration);
744
+          printf("maximum frame duration adapted to %u ms\n", duration);
745
+        }
746
+      } else
747
+        printf("missing maximum frame duration for \"-maxframedur\"\n");
748
+    }
731 749
     // delete frames
732 750
     else if (strcmp(args[i], "-d") == 0) {
733 751
       if (i + 2 < argCnt) {
... ...
@@ -665,6 +665,89 @@ void BlinkenMovieAdaptDuration(stBlinkenMovie *pMovie,
665 665
   }
666 666
 }
667 667
 
668
+void BlinkenMovieAdaptMaxFrameDuration(stBlinkenMovie *pMovie,
669
+                                       int maxDuration /* in ms */)
670
+{
671
+  int i, j, cmp, dur, lastdur;
672
+  unsigned int extraFrames;
673
+  stBlinkenFrame **ppNewFrames;
674
+  stBlinkenFrame *pNewFrame;
675
+
676
+  if (pMovie == NULL)
677
+    return;
678
+  if (maxDuration < BlinkenDurationMin) {
679
+    maxDuration = BlinkenDurationMin;
680
+  }
681
+  if (maxDuration > BlinkenDurationMax) {
682
+    maxDuration = BlinkenDurationMax;
683
+  }
684
+
685
+  // compute how many extra frames are needed
686
+  extraFrames = 0;
687
+  for (i = 0; i < pMovie->frameCnt; i++) {
688
+    dur = BlinkenFrameGetDuration(pMovie->ppFrames[i]);
689
+    extraFrames += (dur + maxDuration - 1) / maxDuration - 1;
690
+  }
691
+
692
+  // allocate new frame array
693
+  ppNewFrames = (stBlinkenFrame **)BlinkenMalloc1D(pMovie->frameCnt
694
+                                                   + extraFrames,
695
+                                                   sizeof(stBlinkenFrame *));
696
+  if (! ppNewFrames) {
697
+    return;
698
+  }
699
+
700
+  // merge/split frames in time
701
+  j = 0;
702
+  for (i = 0; i < pMovie->frameCnt; i++) {
703
+    // join frame with last one if equal
704
+    if (j > 0) {
705
+      cmp = BlinkenFrameCompare(pMovie->ppFrames[i], ppNewFrames[j - 1]);
706
+      if (cmp == 0) {
707
+        // frame equal to last one
708
+        dur = BlinkenFrameGetDuration(pMovie->ppFrames[i]);
709
+        lastdur = BlinkenFrameGetDuration(ppNewFrames[j - 1]);
710
+        if (lastdur + dur <= maxDuration) {
711
+          // merge frame completely
712
+          BlinkenFrameSetDuration(ppNewFrames[j - 1], lastdur + dur);
713
+          BlinkenFrameFree(pMovie->ppFrames[i]);
714
+          pMovie->ppFrames[i] = NULL;
715
+          continue; // frame completely merged
716
+        } else {
717
+          // move as much duration to previous frame
718
+          BlinkenFrameSetDuration(ppNewFrames[j - 1], maxDuration);
719
+          BlinkenFrameSetDuration(pMovie->ppFrames[i],
720
+                                  lastdur + dur - maxDuration);
721
+        }
722
+      }
723
+    }
724
+    // split frames longer than maxDuration
725
+    while (1) {
726
+      dur = BlinkenFrameGetDuration(pMovie->ppFrames[i]);
727
+      if (dur <= maxDuration) {
728
+        break;
729
+      }
730
+      pNewFrame = BlinkenFrameClone(pMovie->ppFrames[i]);
731
+      if (! pNewFrame) {
732
+        break;
733
+      }
734
+      // add new frame with max duration
735
+      BlinkenFrameSetDuration(pNewFrame, maxDuration);
736
+      ppNewFrames[j++] = pNewFrame;
737
+      // reduce duration of current frame
738
+      BlinkenFrameSetDuration(pMovie->ppFrames[i], dur - maxDuration);
739
+    } // while (1)
740
+    // overtake current frame
741
+    ppNewFrames[j++] = pMovie->ppFrames[i];
742
+    pMovie->ppFrames[i] = NULL;
743
+  } // for (i ...
744
+
745
+  // use new frames array in movie
746
+  free(pMovie->ppFrames);
747
+  pMovie->ppFrames = ppNewFrames;
748
+  pMovie->frameCnt = j;
749
+}
750
+
668 751
 void BlinkenMovieResize(stBlinkenMovie *pMovie, int height, int width,
669 752
                         int channels, int maxval)
670 753
 {
... ...
@@ -64,6 +64,8 @@ void BlinkenMovieCutTime(stBlinkenMovie *pMovie,
64 64
                          int begin /* in ms */, int end /* in ms */);
65 65
 void BlinkenMovieAdaptDuration(stBlinkenMovie *pMovie,
66 66
                                int duration /* in ms */);
67
+void BlinkenMovieAdaptMaxFrameDuration(stBlinkenMovie *pMovie,
68
+                                       int maxDuration /* in ms */);
67 69
 
68 70
 void BlinkenMovieResize(stBlinkenMovie *pMovie, int height, int width,
69 71
                         int channels, int maxval);
... ...
@@ -0,0 +1,17 @@
1
+# BlinkenLights Movie 5x1
2
+
3
+@100
4
+10000
5
+
6
+@200
7
+11000
8
+
9
+@300
10
+11100
11
+
12
+@400
13
+11110
14
+
15
+@500
16
+11111
17
+
... ...
@@ -1,5 +1,5 @@
1 1
 VERSION_MAJOR:=0
2 2
 VERSION_MINOR:=7
3
-VERSION_REVISION:=9
3
+VERSION_REVISION:=10
4 4
 VERSION:=$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_REVISION)
5 5
 
6 6