32 #include "freenect_internal.h"
45 extern const struct caminit inits[];
46 extern const int num_inits;
48 static int stream_process(
packet_stream *strm, uint8_t *pkt,
int len)
53 struct pkt_hdr *hdr = (
void*)pkt;
54 uint8_t *data = pkt +
sizeof(*hdr);
55 int datalen = len -
sizeof(*hdr);
57 if (hdr->magic[0] !=
'R' || hdr->magic[1] !=
'B') {
64 uint8_t sof = strm->flag|1;
65 uint8_t mof = strm->flag|2;
66 uint8_t eof = strm->flag|5;
70 if (hdr->flag != sof) {
84 if (strm->seq != hdr->seq) {
85 uint8_t lost = strm->seq - hdr->seq;
93 int left = strm->pkts_per_frame - strm->pkt_num;
95 strm->pkt_num = lost - left;
96 strm->valid_pkts = strm->got_pkts;
99 strm->timestamp = strm->last_timestamp;
101 strm->pkt_num += lost;
106 if (!(strm->pkt_num == 0 && hdr->flag == sof) &&
107 !(strm->pkt_num == strm->pkts_per_frame-1 && hdr->flag == eof) &&
108 !(strm->pkt_num > 0 && strm->pkt_num < strm->pkts_per_frame-1 && hdr->flag == mof)) {
116 if (datalen > strm->pkt_size) {
124 uint8_t *dbuf = strm->buf + strm->pkt_num * strm->pkt_size;
125 memcpy(dbuf, data, datalen);
131 strm->last_timestamp = hdr->timestamp;
133 if (strm->pkt_num == strm->pkts_per_frame) {
135 strm->valid_pkts = strm->got_pkts;
137 strm->timestamp = hdr->timestamp;
145 #define CONVERT_PACKED_BUFFER_TO_16_BIT(depth_raw, depth_frame, vw) {\
146 const int mask = (1 << vw) - 1; \
149 for (i=0; i<(640*480); i++) { \
150 int idx = (i*vw)/8; \
151 uint32_t word = (depth_raw[idx]<<(16)) | (depth_raw[idx+1]<<8) | depth_raw[idx+2]; \
152 depth_frame[i] = ((word >> (((3*8)-vw)-bitshift)) & mask); \
153 bitshift = (bitshift + vw) % 8; \
157 int depthImageIdx[FREENECT_FRAME_PIX];
158 uint8_t depthImageBitShift[FREENECT_FRAME_PIX];
160 static void init_lookups()
164 for(i=0; i<FREENECT_FRAME_PIX; i++){
165 depthImageIdx[i] = (i*11)/8;
166 depthImageBitShift[i] = 13-bitshift;
167 bitshift = (bitshift + 11) % 8;
171 uint16_t unpack_depth(uint8_t* depth_raw,
int row,
int column)
173 const int mask = 0x7FF;
174 unsigned int idx = row*FREENECT_FRAME_W + column;
175 if(idx>FREENECT_FRAME_PIX-1)
178 int rawidx = depthImageIdx[idx];
179 int bitshift = depthImageBitShift[idx];
180 uint32_t word = (depth_raw[rawidx]<<(16)) | (depth_raw[rawidx+1]<<8) | depth_raw[rawidx+2];
181 uint16_t depth = ((word >> (13-bitshift)) & mask);
185 static inline void unpack(uint8_t* depth_raw, uint16_t*depth_frame)
188 __asm__ __volatile__(
191 "testb %%al,%%al\n\t"
193 :
"=&S" (d0),
"=&D" (d1),
"=&a" (d2)
194 :
"0" (depth_raw),
"1" (depth_frame)
204 int got_frame = stream_process(&dev->depth_stream, pkt, len);
212 if (dev->depth_raw_cb){
213 dev->depth_raw_cb(dev,dev->depth_raw, dev->depth_stream.timestamp);
219 uint8_t* depth_raw = dev->depth_raw;
220 uint16_t* depth_frame = dev->depth_frame;
221 const int mask = 0x7FF;
227 for (i=0; i<FREENECT_FRAME_PIX; i++) {
228 idx = depthImageIdx[i];
229 bitshift = depthImageBitShift[i];
230 word = (depth_raw[idx]<<16) | (depth_raw[idx+1]<<8) | depth_raw[idx+2];
231 depth_frame[i] = ((word >> bitshift) & mask);
235 dev->depth_cb(dev, dev->depth_frame, dev->depth_stream.timestamp);
244 int got_frame = stream_process(&dev->rgb_stream, pkt, len);
252 uint8_t *rgb_frame = NULL;
254 if (dev->rgb_format == FREENECT_FORMAT_BAYER) {
255 rgb_frame = dev->rgb_raw;
257 rgb_frame = dev->rgb_frame;
268 int rOffset[] = {1 , 0, -639, -640};
269 int gOffset[] = {0 , -1, -640, 0};
270 int bOffset[] = {640 , 639, 0, -1};
272 uint8_t* rgb_raw = dev->rgb_raw;
273 for (y=1; y<479; y++) {
274 for (x=1; x<639; x++) {
276 pixelType = ((y&1)<<1) + (x&1);
277 rgb_frame[3*i+0] = rgb_raw[i+rOffset[pixelType]];
278 rgb_frame[3*i+1] = rgb_raw[i+gOffset[pixelType]];
279 rgb_frame[3*i+2] = rgb_raw[i+bOffset[pixelType]];
285 dev->rgb_cb(dev, rgb_frame, dev->rgb_stream.timestamp);
300 struct cam_hdr *chdr = (
void*)obuf;
301 struct cam_hdr *rhdr = (
void*)ibuf;
303 ret = fnusb_control(&dev->usb_cam, 0x80, 0x06, 0x3ee, 0, ibuf, 0x12);
306 chdr->magic[0] = 0x47;
307 chdr->magic[1] = 0x4d;
309 for (i=0; i<num_inits; i++) {
310 const struct caminit *ip = &inits[i];
311 chdr->cmd = ip->command;
313 chdr->len = ip->cmdlen / 2;
314 memcpy(obuf+
sizeof(*chdr), ip->cmddata, ip->cmdlen);
319 obuf[
sizeof(*chdr) + 2] = dev->depth_format == FREENECT_FORMAT_11_BIT ? 0x03 : 0x02;
322 ret = fnusb_control(&dev->usb_cam, 0x40, 0, 0, 0, obuf, ip->cmdlen +
sizeof(*chdr));
325 ret = fnusb_control(&dev->usb_cam, 0xc0, 0, 0, 0, ibuf, 0x200);
328 if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) {
332 if (rhdr->cmd != chdr->cmd) {
336 if (rhdr->tag != chdr->tag) {
340 if (rhdr->len != (ret-
sizeof(*rhdr))/2) {
344 if (rhdr->len != (ip->replylen/2) || memcmp(ibuf+
sizeof(*rhdr), ip->replydata, ip->replylen)) {
346 for (j=0; j<ip->replylen; j++) {
350 for (j=0; j<(rhdr->len*2); j++) {
365 dev->depth_stream.buf = dev->depth_raw;
366 dev->depth_stream.pkts_per_frame =
367 dev->depth_format == FREENECT_FORMAT_11_BIT ?
368 DEPTH_PKTS_11_BIT_PER_FRAME : DEPTH_PKTS_10_BIT_PER_FRAME;
369 dev->depth_stream.pkt_size = DEPTH_PKTDSIZE;
370 dev->depth_stream.synced = 0;
371 dev->depth_stream.flag = 0x70;
373 res = fnusb_start_iso(&dev->usb_cam, &dev->depth_isoc, depth_process, 0x82, NUM_XFERS, PKTS_PER_XFER, DEPTH_PKTBUF);
384 dev->rgb_stream.buf = dev->rgb_raw;
385 dev->rgb_stream.pkts_per_frame = RGB_PKTS_PER_FRAME;
386 dev->rgb_stream.pkt_size = RGB_PKTDSIZE;
387 dev->rgb_stream.synced = 0;
388 dev->rgb_stream.flag = 0x80;
390 res = fnusb_start_iso(&dev->usb_cam, &dev->rgb_isoc, rgb_process, 0x81, NUM_XFERS, PKTS_PER_XFER, RGB_PKTBUF);
399 printf(
"%s NOT IMPLEMENTED YET\n", __FUNCTION__);
404 printf(
"%s NOT IMPLEMENTED YET\n", __FUNCTION__);
408 void freenect_set_depth_callback(
freenect_device *dev, freenect_depth_cb cb)
413 void freenect_set_depth_raw_callback(
freenect_device *dev, freenect_depth_raw_cb cb)
415 dev->depth_raw_cb = cb;
418 void freenect_set_rgb_callback(
freenect_device *dev, freenect_rgb_cb cb)
423 int freenect_set_rgb_format(
freenect_device *dev, freenect_rgb_format fmt)
425 dev->rgb_format = fmt;
429 int freenect_set_depth_format(
freenect_device *dev, freenect_depth_format fmt)
431 dev->depth_format = fmt;