#define _XOPEN_SOURCE 500 #include #include #include #include #include #include "video_decode.h" #include "util.h" 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 void usage(void) { fprintf(stderr, "cuttime [-adDfhsT] FILE\n" "\n" "OPTIONS\n" "\t-a\tcalculate average color of a frame\n" "\t-d\tcalculate difference between prev and next frame and\n" "\t\tslope of this value\n" "\t-D\tprint diff and slope of diff (implies -d)\n" "\t-f\tprint frame number of every frame\n" "\t-h\tprint this help message\n" "\t-s\tsave frame from detected cut\n" "\t-T\tprint timestamp of every frame\n"); exit(EXIT_FAILURE); } int main(int argc, char **argv) { struct video_decode *vd; struct video_frame *frame_a = NULL, *frame_b = NULL; int ret, ch; int diff_flag = 0, average_flag = 0, frame_flag = 0, showcut_flag = 0; int print_diff_flag = 0, time_flag = 0; int64_t timestamp = 0; double diff = 0.0, prev_diff = 0.0, diff_slope = 0.0; char filename[BUFSIZ]; while ((ch = getopt(argc, argv, "adDfsTh")) != -1) { switch (ch) { case 'a': average_flag = 1; break; case 'd': diff_flag = 1; break; case 'D': print_diff_flag = 1; diff_flag = 1; /* implies -d */ break; case 'f': frame_flag = 1; break; case 's': showcut_flag = 1; break; case 'T': time_flag = 1; break; case 'h': default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc < 1) usage(); if (argc == 2 && strtol(argv[1], NULL, 10) > 0) timestamp = strtol(argv[1], NULL, 10); ret = video_decode_init(&vd, argv[0], timestamp); if (ret < 0) return -ret; ret = video_decode_get_frame(vd, &frame_a); if (ret < 0) return -ret; for (int i = 0; video_decode_get_frame(vd, &frame_b) > 0; ++i) { if (frame_flag) /* print frame number */ printf("%d\t", i); if (time_flag) printf("%" PRId64 "\t", frame_b->dts); if (average_flag) /* print frame average */ printf("%f", frame_average(frame_a)); if (average_flag && diff_flag) printf("\t"); if (diff_flag) { diff = frame_diff(frame_a, frame_b); diff_slope = diff - prev_diff; prev_diff = diff; if (print_diff_flag) printf("%f\t%f\t", diff, diff_slope); } if (diff_slope > 20.0) { start_new_szene(frame_a->dts, frame_b->dts); if (!frame_flag && !average_flag) { printf("\n"); fflush(stdout); } if (showcut_flag == 1) { snprintf(filename, BUFSIZ, "img/%04i.pgm", i); frame_mix(frame_a, frame_b); if (pgm_save(frame_a->data, frame_a->stride, frame_a->width, frame_a->height, filename) < 0) exit(EXIT_FAILURE); } } if (frame_flag || average_flag) { printf("\n"); fflush(stdout); } pswap((void **)&frame_a, (void **)&frame_b); } if (diff_flag) { /* acutally we just finalize the last frame here */ start_new_szene(frame_a->dts, 0); printf("\n"); } video_decode_free_frame(&frame_a); if (frame_b) video_decode_free_frame(&frame_b); video_decode_uninit(&vd); return EXIT_SUCCESS; }