RGB to YUV conversion using Symbian C++
Article Metadata
Tested with
Compatibility
S60 3rd Edition, Feature Pack 1
S60 3rd Edition, Feature Pack 2
S60 5th Edition
Article
Description
Starting from S60 3rd Edition, Feature Pack 2, the MDF DevVideoRecord API is available as part of the SDK API Plug-in package. DevVideoRecord allows direct and low-level access to video encoders and preprocessors, making it possible to take content from any source in addition to the camera (for example, bitmap images), pass it to DevVideoRecord, and produce an encoded video stream.
Input to the encoder must conform to a specific colour format; YUV422 or more commonly, YUV420 (planar). YUV420 has 8-bit luminance (Y) value per source pixel, and a reduced number of chrominance (U,V) samples, each covering a 2x2 pixel area. In plane mode, the values of Y, U, and V channels are grouped together in the memory [Y0Y1Y2Y3Y4Y5Y6Y7....U0U1....V0V1], improving the compression rate of the image.
Solution
The following code demonstrates how to convert a frame of source RGB (8 bits per channel) to YUV420p.
// Definitions that help access each colour component in source bitmap
#define sR ((TInt32)(s[2]))
#define sG ((TInt32)(s[1]))
#define sB ((TInt32)(s[0]))
#define KImageWidth 176 // QCIF resolution
#define KImageHeigth 144
const TInt KImageNumPixels = KImageWidth * KImageHeigth;
// Lock source bitmap (CFbsBitmap)
iSourceBitmap->LockHeap(EFalse);
TUint8* s = (TUint8*)iSourceBitmap->DataAddress();
TInt i = 0;
TInt ui = KImageNumPixels;
TInt vi = KImageNumPixels + KImageNumPixels/4;
// iYuv is an array of TUint8 values, length (KImageNumPixels*3/2)
for(TInt j=0; j < KImageHeigth; j++)
for(TInt k=0; k < KImageWidth; k++)
{
// Y value is generated for each pixel
iYuv[i] = (TUint8)( ( 66*sR + 129*sG + 25*sB + 128) >> 8 ) + 16;
// U, V values are generated for every other pixel on every other scanline
if(0 == j%2 && 0 == k%2)
{
iYuv[ui++] = (TUint8)( (-38*sR - 74*sG + 112*sB + 128) >> 8 ) + 128;
iYuv[vi++] = (TUint8)( (112*sR - 94*sG - 18*sB + 128) >> 8 ) + 128;
}
i++;
s+=iBytesPerPixel; // Number of bytes representing one pixel in source
// bitmap e.g. if bitmap display mode == EColor16M
// (24bits/pixel), then iBytesPerPixel == 3
}
iSourceBitmap->UnlockHeap(EFalse);
// iYuv now contains the source frame converted to YUV420p format
Notes:
The latest S60 devices have multiple DevVideoRecord codecs with varying capabilities: H.263 and/or MPEG-4 (VSP) encoding, hardware-accelerated and software-based codecs, and some encoders also support direct capture from the camera. Encoders and their capabilities as well as supported input formats can be listed and a suitable encoder selected programmatically.


(no comments yet)