diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-02-29 22:23:54 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-04-17 00:12:39 +0200 |
commit | de646638ac9dcf5dc66cf406cd9f0b034875b848 (patch) | |
tree | b68337caef807b60843489cdc50c4290d3c3f32c | |
parent | bd4cbd581047b08d8c3d08118229e0d9109d7bff (diff) |
snapshot: Support capturing multiple frames per snapshot
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r-- | snapshot.c | 78 |
1 files changed, 57 insertions, 21 deletions
@@ -74,9 +74,14 @@ struct snapshot { struct v4l2_mbus_framefmt format; struct v4l2_rect crop; - unsigned int number; + unsigned int cycle; + unsigned int ncycles; + unsigned int frame; + unsigned int nframes; + unsigned int interval; - unsigned int count; + unsigned int skip; + struct timespec time; enum snapshot_trigger_type trigger; bool save; @@ -84,8 +89,10 @@ struct snapshot { static struct snapshot snap = { .crop = { -1, -1, -1, -1 }, - .number = 1, + .ncycles = 1, + .nframes = 3, .interval = 20, + .skip = 2, }; static struct events events; @@ -117,7 +124,12 @@ static void sigint_handler(int signal __attribute__((__unused__))) static int snapshot_capture(struct omap3_isp_device *isp) { + printf("- snapshot %u\n", snap.cycle); + + snap.cycle++; + snap.frame = 0; clock_gettime(CLOCK_MONOTONIC, &snap.time); + return omap3_isp_snapshot_capture(isp); } @@ -125,13 +137,13 @@ static bool snapshot_process(struct omap3_isp_device *isp, struct v4l2_video_buffer *buffer) { static struct timespec ts; - char name[23]; + char name[33]; int ret; int fd; if (buffer->error) { printf("warning: error in dequeued buffer, skipping\n"); - return false; + goto requeue; } ts.tv_sec = buffer->timestamp.tv_sec - snap.time.tv_sec; @@ -141,10 +153,13 @@ static bool snapshot_process(struct omap3_isp_device *isp, ts.tv_nsec += 1000000000; } - printf("snapshot captured in %lu.%06lus.\n", ts.tv_sec, ts.tv_nsec / 1000); + snap.time.tv_sec = buffer->timestamp.tv_sec; + snap.time.tv_nsec = buffer->timestamp.tv_usec * 1000; + + printf("frame captured in %lu.%06lus.\n", ts.tv_sec, ts.tv_nsec / 1000); - if (snap.save) { - sprintf(name, "snapshot-%06u.bin", snap.count); + if (snap.save && snap.frame >= snap.skip) { + sprintf(name, "snapshot-%06u-%02u.bin", snap.cycle, snap.frame); fd = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); if (fd == -1) @@ -156,8 +171,6 @@ static bool snapshot_process(struct omap3_isp_device *isp, requeue: /* Requeue the buffer */ - snap.count++; - ret = omap3_isp_snapshot_put_buffer(isp, buffer); if (ret < 0) { printf("error: unable to requeue buffer: %s (%d)\n", @@ -165,6 +178,13 @@ requeue: return false; } + if (buffer->error) + return true; + + snap.frame++; + if (snap.frame < snap.nframes) + return true; + if (snap.trigger == SNAPSHOT_TRIGGER_AUTO) events_stop(&events); @@ -361,20 +381,24 @@ static void usage(const char *argv0) printf("-f, --format fmt Snapshot format\n"); printf("-h, --help Show this help screen\n"); printf("-i, --interval n Capture a snapshot every n frames (default 20)\n"); - printf("-n, --count n Capture n consecutive snapshots (default 1)\n"); + printf("-k, --skip n Skip n frames per snapshot when saving to disk (default 2)\n"); + printf("-N, --snap-frames n Capture n frames per snapshot (default 3)\n"); + printf("-n, --snap-number n Capture n snapshots (default 1)\n"); printf("-S, --save Save snapshots to disk\n"); printf("-s, --size wxh Set the snapshot capture size\n"); printf("-v, --view Enable viewfinder\n"); } static struct option opts[] = { - { "count", 1, 0, 'n' }, { "crop", 1, 0, 'c' }, { "format", 1, 0, 'f' }, { "help", 0, 0, 'h' }, { "interval", 1, 0, 'i' }, { "save", 0, 0, 'S' }, { "size", 1, 0, 's' }, + { "snap-frames", 1, 0, 'N' }, + { "snap-number", 1, 0, 'n' }, + { "skip", 1, 0, 'k' }, { "view", 1, 0, 'v' }, { 0, 0, 0, 0 } }; @@ -385,7 +409,6 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu struct omap3_isp_operations ops; struct timespec start, end; int exit_code = EXIT_FAILURE; - unsigned int i; float fps; int ret; int c; @@ -394,7 +417,7 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu snap.format.width = SNAPSHOT_WIDTH; snap.format.height = SNAPSHOT_HEIGHT; - while ((c = getopt_long(argc, argv, "c:f:hi:n:Ss:v", opts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "c:f:hi:k:N:n:Ss:v", opts, NULL)) != -1) { switch (c) { case 'c': if (parse_crop(optarg, &snap.crop)) { @@ -419,10 +442,24 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu return 1; } break; + case 'k': + snap.skip = strtoul(optarg, NULL, 10); + if (snap.skip == 0) { + printf("snapshot skip value must be >0.\n"); + return 1; + } + break; + case 'N': + snap.nframes = strtoul(optarg, NULL, 10); + if (snap.nframes == 0) { + printf("number of frames must be >0.\n"); + return 1; + } + break; case 'n': - snap.number = strtoul(optarg, NULL, 10); - if (snap.number == 0) { - printf("snapshots number value must be >0.\n"); + snap.ncycles = strtoul(optarg, NULL, 10); + if (snap.ncycles == 0) { + printf("number of snapshots must be >0.\n"); return 1; } break; @@ -487,9 +524,8 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu /* Main capture loop. */ clock_gettime(CLOCK_MONOTONIC, &start); - for (i = 0; i < snap.number; ++i) { + for (snap.cycle = 0; snap.cycle < snap.ncycles; ) { if (!vf.enabled) { - printf("- snapshot %u\n", i); ret = snapshot_capture(isp); if (ret < 0) goto cleanup; @@ -513,11 +549,11 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu end.tv_nsec += 1000000000; } - fps = (vf.enabled ? vf.count : snap.count) + fps = (vf.count + snap.cycle * snap.frame) / (end.tv_sec + end.tv_nsec / 1000000000.0); printf("%u images processed in %lu.%06lu seconds (%f fps)\n", - vf.enabled ? vf.count : snap.count, + vf.count + snap.cycle * snap.frame, end.tv_sec, end.tv_nsec / 1000, fps); exit_code = EXIT_SUCCESS; |