Camera Driver Details (Windows Embedded CE 6.0)


You can create a camera driver by designing a class to represent the camera, a class to represent the pins, and then implementing the camera driver interface functions as an interface layer for the objects you instantiate from your classes.

Calls to the CAM_Open function should instantiate a global object for your camera device. This object represents the hardware adapter so the driver must ensure that there is only one instance of this object running at any one time.

The client can dynamically query the driver for dropped frames by using the property CSPROPERTY_DROPPEDFRAMES_CURRENT (see CSPROPERTY_VIDCAP_DROPPEDFRAMES) in the PROPSETID_DROPPEDFRAME property set.   The driver returns the number of captured frames and the number of dropped frames in the CSPROPERTY_DROPPEDFRAMES_CURRENT_S structure.

For cameras that support hardware encoding, the driver uses PROPSETID_VIDCAP_VIDEOCOMPRESSION property set to expose the encoding settings. For specific properties see CSPROPERTY_VIDCAP_VIDEOCOMPRESSION.

The camera driver model is designed to be extensible and driver writers can always define their own customized properties and their own IOCTL codes to expose some features specific to particular hardware.

The null camera driver is provided as a resource to help you begin the process of developing your own camera driver for your own hardware. The null driver source code contains parameters that my or may not work directly with your specific hardware. In general, you should assume that the basic parts of a camera driver are there but that you will need to spend the time to go through a very careful customization process. It can be difficult to bring up your driver certain hardware-specific parameters, such as memory alignment requirements and the number of buffers per pin, are not set correctly for your hardware.

You can preserve the performance of your driver while minimizing its footprint by fine-tuning the values it sets in CSALLOCATOR_FRAMING. Specifically, setting the optimal value for CSALLOCATOR_FRAMING.Frames reduce the driver's working set.

The driver must set the correct capability bits for its DirectDraw overlay surfaces. The following topics provide some common capability bits settings.

A driver that uses overlays must, in software, track whether an overlay is visible. The driver must explicitly turn the overlay off when the driver goes into a power-saving mode. When the driver emerges from the power-saving mode it must restore the overlay based on the software state, not the previous hardware state. These steps help avoid sequencing problems that can arise between the application, the video renderer, and the hardware as the device enters the power-saving mode.

For all YUV formatted media types, the height value in CS_BITMAPINFOHEADER should be negative. As a result you should not rely on the value in biHeight to be positive when using it to calculate or other values. You should always use the absolute value of biHeight when calculating biSizeImage, biBitCount, or values such as frame rates.

Each pin can support one or more formats. The driver can use CS_DATARANGE_VIDEO to manage these formats. Following code shows A CS_DATARANGE_VIDEO structure populated for 176 x 144 YV12 content at 15 fps.

#define SAMPLESIZE (DX * abs(DY) * DBITCOUNT / 8)
#define FOURCC_YV12     mmioFOURCC('Y', 'V', '1', '2')

#define DX          176
#define DY          -144  // **** YUV is always negative ****
#define DBITCOUNT    12   // **** YV12 is 12 bits format ****
#define FRAMERATE    15

    sizeof (CS_DATARANGE_VIDEO),     // Flags
    SAMPLESIZE,                      // SampleSize
    0,                               // Reserved
    0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71,

  TRUE,                   // BOOL,  bFixedSizeSamples
  TRUE,                   // BOOL,  bTemporalCompression
  CS_VIDEOSTREAM_CAPTURE, // StreamDescriptionFlags (CS_VIDEO_DESC_*)
  0,                      // MemoryAllocationFlags (CS_VIDEO_ALLOC_*)

    CS_AnalogVideo_None, // AnalogVideoStandard
    DX,DY,    // InputSize, (the inherent size of the incoming signal
              //             with every digitized pixel unique)
    DX,DY,    // MinCroppingSize, smallest rcSrc cropping rect allowed
    DX,DY,    // MaxCroppingSize, largest  rcSrc cropping rect allowed
    1,        // CropGranularityX, granularity of cropping size
    1,        // CropGranularityY
    1,        // CropAlignX, alignment of cropping rect 
    1,        // CropAlignY;
    DX, DY,   // MinOutputSize, smallest bitmap stream can produce
    DX, DY,   // MaxOutputSize, largest  bitmap stream can produce
    DX,       // OutputGranularityX, granularity of output bitmap size
    DY,       // OutputGranularityY;
    0,        // StretchTapsX  (0 no stretch, 1 pix dup, 2 interp...)
    0,        // StretchTapsY
    0,        // ShrinkTapsX 
    0,        // ShrinkTapsY 
    // Allow 1% difference
    FRAMEINTERVAL_15FPS,   // MinFrameInterval (10,000,000 / 30.00FPS),
                           // 100nS units
    FRAMEINTERVAL_3_75FPS, // MaxFrameInterval (10,000,000 / 3.75FPS),
                           // 100nS units
    BITRATE / 8,           // (DX * DY * DBITCOUNT) * DFPS_MIN,
                           // MinBitsPerSecond (3.75 FPS);
    BITRATE,               // (DX * DY * DBITCOUNT) * DFPS_MAX
                           // MaxBitsPerSecond (30.0 FPS);
  // CS_VIDEOINFOHEADER (default format)
    0,0,DX,DY,                     // RECT  rcSource; 
    0,0,DX,DY,                     // RECT  rcTarget; 
    BITRATE,                       // DWORD dwBitRate;
    0L,                            // DWORD dwBitErrorRate;   
    REFTIME_15FPS,                 // REFERENCE_TIME AvgTimePerFrame; 
    sizeof (CS_BITMAPINFOHEADER),  // DWORD biSize;
    DX,                            // LONG  biWidth;
    DY,                            // LONG  biHeight;
    3,                             // WORD  biPlanes;
    DBITCOUNT,                     // WORD  biBitCount;
    FOURCC_YV12|BI_SRCPREROTATE,   // DWORD biCompression;
    SAMPLESIZE,                    // DWORD biSizeImage;
    0,                             // LONG  biXPelsPerMeter;
    0,                             // LONG  biYPelsPerMeter;
    0,                             // DWORD biClrUsed;
    0,                             // DWORD biClrImportant;
    0, 0, 0                        // DWORD dwBitMasks[3]

Community Additions