Camera Driver Details (Windows Embedded CE 6.0)
1/6/2010
General Implementation
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.
Dropped Frames
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.
Hardware encoding
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.
Custom properties
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.
Null Driver
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.
Memory alignment and working set optimization
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.
Using DirectDraw Overlays
The driver must set the correct capability bits for its DirectDraw overlay surfaces. The following topics provide some common capability bits settings.
- Capability Bits for Non-flippable RGB Overlays
- Capability Bits for Non-flippable YV12 Overlays
- Capability Bits for Flippable YV12 Overlays
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.
Capture with YUV Formats
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 BITRATE (DX * abs(DY) * DBITCOUNT * FRAMERATE)
#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
CS_DATARANGE_VIDEO DCAM_StreamMode = {
// CSDATARANGE
{
sizeof (CS_DATARANGE_VIDEO), // Flags
0,
SAMPLESIZE, // SampleSize
0, // Reserved
STATIC_CSDATAFORMAT_TYPE_VIDEO,
FOURCC_YV12,
0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71,
STATIC_CSDATAFORMAT_SPECIFIER_VIDEOINFO
},
TRUE, // BOOL, bFixedSizeSamples
TRUE, // BOOL, bTemporalCompression
CS_VIDEOSTREAM_CAPTURE, // StreamDescriptionFlags (CS_VIDEO_DESC_*)
0, // MemoryAllocationFlags (CS_VIDEO_ALLOC_*)
// _CS_VIDEO_STREAM_CONFIG_CAPS
{
STATIC_CSDATAFORMAT_SPECIFIER_VIDEOINFO,
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]
}
};