Hi All,
For our new product it is necessary to blend an image on top of a video frame.
I'm using Windows CE 5.0 and it's post processing driver to accomplish the task (pp.dll).
The video frame input is stored system memory (YUV 4:4:4)
The overlay image is also stored in system memory (RGB 24bpp) (alpha value 128, no color keying)
The output image should also be stored in system memory (RGB 24bpp).
So my use case is: MEN -> PP -> MEM
I've enabled color space conversion step 1 (YUV -> RGB, I assume this converts the video input image to a similar RGB format as the overlay image).
For some reason I get a distorted output image as can be seen in out.bmp. I don't have a clue what is wrong.
If I make the overlay completely opaque the result is identical to the overlay which is correct.
So somehow the input image gets messed up.
To troubleshoot i've created a chess pattern as input video. The overlay image and the resulting combined image are presented by the following links:
http://users.pandora.be/dreamspace/out.bmphttp://users.pandora.be/dreamspace/overlay.bmp// This is my code to initialize the combining features of the post processor
----------------------------------------------------------------------------------------------------------------------
// Open camera
m_hPPDll = CreateFile(TEXT("POP1:"), // "special" file name
GENERIC_READ|GENERIC_WRITE, // desired access
FILE_SHARE_READ|FILE_SHARE_WRITE, // sharing mode
NULL, // security attributes (=NULL)
OPEN_EXISTING, // creation disposition
FILE_ATTRIBUTE_NORMAL, // flags and attributes
NULL); // template file (ignored)
if(m_hPPDll == INVALID_HANDLE_VALUE)
{
return false;
}
ppConfigData configData;
memset(&configData,0,sizeof(configData));
// enable overlay
configData.bCombining = true;
// configure overlay image coming from GPU
configData.alpha = 128;
configData.colorKey = 0xaaaaaaaa; // unused color value
configData.CSCEquation = ppCSCY2R_A1;
configData.CSCEquation2 = ppCSCNoOp;
// Input image
configData.inputSize.width = m_Width;
configData.inputSize.height = m_Height;
configData.inputStride = configData.inputSize.width;
configData.inputFormat = ppFormat_YUV444;
configData.inputDataWidth = ppDataWidth_8BPP;
// Overlay
configData.inputCombDataWidth = ppDataWidth_24BPP;
configData.inputCombFormat = ppFormat_RGB;
configData.inputCombSize.width = m_Width;
configData.inputCombSize.height = m_Height;
configData.inputCombStride = configData.inputCombSize.width*3;
configData.inputCombRGBPixelFormat.component0_offset = 0;
configData.inputCombRGBPixelFormat.component1_offset = 8;
configData.inputCombRGBPixelFormat.component2_offset = 16;
configData.inputCombRGBPixelFormat.component0_width = 8;
configData.inputCombRGBPixelFormat.component1_width = 8;
configData.inputCombRGBPixelFormat.component2_width = 8;
// Output image format
configData.outputFormat = ppFormat_RGB;
configData.outputSize.width = m_Width;
configData.outputSize.height = m_Height;
configData.outputStride = configData.outputSize.width*3;
configData.outputDataWidth = ppDataWidth_24BPP;
configData.outputRGBPixelFormat.component0_offset = 0;
configData.outputRGBPixelFormat.component1_offset = 8;
configData.outputRGBPixelFormat.component2_offset = 16;
configData.outputRGBPixelFormat.component0_width = 8;
configData.outputRGBPixelFormat.component1_width = 8;
configData.outputRGBPixelFormat.component2_width = 8;
// issue the IOCTL to configure the PP
if (!DeviceIoControl(m_hPPDll, // file handle to the driver
PP_IOCTL_CONFIGURE, // I/O control code
&configData, // in buffer
sizeof(ppConfigData), // in buffer size
NULL, // out buffer
0, // out buffer size
0, // number of bytes returned
NULL)) // ignored (=NULL)
{
return false;
}
return true;
----------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------
This is the code to tell the post processor to process a new frame
----------------------------------------------------------------------------------------------------------------------------------
bool AddBuffers(TRAF_UINT8 * pYUVImage, TRAF_UINT8 * pOverlay, TRAF_UINT8 * pOut)
{
ppBuffers pBuffers;
memset(&pBuffers,0,sizeof(ppBuffers));
pBuffers.inputBuf = (UINT32*)pYUVImage;
pBuffers.inputUBufOffset = m_Width * m_Height;
pBuffers.inputVBufOffset = pBuffers.inputUBufOffset + m_Width * m_Height;
pBuffers.inBufLen = m_Width*m_Height*3;
pBuffers.inputCombBuf = (UINT32*)pOverlay;
pBuffers.inCombBufLen = m_Width*m_Height*3;
pBuffers.outputBuf = (UINT32*)pOut;
pBuffers.outBufLen = m_Width*m_Height*3;
if (!DeviceIoControl(m_hPPDll, // file handle to the driver
PP_IOCTL_ENQUEUE_BUFFERS, // I/O control code
&pBuffers, // in buffer
sizeof(ppBuffers), // in buffer size
NULL, // out buffer
0, // out buffer size
0, // number of bytes returned
NULL)) // ignored (=NULL)
{
return false;
}
return true;
}
I hope someone has experience with this stuff..
Regards,
Mike