summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Klemkow <j.klemkow@wemelug.de>2013-01-31 17:11:26 +0100
committerJan Klemkow <j.klemkow@wemelug.de>2013-01-31 17:11:26 +0100
commit8bdae5adf908b361447d337cf632f66a3818711c (patch)
tree93fc7a1844e11c6e26ea0f4e5df07411f83463f5
parent3da25dec5a11e2a36d5d663c9bff0166775b92e1 (diff)
downloadadvtime-8bdae5adf908b361447d337cf632f66a3818711c.tar.gz
advtime-8bdae5adf908b361447d337cf632f66a3818711c.tar.bz2
advtime-8bdae5adf908b361447d337cf632f66a3818711c.zip
add overlap tool
-rw-r--r--src/Makefile5
-rwxr-xr-xsrc/cutting2
-rw-r--r--src/draw.plot11
-rw-r--r--src/overlap.c171
4 files changed, 185 insertions, 4 deletions
diff --git a/src/Makefile b/src/Makefile
index 9e6624a..d2e6a94 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,11 +3,14 @@ CFLAGS=-ggdb -std=c99 -Wall -Wstrict-prototypes -Wmissing-prototypes \
LIBAV_DECODE_FLAGS=`pkg-config --libs --cflags libavformat libavcodec \
libavutil libswscale`
-all: advtime decode_frame frame_to_pgm
+all: advtime overlap decode_frame frame_to_pgm
advtime: advtime.c video_decode.c util.c
gcc $(CFLAGS) $(LIBAV_DECODE_FLAGS) advtime.c video_decode.c util.c -o $@
+overlap: overlap.c video_decode.c util.c
+ gcc $(CFLAGS) $(LIBAV_DECODE_FLAGS) overlap.c video_decode.c util.c -o $@
+
decode_frame: decode_frame.c
gcc $(CFLAGS) $(LIBAV_DECODE_FLAGS) decode_frame.c -o $@
diff --git a/src/cutting b/src/cutting
index eb555fd..811f10e 100755
--- a/src/cutting
+++ b/src/cutting
@@ -15,5 +15,5 @@ do
i=$((i+1))
param=$(printf -- "-ss %s -t %s" $time)
- ee ffmpeg -y -i $FILE -sameq $param `printf "outfile-%02d.mpg" $i`
+ ffmpeg -y -i $FILE -sameq $param `printf "outfile-%02d.mpg" $i`
done
diff --git a/src/draw.plot b/src/draw.plot
index dc8a538..77ca447 100644
--- a/src/draw.plot
+++ b/src/draw.plot
@@ -1,8 +1,15 @@
# draw frame diff graph
-#set terminal svg size 800,600 dynamic;
-#set output "graph.svg";
+set terminal svg size 800,600 dynamic;
+set output "graph.svg";
plot 'data.txt' using 2 with lines lt rgb "#204a87" title "average", \
'data.txt' using 3 with lines lt rgb "#a40000" title "diff", \
'data.txt' using 4 with lines lt rgb "#4e9a06" title "rise";
+
+set output "overlap.svg";
+set xrange [0:100000]
+
+plot 'overlap.txt' using 1:2 with lines lt rgb "#204a87" title "diff"
+
+# vim: set syntax=gnuplot :
diff --git a/src/overlap.c b/src/overlap.c
new file mode 100644
index 0000000..94fd9f5
--- /dev/null
+++ b/src/overlap.c
@@ -0,0 +1,171 @@
+#define _XOPEN_SOURCE 500
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "video_decode.h"
+#include "util.h"
+
+static inline void
+pswap(void **p1, void **p2)
+{
+ void *tmp;
+
+ tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+/* print time in format: "hh:mm:ss.xxx" */
+static void
+print_time(int64_t msec) {
+
+ int hh = msec / 1000 / 60 / 60;
+ msec -= hh * 1000 * 60 * 60;
+ int mm = msec / 1000 / 60;
+ msec -= mm * 1000 * 60;
+ int ss = msec / 1000;
+ msec -= ss * 1000;
+
+ printf("%02d:%02d:%02d.%03jd", hh, mm, ss, msec);
+}
+
+static void
+start_new_szene(int64_t prev_szene_end, int64_t start)
+{
+ static int prev_dts_start = 0;
+
+ print_time(prev_dts_start);
+ printf(" ");
+ print_time(prev_szene_end - prev_dts_start);
+ prev_dts_start = start;
+}
+
+static double
+frame_diff(struct video_frame *frame_a, struct video_frame *frame_b)
+{
+ double average = 0;
+ uint8_t *row_a = frame_a->data, *col_a = NULL;
+ uint8_t *row_b = frame_b->data, *col_b = NULL;
+
+ for (int y = 0; y < frame_a->height; ++y) {
+ col_a = row_a;
+ col_b = row_b;
+ for (int x = 0; x < frame_a->width; ++x) {
+ average += abs(*col_a - *col_b);
+ col_a++;
+ col_b++;
+ }
+ row_a += frame_a->stride;
+ row_b += frame_b->stride;
+ }
+
+ return average / (frame_a->width * frame_a->height);
+}
+
+static double
+frame_average(struct video_frame *frame)
+{
+ double average = 0;
+ uint8_t *row = frame->data;
+ uint8_t *col = NULL;
+
+ for (int y = 0; y < frame->height; ++y) {
+ col = row;
+ for (int x = 0; x < frame->width; ++x) {
+ average += *col;
+ col++;
+ }
+ row += frame->stride;
+ }
+
+ return average / (frame->width * frame->height);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "overlap [OPTIONS] FIRST_VIDEO SECOND_VIDEO\n"
+ "\n"
+ "OPTIONS\n"
+ "\t-d\tprint diff for every frame\n"
+ "\t-t\tmax duration to find overlap in milliseconds\n"
+ "\t\t(default 60000 = 1 min)\n");
+
+ exit(EXIT_FAILURE);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct video_decode *first_vd;
+ struct video_decode *second_vd;
+ struct video_frame *cur_frame = NULL, *last_frame = NULL;
+// struct video_frame last_frames[5] = {0};
+ int ret, ch;
+ int diff_flag = 0;
+ int64_t timestamp = 0;
+ int64_t duration = 60 * 1000; /* duration for searching min_diff */
+ /* 60 sec * 1000 msec = 1 min */
+ int64_t min_diff_time = 0; /* dts at overlaping frame */
+ double min_diff, diff = 0.0;
+
+ while ((ch = getopt(argc, argv, "dt")) != -1) {
+ switch (ch) {
+ case 'd':
+ diff_flag = 1; /* print diff of every frame */
+ break;
+ case 't':
+ duration = strtol(optarg, NULL, 10);
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 2)
+ usage();
+
+// if (argc == 2 && strtol(argv[1], NULL, 10) > 0)
+// timestamp = strtol(argv[1], NULL, 10);
+
+ ret = video_decode_init(&first_vd, argv[0], timestamp);
+ if (ret < 0)
+ return -ret;
+
+ /* just get last frame of move */
+ for (int i = 0; video_decode_get_frame(first_vd, &cur_frame) > 0; ++i)
+ pswap((void **)&cur_frame, (void **)&last_frame);
+
+ ret = video_decode_init(&second_vd, argv[1], timestamp);
+
+ for (int i = 0; video_decode_get_frame(second_vd, &cur_frame) > 0; ++i){
+ diff = frame_diff(last_frame, cur_frame);
+
+ if (i == 0 || diff <= min_diff) {
+ min_diff = diff;
+ min_diff_time = cur_frame->dts;
+ }
+
+ if (diff_flag)
+ printf("%ji %f\n", cur_frame->dts, diff);
+
+ if (cur_frame->dts > duration)
+ break;
+ }
+
+ if (!diff_flag) {
+ print_time(min_diff_time);
+ printf("\n");
+ }
+
+ video_decode_free_frame(&cur_frame);
+ video_decode_free_frame(&last_frame);
+ video_decode_uninit(&first_vd);
+ video_decode_uninit(&second_vd);
+ return EXIT_SUCCESS;
+}