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/overlap.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 src/overlap.c (limited to 'src/overlap.c') 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