Home · All Classes · Grouped Classes · Annotated · Functions

Tutorial: Extending the Camera Device Model

Introduction

This small tutorial covers the case where you want your camera device to use the example camera application provided with Qtopia.

The camera extension mechanism

Simply put, the camera::VideoCaptureDevice interface class provides a basic API for capture devices as used in the camera application.

Ideally we have two cases:

  1. For Video4Linux 1 type device drivers, see v4l1videocapturedevice.cpp in the camera application source tree.
  2. For Video4Linux 2 type device drivers, see v4l2videocapturedevice.cpp in the camera application source tree.

Custom drivers

It might be the case that your camera driver will not conform fully to either Video4Linux specifications. An example of such a device is the camera on the Trolltech Greenphone. Although it's driver supports some of Video4Linux 1 API, the support differs sufficiently to warrant a separate implemetation.

In a case like this you will have to subclass from camera::VideoCaptureDevice and implement all virtual functions yourself. Of course, reading the above two source files should make this clear, however here is a code fragment from the greenphones implementation where the getCameraImage() function needs to implement the greenphones idiosyncrasies. (This code will be in the greenphones device profile directory.)

    void OmegaCamera::getCameraImage( QImage& img, bool copy )
    {
        Q_UNUSED(copy);

        if ( fd == -1 ) {
            if ( img.isNull() ) {
                img = QImage(height, width, QImage::Format_RGB16);
            }
            return;
        }

        currentFrame = ++currentFrame % mbuf.frames;

        unsigned char*  buf = frames + mbuf.offsets[currentFrame];
        quint16 *dest;
        for (int x = height  - 1; x >= 0; --x)
        {
            dest = m_imageBuf + x;

            for (int y = 0; y < width; y+=2)
            {
                int u = buf[0];
                int v = buf[2];
                yuv2rgb(buf[1], u, v, dest);
                dest += height;
                yuv2rgb(buf[3], u, v, dest);
                dest += height;
                buf += 4;
            }

         }
        img = QImage((uchar*) m_imageBuf, height, width, QImage::Format_RGB16);

    }

Here is the implementation from v4l1videocapturedevice.cpp:

    void V4L1VideoCaptureDevice::getCameraImage( QImage& img, bool copy )
    {
        if ( fd == -1 ) {
            if ( img.isNull() ) {
                img = QImage(width, height, QImage::Format_RGB32);
            }
            return;
        }

        // Start capturing the next frame (we alternate between 0 and 1).
        int frame = currentFrame;
        struct video_mmap capture;
        if ( mbuf.frames > 1 ) {
            currentFrame = !currentFrame;
            capture.frame = currentFrame;
            capture.width = width;
            capture.height = height;
            capture.format = VIDEO_PALETTE_RGB32;
            ioctl( fd, VIDIOCMCAPTURE, &capture );
        }

        // Wait for the current frame to complete.
        ioctl( fd, VIDIOCSYNC, &frame );

        // Create an image that refers directly to the kernel's
        // frame buffer, to avoid having to copy the data.
        if ( !copy ) {
            img = QImage( frames + mbuf.offsets[frame], width, height,
                          QImage::Format_RGB32 );
        } else {
            img = QImage( width, height, QImage::Format_RGB32 );
            memcpy( img.bits(), frames + mbuf.offsets[frame], width * height * 4 );
        }

        // Queue up another frame if the device only supports one at a time.
        if ( mbuf.frames <= 1 ) {
            capture.frame = currentFrame;
            capture.width = width;
            capture.height = height;
            capture.format = VIDEO_PALETTE_RGB32;
            ioctl( fd, VIDIOCMCAPTURE, &capture );
        }
    }

As one can see by comparison to v4l1videocapturedevice.cpp it differs substantially in that we need to do color space conversion from YUV to RGB in addition some ioctls are not implemented by the Greenphones driver.


Copyright © 2008 Nokia Trademarks
Qtopia 4.3.3