// // Camera.m // FastCam, video camera ObjC interface // // Created by Simon Urbanek on 11/30/07. // Copyright 2007 Simon Urbanek. All rights reserved. // #import "Camera.h" #include AOI AOI_INVALID = { -1, -1, -1, -1 }; static DC1394 *sharedDC; @implementation DC1394 - (id) init { self = [super init]; if (self) { d = dc1394_new (); } return self; } + (DC1394*) sharedInstance { if (!sharedDC) sharedDC = [[DC1394 alloc] init]; return sharedDC; } - (Camera*) cameraAt: (int) cid { dc1394camera_list_t * list; dc1394camera_t *camera; if (!d) { NSLog(@"DC1394.cameraAt: d=nil!"); return nil; } if (dc1394_enumerate_cameras(d, &list) != DC1394_SUCCESS) { NSLog(@"DC1394.cameraAt: Failed to enumerate cameras"); return nil; } if (list->num <= cid) { NSLog(@"DC1394.cameraAt: Found %d cameras, but ID %d required", list->num, cid); dc1394_free_camera_list(list); return nil; } camera = dc1394_camera_new (d, list->ids[cid].guid); dc1394_free_camera_list(list); if (!camera) { NSLog(@"DC1394.cameraAt: Failed to initialize camera at %d", cid); return nil; } return [[[Camera alloc] initWithDescriptor:camera] autorelease]; } - (int) count { dc1394camera_list_t * list; if (!d) { NSLog(@"DC1394.count: d=nil!"); return -1; } if (dc1394_enumerate_cameras (d, &list) != DC1394_SUCCESS) { NSLog(@"Failed to enumerate cameras"); return -1; } int num = list->num; dc1394_free_camera_list (list); return num; } @end @implementation Camera - (void)dealloc { if (isTransmitting) [self stop]; if (inCapture) [self disableCapture]; if (camera) dc1394_camera_free(camera); camera = 0; NSLog(@"Camera.dealloc"); [super dealloc]; } - (id) initWithDescriptor: (dc1394camera_t *) cam { self = [super init]; if (self) { camera = cam; isTransmitting = NO; inCapture = NO; currentMode = DC1394_VIDEO_MODE_FORMAT7_0; // not really, but we have to initialize it to something ... if (!camera) { NSLog(@"Camera.initWithDescriptor: attempt to use NULL camera"); [self release]; return nil; } } return self; } - (BOOL) reset { return (camera && (dc1394_reset_bus (camera) == DC1394_SUCCESS)); } // sets video mode to 7/0 and full AOI - (BOOL) setFormat7: (int) mode { currentMode = (dc1394video_mode_t) (DC1394_VIDEO_MODE_FORMAT7_0 + mode); // WARNING: we explot the fact that format7 modes are all subsequent in the enum! return (((err = dc1394_video_set_mode (camera, currentMode)) == DC1394_SUCCESS) && ((err = dc1394_format7_get_max_image_size(camera, currentMode, &max_width, &max_height)) == DC1394_SUCCESS) && ((err = dc1394_format7_set_roi (camera, currentMode, DC1394_COLOR_CODING_MONO8, DC1394_USE_RECOMMENDED, 0, 0, max_width, max_height)) == DC1394_SUCCESS)); } - (AOI) maxAoi { AOI aoi = AOI_INVALID; if ((err = dc1394_format7_get_max_image_size(camera, currentMode, (unsigned int*) &aoi.w, (unsigned int*) &aoi.h)) != DC1394_SUCCESS) return aoi; aoi.x = aoi.y = 0; return aoi; } - (BOOL) setShutter: (double) shutter { int dc_shutter = (int)((shutter - 5)/20 + 1.5); // we assume 1=5µs, 2=25µs, 3=45µs, ... if (dc_shutter < 1) dc_shutter = 1; if (dc_shutter > 4095) dc_shutter = 4095; return ((err = dc1394_feature_set_value (camera, DC1394_FEATURE_SHUTTER, dc_shutter)) == DC1394_SUCCESS); } - (BOOL) setGain: (double) gain { if (gain<0) gain=0; if (gain>1) gain=1; return ((err = dc1394_feature_set_value (camera, DC1394_FEATURE_GAIN, (int)(gain*255.4))) == DC1394_SUCCESS); } - (BOOL) setBrightness: (double) brightness { if (brightness<0) brightness=0; if (brightness>1) brightness=1; return ((err = dc1394_feature_set_value (camera, DC1394_FEATURE_BRIGHTNESS, (int)(brightness*1023.4))) == DC1394_SUCCESS); } - (AOI) aoi { AOI aoi = AOI_INVALID; unsigned int x,y,w,h; if ((err = dc1394_format7_get_image_position(camera, currentMode, &x, &y) != DC1394_SUCCESS) || (err = dc1394_format7_get_image_size(camera, currentMode, &w, &h) != DC1394_SUCCESS)) return aoi; aoi.x = x; aoi.y = y; aoi.w = w; aoi.h = h; return aoi; } - (BOOL) setAOI: (AOI) aoi { #if 1 BOOL wasTransmitting = isTransmitting, wasCapturing = inCapture; if (isTransmitting) [self stop]; if (inCapture) [self disableCapture]; err = dc1394_format7_set_roi (camera, currentMode, DC1394_COLOR_CODING_MONO8, DC1394_USE_RECOMMENDED, aoi.x, aoi.y, aoi.w, aoi.h); NSLog(@"Camera.setAOI: %dx%d %dx%dm", aoi.x, aoi.y, aoi.w, aoi.h, err, DC1394_SUCCESS); if (wasCapturing) [self setupCapture:10]; if (wasTransmitting) [self start]; return (err == DC1394_SUCCESS); #else unsigned int x, y, w, h; if ((err = dc1394_format7_get_image_position(camera, currentMode, &x, &y) != DC1394_SUCCESS) || (err = dc1394_format7_get_image_size(camera, currentMode, &w, &h) != DC1394_SUCCESS)) return NO; if (aoi.w == w && aoi.h == h) // only move return ((err = dc1394_format7_set_image_position (camera, currentMode, aoi.x, aoi.y)) == DC1394_SUCCESS); if (aoi.x == x && aoi.y == y) // only resize return ((err = dc1394_format7_set_image_size(camera, currentMode, aoi.w, aoi.h)) == DC1394_SUCCESS); if (aoi.w >= w && aoi.h >= h) // new size is strictly bigger, so we can move first return (((err = dc1394_format7_set_image_position (camera, currentMode, aoi.x, aoi.y)) == DC1394_SUCCESS) && ((err = dc1394_format7_set_image_size(camera, currentMode, aoi.w, aoi.h)) == DC1394_SUCCESS)); if (aoi.w <= w && aoi.h >= h) // new size strictly is smaller, so we can resize first return (((err = dc1394_format7_set_image_size(camera, currentMode, aoi.w, aoi.h)) == DC1394_SUCCESS) && ((err = dc1394_format7_set_image_position (camera, currentMode, aoi.x, aoi.y)) == DC1394_SUCCESS)); // new size is smaller is one direction and bigger the other, so we have to do it in three steps: // 1) resize to the smallest common size, 2) move, 3) resize to the desired size return (((err = dc1394_format7_set_image_size(camera, currentMode, (w