#define _XOPEN_SOURCE 500 #include #include #include #include #include "video_decode.h" #include "util.h" 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, "advtime [-a] [-d] FILE\n"); exit(EXIT_FAILURE); } int main(int argc, char **argv) { struct video_decode *vd; struct video_frame *frame_a; struct video_frame *frame_b; int ret, ch; int diff_flag = 0, average_flag = 0; int64_t timestamp = 0; double diff = 0.0; char filename[BUFSIZ]; while ((ch = getopt(argc, argv, "ad")) != -1) { switch (ch) { case 'a': average_flag = 1; break; case 'd': diff_flag = 1; break; 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) { printf("%d\t", i); if (average_flag == 1) printf("%f", frame_average(frame_a)); if (average_flag == 1 && diff_flag == 1) printf("\t"); if (diff_flag == 1) printf("%f", diff = frame_diff(frame_a, frame_b)); if (diff > 40.0) { 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); } printf("\n"); video_decode_free_frame(&frame_a); frame_a = frame_b; } video_decode_free_frame(&frame_b); video_decode_uninit(&vd); return EXIT_SUCCESS; }