implement cutting movie in time
Stefan Schuermans

Stefan Schuermans commited on 2014-05-10 15:48:33
Showing 3 changed files, with 126 additions and 3 deletions.

... ...
@@ -261,10 +261,12 @@ int main(int argCnt, char **args)
261 261
            "     colorize movie\n"
262 262
            "  -R\n"
263 263
            "     reverse movie\n"
264
+           "  -ct <begin> <end>\n"
265
+           "     cut movie to time span from begin (in ms) till end (in ms)\n"
264 266
            "  -d <first> <count>\n"
265 267
            "     delete frames\n"
266 268
            "  -t <width>x<height>-<channels>/<colors> <test_mode> <duration>\n"
267
-           "     generate a test movie\n"
269
+           "     generate a test movie (duration in ms)\n"
268 270
            "  -ta <test_mode> <duration>\n"
269 271
            "     generate a test movie and append it to current video\n"
270 272
            "  -C <file> <src-x>,<src-y> <width>x<height> <dest-x>,<dest-y>\n"
... ...
@@ -495,6 +497,32 @@ int main(int argCnt, char **args)
495 497
         printf("movie reversed\n");
496 498
       }
497 499
     }
500
+    // cut movie to time span
501
+    else if (strcmp(args[i], "-ct") == 0) {
502
+      if (i + 2 < argCnt) {
503
+        const char *str_begin, *str_end;
504
+        unsigned int begin, end;
505
+        i++;
506
+        str_begin = args[i];
507
+        i++;
508
+        str_end = args[i];
509
+        if (sscanf(str_begin, "%u", &begin) != 1)
510
+          printf("invalid begin time \"%s\"\n", str_begin);
511
+        else if (sscanf(str_end, "%u", &end) != 1)
512
+          printf("invalid end time \"%s\"\n", str_end);
513
+        else if (pMovie == NULL)
514
+          printf("no movie loaded to cut to time span\n");
515
+        else {
516
+          BlinkenMovieCutTime(pMovie, begin, end);
517
+          printf("movie cut to time %u-%u\n", begin, end);
518
+        }
519
+      }
520
+      else if (i + 1 < argCnt) {
521
+        printf("missing end time for \"-ct\"\n");
522
+        i++;
523
+      } else
524
+        printf("missing begin time for \"-ct\"\n");
525
+    }
498 526
     // delete frames
499 527
     else if (strcmp(args[i], "-d") == 0) {
500 528
       if (i + 2 < argCnt) {
... ...
@@ -524,10 +552,10 @@ int main(int argCnt, char **args)
524 552
           }
525 553
         }
526 554
       } else if (i + 1 < argCnt) {
527
-        printf("missing colorizing mode for \"-c\"\n");
555
+        printf("missing number of frames for \"-d\"\n");
528 556
         i++;
529 557
       } else
530
-        printf("missing number of channels for \"-c\"\n");
558
+        printf("missing number of first frame for \"-d\"\n");
531 559
     }
532 560
     // generate test movie
533 561
     else if (strcmp(args[i], "-t") == 0) {
... ...
@@ -533,6 +533,99 @@ void BlinkenMovieReverse(stBlinkenMovie *pMovie)
533 533
   }
534 534
 }
535 535
 
536
+void BlinkenMovieCutTime(stBlinkenMovie *pMovie,
537
+                         int begin /* in ms */, int end /* in ms */)
538
+{
539
+  int i, duration, curtime, idx_begin, idx_end, duration_begin, duration_end;
540
+  int frameCnt;
541
+  stBlinkenFrame **ppNewFrames;
542
+
543
+  // do nothing if empty movie
544
+  if (pMovie->frameCnt < 1)
545
+    return;
546
+
547
+  // get movie duration
548
+  duration = 0;
549
+  for (i = 0; i < pMovie->frameCnt; i++)
550
+    duration += BlinkenFrameGetDuration(pMovie->ppFrames[i]);
551
+
552
+  // sanitize inputs
553
+  if (begin < 0)
554
+    begin = 0;
555
+  if (begin > duration)
556
+    begin = duration;
557
+  if (end < begin)
558
+    end = begin;
559
+  if (end > duration)
560
+    end = duration;
561
+
562
+  // get begin and end indices, also get duration of begin and end frames
563
+  if (begin >= end) {
564
+    // empty result movie
565
+    idx_begin = 1;
566
+    idx_end = 0;
567
+    duration_begin = 0;
568
+    duration_end = 0;
569
+  } else {
570
+    // at least one frame in result movie
571
+    curtime = 0;
572
+    idx_begin = 0;
573
+    duration_begin = BlinkenFrameGetDuration(pMovie->ppFrames[idx_begin]);
574
+    idx_end = pMovie->frameCnt - 1;
575
+    duration_end = BlinkenFrameGetDuration(pMovie->ppFrames[idx_end]);
576
+    for (i = 0; i < pMovie->frameCnt; i++) {
577
+      duration = BlinkenFrameGetDuration(pMovie->ppFrames[i]);
578
+      // begin and end in current frame
579
+      if (curtime <= begin && curtime + duration >= end) {
580
+        idx_begin = i;
581
+        idx_end = i;
582
+        duration_begin = end - begin;
583
+        duration_end = end - begin;
584
+        break;
585
+      }
586
+      // begin in current frame
587
+      if (curtime <= begin && curtime + duration > begin) {
588
+        idx_begin = i;
589
+        duration_begin = curtime + duration - begin;
590
+      }
591
+      // end in current frame
592
+      if (curtime < end && curtime + duration >= end) {
593
+        idx_end = i;
594
+        duration_end = end - curtime;
595
+        break;
596
+      }
597
+      curtime += duration;
598
+    }
599
+  }
600
+
601
+  printf("DEBUG bi=%u ei=%u bd=%u ed=%u\n", idx_begin, idx_end, duration_begin, duration_end);
602
+
603
+  // remove/free unneeded frames
604
+
605
+  frameCnt = idx_end - idx_begin + 1;
606
+  ppNewFrames = (stBlinkenFrame **)BlinkenMalloc1D(frameCnt,
607
+                                                   sizeof(stBlinkenFrame *));
608
+  if (ppNewFrames == NULL)
609
+    return;
610
+
611
+  for (i = 0; i < idx_begin; i++)
612
+    BlinkenFrameFree(pMovie->ppFrames[i]);
613
+  for (; i <= idx_end; i++)
614
+    ppNewFrames[i - idx_begin] = pMovie->ppFrames[i];
615
+  for (; i < pMovie->frameCnt; i++)
616
+    BlinkenFrameFree(pMovie->ppFrames[i]);
617
+
618
+  free(pMovie->ppFrames);
619
+  pMovie->ppFrames = ppNewFrames;
620
+  pMovie->frameCnt = frameCnt;
621
+
622
+  // change duration of begin and end frame
623
+  if (frameCnt > 0) {
624
+    BlinkenFrameSetDuration(pMovie->ppFrames[0], duration_begin);
625
+    BlinkenFrameSetDuration(pMovie->ppFrames[frameCnt - 1], duration_end);
626
+  }
627
+}
628
+
536 629
 void BlinkenMovieResize(stBlinkenMovie *pMovie, int height, int width,
537 630
                         int channels, int maxval)
538 631
 {
... ...
@@ -60,6 +60,8 @@ void BlinkenMovieDeleteFrames(stBlinkenMovie *pMovie);
60 60
 int BlinkenMovieConcat(stBlinkenMovie *pMovie,
61 61
                        stBlinkenMovie *pMovie2 /* appended and freed */);
62 62
 void BlinkenMovieReverse(stBlinkenMovie *pMovie);
63
+void BlinkenMovieCutTime(stBlinkenMovie *pMovie,
64
+                         int begin /* in ms */, int end /* in ms */);
63 65
 
64 66
 void BlinkenMovieResize(stBlinkenMovie *pMovie, int height, int width,
65 67
                         int channels, int maxval);
66 68