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); |