cameras.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 individual OpenKinect contributors. See the CONTRIB file
5  * for details.
6  *
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
13  *
14  * If you redistribute this file in source form, modified or unmodified, you
15  * may:
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.
22  *
23  * Binary distributions must follow the binary distribution requirements of
24  * either License.
25  */
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 
32 #include "freenect_internal.h"
33 #include "registration.h"
34 #include "cameras.h"
35 #include "flags.h"
36 
37 #define MAKE_RESERVED(res, fmt) (uint32_t)(((res & 0xff) << 8) | (((fmt & 0xff))))
38 #define RESERVED_TO_RESOLUTION(reserved) (freenect_resolution)((reserved >> 8) & 0xff)
39 #define RESERVED_TO_FORMAT(reserved) ((reserved) & 0xff)
40 
41 #define video_mode_count 12
43  // reserved, resolution, format, bytes, width, height, data_bits_per_pixel, padding_bits_per_pixel, framerate, is_valid
46 
49 
52 
55 
58 
60 
62 };
63 
64 #define depth_mode_count 6
66  // reserved, resolution, format, bytes, width, height, data_bits_per_pixel, padding_bits_per_pixel, framerate, is_valid
73 };
74 static const freenect_frame_mode invalid_mode = {0, (freenect_resolution)0, {(freenect_video_format)0}, 0, 0, 0, 0, 0, 0, 0};
75 
76 struct pkt_hdr {
85 };
86 
87 static int stream_process(freenect_context *ctx, packet_stream *strm, uint8_t *pkt, int len, freenect_chunk_cb cb, void *user_data)
88 {
89  if (len < 12)
90  return 0;
91 
92  struct pkt_hdr *hdr = (struct pkt_hdr*)pkt;
93  uint8_t *data = pkt + sizeof(*hdr);
94  int datalen = len - sizeof(*hdr);
95 
96  freenect_loglevel l_info = LL_INFO;
97  freenect_loglevel l_notice = LL_NOTICE;
98  freenect_loglevel l_warning = LL_WARNING;
99  if (strm->valid_frames < 2)
100  l_info = l_notice = l_warning = LL_SPEW;
101 
102  if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') {
103  FN_LOG(l_notice, "[Stream %02x] Invalid magic %02x%02x\n",
104  strm->flag, hdr->magic[0], hdr->magic[1]);
105  return 0;
106  }
107 
108  FN_FLOOD("[Stream %02x] Packet with flag: %02x\n", strm->flag, hdr->flag);
109 
110  uint8_t sof = strm->flag|1;
111  uint8_t mof = strm->flag|2;
112  uint8_t eof = strm->flag|5;
113 
114  // sync if required, dropping packets until SOF
115  if (!strm->synced) {
116  if (hdr->flag != sof) {
117  FN_SPEW("[Stream %02x] Not synced yet...\n", strm->flag);
118  return 0;
119  }
120  strm->synced = 1;
121  strm->seq = hdr->seq;
122  strm->pkt_num = 0;
123  strm->valid_pkts = 0;
124  strm->got_pkts = 0;
125  }
126 
127  int got_frame_size = 0;
128 
129  // handle lost packets
130  if (strm->seq != hdr->seq) {
131  uint8_t lost = hdr->seq - strm->seq;
132  strm->lost_pkts += lost;
133  FN_LOG(l_info, "[Stream %02x] Lost %d packets\n", strm->flag, lost);
134 
135  FN_DEBUG("[Stream %02x] Lost %d total packets in %d frames (%f lppf)\n",
136  strm->flag, strm->lost_pkts, strm->valid_frames, (float)strm->lost_pkts / strm->valid_frames);
137 
138  if (lost > 5 || strm->variable_length) {
139  FN_LOG(l_notice, "[Stream %02x] Lost too many packets, resyncing...\n", strm->flag);
140  strm->synced = 0;
141  return 0;
142  }
143  strm->seq = hdr->seq;
144  int left = strm->pkts_per_frame - strm->pkt_num;
145  if (left <= lost) {
146  strm->pkt_num = lost - left;
147  strm->valid_pkts = strm->got_pkts;
148  strm->got_pkts = 0;
149  got_frame_size = strm->frame_size;
150  strm->timestamp = strm->last_timestamp;
151  strm->valid_frames++;
152  } else {
153  strm->pkt_num += lost;
154  }
155  }
156 
157  int expected_pkt_size = (strm->pkt_num == strm->pkts_per_frame-1) ? strm->last_pkt_size : strm->pkt_size;
158 
159  if (!strm->variable_length) {
160  // check the header to make sure it's what we expect
161  if (!(strm->pkt_num == 0 && hdr->flag == sof) &&
162  !(strm->pkt_num == strm->pkts_per_frame-1 && hdr->flag == eof) &&
163  !(strm->pkt_num > 0 && strm->pkt_num < strm->pkts_per_frame-1 && hdr->flag == mof)) {
164  FN_LOG(l_notice, "[Stream %02x] Inconsistent flag %02x with %d packets in buf (%d total), resyncing...\n",
165  strm->flag, hdr->flag, strm->pkt_num, strm->pkts_per_frame);
166  strm->synced = 0;
167  return got_frame_size;
168  }
169  // check data length
170  if (datalen > expected_pkt_size) {
171  FN_LOG(l_warning, "[Stream %02x] Expected max %d data bytes, but got %d. Dropping...\n",
172  strm->flag, expected_pkt_size, datalen);
173  return got_frame_size;
174  }
175  if (datalen < expected_pkt_size)
176  FN_LOG(l_warning, "[Stream %02x] Expected %d data bytes, but got %d\n",
177  strm->flag, expected_pkt_size, datalen);
178  } else {
179  // check the header to make sure it's what we expect
180  if (!(strm->pkt_num == 0 && hdr->flag == sof) &&
181  !(strm->pkt_num < strm->pkts_per_frame && (hdr->flag == eof || hdr->flag == mof))) {
182  FN_LOG(l_notice, "[Stream %02x] Inconsistent flag %02x with %d packets in buf (%d total), resyncing...\n",
183  strm->flag, hdr->flag, strm->pkt_num, strm->pkts_per_frame);
184  strm->synced = 0;
185  return got_frame_size;
186  }
187  // check data length
188  if (datalen > expected_pkt_size) {
189  FN_LOG(l_warning, "[Stream %02x] Expected max %d data bytes, but got %d. Resyncng...\n",
190  strm->flag, expected_pkt_size, datalen);
191  strm->synced = 0;
192  return got_frame_size;
193  }
194  if (datalen < expected_pkt_size && hdr->flag != eof) {
195  FN_LOG(l_warning, "[Stream %02x] Expected %d data bytes, but got %d. Resyncing...\n",
196  strm->flag, expected_pkt_size, datalen);
197  strm->synced = 0;
198  return got_frame_size;
199  }
200  }
201 
202  // copy or chunk process the data
203  uint8_t *dbuf = strm->raw_buf + strm->pkt_num * strm->pkt_size;
204  if(cb){
205  cb(strm->raw_buf,data,strm->pkt_num,datalen,user_data);
206  }else{
207  memcpy(dbuf, data, datalen);
208  }
209 
210  strm->pkt_num++;
211  strm->seq++;
212  strm->got_pkts++;
213 
214  strm->last_timestamp = fn_le32(hdr->timestamp);
215 
216  if (hdr->flag == eof) {
217  if (strm->variable_length)
218  got_frame_size = (dbuf - strm->raw_buf) + datalen;
219  else
220  got_frame_size = (dbuf - strm->raw_buf) + strm->last_pkt_size;
221  strm->pkt_num = 0;
222  strm->valid_pkts = strm->got_pkts;
223  strm->got_pkts = 0;
224  strm->timestamp = strm->last_timestamp;
225  strm->valid_frames++;
226  }
227 
228  return got_frame_size;
229 }
230 
231 static void stream_init(freenect_context *ctx, packet_stream *strm, int rlen, int plen)
232 {
233  strm->valid_frames = 0;
234  strm->synced = 0;
235 
236  if (strm->usr_buf) {
237  strm->lib_buf = NULL;
238  strm->proc_buf = strm->usr_buf;
239  } else {
240  strm->lib_buf = malloc(plen);
241  strm->proc_buf = strm->lib_buf;
242  }
243 
244  if (rlen == 0) {
245  strm->split_bufs = 0;
246  strm->raw_buf = (uint8_t*)strm->proc_buf;
247  strm->frame_size = plen;
248  } else {
249  strm->split_bufs = 1;
250  strm->raw_buf = (uint8_t*)malloc(rlen);
251  strm->frame_size = rlen;
252  }
253 
254  strm->last_pkt_size = strm->frame_size % strm->pkt_size;
255  if (strm->last_pkt_size == 0)
256  strm->last_pkt_size = strm->pkt_size;
257  strm->pkts_per_frame = (strm->frame_size + strm->pkt_size - 1) / strm->pkt_size;
258 }
259 
261 {
262  if (strm->split_bufs)
263  free(strm->raw_buf);
264  if (strm->lib_buf)
265  free(strm->lib_buf);
266 
267  strm->raw_buf = NULL;
268  strm->proc_buf = NULL;
269  strm->lib_buf = NULL;
270 }
271 
272 static int stream_setbuf(freenect_context *ctx, packet_stream *strm, void *pbuf)
273 {
274  if (!strm->running) {
275  strm->usr_buf = pbuf;
276  return 0;
277  } else {
278  if (!pbuf && !strm->lib_buf) {
279  FN_ERROR("Attempted to set buffer to NULL but stream was started with no internal buffer\n");
280  return -1;
281  }
282  strm->usr_buf = pbuf;
283 
284  if (!pbuf)
285  strm->proc_buf = strm->lib_buf;
286  else
287  strm->proc_buf = pbuf;
288 
289  if (!strm->split_bufs)
290  strm->raw_buf = (uint8_t*)strm->proc_buf;
291  return 0;
292  }
293 }
294 
304 static inline void convert_packed_to_16bit(uint8_t *src, uint16_t *dest, int vw, int n)
305 {
306  unsigned int mask = (1 << vw) - 1;
307  uint32_t buffer = 0;
308  int bitsIn = 0;
309  while (n--) {
310  while (bitsIn < vw) {
311  buffer = (buffer << 8) | *(src++);
312  bitsIn += 8;
313  }
314  bitsIn -= vw;
315  *(dest++) = (buffer >> bitsIn) & mask;
316  }
317 }
318 
330 static inline void convert_packed_to_8bit(uint8_t *src, uint8_t *dest, int vw, int n)
331 {
332  uint32_t buffer = 0;
333  int bitsIn = 0;
334  while (n--) {
335  while (bitsIn < vw) {
336  buffer = (buffer << 8) | *(src++);
337  bitsIn += 8;
338  }
339  bitsIn -= vw;
340  *(dest++) = buffer >> (bitsIn + vw - 8);
341  }
342 }
343 
344 // Loop-unrolled version of the 11-to-16 bit unpacker. n must be a multiple of 8.
346 {
347  uint16_t baseMask = (1 << 11) - 1;
348  while(n >= 8)
349  {
350  uint8_t r0 = *(raw+0);
351  uint8_t r1 = *(raw+1);
352  uint8_t r2 = *(raw+2);
353  uint8_t r3 = *(raw+3);
354  uint8_t r4 = *(raw+4);
355  uint8_t r5 = *(raw+5);
356  uint8_t r6 = *(raw+6);
357  uint8_t r7 = *(raw+7);
358  uint8_t r8 = *(raw+8);
359  uint8_t r9 = *(raw+9);
360  uint8_t r10 = *(raw+10);
361 
362  frame[0] = (r0<<3) | (r1>>5);
363  frame[1] = ((r1<<6) | (r2>>2) ) & baseMask;
364  frame[2] = ((r2<<9) | (r3<<1) | (r4>>7) ) & baseMask;
365  frame[3] = ((r4<<4) | (r5>>4) ) & baseMask;
366  frame[4] = ((r5<<7) | (r6>>1) ) & baseMask;
367  frame[5] = ((r6<<10) | (r7<<2) | (r8>>6) ) & baseMask;
368  frame[6] = ((r8<<5) | (r9>>3) ) & baseMask;
369  frame[7] = ((r9<<8) | (r10) ) & baseMask;
370 
371  n -= 8;
372  raw += 11;
373  frame += 8;
374  }
375 }
376 
377 static void depth_process(freenect_device *dev, uint8_t *pkt, int len)
378 {
379  freenect_context *ctx = dev->parent;
380 
381  if (len == 0)
382  return;
383 
384  if (!dev->depth.running)
385  return;
386 
387  int got_frame_size = stream_process(ctx, &dev->depth, pkt, len,dev->depth_chunk_cb,dev->user_data);
388 
389  if (!got_frame_size)
390  return;
391 
392  FN_SPEW("Got depth frame of size %d/%d, %d/%d packets arrived, TS %08x\n", got_frame_size,
394 
395  switch (dev->depth_format) {
398  break;
401  break;
402  case FREENECT_DEPTH_MM:
404  break;
406  convert_packed_to_16bit(dev->depth.raw_buf, (uint16_t*)dev->depth.proc_buf, 10, 640*480);
407  break;
410  break;
411  default:
412  FN_ERROR("depth_process() was called, but an invalid depth_format is set\n");
413  break;
414  }
415  if (dev->depth_cb)
416  dev->depth_cb(dev, dev->depth.proc_buf, dev->depth.timestamp);
417 }
418 
419 #define CLAMP(x) if (x < 0) {x = 0;} if (x > 255) {x = 255;}
420 static void convert_uyvy_to_rgb(uint8_t *raw_buf, uint8_t *proc_buf, freenect_frame_mode frame_mode)
421 {
422  int x, y;
423  for(y = 0; y < frame_mode.height; ++y) {
424  for(x = 0; x < frame_mode.width; x+=2) {
425  int i = (frame_mode.width * y + x);
426  int u = raw_buf[2*i];
427  int y1 = raw_buf[2*i+1];
428  int v = raw_buf[2*i+2];
429  int y2 = raw_buf[2*i+3];
430  int r1 = (y1-16)*1164/1000 + (v-128)*1596/1000;
431  int g1 = (y1-16)*1164/1000 - (v-128)*813/1000 - (u-128)*391/1000;
432  int b1 = (y1-16)*1164/1000 + (u-128)*2018/1000;
433  int r2 = (y2-16)*1164/1000 + (v-128)*1596/1000;
434  int g2 = (y2-16)*1164/1000 - (v-128)*813/1000 - (u-128)*391/1000;
435  int b2 = (y2-16)*1164/1000 + (u-128)*2018/1000;
436  CLAMP(r1)
437  CLAMP(g1)
438  CLAMP(b1)
439  CLAMP(r2)
440  CLAMP(g2)
441  CLAMP(b2)
442  proc_buf[3*i] =r1;
443  proc_buf[3*i+1]=g1;
444  proc_buf[3*i+2]=b1;
445  proc_buf[3*i+3]=r2;
446  proc_buf[3*i+4]=g2;
447  proc_buf[3*i+5]=b2;
448  }
449  }
450 }
451 #undef CLAMP
452 
453 static void convert_bayer_to_rgb(uint8_t *raw_buf, uint8_t *proc_buf, freenect_frame_mode frame_mode)
454 {
455  int x,y;
456  /* Pixel arrangement:
457  * G R G R G R G R
458  * B G B G B G B G
459  * G R G R G R G R
460  * B G B G B G B G
461  * G R G R G R G R
462  * B G B G B G B G
463  *
464  * To convert a Bayer-pattern into RGB you have to handle four pattern
465  * configurations:
466  * 1) 2) 3) 4)
467  * B1 B1 G1 B2 R1 G1 R2 R1 <- previous line
468  * R1 G1 R2 G2 R1 G3 G2 B1 G3 B1 G1 B2 <- current line
469  * B2 B3 G4 B4 R3 G4 R4 R2 <- next line
470  * ^ ^ ^
471  * | | next pixel
472  * | current pixel
473  * previous pixel
474  *
475  * The RGB values (r,g,b) for each configuration are calculated as
476  * follows:
477  *
478  * 1) r = (R1 + R2) / 2
479  * g = G1
480  * b = (B1 + B2) / 2
481  *
482  * 2) r = R1
483  * g = (G1 + G2 + G3 + G4) / 4
484  * b = (B1 + B2 + B3 + B4) / 4
485  *
486  * 3) r = (R1 + R2 + R3 + R4) / 4
487  * g = (G1 + G2 + G3 + G4) / 4
488  * b = B1
489  *
490  * 4) r = (R1 + R2) / 2
491  * g = G1
492  * b = (B1 + B2) / 2
493  *
494  * To efficiently calculate these values, two 32bit integers are used
495  * as "shift-buffers". One integer to store the 3 horizontal bayer pixel
496  * values (previous, current, next) of the current line. The other
497  * integer to store the vertical average value of the bayer pixels
498  * (previous, current, next) of the previous and next line.
499  *
500  * The boundary conditions for the first and last line and the first
501  * and last column are solved via mirroring the second and second last
502  * line and the second and second last column.
503  *
504  * To reduce slow memory access, the values of a rgb pixel are packet
505  * into a 32bit variable and transfered together.
506  */
507 
508  uint8_t *dst = proc_buf; // pointer to destination
509 
510  uint8_t *prevLine; // pointer to previous, current and next line
511  uint8_t *curLine; // of the source bayer pattern
512  uint8_t *nextLine;
513 
514  // storing horizontal values in hVals:
515  // previous << 16, current << 8, next
516  uint32_t hVals;
517  // storing vertical averages in vSums:
518  // previous << 16, current << 8, next
519  uint32_t vSums;
520 
521  // init curLine and nextLine pointers
522  curLine = raw_buf;
523  nextLine = curLine + frame_mode.width;
524  for (y = 0; y < frame_mode.height; ++y) {
525 
526  if ((y > 0) && (y < frame_mode.height-1))
527  prevLine = curLine - frame_mode.width; // normal case
528  else if (y == 0)
529  prevLine = nextLine; // top boundary case
530  else
531  nextLine = prevLine; // bottom boundary case
532 
533  // init horizontal shift-buffer with current value
534  hVals = (*(curLine++) << 8);
535  // handle left column boundary case
536  hVals |= (*curLine << 16);
537  // init vertical average shift-buffer with current values average
538  vSums = ((*(prevLine++) + *(nextLine++)) << 7) & 0xFF00;
539  // handle left column boundary case
540  vSums |= ((*prevLine + *nextLine) << 15) & 0xFF0000;
541 
542  // store if line is odd or not
543  uint8_t yOdd = y & 1;
544  // the right column boundary case is not handled inside this loop
545  // thus the "639"
546  for (x = 0; x < frame_mode.width-1; ++x) {
547  // place next value in shift buffers
548  hVals |= *(curLine++);
549  vSums |= (*(prevLine++) + *(nextLine++)) >> 1;
550 
551  // calculate the horizontal sum as this sum is needed in
552  // any configuration
553  uint8_t hSum = ((uint8_t)(hVals >> 16) + (uint8_t)(hVals)) >> 1;
554 
555  if (yOdd == 0) {
556  if ((x & 1) == 0) {
557  // Configuration 1
558  *(dst++) = hSum; // r
559  *(dst++) = hVals >> 8; // g
560  *(dst++) = vSums >> 8; // b
561  } else {
562  // Configuration 2
563  *(dst++) = hVals >> 8;
564  *(dst++) = (hSum + (uint8_t)(vSums >> 8)) >> 1;
565  *(dst++) = ((uint8_t)(vSums >> 16) + (uint8_t)(vSums)) >> 1;
566  }
567  } else {
568  if ((x & 1) == 0) {
569  // Configuration 3
570  *(dst++) = ((uint8_t)(vSums >> 16) + (uint8_t)(vSums)) >> 1;
571  *(dst++) = (hSum + (uint8_t)(vSums >> 8)) >> 1;
572  *(dst++) = hVals >> 8;
573  } else {
574  // Configuration 4
575  *(dst++) = vSums >> 8;
576  *(dst++) = hVals >> 8;
577  *(dst++) = hSum;
578  }
579  }
580 
581  // shift the shift-buffers
582  hVals <<= 8;
583  vSums <<= 8;
584  } // end of for x loop
585  // right column boundary case, mirroring second last column
586  hVals |= (uint8_t)(hVals >> 16);
587  vSums |= (uint8_t)(vSums >> 16);
588 
589  // the horizontal sum simplifies to the second last column value
590  uint8_t hSum = (uint8_t)(hVals);
591 
592  if (yOdd == 0) {
593  if ((x & 1) == 0) {
594  *(dst++) = hSum;
595  *(dst++) = hVals >> 8;
596  *(dst++) = vSums >> 8;
597  } else {
598  *(dst++) = hVals >> 8;
599  *(dst++) = (hSum + (uint8_t)(vSums >> 8)) >> 1;
600  *(dst++) = vSums;
601  }
602  } else {
603  if ((x & 1) == 0) {
604  *(dst++) = vSums;
605  *(dst++) = (hSum + (uint8_t)(vSums >> 8)) >> 1;
606  *(dst++) = hVals >> 8;
607  } else {
608  *(dst++) = vSums >> 8;
609  *(dst++) = hVals >> 8;
610  *(dst++) = hSum;
611  }
612  }
613 
614  } // end of for y loop
615 }
616 
617 static void video_process(freenect_device *dev, uint8_t *pkt, int len)
618 {
619  freenect_context *ctx = dev->parent;
620 
621  if (len == 0)
622  return;
623 
624  if (!dev->video.running)
625  return;
626 
627  int got_frame_size = stream_process(ctx, &dev->video, pkt, len,dev->video_chunk_cb,dev->user_data);
628 
629  if (!got_frame_size)
630  return;
631 
632  FN_SPEW("Got video frame of size %d/%d, %d/%d packets arrived, TS %08x\n", got_frame_size,
634 
636  switch (dev->video_format) {
637  case FREENECT_VIDEO_RGB:
638  convert_bayer_to_rgb(dev->video.raw_buf, (uint8_t*)dev->video.proc_buf, frame_mode);
639  break;
641  break;
643  convert_packed_to_16bit(dev->video.raw_buf, (uint16_t*)dev->video.proc_buf, 10, frame_mode.width * frame_mode.height);
644  break;
646  break;
648  convert_packed_to_8bit(dev->video.raw_buf, (uint8_t*)dev->video.proc_buf, 10, frame_mode.width * frame_mode.height);
649  break;
651  convert_uyvy_to_rgb(dev->video.raw_buf, (uint8_t*)dev->video.proc_buf, frame_mode);
652  break;
654  break;
655  default:
656  FN_ERROR("video_process() was called, but an invalid video_format is set\n");
657  break;
658  }
659 
660  if (dev->video_cb)
661  dev->video_cb(dev, dev->video.proc_buf, dev->video.timestamp);
662 }
663 
665 {
666  freenect_context *ctx = dev->parent;
667  char reply[0x200];
668  uint16_t cmd[5];
670  cmd[0] = fn_le16(0x40); // ParamID - in this scenario, XN_HOST_PROTOCOL_ALGORITHM_REGISTRATION
671  cmd[1] = fn_le16(0); // Format
672  cmd[2] = fn_le16((uint16_t)mode.resolution); // Resolution
673  cmd[3] = fn_le16((uint16_t)mode.framerate); // FPS
674  cmd[4] = fn_le16(0); // Offset
675 
676  int res;
677  res = send_cmd(dev, 0x16, cmd, 10, reply, 118); // OPCODE_ALGORITHM_PARAMS
678  if(res != 118) {
679  FN_ERROR("freenect_fetch_reg_info: send_cmd read %d bytes (expected 118)\n", res);
680  return -1;
681  }
682  memcpy(&dev->registration.reg_info, reply + 2, sizeof(dev->registration.reg_info));
707  FN_SPEW("ax: %d\n", dev->registration.reg_info.ax);
708  FN_SPEW("bx: %d\n", dev->registration.reg_info.bx);
709  FN_SPEW("cx: %d\n", dev->registration.reg_info.cx);
710  FN_SPEW("dx: %d\n", dev->registration.reg_info.dx);
711  FN_SPEW("ay: %d\n", dev->registration.reg_info.ay);
712  FN_SPEW("by: %d\n", dev->registration.reg_info.by);
713  FN_SPEW("cy: %d\n", dev->registration.reg_info.cy);
714  FN_SPEW("dy: %d\n", dev->registration.reg_info.dy);
715  FN_SPEW("dx_start: %d\n", dev->registration.reg_info.dx_start);
716  FN_SPEW("dy_start: %d\n", dev->registration.reg_info.dy_start);
717  FN_SPEW("dx_beta_start: %d\n", dev->registration.reg_info.dx_beta_start);
718  FN_SPEW("dy_beta_start: %d\n", dev->registration.reg_info.dy_beta_start);
719  FN_SPEW("dx_beta_inc: %d\n", dev->registration.reg_info.dx_beta_inc);
720  FN_SPEW("dy_beta_inc: %d\n", dev->registration.reg_info.dy_beta_inc);
721  FN_SPEW("dxdx_start: %d\n", dev->registration.reg_info.dxdx_start);
722  FN_SPEW("dxdy_start: %d\n", dev->registration.reg_info.dxdy_start);
723  FN_SPEW("dydx_start: %d\n", dev->registration.reg_info.dydx_start);
724  FN_SPEW("dydy_start: %d\n", dev->registration.reg_info.dydy_start);
725  FN_SPEW("dxdxdx_start: %d\n", dev->registration.reg_info.dxdxdx_start);
726  FN_SPEW("dydxdx_start: %d\n", dev->registration.reg_info.dydxdx_start);
727  FN_SPEW("dxdxdy_start: %d\n", dev->registration.reg_info.dxdxdy_start);
728  FN_SPEW("dydxdy_start: %d\n", dev->registration.reg_info.dydxdy_start);
729  FN_SPEW("dydydx_start: %d\n", dev->registration.reg_info.dydydx_start);
730  FN_SPEW("dydydy_start: %d\n", dev->registration.reg_info.dydydy_start);
731  /*
732  // NOTE: Not assigned above
733  FN_SPEW("dx_center: %d\n", dev_reg_info->dx_center);
734  FN_SPEW("rollout_blank: %d\n", dev_reg_info->rollout_blank);
735  FN_SPEW("rollout_size: %d\n", dev_reg_info->rollout_size);
736  FN_SPEW("back_comp1: %d\n", dev_reg_info->back_comp1);
737  FN_SPEW("back_comp2: %d\n", dev_reg_info->back_comp2);
738  */
739  return 0;
740 }
741 
743 {
744  freenect_context *ctx = dev->parent;
745  char reply[0x200];
746  uint16_t cmd[5];
748  cmd[0] = fn_le16(0x41); // ParamID
749  cmd[1] = fn_le16(0); // Format
750  cmd[2] = fn_le16((uint16_t)mode.resolution); // Resolution
751  cmd[3] = fn_le16((uint16_t)mode.framerate); // FPS
752  cmd[4] = fn_le16(0); // Offset
753  int res;
754  res = send_cmd(dev, 0x16, cmd, 10, reply, 8); // OPCODE_ALGORITHM_PARAMS
755  if(res != 8) {
756  FN_ERROR("freenect_fetch_reg_pad_info: send_cmd read %d bytes (expected 8)\n", res);
757  return -1;
758  }
759  memcpy(&dev->registration.reg_pad_info, reply+2, sizeof(dev->registration.reg_pad_info));
763  FN_SPEW("start_lines: %u\n",dev->registration.reg_pad_info.start_lines);
764  FN_SPEW("end_lines: %u\n",dev->registration.reg_pad_info.end_lines);
765  FN_SPEW("cropping_lines: %u\n",dev->registration.reg_pad_info.cropping_lines);
766  return 0;
767 }
768 
770 {
771  freenect_context *ctx = dev->parent;
772  char reply[0x200];
773  uint16_t cmd[5];
775  cmd[0] = fn_le16(0x00); // ParamID
776  cmd[1] = fn_le16(0); // Format
777  cmd[2] = fn_le16((uint16_t)mode.resolution); // Resolution
778  cmd[3] = fn_le16((uint16_t)mode.framerate); // FPS
779  cmd[4] = fn_le16(0); // Offset
780  int res;
781  res = send_cmd(dev, 0x16, cmd, 10, reply, 4); // OPCODE_ALGORITHM_PARAMS
782  if(res != 4) {
783  FN_ERROR("freenect_fetch_reg_const_shift: send_cmd read %d bytes (expected 8)\n", res);
784  return -1;
785  }
786  uint16_t shift;
787  memcpy(&shift, reply+2, sizeof(shift));
788  shift = fn_le16(shift);
789  dev->registration.const_shift = (double)shift;
790  FN_SPEW("const_shift: %f\n",dev->registration.const_shift);
791  return 0;
792 }
793 
795 {
796  freenect_context *ctx = dev->parent;
797 
798  char reply[0x200];
799  uint16_t cmd[5] = {0}; // Offset is the only field in this command, and it's 0
800 
801  int res;
802  res = send_cmd(dev, 0x04, cmd, 10, reply, ctx->zero_plane_res); //OPCODE_GET_FIXED_PARAMS = 4,
803  if (res != ctx->zero_plane_res) {
804  FN_ERROR("freenect_fetch_zero_plane_info: send_cmd read %d bytes (expected %d)\n", res,ctx->zero_plane_res);
805  return -1;
806  }
807 
808  memcpy(&(dev->registration.zero_plane_info), reply + 94, sizeof(dev->registration.zero_plane_info));
809  union {
810  uint32_t ui;
811  float f;
812  } conversion_union;
813  conversion_union.f = dev->registration.zero_plane_info.dcmos_emitter_dist;
814  conversion_union.ui = fn_le32(conversion_union.ui);
815  dev->registration.zero_plane_info.dcmos_emitter_dist = conversion_union.f;
816 
817  conversion_union.f = dev->registration.zero_plane_info.dcmos_rcmos_dist;
818  conversion_union.ui = fn_le32(conversion_union.ui);
819  dev->registration.zero_plane_info.dcmos_rcmos_dist = conversion_union.f;
820 
821  conversion_union.f = dev->registration.zero_plane_info.reference_distance;
822  conversion_union.ui = fn_le32(conversion_union.ui);
823  dev->registration.zero_plane_info.reference_distance = conversion_union.f;
824 
825  conversion_union.f = dev->registration.zero_plane_info.reference_pixel_size;
826  conversion_union.ui = fn_le32(conversion_union.ui);
827  dev->registration.zero_plane_info.reference_pixel_size = conversion_union.f;
828 
829  // WTF is all this data? it's way bigger than sizeof(XnFixedParams)...
830  FN_SPEW("dcmos_emitter_distance: %f\n", dev->registration.zero_plane_info.dcmos_emitter_dist);
831  FN_SPEW("dcmos_rcmos_distance: %f\n", dev->registration.zero_plane_info.dcmos_rcmos_dist);
832  FN_SPEW("reference_distance: %f\n", dev->registration.zero_plane_info.reference_distance);
833  FN_SPEW("reference_pixel_size: %f\n", dev->registration.zero_plane_info.reference_pixel_size);
834 
835  // FIXME: OpenNI seems to use a hardcoded value of 2.4 instead of 2.3 as reported by Kinect
837 
838  return 0;
839 }
840 
842 {
843  freenect_context *ctx = dev->parent;
844  int res;
845 
846  if (dev->depth.running)
847  return -1;
848 
850  dev->depth.flag = 0x70;
851  dev->depth.variable_length = 0;
852 
853  switch (dev->depth_format) {
855  case FREENECT_DEPTH_MM:
859  break;
862  break;
866  break;
867  default:
868  FN_ERROR("freenect_start_depth() called with invalid depth format %d\n", dev->depth_format);
869  return -1;
870  }
871 
873  if (res < 0)
874  return res;
875 
876  write_register(dev, 0x105, 0x00); // Disable auto-cycle of projector
877  write_register(dev, 0x06, 0x00); // reset depth stream
878  switch (dev->depth_format) {
882  case FREENECT_DEPTH_MM:
883  write_register(dev, 0x12, 0x03);
884  break;
887  write_register(dev, 0x12, 0x02);
888  break;
889  case FREENECT_DEPTH_DUMMY: // Returned already, hush gcc
890  break;
891  }
892  write_register(dev, 0x13, 0x01);
893  write_register(dev, 0x14, 0x1e);
894  write_register(dev, 0x06, 0x02); // start depth stream
895  write_register(dev, 0x17, 0x00); // disable depth hflip
896 
897  dev->depth.running = 1;
898  return 0;
899 }
900 
902 {
903  freenect_context *ctx = dev->parent;
904  int res;
905 
906  if (dev->video.running)
907  return -1;
908 
910  dev->video.flag = 0x80;
911  dev->video.variable_length = 0;
912 
913  uint16_t mode_reg, mode_value;
914  uint16_t res_reg, res_value;
915  uint16_t fps_reg, fps_value;
916  uint16_t hflip_reg;
917 
918  switch(dev->video_format) {
919  case FREENECT_VIDEO_RGB:
922  mode_value = 0x00; // Bayer
923  res_value = 0x02; // 1280x1024
924  fps_value = 0x0f; // "15" Hz
925  } else if (dev->video_resolution == FREENECT_RESOLUTION_MEDIUM) {
926  mode_value = 0x00; // Bayer
927  res_value = 0x01; // 640x480
928  fps_value = 0x1e; // 30 Hz
929  } else {
930  FN_ERROR("freenect_start_video(): called with invalid format/resolution combination\n");
931  return -1;
932  }
933  mode_reg = 0x0c;
934  res_reg = 0x0d;
935  fps_reg = 0x0e;
936  hflip_reg = 0x47;
937  break;
942  if(dev->depth.running) {
943  FN_ERROR("freenect_start_video(): cannot stream high-resolution IR at same time as depth stream\n");
944  return -1;
945  }
946 
947  // Due to some ridiculous condition in the firmware, we have to start and stop the
948  // depth stream before the camera will hand us 1280x1024 IR. This is a stupid
949  // workaround, but we've yet to find a better solution.
950  write_register(dev, 0x13, 0x01); // set depth camera resolution (640x480)
951  write_register(dev, 0x14, 0x1e); // set depth camera FPS (30)
952  write_register(dev, 0x06, 0x02); // start depth camera
953  write_register(dev, 0x06, 0x00); // stop depth camera
954 
955  mode_value = 0x00; // Luminance, 10-bit packed
956  res_value = 0x02; // 1280x1024
957  fps_value = 0x0f; // "15" Hz
958  } else if (dev->video_resolution == FREENECT_RESOLUTION_MEDIUM) {
959  mode_value = 0x00; // Luminance, 10-bit packed
960  res_value = 0x01; // 640x480
961  fps_value = 0x1e; // 30 Hz
962  } else {
963  FN_ERROR("freenect_start_video(): called with invalid format/resolution combination\n");
964  return -1;
965  }
966  mode_reg = 0x19;
967  res_reg = 0x1a;
968  fps_reg = 0x1b;
969  hflip_reg = 0x48;
970  break;
974  mode_value = 0x05; // UYUV mode
975  res_value = 0x01; // 640x480
976  fps_value = 0x0f; // 15Hz
977  } else {
978  FN_ERROR("freenect_start_video(): called with invalid format/resolution combination\n");
979  return -1;
980  }
981  mode_reg = 0x0c;
982  res_reg = 0x0d;
983  fps_reg = 0x0e;
984  hflip_reg = 0x47;
985  break;
986  default:
987  FN_ERROR("freenect_start_video(): called with invalid video format %d\n", dev->video_format);
988  return -1;
989  }
990 
992  switch (dev->video_format) {
993  case FREENECT_VIDEO_RGB:
995  break;
997  stream_init(ctx, &dev->video, 0, frame_mode.bytes);
998  break;
1001  break;
1004  break;
1006  stream_init(ctx, &dev->video, 0, frame_mode.bytes);
1007  break;
1010  break;
1012  stream_init(ctx, &dev->video, 0, frame_mode.bytes);
1013  break;
1014  case FREENECT_VIDEO_DUMMY: // Silence compiler
1015  break;
1016  }
1017 
1019  if (res < 0)
1020  return res;
1021 
1022  write_register(dev, mode_reg, mode_value);
1023  write_register(dev, res_reg, res_value);
1024  write_register(dev, fps_reg, fps_value);
1025 
1026  switch (dev->video_format) {
1027  case FREENECT_VIDEO_RGB:
1028  case FREENECT_VIDEO_BAYER:
1031  write_register(dev, 0x05, 0x01); // start video stream
1032  break;
1036  write_register(dev, 0x105, 0x00); // Disable auto-cycle of projector
1037  write_register(dev, 0x05, 0x03); // start video stream
1038  break;
1039  case FREENECT_VIDEO_DUMMY: // Silence compiler
1040  break;
1041  }
1042  write_register(dev, hflip_reg, 0x00); // disable Hflip
1043 
1044  dev->video.running = 1;
1045  return 0;
1046 }
1047 
1049 {
1050  freenect_context *ctx = dev->parent;
1051  int res;
1052 
1053  if (!dev->depth.running)
1054  return -1;
1055 
1056  dev->depth.running = 0;
1057  write_register(dev, 0x06, 0x00); // stop depth stream
1058 
1059  res = fnusb_stop_iso(&dev->usb_cam, &dev->depth_isoc);
1060  if (res < 0) {
1061  FN_ERROR("Failed to stop depth isochronous stream: %d\n", res);
1062  return res;
1063  }
1064 
1066  stream_freebufs(ctx, &dev->depth);
1067  return 0;
1068 }
1069 
1071 {
1072  freenect_context *ctx = dev->parent;
1073  int res;
1074 
1075  if (!dev->video.running)
1076  return -1;
1077 
1078  dev->video.running = 0;
1079  write_register(dev, 0x05, 0x00); // stop video stream
1080 
1081  res = fnusb_stop_iso(&dev->usb_cam, &dev->video_isoc);
1082  if (res < 0) {
1083  FN_ERROR("Failed to stop RGB isochronous stream: %d\n", res);
1084  return res;
1085  }
1086 
1087  stream_freebufs(ctx, &dev->video);
1088  return 0;
1089 }
1090 
1092 {
1093  dev->depth_cb = cb;
1094 }
1095 
1097 {
1098  dev->video_cb = cb;
1099 }
1100 
1101 
1103 {
1104  dev->depth_chunk_cb = cb;
1105 }
1106 
1108 {
1109  dev->video_chunk_cb = cb;
1110 }
1111 
1113 {
1114  return video_mode_count;
1115 }
1116 
1118 {
1119  if (mode_num >= 0 && mode_num < video_mode_count)
1120  return supported_video_modes[mode_num];
1121  freenect_frame_mode retval;
1122  retval.is_valid = 0;
1123  return retval;
1124 }
1125 
1127 {
1129 }
1130 
1132 {
1133  uint32_t unique_id = MAKE_RESERVED(res, fmt);
1134  int i;
1135  for(i = 0 ; i < video_mode_count; i++) {
1136  if (supported_video_modes[i].reserved == unique_id)
1137  return supported_video_modes[i];
1138  }
1139  freenect_frame_mode retval;
1140  retval.is_valid = 0;
1141  return retval;
1142 }
1143 
1145 {
1146  freenect_context *ctx = dev->parent;
1147  if (dev->video.running) {
1148  FN_ERROR("Tried to set video mode while stream is active\n");
1149  return -1;
1150  }
1151  // Verify that the mode passed in is actually in the supported mode list
1152  int found = 0;
1153  int i;
1154  for(i = 0 ; i < video_mode_count; i++) {
1155  if (supported_video_modes[i].reserved == mode.reserved) {
1156  found = 1;
1157  break;
1158  }
1159  }
1160  if (!found) {
1161  FN_ERROR("freenect_set_video_mode: freenect_frame_mode provided is invalid\n");
1162  return -1;
1163  }
1164 
1167  dev->video_format = fmt;
1168  dev->video_resolution = res;
1169  // Now that we've changed video format and resolution, we need to update
1170  // registration tables.
1172  return 0;
1173 }
1174 
1176 {
1177  return depth_mode_count;
1178 }
1179 
1181 {
1182  if (mode_num >= 0 && mode_num < depth_mode_count)
1183  return supported_depth_modes[mode_num];
1184  freenect_frame_mode retval;
1185  retval.is_valid = 0;
1186  return retval;
1187 }
1188 
1190 {
1192 }
1193 
1195 {
1196  uint32_t unique_id = MAKE_RESERVED(res, fmt);
1197  int i;
1198  for(i = 0 ; i < depth_mode_count; i++) {
1199  if (supported_depth_modes[i].reserved == unique_id)
1200  return supported_depth_modes[i];
1201  }
1202  freenect_frame_mode retval;
1203  retval.is_valid = 0;
1204  return retval;
1205 }
1206 
1208 {
1209  freenect_context *ctx = dev->parent;
1210  if (dev->depth.running) {
1211  FN_ERROR("Tried to set depth mode while stream is active\n");
1212  return -1;
1213  }
1214  // Verify that the mode passed in is actually in the supported mode list
1215  int found = 0;
1216  int i;
1217  for(i = 0 ; i < depth_mode_count; i++) {
1218  if (supported_depth_modes[i].reserved == mode.reserved) {
1219  found = 1;
1220  break;
1221  }
1222  }
1223  if (!found) {
1224  FN_ERROR("freenect_set_depth_mode: freenect_frame_mode provided is invalid\n");
1225  return -1;
1226  }
1229  dev->depth_format = fmt;
1230  dev->depth_resolution = res;
1231  return 0;
1232 }
1234 {
1235  return stream_setbuf(dev->parent, &dev->depth, buf);
1236 }
1237 
1239 {
1240  return stream_setbuf(dev->parent, &dev->video, buf);
1241 }
1242 
1244 {
1245  freenect_context *ctx = dev->parent;
1246  int res;
1247  res = freenect_fetch_reg_pad_info(dev);
1248  if (res < 0) {
1249  FN_ERROR("freenect_camera_init(): Failed to fetch registration pad info for device\n");
1250  return res;
1251  }
1252  res = freenect_fetch_zero_plane_info(dev);
1253  if (res < 0) {
1254  FN_ERROR("freenect_camera_init(): Failed to fetch zero plane info for device\n");
1255  return res;
1256  }
1259  res = freenect_fetch_reg_const_shift(dev);
1260  if (res < 0) {
1261  FN_ERROR("freenect_camera_init(): Failed to fetch const shift for device\n");
1262  return res;
1263  }
1264  return 0;
1265 }
1266 
1268 {
1269  freenect_context *ctx = dev->parent;
1270  int res = 0;
1271  if (dev->depth.running) {
1272  res = freenect_stop_depth(dev);
1273  if (res < 0) {
1274  FN_ERROR("freenect_camera_teardown(): Failed to stop depth camera\n");
1275  }
1276  return res;
1277  }
1278  if (dev->video.running) {
1279  res = freenect_stop_video(dev);
1280  if (res < 0) {
1281  FN_ERROR("freenect_camera_teardown(): Failed to stop video camera\n");
1282  }
1283  return res;
1284  }
1286  return 0;
1287 }
freenect_chunk_cb depth_chunk_cb
uint8_t seq
Definition: cameras.c:81
void freenect_set_video_chunk_callback(freenect_device *dev, freenect_chunk_cb cb)
Definition: cameras.c:1107
FREENECTAPI int freenect_destroy_registration(freenect_registration *reg)
Definition: registration.c:367
freenect_video_format video_format
int freenect_set_depth_buffer(freenect_device *dev, void *buf)
Definition: cameras.c:1233
FN_INTERNAL int freenect_init_registration(freenect_device *dev)
Definition: registration.c:335
freenect_context * parent
uint8_t magic[2]
Definition: cameras.c:77
FN_INTERNAL int fnusb_start_iso(fnusb_dev *dev, fnusb_isoc_stream *strm, fnusb_iso_cb cb, int ep, int xfers, int pkts, int len)
Definition: usb_libusb10.c:755
freenect_zero_plane_info zero_plane_info
packet_stream video
int freenect_get_video_mode_count()
Definition: cameras.c:1112
static void stream_init(freenect_context *ctx, packet_stream *strm, int rlen, int plen)
Definition: cameras.c:231
freenect_registration registration
freenect_video_format
Definition: libfreenect.h:86
uint32_t last_timestamp
void freenect_set_video_callback(freenect_device *dev, freenect_video_cb cb)
Definition: cameras.c:1096
unsigned short uint16_t
static void convert_bayer_to_rgb(uint8_t *raw_buf, uint8_t *proc_buf, freenect_frame_mode frame_mode)
Definition: cameras.c:453
int freenect_start_video(freenect_device *dev)
Definition: cameras.c:901
#define FN_ERROR(...)
#define FN_FLOOD(...)
freenect_depth_format depth_format
static int freenect_fetch_reg_const_shift(freenect_device *dev)
Definition: cameras.c:769
#define fn_le32s(x)
FN_INTERNAL int fnusb_stop_iso(fnusb_dev *dev, fnusb_isoc_stream *strm)
Definition: usb_libusb10.c:793
#define DEPTH_PKTDSIZE
freenect_frame_mode freenect_get_depth_mode(int mode_num)
Definition: cameras.c:1180
static void video_process(freenect_device *dev, uint8_t *pkt, int len)
Definition: cameras.c:617
#define FN_LOG(level,...)
int freenect_stop_video(freenect_device *dev)
Definition: cameras.c:1070
static int stream_setbuf(freenect_context *ctx, packet_stream *strm, void *pbuf)
Definition: cameras.c:272
fnusb_isoc_stream video_isoc
#define fn_le16(x)
static int freenect_fetch_reg_pad_info(freenect_device *dev)
Definition: cameras.c:742
void freenect_set_depth_chunk_callback(freenect_device *dev, freenect_chunk_cb cb)
Definition: cameras.c:1102
unsigned char uint8_t
freenect_resolution depth_resolution
packet_stream depth
int frame
Definition: regview.c:72
void(* freenect_depth_cb)(freenect_device *dev, void *depth, uint32_t timestamp)
Typedef for depth image received event callbacks.
Definition: libfreenect.h:385
#define LL_SPEW
freenect_depth_cb depth_cb
#define depth_mode_count
Definition: cameras.c:64
#define FN_DEBUG(...)
int freenect_set_depth_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: cameras.c:1207
static int freenect_fetch_reg_info(freenect_device *dev)
Definition: cameras.c:664
int freenect_set_video_mode(freenect_device *dev, const freenect_frame_mode mode)
Definition: cameras.c:1144
freenect_depth_format
Definition: libfreenect.h:99
#define fn_le16s(x)
uint8_t unk2
Definition: cameras.c:82
freenect_frame_mode freenect_find_video_mode(freenect_resolution res, freenect_video_format fmt)
Definition: cameras.c:1131
freenect_loglevel
Enumeration of message logging levels.
Definition: libfreenect.h:200
#define LL_NOTICE
static int stream_process(freenect_context *ctx, packet_stream *strm, uint8_t *pkt, int len, freenect_chunk_cb cb, void *user_data)
Definition: cameras.c:87
static void convert_packed_to_8bit(uint8_t *src, uint8_t *dest, int vw, int n)
Definition: cameras.c:330
#define CLAMP(x)
Definition: cameras.c:419
int freenect_set_video_buffer(freenect_device *dev, void *buf)
Definition: cameras.c:1238
static void convert_uyvy_to_rgb(uint8_t *raw_buf, uint8_t *proc_buf, freenect_frame_mode frame_mode)
Definition: cameras.c:420
#define LL_INFO
freenect_frame_mode freenect_get_video_mode(int mode_num)
Definition: cameras.c:1117
#define DEPTH_PKTBUF
Definition: usb_libusb10.h:59
freenect_frame_mode freenect_find_depth_mode(freenect_resolution res, freenect_depth_format fmt)
Definition: cameras.c:1194
#define FN_SPEW(...)
static void stream_freebufs(freenect_context *ctx, packet_stream *strm)
Definition: cameras.c:260
#define NUM_XFERS
Definition: usb_libusb10.h:57
#define video_mode_count
Definition: cameras.c:41
#define LL_WARNING
static void depth_process(freenect_device *dev, uint8_t *pkt, int len)
Definition: cameras.c:377
static freenect_frame_mode supported_video_modes[video_mode_count]
Definition: cameras.c:42
#define PKTS_PER_XFER
Definition: usb_libusb10.h:56
unsigned int lost_pkts
static const freenect_frame_mode invalid_mode
Definition: cameras.c:74
freenect_resolution
Definition: libfreenect.h:77
uint8_t unk3
Definition: cameras.c:83
uint8_t pad
Definition: cameras.c:78
#define VIDEO_PKTBUF
Definition: usb_libusb10.h:60
uint8_t flag
Definition: cameras.c:79
static freenect_context * ctx
int freenect_start_depth(freenect_device *dev)
Definition: cameras.c:841
FN_INTERNAL int write_register(freenect_device *dev, uint16_t reg, uint16_t data)
Definition: flags.c:167
#define FN_INTERNAL
#define VIDEO_PKTDSIZE
unsigned int uint32_t
#define MAKE_RESERVED(res, fmt)
Definition: cameras.c:37
static freenect_frame_mode supported_depth_modes[depth_mode_count]
Definition: cameras.c:65
static void convert_packed11_to_16bit(uint8_t *raw, uint16_t *frame, int n)
Definition: cameras.c:345
freenect_resolution video_resolution
FN_INTERNAL int send_cmd(freenect_device *dev, uint16_t cmd, void *cmdbuf, unsigned int cmd_len, void *replybuf, int reply_len)
Definition: flags.c:77
freenect_reg_pad_info reg_pad_info
FN_INTERNAL int freenect_camera_teardown(freenect_device *dev)
Definition: cameras.c:1267
int freenect_stop_depth(freenect_device *dev)
Definition: cameras.c:1048
freenect_frame_mode freenect_get_current_depth_mode(freenect_device *dev)
Definition: cameras.c:1189
fnusb_isoc_stream depth_isoc
uint32_t timestamp
Definition: cameras.c:84
uint8_t unk1
Definition: cameras.c:80
static int freenect_fetch_zero_plane_info(freenect_device *dev)
Definition: cameras.c:794
FN_INTERNAL int freenect_apply_depth_to_mm(freenect_device *dev, uint8_t *input_packed, uint16_t *output_mm)
Definition: registration.c:172
freenect_resolution resolution
Definition: libfreenect.h:131
#define fn_le32(x)
void(* freenect_chunk_cb)(void *buffer, void *pkt_data, int pkt_num, int datalen, void *user_data)
Typedef for stream chunk processing callbacks.
Definition: libfreenect.h:389
freenect_chunk_cb video_chunk_cb
void(* freenect_video_cb)(freenect_device *dev, void *video, uint32_t timestamp)
Typedef for video image received event callbacks.
Definition: libfreenect.h:387
static void convert_packed_to_16bit(uint8_t *src, uint16_t *dest, int vw, int n)
Definition: cameras.c:304
FN_INTERNAL int freenect_camera_init(freenect_device *dev)
Definition: cameras.c:1243
int freenect_get_depth_mode_count()
Definition: cameras.c:1175
freenect_video_cb video_cb
void freenect_set_depth_callback(freenect_device *dev, freenect_depth_cb cb)
Definition: cameras.c:1091
freenect_frame_mode freenect_get_current_video_mode(freenect_device *dev)
Definition: cameras.c:1126
#define RESERVED_TO_RESOLUTION(reserved)
Definition: cameras.c:38
#define RESERVED_TO_FORMAT(reserved)
Definition: cameras.c:39
FN_INTERNAL int freenect_apply_registration(freenect_device *dev, uint8_t *input_packed, uint16_t *output_mm)
Definition: registration.c:104


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