Camera Capture Performance (Part1)
Still Image Capture
Windows Mobile 5.0 contains an Image Sink Filter (a DShow filter). This filter encodes the image data and writes the encoded image to a file. For encoding, the Image Sink Filter uses Imaging API to access the installed Imaging encoders. The still image encoders which Microsoft ships with Windows Mobile 5.0 are not optimized and should, in general be replaced by OEMs with optimized encoders for the particular platform. One limitation of Imaging framework is that it only accepts RGB input, i.e., the raw buffer sent to Imaging encoder must be in RGB format. For this very reason, the Image Sink filter does not accept YCbCr.
Besides accepting RGB data, the Image Sink Filter also accepts pre-encoded JPG data. This is useful when there is an optimized still image encoder available on a given platform, which accepts YCbCr. For this to work the actual encoding is done by the driver and the camera driver exposes a format with SubFormat field of CSDATARANGE equal to MEDIASUBTYPE_IJPG GUID. The encoded buffer will then be passed down to the Image Sink Filter simply for file I/O. This optimized encoding can also be done in a DShow Transform filter with the transform filter exposing MEDIASUBTYPE_IJPG on its output pin.
The OEMs can still use the encoders that are shipped with Windows Mobile 5.0. These encoders provide a stable, platform independent solution. However, as the resolution of still image increases, the performance of these encoders deteriorates.
Following is how you would change the sample null camera driver to provide JPG data on STILL pin.
Step 1: Define the format
In adapterprops.h define the following
#define FOURCC_IJPG mmioFOURCC('I', 'J', 'P', 'G')
#define MEDIASUBTYPE_IJPG {0x47504A49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define DX 176
#define DY 144
#define DBITCOUNT 16
#define FRAMERATE 15
CS_DATARANGE_VIDEO DCAM_StreamMode =
{
// CSDATARANGE
{
sizeof (CS_DATARANGE_VIDEO), // Flags
0,
SAMPLESIZE, // Replace with maximum Sample Size that the JPG data would take for the current resolution and image quality
0, // Reserved
STATIC_CSDATAFORMAT_TYPE_VIDEO,
MEDIASUBTYPE_IJPG,
STATIC_CSDATAFORMAT_SPECIFIER_VIDEOINFO
},
TRUE, // BOOL, bFixedSizeSamples (all samples same size?)
TRUE, // BOOL, bTemporalCompression (all I frames?)
CS_VIDEOSTREAM_CAPTURE, // StreamDescriptionFlags (CS_VIDEO_DESC_*)
0, // MemoryAllocationFlags (CS_VIDEO_ALLOC_*)
// _CS_VIDEO_STREAM_CONFIG_CAPS
{
// Omitted for this sample. Please refer to adapterprops.h in the sample null camera driver for ways to fill in this structure
………
………
},
// CS_VIDEOINFOHEADER
{
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_IJPG | 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]
}
};
Step 2: Add this format to the list of formats of Still pin
In sample null camera driver, you would modify CCameraDevice::Initialize() in cameradevice.cpp to have
m_PinVideoFormat[STILL].categoryGUID = PINNAME_VIDEO_STILL;
m_PinVideoFormat[STILL].ulAvailFormats = 1;
m_PinVideoFormat[STILL].pCsDataRangeVideo[0] = &DCAM_StreamMode;
Step 3: Modify the BufferFill() function
Use biCompression field of the current format to determine whether MEDIASUBTYPE_IJPG format is selected. In BufferFill() you can have following check
UINT
BufferFill( PUCHAR pImage, PCS_VIDEOINFOHEADER pCsVideoInfoHdr, IMAGECOMMAND Command, bool FlipHorizontal, LPVOID lpParam )
{
if( NULL == pCsVideoInfoHdr )
{
return -1;
}
DWORD biCompression = pCsVideoInfoHdr->bmiHeader.biCompression;
if ( (FOURCC_IJPG == (biCompression & ~BI_SRCPREROTATE)) )
{
// Real drivers would add code here to handle JPEG encoding.
// The biSizeImage that is returned here should be the actual
// size of JPEG data that is written to the buffer.
return biSizeImage;
}
……….
……….
}
Step 4: Handle PROPSETID_VIDCAP_VIDEOCOMPRESSION
The default implementation(AdapterHandleCompressionRequests()) for PROPSETID_VIDCAP_VIDEOCOMPRESSION returns ERROR_INVALID_PARAMETER. Camera application on Windows Mobile 5.0 and later, uses this interface to set encoder quality. You would need to change this to return ERROR_SUCCESS after correctly handling various properties in this property set. Failure to do this would result in camera application raising an exception at initialization.
Comments
Anonymous
April 01, 2007
Hi I m trying to capture camera buffer using Dshow, but i m not able find any information on that Can u help for that??? i m getting information about writting buffer to file, but i want camera buffer, as i need to send it over network. please help me , Thanks. TestAnonymous
April 16, 2007
Hello Saad, Why has the Imaging API been not yet updated/modified to accept YCbCr color format? As this will give an extra option for users developing Imaging encoders/decoders using MS provided ImagingAPI. You mention that, platforms with optimized JPEG encoders accepting YCbCr format at the input should perform this encoding inside the camera driver and provide the encoded data to Image Sink filter. Yes currently this is the only option! But on such platforms, applications like Image editing can not be accelerated for optimized encoding as there is no optimized Image encoder with RGB format (default encoder must be used). ImagingAPI accepting YCbCr will solve this issue. Regards, Sandeep ShindeAnonymous
April 20, 2007
vishaljogi, What platform/version you are using. Is it based on Windows CE or Windows Mobile? Camera API was introduced in WM 5.0 and then shipped with WM 6.0 as well as Windows CE 6.0. http://msdn2.microsoft.com/en-us/library/aa451185.aspx should give you some information. -SaadAnonymous
April 20, 2007
Sandeep, Thanks for you comments. You can still plug-in your optimized YUV encoder as an Imaging Plugin. You will have to do an RGB-YUV conversion in your plugin before feeding the data to your encoder. This way any editing application can make use of your optimized encoder. I know the concerns about the redundant RGB->YUV conversion but we need to live with that. -SaadAnonymous
May 07, 2007
Thank you for the response. The conversion of course takes lot of memory (as still images are very big these days around 3MP). Could you please write a blog about the changes in camera driver structure (if any) from WM6.0 to Windows CE 6.0. As far as I know, the driver existing on WM6.0 will work with WinCE6.0 without any changes. Is this assumption correct. Regards, SandeepAnonymous
May 07, 2007
Saad, Thank you for the response. The conversion of course takes lot of memory (as still images are very big these days around 3MP). Could you please write a blog about the changes in camera driver structure (if any) from WM6.0 to Windows CE 6.0. As far as I know, the driver existing on WM6.0 will work with WinCE6.0 without any changes. Is this assumption correct. Regards, SandeepAnonymous
August 23, 2007
Hi Saad, I'm developing camera driver on WinCE5.0 (not Magneto or XBow). I expect to make the camera driver to support DShow framework. As I know, streaming architecture for cameras were added since WM5.0 or later. I found nothing for that in PB5.0(WinCE5.0) help document. So my question is, could I develop a DShow camera driver on "WinCE5.0"? If yes, how to do? Regards, AlecAnonymous
February 11, 2008
Hi Saad, I am writing a DirestShow Camera application. I am loading the camera driver using the following code. varCamName = _T ("CAM1:"); hr = PropBag.Write( L"VCapName", &varCamName ); hr = pPropertyBag->Load( &PropBag, NULL); It starts well for the first time, but after destroying the graph, if the capture graph is started for the second time it gives the following error.. //hr fails with -2147024841 (ERROR_DEV_NOT_EXIST) What could be the reason ? Can u give some solution ? Thanks in advance, Sitharth.Anonymous
December 02, 2008
Hello Saad, Can you please tell me how should I register a OEM developed Imaging encoder plug-in (IImageEncoder) with the default applications. There is no help available for this anywhere. Thanks in advance for the help, Regards, Sandeep