Alan Perry's Blog

All | Firewire | General | Puget Sound OpenSolaris User Group | Stage Rally
« Rally Costs: Running... | Main | Watch Arrested Devel... »
20060111 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]

Comments:

I was really excited when I found your page and read about dcam & solaris. It happens not often to find something related to this topic. In our department (High Power Lasers) we are using SPARC based VME-Computers for control and inspection tasks. Up until now the inspection tasks are done by bulky framegrabbers connected to a camera. The firewire cameras seemed to be a handy and more easier replacement to this former setup. Unfortunately we had to learn that things weren't has good as they seemed. Solaris has, as you mentioned, support for IIDC camera's for quite a while. But most camera's available on the market are supporting version >= 1.30 of the IIDC specification. Backwards compatibility is very bad (I learned after purchasing a basler a311) and we also need features such as trigger-functionality, that are not defined in the older version of the specification. Now I read on your site that support for the latest IIDC version is underway, what really sounds great. Can you tell when it will be released or in what timeframe it is scheduled to be ready? If we can help in testing the driver we would be grateful to help. regards matthias

Posted by matthias gehrmann on January 16, 2006 at 06:16 AM PST #

Thanks for your comments. It is very useful to hear from customers (and potential customers) on this stuff because it is sometimes hard for us to figure out what features they really need.

I have received a lot of positive feedback in response to this, which has caused me to rethink what features I should be adding and how soon I should be doing it and what priority it should have relative to the other 1394 features that I am working on.

I will keep you in mind when the new version is ready for testing.

Posted by Alan Perry on January 18, 2006 at 10:38 AM PST #

One more thing -

Let me know what specific feature from a newer version of the IIDC spec and, when I write the blog on using the software interface for directly accessing the IIDC control registers, I will try to incorporate what you want to do to in the example code in the upcoming blog that explains the interface.

Posted by Alan Perry on January 18, 2006 at 11:20 AM PST #

Post a Comment:

Comments are closed for this entry.

Calendar

RSS Feeds

Search

Links

Navigation

Referers