2
* This file is part of the OpenKinect Project. http://www.openkinect.org
4
* Copyright (c) 2010 individual OpenKinect contributors. See the CONTRIB file
7
* This code is licensed to you under the terms of the Apache License, version
8
* 2.0, or, at your option, the terms of the GNU General Public License,
9
* version 2.0. See the APACHE20 and GPL2 files for the text of the licenses,
10
* or the following URLs:
11
* http://www.apache.org/licenses/LICENSE-2.0
12
* http://www.gnu.org/licenses/gpl-2.0.txt
14
* If you redistribute this file in source form, modified or unmodified, you
16
* 1) Leave this header intact and distribute it under the same terms,
17
* accompanying it with the APACHE20 and GPL20 files, or
18
* 2) Delete the Apache 2.0 clause and accompany it with the GPL2 file, or
19
* 3) Delete the GPL v2 clause and accompany it with the APACHE20 file
20
* In all cases you must keep the copyright notice intact and include a copy
21
* of the CONTRIB file.
23
* Binary distributions must follow the binary distribution requirements of
32
#include "freenect_internal.h"
46
extern const struct caminit inits[];
47
extern const int num_inits;
50
stream_process (freenect_context * ctx, packet_stream * strm, uint8_t * pkt, int len)
55
struct pkt_hdr *hdr = (void *) pkt;
56
uint8_t *data = pkt + sizeof (*hdr);
57
int datalen = len - sizeof (*hdr);
59
if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B')
61
FN_LOG (strm->valid_frames < 2 ? LL_SPEW : LL_NOTICE,
62
"[Stream %02x] Invalid magic %02x%02x\n", strm->flag, hdr->magic[0], hdr->magic[1]);
66
FN_FLOOD ("[Stream %02x] Packet with flag: %02x\n", strm->flag, hdr->flag);
68
uint8_t sof = strm->flag | 1;
69
uint8_t mof = strm->flag | 2;
70
uint8_t eof = strm->flag | 5;
72
// sync if required, dropping packets until SOF
77
FN_SPEW ("[Stream %02x] Not synced yet...\n", strm->flag);
89
// handle lost packets
90
if (strm->seq != hdr->seq)
92
uint8_t lost = strm->seq - hdr->seq;
93
FN_LOG (strm->valid_frames < 2 ? LL_SPEW : LL_INFO, "[Stream %02x] Lost %d packets\n", strm->flag, lost);
96
FN_LOG (strm->valid_frames < 2 ? LL_SPEW : LL_NOTICE,
97
"[Stream %02x] Lost too many packets, resyncing...\n", strm->flag);
101
strm->seq = hdr->seq;
102
int left = strm->pkts_per_frame - strm->pkt_num;
105
strm->pkt_num = lost - left;
106
strm->valid_pkts = strm->got_pkts;
109
strm->timestamp = strm->last_timestamp;
110
strm->valid_frames++;
114
strm->pkt_num += lost;
118
// check the header to make sure it's what we expect
119
if (!(strm->pkt_num == 0 && hdr->flag == sof) &&
120
!(strm->pkt_num == strm->pkts_per_frame - 1 && hdr->flag == eof) &&
121
!(strm->pkt_num > 0 && strm->pkt_num < strm->pkts_per_frame - 1 && hdr->flag == mof))
123
FN_LOG (strm->valid_frames < 2 ? LL_SPEW : LL_NOTICE,
124
"[Stream %02x] Inconsistent flag %02x with %d packets in buf (%d total), resyncing...\n",
125
strm->flag, hdr->flag, strm->pkt_num, strm->pkts_per_frame);
131
if (datalen > strm->pkt_size)
133
FN_LOG (strm->valid_frames < 2 ? LL_SPEW : LL_WARNING,
134
"[Stream %02x] Expected %d data bytes, but got %d. Dropping...\n", strm->flag, strm->pkt_size, datalen);
138
if (datalen != strm->pkt_size && hdr->flag != eof)
139
FN_LOG (strm->valid_frames < 2 ? LL_SPEW : LL_WARNING,
140
"[Stream %02x] Expected %d data bytes, but got only %d\n", strm->flag, strm->pkt_size, datalen);
142
uint8_t *dbuf = strm->buf + strm->pkt_num * strm->pkt_size;
143
memcpy (dbuf, data, datalen);
149
strm->last_timestamp = hdr->timestamp;
151
if (strm->pkt_num == strm->pkts_per_frame)
154
strm->valid_pkts = strm->got_pkts;
156
strm->timestamp = hdr->timestamp;
157
strm->valid_frames++;
166
// Unpack buffer of (vw bit) data into padded 16bit buffer.
168
convert_packed_to_16bit (uint8_t * raw, uint16_t * frame, int vw)
170
int mask = (1 << vw) - 1;
173
for (i = 0; i < (640 * 480); i++)
175
int idx = (i * vw) / 8;
176
uint32_t word = (raw[idx] << (16)) | (raw[idx + 1] << 8) | raw[idx + 2];
177
frame[i] = ((word >> (((3 * 8) - vw) - bitshift)) & mask);
178
bitshift = (bitshift + vw) % 8;
183
depth_process (freenect_device * dev, uint8_t * pkt, int len)
185
freenect_context *ctx = dev->parent;
190
if (!dev->depth_running)
193
int got_frame = stream_process (ctx, &dev->depth_stream, pkt, len);
198
FN_SPEW ("Got depth frame %d/%d packets arrived, TS %08x\n",
199
dev->depth_stream.valid_pkts, dev->depth_stream.pkts_per_frame, dev->depth_stream.timestamp);
201
switch (dev->depth_format)
203
case FREENECT_FORMAT_11_BIT:
204
convert_packed_to_16bit (dev->depth_raw, dev->depth_frame, 11);
206
dev->depth_cb (dev, dev->depth_frame, dev->depth_stream.timestamp);
208
case FREENECT_FORMAT_10_BIT:
209
convert_packed_to_16bit (dev->depth_raw, dev->depth_frame, 10);
211
dev->depth_cb (dev, dev->depth_frame, dev->depth_stream.timestamp);
213
case FREENECT_FORMAT_PACKED_10_BIT:
214
case FREENECT_FORMAT_PACKED_11_BIT:
216
dev->depth_cb (dev, dev->depth_raw, dev->depth_stream.timestamp);
222
rgb_process (freenect_device * dev, uint8_t * pkt, int len)
224
freenect_context *ctx = dev->parent;
230
if (!dev->rgb_running && !dev->ir_running)
233
int got_frame = stream_process (ctx, &dev->rgb_stream, pkt, len);
238
FN_SPEW ("Got RGB frame %d/%d packets arrived, TS %08x\n", dev->rgb_stream.valid_pkts,
239
dev->rgb_stream.pkts_per_frame, dev->rgb_stream.timestamp);
241
freenect_pixel *rgb_frame = NULL;
242
freenect_pixel_ir *ir_frame = NULL;
244
if (dev->rgb_format == FREENECT_FORMAT_BAYER)
246
if (!dev->rgb_running)
248
rgb_frame = dev->rgb_raw;
250
else if (dev->rgb_format == FREENECT_FORMAT_IR)
252
if (!dev->ir_running)
254
ir_frame = (freenect_pixel_ir *) dev->ir_frame;
255
convert_packed_to_16bit (dev->ir_raw, ir_frame, 10);
259
if (!dev->rgb_running)
261
rgb_frame = dev->rgb_frame;
262
/* Pixel arrangement:
270
for (y = 0; y < 480; y++)
272
for (x = 0; x < 640; x++)
280
uint8_t rr = dev->rgb_raw[i + 1];
281
uint8_t rl = x == 0 ? rr : dev->rgb_raw[i - 1];
282
uint8_t bb = dev->rgb_raw[i + 640];
283
uint8_t bt = y == 0 ? bb : dev->rgb_raw[i - 640];
284
rgb_frame[3 * i + 0] = (rl + rr) >> 1;
285
rgb_frame[3 * i + 1] = dev->rgb_raw[i];
286
rgb_frame[3 * i + 2] = (bt + bb) >> 1;
291
uint8_t gl = dev->rgb_raw[i - 1];
292
uint8_t gr = x == 639 ? gl : dev->rgb_raw[i + 1];
293
uint8_t gb = dev->rgb_raw[i + 640];
294
uint8_t gt = y == 0 ? gb : dev->rgb_raw[i - 640];
295
uint8_t bbl = dev->rgb_raw[i + 639];
296
uint8_t btl = y == 0 ? bbl : dev->rgb_raw[i - 641];
297
uint8_t bbr = x == 639 ? bbl : dev->rgb_raw[i + 641];
298
uint8_t btr = x == 639 ? btl : y == 0 ? bbr : dev->rgb_raw[i - 639];
299
rgb_frame[3 * i + 0] = dev->rgb_raw[i];
300
rgb_frame[3 * i + 1] = (gl + gr + gb + gt) >> 2;
301
rgb_frame[3 * i + 2] = (bbl + btl + bbr + btr) >> 2;
309
uint8_t gr = dev->rgb_raw[i + 1];
310
uint8_t gl = x == 0 ? gr : dev->rgb_raw[i - 1];
311
uint8_t gt = dev->rgb_raw[i - 640];
312
uint8_t gb = y == 479 ? gt : dev->rgb_raw[i + 640];
313
uint8_t rtr = dev->rgb_raw[i - 639];
314
uint8_t rbr = y == 479 ? rtr : dev->rgb_raw[i - 641];
315
uint8_t rtl = x == 0 ? rtr : dev->rgb_raw[i - 641];
316
uint8_t rbl = x == 0 ? rbr : y == 479 ? rtl : dev->rgb_raw[i + 639];
317
rgb_frame[3 * i + 0] = (rbl + rtl + rbr + rtr) >> 2;
318
rgb_frame[3 * i + 1] = (gl + gr + gb + gt) >> 2;
319
rgb_frame[3 * i + 2] = dev->rgb_raw[i];
324
uint8_t bl = dev->rgb_raw[i - 1];
325
uint8_t br = x == 639 ? bl : dev->rgb_raw[i + 1];
326
uint8_t rt = dev->rgb_raw[i - 640];
327
uint8_t rb = y == 479 ? rt : dev->rgb_raw[i + 640];
328
rgb_frame[3 * i + 0] = (rt + rb) >> 1;
329
rgb_frame[3 * i + 1] = dev->rgb_raw[i];
330
rgb_frame[3 * i + 2] = (bl + br) >> 1;
337
if (dev->rgb_cb && dev->rgb_running)
338
dev->rgb_cb (dev, rgb_frame, dev->rgb_stream.timestamp);
339
if (dev->ir_cb && dev->ir_running)
340
dev->ir_cb (dev, ir_frame, dev->rgb_stream.timestamp);
352
send_cmd (freenect_device * dev, uint16_t cmd, void *cmdbuf, unsigned int cmd_len, void *replybuf,
353
unsigned int reply_len)
355
freenect_context *ctx = dev->parent;
359
cam_hdr *chdr = (void *) obuf;
360
cam_hdr *rhdr = (void *) ibuf;
362
if (cmd_len & 1 || cmd_len > (0x400 - sizeof (*chdr)))
364
FN_ERROR ("send_cmd: Invalid command length (0x%x)\n", cmd_len);
368
chdr->magic[0] = 0x47;
369
chdr->magic[1] = 0x4d;
371
chdr->tag = dev->cam_tag;
372
chdr->len = cmd_len / 2;
374
memcpy (obuf + sizeof (*chdr), cmdbuf, cmd_len);
376
res = fnusb_control (&dev->usb_cam, 0x40, 0, 0, 0, obuf, cmd_len + sizeof (*chdr));
377
FN_SPEW ("Control cmd=%04x tag=%04x len=%04x: %d\n", cmd, dev->cam_tag, cmd_len, res);
380
FN_ERROR ("send_cmd: Output control transfer failed (%d)\n", res);
386
actual_len = fnusb_control (&dev->usb_cam, 0xc0, 0, 0, 0, ibuf, 0x200);
388
while (actual_len == 0);
389
FN_SPEW ("Control reply: %d\n", res);
390
if (actual_len < sizeof (*rhdr))
392
FN_ERROR ("send_cmd: Input control transfer failed (%d)\n", res);
395
actual_len -= sizeof (*rhdr);
397
if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42)
399
FN_ERROR ("send_cmd: Bad magic %02x %02x\n", rhdr->magic[0], rhdr->magic[1]);
402
if (rhdr->cmd != chdr->cmd)
404
FN_ERROR ("send_cmd: Bad cmd %02x != %02x\n", rhdr->cmd, chdr->cmd);
407
if (rhdr->tag != chdr->tag)
409
FN_ERROR ("send_cmd: Bad tag %04x != %04x\n", rhdr->tag, chdr->tag);
412
if (rhdr->len != (actual_len / 2))
414
FN_ERROR ("send_cmd: Bad len %04x != %04x\n", rhdr->len, (int) (actual_len / 2));
418
if (actual_len > reply_len)
420
FN_WARNING ("send_cmd: Data buffer is %d bytes long, but got %d bytes\n", reply_len, actual_len);
421
memcpy (replybuf, ibuf + sizeof (*rhdr), reply_len);
425
memcpy (replybuf, ibuf + sizeof (*rhdr), actual_len);
434
write_register (freenect_device * dev, uint16_t reg, uint16_t data)
436
freenect_context *ctx = dev->parent;
444
FN_DEBUG ("Write Reg 0x%04x <= 0x%02x\n", reg, data);
445
res = send_cmd (dev, 0x03, cmd, 4, reply, 4);
450
FN_WARNING ("send_cmd returned %d [%04x %04x], 0000 expected\n", res, reply[0], reply[1]);
455
/** \brief Start the RGB stream acquisition for the given Freenect device. */
457
freenect_start_depth (freenect_device * dev)
459
freenect_context *ctx = dev->parent;
462
if (dev->depth_running)
465
dev->depth_stream.buf = dev->depth_raw;
466
dev->depth_stream.pkts_per_frame =
467
dev->depth_format == FREENECT_FORMAT_11_BIT ? DEPTH_PKTS_11_BIT_PER_FRAME : DEPTH_PKTS_10_BIT_PER_FRAME;
468
dev->depth_stream.pkt_size = DEPTH_PKTDSIZE;
469
dev->depth_stream.synced = 0;
470
dev->depth_stream.flag = 0x70;
471
dev->depth_stream.valid_frames = 0;
473
res = fnusb_start_iso (&dev->usb_cam, &dev->depth_isoc, depth_process, 0x82, NUM_XFERS, PKTS_PER_XFER, DEPTH_PKTBUF);
477
write_register (dev, 0x06, 0x00); // reset depth stream
478
switch (dev->depth_format)
480
case FREENECT_FORMAT_11_BIT:
481
case FREENECT_FORMAT_PACKED_11_BIT:
482
write_register (dev, 0x12, 0x03);
484
case FREENECT_FORMAT_10_BIT:
485
case FREENECT_FORMAT_PACKED_10_BIT:
486
write_register (dev, 0x12, 0x02);
489
FN_ERROR ("Invalid depth format %d\n", dev->depth_format);
492
write_register (dev, 0x13, 0x01);
493
write_register (dev, 0x14, 0x1e);
494
write_register (dev, 0x06, 0x02); // start depth stream
496
dev->depth_running = 1;
500
/** \brief Start the RGB stream acquisition for the given Freenect device. */
502
freenect_start_rgb (freenect_device * dev)
506
if (dev->rgb_running)
511
freenect_context *ctx = dev->parent;
512
FN_WARNING ("Stopping IR stream...");
513
freenect_stop_ir (dev);
514
FN_WARNING ("done\n");
517
dev->rgb_stream.buf = dev->rgb_raw;
518
dev->rgb_stream.pkts_per_frame = RGB_PKTS_PER_FRAME_RGB;
519
dev->rgb_stream.pkt_size = RGB_PKTDSIZE;
520
dev->rgb_stream.synced = 0;
521
dev->rgb_stream.flag = 0x80;
522
dev->rgb_stream.valid_frames = 0;
524
res = fnusb_start_iso (&dev->usb_cam, &dev->rgb_isoc, rgb_process, 0x81, NUM_XFERS, PKTS_PER_XFER, RGB_PKTBUF);
528
write_register (dev, 0x05, 0x00); // reset rgb stream
529
write_register (dev, 0x0c, 0x00);
530
write_register (dev, 0x0d, 0x01);
531
write_register (dev, 0x0e, 0x1e); // 30Hz bayer
532
write_register (dev, 0x05, 0x01); // start rgb stream
533
write_register (dev, 0x47, 0x00); // disable Hflip
535
dev->rgb_running = 1;
539
/** \brief Start the IR stream acquisition for the given Freenect device. */
541
freenect_start_ir (freenect_device * dev)
548
if (dev->rgb_running)
550
freenect_context *ctx = dev->parent;
551
FN_WARNING ("Stopping RGB stream...");
552
freenect_stop_rgb (dev);
553
FN_WARNING ("done\n");
556
dev->rgb_stream.buf = dev->ir_raw;
557
dev->rgb_stream.pkts_per_frame = RGB_PKTS_PER_FRAME_IR;
558
dev->rgb_stream.pkt_size = RGB_PKTDSIZE;
559
dev->rgb_stream.synced = 0;
560
dev->rgb_stream.flag = 0x80;
561
dev->rgb_stream.valid_frames = 0;
563
res = fnusb_start_iso (&dev->usb_cam, &dev->rgb_isoc, rgb_process, 0x81, NUM_XFERS, PKTS_PER_XFER, RGB_PKTBUF);
567
write_register (dev, 0x05, 0x00); // reset rgb stream
568
write_register (dev, 0x0c, 0x00);
569
write_register (dev, 0x0d, 0x01);
570
write_register (dev, 0x0e, 0x1e); // 30Hz bayer
571
write_register (dev, 0x05, 0x03); // start IR stream
572
write_register (dev, 0x47, 0x00); // disable Hflip
578
/** \brief Stop the depth stream for the given Freenect device. */
580
freenect_stop_depth (freenect_device * dev)
582
freenect_context *ctx = dev->parent;
585
if (!dev->depth_running)
588
dev->depth_running = 0;
589
write_register (dev, 0x06, 0x00); // stop depth stream
591
res = fnusb_stop_iso (&dev->usb_cam, &dev->depth_isoc);
594
FN_ERROR ("Failed to stop depth isochronous stream: %d\n", res);
601
/** \brief Stop the RGB stream for the given Freenect device. */
603
freenect_stop_rgb (freenect_device * dev)
605
freenect_context *ctx = dev->parent;
608
if (!dev->rgb_running)
611
dev->rgb_running = 0;
612
write_register (dev, 0x05, 0x00); // stop rgb stream
614
res = fnusb_stop_iso (&dev->usb_cam, &dev->rgb_isoc);
617
FN_ERROR ("Failed to stop RGB isochronous stream: %d\n", res);
624
/** \brief Stop the IR stream for the given Freenect device. */
626
freenect_stop_ir (freenect_device * dev)
628
freenect_context *ctx = dev->parent;
631
if (!dev->ir_running)
635
write_register (dev, 0x05, 0x00); // stop IR stream
637
res = fnusb_stop_iso (&dev->usb_cam, &dev->rgb_isoc);
640
FN_ERROR ("Failed to stop IR isochronous stream: %d\n", res);
648
freenect_set_depth_callback (freenect_device * dev, freenect_depth_cb cb)
654
freenect_set_rgb_callback (freenect_device * dev, freenect_rgb_cb cb)
660
freenect_set_ir_callback (freenect_device * dev, freenect_ir_cb cb)
666
freenect_set_rgb_format (freenect_device * dev, freenect_rgb_format fmt)
668
dev->rgb_format = fmt;
673
freenect_set_depth_format (freenect_device * dev, freenect_depth_format fmt)
675
dev->depth_format = fmt;