Video Encoding YUV422 Convert to 32bit RGBA

Video Encoding YUV422 Convert to 32bit RGBA


YUV Colorspaces Encoding is used extensively in video graphics ( as oppposed to RGB for images ). You can read about YUV in great detail on Wikipedia --> http://en.wikipedia.org/wiki/YUV. Below is an extremely slow, but clear to understand, Qt/C++ function to convert a raw frame of YUV422 video to an RGB888 Bitmap. I hope it can be used as a learning activity. Happy Coding!

void image::YUV422_to_RGB888( QByteArray rawStreamingFrame ) {

// Print data size

qDebug() << "Print the data size from read file: " << rawStreamingFrame.length() << " bytes...";

// Get the raw data in the bytearray

const char *binaryData = rawStreamingFrame.data();

// Define the H and W of our output image ( we know it's 640 x 480 )

int height = 480;

int width = 640;

// Create a QByteArray to store the RGB Data

int redContainer[height*width];

int greenContainer[height*width];

int blueContainer[height*width];

// To reconstruct pixels in pairs, 4 bytes of data are required. The bytes are arranged as u, y1, v, y2. The total number of bytes in the image stream is 2 x width x height.

qDebug() << "Looping through... " << rawStreamingFrame.length()-4;

// Loop through 4 bytes at a time

int cnt = -1;

for ( int i = 0 ; i <= rawStreamingFrame.length()-4 ; i += 4 ) {

// Extract yuv components

int u = (int)binaryData[i];

int y1 = (int)binaryData[i+1];

int v = (int)binaryData[i+2];

int y2 = (int)binaryData[i+3];

// Define the RGB

int r1 = 0 , g1 = 0 , b1 = 0;

int r2 = 0 , g2 = 0 , b2 = 0;

// u and v are +-0.5

u -= 128;

v -= 128;

// Conversion

r1 = y1 + 1.403*v;

g1 = y1 - 0.344*u - 0.714*v;

b1 = y1 + 1.770*u;

r2 = y2 + 1.403*v;

g2 = y2 - 0.344*u - 0.714*v;

b2 = y2 + 1.770*u;

// Increment by one so we can insert

cnt+=1;

// Append to the array holding our RGB Values

redContainer[cnt] = r1;

greenContainer[cnt] = g1;

blueContainer[cnt] = b1;

// Increment again since we have 2 pixels per uv value

cnt+=1;

// Store the second pixel

redContainer[cnt] = r2;

greenContainer[cnt] = g2;

blueContainer[cnt] = b2;

}

// Define a QImage for our RGB Data

QImage rgbImage = QImage(width, height, QImage::Format_RGB888);

// Print constructing RGB image

qDebug() << "Now constructing RGB Image... ";

// Now construct our RGB image

int pixelCounter = -1;

for ( int i = 0; i < height; ++i ) {

for ( int j = 0; j < width; ++j ) {

pixelCounter+=1;

rgbImage.setPixel( j, i, qRgb( redContainer[pixelCounter] , greenContainer[pixelCounter] , blueContainer[pixelCounter] ) );

}

}

// Print pixel counter

qDebug() << "Counted number of pixels: " << pixelCounter;

// Save our Image!

rgbImage.save("/home/user/rgb_from_yuv.bmp");

}



ClassyBits 2016