summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-02-29 22:23:54 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-04-17 00:12:39 +0200
commitde646638ac9dcf5dc66cf406cd9f0b034875b848 (patch)
treeb68337caef807b60843489cdc50c4290d3c3f32c
parentbd4cbd581047b08d8c3d08118229e0d9109d7bff (diff)
snapshot: Support capturing multiple frames per snapshot
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--snapshot.c78
1 files changed, 57 insertions, 21 deletions
diff --git a/snapshot.c b/snapshot.c
index 7a0302e..9763d6e 100644
--- a/snapshot.c
+++ b/snapshot.c
@@ -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;