1 /*
2 * This file is part of the OpenKinect Project. http://www.openkinect.org
3 *
4 * Copyright (c) 2010 Brandyn White (bwhite@dappervision.com)
5 *
6 * This code is licensed to you under the terms of the Apache License, version
7 * 2.0, or, at your option, the terms of the GNU General Public License,
8 * version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
9 * or the following URLs:
10 * http://www.apache.org/licenses/LICENSE-2.0
11 * http://www.gnu.org/licenses/gpl-2.0.txt
12 *
13 * If you redistribute this file in source form, modified or unmodified, you
14 * may:
15 * 1) Leave this header intact and distribute it under the same terms,
16 * accompanying it with the APACHE20 and GPL20 files, or
17 * 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
18 * 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
19 * In all cases you must keep the copyright notice intact and include a copy
20 * of the CONTRIB file.
21 *
22 * Binary distributions must follow the binary distribution requirements of
23 * either License.
24 */
25
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <libfreenect.h>
29 #include <stdio.h>
30 #include <signal.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <sys/time.h>
34
35 char *out_dir;
36 volatile sig_atomic_t running = 1;
37 uint32_t last_timestamp = 0;
38 FILE *index_fp = NULL;
39
40
get_time()41 double get_time()
42 {
43 struct timeval cur;
44 gettimeofday(&cur, NULL);
45 return cur.tv_sec + cur.tv_usec / 1000000.;
46 }
47
dump_depth(FILE * fp,void * data,int data_size)48 void dump_depth(FILE *fp, void *data, int data_size)
49 {
50 fprintf(fp, "P5 %d %d 65535\n", FREENECT_FRAME_W, FREENECT_FRAME_H);
51 fwrite(data, data_size, 1, fp);
52 }
53
dump_rgb(FILE * fp,void * data,int data_size)54 void dump_rgb(FILE *fp, void *data, int data_size)
55 {
56 fprintf(fp, "P6 %d %d 255\n", FREENECT_FRAME_W, FREENECT_FRAME_H);
57 fwrite(data, data_size, 1, fp);
58 }
59
open_dump(char type,double cur_time,uint32_t timestamp,int data_size,const char * extension)60 FILE *open_dump(char type, double cur_time, uint32_t timestamp, int data_size, const char *extension)
61 {
62 char *fn = malloc(strlen(out_dir) + 50);
63 sprintf(fn, "%c-%f-%u.%s", type, cur_time, timestamp, extension);
64 fprintf(index_fp, "%s\n", fn);
65 sprintf(fn, "%s/%c-%f-%u.%s", out_dir, type, cur_time, timestamp, extension);
66 FILE* fp = fopen(fn, "w");
67 if (!fp) {
68 printf("Error: Cannot open file [%s]\n", fn);
69 exit(1);
70 }
71 printf("%s\n", fn);
72 free(fn);
73 return fp;
74 }
75
dump(char type,uint32_t timestamp,void * data,int data_size)76 void dump(char type, uint32_t timestamp, void *data, int data_size)
77 {
78 // timestamp can be at most 10 characters, we have a few extra
79 double cur_time = get_time();
80 FILE *fp;
81 last_timestamp = timestamp;
82 switch (type) {
83 case 'd':
84 fp = open_dump(type, cur_time, timestamp, data_size, "pgm");
85 dump_depth(fp, data, data_size);
86 fclose(fp);
87 break;
88 case 'r':
89 fp = open_dump(type, cur_time, timestamp, data_size, "ppm");
90 dump_rgb(fp, data, data_size);
91 fclose(fp);
92 break;
93 case 'a':
94 fp = open_dump(type, cur_time, timestamp, data_size, "dump");
95 fwrite(data, data_size, 1, fp);
96 fclose(fp);
97 break;
98 }
99 }
100
snapshot_accel(freenect_device * dev)101 void snapshot_accel(freenect_device *dev)
102 {
103 if (!last_timestamp)
104 return;
105 freenect_raw_tilt_state* state;
106 freenect_update_tilt_state(dev);
107 state = freenect_get_tilt_state(dev);
108 dump('a', last_timestamp, state, sizeof *state);
109 }
110
111
depth_cb(freenect_device * dev,void * depth,uint32_t timestamp)112 void depth_cb(freenect_device *dev, void *depth, uint32_t timestamp)
113 {
114 dump('d', timestamp, depth, FREENECT_DEPTH_11BIT_SIZE);
115 }
116
117
rgb_cb(freenect_device * dev,void * rgb,uint32_t timestamp)118 void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
119 {
120 dump('r', timestamp, rgb, FREENECT_VIDEO_RGB_SIZE);
121 }
122
init()123 void init()
124 {
125 freenect_context *ctx;
126 freenect_device *dev;
127 if (freenect_init(&ctx, 0)) {
128 printf("Error: Cannot get context\n");
129 return;
130 }
131
132 if (freenect_open_device(ctx, &dev, 0)) {
133 printf("Error: Cannot get device\n");
134 return;
135 }
136 freenect_set_depth_format(dev, FREENECT_DEPTH_11BIT);
137 freenect_start_depth(dev);
138 freenect_set_video_format(dev, FREENECT_VIDEO_RGB);
139 freenect_start_video(dev);
140 freenect_set_depth_callback(dev, depth_cb);
141 freenect_set_video_callback(dev, rgb_cb);
142 while (running && freenect_process_events(ctx) >= 0)
143 snapshot_accel(dev);
144 freenect_stop_depth(dev);
145 freenect_stop_video(dev);
146 freenect_close_device(dev);
147 freenect_shutdown(ctx);
148 }
149
signal_cleanup(int num)150 void signal_cleanup(int num)
151 {
152 running = 0;
153 printf("Caught signal, cleaning up\n");
154 signal(SIGINT, signal_cleanup);
155 }
156
main(int argc,char ** argv)157 int main(int argc, char **argv)
158 {
159 if (argc != 2) {
160 printf("Records the Kinect sensor data to a directory\nResult can be used as input to Fakenect\nUsage: ./record <out_dir>\n");
161 return 1;
162 }
163 out_dir = argv[1];
164 mkdir(out_dir, S_IRWXU | S_IRWXG | S_IRWXO);
165 signal(SIGINT, signal_cleanup);
166 char *fn = malloc(strlen(out_dir) + 50);
167 sprintf(fn, "%s/INDEX.txt", out_dir);
168 index_fp = fopen(fn, "r");
169 if (index_fp) {
170 printf("Error: Index already exists, to avoid overwriting use a different directory.\n");
171 return 1;
172 }
173 index_fp = fopen(fn, "w");
174 if (!index_fp) {
175 printf("Error: Cannot open file [%s]\n", fn);
176 return 1;
177 }
178 free(fn);
179 init();
180 fclose(index_fp);
181 return 0;
182 }
183