From 8bdae5adf908b361447d337cf632f66a3818711c Mon Sep 17 00:00:00 2001 From: Jan Klemkow Date: Thu, 31 Jan 2013 17:11:26 +0100 Subject: add overlap tool --- src/Makefile | 5 +- src/cutting | 2 +- src/draw.plot | 11 +++- src/overlap.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 4 deletions(-) create mode 100644 src/overlap.c 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 +#include +#include +#include + +#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; +} -- cgit