Wednesday January 11, 2006 Writing Solaris apps for 1394-based digital cameras
Since Solaris Express 8/05, support for 1394-based digital cameras (also referred to as IIDC cameras) has been available in Solaris for SPARC and x86/x64. This support includes a public software interface to allow applications that use these cameras to be developed.
Actually, this support has been available on SPARC for some time. However, it was intended as part of a Sun video package that used a particular piece of hardware that is no longer available. Also, the software interface to that driver was not a public interface.
These cameras generally fall into one of two categories. At the low end are inexpensive web-cam devices, such as the (now defunct) Orange Micro iBot and the Apple iSight. At the high end are industrial cameras, such as devices from PixelLINK and Sony. These cameras implement the 1394-based Digital Camera Specification (later called the IIDC specification) from the 1394 Trade Association.
The driver in Solaris that deals with this class of devices is dcam1394 (referred to as dcam in this discussion). It currently supports the 1.04 version of the IIDC specification. Work is underway to enhance it to support the latest version of the specification. Unfortunately, the Apple iSight camera will not work with Solaris until this work has been completed.
When a dcam device is connected to the 1394 bus on a system running Solaris, there are two device files created for each instance of the device. /dev/dcamctlinstance is used to control the camera (the control device) and /dev/dcaminstance is used to read video frames from the camera (the streaming device).
Control of the camera is done through IOCTLs sent to the control device file. The ioctls and the data strutures that are passed to them are listed in the header file sys/dcam/dcam1394_io.h and you should include this file in your application.
There are three different types of control operations - simple camera operations, accessing camera registers directly and setting and querying camera parameters.
Most of the simple camera operations are involved with reading video frames from the camera, so I will defer that topic to the discussion of the streaming device. Also, directly accessing camera registers is not the preferred method of camera control, so I will defer discussion as well.
Setting and querying camera parameters is done in a manner that is a little awkward for accessing one parameter at a time, but very handy for accessing several at once. You allocate a parameter list, enable the parameters that you care about, assign new values to parameters (if setting values), pass the parameter list to the driver through an IOCTL and access the values read from the camera (if getting values).
What does this look like in C code? This is how you would read a parameter.
/* dcamctl_fd is the file descriptor from opening /dev/dcamctl */
int current_video_mode; /* video mode from camera */
dcam1394_param_list_t param_list;
PARAM_LIST_INIT(param_list);
PARAM_LIST_ADD(DCAM1394_PARAM_VID_MODE, DCAM1394_SUBPARAM_NONE);
if (ioctl(dcamctl_fd, DCAM1394_CMD_PARAM_GET, param_list) == -1)
fprintf(stderr, "cannot get video mode\n")
current_video_mode = PARAM_VAL(param_list, DCAM1394_PARAM_VIDEO_MODE,
DCAM1394_SUBPARAM_NONE);
This is how you would set a parameter:
/* dcamctl_fd is the file descriptor from opening /dev/dcamctl */
int new_video_mode = 1; /* new video mode for the camera */
dcam1394_param_list_t param_list;
PARAM_LIST_INIT(param_list);
PARAM_LIST_ADD(DCAM1394_PARAM_VID_MODE, DCAM1394_SUBPARAM_NONE);
PARAM_VAL(param_list, DCAM1394_PARAM_VIDEO_MODE, DCAM1394_SUBPARAM_NONE) =
new_video_mode;
if (ioctl(dcamctl_fd, DCAM1394_CMD_PARAM_SET, param_list) == -1)
fprintf(stderr, "cannot set video mode\n")
This is how you would set multiple parameters at once:
/* dcamctl_fd is the file descriptor from opening /dev/dcamctl */
int new_video_mode = 1; /* new video mode for the camera */
int new_frame_rate = 2; /* new frame rate for the camera */
int new_exposure = 128; /* new exposure value for the camera */
dcam1394_param_list_t param_list;
PARAM_LIST_INIT(param_list);
PARAM_LIST_ADD(DCAM1394_PARAM_VID_MODE, DCAM1394_SUBPARAM_NONE);
PARAM_LIST_ADD(DCAM1394_PARAM_FRAME_RATE, DCAM1394_SUBPARAM_NONE);
PARAM_LIST_ADD(DCAM1394_PARAM_EXPOSURE, DCAM1394_SUBPARAM_VALUE);
PARAM_VAL(param_list, DCAM1394_PARAM_VIDEO_MODE, DCAM1394_SUBPARAM_NONE) =
new_video_mode;
PARAM_VAL(param_list, DCAM1394_PARAM_FRAME_RATE, DCAM1394_SUBPARAM_NONE) =
new_frame_rate;
PARAM_VAL(param_list, DCAM1394_PARAM_EXPOSURE, DCAM1394_SUBPARAM_VALUE) =
new_exposure;
if (ioctl(dcamctl_fd, DCAM1394_CMD_PARAM_SET, param_list) == -1)
fprintf(stderr, "cannot set video mode\n")
For a list of parameters that you can access, refer to the dcam1394_io.h header file or the dcam1394(7D) man page as well as the IIDC specification or the documentation for your camera.
In a few days, I will describe how to read video frames from the camera.
( Jan 11 2006, 09:35:00 PM PST ) Permalink Comments [3]