record.c
Go to the documentation of this file.
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 "libfreenect.h"
27 #include "platform.h"
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <signal.h>
32 #include <string.h>
33 #include <stdlib.h>
34 
35 char *out_dir=0;
36 volatile sig_atomic_t running = 1;
38 FILE *index_fp = NULL;
39 
40 #define FREENECT_FRAME_W 640
41 #define FREENECT_FRAME_H 480
42 
43 int use_ffmpeg = 0;
44 char *ffmpeg_opts = 0;
45 char *depth_name = 0;
46 char *rgb_name = 0;
47 
48 FILE *depth_stream=0;
49 FILE *rgb_stream=0;
50 
51 void dump_depth(FILE *fp, void *data, int data_size)
52 {
53  fprintf(fp, "P5 %d %d 65535\n", FREENECT_FRAME_W, FREENECT_FRAME_H);
54  fwrite(data, data_size, 1, fp);
55 }
56 
57 void dump_rgb(FILE *fp, void *data, int data_size)
58 {
59  fprintf(fp, "P6 %d %d 255\n", FREENECT_FRAME_W, FREENECT_FRAME_H);
60  fwrite(data, data_size, 1, fp);
61 }
62 
63 FILE *open_dump(char type, double cur_time, uint32_t timestamp, int data_size, const char *extension)
64 {
65  char *fn = malloc(strlen(out_dir) + 50);
66  sprintf(fn, "%c-%f-%u.%s", type, cur_time, timestamp, extension);
67  fprintf(index_fp, "%s\n", fn);
68  sprintf(fn, "%s/%c-%f-%u.%s", out_dir, type, cur_time, timestamp, extension);
69  FILE* fp = fopen(fn, "wb");
70  if (!fp) {
71  printf("Error: Cannot open file [%s]\n", fn);
72  exit(1);
73  }
74  printf("%s\n", fn);
75  free(fn);
76  return fp;
77 }
78 
79 FILE *open_ffmpeg(char *output_filename)
80 {
81  char cmd[1024];
82 
83  if (ffmpeg_opts==0)
84  ffmpeg_opts = "-aspect 4:3 -r 20 -vcodec msmpeg4 -b 30000k";
85 
86  snprintf(cmd, 1024, "ffmpeg -pix_fmt rgb24 -s %dx%d -f rawvideo "
87  "-i /dev/stdin %s %s",
89  ffmpeg_opts, output_filename);
90 
91  fprintf(stderr, "%s\n", cmd);
92 
93  FILE* proc = popen(cmd, "w");
94  if (!proc) {
95  printf("Error: Cannot run ffmpeg\n");
96  exit(1);
97  }
98 
99  return proc;
100 }
101 
102 void dump(char type, uint32_t timestamp, void *data, int data_size)
103 {
104  // timestamp can be at most 10 characters, we have a few extra
105  double cur_time = get_time();
106  FILE *fp;
107  last_timestamp = timestamp;
108  switch (type) {
109  case 'd':
110  fp = open_dump(type, cur_time, timestamp, data_size, "pgm");
111  dump_depth(fp, data, data_size);
112  fclose(fp);
113  break;
114  case 'r':
115  fp = open_dump(type, cur_time, timestamp, data_size, "ppm");
116  dump_rgb(fp, data, data_size);
117  fclose(fp);
118  break;
119  case 'a':
120  fp = open_dump(type, cur_time, timestamp, data_size, "dump");
121  fwrite(data, data_size, 1, fp);
122  fclose(fp);
123  break;
124  }
125 }
126 
127 void dump_ffmpeg_24(FILE *stream, uint32_t timestamp, void *data,
128  int data_size)
129 {
130  fwrite(data, data_size, 1, stream);
131 }
132 
133 void dump_ffmpeg_pad16(FILE *stream, uint32_t timestamp, void *data,
134  int data_size)
135 {
136  unsigned int z = 0;
137  uint16_t* data_ptr = (uint16_t*)data;
138  uint16_t* end = data_ptr + data_size;
139  while (data_ptr < end) {
140  z = *data_ptr;
141  fwrite(((char*)(&z)), 3, 1, stream);
142  data_ptr += 2;
143  }
144 }
145 
147 {
149  if (!last_timestamp)
150  return;
152  state = freenect_get_tilt_state(dev);
153  dump('a', last_timestamp, state, sizeof *state);
154 }
155 
156 
157 void depth_cb(freenect_device *dev, void *depth, uint32_t timestamp)
158 {
159  dump('d', timestamp, depth, freenect_get_current_depth_mode(dev).bytes);
160 }
161 
162 
163 void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
164 {
165  dump('r', timestamp, rgb, freenect_get_current_video_mode(dev).bytes);
166 }
167 
168 void depth_cb_ffmpeg(freenect_device *dev, void *depth, uint32_t timestamp)
169 {
170  double cur_time = get_time();
171  fprintf(index_fp, "d-%f-%u\n", cur_time, timestamp);
172 
173  dump_ffmpeg_pad16(depth_stream, timestamp, depth,
175  FREENECT_DEPTH_11BIT).bytes);
176 }
177 
178 void rgb_cb_ffmpeg(freenect_device *dev, void *rgb, uint32_t timestamp)
179 {
180  double cur_time = get_time();
181  fprintf(index_fp, "d-%f-%u\n", cur_time, timestamp);
182 
183  dump_ffmpeg_24(rgb_stream, timestamp, rgb,
185 }
186 
188 {
191 }
192 
193 void print_mode(const char *name, freenect_frame_mode mode) {
194  /* This is just a courtesy function to let the user know the mode
195  if it becomes a bother for maintainability just comment out the
196  code in its body. It will only break if struct entries go missing.
197  */
198  printf("%s Mode: {%d, %d, {%d}, %d, %d, %d, %d, %d, %d, %d}\n", name,
199  mode.reserved, (int)mode.resolution, (int)mode.video_format, mode.bytes, mode.width,
201  mode.framerate, mode.is_valid);
202 }
203 
204 void init()
205 {
207  freenect_device *dev;
208  if (freenect_init(&ctx, 0)) {
209  printf("Error: Cannot get context\n");
210  return;
211  }
212 
213  // fakenect doesn't support audio yet, so don't bother claiming the device
215 
216  if (freenect_open_device(ctx, &dev, 0)) {
217  printf("Error: Cannot get device\n");
218  return;
219  }
226  if (use_ffmpeg) {
230  } else {
233  }
234  while (running && freenect_process_events(ctx) >= 0)
235  snapshot_accel(dev);
236  freenect_stop_depth(dev);
237  freenect_stop_video(dev);
239  freenect_shutdown(ctx);
240 }
241 
242 FILE *open_index(const char *fn)
243 {
244  FILE *fp = fopen(fn, "r");
245  if (fp) {
246  fclose(fp);
247  printf("Error: Index already exists, to avoid overwriting "
248  "use a different directory.\n");
249  return 0;
250  }
251  fp = fopen(fn, "wb");
252  if (!fp) {
253  printf("Error: Cannot open file [%s]\n", fn);
254  return 0;
255  }
256  return fp;
257 }
258 
259 void signal_cleanup(int num)
260 {
261  running = 0;
262  printf("Caught signal, cleaning up\n");
263  signal(SIGINT, signal_cleanup);
264 }
265 
266 void usage()
267 {
268  printf("Records the Kinect sensor data to a directory\nResult can be used as input to Fakenect\nUsage:\n");
269  printf(" record [-h] [-ffmpeg] [-ffmpeg-opts <options>] "
270  "<target basename>\n");
271  exit(0);
272 }
273 
274 int main(int argc, char **argv)
275 {
276  int c=1;
277  while (c < argc) {
278  if (strcmp(argv[c],"-ffmpeg")==0)
279  use_ffmpeg = 1;
280  else if (strcmp(argv[c],"-ffmpeg-opts")==0) {
281  if (++c < argc)
282  ffmpeg_opts = argv[c];
283  } else if (strcmp(argv[c],"-h")==0)
284  usage();
285  else
286  out_dir = argv[c];
287  c++;
288  }
289 
290  if (!out_dir)
291  usage();
292 
293  signal(SIGINT, signal_cleanup);
294 
295  if (use_ffmpeg) {
296  FILE *f;
297 
298  char *index_fn = malloc(strlen(out_dir) + 50);
299  sprintf(index_fn, "%s-index.txt", out_dir);
300  index_fp = open_index(index_fn);
301  free(index_fn);
302  if (!index_fp)
303  return 1;
304 
305  depth_name = malloc(strlen(out_dir) + 50);
306  rgb_name = malloc(strlen(out_dir) + 50);
307  sprintf(depth_name, "%s-depth.avi", out_dir);
308  sprintf(rgb_name, "%s-rgb.avi", out_dir);
309 
310  f = fopen(depth_name, "r");
311  if (f) {
312  printf("Error: %s already exists, to avoid overwriting "
313  "use a different name.\n", depth_name);
314  fclose(f);
315  exit(1);
316  }
317  f = fopen(rgb_name, "r");
318  if (f) {
319  printf("Error: %s already exists, to avoid overwriting "
320  "use a different name.\n", depth_name);
321  fclose(f);
322  exit(1);
323  }
324  init();
325  free(depth_name);
326  free(rgb_name);
327  if (depth_stream) fclose(depth_stream);
328  if (rgb_stream) fclose(rgb_stream);
329  fclose(index_fp);
330  } else {
331 #ifdef _WIN32
332  _mkdir(out_dir);
333 #else
334  mkdir(out_dir, S_IRWXU | S_IRWXG | S_IRWXO);
335 #endif
336  char *fn = malloc(strlen(out_dir) + 50);
337  sprintf(fn, "%s/INDEX.txt", out_dir);
338  index_fp = open_index(fn);
339  free(fn);
340  if (!index_fp) {
341  fclose(index_fp);
342  return 1;
343  }
344 
345  init();
346  fclose(index_fp);
347  }
348  return 0;
349 }
void init()
Definition: record.c:204
void freenect_set_video_callback(freenect_device *dev, freenect_video_cb cb)
Definition: fakenect.c:241
void depth_cb(freenect_device *dev, void *depth, uint32_t timestamp)
Definition: record.c:157
void freenect_select_subdevices(freenect_context *ctx, freenect_device_flags subdevs)
Definition: fakenect.c:338
void dump_ffmpeg_pad16(FILE *stream, uint32_t timestamp, void *data, int data_size)
Definition: record.c:133
#define FREENECT_FRAME_W
Definition: record.c:40
int freenect_stop_video(freenect_device *dev)
Definition: fakenect.c:383
void print_mode(const char *name, freenect_frame_mode mode)
Definition: record.c:193
void dump_ffmpeg_24(FILE *stream, uint32_t timestamp, void *data, int data_size)
Definition: record.c:127
void dump_rgb(FILE *fp, void *data, int data_size)
Definition: record.c:57
void init_ffmpeg_streams()
Definition: record.c:187
char * ffmpeg_opts
Definition: record.c:44
unsigned short uint16_t
int8_t data_bits_per_pixel
Definition: libfreenect.h:140
uint32_t last_timestamp
Definition: record.c:37
int use_ffmpeg
Definition: record.c:43
void depth_cb_ffmpeg(freenect_device *dev, void *depth, uint32_t timestamp)
Definition: record.c:168
#define FREENECT_FRAME_H
Definition: record.c:41
int freenect_start_depth(freenect_device *dev)
Definition: fakenect.c:365
FILE * open_index(const char *fn)
Definition: record.c:242
int freenect_shutdown(freenect_context *ctx)
Definition: fakenect.c:402
char * out_dir
Definition: record.c:35
FILE * open_ffmpeg(char *output_filename)
Definition: record.c:79
void usage()
Definition: record.c:266
int freenect_set_video_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:246
void freenect_set_depth_callback(freenect_device *dev, freenect_depth_cb cb)
Definition: fakenect.c:236
int freenect_start_video(freenect_device *dev)
Definition: fakenect.c:371
volatile sig_atomic_t running
Definition: record.c:36
freenect_frame_mode freenect_find_video_mode(freenect_resolution res, freenect_video_format fmt)
Definition: fakenect.c:260
freenect_frame_mode freenect_get_current_depth_mode(freenect_device *dev)
Definition: fakenect.c:303
int main(int argc, char **argv)
Definition: record.c:274
char * rgb_name
Definition: record.c:46
FILE * open_dump(char type, double cur_time, uint32_t timestamp, int data_size, const char *extension)
Definition: record.c:63
freenect_frame_mode freenect_find_depth_mode(freenect_resolution res, freenect_depth_format fmt)
Definition: fakenect.c:284
void dump(char type, uint32_t timestamp, void *data, int data_size)
Definition: record.c:102
FILE * depth_stream
Definition: record.c:48
void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
Definition: record.c:163
char * depth_name
Definition: record.c:45
freenect_raw_tilt_state * freenect_get_tilt_state(freenect_device *dev)
Definition: fakenect.c:217
int freenect_update_tilt_state(freenect_device *dev)
Definition: fakenect.c:418
void dump_depth(FILE *fp, void *data, int data_size)
Definition: record.c:51
int freenect_close_device(freenect_device *dev)
Definition: fakenect.c:406
int freenect_set_depth_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: fakenect.c:253
freenect_frame_mode freenect_get_current_video_mode(freenect_device *dev)
Definition: fakenect.c:279
int freenect_open_device(freenect_context *ctx, freenect_device **dev, int index)
Definition: fakenect.c:314
void rgb_cb_ffmpeg(freenect_device *dev, void *rgb, uint32_t timestamp)
Definition: record.c:178
double get_time()
Definition: platform.h:39
static freenect_context * ctx
Data from the tilt motor and accelerometer.
Definition: libfreenect.h:167
FILE * rgb_stream
Definition: record.c:49
unsigned int uint32_t
int8_t padding_bits_per_pixel
Definition: libfreenect.h:141
void signal_cleanup(int num)
Definition: record.c:259
capture state
Definition: micview.c:53
freenect_device_flags
Definition: libfreenect.h:58
int freenect_stop_depth(freenect_device *dev)
Definition: fakenect.c:377
FILE * index_fp
Definition: record.c:38
freenect_resolution resolution
Definition: libfreenect.h:131
void snapshot_accel(freenect_device *dev)
Definition: record.c:146
int freenect_process_events(freenect_context *ctx)
Definition: fakenect.c:140
freenect_video_format video_format
Definition: libfreenect.h:134
int freenect_init(freenect_context **ctx, freenect_usb_context *usb_ctx)
Definition: fakenect.c:327


libfreenect
Author(s): Hector Martin, Josh Blake, Kyle Machulis, OpenKinect community
autogenerated on Thu Jun 6 2019 19:25:38