diff options
| -rw-r--r-- | snapshot.c | 118 | 
1 files changed, 81 insertions, 37 deletions
| @@ -65,10 +65,28 @@ struct viewfinder {  static struct viewfinder vf = { 0, false, NULL }; -static unsigned int snapshot_interval = 20; -static unsigned int snapshot_count = 0; -static struct timespec snapshot_time; -static bool snapshot_save = false; +enum snapshot_trigger_type { +	SNAPSHOT_TRIGGER_AUTO = 0, +	SNAPSHOT_TRIGGER_MANUAL, +}; + +struct snapshot { +	struct v4l2_mbus_framefmt format; +	struct v4l2_rect crop; + +	unsigned int number; +	unsigned int interval; +	unsigned int count; +	struct timespec time; +	enum snapshot_trigger_type trigger; +	bool save; +}; + +static struct snapshot snap = { +	.crop = { -1, -1, -1, -1 }, +	.number = 1, +	.interval = 20, +};  static struct events events; @@ -99,7 +117,7 @@ static void sigint_handler(int signal __attribute__((__unused__)))  static int snapshot_capture(struct omap3_isp_device *isp)  { -	clock_gettime(CLOCK_MONOTONIC, &snapshot_time); +	clock_gettime(CLOCK_MONOTONIC, &snap.time);  	return omap3_isp_snapshot_capture(isp);  } @@ -116,8 +134,8 @@ static void snapshot_process(struct omap3_isp_device *isp,  		return;  	} -	ts.tv_sec = buffer->timestamp.tv_sec - snapshot_time.tv_sec; -	ts.tv_nsec = (buffer->timestamp.tv_usec * 1000) - snapshot_time.tv_nsec; +	ts.tv_sec = buffer->timestamp.tv_sec - snap.time.tv_sec; +	ts.tv_nsec = (buffer->timestamp.tv_usec * 1000) - snap.time.tv_nsec;  	if (ts.tv_nsec < 0) {  		ts.tv_sec--;  		ts.tv_nsec += 1000000000; @@ -125,8 +143,8 @@ static void snapshot_process(struct omap3_isp_device *isp,  	printf("snapshot captured in %lu.%06lus.\n", ts.tv_sec, ts.tv_nsec / 1000); -	if (snapshot_save) { -		sprintf(name, "snapshot-%06u.bin", snapshot_count); +	if (snap.save) { +		sprintf(name, "snapshot-%06u.bin", snap.count);  		fd = open(name, O_WRONLY | O_CREAT,  			  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);  		if (fd == -1) @@ -138,7 +156,7 @@ static void snapshot_process(struct omap3_isp_device *isp,  requeue:  	/* Requeue the buffer */ -	snapshot_count++; +	snap.count++;  	ret = omap3_isp_snapshot_put_buffer(isp, buffer);  	if (ret < 0) { @@ -147,8 +165,34 @@ requeue:  		return;  	} -	if (!vf.enabled) -		events_stop(&events); +	if (snap.trigger == SNAPSHOT_TRIGGER_AUTO) { +		if (snap.count < snap.number) +			snapshot_capture(isp); +		else +			events_stop(&events); +	} +} + +static int snapshot_init(struct omap3_isp_device *isp) +{ +	struct v4l2_rect *crop; +	int ret; + +	if (snap.crop.width > 0 && snap.crop.height > 0) +		crop = &snap.crop; +	else +		crop = NULL; + +	ret = omap3_isp_snapshot_setup(isp, crop, &snap.format); +	if (ret < 0) { +		printf("error: unable to setup pipeline\n"); +		return ret; +	} + +	printf("snapshot configured for %04x %ux%u\n", +	       snap.format.code, snap.format.width, snap.format.height); + +	return 0;  }  /* ----------------------------------------------------------------------------- @@ -168,7 +212,7 @@ static void viewfinder_process(struct omap3_isp_device *isp,  	vf.count++;  	printf("viewfinder frame %u captured.\n", vf.count); -	if ((vf.count % snapshot_interval) == 0) +	if ((vf.count % snap.interval) == 0)  		snapshot_capture(isp);  	/* Requeue the buffer */ @@ -318,13 +362,15 @@ static void usage(const char *argv0)  	printf("-c, --crop (x,y)/wxh	Set the snapshot capture crop\n");  	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\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("-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' }, @@ -337,34 +383,29 @@ static struct option opts[] = {  int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__)))  { -	struct v4l2_mbus_framefmt snap_format; -	struct v4l2_rect snap_crop;  	struct omap3_isp_device *isp = NULL;  	struct omap3_isp_operations ops;  	struct timespec start, end;  	int exit_code = EXIT_FAILURE; -	bool do_crop = false;  	float fps;  	int ret;  	int c; -	memset(&snap_format, 0, sizeof snap_format); -	snap_format.code = V4L2_MBUS_FMT_SGRBG10_1X10; -	snap_format.width = SNAPSHOT_WIDTH; -	snap_format.height = SNAPSHOT_HEIGHT; +	snap.format.code = V4L2_MBUS_FMT_SGRBG10_1X10; +	snap.format.width = SNAPSHOT_WIDTH; +	snap.format.height = SNAPSHOT_HEIGHT; -	while ((c = getopt_long(argc, argv, "c:f:hi:Ss:v", opts, NULL)) != -1) { +	while ((c = getopt_long(argc, argv, "c:f:hi:n:Ss:v", opts, NULL)) != -1) {  		switch (c) {  		case 'c': -			if (parse_crop(optarg, &snap_crop)) { +			if (parse_crop(optarg, &snap.crop)) {  				printf("invalid crop rectangle %s.\n", optarg);  				return 1;  			} -			do_crop = true;  			break;  		case 'f': -			snap_format.code = parse_format(optarg); -			if (snap_format.code == 0) { +			snap.format.code = parse_format(optarg); +			if (snap.format.code == 0) {  				printf("invalid format %s.\n", optarg);  				return 1;  			} @@ -373,23 +414,31 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu  			usage(argv[0]);  			return 0;  		case 'i': -			snapshot_interval = strtoul(optarg, NULL, 10); -			if (snapshot_interval == 0) { +			snap.interval = strtoul(optarg, NULL, 10); +			if (snap.interval == 0) {  				printf("snapshot interval value 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"); +				return 1; +			} +			break;  		case 'S': -			snapshot_save = true; +			snap.save = true;  			break;  		case 's': -			if (parse_size(optarg, &snap_format)) { +			if (parse_size(optarg, &snap.format)) {  				printf("invalid size %s.\n", optarg);  				return 1;  			}  			break;  		case 'v':  			vf.enabled = true; +			snap.trigger = SNAPSHOT_TRIGGER_MANUAL;  			break;  		default:  			printf("Invalid option -%c\n", c); @@ -425,14 +474,9 @@ int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unu  			goto cleanup;  	} -	ret = omap3_isp_snapshot_setup(isp, do_crop ? &snap_crop : NULL, &snap_format); -	if (ret < 0) { -		printf("error: unable to setup pipeline\n"); +	ret = snapshot_init(isp); +	if (ret < 0)  		goto cleanup; -	} - -	printf("snapshot configured for %04x %ux%u\n", -	       snap_format.code, snap_format.width, snap_format.height);  	/* Start the ISP. */  	if (vf.enabled) | 
