Commits

Cliff Biffle committed 05121e9

Depth fields are now rendered directly from freenect's buffers, eliminating a 600KiB copy on each frame.

  • Participants
  • Parent commits a3375f9

Comments (0)

Files changed (5)

 @protocol KFKinectDelegate;
 
 @interface KFKinect : NSObject {
-	uint8_t *_depthBuffer;
-	uint8_t *_rgbBuffer;
-	
 	freenect_context *_context;
 	freenect_device *_device;
 	
 }
 
 - init;
-- (void)openWithDepthBuffer: (void *)depthBuffer rgbBuffer: (void *)rgbBuffer;
+- (void)open;
 - (void)close;
 
 @property(assign) id<KFKinectDelegate> delegate;
 @end
 
 @protocol KFKinectDelegate
-- (void)depthFieldUpdated: (KFKinect *)kinect;
+- (void)depthFieldUpdated: (const uint16_t *)bytes from: (KFKinect *)kinect;
 @end
 
 	delegate = nil;
 	return self;
 }
-- (void)openWithDepthBuffer: (void *)depthBuffer rgbBuffer: (void *)rgbBuffer
+- (void)open
 {
-	_depthBuffer = depthBuffer;
-	_rgbBuffer = rgbBuffer;
 	[NSThread detachNewThreadSelector:@selector(ioThread) toTarget:self withObject:nil];
 }
 - (void)close
             freenect_set_rgb_callback(_device, rgbCallback);
             freenect_set_rgb_format(_device, FREENECT_FORMAT_RGB);
             freenect_set_depth_format(_device, FREENECT_FORMAT_11_BIT);
-          if (_depthBuffer) freenect_start_depth(_device);
-          if (_rgbBuffer) freenect_start_rgb(_device);
+            freenect_start_depth(_device);
+            freenect_start_rgb(_device);
             
           NSLog(@"wheeee");
           
 
 - (void)depthCallback: (freenect_depth *)buffer
 {
-	if (_depthBuffer) memcpy(_depthBuffer, buffer, FREENECT_DEPTH_SIZE);
-	[delegate depthFieldUpdated: self];
+	[delegate depthFieldUpdated: (const uint16_t *)buffer from: self];
 }
 
 - (void)rgbCallback: (freenect_pixel *)buffer
 {
-	if (_rgbBuffer) memcpy(_rgbBuffer, buffer, FREENECT_RGB_SIZE);
 }
 
 @end

File KVDepthView.h

 } camera_t;
 
 @interface KVDepthView : NSOpenGLView <KFKinectDelegate> {
-  NSMutableData *rawDepthField;
   NSMutableData *backgroundDepthField;
   NSMutableData *foregroundDepthField;
   
   FILE *depthOutput;
 }
 
-@property(retain) NSMutableData *rawDepthField;
 @property(copy) void (^renderAction)(NSData *, const vec3f_t *);
 @property(assign) BOOL frozen;
 @property(assign, nonatomic) BOOL lightsOn;
 @property(nonatomic) BOOL drawBackground;
 @property(nonatomic) BOOL recording;
 
-- (void) depthFieldUpdated: (KFKinect *)kinect;
+- (void) depthFieldUpdated: (const uint16_t *)buffer from: (KFKinect *)kinect;
 
 - (IBAction) selectPointCloudRenderer: sender;
 - (IBAction) selectMeshRenderer: sender;

File KVDepthView.m

 - (void) updateModelView;
 
 - (void) computeLinearDepthField: (NSMutableData *)output 
+                  fromRawSamples: (const uint16_t *)buffer
                     andFoldUsing: (GLfloat (^)(int,int,GLfloat,GLfloat))fold;
 - (void) drawDepthFieldAsPoints: (NSData *)field baseColor: (const vec3f_t *)color;
 - (void) drawDepthFieldAsCards: (NSData *)field baseColor: (const vec3f_t *)color;
 @implementation KVDepthView
 #pragma mark --- Properties ---
 
-@synthesize rawDepthField;
 @synthesize renderAction;
 @synthesize frozen;
 @synthesize lightsOn;
 }
 
 - (void) awakeFromNib {
-  rawDepthField = [[NSMutableData alloc] initWithBytesNoCopy: calloc(640 * 480, sizeof(uint16_t))
-                                                      length: (640 * 480 * sizeof(uint16_t))];
   foregroundDepthField = [[NSMutableData alloc] initWithBytesNoCopy: calloc(640 * 480, sizeof(GLfloat))
                                                              length: (640 * 480 * sizeof(GLfloat))];
   backgroundDepthField = [[NSMutableData alloc] initWithBytesNoCopy: calloc(640 * 480, sizeof(GLfloat))
 	}
 }
 
-- (void) depthFieldUpdated: (KFKinect *)kinect {
+- (void) depthFieldUpdated: (const uint16_t *)buffer from: (KFKinect *)kinect {
   @synchronized (self) {
     if (recording) {
-      const uint8_t *rawBytes = [rawDepthField bytes];
-      fwrite(rawBytes, sizeof(uint16_t), 640*480, depthOutput);
+      fwrite(buffer, sizeof(uint16_t), 640*480, depthOutput);
     }
   }
       
     if (separateForeground) {
       const GLfloat *backgroundData = [backgroundDepthField bytes];
       [self computeLinearDepthField: backgroundDepthField
+                     fromRawSamples: buffer
                        andFoldUsing: ^(int x, int y, GLfloat a, GLfloat b){ return fmaxf(a, b); }]; 
       [self computeLinearDepthField: foregroundDepthField 
+                     fromRawSamples: buffer
                        andFoldUsing: ^(int x, int y, GLfloat _, GLfloat z){
                          GLfloat bg = backgroundData[y * 640 + x];
                          GLfloat deltaZ = fabsf(z - bg);
                        }];
     } else {
       [self computeLinearDepthField: backgroundDepthField 
+                     fromRawSamples: buffer
                        andFoldUsing: ^(int x, int y, GLfloat _, GLfloat b){ return b; }];
     }
     [self setNeedsDisplay: YES];
   camera = (camera_t) {
     .fov = 57,
     .pivot = { 0, 0, 0 },
-    .pos = { 0, 0, -7.5 },
+    .pos = { 0, 0, -3 },
     .target = { 0, 0, 0 },
     .up = { 0, 1, 0 },
   };
 }
 
 - (void) computeLinearDepthField: (NSMutableData *)output
+                  fromRawSamples: (const uint16_t *)depths
                     andFoldUsing: (GLfloat (^)(int,int,GLfloat,GLfloat))fold; {
-  const uint16_t *depths = [rawDepthField bytes];
   GLfloat *linear = [output mutableBytes];
   
   for (int y = 0; y < 480; y++) {

File KinectViewerAppDelegate.m

   } else {
     kinect = [[KFKinect alloc] init];
     kinect.delegate = depthView;
-    [kinect openWithDepthBuffer: [[depthView rawDepthField] mutableBytes] rgbBuffer: nil];
+    [kinect open];
   }
 }
 
 - (void)replayThread: (NSString *)replayFile {
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   
-  uint8_t *bytes = [[depthView rawDepthField] mutableBytes];
+  uint16_t *bytes = calloc(640*480, sizeof(uint16_t));
   while (true) {
     int fd = open([replayFile cStringUsingEncoding: NSASCIIStringEncoding], O_RDONLY);
     do {
       int r = 0;
       r = read(fd, bytes, 640*480*2);
       if (r < 640*480*2) break;
-      [depthView depthFieldUpdated: nil];
+      [depthView depthFieldUpdated: bytes from: nil];
       usleep(1000000 / 30);
     } while (YES);
     close(fd);